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