yui-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4207 @@
1
+ /*
2
+ Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3
+ Code licensed under the BSD License:
4
+ http://developer.yahoo.com/yui/license.html
5
+ version: 3.3.0
6
+ build: 3167
7
+ */
8
+ /**
9
+ * The YUI module contains the components required for building the YUI seed
10
+ * file. This includes the script loading mechanism, a simple queue, and
11
+ * the core utilities for the library.
12
+ * @module yui
13
+ * @submodule yui-base
14
+ */
15
+
16
+ if (typeof YUI != 'undefined') {
17
+ YUI._YUI = YUI;
18
+ }
19
+
20
+ /**
21
+ * The YUI global namespace object. If YUI is already defined, the
22
+ * existing YUI object will not be overwritten so that defined
23
+ * namespaces are preserved. It is the constructor for the object
24
+ * the end user interacts with. As indicated below, each instance
25
+ * has full custom event support, but only if the event system
26
+ * is available. This is a self-instantiable factory function. You
27
+ * can invoke it directly like this:
28
+ *
29
+ * YUI().use('*', function(Y) {
30
+ * // ready
31
+ * });
32
+ *
33
+ * But it also works like this:
34
+ *
35
+ * var Y = YUI();
36
+ *
37
+ * @class YUI
38
+ * @constructor
39
+ * @global
40
+ * @uses EventTarget
41
+ * @param o* {object} 0..n optional configuration objects. these values
42
+ * are store in Y.config. See config for the list of supported
43
+ * properties.
44
+ */
45
+ /*global YUI*/
46
+ /*global YUI_config*/
47
+ var YUI = function() {
48
+ var i = 0,
49
+ Y = this,
50
+ args = arguments,
51
+ l = args.length,
52
+ instanceOf = function(o, type) {
53
+ return (o && o.hasOwnProperty && (o instanceof type));
54
+ },
55
+ gconf = (typeof YUI_config !== 'undefined') && YUI_config;
56
+
57
+ if (!(instanceOf(Y, YUI))) {
58
+ Y = new YUI();
59
+ } else {
60
+ // set up the core environment
61
+ Y._init();
62
+
63
+ // YUI.GlobalConfig is a master configuration that might span
64
+ // multiple contexts in a non-browser environment. It is applied
65
+ // first to all instances in all contexts.
66
+ if (YUI.GlobalConfig) {
67
+ Y.applyConfig(YUI.GlobalConfig);
68
+ }
69
+
70
+ // YUI_Config is a page-level config. It is applied to all
71
+ // instances created on the page. This is applied after
72
+ // YUI.GlobalConfig, and before the instance level configuration
73
+ // objects.
74
+ if (gconf) {
75
+ Y.applyConfig(gconf);
76
+ }
77
+
78
+ // bind the specified additional modules for this instance
79
+ if (!l) {
80
+ Y._setup();
81
+ }
82
+ }
83
+
84
+ if (l) {
85
+ // Each instance can accept one or more configuration objects.
86
+ // These are applied after YUI.GlobalConfig and YUI_Config,
87
+ // overriding values set in those config files if there is a '
88
+ // matching property.
89
+ for (; i < l; i++) {
90
+ Y.applyConfig(args[i]);
91
+ }
92
+
93
+ Y._setup();
94
+ }
95
+
96
+ Y.instanceOf = instanceOf;
97
+
98
+ return Y;
99
+ };
100
+
101
+ (function() {
102
+
103
+ var proto, prop,
104
+ VERSION = '3.3.0',
105
+ PERIOD = '.',
106
+ BASE = 'http://yui.yahooapis.com/',
107
+ DOC_LABEL = 'yui3-js-enabled',
108
+ NOOP = function() {},
109
+ SLICE = Array.prototype.slice,
110
+ APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo
111
+ 'io.xdrResponse': 1, // can call. this should
112
+ 'SWF.eventHandler': 1 }, // be done at build time
113
+ hasWin = (typeof window != 'undefined'),
114
+ win = (hasWin) ? window : null,
115
+ doc = (hasWin) ? win.document : null,
116
+ docEl = doc && doc.documentElement,
117
+ docClass = docEl && docEl.className,
118
+ instances = {},
119
+ time = new Date().getTime(),
120
+ add = function(el, type, fn, capture) {
121
+ if (el && el.addEventListener) {
122
+ el.addEventListener(type, fn, capture);
123
+ } else if (el && el.attachEvent) {
124
+ el.attachEvent('on' + type, fn);
125
+ }
126
+ },
127
+ remove = function(el, type, fn, capture) {
128
+ if (el && el.removeEventListener) {
129
+ // this can throw an uncaught exception in FF
130
+ try {
131
+ el.removeEventListener(type, fn, capture);
132
+ } catch (ex) {}
133
+ } else if (el && el.detachEvent) {
134
+ el.detachEvent('on' + type, fn);
135
+ }
136
+ },
137
+ handleLoad = function() {
138
+ YUI.Env.windowLoaded = true;
139
+ YUI.Env.DOMReady = true;
140
+ if (hasWin) {
141
+ remove(window, 'load', handleLoad);
142
+ }
143
+ },
144
+ getLoader = function(Y, o) {
145
+ var loader = Y.Env._loader;
146
+ if (loader) {
147
+ loader.ignoreRegistered = false;
148
+ loader.onEnd = null;
149
+ loader.data = null;
150
+ loader.required = [];
151
+ loader.loadType = null;
152
+ } else {
153
+ loader = new Y.Loader(Y.config);
154
+ Y.Env._loader = loader;
155
+ }
156
+
157
+ return loader;
158
+ },
159
+
160
+ clobber = function(r, s) {
161
+ for (var i in s) {
162
+ if (s.hasOwnProperty(i)) {
163
+ r[i] = s[i];
164
+ }
165
+ }
166
+ },
167
+
168
+ ALREADY_DONE = { success: true };
169
+
170
+ // Stamp the documentElement (HTML) with a class of "yui-loaded" to
171
+ // enable styles that need to key off of JS being enabled.
172
+ if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
173
+ if (docClass) {
174
+ docClass += ' ';
175
+ }
176
+ docClass += DOC_LABEL;
177
+ docEl.className = docClass;
178
+ }
179
+
180
+ if (VERSION.indexOf('@') > -1) {
181
+ VERSION = '3.2.0'; // dev time hack for cdn test
182
+ }
183
+
184
+ proto = {
185
+ /**
186
+ * Applies a new configuration object to the YUI instance config.
187
+ * This will merge new group/module definitions, and will also
188
+ * update the loader cache if necessary. Updating Y.config directly
189
+ * will not update the cache.
190
+ * @method applyConfig
191
+ * @param {object} the configuration object.
192
+ * @since 3.2.0
193
+ */
194
+ applyConfig: function(o) {
195
+
196
+ o = o || NOOP;
197
+
198
+ var attr,
199
+ name,
200
+ // detail,
201
+ config = this.config,
202
+ mods = config.modules,
203
+ groups = config.groups,
204
+ rls = config.rls,
205
+ loader = this.Env._loader;
206
+
207
+ for (name in o) {
208
+ if (o.hasOwnProperty(name)) {
209
+ attr = o[name];
210
+ if (mods && name == 'modules') {
211
+ clobber(mods, attr);
212
+ } else if (groups && name == 'groups') {
213
+ clobber(groups, attr);
214
+ } else if (rls && name == 'rls') {
215
+ clobber(rls, attr);
216
+ } else if (name == 'win') {
217
+ config[name] = attr.contentWindow || attr;
218
+ config.doc = config[name].document;
219
+ } else if (name == '_yuid') {
220
+ // preserve the guid
221
+ } else {
222
+ config[name] = attr;
223
+ }
224
+ }
225
+ }
226
+
227
+ if (loader) {
228
+ loader._config(o);
229
+ }
230
+ },
231
+
232
+ _config: function(o) {
233
+ this.applyConfig(o);
234
+ },
235
+
236
+ /**
237
+ * Initialize this YUI instance
238
+ * @private
239
+ */
240
+ _init: function() {
241
+ var filter,
242
+ Y = this,
243
+ G_ENV = YUI.Env,
244
+ Env = Y.Env,
245
+ prop;
246
+
247
+ /**
248
+ * The version number of the YUI instance.
249
+ * @property version
250
+ * @type string
251
+ */
252
+ Y.version = VERSION;
253
+
254
+ if (!Env) {
255
+ Y.Env = {
256
+ mods: {}, // flat module map
257
+ versions: {}, // version module map
258
+ base: BASE,
259
+ cdn: BASE + VERSION + '/build/',
260
+ // bootstrapped: false,
261
+ _idx: 0,
262
+ _used: {},
263
+ _attached: {},
264
+ _yidx: 0,
265
+ _uidx: 0,
266
+ _guidp: 'y',
267
+ _loaded: {},
268
+ serviced: {},
269
+ getBase: G_ENV && G_ENV.getBase ||
270
+
271
+ function(srcPattern, comboPattern) {
272
+ var b, nodes, i, src, match;
273
+ // get from querystring
274
+ nodes = (doc && doc.getElementsByTagName('script')) || [];
275
+ for (i = 0; i < nodes.length; i = i + 1) {
276
+ src = nodes[i].src;
277
+ if (src) {
278
+
279
+ match = src.match(srcPattern);
280
+ b = match && match[1];
281
+ if (b) {
282
+ // this is to set up the path to the loader. The file
283
+ // filter for loader should match the yui include.
284
+ filter = match[2];
285
+
286
+ if (filter) {
287
+ match = filter.indexOf('js');
288
+
289
+ if (match > -1) {
290
+ filter = filter.substr(0, match);
291
+ }
292
+ }
293
+
294
+ // extract correct path for mixed combo urls
295
+ // http://yuilibrary.com/projects/yui3/ticket/2528423
296
+ match = src.match(comboPattern);
297
+ if (match && match[3]) {
298
+ b = match[1] + match[3];
299
+ }
300
+
301
+ break;
302
+ }
303
+ }
304
+ }
305
+
306
+ // use CDN default
307
+ return b || Env.cdn;
308
+ }
309
+ };
310
+
311
+ Env = Y.Env;
312
+
313
+ Env._loaded[VERSION] = {};
314
+
315
+ if (G_ENV && Y !== YUI) {
316
+ Env._yidx = ++G_ENV._yidx;
317
+ Env._guidp = ('yui_' + VERSION + '_' +
318
+ Env._yidx + '_' + time).replace(/\./g, '_');
319
+ } else if (YUI._YUI) {
320
+
321
+ G_ENV = YUI._YUI.Env;
322
+ Env._yidx += G_ENV._yidx;
323
+ Env._uidx += G_ENV._uidx;
324
+
325
+ for (prop in G_ENV) {
326
+ if (!(prop in Env)) {
327
+ Env[prop] = G_ENV[prop];
328
+ }
329
+ }
330
+
331
+ delete YUI._YUI;
332
+ }
333
+
334
+ Y.id = Y.stamp(Y);
335
+ instances[Y.id] = Y;
336
+
337
+ }
338
+
339
+ Y.constructor = YUI;
340
+
341
+ // configuration defaults
342
+ Y.config = Y.config || {
343
+ win: win,
344
+ doc: doc,
345
+ debug: true,
346
+ useBrowserConsole: true,
347
+ throwFail: true,
348
+ bootstrap: true,
349
+ cacheUse: true,
350
+ fetchCSS: true
351
+ };
352
+
353
+ Y.config.base = YUI.config.base ||
354
+ Y.Env.getBase(/^(.*)yui\/yui([\.\-].*)js(\?.*)?$/,
355
+ /^(.*\?)(.*\&)(.*)yui\/yui[\.\-].*js(\?.*)?$/);
356
+
357
+ if (!filter || (!('-min.-debug.').indexOf(filter))) {
358
+ filter = '-min.';
359
+ }
360
+
361
+ Y.config.loaderPath = YUI.config.loaderPath ||
362
+ 'loader/loader' + (filter || '-min.') + 'js';
363
+
364
+ },
365
+
366
+ /**
367
+ * Finishes the instance setup. Attaches whatever modules were defined
368
+ * when the yui modules was registered.
369
+ * @method _setup
370
+ * @private
371
+ */
372
+ _setup: function(o) {
373
+ var i, Y = this,
374
+ core = [],
375
+ mods = YUI.Env.mods,
376
+ extras = Y.config.core || ['get',
377
+ 'rls',
378
+ 'intl-base',
379
+ 'loader',
380
+ 'yui-log',
381
+ 'yui-later',
382
+ 'yui-throttle'];
383
+
384
+ for (i = 0; i < extras.length; i++) {
385
+ if (mods[extras[i]]) {
386
+ core.push(extras[i]);
387
+ }
388
+ }
389
+
390
+ Y._attach(['yui-base']);
391
+ Y._attach(core);
392
+
393
+ // Y.log(Y.id + ' initialized', 'info', 'yui');
394
+ },
395
+
396
+ /**
397
+ * Executes a method on a YUI instance with
398
+ * the specified id if the specified method is whitelisted.
399
+ * @method applyTo
400
+ * @param id {string} the YUI instance id.
401
+ * @param method {string} the name of the method to exectute.
402
+ * Ex: 'Object.keys'.
403
+ * @param args {Array} the arguments to apply to the method.
404
+ * @return {object} the return value from the applied method or null.
405
+ */
406
+ applyTo: function(id, method, args) {
407
+ if (!(method in APPLY_TO_AUTH)) {
408
+ this.log(method + ': applyTo not allowed', 'warn', 'yui');
409
+ return null;
410
+ }
411
+
412
+ var instance = instances[id], nest, m, i;
413
+ if (instance) {
414
+ nest = method.split('.');
415
+ m = instance;
416
+ for (i = 0; i < nest.length; i = i + 1) {
417
+ m = m[nest[i]];
418
+ if (!m) {
419
+ this.log('applyTo not found: ' + method, 'warn', 'yui');
420
+ }
421
+ }
422
+ return m.apply(instance, args);
423
+ }
424
+
425
+ return null;
426
+ },
427
+
428
+ /**
429
+ * Registers a module with the YUI global. The easiest way to create a
430
+ * first-class YUI module is to use the YUI component build tool.
431
+ *
432
+ * http://yuilibrary.com/projects/builder
433
+ *
434
+ * The build system will produce the YUI.add wrapper for you module, along
435
+ * with any configuration info required for the module.
436
+ * @method add
437
+ * @param name {string} module name.
438
+ * @param fn {Function} entry point into the module that
439
+ * is used to bind module to the YUI instance.
440
+ * @param version {string} version string.
441
+ * @param details {object} optional config data:
442
+ * requires: features that must be present before this module can be
443
+ * attached.
444
+ * optional: optional features that should be present if loadOptional
445
+ * is defined. Note: modules are not often loaded this way in YUI 3,
446
+ * but this field is still useful to inform the user that certain
447
+ * features in the component will require additional dependencies.
448
+ * use: features that are included within this module which need to
449
+ * be attached automatically when this module is attached. This
450
+ * supports the YUI 3 rollup system -- a module with submodules
451
+ * defined will need to have the submodules listed in the 'use'
452
+ * config. The YUI component build tool does this for you.
453
+ * @return {YUI} the YUI instance.
454
+ *
455
+ */
456
+ add: function(name, fn, version, details) {
457
+ details = details || {};
458
+ var env = YUI.Env,
459
+ mod = {
460
+ name: name,
461
+ fn: fn,
462
+ version: version,
463
+ details: details
464
+ },
465
+ loader,
466
+ i, versions = env.versions;
467
+
468
+ env.mods[name] = mod;
469
+ versions[version] = versions[version] || {};
470
+ versions[version][name] = mod;
471
+
472
+ for (i in instances) {
473
+ if (instances.hasOwnProperty(i)) {
474
+ loader = instances[i].Env._loader;
475
+ if (loader) {
476
+ if (!loader.moduleInfo[name]) {
477
+ loader.addModule(details, name);
478
+ }
479
+ }
480
+ }
481
+ }
482
+
483
+ return this;
484
+ },
485
+
486
+ /**
487
+ * Executes the function associated with each required
488
+ * module, binding the module to the YUI instance.
489
+ * @method _attach
490
+ * @private
491
+ */
492
+ _attach: function(r, fromLoader) {
493
+ var i, name, mod, details, req, use, after,
494
+ mods = YUI.Env.mods,
495
+ Y = this, j,
496
+ done = Y.Env._attached,
497
+ len = r.length, loader;
498
+
499
+ // Y.log('attaching: ' + r, 'info', 'yui');
500
+
501
+ for (i = 0; i < len; i++) {
502
+ if (!done[r[i]]) {
503
+ name = r[i];
504
+ mod = mods[name];
505
+ if (!mod) {
506
+ loader = Y.Env._loader;
507
+
508
+ // Y.log('no js def for: ' + name, 'info', 'yui');
509
+
510
+ if (!loader || !loader.moduleInfo[name]) {
511
+ Y.message('NOT loaded: ' + name, 'warn', 'yui');
512
+ }
513
+ } else {
514
+ done[name] = true;
515
+ details = mod.details;
516
+ req = details.requires;
517
+ use = details.use;
518
+ after = details.after;
519
+
520
+ if (req) {
521
+ for (j = 0; j < req.length; j++) {
522
+ if (!done[req[j]]) {
523
+ if (!Y._attach(req)) {
524
+ return false;
525
+ }
526
+ break;
527
+ }
528
+ }
529
+ }
530
+
531
+ if (after) {
532
+ for (j = 0; j < after.length; j++) {
533
+ if (!done[after[j]]) {
534
+ if (!Y._attach(after)) {
535
+ return false;
536
+ }
537
+ break;
538
+ }
539
+ }
540
+ }
541
+
542
+ if (use) {
543
+ for (j = 0; j < use.length; j++) {
544
+ if (!done[use[j]]) {
545
+ if (!Y._attach(use)) {
546
+ return false;
547
+ }
548
+ break;
549
+ }
550
+ }
551
+ }
552
+
553
+ if (mod.fn) {
554
+ try {
555
+ mod.fn(Y, name);
556
+ } catch (e) {
557
+ Y.error('Attach error: ' + name, e, name);
558
+ return false;
559
+ }
560
+ }
561
+
562
+ }
563
+ }
564
+ }
565
+
566
+ return true;
567
+ },
568
+
569
+ /**
570
+ * Attaches one or more modules to the YUI instance. When this
571
+ * is executed, the requirements are analyzed, and one of
572
+ * several things can happen:
573
+ *
574
+ * - All requirements are available on the page -- The modules
575
+ * are attached to the instance. If supplied, the use callback
576
+ * is executed synchronously.
577
+ *
578
+ * - Modules are missing, the Get utility is not available OR
579
+ * the 'bootstrap' config is false -- A warning is issued about
580
+ * the missing modules and all available modules are attached.
581
+ *
582
+ * - Modules are missing, the Loader is not available but the Get
583
+ * utility is and boostrap is not false -- The loader is bootstrapped
584
+ * before doing the following....
585
+ *
586
+ * - Modules are missing and the Loader is available -- The loader
587
+ * expands the dependency tree and fetches missing modules. When
588
+ * the loader is finshed the callback supplied to use is executed
589
+ * asynchronously.
590
+ *
591
+ * @param modules* {string} 1-n modules to bind (uses arguments array).
592
+ * @param *callback {function} callback function executed when
593
+ * the instance has the required functionality. If included, it
594
+ * must be the last parameter.
595
+ * <code>
596
+ * // loads and attaches drag and drop and its dependencies
597
+ * YUI().use('dd', function(Y) &#123;&#125);
598
+ * // attaches all modules that are available on the page
599
+ * YUI().use('*', function(Y) &#123;&#125);
600
+ * // intrinsic YUI gallery support (since 3.1.0)
601
+ * YUI().use('gallery-yql', function(Y) &#123;&#125);
602
+ * // intrinsic YUI 2in3 support (since 3.1.0)
603
+ * YUI().use('yui2-datatable', function(Y) &#123;&#125);.
604
+ * </code>
605
+ *
606
+ * @return {YUI} the YUI instance.
607
+ */
608
+ use: function() {
609
+ var args = SLICE.call(arguments, 0),
610
+ callback = args[args.length - 1],
611
+ Y = this,
612
+ key;
613
+
614
+ // The last argument supplied to use can be a load complete callback
615
+ if (Y.Lang.isFunction(callback)) {
616
+ args.pop();
617
+ } else {
618
+ callback = null;
619
+ }
620
+
621
+ if (Y._loading) {
622
+ Y._useQueue = Y._useQueue || new Y.Queue();
623
+ Y._useQueue.add([args, callback]);
624
+ } else {
625
+ key = args.join();
626
+
627
+ if (Y.config.cacheUse && Y.Env.serviced[key]) {
628
+ Y.log('already provisioned: ' + key, 'info', 'yui');
629
+ Y._notify(callback, ALREADY_DONE, args);
630
+ } else {
631
+ Y._use(args, function(Y, response) {
632
+ if (Y.config.cacheUse) {
633
+ Y.log('caching request: ' + key, 'info', 'yui');
634
+ Y.Env.serviced[key] = true;
635
+ }
636
+ Y._notify(callback, response, args);
637
+ });
638
+ }
639
+ }
640
+
641
+ return Y;
642
+ },
643
+
644
+ _notify: function(callback, response, args) {
645
+ if (!response.success && this.config.loadErrorFn) {
646
+ this.config.loadErrorFn.call(this, this, callback, response, args);
647
+ } else if (callback) {
648
+ try {
649
+ callback(this, response);
650
+ } catch (e) {
651
+ this.error('use callback error', e, args);
652
+ }
653
+ }
654
+ },
655
+
656
+ _use: function(args, callback) {
657
+
658
+ if (!this.Array) {
659
+ this._attach(['yui-base']);
660
+ }
661
+
662
+ var len, loader, handleBoot,
663
+ Y = this,
664
+ G_ENV = YUI.Env,
665
+ mods = G_ENV.mods,
666
+ Env = Y.Env,
667
+ used = Env._used,
668
+ queue = G_ENV._loaderQueue,
669
+ firstArg = args[0],
670
+ YArray = Y.Array,
671
+ config = Y.config,
672
+ boot = config.bootstrap,
673
+ missing = [],
674
+ r = [],
675
+ ret = true,
676
+ fetchCSS = config.fetchCSS,
677
+ process = function(names, skip) {
678
+
679
+ if (!names.length) {
680
+ return;
681
+ }
682
+
683
+ YArray.each(names, function(name) {
684
+
685
+ // add this module to full list of things to attach
686
+ if (!skip) {
687
+ r.push(name);
688
+ }
689
+
690
+ // only attach a module once
691
+ if (used[name]) {
692
+ return;
693
+ }
694
+
695
+ var m = mods[name], req, use;
696
+
697
+ if (m) {
698
+ used[name] = true;
699
+ req = m.details.requires;
700
+ use = m.details.use;
701
+ } else {
702
+ // CSS files don't register themselves, see if it has
703
+ // been loaded
704
+ if (!G_ENV._loaded[VERSION][name]) {
705
+ missing.push(name);
706
+ } else {
707
+ used[name] = true; // probably css
708
+ }
709
+ }
710
+
711
+ // make sure requirements are attached
712
+ if (req && req.length) {
713
+ process(req);
714
+ }
715
+
716
+ // make sure we grab the submodule dependencies too
717
+ if (use && use.length) {
718
+ process(use, 1);
719
+ }
720
+ });
721
+ },
722
+
723
+ handleLoader = function(fromLoader) {
724
+ var response = fromLoader || {
725
+ success: true,
726
+ msg: 'not dynamic'
727
+ },
728
+ redo, origMissing,
729
+ ret = true,
730
+ data = response.data;
731
+
732
+
733
+ Y._loading = false;
734
+
735
+ if (data) {
736
+ origMissing = missing;
737
+ missing = [];
738
+ r = [];
739
+ process(data);
740
+ redo = missing.length;
741
+ if (redo) {
742
+ if (missing.sort().join() ==
743
+ origMissing.sort().join()) {
744
+ redo = false;
745
+ }
746
+ }
747
+ }
748
+
749
+ if (redo && data) {
750
+ Y._loading = false;
751
+ Y._use(args, function() {
752
+ Y.log('Nested use callback: ' + data, 'info', 'yui');
753
+ if (Y._attach(data)) {
754
+ Y._notify(callback, response, data);
755
+ }
756
+ });
757
+ } else {
758
+ if (data) {
759
+ // Y.log('attaching from loader: ' + data, 'info', 'yui');
760
+ ret = Y._attach(data);
761
+ }
762
+ if (ret) {
763
+ Y._notify(callback, response, args);
764
+ }
765
+ }
766
+
767
+ if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
768
+ Y._use.apply(Y, Y._useQueue.next());
769
+ }
770
+
771
+ };
772
+
773
+ // Y.log(Y.id + ': use called: ' + a + ' :: ' + callback, 'info', 'yui');
774
+
775
+ // YUI().use('*'); // bind everything available
776
+ if (firstArg === '*') {
777
+ ret = Y._attach(Y.Object.keys(mods));
778
+ if (ret) {
779
+ handleLoader();
780
+ }
781
+ return Y;
782
+ }
783
+
784
+ // Y.log('before loader requirements: ' + args, 'info', 'yui');
785
+
786
+ // use loader to expand dependencies and sort the
787
+ // requirements if it is available.
788
+ if (boot && Y.Loader && args.length) {
789
+ loader = getLoader(Y);
790
+ loader.require(args);
791
+ loader.ignoreRegistered = true;
792
+ loader.calculate(null, (fetchCSS) ? null : 'js');
793
+ args = loader.sorted;
794
+ }
795
+
796
+ // process each requirement and any additional requirements
797
+ // the module metadata specifies
798
+ process(args);
799
+
800
+ len = missing.length;
801
+
802
+ if (len) {
803
+ missing = Y.Object.keys(YArray.hash(missing));
804
+ len = missing.length;
805
+ Y.log('Modules missing: ' + missing + ', ' + missing.length, 'info', 'yui');
806
+ }
807
+
808
+ // dynamic load
809
+ if (boot && len && Y.Loader) {
810
+ // Y.log('Using loader to fetch missing deps: ' + missing, 'info', 'yui');
811
+ Y.log('Using Loader', 'info', 'yui');
812
+ Y._loading = true;
813
+ loader = getLoader(Y);
814
+ loader.onEnd = handleLoader;
815
+ loader.context = Y;
816
+ loader.data = args;
817
+ loader.ignoreRegistered = false;
818
+ loader.require(args);
819
+ loader.insert(null, (fetchCSS) ? null : 'js');
820
+ // loader.partial(missing, (fetchCSS) ? null : 'js');
821
+
822
+ } else if (len && Y.config.use_rls) {
823
+
824
+ // server side loader service
825
+ Y.Get.script(Y._rls(args), {
826
+ onEnd: function(o) {
827
+ handleLoader(o);
828
+ },
829
+ data: args
830
+ });
831
+
832
+ } else if (boot && len && Y.Get && !Env.bootstrapped) {
833
+
834
+ Y._loading = true;
835
+
836
+ handleBoot = function() {
837
+ Y._loading = false;
838
+ queue.running = false;
839
+ Env.bootstrapped = true;
840
+ if (Y._attach(['loader'])) {
841
+ Y._use(args, callback);
842
+ }
843
+ };
844
+
845
+ if (G_ENV._bootstrapping) {
846
+ Y.log('Waiting for loader', 'info', 'yui');
847
+ queue.add(handleBoot);
848
+ } else {
849
+ G_ENV._bootstrapping = true;
850
+ Y.log('Fetching loader: ' + config.base + config.loaderPath, 'info', 'yui');
851
+ Y.Get.script(config.base + config.loaderPath, {
852
+ onEnd: handleBoot
853
+ });
854
+ }
855
+
856
+ } else {
857
+ Y.log('Attaching available dependencies: ' + args, 'info', 'yui');
858
+ ret = Y._attach(args);
859
+ if (ret) {
860
+ handleLoader();
861
+ }
862
+ }
863
+
864
+ return Y;
865
+ },
866
+
867
+
868
+ /**
869
+ * Returns the namespace specified and creates it if it doesn't exist
870
+ * <pre>
871
+ * YUI.namespace("property.package");
872
+ * YUI.namespace("YAHOO.property.package");
873
+ * </pre>
874
+ * Either of the above would create YUI.property, then
875
+ * YUI.property.package (YAHOO is scrubbed out, this is
876
+ * to remain compatible with YUI2)
877
+ *
878
+ * Be careful when naming packages. Reserved words may work in some browsers
879
+ * and not others. For instance, the following will fail in Safari:
880
+ * <pre>
881
+ * YUI.namespace("really.long.nested.namespace");
882
+ * </pre>
883
+ * This fails because "long" is a future reserved word in ECMAScript
884
+ *
885
+ * @method namespace
886
+ * @param {string*} arguments 1-n namespaces to create.
887
+ * @return {object} A reference to the last namespace object created.
888
+ */
889
+ namespace: function() {
890
+ var a = arguments, o = this, i = 0, j, d, arg;
891
+ for (; i < a.length; i++) {
892
+ // d = ('' + a[i]).split('.');
893
+ arg = a[i];
894
+ if (arg.indexOf(PERIOD)) {
895
+ d = arg.split(PERIOD);
896
+ for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
897
+ o[d[j]] = o[d[j]] || {};
898
+ o = o[d[j]];
899
+ }
900
+ } else {
901
+ o[arg] = o[arg] || {};
902
+ }
903
+ }
904
+ return o;
905
+ },
906
+
907
+ // this is replaced if the log module is included
908
+ log: NOOP,
909
+ message: NOOP,
910
+
911
+ /**
912
+ * Report an error. The reporting mechanism is controled by
913
+ * the 'throwFail' configuration attribute. If throwFail is
914
+ * not specified, the message is written to the Logger, otherwise
915
+ * a JS error is thrown
916
+ * @method error
917
+ * @param msg {string} the error message.
918
+ * @param e {Error|string} Optional JS error that was caught, or an error string.
919
+ * @param data Optional additional info
920
+ * and throwFail is specified, this error will be re-thrown.
921
+ * @return {YUI} this YUI instance.
922
+ */
923
+ error: function(msg, e, data) {
924
+
925
+ var Y = this, ret;
926
+
927
+ if (Y.config.errorFn) {
928
+ ret = Y.config.errorFn.apply(Y, arguments);
929
+ }
930
+
931
+ if (Y.config.throwFail && !ret) {
932
+ throw (e || new Error(msg));
933
+ } else {
934
+ Y.message(msg, 'error'); // don't scrub this one
935
+ }
936
+
937
+ return Y;
938
+ },
939
+
940
+ /**
941
+ * Generate an id that is unique among all YUI instances
942
+ * @method guid
943
+ * @param pre {string} optional guid prefix.
944
+ * @return {string} the guid.
945
+ */
946
+ guid: function(pre) {
947
+ var id = this.Env._guidp + (++this.Env._uidx);
948
+ return (pre) ? (pre + id) : id;
949
+ },
950
+
951
+ /**
952
+ * Returns a guid associated with an object. If the object
953
+ * does not have one, a new one is created unless readOnly
954
+ * is specified.
955
+ * @method stamp
956
+ * @param o The object to stamp.
957
+ * @param readOnly {boolean} if true, a valid guid will only
958
+ * be returned if the object has one assigned to it.
959
+ * @return {string} The object's guid or null.
960
+ */
961
+ stamp: function(o, readOnly) {
962
+ var uid;
963
+ if (!o) {
964
+ return o;
965
+ }
966
+
967
+ // IE generates its own unique ID for dom nodes
968
+ // The uniqueID property of a document node returns a new ID
969
+ if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
970
+ uid = o.uniqueID;
971
+ } else {
972
+ uid = (typeof o === 'string') ? o : o._yuid;
973
+ }
974
+
975
+ if (!uid) {
976
+ uid = this.guid();
977
+ if (!readOnly) {
978
+ try {
979
+ o._yuid = uid;
980
+ } catch (e) {
981
+ uid = null;
982
+ }
983
+ }
984
+ }
985
+ return uid;
986
+ },
987
+
988
+ /**
989
+ * Destroys the YUI instance
990
+ * @method destroy
991
+ * @since 3.3.0
992
+ */
993
+ destroy: function() {
994
+ var Y = this;
995
+ if (Y.Event) {
996
+ Y.Event._unload();
997
+ }
998
+ delete instances[Y.id];
999
+ delete Y.Env;
1000
+ delete Y.config;
1001
+ }
1002
+
1003
+ /**
1004
+ * instanceof check for objects that works around
1005
+ * memory leak in IE when the item tested is
1006
+ * window/document
1007
+ * @method instanceOf
1008
+ * @since 3.3.0
1009
+ */
1010
+ };
1011
+
1012
+
1013
+
1014
+ YUI.prototype = proto;
1015
+
1016
+ // inheritance utilities are not available yet
1017
+ for (prop in proto) {
1018
+ if (proto.hasOwnProperty(prop)) {
1019
+ YUI[prop] = proto[prop];
1020
+ }
1021
+ }
1022
+
1023
+ // set up the environment
1024
+ YUI._init();
1025
+
1026
+ if (hasWin) {
1027
+ // add a window load event at load time so we can capture
1028
+ // the case where it fires before dynamic loading is
1029
+ // complete.
1030
+ add(window, 'load', handleLoad);
1031
+ } else {
1032
+ handleLoad();
1033
+ }
1034
+
1035
+ YUI.Env.add = add;
1036
+ YUI.Env.remove = remove;
1037
+
1038
+ /*global exports*/
1039
+ // Support the CommonJS method for exporting our single global
1040
+ if (typeof exports == 'object') {
1041
+ exports.YUI = YUI;
1042
+ }
1043
+
1044
+ }());
1045
+
1046
+
1047
+ /**
1048
+ * The config object contains all of the configuration options for
1049
+ * the YUI instance. This object is supplied by the implementer
1050
+ * when instantiating a YUI instance. Some properties have default
1051
+ * values if they are not supplied by the implementer. This should
1052
+ * not be updated directly because some values are cached. Use
1053
+ * applyConfig() to update the config object on a YUI instance that
1054
+ * has already been configured.
1055
+ *
1056
+ * @class config
1057
+ * @static
1058
+ */
1059
+
1060
+ /**
1061
+ * Allows the YUI seed file to fetch the loader component and library
1062
+ * metadata to dynamically load additional dependencies.
1063
+ *
1064
+ * @property bootstrap
1065
+ * @type boolean
1066
+ * @default true
1067
+ */
1068
+
1069
+ /**
1070
+ * Log to the browser console if debug is on and the browser has a
1071
+ * supported console.
1072
+ *
1073
+ * @property useBrowserConsole
1074
+ * @type boolean
1075
+ * @default true
1076
+ */
1077
+
1078
+ /**
1079
+ * A hash of log sources that should be logged. If specified, only
1080
+ * log messages from these sources will be logged.
1081
+ *
1082
+ * @property logInclude
1083
+ * @type object
1084
+ */
1085
+
1086
+ /**
1087
+ * A hash of log sources that should be not be logged. If specified,
1088
+ * all sources are logged if not on this list.
1089
+ *
1090
+ * @property logExclude
1091
+ * @type object
1092
+ */
1093
+
1094
+ /**
1095
+ * Set to true if the yui seed file was dynamically loaded in
1096
+ * order to bootstrap components relying on the window load event
1097
+ * and the 'domready' custom event.
1098
+ *
1099
+ * @property injected
1100
+ * @type boolean
1101
+ * @default false
1102
+ */
1103
+
1104
+ /**
1105
+ * If throwFail is set, Y.error will generate or re-throw a JS Error.
1106
+ * Otherwise the failure is logged.
1107
+ *
1108
+ * @property throwFail
1109
+ * @type boolean
1110
+ * @default true
1111
+ */
1112
+
1113
+ /**
1114
+ * The window/frame that this instance should operate in.
1115
+ *
1116
+ * @property win
1117
+ * @type Window
1118
+ * @default the window hosting YUI
1119
+ */
1120
+
1121
+ /**
1122
+ * The document associated with the 'win' configuration.
1123
+ *
1124
+ * @property doc
1125
+ * @type Document
1126
+ * @default the document hosting YUI
1127
+ */
1128
+
1129
+ /**
1130
+ * A list of modules that defines the YUI core (overrides the default).
1131
+ *
1132
+ * @property core
1133
+ * @type string[]
1134
+ */
1135
+
1136
+ /**
1137
+ * A list of languages in order of preference. This list is matched against
1138
+ * the list of available languages in modules that the YUI instance uses to
1139
+ * determine the best possible localization of language sensitive modules.
1140
+ * Languages are represented using BCP 47 language tags, such as "en-GB" for
1141
+ * English as used in the United Kingdom, or "zh-Hans-CN" for simplified
1142
+ * Chinese as used in China. The list can be provided as a comma-separated
1143
+ * list or as an array.
1144
+ *
1145
+ * @property lang
1146
+ * @type string|string[]
1147
+ */
1148
+
1149
+ /**
1150
+ * The default date format
1151
+ * @property dateFormat
1152
+ * @type string
1153
+ * @deprecated use configuration in DataType.Date.format() instead.
1154
+ */
1155
+
1156
+ /**
1157
+ * The default locale
1158
+ * @property locale
1159
+ * @type string
1160
+ * @deprecated use config.lang instead.
1161
+ */
1162
+
1163
+ /**
1164
+ * The default interval when polling in milliseconds.
1165
+ * @property pollInterval
1166
+ * @type int
1167
+ * @default 20
1168
+ */
1169
+
1170
+ /**
1171
+ * The number of dynamic nodes to insert by default before
1172
+ * automatically removing them. This applies to script nodes
1173
+ * because remove the node will not make the evaluated script
1174
+ * unavailable. Dynamic CSS is not auto purged, because removing
1175
+ * a linked style sheet will also remove the style definitions.
1176
+ * @property purgethreshold
1177
+ * @type int
1178
+ * @default 20
1179
+ */
1180
+
1181
+ /**
1182
+ * The default interval when polling in milliseconds.
1183
+ * @property windowResizeDelay
1184
+ * @type int
1185
+ * @default 40
1186
+ */
1187
+
1188
+ /**
1189
+ * Base directory for dynamic loading
1190
+ * @property base
1191
+ * @type string
1192
+ */
1193
+
1194
+ /*
1195
+ * The secure base dir (not implemented)
1196
+ * For dynamic loading.
1197
+ * @property secureBase
1198
+ * @type string
1199
+ */
1200
+
1201
+ /**
1202
+ * The YUI combo service base dir. Ex: http://yui.yahooapis.com/combo?
1203
+ * For dynamic loading.
1204
+ * @property comboBase
1205
+ * @type string
1206
+ */
1207
+
1208
+ /**
1209
+ * The root path to prepend to module path for the combo service.
1210
+ * Ex: 3.0.0b1/build/
1211
+ * For dynamic loading.
1212
+ * @property root
1213
+ * @type string
1214
+ */
1215
+
1216
+ /**
1217
+ * A filter to apply to result urls. This filter will modify the default
1218
+ * path for all modules. The default path for the YUI library is the
1219
+ * minified version of the files (e.g., event-min.js). The filter property
1220
+ * can be a predefined filter or a custom filter. The valid predefined
1221
+ * filters are:
1222
+ * <dl>
1223
+ * <dt>DEBUG</dt>
1224
+ * <dd>Selects the debug versions of the library (e.g., event-debug.js).
1225
+ * This option will automatically include the Logger widget</dd>
1226
+ * <dt>RAW</dt>
1227
+ * <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
1228
+ * </dl>
1229
+ * You can also define a custom filter, which must be an object literal
1230
+ * containing a search expression and a replace string:
1231
+ * <pre>
1232
+ * myFilter: &#123;
1233
+ * 'searchExp': "-min\\.js",
1234
+ * 'replaceStr': "-debug.js"
1235
+ * &#125;
1236
+ * </pre>
1237
+ *
1238
+ * For dynamic loading.
1239
+ *
1240
+ * @property filter
1241
+ * @type string|object
1242
+ */
1243
+
1244
+ /**
1245
+ * The 'skin' config let's you configure application level skin
1246
+ * customizations. It contains the following attributes which
1247
+ * can be specified to override the defaults:
1248
+ *
1249
+ * // The default skin, which is automatically applied if not
1250
+ * // overriden by a component-specific skin definition.
1251
+ * // Change this in to apply a different skin globally
1252
+ * defaultSkin: 'sam',
1253
+ *
1254
+ * // This is combined with the loader base property to get
1255
+ * // the default root directory for a skin.
1256
+ * base: 'assets/skins/',
1257
+ *
1258
+ * // Any component-specific overrides can be specified here,
1259
+ * // making it possible to load different skins for different
1260
+ * // components. It is possible to load more than one skin
1261
+ * // for a given component as well.
1262
+ * overrides: {
1263
+ * slider: ['capsule', 'round']
1264
+ * }
1265
+ *
1266
+ * For dynamic loading.
1267
+ *
1268
+ * @property skin
1269
+ */
1270
+
1271
+ /**
1272
+ * Hash of per-component filter specification. If specified for a given
1273
+ * component, this overrides the filter config.
1274
+ *
1275
+ * For dynamic loading.
1276
+ *
1277
+ * @property filters
1278
+ */
1279
+
1280
+ /**
1281
+ * Use the YUI combo service to reduce the number of http connections
1282
+ * required to load your dependencies. Turning this off will
1283
+ * disable combo handling for YUI and all module groups configured
1284
+ * with a combo service.
1285
+ *
1286
+ * For dynamic loading.
1287
+ *
1288
+ * @property combine
1289
+ * @type boolean
1290
+ * @default true if 'base' is not supplied, false if it is.
1291
+ */
1292
+
1293
+ /**
1294
+ * A list of modules that should never be dynamically loaded
1295
+ *
1296
+ * @property ignore
1297
+ * @type string[]
1298
+ */
1299
+
1300
+ /**
1301
+ * A list of modules that should always be loaded when required, even if already
1302
+ * present on the page.
1303
+ *
1304
+ * @property force
1305
+ * @type string[]
1306
+ */
1307
+
1308
+ /**
1309
+ * Node or id for a node that should be used as the insertion point for new
1310
+ * nodes. For dynamic loading.
1311
+ *
1312
+ * @property insertBefore
1313
+ * @type string
1314
+ */
1315
+
1316
+ /**
1317
+ * Object literal containing attributes to add to dynamically loaded script
1318
+ * nodes.
1319
+ * @property jsAttributes
1320
+ * @type string
1321
+ */
1322
+
1323
+ /**
1324
+ * Object literal containing attributes to add to dynamically loaded link
1325
+ * nodes.
1326
+ * @property cssAttributes
1327
+ * @type string
1328
+ */
1329
+
1330
+ /**
1331
+ * Number of milliseconds before a timeout occurs when dynamically
1332
+ * loading nodes. If not set, there is no timeout.
1333
+ * @property timeout
1334
+ * @type int
1335
+ */
1336
+
1337
+ /**
1338
+ * Callback for the 'CSSComplete' event. When dynamically loading YUI
1339
+ * components with CSS, this property fires when the CSS is finished
1340
+ * loading but script loading is still ongoing. This provides an
1341
+ * opportunity to enhance the presentation of a loading page a little
1342
+ * bit before the entire loading process is done.
1343
+ *
1344
+ * @property onCSS
1345
+ * @type function
1346
+ */
1347
+
1348
+ /**
1349
+ * A hash of module definitions to add to the list of YUI components.
1350
+ * These components can then be dynamically loaded side by side with
1351
+ * YUI via the use() method. This is a hash, the key is the module
1352
+ * name, and the value is an object literal specifying the metdata
1353
+ * for the module. * See Loader.addModule for the supported module
1354
+ * metadata fields. Also @see groups, which provides a way to
1355
+ * configure the base and combo spec for a set of modules.
1356
+ * <code>
1357
+ * modules: {
1358
+ * &nbsp; mymod1: {
1359
+ * &nbsp; requires: ['node'],
1360
+ * &nbsp; fullpath: 'http://myserver.mydomain.com/mymod1/mymod1.js'
1361
+ * &nbsp; },
1362
+ * &nbsp; mymod2: {
1363
+ * &nbsp; requires: ['mymod1'],
1364
+ * &nbsp; fullpath: 'http://myserver.mydomain.com/mymod2/mymod2.js'
1365
+ * &nbsp; }
1366
+ * }
1367
+ * </code>
1368
+ *
1369
+ * @property modules
1370
+ * @type object
1371
+ */
1372
+
1373
+ /**
1374
+ * A hash of module group definitions. It for each group you
1375
+ * can specify a list of modules and the base path and
1376
+ * combo spec to use when dynamically loading the modules. @see
1377
+ * @see modules for the details about the modules part of the
1378
+ * group definition.
1379
+ * <code>
1380
+ * &nbsp; groups: {
1381
+ * &nbsp; yui2: {
1382
+ * &nbsp; // specify whether or not this group has a combo service
1383
+ * &nbsp; combine: true,
1384
+ * &nbsp;
1385
+ * &nbsp; // the base path for non-combo paths
1386
+ * &nbsp; base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1387
+ * &nbsp;
1388
+ * &nbsp; // the path to the combo service
1389
+ * &nbsp; comboBase: 'http://yui.yahooapis.com/combo?',
1390
+ * &nbsp;
1391
+ * &nbsp; // a fragment to prepend to the path attribute when
1392
+ * &nbsp; // when building combo urls
1393
+ * &nbsp; root: '2.8.0r4/build/',
1394
+ * &nbsp;
1395
+ * &nbsp; // the module definitions
1396
+ * &nbsp; modules: {
1397
+ * &nbsp; yui2_yde: {
1398
+ * &nbsp; path: "yahoo-dom-event/yahoo-dom-event.js"
1399
+ * &nbsp; },
1400
+ * &nbsp; yui2_anim: {
1401
+ * &nbsp; path: "animation/animation.js",
1402
+ * &nbsp; requires: ['yui2_yde']
1403
+ * &nbsp; }
1404
+ * &nbsp; }
1405
+ * &nbsp; }
1406
+ * &nbsp; }
1407
+ * </code>
1408
+ * @property modules
1409
+ * @type object
1410
+ */
1411
+
1412
+ /**
1413
+ * The loader 'path' attribute to the loader itself. This is combined
1414
+ * with the 'base' attribute to dynamically load the loader component
1415
+ * when boostrapping with the get utility alone.
1416
+ *
1417
+ * @property loaderPath
1418
+ * @type string
1419
+ * @default loader/loader-min.js
1420
+ */
1421
+
1422
+ /**
1423
+ * Specifies whether or not YUI().use(...) will attempt to load CSS
1424
+ * resources at all. Any truthy value will cause CSS dependencies
1425
+ * to load when fetching script. The special value 'force' will
1426
+ * cause CSS dependencies to be loaded even if no script is needed.
1427
+ *
1428
+ * @property fetchCSS
1429
+ * @type boolean|string
1430
+ * @default true
1431
+ */
1432
+
1433
+ /**
1434
+ * The default gallery version to build gallery module urls
1435
+ * @property gallery
1436
+ * @type string
1437
+ * @since 3.1.0
1438
+ */
1439
+
1440
+ /**
1441
+ * The default YUI 2 version to build yui2 module urls. This is for
1442
+ * intrinsic YUI 2 support via the 2in3 project. Also @see the '2in3'
1443
+ * config for pulling different revisions of the wrapped YUI 2
1444
+ * modules.
1445
+ * @since 3.1.0
1446
+ * @property yui2
1447
+ * @type string
1448
+ * @default 2.8.1
1449
+ */
1450
+
1451
+ /**
1452
+ * The 2in3 project is a deployment of the various versions of YUI 2
1453
+ * deployed as first-class YUI 3 modules. Eventually, the wrapper
1454
+ * for the modules will change (but the underlying YUI 2 code will
1455
+ * be the same), and you can select a particular version of
1456
+ * the wrapper modules via this config.
1457
+ * @since 3.1.0
1458
+ * @property 2in3
1459
+ * @type string
1460
+ * @default 1
1461
+ */
1462
+
1463
+ /**
1464
+ * Alternative console log function for use in environments without
1465
+ * a supported native console. The function is executed in the
1466
+ * YUI instance context.
1467
+ * @since 3.1.0
1468
+ * @property logFn
1469
+ * @type Function
1470
+ */
1471
+
1472
+ /**
1473
+ * A callback to execute when Y.error is called. It receives the
1474
+ * error message and an javascript error object if Y.error was
1475
+ * executed because a javascript error was caught. The function
1476
+ * is executed in the YUI instance context.
1477
+ *
1478
+ * @since 3.2.0
1479
+ * @property errorFn
1480
+ * @type Function
1481
+ */
1482
+
1483
+ /**
1484
+ * A callback to execute when the loader fails to load one or
1485
+ * more resource. This could be because of a script load
1486
+ * failure. It can also fail if a javascript module fails
1487
+ * to register itself, but only when the 'requireRegistration'
1488
+ * is true. If this function is defined, the use() callback will
1489
+ * only be called when the loader succeeds, otherwise it always
1490
+ * executes unless there was a javascript error when attaching
1491
+ * a module.
1492
+ *
1493
+ * @since 3.3.0
1494
+ * @property loadErrorFn
1495
+ * @type Function
1496
+ */
1497
+
1498
+ /**
1499
+ * When set to true, the YUI loader will expect that all modules
1500
+ * it is responsible for loading will be first-class YUI modules
1501
+ * that register themselves with the YUI global. If this is
1502
+ * set to true, loader will fail if the module registration fails
1503
+ * to happen after the script is loaded.
1504
+ *
1505
+ * @since 3.3.0
1506
+ * @property requireRegistration
1507
+ * @type boolean
1508
+ * @default false
1509
+ */
1510
+
1511
+ /**
1512
+ * Cache serviced use() requests.
1513
+ * @since 3.3.0
1514
+ * @property cacheUse
1515
+ * @type boolean
1516
+ * @default true
1517
+ */
1518
+
1519
+ /**
1520
+ * The parameter defaults for the remote loader service.
1521
+ * Requires the rls submodule. The properties that are
1522
+ * supported:
1523
+ * <pre>
1524
+ * m: comma separated list of module requirements. This
1525
+ * must be the param name even for custom implemetations.
1526
+ * v: the version of YUI to load. Defaults to the version
1527
+ * of YUI that is being used.
1528
+ * gv: the version of the gallery to load (@see the gallery config)
1529
+ * env: comma separated list of modules already on the page.
1530
+ * this must be the param name even for custom implemetations.
1531
+ * lang: the languages supported on the page (@see the lang config)
1532
+ * '2in3v': the version of the 2in3 wrapper to use (@see the 2in3 config).
1533
+ * '2v': the version of yui2 to use in the yui 2in3 wrappers
1534
+ * (@see the yui2 config)
1535
+ * filt: a filter def to apply to the urls (@see the filter config).
1536
+ * filts: a list of custom filters to apply per module
1537
+ * (@see the filters config).
1538
+ * tests: this is a map of conditional module test function id keys
1539
+ * with the values of 1 if the test passes, 0 if not. This must be
1540
+ * the name of the querystring param in custom templates.
1541
+ *</pre>
1542
+ *
1543
+ * @since 3.2.0
1544
+ * @property rls
1545
+ */
1546
+
1547
+ /**
1548
+ * The base path to the remote loader service
1549
+ *
1550
+ * @since 3.2.0
1551
+ * @property rls_base
1552
+ */
1553
+
1554
+ /**
1555
+ * The template to use for building the querystring portion
1556
+ * of the remote loader service url. The default is determined
1557
+ * by the rls config -- each property that has a value will be
1558
+ * represented.
1559
+ *
1560
+ * ex: m={m}&v={v}&env={env}&lang={lang}&filt={filt}&tests={tests}
1561
+ *
1562
+ *
1563
+ * @since 3.2.0
1564
+ * @property rls_tmpl
1565
+ */
1566
+
1567
+ /**
1568
+ * Configure the instance to use a remote loader service instead of
1569
+ * the client loader.
1570
+ *
1571
+ * @since 3.2.0
1572
+ * @property use_rls
1573
+ */
1574
+ YUI.add('yui-base', function(Y) {
1575
+
1576
+ /*
1577
+ * YUI stub
1578
+ * @module yui
1579
+ * @submodule yui-base
1580
+ */
1581
+ /**
1582
+ * The YUI module contains the components required for building the YUI
1583
+ * seed file. This includes the script loading mechanism, a simple queue,
1584
+ * and the core utilities for the library.
1585
+ * @module yui
1586
+ * @submodule yui-base
1587
+ */
1588
+
1589
+ /**
1590
+ * Provides the language utilites and extensions used by the library
1591
+ * @class Lang
1592
+ * @static
1593
+ */
1594
+ Y.Lang = Y.Lang || {};
1595
+
1596
+ var L = Y.Lang,
1597
+
1598
+ ARRAY = 'array',
1599
+ BOOLEAN = 'boolean',
1600
+ DATE = 'date',
1601
+ ERROR = 'error',
1602
+ FUNCTION = 'function',
1603
+ NUMBER = 'number',
1604
+ NULL = 'null',
1605
+ OBJECT = 'object',
1606
+ REGEX = 'regexp',
1607
+ STRING = 'string',
1608
+ STRING_PROTO = String.prototype,
1609
+ TOSTRING = Object.prototype.toString,
1610
+ UNDEFINED = 'undefined',
1611
+
1612
+ TYPES = {
1613
+ 'undefined' : UNDEFINED,
1614
+ 'number' : NUMBER,
1615
+ 'boolean' : BOOLEAN,
1616
+ 'string' : STRING,
1617
+ '[object Function]' : FUNCTION,
1618
+ '[object RegExp]' : REGEX,
1619
+ '[object Array]' : ARRAY,
1620
+ '[object Date]' : DATE,
1621
+ '[object Error]' : ERROR
1622
+ },
1623
+
1624
+ TRIMREGEX = /^\s+|\s+$/g,
1625
+ EMPTYSTRING = '',
1626
+ SUBREGEX = /\{\s*([^\|\}]+?)\s*(?:\|([^\}]*))?\s*\}/g;
1627
+
1628
+ /**
1629
+ * Determines whether or not the provided item is an array.
1630
+ * Returns false for array-like collections such as the
1631
+ * function arguments collection or HTMLElement collection
1632
+ * will return false. Use <code>Y.Array.test</code> if you
1633
+ * want to test for an array-like collection.
1634
+ * @method isArray
1635
+ * @static
1636
+ * @param o The object to test.
1637
+ * @return {boolean} true if o is an array.
1638
+ */
1639
+ // L.isArray = Array.isArray || function(o) {
1640
+ // return L.type(o) === ARRAY;
1641
+ // };
1642
+
1643
+ L.isArray = function(o) {
1644
+ return L.type(o) === ARRAY;
1645
+ };
1646
+
1647
+ /**
1648
+ * Determines whether or not the provided item is a boolean.
1649
+ * @method isBoolean
1650
+ * @static
1651
+ * @param o The object to test.
1652
+ * @return {boolean} true if o is a boolean.
1653
+ */
1654
+ L.isBoolean = function(o) {
1655
+ return typeof o === BOOLEAN;
1656
+ };
1657
+
1658
+ /**
1659
+ * <p>
1660
+ * Determines whether or not the provided item is a function.
1661
+ * Note: Internet Explorer thinks certain functions are objects:
1662
+ * </p>
1663
+ *
1664
+ * <pre>
1665
+ * var obj = document.createElement("object");
1666
+ * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1667
+ * &nbsp;
1668
+ * var input = document.createElement("input"); // append to body
1669
+ * Y.Lang.isFunction(input.focus) // reports false in IE
1670
+ * </pre>
1671
+ *
1672
+ * <p>
1673
+ * You will have to implement additional tests if these functions
1674
+ * matter to you.
1675
+ * </p>
1676
+ *
1677
+ * @method isFunction
1678
+ * @static
1679
+ * @param o The object to test.
1680
+ * @return {boolean} true if o is a function.
1681
+ */
1682
+ L.isFunction = function(o) {
1683
+ return L.type(o) === FUNCTION;
1684
+ };
1685
+
1686
+ /**
1687
+ * Determines whether or not the supplied item is a date instance.
1688
+ * @method isDate
1689
+ * @static
1690
+ * @param o The object to test.
1691
+ * @return {boolean} true if o is a date.
1692
+ */
1693
+ L.isDate = function(o) {
1694
+ // return o instanceof Date;
1695
+ return L.type(o) === DATE && o.toString() !== 'Invalid Date' && !isNaN(o);
1696
+ };
1697
+
1698
+ /**
1699
+ * Determines whether or not the provided item is null.
1700
+ * @method isNull
1701
+ * @static
1702
+ * @param o The object to test.
1703
+ * @return {boolean} true if o is null.
1704
+ */
1705
+ L.isNull = function(o) {
1706
+ return o === null;
1707
+ };
1708
+
1709
+ /**
1710
+ * Determines whether or not the provided item is a legal number.
1711
+ * @method isNumber
1712
+ * @static
1713
+ * @param o The object to test.
1714
+ * @return {boolean} true if o is a number.
1715
+ */
1716
+ L.isNumber = function(o) {
1717
+ return typeof o === NUMBER && isFinite(o);
1718
+ };
1719
+
1720
+ /**
1721
+ * Determines whether or not the provided item is of type object
1722
+ * or function. Note that arrays are also objects, so
1723
+ * <code>Y.Lang.isObject([]) === true</code>.
1724
+ * @method isObject
1725
+ * @static
1726
+ * @param o The object to test.
1727
+ * @param failfn {boolean} fail if the input is a function.
1728
+ * @return {boolean} true if o is an object.
1729
+ */
1730
+ L.isObject = function(o, failfn) {
1731
+ var t = typeof o;
1732
+ return (o && (t === OBJECT ||
1733
+ (!failfn && (t === FUNCTION || L.isFunction(o))))) || false;
1734
+ };
1735
+
1736
+ /**
1737
+ * Determines whether or not the provided item is a string.
1738
+ * @method isString
1739
+ * @static
1740
+ * @param o The object to test.
1741
+ * @return {boolean} true if o is a string.
1742
+ */
1743
+ L.isString = function(o) {
1744
+ return typeof o === STRING;
1745
+ };
1746
+
1747
+ /**
1748
+ * Determines whether or not the provided item is undefined.
1749
+ * @method isUndefined
1750
+ * @static
1751
+ * @param o The object to test.
1752
+ * @return {boolean} true if o is undefined.
1753
+ */
1754
+ L.isUndefined = function(o) {
1755
+ return typeof o === UNDEFINED;
1756
+ };
1757
+
1758
+ /**
1759
+ * Returns a string without any leading or trailing whitespace. If
1760
+ * the input is not a string, the input will be returned untouched.
1761
+ * @method trim
1762
+ * @static
1763
+ * @param s {string} the string to trim.
1764
+ * @return {string} the trimmed string.
1765
+ */
1766
+ L.trim = STRING_PROTO.trim ? function(s) {
1767
+ return (s && s.trim) ? s.trim() : s;
1768
+ } : function (s) {
1769
+ try {
1770
+ return s.replace(TRIMREGEX, EMPTYSTRING);
1771
+ } catch (e) {
1772
+ return s;
1773
+ }
1774
+ };
1775
+
1776
+ /**
1777
+ * Returns a string without any leading whitespace.
1778
+ * @method trimLeft
1779
+ * @static
1780
+ * @param s {string} the string to trim.
1781
+ * @return {string} the trimmed string.
1782
+ */
1783
+ L.trimLeft = STRING_PROTO.trimLeft ? function (s) {
1784
+ return s.trimLeft();
1785
+ } : function (s) {
1786
+ return s.replace(/^\s+/, '');
1787
+ };
1788
+
1789
+ /**
1790
+ * Returns a string without any trailing whitespace.
1791
+ * @method trimRight
1792
+ * @static
1793
+ * @param s {string} the string to trim.
1794
+ * @return {string} the trimmed string.
1795
+ */
1796
+ L.trimRight = STRING_PROTO.trimRight ? function (s) {
1797
+ return s.trimRight();
1798
+ } : function (s) {
1799
+ return s.replace(/\s+$/, '');
1800
+ };
1801
+
1802
+ /**
1803
+ * A convenience method for detecting a legitimate non-null value.
1804
+ * Returns false for null/undefined/NaN, true for other values,
1805
+ * including 0/false/''
1806
+ * @method isValue
1807
+ * @static
1808
+ * @param o The item to test.
1809
+ * @return {boolean} true if it is not null/undefined/NaN || false.
1810
+ */
1811
+ L.isValue = function(o) {
1812
+ var t = L.type(o);
1813
+ switch (t) {
1814
+ case NUMBER:
1815
+ return isFinite(o);
1816
+ case NULL:
1817
+ case UNDEFINED:
1818
+ return false;
1819
+ default:
1820
+ return !!(t);
1821
+ }
1822
+ };
1823
+
1824
+ /**
1825
+ * <p>
1826
+ * Returns a string representing the type of the item passed in.
1827
+ * </p>
1828
+ *
1829
+ * <p>
1830
+ * Known issues:
1831
+ * </p>
1832
+ *
1833
+ * <ul>
1834
+ * <li>
1835
+ * <code>typeof HTMLElementCollection</code> returns function in Safari, but
1836
+ * <code>Y.type()</code> reports object, which could be a good thing --
1837
+ * but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
1838
+ * </li>
1839
+ * </ul>
1840
+ *
1841
+ * @method type
1842
+ * @param o the item to test.
1843
+ * @return {string} the detected type.
1844
+ * @static
1845
+ */
1846
+ L.type = function(o) {
1847
+ return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? OBJECT : NULL);
1848
+ };
1849
+
1850
+ /**
1851
+ * Lightweight version of <code>Y.substitute</code>. Uses the same template
1852
+ * structure as <code>Y.substitute</code>, but doesn't support recursion,
1853
+ * auto-object coersion, or formats.
1854
+ * @method sub
1855
+ * @param {string} s String to be modified.
1856
+ * @param {object} o Object containing replacement values.
1857
+ * @return {string} the substitute result.
1858
+ * @static
1859
+ * @since 3.2.0
1860
+ */
1861
+ L.sub = function(s, o) {
1862
+ return ((s.replace) ? s.replace(SUBREGEX, function(match, key) {
1863
+ return (!L.isUndefined(o[key])) ? o[key] : match;
1864
+ }) : s);
1865
+ };
1866
+
1867
+ /**
1868
+ * Returns the current time in milliseconds.
1869
+ * @method now
1870
+ * @return {int} the current date
1871
+ * @since 3.3.0
1872
+ */
1873
+ L.now = Date.now || function () {
1874
+ return new Date().getTime();
1875
+ };
1876
+
1877
+ /**
1878
+ * The YUI module contains the components required for building the YUI seed
1879
+ * file. This includes the script loading mechanism, a simple queue, and the
1880
+ * core utilities for the library.
1881
+ * @module yui
1882
+ * @submodule yui-base
1883
+ */
1884
+
1885
+
1886
+ var Native = Array.prototype, LENGTH = 'length',
1887
+
1888
+ /**
1889
+ * Adds the following array utilities to the YUI instance. Additional
1890
+ * array helpers can be found in the collection component.
1891
+ * @class Array
1892
+ */
1893
+
1894
+ /**
1895
+ * Y.Array(o) returns an array:
1896
+ * - Arrays are return unmodified unless the start position is specified.
1897
+ * - "Array-like" collections (@see Array.test) are converted to arrays
1898
+ * - For everything else, a new array is created with the input as the sole
1899
+ * item.
1900
+ * - The start position is used if the input is or is like an array to return
1901
+ * a subset of the collection.
1902
+ *
1903
+ * @todo this will not automatically convert elements that are also
1904
+ * collections such as forms and selects. Passing true as the third
1905
+ * param will force a conversion.
1906
+ *
1907
+ * @method ()
1908
+ * @static
1909
+ * @param {object} o the item to arrayify.
1910
+ * @param {int} startIdx if an array or array-like, this is the start index.
1911
+ * @param {boolean} arraylike if true, it forces the array-like fork. This
1912
+ * can be used to avoid multiple Array.test calls.
1913
+ * @return {Array} the resulting array.
1914
+ */
1915
+ YArray = function(o, startIdx, arraylike) {
1916
+ var t = (arraylike) ? 2 : YArray.test(o),
1917
+ l, a, start = startIdx || 0;
1918
+
1919
+ if (t) {
1920
+ // IE errors when trying to slice HTMLElement collections
1921
+ try {
1922
+ return Native.slice.call(o, start);
1923
+ } catch (e) {
1924
+ a = [];
1925
+ l = o.length;
1926
+ for (; start < l; start++) {
1927
+ a.push(o[start]);
1928
+ }
1929
+ return a;
1930
+ }
1931
+ } else {
1932
+ return [o];
1933
+ }
1934
+ };
1935
+
1936
+ Y.Array = YArray;
1937
+
1938
+ /**
1939
+ * Evaluates the input to determine if it is an array, array-like, or
1940
+ * something else. This is used to handle the arguments collection
1941
+ * available within functions, and HTMLElement collections
1942
+ *
1943
+ * @method test
1944
+ * @static
1945
+ *
1946
+ * @todo current implementation (intenionally) will not implicitly
1947
+ * handle html elements that are array-like (forms, selects, etc).
1948
+ *
1949
+ * @param {object} o the object to test.
1950
+ *
1951
+ * @return {int} a number indicating the results:
1952
+ * 0: Not an array or an array-like collection
1953
+ * 1: A real array.
1954
+ * 2: array-like collection.
1955
+ */
1956
+ YArray.test = function(o) {
1957
+ var r = 0;
1958
+ if (Y.Lang.isObject(o)) {
1959
+ if (Y.Lang.isArray(o)) {
1960
+ r = 1;
1961
+ } else {
1962
+ try {
1963
+ // indexed, but no tagName (element) or alert (window),
1964
+ // or functions without apply/call (Safari
1965
+ // HTMLElementCollection bug).
1966
+ if ((LENGTH in o) && !o.tagName && !o.alert && !o.apply) {
1967
+ r = 2;
1968
+ }
1969
+
1970
+ } catch (e) {}
1971
+ }
1972
+ }
1973
+ return r;
1974
+ };
1975
+
1976
+ /**
1977
+ * Executes the supplied function on each item in the array.
1978
+ * @method each
1979
+ * @param {Array} a the array to iterate.
1980
+ * @param {Function} f the function to execute on each item. The
1981
+ * function receives three arguments: the value, the index, the full array.
1982
+ * @param {object} o Optional context object.
1983
+ * @static
1984
+ * @return {YUI} the YUI instance.
1985
+ */
1986
+ YArray.each = (Native.forEach) ?
1987
+ function(a, f, o) {
1988
+ Native.forEach.call(a || [], f, o || Y);
1989
+ return Y;
1990
+ } :
1991
+ function(a, f, o) {
1992
+ var l = (a && a.length) || 0, i;
1993
+ for (i = 0; i < l; i = i + 1) {
1994
+ f.call(o || Y, a[i], i, a);
1995
+ }
1996
+ return Y;
1997
+ };
1998
+
1999
+ /**
2000
+ * Returns an object using the first array as keys, and
2001
+ * the second as values. If the second array is not
2002
+ * provided the value is set to true for each.
2003
+ * @method hash
2004
+ * @static
2005
+ * @param {Array} k keyset.
2006
+ * @param {Array} v optional valueset.
2007
+ * @return {object} the hash.
2008
+ */
2009
+ YArray.hash = function(k, v) {
2010
+ var o = {}, l = k.length, vl = v && v.length, i;
2011
+ for (i = 0; i < l; i = i + 1) {
2012
+ o[k[i]] = (vl && vl > i) ? v[i] : true;
2013
+ }
2014
+
2015
+ return o;
2016
+ };
2017
+
2018
+ /**
2019
+ * Returns the index of the first item in the array
2020
+ * that contains the specified value, -1 if the
2021
+ * value isn't found.
2022
+ * @method indexOf
2023
+ * @static
2024
+ * @param {Array} a the array to search.
2025
+ * @param {any} val the value to search for.
2026
+ * @return {int} the index of the item that contains the value or -1.
2027
+ */
2028
+ YArray.indexOf = (Native.indexOf) ?
2029
+ function(a, val) {
2030
+ return Native.indexOf.call(a, val);
2031
+ } :
2032
+ function(a, val) {
2033
+ for (var i = 0; i < a.length; i = i + 1) {
2034
+ if (a[i] === val) {
2035
+ return i;
2036
+ }
2037
+ }
2038
+
2039
+ return -1;
2040
+ };
2041
+
2042
+ /**
2043
+ * Numeric sort convenience function.
2044
+ * Y.ArrayAssert.itemsAreEqual([1,2,3], [3,1,2].sort(Y.Array.numericSort));
2045
+ * @method numericSort
2046
+ * @static
2047
+ * @param {number} a a number.
2048
+ * @param {number} b a number.
2049
+ */
2050
+ YArray.numericSort = function(a, b) {
2051
+ return (a - b);
2052
+ };
2053
+
2054
+ /**
2055
+ * Executes the supplied function on each item in the array.
2056
+ * Returning true from the processing function will stop the
2057
+ * processing of the remaining items.
2058
+ * @method some
2059
+ * @param {Array} a the array to iterate.
2060
+ * @param {Function} f the function to execute on each item. The function
2061
+ * receives three arguments: the value, the index, the full array.
2062
+ * @param {object} o Optional context object.
2063
+ * @static
2064
+ * @return {boolean} true if the function returns true on
2065
+ * any of the items in the array.
2066
+ */
2067
+ YArray.some = (Native.some) ?
2068
+ function(a, f, o) {
2069
+ return Native.some.call(a, f, o);
2070
+ } :
2071
+ function(a, f, o) {
2072
+ var l = a.length, i;
2073
+ for (i = 0; i < l; i = i + 1) {
2074
+ if (f.call(o, a[i], i, a)) {
2075
+ return true;
2076
+ }
2077
+ }
2078
+ return false;
2079
+ };
2080
+
2081
+ /**
2082
+ * The YUI module contains the components required for building the YUI
2083
+ * seed file. This includes the script loading mechanism, a simple queue,
2084
+ * and the core utilities for the library.
2085
+ * @module yui
2086
+ * @submodule yui-base
2087
+ */
2088
+
2089
+ /**
2090
+ * A simple FIFO queue. Items are added to the Queue with add(1..n items) and
2091
+ * removed using next().
2092
+ *
2093
+ * @class Queue
2094
+ * @constructor
2095
+ * @param {MIXED} item* 0..n items to seed the queue.
2096
+ */
2097
+ function Queue() {
2098
+ this._init();
2099
+ this.add.apply(this, arguments);
2100
+ }
2101
+
2102
+ Queue.prototype = {
2103
+ /**
2104
+ * Initialize the queue
2105
+ *
2106
+ * @method _init
2107
+ * @protected
2108
+ */
2109
+ _init: function() {
2110
+ /**
2111
+ * The collection of enqueued items
2112
+ *
2113
+ * @property _q
2114
+ * @type Array
2115
+ * @protected
2116
+ */
2117
+ this._q = [];
2118
+ },
2119
+
2120
+ /**
2121
+ * Get the next item in the queue. FIFO support
2122
+ *
2123
+ * @method next
2124
+ * @return {MIXED} the next item in the queue.
2125
+ */
2126
+ next: function() {
2127
+ return this._q.shift();
2128
+ },
2129
+
2130
+ /**
2131
+ * Get the last in the queue. LIFO support.
2132
+ *
2133
+ * @method last
2134
+ * @return {MIXED} the last item in the queue.
2135
+ */
2136
+ last: function() {
2137
+ return this._q.pop();
2138
+ },
2139
+
2140
+ /**
2141
+ * Add 0..n items to the end of the queue.
2142
+ *
2143
+ * @method add
2144
+ * @param {MIXED} item* 0..n items.
2145
+ * @return {object} this queue.
2146
+ */
2147
+ add: function() {
2148
+ this._q.push.apply(this._q, arguments);
2149
+
2150
+ return this;
2151
+ },
2152
+
2153
+ /**
2154
+ * Returns the current number of queued items.
2155
+ *
2156
+ * @method size
2157
+ * @return {Number} The size.
2158
+ */
2159
+ size: function() {
2160
+ return this._q.length;
2161
+ }
2162
+ };
2163
+
2164
+ Y.Queue = Queue;
2165
+
2166
+ YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2167
+
2168
+ /**
2169
+ * The YUI module contains the components required for building the YUI
2170
+ * seed file. This includes the script loading mechanism, a simple queue,
2171
+ * and the core utilities for the library.
2172
+ * @module yui
2173
+ * @submodule yui-base
2174
+ */
2175
+
2176
+ var CACHED_DELIMITER = '__',
2177
+
2178
+ /*
2179
+ * IE will not enumerate native functions in a derived object even if the
2180
+ * function was overridden. This is a workaround for specific functions
2181
+ * we care about on the Object prototype.
2182
+ * @property _iefix
2183
+ * @for YUI
2184
+ * @param {Function} r the object to receive the augmentation
2185
+ * @param {Function} s the object that supplies the properties to augment
2186
+ * @private
2187
+ */
2188
+ _iefix = function(r, s) {
2189
+ var fn = s.toString;
2190
+ if (Y.Lang.isFunction(fn) && fn != Object.prototype.toString) {
2191
+ r.toString = fn;
2192
+ }
2193
+ };
2194
+
2195
+
2196
+ /**
2197
+ * Returns a new object containing all of the properties of
2198
+ * all the supplied objects. The properties from later objects
2199
+ * will overwrite those in earlier objects. Passing in a
2200
+ * single object will create a shallow copy of it. For a deep
2201
+ * copy, use clone.
2202
+ * @method merge
2203
+ * @for YUI
2204
+ * @param arguments {Object*} the objects to merge.
2205
+ * @return {object} the new merged object.
2206
+ */
2207
+ Y.merge = function() {
2208
+ var a = arguments, o = {}, i, l = a.length;
2209
+ for (i = 0; i < l; i = i + 1) {
2210
+ Y.mix(o, a[i], true);
2211
+ }
2212
+ return o;
2213
+ };
2214
+
2215
+ /**
2216
+ * Applies the supplier's properties to the receiver. By default
2217
+ * all prototype and static propertes on the supplier are applied
2218
+ * to the corresponding spot on the receiver. By default all
2219
+ * properties are applied, and a property that is already on the
2220
+ * reciever will not be overwritten. The default behavior can
2221
+ * be modified by supplying the appropriate parameters.
2222
+ *
2223
+ * @todo add constants for the modes
2224
+ *
2225
+ * @method mix
2226
+ * @param {Function} r the object to receive the augmentation.
2227
+ * @param {Function} s the object that supplies the properties to augment.
2228
+ * @param ov {boolean} if true, properties already on the receiver
2229
+ * will be overwritten if found on the supplier.
2230
+ * @param wl {string[]} a whitelist. If supplied, only properties in
2231
+ * this list will be applied to the receiver.
2232
+ * @param {int} mode what should be copies, and to where
2233
+ * default(0): object to object
2234
+ * 1: prototype to prototype (old augment)
2235
+ * 2: prototype to prototype and object props (new augment)
2236
+ * 3: prototype to object
2237
+ * 4: object to prototype.
2238
+ * @param merge {boolean/int} merge objects instead of overwriting/ignoring.
2239
+ * A value of 2 will skip array merge
2240
+ * Used by Y.aggregate.
2241
+ * @return {object} the augmented object.
2242
+ */
2243
+ Y.mix = function(r, s, ov, wl, mode, merge) {
2244
+
2245
+ if (!s || !r) {
2246
+ return r || Y;
2247
+ }
2248
+
2249
+ if (mode) {
2250
+ switch (mode) {
2251
+ case 1: // proto to proto
2252
+ return Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
2253
+ case 2: // object to object and proto to proto
2254
+ Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
2255
+ break; // pass through
2256
+ case 3: // proto to static
2257
+ return Y.mix(r, s.prototype, ov, wl, 0, merge);
2258
+ case 4: // static to proto
2259
+ return Y.mix(r.prototype, s, ov, wl, 0, merge);
2260
+ default: // object to object is what happens below
2261
+ }
2262
+ }
2263
+
2264
+ // Maybe don't even need this wl && wl.length check anymore??
2265
+ var i, l, p, type;
2266
+
2267
+ if (wl && wl.length) {
2268
+ for (i = 0, l = wl.length; i < l; ++i) {
2269
+ p = wl[i];
2270
+ type = Y.Lang.type(r[p]);
2271
+ if (s.hasOwnProperty(p)) {
2272
+ if (merge && type == 'object') {
2273
+ Y.mix(r[p], s[p]);
2274
+ } else if (ov || !(p in r)) {
2275
+ r[p] = s[p];
2276
+ }
2277
+ }
2278
+ }
2279
+ } else {
2280
+ for (i in s) {
2281
+ // if (s.hasOwnProperty(i) && !(i in FROZEN)) {
2282
+ if (s.hasOwnProperty(i)) {
2283
+ // check white list if it was supplied
2284
+ // if the receiver has this property, it is an object,
2285
+ // and merge is specified, merge the two objects.
2286
+ if (merge && Y.Lang.isObject(r[i], true)) {
2287
+ Y.mix(r[i], s[i], ov, wl, 0, true); // recursive
2288
+ // otherwise apply the property only if overwrite
2289
+ // is specified or the receiver doesn't have one.
2290
+ } else if (ov || !(i in r)) {
2291
+ r[i] = s[i];
2292
+ }
2293
+ // if merge is specified and the receiver is an array,
2294
+ // append the array item
2295
+ // } else if (arr) {
2296
+ // r.push(s[i]);
2297
+ // }
2298
+ }
2299
+ }
2300
+
2301
+ if (Y.UA.ie) {
2302
+ _iefix(r, s);
2303
+ }
2304
+ }
2305
+
2306
+ return r;
2307
+ };
2308
+
2309
+ /**
2310
+ * Returns a wrapper for a function which caches the
2311
+ * return value of that function, keyed off of the combined
2312
+ * argument values.
2313
+ * @method cached
2314
+ * @param source {function} the function to memoize.
2315
+ * @param cache an optional cache seed.
2316
+ * @param refetch if supplied, this value is tested against the cached
2317
+ * value. If the values are equal, the wrapped function is executed again.
2318
+ * @return {Function} the wrapped function.
2319
+ */
2320
+ Y.cached = function(source, cache, refetch) {
2321
+ cache = cache || {};
2322
+
2323
+ return function(arg1) {
2324
+
2325
+ var k = (arguments.length > 1) ?
2326
+ Array.prototype.join.call(arguments, CACHED_DELIMITER) : arg1;
2327
+
2328
+ if (!(k in cache) || (refetch && cache[k] == refetch)) {
2329
+ cache[k] = source.apply(source, arguments);
2330
+ }
2331
+
2332
+ return cache[k];
2333
+ };
2334
+
2335
+ };
2336
+
2337
+ /**
2338
+ * The YUI module contains the components required for building the YUI
2339
+ * seed file. This includes the script loading mechanism, a simple queue,
2340
+ * and the core utilities for the library.
2341
+ * @module yui
2342
+ * @submodule yui-base
2343
+ */
2344
+
2345
+ /**
2346
+ * Adds the following Object utilities to the YUI instance
2347
+ * @class Object
2348
+ */
2349
+
2350
+ /**
2351
+ * Y.Object(o) returns a new object based upon the supplied object.
2352
+ * @method ()
2353
+ * @static
2354
+ * @param o the supplier object.
2355
+ * @return {Object} the new object.
2356
+ */
2357
+ var F = function() {},
2358
+
2359
+ // O = Object.create || function(o) {
2360
+ // F.prototype = o;
2361
+ // return new F();
2362
+ // },
2363
+
2364
+ O = function(o) {
2365
+ F.prototype = o;
2366
+ return new F();
2367
+ },
2368
+
2369
+ owns = function(o, k) {
2370
+ return o && o.hasOwnProperty && o.hasOwnProperty(k);
2371
+ // return Object.prototype.hasOwnProperty.call(o, k);
2372
+ },
2373
+
2374
+ UNDEF,
2375
+
2376
+ /**
2377
+ * Extracts the keys, values, or size from an object
2378
+ *
2379
+ * @method _extract
2380
+ * @param o the object.
2381
+ * @param what what to extract (0: keys, 1: values, 2: size).
2382
+ * @return {boolean|Array} the extracted info.
2383
+ * @static
2384
+ * @private
2385
+ */
2386
+ _extract = function(o, what) {
2387
+ var count = (what === 2), out = (count) ? 0 : [], i;
2388
+
2389
+ for (i in o) {
2390
+ if (owns(o, i)) {
2391
+ if (count) {
2392
+ out++;
2393
+ } else {
2394
+ out.push((what) ? o[i] : i);
2395
+ }
2396
+ }
2397
+ }
2398
+
2399
+ return out;
2400
+ };
2401
+
2402
+ Y.Object = O;
2403
+
2404
+ /**
2405
+ * Returns an array containing the object's keys
2406
+ * @method keys
2407
+ * @static
2408
+ * @param o an object.
2409
+ * @return {string[]} the keys.
2410
+ */
2411
+ // O.keys = Object.keys || function(o) {
2412
+ // return _extract(o);
2413
+ // };
2414
+
2415
+ O.keys = function(o) {
2416
+ return _extract(o);
2417
+ };
2418
+
2419
+ /**
2420
+ * Returns an array containing the object's values
2421
+ * @method values
2422
+ * @static
2423
+ * @param o an object.
2424
+ * @return {Array} the values.
2425
+ */
2426
+ // O.values = Object.values || function(o) {
2427
+ // return _extract(o, 1);
2428
+ // };
2429
+
2430
+ O.values = function(o) {
2431
+ return _extract(o, 1);
2432
+ };
2433
+
2434
+ /**
2435
+ * Returns the size of an object
2436
+ * @method size
2437
+ * @static
2438
+ * @param o an object.
2439
+ * @return {int} the size.
2440
+ */
2441
+ O.size = Object.size || function(o) {
2442
+ return _extract(o, 2);
2443
+ };
2444
+
2445
+ /**
2446
+ * Returns true if the object contains a given key
2447
+ * @method hasKey
2448
+ * @static
2449
+ * @param o an object.
2450
+ * @param k the key to query.
2451
+ * @return {boolean} true if the object contains the key.
2452
+ */
2453
+ O.hasKey = owns;
2454
+ /**
2455
+ * Returns true if the object contains a given value
2456
+ * @method hasValue
2457
+ * @static
2458
+ * @param o an object.
2459
+ * @param v the value to query.
2460
+ * @return {boolean} true if the object contains the value.
2461
+ */
2462
+ O.hasValue = function(o, v) {
2463
+ return (Y.Array.indexOf(O.values(o), v) > -1);
2464
+ };
2465
+
2466
+ /**
2467
+ * Determines whether or not the property was added
2468
+ * to the object instance. Returns false if the property is not present
2469
+ * in the object, or was inherited from the prototype.
2470
+ *
2471
+ * @method owns
2472
+ * @static
2473
+ * @param o {any} The object being testing.
2474
+ * @param p {string} the property to look for.
2475
+ * @return {boolean} true if the object has the property on the instance.
2476
+ */
2477
+ O.owns = owns;
2478
+
2479
+ /**
2480
+ * Executes a function on each item. The function
2481
+ * receives the value, the key, and the object
2482
+ * as parameters (in that order).
2483
+ * @method each
2484
+ * @static
2485
+ * @param o the object to iterate.
2486
+ * @param f {Function} the function to execute on each item. The function
2487
+ * receives three arguments: the value, the the key, the full object.
2488
+ * @param c the execution context.
2489
+ * @param proto {boolean} include proto.
2490
+ * @return {YUI} the YUI instance.
2491
+ */
2492
+ O.each = function(o, f, c, proto) {
2493
+ var s = c || Y, i;
2494
+
2495
+ for (i in o) {
2496
+ if (proto || owns(o, i)) {
2497
+ f.call(s, o[i], i, o);
2498
+ }
2499
+ }
2500
+ return Y;
2501
+ };
2502
+
2503
+ /**
2504
+ * Executes a function on each item, but halts if the
2505
+ * function returns true. The function
2506
+ * receives the value, the key, and the object
2507
+ * as paramters (in that order).
2508
+ * @method some
2509
+ * @static
2510
+ * @param o the object to iterate.
2511
+ * @param f {Function} the function to execute on each item. The function
2512
+ * receives three arguments: the value, the the key, the full object.
2513
+ * @param c the execution context.
2514
+ * @param proto {boolean} include proto.
2515
+ * @return {boolean} true if any execution of the function returns true,
2516
+ * false otherwise.
2517
+ */
2518
+ O.some = function(o, f, c, proto) {
2519
+ var s = c || Y, i;
2520
+
2521
+ for (i in o) {
2522
+ if (proto || owns(o, i)) {
2523
+ if (f.call(s, o[i], i, o)) {
2524
+ return true;
2525
+ }
2526
+ }
2527
+ }
2528
+ return false;
2529
+ };
2530
+
2531
+ /**
2532
+ * Retrieves the sub value at the provided path,
2533
+ * from the value object provided.
2534
+ *
2535
+ * @method getValue
2536
+ * @static
2537
+ * @param o The object from which to extract the property value.
2538
+ * @param path {Array} A path array, specifying the object traversal path
2539
+ * from which to obtain the sub value.
2540
+ * @return {Any} The value stored in the path, undefined if not found,
2541
+ * undefined if the source is not an object. Returns the source object
2542
+ * if an empty path is provided.
2543
+ */
2544
+ O.getValue = function(o, path) {
2545
+ if (!Y.Lang.isObject(o)) {
2546
+ return UNDEF;
2547
+ }
2548
+
2549
+ var i,
2550
+ p = Y.Array(path),
2551
+ l = p.length;
2552
+
2553
+ for (i = 0; o !== UNDEF && i < l; i++) {
2554
+ o = o[p[i]];
2555
+ }
2556
+
2557
+ return o;
2558
+ };
2559
+
2560
+ /**
2561
+ * Sets the sub-attribute value at the provided path on the
2562
+ * value object. Returns the modified value object, or
2563
+ * undefined if the path is invalid.
2564
+ *
2565
+ * @method setValue
2566
+ * @static
2567
+ * @param o The object on which to set the sub value.
2568
+ * @param path {Array} A path array, specifying the object traversal path
2569
+ * at which to set the sub value.
2570
+ * @param val {Any} The new value for the sub-attribute.
2571
+ * @return {Object} The modified object, with the new sub value set, or
2572
+ * undefined, if the path was invalid.
2573
+ */
2574
+ O.setValue = function(o, path, val) {
2575
+ var i,
2576
+ p = Y.Array(path),
2577
+ leafIdx = p.length - 1,
2578
+ ref = o;
2579
+
2580
+ if (leafIdx >= 0) {
2581
+ for (i = 0; ref !== UNDEF && i < leafIdx; i++) {
2582
+ ref = ref[p[i]];
2583
+ }
2584
+
2585
+ if (ref !== UNDEF) {
2586
+ ref[p[i]] = val;
2587
+ } else {
2588
+ return UNDEF;
2589
+ }
2590
+ }
2591
+
2592
+ return o;
2593
+ };
2594
+
2595
+ /**
2596
+ * Returns true if the object has no properties of its own
2597
+ * @method isEmpty
2598
+ * @static
2599
+ * @return {boolean} true if the object is empty.
2600
+ * @since 3.2.0
2601
+ */
2602
+ O.isEmpty = function(o) {
2603
+ for (var i in o) {
2604
+ if (owns(o, i)) {
2605
+ return false;
2606
+ }
2607
+ }
2608
+ return true;
2609
+ };
2610
+ /**
2611
+ * The YUI module contains the components required for building the YUI seed
2612
+ * file. This includes the script loading mechanism, a simple queue, and the
2613
+ * core utilities for the library.
2614
+ * @module yui
2615
+ * @submodule yui-base
2616
+ */
2617
+
2618
+ /**
2619
+ * YUI user agent detection.
2620
+ * Do not fork for a browser if it can be avoided. Use feature detection when
2621
+ * you can. Use the user agent as a last resort. UA stores a version
2622
+ * number for the browser engine, 0 otherwise. This value may or may not map
2623
+ * to the version number of the browser using the engine. The value is
2624
+ * presented as a float so that it can easily be used for boolean evaluation
2625
+ * as well as for looking for a particular range of versions. Because of this,
2626
+ * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9
2627
+ * reports 1.8).
2628
+ * @class UA
2629
+ * @static
2630
+ */
2631
+ /**
2632
+ * Static method for parsing the UA string. Defaults to assigning it's value to Y.UA
2633
+ * @static
2634
+ * @method Env.parseUA
2635
+ * @param {String} subUA Parse this UA string instead of navigator.userAgent
2636
+ * @returns {Object} The Y.UA object
2637
+ */
2638
+ YUI.Env.parseUA = function(subUA) {
2639
+
2640
+ var numberify = function(s) {
2641
+ var c = 0;
2642
+ return parseFloat(s.replace(/\./g, function() {
2643
+ return (c++ == 1) ? '' : '.';
2644
+ }));
2645
+ },
2646
+
2647
+ win = Y.config.win,
2648
+
2649
+ nav = win && win.navigator,
2650
+
2651
+ o = {
2652
+
2653
+ /**
2654
+ * Internet Explorer version number or 0. Example: 6
2655
+ * @property ie
2656
+ * @type float
2657
+ * @static
2658
+ */
2659
+ ie: 0,
2660
+
2661
+ /**
2662
+ * Opera version number or 0. Example: 9.2
2663
+ * @property opera
2664
+ * @type float
2665
+ * @static
2666
+ */
2667
+ opera: 0,
2668
+
2669
+ /**
2670
+ * Gecko engine revision number. Will evaluate to 1 if Gecko
2671
+ * is detected but the revision could not be found. Other browsers
2672
+ * will be 0. Example: 1.8
2673
+ * <pre>
2674
+ * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7
2675
+ * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
2676
+ * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
2677
+ * Firefox 3.0 <-- 1.9
2678
+ * Firefox 3.5 <-- 1.91
2679
+ * </pre>
2680
+ * @property gecko
2681
+ * @type float
2682
+ * @static
2683
+ */
2684
+ gecko: 0,
2685
+
2686
+ /**
2687
+ * AppleWebKit version. KHTML browsers that are not WebKit browsers
2688
+ * will evaluate to 1, other browsers 0. Example: 418.9
2689
+ * <pre>
2690
+ * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
2691
+ * latest available for Mac OSX 10.3.
2692
+ * Safari 2.0.2: 416 <-- hasOwnProperty introduced
2693
+ * Safari 2.0.4: 418 <-- preventDefault fixed
2694
+ * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
2695
+ * different versions of webkit
2696
+ * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been
2697
+ * updated, but not updated
2698
+ * to the latest patch.
2699
+ * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native
2700
+ * SVG and many major issues fixed).
2701
+ * Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic
2702
+ * update from 2.x via the 10.4.11 OS patch.
2703
+ * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event.
2704
+ * yahoo.com user agent hack removed.
2705
+ * </pre>
2706
+ * http://en.wikipedia.org/wiki/Safari_version_history
2707
+ * @property webkit
2708
+ * @type float
2709
+ * @static
2710
+ */
2711
+ webkit: 0,
2712
+
2713
+ /**
2714
+ * Chrome will be detected as webkit, but this property will also
2715
+ * be populated with the Chrome version number
2716
+ * @property chrome
2717
+ * @type float
2718
+ * @static
2719
+ */
2720
+ chrome: 0,
2721
+
2722
+ /**
2723
+ * The mobile property will be set to a string containing any relevant
2724
+ * user agent information when a modern mobile browser is detected.
2725
+ * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
2726
+ * devices with the WebKit-based browser, and Opera Mini.
2727
+ * @property mobile
2728
+ * @type string
2729
+ * @static
2730
+ */
2731
+ mobile: null,
2732
+
2733
+ /**
2734
+ * Adobe AIR version number or 0. Only populated if webkit is detected.
2735
+ * Example: 1.0
2736
+ * @property air
2737
+ * @type float
2738
+ */
2739
+ air: 0,
2740
+ /**
2741
+ * Detects Apple iPad's OS version
2742
+ * @property ipad
2743
+ * @type float
2744
+ * @static
2745
+ */
2746
+ ipad: 0,
2747
+ /**
2748
+ * Detects Apple iPhone's OS version
2749
+ * @property iphone
2750
+ * @type float
2751
+ * @static
2752
+ */
2753
+ iphone: 0,
2754
+ /**
2755
+ * Detects Apples iPod's OS version
2756
+ * @property ipod
2757
+ * @type float
2758
+ * @static
2759
+ */
2760
+ ipod: 0,
2761
+ /**
2762
+ * General truthy check for iPad, iPhone or iPod
2763
+ * @property ios
2764
+ * @type float
2765
+ * @static
2766
+ */
2767
+ ios: null,
2768
+ /**
2769
+ * Detects Googles Android OS version
2770
+ * @property android
2771
+ * @type float
2772
+ * @static
2773
+ */
2774
+ android: 0,
2775
+ /**
2776
+ * Detects Palms WebOS version
2777
+ * @property webos
2778
+ * @type float
2779
+ * @static
2780
+ */
2781
+ webos: 0,
2782
+
2783
+ /**
2784
+ * Google Caja version number or 0.
2785
+ * @property caja
2786
+ * @type float
2787
+ */
2788
+ caja: nav && nav.cajaVersion,
2789
+
2790
+ /**
2791
+ * Set to true if the page appears to be in SSL
2792
+ * @property secure
2793
+ * @type boolean
2794
+ * @static
2795
+ */
2796
+ secure: false,
2797
+
2798
+ /**
2799
+ * The operating system. Currently only detecting windows or macintosh
2800
+ * @property os
2801
+ * @type string
2802
+ * @static
2803
+ */
2804
+ os: null
2805
+
2806
+ },
2807
+
2808
+ ua = subUA || nav && nav.userAgent,
2809
+
2810
+ loc = win && win.location,
2811
+
2812
+ href = loc && loc.href,
2813
+
2814
+ m;
2815
+
2816
+ o.secure = href && (href.toLowerCase().indexOf('https') === 0);
2817
+
2818
+ if (ua) {
2819
+
2820
+ if ((/windows|win32/i).test(ua)) {
2821
+ o.os = 'windows';
2822
+ } else if ((/macintosh/i).test(ua)) {
2823
+ o.os = 'macintosh';
2824
+ } else if ((/rhino/i).test(ua)) {
2825
+ o.os = 'rhino';
2826
+ }
2827
+
2828
+ // Modern KHTML browsers should qualify as Safari X-Grade
2829
+ if ((/KHTML/).test(ua)) {
2830
+ o.webkit = 1;
2831
+ }
2832
+ // Modern WebKit browsers are at least X-Grade
2833
+ m = ua.match(/AppleWebKit\/([^\s]*)/);
2834
+ if (m && m[1]) {
2835
+ o.webkit = numberify(m[1]);
2836
+
2837
+ // Mobile browser check
2838
+ if (/ Mobile\//.test(ua)) {
2839
+ o.mobile = 'Apple'; // iPhone or iPod Touch
2840
+
2841
+ m = ua.match(/OS ([^\s]*)/);
2842
+ if (m && m[1]) {
2843
+ m = numberify(m[1].replace('_', '.'));
2844
+ }
2845
+ o.ios = m;
2846
+ o.ipad = o.ipod = o.iphone = 0;
2847
+
2848
+ m = ua.match(/iPad|iPod|iPhone/);
2849
+ if (m && m[0]) {
2850
+ o[m[0].toLowerCase()] = o.ios;
2851
+ }
2852
+ } else {
2853
+ m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/);
2854
+ if (m) {
2855
+ // Nokia N-series, Android, webOS, ex: NokiaN95
2856
+ o.mobile = m[0];
2857
+ }
2858
+ if (/webOS/.test(ua)) {
2859
+ o.mobile = 'WebOS';
2860
+ m = ua.match(/webOS\/([^\s]*);/);
2861
+ if (m && m[1]) {
2862
+ o.webos = numberify(m[1]);
2863
+ }
2864
+ }
2865
+ if (/ Android/.test(ua)) {
2866
+ o.mobile = 'Android';
2867
+ m = ua.match(/Android ([^\s]*);/);
2868
+ if (m && m[1]) {
2869
+ o.android = numberify(m[1]);
2870
+ }
2871
+
2872
+ }
2873
+ }
2874
+
2875
+ m = ua.match(/Chrome\/([^\s]*)/);
2876
+ if (m && m[1]) {
2877
+ o.chrome = numberify(m[1]); // Chrome
2878
+ } else {
2879
+ m = ua.match(/AdobeAIR\/([^\s]*)/);
2880
+ if (m) {
2881
+ o.air = m[0]; // Adobe AIR 1.0 or better
2882
+ }
2883
+ }
2884
+ }
2885
+
2886
+ if (!o.webkit) { // not webkit
2887
+ // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
2888
+ m = ua.match(/Opera[\s\/]([^\s]*)/);
2889
+ if (m && m[1]) {
2890
+ o.opera = numberify(m[1]);
2891
+ m = ua.match(/Opera Mini[^;]*/);
2892
+ if (m) {
2893
+ o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
2894
+ }
2895
+ } else { // not opera or webkit
2896
+ m = ua.match(/MSIE\s([^;]*)/);
2897
+ if (m && m[1]) {
2898
+ o.ie = numberify(m[1]);
2899
+ } else { // not opera, webkit, or ie
2900
+ m = ua.match(/Gecko\/([^\s]*)/);
2901
+ if (m) {
2902
+ o.gecko = 1; // Gecko detected, look for revision
2903
+ m = ua.match(/rv:([^\s\)]*)/);
2904
+ if (m && m[1]) {
2905
+ o.gecko = numberify(m[1]);
2906
+ }
2907
+ }
2908
+ }
2909
+ }
2910
+ }
2911
+ }
2912
+
2913
+ YUI.Env.UA = o;
2914
+
2915
+ return o;
2916
+ };
2917
+
2918
+
2919
+ Y.UA = YUI.Env.UA || YUI.Env.parseUA();
2920
+
2921
+
2922
+ }, '3.3.0' );
2923
+ YUI.add('get', function(Y) {
2924
+
2925
+
2926
+ /**
2927
+ * Provides a mechanism to fetch remote resources and
2928
+ * insert them into a document.
2929
+ * @module yui
2930
+ * @submodule get
2931
+ */
2932
+
2933
+ var ua = Y.UA,
2934
+ L = Y.Lang,
2935
+ TYPE_JS = 'text/javascript',
2936
+ TYPE_CSS = 'text/css',
2937
+ STYLESHEET = 'stylesheet';
2938
+
2939
+ /**
2940
+ * Fetches and inserts one or more script or link nodes into the document
2941
+ * @class Get
2942
+ * @static
2943
+ */
2944
+ Y.Get = function() {
2945
+
2946
+ /**
2947
+ * hash of queues to manage multiple requests
2948
+ * @property queues
2949
+ * @private
2950
+ */
2951
+ var _get, _purge, _track,
2952
+
2953
+ queues = {},
2954
+
2955
+ /**
2956
+ * queue index used to generate transaction ids
2957
+ * @property qidx
2958
+ * @type int
2959
+ * @private
2960
+ */
2961
+ qidx = 0,
2962
+
2963
+ /**
2964
+ * interal property used to prevent multiple simultaneous purge
2965
+ * processes
2966
+ * @property purging
2967
+ * @type boolean
2968
+ * @private
2969
+ */
2970
+ purging,
2971
+
2972
+
2973
+ /**
2974
+ * Generates an HTML element, this is not appended to a document
2975
+ * @method _node
2976
+ * @param {string} type the type of element.
2977
+ * @param {string} attr the attributes.
2978
+ * @param {Window} win optional window to create the element in.
2979
+ * @return {HTMLElement} the generated node.
2980
+ * @private
2981
+ */
2982
+ _node = function(type, attr, win) {
2983
+ var w = win || Y.config.win,
2984
+ d = w.document,
2985
+ n = d.createElement(type),
2986
+ i;
2987
+
2988
+ for (i in attr) {
2989
+ if (attr[i] && attr.hasOwnProperty(i)) {
2990
+ n.setAttribute(i, attr[i]);
2991
+ }
2992
+ }
2993
+
2994
+ return n;
2995
+ },
2996
+
2997
+ /**
2998
+ * Generates a link node
2999
+ * @method _linkNode
3000
+ * @param {string} url the url for the css file.
3001
+ * @param {Window} win optional window to create the node in.
3002
+ * @param {object} attributes optional attributes collection to apply to the
3003
+ * new node.
3004
+ * @return {HTMLElement} the generated node.
3005
+ * @private
3006
+ */
3007
+ _linkNode = function(url, win, attributes) {
3008
+ var o = {
3009
+ id: Y.guid(),
3010
+ type: TYPE_CSS,
3011
+ rel: STYLESHEET,
3012
+ href: url
3013
+ };
3014
+ if (attributes) {
3015
+ Y.mix(o, attributes);
3016
+ }
3017
+ return _node('link', o, win);
3018
+ },
3019
+
3020
+ /**
3021
+ * Generates a script node
3022
+ * @method _scriptNode
3023
+ * @param {string} url the url for the script file.
3024
+ * @param {Window} win optional window to create the node in.
3025
+ * @param {object} attributes optional attributes collection to apply to the
3026
+ * new node.
3027
+ * @return {HTMLElement} the generated node.
3028
+ * @private
3029
+ */
3030
+ _scriptNode = function(url, win, attributes) {
3031
+ var o = {
3032
+ id: Y.guid(),
3033
+ type: TYPE_JS
3034
+ };
3035
+
3036
+ if (attributes) {
3037
+ Y.mix(o, attributes);
3038
+ }
3039
+
3040
+ o.src = url;
3041
+
3042
+ return _node('script', o, win);
3043
+ },
3044
+
3045
+ /**
3046
+ * Returns the data payload for callback functions.
3047
+ * @method _returnData
3048
+ * @param {object} q the queue.
3049
+ * @param {string} msg the result message.
3050
+ * @param {string} result the status message from the request.
3051
+ * @return {object} the state data from the request.
3052
+ * @private
3053
+ */
3054
+ _returnData = function(q, msg, result) {
3055
+ return {
3056
+ tId: q.tId,
3057
+ win: q.win,
3058
+ data: q.data,
3059
+ nodes: q.nodes,
3060
+ msg: msg,
3061
+ statusText: result,
3062
+ purge: function() {
3063
+ _purge(this.tId);
3064
+ }
3065
+ };
3066
+ },
3067
+
3068
+ /**
3069
+ * The transaction is finished
3070
+ * @method _end
3071
+ * @param {string} id the id of the request.
3072
+ * @param {string} msg the result message.
3073
+ * @param {string} result the status message from the request.
3074
+ * @private
3075
+ */
3076
+ _end = function(id, msg, result) {
3077
+ var q = queues[id], sc;
3078
+ if (q && q.onEnd) {
3079
+ sc = q.context || q;
3080
+ q.onEnd.call(sc, _returnData(q, msg, result));
3081
+ }
3082
+ },
3083
+
3084
+ /*
3085
+ * The request failed, execute fail handler with whatever
3086
+ * was accomplished. There isn't a failure case at the
3087
+ * moment unless you count aborted transactions
3088
+ * @method _fail
3089
+ * @param {string} id the id of the request
3090
+ * @private
3091
+ */
3092
+ _fail = function(id, msg) {
3093
+ Y.log('get failure: ' + msg, 'warn', 'get');
3094
+
3095
+ var q = queues[id], sc;
3096
+ if (q.timer) {
3097
+ // q.timer.cancel();
3098
+ clearTimeout(q.timer);
3099
+ }
3100
+
3101
+ // execute failure callback
3102
+ if (q.onFailure) {
3103
+ sc = q.context || q;
3104
+ q.onFailure.call(sc, _returnData(q, msg));
3105
+ }
3106
+
3107
+ _end(id, msg, 'failure');
3108
+ },
3109
+
3110
+ /**
3111
+ * The request is complete, so executing the requester's callback
3112
+ * @method _finish
3113
+ * @param {string} id the id of the request.
3114
+ * @private
3115
+ */
3116
+ _finish = function(id) {
3117
+ // Y.log("Finishing transaction " + id, "info", "get");
3118
+ var q = queues[id], msg, sc;
3119
+ if (q.timer) {
3120
+ // q.timer.cancel();
3121
+ clearTimeout(q.timer);
3122
+ }
3123
+ q.finished = true;
3124
+
3125
+ if (q.aborted) {
3126
+ msg = 'transaction ' + id + ' was aborted';
3127
+ _fail(id, msg);
3128
+ return;
3129
+ }
3130
+
3131
+ // execute success callback
3132
+ if (q.onSuccess) {
3133
+ sc = q.context || q;
3134
+ q.onSuccess.call(sc, _returnData(q));
3135
+ }
3136
+
3137
+ _end(id, msg, 'OK');
3138
+ },
3139
+
3140
+ /**
3141
+ * Timeout detected
3142
+ * @method _timeout
3143
+ * @param {string} id the id of the request.
3144
+ * @private
3145
+ */
3146
+ _timeout = function(id) {
3147
+ Y.log('Timeout ' + id, 'info', 'get');
3148
+ var q = queues[id], sc;
3149
+ if (q.onTimeout) {
3150
+ sc = q.context || q;
3151
+ q.onTimeout.call(sc, _returnData(q));
3152
+ }
3153
+
3154
+ _end(id, 'timeout', 'timeout');
3155
+ },
3156
+
3157
+
3158
+ /**
3159
+ * Loads the next item for a given request
3160
+ * @method _next
3161
+ * @param {string} id the id of the request.
3162
+ * @param {string} loaded the url that was just loaded, if any.
3163
+ * @return {string} the result.
3164
+ * @private
3165
+ */
3166
+ _next = function(id, loaded) {
3167
+ // Y.log("_next: " + id + ", loaded: " + (loaded || "nothing"), "info", "get");
3168
+ var q = queues[id], msg, w, d, h, n, url, s,
3169
+ insertBefore;
3170
+
3171
+ if (q.timer) {
3172
+ // Y.log('cancel timer');
3173
+ // q.timer.cancel();
3174
+ clearTimeout(q.timer);
3175
+ }
3176
+
3177
+ if (q.aborted) {
3178
+ msg = 'transaction ' + id + ' was aborted';
3179
+ _fail(id, msg);
3180
+ return;
3181
+ }
3182
+
3183
+ if (loaded) {
3184
+ q.url.shift();
3185
+ if (q.varName) {
3186
+ q.varName.shift();
3187
+ }
3188
+ } else {
3189
+ // This is the first pass: make sure the url is an array
3190
+ q.url = (L.isString(q.url)) ? [q.url] : q.url;
3191
+ if (q.varName) {
3192
+ q.varName = (L.isString(q.varName)) ? [q.varName] : q.varName;
3193
+ }
3194
+ }
3195
+
3196
+ w = q.win;
3197
+ d = w.document;
3198
+ h = d.getElementsByTagName('head')[0];
3199
+
3200
+ if (q.url.length === 0) {
3201
+ _finish(id);
3202
+ return;
3203
+ }
3204
+
3205
+ url = q.url[0];
3206
+
3207
+ // if the url is undefined, this is probably a trailing comma
3208
+ // problem in IE.
3209
+ if (!url) {
3210
+ q.url.shift();
3211
+ Y.log('skipping empty url');
3212
+ return _next(id);
3213
+ }
3214
+
3215
+ Y.log('attempting to load ' + url, 'info', 'get');
3216
+
3217
+ if (q.timeout) {
3218
+ // Y.log('create timer');
3219
+ // q.timer = L.later(q.timeout, q, _timeout, id);
3220
+ q.timer = setTimeout(function() {
3221
+ _timeout(id);
3222
+ }, q.timeout);
3223
+ }
3224
+
3225
+ if (q.type === 'script') {
3226
+ n = _scriptNode(url, w, q.attributes);
3227
+ } else {
3228
+ n = _linkNode(url, w, q.attributes);
3229
+ }
3230
+
3231
+ // track this node's load progress
3232
+ _track(q.type, n, id, url, w, q.url.length);
3233
+
3234
+ // add the node to the queue so we can return it to the user supplied
3235
+ // callback
3236
+ q.nodes.push(n);
3237
+
3238
+ // add it to the head or insert it before 'insertBefore'. Work around
3239
+ // IE bug if there is a base tag.
3240
+ insertBefore = q.insertBefore ||
3241
+ d.getElementsByTagName('base')[0];
3242
+
3243
+ if (insertBefore) {
3244
+ s = _get(insertBefore, id);
3245
+ if (s) {
3246
+ Y.log('inserting before: ' + insertBefore, 'info', 'get');
3247
+ s.parentNode.insertBefore(n, s);
3248
+ }
3249
+ } else {
3250
+ h.appendChild(n);
3251
+ }
3252
+
3253
+ // Y.log("Appending node: " + url, "info", "get");
3254
+
3255
+ // FireFox does not support the onload event for link nodes, so
3256
+ // there is no way to make the css requests synchronous. This means
3257
+ // that the css rules in multiple files could be applied out of order
3258
+ // in this browser if a later request returns before an earlier one.
3259
+ // Safari too.
3260
+ if ((ua.webkit || ua.gecko) && q.type === 'css') {
3261
+ _next(id, url);
3262
+ }
3263
+ },
3264
+
3265
+ /**
3266
+ * Removes processed queues and corresponding nodes
3267
+ * @method _autoPurge
3268
+ * @private
3269
+ */
3270
+ _autoPurge = function() {
3271
+ if (purging) {
3272
+ return;
3273
+ }
3274
+ purging = true;
3275
+
3276
+ var i, q;
3277
+
3278
+ for (i in queues) {
3279
+ if (queues.hasOwnProperty(i)) {
3280
+ q = queues[i];
3281
+ if (q.autopurge && q.finished) {
3282
+ _purge(q.tId);
3283
+ delete queues[i];
3284
+ }
3285
+ }
3286
+ }
3287
+
3288
+ purging = false;
3289
+ },
3290
+
3291
+ /**
3292
+ * Saves the state for the request and begins loading
3293
+ * the requested urls
3294
+ * @method queue
3295
+ * @param {string} type the type of node to insert.
3296
+ * @param {string} url the url to load.
3297
+ * @param {object} opts the hash of options for this request.
3298
+ * @return {object} transaction object.
3299
+ * @private
3300
+ */
3301
+ _queue = function(type, url, opts) {
3302
+ opts = opts || {};
3303
+
3304
+ var id = 'q' + (qidx++), q,
3305
+ thresh = opts.purgethreshold || Y.Get.PURGE_THRESH;
3306
+
3307
+ if (qidx % thresh === 0) {
3308
+ _autoPurge();
3309
+ }
3310
+
3311
+ queues[id] = Y.merge(opts, {
3312
+ tId: id,
3313
+ type: type,
3314
+ url: url,
3315
+ finished: false,
3316
+ nodes: []
3317
+ });
3318
+
3319
+ q = queues[id];
3320
+ q.win = q.win || Y.config.win;
3321
+ q.context = q.context || q;
3322
+ q.autopurge = ('autopurge' in q) ? q.autopurge :
3323
+ (type === 'script') ? true : false;
3324
+
3325
+ q.attributes = q.attributes || {};
3326
+ q.attributes.charset = opts.charset || q.attributes.charset || 'utf-8';
3327
+
3328
+ _next(id);
3329
+
3330
+ return {
3331
+ tId: id
3332
+ };
3333
+ };
3334
+
3335
+ /**
3336
+ * Detects when a node has been loaded. In the case of
3337
+ * script nodes, this does not guarantee that contained
3338
+ * script is ready to use.
3339
+ * @method _track
3340
+ * @param {string} type the type of node to track.
3341
+ * @param {HTMLElement} n the node to track.
3342
+ * @param {string} id the id of the request.
3343
+ * @param {string} url the url that is being loaded.
3344
+ * @param {Window} win the targeted window.
3345
+ * @param {int} qlength the number of remaining items in the queue,
3346
+ * including this one.
3347
+ * @param {Function} trackfn function to execute when finished
3348
+ * the default is _next.
3349
+ * @private
3350
+ */
3351
+ _track = function(type, n, id, url, win, qlength, trackfn) {
3352
+ var f = trackfn || _next;
3353
+
3354
+ // IE supports the readystatechange event for script and css nodes
3355
+ // Opera only for script nodes. Opera support onload for script
3356
+ // nodes, but this doesn't fire when there is a load failure.
3357
+ // The onreadystatechange appears to be a better way to respond
3358
+ // to both success and failure.
3359
+ if (ua.ie) {
3360
+ n.onreadystatechange = function() {
3361
+ var rs = this.readyState;
3362
+ if ('loaded' === rs || 'complete' === rs) {
3363
+ // Y.log(id + " onreadstatechange " + url, "info", "get");
3364
+ n.onreadystatechange = null;
3365
+ f(id, url);
3366
+ }
3367
+ };
3368
+
3369
+ // webkit prior to 3.x is no longer supported
3370
+ } else if (ua.webkit) {
3371
+ if (type === 'script') {
3372
+ // Safari 3.x supports the load event for script nodes (DOM2)
3373
+ n.addEventListener('load', function() {
3374
+ // Y.log(id + " DOM2 onload " + url, "info", "get");
3375
+ f(id, url);
3376
+ });
3377
+ }
3378
+
3379
+ // FireFox and Opera support onload (but not DOM2 in FF) handlers for
3380
+ // script nodes. Opera, but not FF, supports the onload event for link
3381
+ // nodes.
3382
+ } else {
3383
+ n.onload = function() {
3384
+ // Y.log(id + " onload " + url, "info", "get");
3385
+ f(id, url);
3386
+ };
3387
+
3388
+ n.onerror = function(e) {
3389
+ _fail(id, e + ': ' + url);
3390
+ };
3391
+ }
3392
+ };
3393
+
3394
+ _get = function(nId, tId) {
3395
+ var q = queues[tId],
3396
+ n = (L.isString(nId)) ? q.win.document.getElementById(nId) : nId;
3397
+ if (!n) {
3398
+ _fail(tId, 'target node not found: ' + nId);
3399
+ }
3400
+
3401
+ return n;
3402
+ };
3403
+
3404
+ /**
3405
+ * Removes the nodes for the specified queue
3406
+ * @method _purge
3407
+ * @param {string} tId the transaction id.
3408
+ * @private
3409
+ */
3410
+ _purge = function(tId) {
3411
+ var n, l, d, h, s, i, node, attr, insertBefore,
3412
+ q = queues[tId];
3413
+
3414
+ if (q) {
3415
+ n = q.nodes;
3416
+ l = n.length;
3417
+ d = q.win.document;
3418
+ h = d.getElementsByTagName('head')[0];
3419
+
3420
+ insertBefore = q.insertBefore ||
3421
+ d.getElementsByTagName('base')[0];
3422
+
3423
+ if (insertBefore) {
3424
+ s = _get(insertBefore, tId);
3425
+ if (s) {
3426
+ h = s.parentNode;
3427
+ }
3428
+ }
3429
+
3430
+ for (i = 0; i < l; i = i + 1) {
3431
+ node = n[i];
3432
+ if (node.clearAttributes) {
3433
+ node.clearAttributes();
3434
+ } else {
3435
+ for (attr in node) {
3436
+ if (node.hasOwnProperty(attr)) {
3437
+ delete node[attr];
3438
+ }
3439
+ }
3440
+ }
3441
+
3442
+ h.removeChild(node);
3443
+ }
3444
+ }
3445
+ q.nodes = [];
3446
+ };
3447
+
3448
+ return {
3449
+
3450
+ /**
3451
+ * The number of request required before an automatic purge.
3452
+ * Can be configured via the 'purgethreshold' config
3453
+ * property PURGE_THRESH
3454
+ * @static
3455
+ * @type int
3456
+ * @default 20
3457
+ * @private
3458
+ */
3459
+ PURGE_THRESH: 20,
3460
+
3461
+ /**
3462
+ * Called by the the helper for detecting script load in Safari
3463
+ * @method _finalize
3464
+ * @static
3465
+ * @param {string} id the transaction id.
3466
+ * @private
3467
+ */
3468
+ _finalize: function(id) {
3469
+ Y.log(id + ' finalized ', 'info', 'get');
3470
+ setTimeout(function() {
3471
+ _finish(id);
3472
+ }, 0);
3473
+ },
3474
+
3475
+ /**
3476
+ * Abort a transaction
3477
+ * @method abort
3478
+ * @static
3479
+ * @param {string|object} o Either the tId or the object returned from
3480
+ * script() or css().
3481
+ */
3482
+ abort: function(o) {
3483
+ var id = (L.isString(o)) ? o : o.tId,
3484
+ q = queues[id];
3485
+ if (q) {
3486
+ Y.log('Aborting ' + id, 'info', 'get');
3487
+ q.aborted = true;
3488
+ }
3489
+ },
3490
+
3491
+ /**
3492
+ * Fetches and inserts one or more script nodes into the head
3493
+ * of the current document or the document in a specified window.
3494
+ *
3495
+ * @method script
3496
+ * @static
3497
+ * @param {string|string[]} url the url or urls to the script(s).
3498
+ * @param {object} opts Options:
3499
+ * <dl>
3500
+ * <dt>onSuccess</dt>
3501
+ * <dd>
3502
+ * callback to execute when the script(s) are finished loading
3503
+ * The callback receives an object back with the following
3504
+ * data:
3505
+ * <dl>
3506
+ * <dt>win</dt>
3507
+ * <dd>the window the script(s) were inserted into</dd>
3508
+ * <dt>data</dt>
3509
+ * <dd>the data object passed in when the request was made</dd>
3510
+ * <dt>nodes</dt>
3511
+ * <dd>An array containing references to the nodes that were
3512
+ * inserted</dd>
3513
+ * <dt>purge</dt>
3514
+ * <dd>A function that, when executed, will remove the nodes
3515
+ * that were inserted</dd>
3516
+ * <dt>
3517
+ * </dl>
3518
+ * </dd>
3519
+ * <dt>onTimeout</dt>
3520
+ * <dd>
3521
+ * callback to execute when a timeout occurs.
3522
+ * The callback receives an object back with the following
3523
+ * data:
3524
+ * <dl>
3525
+ * <dt>win</dt>
3526
+ * <dd>the window the script(s) were inserted into</dd>
3527
+ * <dt>data</dt>
3528
+ * <dd>the data object passed in when the request was made</dd>
3529
+ * <dt>nodes</dt>
3530
+ * <dd>An array containing references to the nodes that were
3531
+ * inserted</dd>
3532
+ * <dt>purge</dt>
3533
+ * <dd>A function that, when executed, will remove the nodes
3534
+ * that were inserted</dd>
3535
+ * <dt>
3536
+ * </dl>
3537
+ * </dd>
3538
+ * <dt>onEnd</dt>
3539
+ * <dd>a function that executes when the transaction finishes,
3540
+ * regardless of the exit path</dd>
3541
+ * <dt>onFailure</dt>
3542
+ * <dd>
3543
+ * callback to execute when the script load operation fails
3544
+ * The callback receives an object back with the following
3545
+ * data:
3546
+ * <dl>
3547
+ * <dt>win</dt>
3548
+ * <dd>the window the script(s) were inserted into</dd>
3549
+ * <dt>data</dt>
3550
+ * <dd>the data object passed in when the request was made</dd>
3551
+ * <dt>nodes</dt>
3552
+ * <dd>An array containing references to the nodes that were
3553
+ * inserted successfully</dd>
3554
+ * <dt>purge</dt>
3555
+ * <dd>A function that, when executed, will remove any nodes
3556
+ * that were inserted</dd>
3557
+ * <dt>
3558
+ * </dl>
3559
+ * </dd>
3560
+ * <dt>context</dt>
3561
+ * <dd>the execution context for the callbacks</dd>
3562
+ * <dt>win</dt>
3563
+ * <dd>a window other than the one the utility occupies</dd>
3564
+ * <dt>autopurge</dt>
3565
+ * <dd>
3566
+ * setting to true will let the utilities cleanup routine purge
3567
+ * the script once loaded
3568
+ * </dd>
3569
+ * <dt>purgethreshold</dt>
3570
+ * <dd>
3571
+ * The number of transaction before autopurge should be initiated
3572
+ * </dd>
3573
+ * <dt>data</dt>
3574
+ * <dd>
3575
+ * data that is supplied to the callback when the script(s) are
3576
+ * loaded.
3577
+ * </dd>
3578
+ * <dt>insertBefore</dt>
3579
+ * <dd>node or node id that will become the new node's nextSibling.
3580
+ * If this is not specified, nodes will be inserted before a base
3581
+ * tag should it exist. Otherwise, the nodes will be appended to the
3582
+ * end of the document head.</dd>
3583
+ * </dl>
3584
+ * <dt>charset</dt>
3585
+ * <dd>Node charset, default utf-8 (deprecated, use the attributes
3586
+ * config)</dd>
3587
+ * <dt>attributes</dt>
3588
+ * <dd>An object literal containing additional attributes to add to
3589
+ * the link tags</dd>
3590
+ * <dt>timeout</dt>
3591
+ * <dd>Number of milliseconds to wait before aborting and firing
3592
+ * the timeout event</dd>
3593
+ * <pre>
3594
+ * &nbsp; Y.Get.script(
3595
+ * &nbsp; ["http://yui.yahooapis.com/2.5.2/build/yahoo/yahoo-min.js",
3596
+ * &nbsp; "http://yui.yahooapis.com/2.5.2/build/event/event-min.js"],
3597
+ * &nbsp; &#123;
3598
+ * &nbsp; onSuccess: function(o) &#123;
3599
+ * &nbsp; this.log("won't cause error because Y is the context");
3600
+ * &nbsp; Y.log(o.data); // foo
3601
+ * &nbsp; Y.log(o.nodes.length === 2) // true
3602
+ * &nbsp; // o.purge(); // optionally remove the script nodes
3603
+ * &nbsp; // immediately
3604
+ * &nbsp; &#125;,
3605
+ * &nbsp; onFailure: function(o) &#123;
3606
+ * &nbsp; Y.log("transaction failed");
3607
+ * &nbsp; &#125;,
3608
+ * &nbsp; onTimeout: function(o) &#123;
3609
+ * &nbsp; Y.log("transaction timed out");
3610
+ * &nbsp; &#125;,
3611
+ * &nbsp; data: "foo",
3612
+ * &nbsp; timeout: 10000, // 10 second timeout
3613
+ * &nbsp; context: Y, // make the YUI instance
3614
+ * &nbsp; // win: otherframe // target another window/frame
3615
+ * &nbsp; autopurge: true // allow the utility to choose when to
3616
+ * &nbsp; // remove the nodes
3617
+ * &nbsp; purgetheshold: 1 // purge previous transaction before
3618
+ * &nbsp; // next transaction
3619
+ * &nbsp; &#125;);.
3620
+ * </pre>
3621
+ * @return {tId: string} an object containing info about the
3622
+ * transaction.
3623
+ */
3624
+ script: function(url, opts) {
3625
+ return _queue('script', url, opts);
3626
+ },
3627
+
3628
+ /**
3629
+ * Fetches and inserts one or more css link nodes into the
3630
+ * head of the current document or the document in a specified
3631
+ * window.
3632
+ * @method css
3633
+ * @static
3634
+ * @param {string} url the url or urls to the css file(s).
3635
+ * @param {object} opts Options:
3636
+ * <dl>
3637
+ * <dt>onSuccess</dt>
3638
+ * <dd>
3639
+ * callback to execute when the css file(s) are finished loading
3640
+ * The callback receives an object back with the following
3641
+ * data:
3642
+ * <dl>win</dl>
3643
+ * <dd>the window the link nodes(s) were inserted into</dd>
3644
+ * <dt>data</dt>
3645
+ * <dd>the data object passed in when the request was made</dd>
3646
+ * <dt>nodes</dt>
3647
+ * <dd>An array containing references to the nodes that were
3648
+ * inserted</dd>
3649
+ * <dt>purge</dt>
3650
+ * <dd>A function that, when executed, will remove the nodes
3651
+ * that were inserted</dd>
3652
+ * <dt>
3653
+ * </dl>
3654
+ * </dd>
3655
+ * <dt>context</dt>
3656
+ * <dd>the execution context for the callbacks</dd>
3657
+ * <dt>win</dt>
3658
+ * <dd>a window other than the one the utility occupies</dd>
3659
+ * <dt>data</dt>
3660
+ * <dd>
3661
+ * data that is supplied to the callbacks when the nodes(s) are
3662
+ * loaded.
3663
+ * </dd>
3664
+ * <dt>insertBefore</dt>
3665
+ * <dd>node or node id that will become the new node's nextSibling</dd>
3666
+ * <dt>charset</dt>
3667
+ * <dd>Node charset, default utf-8 (deprecated, use the attributes
3668
+ * config)</dd>
3669
+ * <dt>attributes</dt>
3670
+ * <dd>An object literal containing additional attributes to add to
3671
+ * the link tags</dd>
3672
+ * </dl>
3673
+ * <pre>
3674
+ * Y.Get.css("http://localhost/css/menu.css");
3675
+ * </pre>
3676
+ * <pre>
3677
+ * &nbsp; Y.Get.css(
3678
+ * &nbsp; ["http://localhost/css/menu.css",
3679
+ * &nbsp; "http://localhost/css/logger.css"], &#123;
3680
+ * &nbsp; insertBefore: 'custom-styles' // nodes will be inserted
3681
+ * &nbsp; // before the specified node
3682
+ * &nbsp; &#125;);.
3683
+ * </pre>
3684
+ * @return {tId: string} an object containing info about the
3685
+ * transaction.
3686
+ */
3687
+ css: function(url, opts) {
3688
+ return _queue('css', url, opts);
3689
+ }
3690
+ };
3691
+ }();
3692
+
3693
+
3694
+
3695
+ }, '3.3.0' ,{requires:['yui-base']});
3696
+ YUI.add('features', function(Y) {
3697
+
3698
+ var feature_tests = {};
3699
+
3700
+ Y.mix(Y.namespace('Features'), {
3701
+
3702
+ tests: feature_tests,
3703
+
3704
+ add: function(cat, name, o) {
3705
+ feature_tests[cat] = feature_tests[cat] || {};
3706
+ feature_tests[cat][name] = o;
3707
+ },
3708
+
3709
+ all: function(cat, args) {
3710
+ var cat_o = feature_tests[cat],
3711
+ // results = {};
3712
+ result = '';
3713
+ if (cat_o) {
3714
+ Y.Object.each(cat_o, function(v, k) {
3715
+ // results[k] = Y.Features.test(cat, k, args);
3716
+ result += k + ':' +
3717
+ (Y.Features.test(cat, k, args) ? 1 : 0) + ';';
3718
+ });
3719
+ }
3720
+
3721
+ return result;
3722
+ },
3723
+
3724
+ test: function(cat, name, args) {
3725
+ args = args || [];
3726
+ var result, ua, test,
3727
+ cat_o = feature_tests[cat],
3728
+ feature = cat_o && cat_o[name];
3729
+
3730
+ if (!feature) {
3731
+ Y.log('Feature test ' + cat + ', ' + name + ' not found');
3732
+ } else {
3733
+
3734
+ result = feature.result;
3735
+
3736
+ if (Y.Lang.isUndefined(result)) {
3737
+
3738
+ ua = feature.ua;
3739
+ if (ua) {
3740
+ result = (Y.UA[ua]);
3741
+ }
3742
+
3743
+ test = feature.test;
3744
+ if (test && ((!ua) || result)) {
3745
+ result = test.apply(Y, args);
3746
+ }
3747
+
3748
+ feature.result = result;
3749
+ }
3750
+ }
3751
+
3752
+ return result;
3753
+ }
3754
+ });
3755
+
3756
+ // Y.Features.add("load", "1", {});
3757
+ // Y.Features.test("load", "1");
3758
+ // caps=1:1;2:0;3:1;
3759
+
3760
+ /* This file is auto-generated by src/loader/meta_join.py */
3761
+ var add = Y.Features.add;
3762
+ // autocomplete-list-keys-sniff.js
3763
+ add('load', '0', {
3764
+ "test": function (Y) {
3765
+ // Only add keyboard support to autocomplete-list if this doesn't appear to
3766
+ // be an iOS or Android-based mobile device.
3767
+ //
3768
+ // There's currently no feasible way to actually detect whether a device has
3769
+ // a hardware keyboard, so this sniff will have to do. It can easily be
3770
+ // overridden by manually loading the autocomplete-list-keys module.
3771
+ //
3772
+ // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
3773
+ // doesn't fire the keyboard events used by AutoCompleteList, so there's
3774
+ // no point loading the -keys module even when a bluetooth keyboard may be
3775
+ // available.
3776
+ return !(Y.UA.ios || Y.UA.android);
3777
+ },
3778
+ "trigger": "autocomplete-list"
3779
+ });
3780
+ // ie-style-test.js
3781
+ add('load', '1', {
3782
+ "test": function (Y) {
3783
+
3784
+ var testFeature = Y.Features.test,
3785
+ addFeature = Y.Features.add,
3786
+ WINDOW = Y.config.win,
3787
+ DOCUMENT = Y.config.doc,
3788
+ DOCUMENT_ELEMENT = 'documentElement',
3789
+ ret = false;
3790
+
3791
+ addFeature('style', 'computedStyle', {
3792
+ test: function() {
3793
+ return WINDOW && 'getComputedStyle' in WINDOW;
3794
+ }
3795
+ });
3796
+
3797
+ addFeature('style', 'opacity', {
3798
+ test: function() {
3799
+ return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
3800
+ }
3801
+ });
3802
+
3803
+ ret = (!testFeature('style', 'opacity') &&
3804
+ !testFeature('style', 'computedStyle'));
3805
+
3806
+ return ret;
3807
+ },
3808
+ "trigger": "dom-style"
3809
+ });
3810
+ // 0
3811
+ add('load', '2', {
3812
+ "trigger": "widget-base",
3813
+ "ua": "ie"
3814
+ });
3815
+ // ie-base-test.js
3816
+ add('load', '3', {
3817
+ "test": function(Y) {
3818
+ var imp = Y.config.doc && Y.config.doc.implementation;
3819
+ return (imp && (!imp.hasFeature('Events', '2.0')));
3820
+ },
3821
+ "trigger": "node-base"
3822
+ });
3823
+ // dd-gestures-test.js
3824
+ add('load', '4', {
3825
+ "test": function(Y) {
3826
+ return (Y.config.win && ('ontouchstart' in Y.config.win && !Y.UA.chrome));
3827
+ },
3828
+ "trigger": "dd-drag"
3829
+ });
3830
+ // history-hash-ie-test.js
3831
+ add('load', '5', {
3832
+ "test": function (Y) {
3833
+ var docMode = Y.config.doc.documentMode;
3834
+
3835
+ return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
3836
+ !docMode || docMode < 8);
3837
+ },
3838
+ "trigger": "history-hash"
3839
+ });
3840
+
3841
+
3842
+ }, '3.3.0' ,{requires:['yui-base']});
3843
+ YUI.add('rls', function(Y) {
3844
+
3845
+ /**
3846
+ * Implentation for building the remote loader service url.
3847
+ * @method _rls
3848
+ * @param {Array} what the requested modules.
3849
+ * @since 3.2.0
3850
+ * @return {string} the url for the remote loader service call.
3851
+ */
3852
+ Y._rls = function(what) {
3853
+
3854
+ var config = Y.config,
3855
+
3856
+ // the configuration
3857
+ rls = config.rls || {
3858
+ m: 1, // required in the template
3859
+ v: Y.version,
3860
+ gv: config.gallery,
3861
+ env: 1, // required in the template
3862
+ lang: config.lang,
3863
+ '2in3v': config['2in3'],
3864
+ '2v': config.yui2,
3865
+ filt: config.filter,
3866
+ filts: config.filters,
3867
+ tests: 1 // required in the template
3868
+ },
3869
+
3870
+ // The rls base path
3871
+ rls_base = config.rls_base || 'load?',
3872
+
3873
+ // the template
3874
+ rls_tmpl = config.rls_tmpl || function() {
3875
+ var s = '', param;
3876
+ for (param in rls) {
3877
+ if (param in rls && rls[param]) {
3878
+ s += param + '={' + param + '}&';
3879
+ }
3880
+ }
3881
+ // console.log('rls_tmpl: ' + s);
3882
+ return s;
3883
+ }(),
3884
+
3885
+ url;
3886
+
3887
+ // update the request
3888
+ rls.m = what;
3889
+ rls.env = Y.Object.keys(YUI.Env.mods);
3890
+ rls.tests = Y.Features.all('load', [Y]);
3891
+
3892
+ url = Y.Lang.sub(rls_base + rls_tmpl, rls);
3893
+
3894
+ config.rls = rls;
3895
+ config.rls_tmpl = rls_tmpl;
3896
+
3897
+ // console.log(url);
3898
+ return url;
3899
+ };
3900
+
3901
+
3902
+
3903
+ }, '3.3.0' ,{requires:['get','features']});
3904
+ YUI.add('intl-base', function(Y) {
3905
+
3906
+ /**
3907
+ * The Intl utility provides a central location for managing sets of
3908
+ * localized resources (strings and formatting patterns).
3909
+ *
3910
+ * @class Intl
3911
+ * @uses EventTarget
3912
+ * @static
3913
+ */
3914
+
3915
+ var SPLIT_REGEX = /[, ]/;
3916
+
3917
+ Y.mix(Y.namespace('Intl'), {
3918
+
3919
+ /**
3920
+ * Returns the language among those available that
3921
+ * best matches the preferred language list, using the Lookup
3922
+ * algorithm of BCP 47.
3923
+ * If none of the available languages meets the user's preferences,
3924
+ * then "" is returned.
3925
+ * Extended language ranges are not supported.
3926
+ *
3927
+ * @method lookupBestLang
3928
+ * @param {String[] | String} preferredLanguages The list of preferred
3929
+ * languages in descending preference order, represented as BCP 47
3930
+ * language tags. A string array or a comma-separated list.
3931
+ * @param {String[]} availableLanguages The list of languages
3932
+ * that the application supports, represented as BCP 47 language
3933
+ * tags.
3934
+ *
3935
+ * @return {String} The available language that best matches the
3936
+ * preferred language list, or "".
3937
+ * @since 3.1.0
3938
+ */
3939
+ lookupBestLang: function(preferredLanguages, availableLanguages) {
3940
+
3941
+ var i, language, result, index;
3942
+
3943
+ // check whether the list of available languages contains language;
3944
+ // if so return it
3945
+ function scan(language) {
3946
+ var i;
3947
+ for (i = 0; i < availableLanguages.length; i += 1) {
3948
+ if (language.toLowerCase() ===
3949
+ availableLanguages[i].toLowerCase()) {
3950
+ return availableLanguages[i];
3951
+ }
3952
+ }
3953
+ }
3954
+
3955
+ if (Y.Lang.isString(preferredLanguages)) {
3956
+ preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
3957
+ }
3958
+
3959
+ for (i = 0; i < preferredLanguages.length; i += 1) {
3960
+ language = preferredLanguages[i];
3961
+ if (!language || language === '*') {
3962
+ continue;
3963
+ }
3964
+ // check the fallback sequence for one language
3965
+ while (language.length > 0) {
3966
+ result = scan(language);
3967
+ if (result) {
3968
+ return result;
3969
+ } else {
3970
+ index = language.lastIndexOf('-');
3971
+ if (index >= 0) {
3972
+ language = language.substring(0, index);
3973
+ // one-character subtags get cut along with the
3974
+ // following subtag
3975
+ if (index >= 2 && language.charAt(index - 2) === '-') {
3976
+ language = language.substring(0, index - 2);
3977
+ }
3978
+ } else {
3979
+ // nothing available for this language
3980
+ break;
3981
+ }
3982
+ }
3983
+ }
3984
+ }
3985
+
3986
+ return '';
3987
+ }
3988
+ });
3989
+
3990
+
3991
+ }, '3.3.0' ,{requires:['yui-base']});
3992
+ YUI.add('yui-log', function(Y) {
3993
+
3994
+ /**
3995
+ * Provides console log capability and exposes a custom event for
3996
+ * console implementations.
3997
+ * @module yui
3998
+ * @submodule yui-log
3999
+ */
4000
+
4001
+ var INSTANCE = Y,
4002
+ LOGEVENT = 'yui:log',
4003
+ UNDEFINED = 'undefined',
4004
+ LEVELS = { debug: 1,
4005
+ info: 1,
4006
+ warn: 1,
4007
+ error: 1 };
4008
+
4009
+ /**
4010
+ * If the 'debug' config is true, a 'yui:log' event will be
4011
+ * dispatched, which the Console widget and anything else
4012
+ * can consume. If the 'useBrowserConsole' config is true, it will
4013
+ * write to the browser console if available. YUI-specific log
4014
+ * messages will only be present in the -debug versions of the
4015
+ * JS files. The build system is supposed to remove log statements
4016
+ * from the raw and minified versions of the files.
4017
+ *
4018
+ * @method log
4019
+ * @for YUI
4020
+ * @param {String} msg The message to log.
4021
+ * @param {String} cat The log category for the message. Default
4022
+ * categories are "info", "warn", "error", time".
4023
+ * Custom categories can be used as well. (opt).
4024
+ * @param {String} src The source of the the message (opt).
4025
+ * @param {boolean} silent If true, the log event won't fire.
4026
+ * @return {YUI} YUI instance.
4027
+ */
4028
+ INSTANCE.log = function(msg, cat, src, silent) {
4029
+ var bail, excl, incl, m, f,
4030
+ Y = INSTANCE,
4031
+ c = Y.config,
4032
+ publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
4033
+ // suppress log message if the config is off or the event stack
4034
+ // or the event call stack contains a consumer of the yui:log event
4035
+ if (c.debug) {
4036
+ // apply source filters
4037
+ if (src) {
4038
+ excl = c.logExclude;
4039
+ incl = c.logInclude;
4040
+ if (incl && !(src in incl)) {
4041
+ bail = 1;
4042
+ } else if (excl && (src in excl)) {
4043
+ bail = 1;
4044
+ }
4045
+ }
4046
+ if (!bail) {
4047
+ if (c.useBrowserConsole) {
4048
+ m = (src) ? src + ': ' + msg : msg;
4049
+ if (Y.Lang.isFunction(c.logFn)) {
4050
+ c.logFn.call(Y, msg, cat, src);
4051
+ } else if (typeof console != UNDEFINED && console.log) {
4052
+ f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
4053
+ console[f](m);
4054
+ } else if (typeof opera != UNDEFINED) {
4055
+ opera.postError(m);
4056
+ }
4057
+ }
4058
+
4059
+ if (publisher && !silent) {
4060
+
4061
+ if (publisher == Y && (!publisher.getEvent(LOGEVENT))) {
4062
+ publisher.publish(LOGEVENT, {
4063
+ broadcast: 2
4064
+ });
4065
+ }
4066
+
4067
+ publisher.fire(LOGEVENT, {
4068
+ msg: msg,
4069
+ cat: cat,
4070
+ src: src
4071
+ });
4072
+ }
4073
+ }
4074
+ }
4075
+
4076
+ return Y;
4077
+ };
4078
+
4079
+ /**
4080
+ * Write a system message. This message will be preserved in the
4081
+ * minified and raw versions of the YUI files, unlike log statements.
4082
+ * @method message
4083
+ * @for YUI
4084
+ * @param {String} msg The message to log.
4085
+ * @param {String} cat The log category for the message. Default
4086
+ * categories are "info", "warn", "error", time".
4087
+ * Custom categories can be used as well. (opt).
4088
+ * @param {String} src The source of the the message (opt).
4089
+ * @param {boolean} silent If true, the log event won't fire.
4090
+ * @return {YUI} YUI instance.
4091
+ */
4092
+ INSTANCE.message = function() {
4093
+ return INSTANCE.log.apply(INSTANCE, arguments);
4094
+ };
4095
+
4096
+
4097
+ }, '3.3.0' ,{requires:['yui-base']});
4098
+ YUI.add('yui-later', function(Y) {
4099
+
4100
+ /**
4101
+ * Provides a setTimeout/setInterval wrapper
4102
+ * @module yui
4103
+ * @submodule yui-later
4104
+ */
4105
+
4106
+ /**
4107
+ * Executes the supplied function in the context of the supplied
4108
+ * object 'when' milliseconds later. Executes the function a
4109
+ * single time unless periodic is set to true.
4110
+ * @method later
4111
+ * @for YUI
4112
+ * @param when {int} the number of milliseconds to wait until the fn
4113
+ * is executed.
4114
+ * @param o the context object.
4115
+ * @param fn {Function|String} the function to execute or the name of
4116
+ * the method in the 'o' object to execute.
4117
+ * @param data [Array] data that is provided to the function. This
4118
+ * accepts either a single item or an array. If an array is provided,
4119
+ * the function is executed with one parameter for each array item.
4120
+ * If you need to pass a single array parameter, it needs to be wrapped
4121
+ * in an array [myarray].
4122
+ * @param periodic {boolean} if true, executes continuously at supplied
4123
+ * interval until canceled.
4124
+ * @return {object} a timer object. Call the cancel() method on this
4125
+ * object to stop the timer.
4126
+ */
4127
+ Y.later = function(when, o, fn, data, periodic) {
4128
+ when = when || 0;
4129
+
4130
+ var m = fn, f, id;
4131
+
4132
+ if (o && Y.Lang.isString(fn)) {
4133
+ m = o[fn];
4134
+ }
4135
+
4136
+ f = !Y.Lang.isUndefined(data) ? function() {
4137
+ m.apply(o, Y.Array(data));
4138
+ } : function() {
4139
+ m.call(o);
4140
+ };
4141
+
4142
+ id = (periodic) ? setInterval(f, when) : setTimeout(f, when);
4143
+
4144
+ return {
4145
+ id: id,
4146
+ interval: periodic,
4147
+ cancel: function() {
4148
+ if (this.interval) {
4149
+ clearInterval(id);
4150
+ } else {
4151
+ clearTimeout(id);
4152
+ }
4153
+ }
4154
+ };
4155
+ };
4156
+
4157
+ Y.Lang.later = Y.later;
4158
+
4159
+
4160
+
4161
+ }, '3.3.0' ,{requires:['yui-base']});
4162
+ YUI.add('yui-throttle', function(Y) {
4163
+
4164
+ /**
4165
+ * Provides a throttle/limiter for function calls
4166
+ * @module yui
4167
+ * @submodule yui-throttle
4168
+ */
4169
+
4170
+ /*! Based on work by Simon Willison: http://gist.github.com/292562 */
4171
+ /**
4172
+ * Throttles a call to a method based on the time between calls.
4173
+ * @method throttle
4174
+ * @for YUI
4175
+ * @param fn {function} The function call to throttle.
4176
+ * @param ms {int} The number of milliseconds to throttle the method call.
4177
+ * Can set globally with Y.config.throttleTime or by call. Passing a -1 will
4178
+ * disable the throttle. Defaults to 150.
4179
+ * @return {function} Returns a wrapped function that calls fn throttled.
4180
+ * @since 3.1.0
4181
+ */
4182
+ Y.throttle = function(fn, ms) {
4183
+ ms = (ms) ? ms : (Y.config.throttleTime || 150);
4184
+
4185
+ if (ms === -1) {
4186
+ return (function() {
4187
+ fn.apply(null, arguments);
4188
+ });
4189
+ }
4190
+
4191
+ var last = Y.Lang.now();
4192
+
4193
+ return (function() {
4194
+ var now = Y.Lang.now();
4195
+ if (now - last > ms) {
4196
+ last = now;
4197
+ fn.apply(null, arguments);
4198
+ }
4199
+ });
4200
+ };
4201
+
4202
+
4203
+ }, '3.3.0' ,{requires:['yui-base']});
4204
+
4205
+
4206
+ YUI.add('yui', function(Y){}, '3.3.0' ,{use:['yui-base','get','features','rls','intl-base','yui-log','yui-later','yui-throttle']});
4207
+