3
Copyright 2011 Yahoo! Inc. All rights reserved.
4
Licensed under the BSD License.
5
http://yuilibrary.com/license/
8
* The YUI module contains the components required for building the YUI seed
9
* file. This includes the script loading mechanism, a simple queue, and
10
* the core utilities for the library.
15
if (typeof YUI != 'undefined') {
20
The YUI global namespace object. If YUI is already defined, the
21
existing YUI object will not be overwritten so that defined
22
namespaces are preserved. It is the constructor for the object
23
the end user interacts with. As indicated below, each instance
24
has full custom event support, but only if the event system
25
is available. This is a self-instantiable factory function. You
26
can invoke it directly like this:
28
YUI().use('*', function(Y) {
32
But it also works like this:
40
@param o* {Object} 0..n optional configuration objects. these values
41
are store in Y.config. See <a href="config.html">Config</a> for the list of supported
46
var YUI = function() {
51
instanceOf = function(o, type) {
52
return (o && o.hasOwnProperty && (o instanceof type));
54
gconf = (typeof YUI_config !== 'undefined') && YUI_config;
56
if (!(instanceOf(Y, YUI))) {
59
// set up the core environment
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
@property GlobalConfig
77
YUI().use('node', function(Y) {
78
//debug files used here
83
}).use('node', function(Y) {
88
if (YUI.GlobalConfig) {
89
Y.applyConfig(YUI.GlobalConfig);
93
YUI_config is a page-level config. It is applied to all
94
instances created on the page. This is applied after
95
YUI.GlobalConfig, and before the instance level configuration
103
//Single global var to include before YUI seed file
108
YUI().use('node', function(Y) {
109
//debug files used here
114
}).use('node', function(Y) {
115
//min files used here
119
Y.applyConfig(gconf);
122
// bind the specified additional modules for this instance
129
// Each instance can accept one or more configuration objects.
130
// These are applied after YUI.GlobalConfig and YUI_Config,
131
// overriding values set in those config files if there is a '
132
// matching property.
134
Y.applyConfig(args[i]);
140
Y.instanceOf = instanceOf;
150
BASE = 'http://yui.yahooapis.com/',
151
DOC_LABEL = 'yui3-js-enabled',
152
NOOP = function() {},
153
SLICE = Array.prototype.slice,
154
APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo
155
'io.xdrResponse': 1, // can call. this should
156
'SWF.eventHandler': 1 }, // be done at build time
157
hasWin = (typeof window != 'undefined'),
158
win = (hasWin) ? window : null,
159
doc = (hasWin) ? win.document : null,
160
docEl = doc && doc.documentElement,
161
docClass = docEl && docEl.className,
163
time = new Date().getTime(),
164
add = function(el, type, fn, capture) {
165
if (el && el.addEventListener) {
166
el.addEventListener(type, fn, capture);
167
} else if (el && el.attachEvent) {
168
el.attachEvent('on' + type, fn);
171
remove = function(el, type, fn, capture) {
172
if (el && el.removeEventListener) {
173
// this can throw an uncaught exception in FF
175
el.removeEventListener(type, fn, capture);
177
} else if (el && el.detachEvent) {
178
el.detachEvent('on' + type, fn);
181
handleLoad = function() {
182
YUI.Env.windowLoaded = true;
183
YUI.Env.DOMReady = true;
185
remove(window, 'load', handleLoad);
188
getLoader = function(Y, o) {
189
var loader = Y.Env._loader;
191
//loader._config(Y.config);
192
loader.ignoreRegistered = false;
195
loader.required = [];
196
loader.loadType = null;
198
loader = new Y.Loader(Y.config);
199
Y.Env._loader = loader;
201
YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, [ 'loader-base', 'loader-rollup', 'loader-yui3' ]));
206
clobber = function(r, s) {
208
if (s.hasOwnProperty(i)) {
214
ALREADY_DONE = { success: true };
216
// Stamp the documentElement (HTML) with a class of "yui-loaded" to
217
// enable styles that need to key off of JS being enabled.
218
if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
222
docClass += DOC_LABEL;
223
docEl.className = docClass;
226
if (VERSION.indexOf('@') > -1) {
227
VERSION = '3.3.0'; // dev time hack for cdn test
232
* Applies a new configuration object to the YUI instance config.
233
* This will merge new group/module definitions, and will also
234
* update the loader cache if necessary. Updating Y.config directly
235
* will not update the cache.
236
* @method applyConfig
237
* @param {Object} o the configuration object.
240
applyConfig: function(o) {
247
config = this.config,
248
mods = config.modules,
249
groups = config.groups,
251
loader = this.Env._loader;
254
if (o.hasOwnProperty(name)) {
256
if (mods && name == 'modules') {
258
} else if (groups && name == 'groups') {
259
clobber(groups, attr);
260
} else if (rls && name == 'rls') {
262
} else if (name == 'win') {
263
config[name] = attr.contentWindow || attr;
264
config.doc = config[name].document;
265
} else if (name == '_yuid') {
278
* Old way to apply a config to the instance (calls `applyConfig` under the hood)
281
* @param {Object} o The config to apply
283
_config: function(o) {
288
* Initialize this YUI instance
300
* The version number of the YUI instance.
308
core: ['get','intl-base'],
309
mods: {}, // flat module map
310
versions: {}, // version module map
312
cdn: BASE + VERSION + '/build/',
313
// bootstrapped: false,
324
// I'll start at the \b(simpleyui).
325
// 1. Look in the test string for "simpleyui" or "yui" or
326
// "yui-base" or "yui-rls" or "yui-foobar" that comes after a word break. That is, it
327
// can't match "foyui" or "i_heart_simpleyui". This can be anywhere in the string.
328
// 2. After #1 must come a forward slash followed by the string matched in #1, so
329
// "yui-base/yui-base" or "simpleyui/simpleyui" or "yui-pants/yui-pants".
330
// 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
331
// so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
332
// 4. This is followed by ".js", so "yui/yui.js", "simpleyui/simpleyui-min.js"
333
// 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
334
// then capture the junk between the LAST "&" and the string in 1-4. So
335
// "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-rls/yui-rls.js"
336
// will capture "3.3.0/build/"
340
// (?:[^&]*&) followed by 0..n characters followed by an &
341
// * in fact, find as many sets of characters followed by a & as you can
342
// ([^&]*) capture the stuff after the last & in \1
343
// )? but it's ok if all this ?junk&more_junk stuff isn't even there
344
// \b(simpleyui| after a word break find either the string "simpleyui" or
345
// yui(?:-\w+)? the string "yui" optionally followed by a -, then more characters
346
// ) and store the simpleyui or yui-* string in \2
347
// \/\2 then comes a / followed by the simpleyui or yui-* string in \2
348
// (?:-(min|debug))? optionally followed by "-min" or "-debug"
349
// .js and ending in ".js"
350
_BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(simpleyui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
351
parseBasePath: function(src, pattern) {
352
var match = src.match(pattern),
356
path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
358
// this is to set up the path to the loader. The file
359
// filter for loader should match the yui include.
362
// extract correct path for mixed combo urls
363
// http://yuilibrary.com/projects/yui3/ticket/2528423
365
path += '?' + match[1];
374
getBase: G_ENV && G_ENV.getBase ||
376
var nodes = (doc && doc.getElementsByTagName('script')) || [],
377
path = Env.cdn, parsed,
380
for (i = 0, len = nodes.length; i < len; ++i) {
383
parsed = Y.Env.parseBasePath(src, pattern);
385
filter = parsed.filter;
400
Env._loaded[VERSION] = {};
402
if (G_ENV && Y !== YUI) {
403
Env._yidx = ++G_ENV._yidx;
404
Env._guidp = ('yui_' + VERSION + '_' +
405
Env._yidx + '_' + time).replace(/\./g, '_');
406
} else if (YUI._YUI) {
408
G_ENV = YUI._YUI.Env;
409
Env._yidx += G_ENV._yidx;
410
Env._uidx += G_ENV._uidx;
412
for (prop in G_ENV) {
413
if (!(prop in Env)) {
414
Env[prop] = G_ENV[prop];
428
// configuration defaults
429
Y.config = Y.config || {
433
useBrowserConsole: true,
442
if (YUI.Env.rls_disabled) {
443
Y.config.use_rls = false;
446
Y.config.lang = Y.config.lang || 'en-US';
448
Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
450
if (!filter || (!('mindebug').indexOf(filter))) {
453
filter = (filter) ? '-' + filter : filter;
454
Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
459
* Finishes the instance setup. Attaches whatever modules were defined
460
* when the yui modules was registered.
464
_setup: function(o) {
468
//extras = Y.config.core || ['get','intl-base'];
469
extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
471
for (i = 0; i < extras.length; i++) {
472
if (mods[extras[i]]) {
473
core.push(extras[i]);
477
Y._attach(['yui-base']);
484
// Y.log(Y.id + ' initialized', 'info', 'yui');
488
* Executes a method on a YUI instance with
489
* the specified id if the specified method is whitelisted.
491
* @param id {String} the YUI instance id.
492
* @param method {String} the name of the method to exectute.
494
* @param args {Array} the arguments to apply to the method.
495
* @return {Object} the return value from the applied method or null.
497
applyTo: function(id, method, args) {
498
if (!(method in APPLY_TO_AUTH)) {
499
this.log(method + ': applyTo not allowed', 'warn', 'yui');
503
var instance = instances[id], nest, m, i;
505
nest = method.split('.');
507
for (i = 0; i < nest.length; i = i + 1) {
510
this.log('applyTo not found: ' + method, 'warn', 'yui');
513
return m.apply(instance, args);
520
Registers a module with the YUI global. The easiest way to create a
521
first-class YUI module is to use the YUI component build tool.
523
http://yuilibrary.com/projects/builder
525
The build system will produce the `YUI.add` wrapper for you module, along
526
with any configuration info required for the module.
528
@param name {String} module name.
529
@param fn {Function} entry point into the module that is used to bind module to the YUI instance.
530
@param {YUI} fn.Y The YUI instance this module is executed in.
531
@param {String} fn.name The name of the module
532
@param version {String} version string.
533
@param details {Object} optional config data:
534
@param details.requires {Array} features that must be present before this module can be attached.
535
@param details.optional {Array} optional features that should be present if loadOptional
536
is defined. Note: modules are not often loaded this way in YUI 3,
537
but this field is still useful to inform the user that certain
538
features in the component will require additional dependencies.
539
@param details.use {Array} features that are included within this module which need to
540
be attached automatically when this module is attached. This
541
supports the YUI 3 rollup system -- a module with submodules
542
defined will need to have the submodules listed in the 'use'
543
config. The YUI component build tool does this for you.
544
@return {YUI} the YUI instance.
547
YUI.add('davglass', function(Y, name) {
548
Y.davglass = function() {
549
alert('Dav was here!');
551
}, '3.4.0', { requires: ['yui-base', 'harley-davidson', 'mt-dew'] });
554
add: function(name, fn, version, details) {
555
details = details || {};
564
i, versions = env.versions;
566
env.mods[name] = mod;
567
versions[version] = versions[version] || {};
568
versions[version][name] = mod;
570
for (i in instances) {
571
if (instances.hasOwnProperty(i)) {
572
loader = instances[i].Env._loader;
574
if (!loader.moduleInfo[name]) {
575
loader.addModule(details, name);
585
* Executes the function associated with each required
586
* module, binding the module to the YUI instance.
587
* @param {Array} r The array of modules to attach
588
* @param {Boolean} [moot=false] Don't throw a warning if the module is not attached
592
_attach: function(r, moot) {
593
var i, name, mod, details, req, use, after,
595
aliases = YUI.Env.aliases,
597
loader = Y.Env._loader,
598
done = Y.Env._attached,
599
len = r.length, loader,
602
//Check for conditional modules (in a second+ instance) and add their requirements
603
//TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
604
for (i = 0; i < len; i++) {
608
if (loader && loader.conditions[name]) {
609
Y.Object.each(loader.conditions[name], function(def) {
610
var go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
620
for (i = 0; i < len; i++) {
625
if (aliases && aliases[name]) {
626
Y._attach(aliases[name]);
630
if (loader && loader.moduleInfo[name]) {
631
mod = loader.moduleInfo[name];
635
// Y.log('no js def for: ' + name, 'info', 'yui');
637
//if (!loader || !loader.moduleInfo[name]) {
638
//if ((!loader || !loader.moduleInfo[name]) && !moot) {
640
if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
641
Y.Env._missed.push(name);
642
Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
643
Y.message('NOT loaded: ' + name, 'warn', 'yui');
648
//Don't like this, but in case a mod was asked for once, then we fetch it
649
//We need to remove it from the missed list ^davglass
650
for (j = 0; j < Y.Env._missed.length; j++) {
651
if (Y.Env._missed[j] === name) {
652
Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
653
Y.Env._missed.splice(j, 1);
656
details = mod.details;
657
req = details.requires;
659
after = details.after;
662
for (j = 0; j < req.length; j++) {
664
if (!Y._attach(req)) {
673
for (j = 0; j < after.length; j++) {
674
if (!done[after[j]]) {
675
if (!Y._attach(after, true)) {
687
Y.error('Attach error: ' + name, e, name);
693
for (j = 0; j < use.length; j++) {
695
if (!Y._attach(use)) {
713
* Attaches one or more modules to the YUI instance. When this
714
* is executed, the requirements are analyzed, and one of
715
* several things can happen:
717
* * All requirements are available on the page -- The modules
718
* are attached to the instance. If supplied, the use callback
719
* is executed synchronously.
721
* * Modules are missing, the Get utility is not available OR
722
* the 'bootstrap' config is false -- A warning is issued about
723
* the missing modules and all available modules are attached.
725
* * Modules are missing, the Loader is not available but the Get
726
* utility is and boostrap is not false -- The loader is bootstrapped
727
* before doing the following....
729
* * Modules are missing and the Loader is available -- The loader
730
* expands the dependency tree and fetches missing modules. When
731
* the loader is finshed the callback supplied to use is executed
735
* @param modules* {String} 1-n modules to bind (uses arguments array).
736
* @param *callback {Function} callback function executed when
737
* the instance has the required functionality. If included, it
738
* must be the last parameter.
741
* // loads and attaches dd and its dependencies
742
* YUI().use('dd', function(Y) {});
744
* // loads and attaches dd and node as well as all of their dependencies (since 3.4.0)
745
* YUI().use(['dd', 'node'], function(Y) {});
747
* // attaches all modules that are available on the page
748
* YUI().use('*', function(Y) {});
750
* // intrinsic YUI gallery support (since 3.1.0)
751
* YUI().use('gallery-yql', function(Y) {});
753
* // intrinsic YUI 2in3 support (since 3.1.0)
754
* YUI().use('yui2-datatable', function(Y) {});
756
* @return {YUI} the YUI instance.
759
var args = SLICE.call(arguments, 0),
760
callback = args[args.length - 1],
767
// The last argument supplied to use can be a load complete callback
768
if (Y.Lang.isFunction(callback)) {
773
if (Y.Lang.isArray(args[0])) {
777
if (Y.config.cacheUse) {
778
while ((name = args[i++])) {
779
if (!Env._attached[name]) {
787
Y.log('already provisioned: ' + args, 'info', 'yui');
789
Y._notify(callback, ALREADY_DONE, args);
795
Y._useQueue = Y._useQueue || new Y.Queue();
796
Y._useQueue.add([args, callback]);
798
Y._use(args, function(Y, response) {
799
Y._notify(callback, response, args);
806
* Notify handler from Loader for attachment/load errors
808
* @param callback {Function} The callback to pass to the `Y.config.loadErrorFn`
809
* @param response {Object} The response returned from Loader
810
* @param args {Array} The aruments passed from Loader
813
_notify: function(callback, response, args) {
814
if (!response.success && this.config.loadErrorFn) {
815
this.config.loadErrorFn.call(this, this, callback, response, args);
816
} else if (callback) {
818
callback(this, response);
820
this.error('use callback error', e, args);
826
* This private method is called from the `use` method queue. To ensure that only one set of loading
827
* logic is performed at a time.
830
* @param args* {String} 1-n modules to bind (uses arguments array).
831
* @param *callback {Function} callback function executed when
832
* the instance has the required functionality. If included, it
833
* must be the last parameter.
835
_use: function(args, callback) {
838
this._attach(['yui-base']);
841
var len, loader, handleBoot, handleRLS,
847
queue = G_ENV._loaderQueue,
851
boot = config.bootstrap,
855
fetchCSS = config.fetchCSS,
856
process = function(names, skip) {
862
YArray.each(names, function(name) {
864
// add this module to full list of things to attach
869
// only attach a module once
874
var m = mods[name], req, use;
878
req = m.details.requires;
881
// CSS files don't register themselves, see if it has
883
if (!G_ENV._loaded[VERSION][name]) {
886
used[name] = true; // probably css
890
// make sure requirements are attached
891
if (req && req.length) {
895
// make sure we grab the submodule dependencies too
896
if (use && use.length) {
902
handleLoader = function(fromLoader) {
903
var response = fromLoader || {
909
data = response.data;
915
origMissing = missing;
919
redo = missing.length;
921
if (missing.sort().join() ==
922
origMissing.sort().join()) {
930
Y._use(args, function() {
931
Y.log('Nested use callback: ' + data, 'info', 'yui');
932
if (Y._attach(data)) {
933
Y._notify(callback, response, data);
938
// Y.log('attaching from loader: ' + data, 'info', 'yui');
939
ret = Y._attach(data);
942
Y._notify(callback, response, args);
946
if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
947
Y._use.apply(Y, Y._useQueue.next());
952
// Y.log(Y.id + ': use called: ' + a + ' :: ' + callback, 'info', 'yui');
954
// YUI().use('*'); // bind everything available
955
if (firstArg === '*') {
956
ret = Y._attach(Y.Object.keys(mods));
963
// Y.log('before loader requirements: ' + args, 'info', 'yui');
965
// use loader to expand dependencies and sort the
966
// requirements if it is available.
967
if (boot && Y.Loader && args.length) {
968
loader = getLoader(Y);
969
loader.require(args);
970
loader.ignoreRegistered = true;
971
loader.calculate(null, (fetchCSS) ? null : 'js');
972
args = loader.sorted;
975
// process each requirement and any additional requirements
976
// the module metadata specifies
979
len = missing.length;
982
missing = Y.Object.keys(YArray.hash(missing));
983
len = missing.length;
984
Y.log('Modules missing: ' + missing + ', ' + missing.length, 'info', 'yui');
989
if (boot && len && Y.Loader) {
990
// Y.log('Using loader to fetch missing deps: ' + missing, 'info', 'yui');
991
Y.log('Using Loader', 'info', 'yui');
993
loader = getLoader(Y);
994
loader.onEnd = handleLoader;
997
loader.ignoreRegistered = false;
998
loader.require(args);
999
loader.insert(null, (fetchCSS) ? null : 'js');
1000
// loader.partial(missing, (fetchCSS) ? null : 'js');
1002
} else if (len && Y.config.use_rls && !YUI.Env.rls_enabled) {
1004
G_ENV._rls_queue = G_ENV._rls_queue || new Y.Queue();
1006
// server side loader service
1007
handleRLS = function(instance, argz) {
1009
var rls_end = function(o) {
1011
instance.rls_advance();
1013
rls_url = instance._rls(argz);
1016
Y.log('Fetching RLS url', 'info', 'rls');
1017
instance.rls_oncomplete(function(o) {
1020
instance.Get.script(rls_url, {
1022
timeout: instance.config.rls_timeout,
1023
onFailure: instance.rls_handleFailure,
1024
onTimeout: instance.rls_handleTimeout
1034
G_ENV._rls_queue.add(function() {
1035
Y.log('executing queued rls request', 'info', 'rls');
1036
G_ENV._rls_in_progress = true;
1037
Y.rls_callback = callback;
1038
Y.rls_locals(Y, args, handleRLS);
1041
if (!G_ENV._rls_in_progress && G_ENV._rls_queue.size()) {
1042
G_ENV._rls_queue.next()();
1045
} else if (boot && len && Y.Get && !Env.bootstrapped) {
1049
handleBoot = function() {
1051
queue.running = false;
1052
Env.bootstrapped = true;
1053
G_ENV._bootstrapping = false;
1054
if (Y._attach(['loader'])) {
1055
Y._use(args, callback);
1059
if (G_ENV._bootstrapping) {
1060
Y.log('Waiting for loader', 'info', 'yui');
1061
queue.add(handleBoot);
1063
G_ENV._bootstrapping = true;
1064
Y.log('Fetching loader: ' + config.base + config.loaderPath, 'info', 'yui');
1065
Y.Get.script(config.base + config.loaderPath, {
1071
Y.log('Attaching available dependencies: ' + args, 'info', 'yui');
1072
ret = Y._attach(args);
1083
Adds a namespace object onto the YUI global if called statically.
1085
// creates YUI.your.namespace.here as nested objects
1086
YUI.namespace("your.namespace.here");
1088
If called as a method on a YUI <em>instance</em>, it creates the
1089
namespace on the instance.
1091
// creates Y.property.package
1092
Y.namespace("property.package");
1094
Dots in the input string cause `namespace` to create nested objects for
1095
each token. If any part of the requested namespace already exists, the
1096
current object will be left in place. This allows multiple calls to
1097
`namespace` to preserve existing namespaced properties.
1099
If the first token in the namespace string is "YAHOO", the token is
1102
Be careful with namespace tokens. Reserved words may work in some browsers
1103
and not others. For instance, the following will fail in some browsers
1104
because the supported version of JavaScript reserves the word "long":
1106
Y.namespace("really.long.nested.namespace");
1109
@param {String} namespace* namespaces to create.
1110
@return {Object} A reference to the last namespace object created.
1112
namespace: function() {
1113
var a = arguments, o = this, i = 0, j, d, arg;
1114
for (; i < a.length; i++) {
1115
// d = ('' + a[i]).split('.');
1117
if (arg.indexOf(PERIOD)) {
1118
d = arg.split(PERIOD);
1119
for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1120
o[d[j]] = o[d[j]] || {};
1124
o[arg] = o[arg] || {};
1130
// this is replaced if the log module is included
1133
// this is replaced if the dump module is included
1134
dump: function (o) { return ''+o; },
1137
* Report an error. The reporting mechanism is controled by
1138
* the `throwFail` configuration attribute. If throwFail is
1139
* not specified, the message is written to the Logger, otherwise
1140
* a JS error is thrown
1142
* @param msg {String} the error message.
1143
* @param e {Error|String} Optional JS error that was caught, or an error string.
1144
* @param data Optional additional info
1145
* and `throwFail` is specified, this error will be re-thrown.
1146
* @return {YUI} this YUI instance.
1148
error: function(msg, e, data) {
1152
if (Y.config.errorFn) {
1153
ret = Y.config.errorFn.apply(Y, arguments);
1156
if (Y.config.throwFail && !ret) {
1157
throw (e || new Error(msg));
1159
Y.message(msg, 'error'); // don't scrub this one
1166
* Generate an id that is unique among all YUI instances
1168
* @param pre {String} optional guid prefix.
1169
* @return {String} the guid.
1171
guid: function(pre) {
1172
var id = this.Env._guidp + '_' + (++this.Env._uidx);
1173
return (pre) ? (pre + id) : id;
1177
* Returns a `guid` associated with an object. If the object
1178
* does not have one, a new one is created unless `readOnly`
1181
* @param o {Object} The object to stamp.
1182
* @param readOnly {Boolean} if `true`, a valid guid will only
1183
* be returned if the object has one assigned to it.
1184
* @return {String} The object's guid or null.
1186
stamp: function(o, readOnly) {
1192
// IE generates its own unique ID for dom nodes
1193
// The uniqueID property of a document node returns a new ID
1194
if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1197
uid = (typeof o === 'string') ? o : o._yuid;
1214
* Destroys the YUI instance
1218
destroy: function() {
1223
delete instances[Y.id];
1229
* instanceof check for objects that works around
1230
* memory leak in IE when the item tested is
1232
* @method instanceOf
1239
YUI.prototype = proto;
1241
// inheritance utilities are not available yet
1242
for (prop in proto) {
1243
if (proto.hasOwnProperty(prop)) {
1244
YUI[prop] = proto[prop];
1248
// set up the environment
1252
// add a window load event at load time so we can capture
1253
// the case where it fires before dynamic loading is
1255
add(window, 'load', handleLoad);
1261
YUI.Env.remove = remove;
1264
// Support the CommonJS method for exporting our single global
1265
if (typeof exports == 'object') {
1273
* The config object contains all of the configuration options for
1274
* the `YUI` instance. This object is supplied by the implementer
1275
* when instantiating a `YUI` instance. Some properties have default
1276
* values if they are not supplied by the implementer. This should
1277
* not be updated directly because some values are cached. Use
1278
* `applyConfig()` to update the config object on a YUI instance that
1279
* has already been configured.
1286
* Allows the YUI seed file to fetch the loader component and library
1287
* metadata to dynamically load additional dependencies.
1289
* @property bootstrap
1295
* Log to the browser console if debug is on and the browser has a
1296
* supported console.
1298
* @property useBrowserConsole
1304
* A hash of log sources that should be logged. If specified, only
1305
* log messages from these sources will be logged.
1307
* @property logInclude
1312
* A hash of log sources that should be not be logged. If specified,
1313
* all sources are logged if not on this list.
1315
* @property logExclude
1320
* Set to true if the yui seed file was dynamically loaded in
1321
* order to bootstrap components relying on the window load event
1322
* and the `domready` custom event.
1324
* @property injected
1330
* If `throwFail` is set, `Y.error` will generate or re-throw a JS Error.
1331
* Otherwise the failure is logged.
1333
* @property throwFail
1339
* The window/frame that this instance should operate in.
1343
* @default the window hosting YUI
1347
* The document associated with the 'win' configuration.
1351
* @default the document hosting YUI
1355
* A list of modules that defines the YUI core (overrides the default).
1362
* A list of languages in order of preference. This list is matched against
1363
* the list of available languages in modules that the YUI instance uses to
1364
* determine the best possible localization of language sensitive modules.
1365
* Languages are represented using BCP 47 language tags, such as "en-GB" for
1366
* English as used in the United Kingdom, or "zh-Hans-CN" for simplified
1367
* Chinese as used in China. The list can be provided as a comma-separated
1368
* list or as an array.
1371
* @type string|string[]
1375
* The default date format
1376
* @property dateFormat
1378
* @deprecated use configuration in `DataType.Date.format()` instead.
1382
* The default locale
1385
* @deprecated use `config.lang` instead.
1389
* The default interval when polling in milliseconds.
1390
* @property pollInterval
1396
* The number of dynamic nodes to insert by default before
1397
* automatically removing them. This applies to script nodes
1398
* because removing the node will not make the evaluated script
1399
* unavailable. Dynamic CSS is not auto purged, because removing
1400
* a linked style sheet will also remove the style definitions.
1401
* @property purgethreshold
1407
* The default interval when polling in milliseconds.
1408
* @property windowResizeDelay
1414
* Base directory for dynamic loading
1420
* The secure base dir (not implemented)
1421
* For dynamic loading.
1422
* @property secureBase
1427
* The YUI combo service base dir. Ex: `http://yui.yahooapis.com/combo?`
1428
* For dynamic loading.
1429
* @property comboBase
1434
* The root path to prepend to module path for the combo service.
1435
* Ex: 3.0.0b1/build/
1436
* For dynamic loading.
1442
* A filter to apply to result urls. This filter will modify the default
1443
* path for all modules. The default path for the YUI library is the
1444
* minified version of the files (e.g., event-min.js). The filter property
1445
* can be a predefined filter or a custom filter. The valid predefined
1449
* <dd>Selects the debug versions of the library (e.g., event-debug.js).
1450
* This option will automatically include the Logger widget</dd>
1452
* <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
1454
* You can also define a custom filter, which must be an object literal
1455
* containing a search expression and a replace string:
1458
* 'searchExp': "-min\\.js",
1459
* 'replaceStr': "-debug.js"
1462
* For dynamic loading.
1465
* @type string|object
1469
* The `skin` config let's you configure application level skin
1470
* customizations. It contains the following attributes which
1471
* can be specified to override the defaults:
1473
* // The default skin, which is automatically applied if not
1474
* // overriden by a component-specific skin definition.
1475
* // Change this in to apply a different skin globally
1476
* defaultSkin: 'sam',
1478
* // This is combined with the loader base property to get
1479
* // the default root directory for a skin.
1480
* base: 'assets/skins/',
1482
* // Any component-specific overrides can be specified here,
1483
* // making it possible to load different skins for different
1484
* // components. It is possible to load more than one skin
1485
* // for a given component as well.
1487
* slider: ['capsule', 'round']
1490
* For dynamic loading.
1496
* Hash of per-component filter specification. If specified for a given
1497
* component, this overrides the filter config.
1499
* For dynamic loading.
1505
* Use the YUI combo service to reduce the number of http connections
1506
* required to load your dependencies. Turning this off will
1507
* disable combo handling for YUI and all module groups configured
1508
* with a combo service.
1510
* For dynamic loading.
1514
* @default true if 'base' is not supplied, false if it is.
1518
* A list of modules that should never be dynamically loaded
1525
* A list of modules that should always be loaded when required, even if already
1526
* present on the page.
1533
* Node or id for a node that should be used as the insertion point for new
1534
* nodes. For dynamic loading.
1536
* @property insertBefore
1541
* Object literal containing attributes to add to dynamically loaded script
1543
* @property jsAttributes
1548
* Object literal containing attributes to add to dynamically loaded link
1550
* @property cssAttributes
1555
* Number of milliseconds before a timeout occurs when dynamically
1556
* loading nodes. If not set, there is no timeout.
1562
* Callback for the 'CSSComplete' event. When dynamically loading YUI
1563
* components with CSS, this property fires when the CSS is finished
1564
* loading but script loading is still ongoing. This provides an
1565
* opportunity to enhance the presentation of a loading page a little
1566
* bit before the entire loading process is done.
1573
* A hash of module definitions to add to the list of YUI components.
1574
* These components can then be dynamically loaded side by side with
1575
* YUI via the `use()` method. This is a hash, the key is the module
1576
* name, and the value is an object literal specifying the metdata
1577
* for the module. See `Loader.addModule` for the supported module
1578
* metadata fields. Also see groups, which provides a way to
1579
* configure the base and combo spec for a set of modules.
1583
* requires: ['node'],
1584
* fullpath: 'http://myserver.mydomain.com/mymod1/mymod1.js'
1587
* requires: ['mymod1'],
1588
* fullpath: 'http://myserver.mydomain.com/mymod2/mymod2.js'
1597
* A hash of module group definitions. It for each group you
1598
* can specify a list of modules and the base path and
1599
* combo spec to use when dynamically loading the modules.
1603
* // specify whether or not this group has a combo service
1606
* // the base path for non-combo paths
1607
* base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1609
* // the path to the combo service
1610
* comboBase: 'http://yui.yahooapis.com/combo?',
1612
* // a fragment to prepend to the path attribute when
1613
* // when building combo urls
1614
* root: '2.8.0r4/build/',
1616
* // the module definitions
1619
* path: "yahoo-dom-event/yahoo-dom-event.js"
1622
* path: "animation/animation.js",
1623
* requires: ['yui2_yde']
1634
* The loader 'path' attribute to the loader itself. This is combined
1635
* with the 'base' attribute to dynamically load the loader component
1636
* when boostrapping with the get utility alone.
1638
* @property loaderPath
1640
* @default loader/loader-min.js
1644
* Specifies whether or not YUI().use(...) will attempt to load CSS
1645
* resources at all. Any truthy value will cause CSS dependencies
1646
* to load when fetching script. The special value 'force' will
1647
* cause CSS dependencies to be loaded even if no script is needed.
1649
* @property fetchCSS
1650
* @type boolean|string
1655
* The default gallery version to build gallery module urls
1662
* The default YUI 2 version to build yui2 module urls. This is for
1663
* intrinsic YUI 2 support via the 2in3 project. Also see the '2in3'
1664
* config for pulling different revisions of the wrapped YUI 2
1673
* The 2in3 project is a deployment of the various versions of YUI 2
1674
* deployed as first-class YUI 3 modules. Eventually, the wrapper
1675
* for the modules will change (but the underlying YUI 2 code will
1676
* be the same), and you can select a particular version of
1677
* the wrapper modules via this config.
1685
* Alternative console log function for use in environments without
1686
* a supported native console. The function is executed in the
1687
* YUI instance context.
1694
* A callback to execute when Y.error is called. It receives the
1695
* error message and an javascript error object if Y.error was
1696
* executed because a javascript error was caught. The function
1697
* is executed in the YUI instance context.
1705
* A callback to execute when the loader fails to load one or
1706
* more resource. This could be because of a script load
1707
* failure. It can also fail if a javascript module fails
1708
* to register itself, but only when the 'requireRegistration'
1709
* is true. If this function is defined, the use() callback will
1710
* only be called when the loader succeeds, otherwise it always
1711
* executes unless there was a javascript error when attaching
1715
* @property loadErrorFn
1720
* When set to true, the YUI loader will expect that all modules
1721
* it is responsible for loading will be first-class YUI modules
1722
* that register themselves with the YUI global. If this is
1723
* set to true, loader will fail if the module registration fails
1724
* to happen after the script is loaded.
1727
* @property requireRegistration
1733
* Cache serviced use() requests.
1735
* @property cacheUse
1738
* @deprecated no longer used
1742
* The parameter defaults for the remote loader service. **Requires the rls seed file.** The properties that are supported:
1744
* * `m`: comma separated list of module requirements. This
1745
* must be the param name even for custom implemetations.
1746
* * `v`: the version of YUI to load. Defaults to the version
1747
* of YUI that is being used.
1748
* * `gv`: the version of the gallery to load (see the gallery config)
1749
* * `env`: comma separated list of modules already on the page.
1750
* this must be the param name even for custom implemetations.
1751
* * `lang`: the languages supported on the page (see the lang config)
1752
* * `'2in3v'`: the version of the 2in3 wrapper to use (see the 2in3 config).
1753
* * `'2v'`: the version of yui2 to use in the yui 2in3 wrappers
1754
* * `filt`: a filter def to apply to the urls (see the filter config).
1755
* * `filts`: a list of custom filters to apply per module
1756
* * `tests`: this is a map of conditional module test function id keys
1757
* with the values of 1 if the test passes, 0 if not. This must be
1758
* the name of the querystring param in custom templates.
1766
* The base path to the remote loader service. **Requires the rls seed file.**
1769
* @property rls_base
1774
* The template to use for building the querystring portion
1775
* of the remote loader service url. The default is determined
1776
* by the rls config -- each property that has a value will be
1777
* represented. **Requires the rls seed file.**
1780
* @property rls_tmpl
1783
* m={m}&v={v}&env={env}&lang={lang}&filt={filt}&tests={tests}
1788
* Configure the instance to use a remote loader service instead of
1789
* the client loader. **Requires the rls seed file.**
1795
YUI.add('yui-base', function(Y) {
1800
* @submodule yui-base
1803
* The YUI module contains the components required for building the YUI
1804
* seed file. This includes the script loading mechanism, a simple queue,
1805
* and the core utilities for the library.
1807
* @submodule yui-base
1811
* Provides core language utilites and extensions used throughout YUI.
1817
var L = Y.Lang || (Y.Lang = {}),
1819
STRING_PROTO = String.prototype,
1820
TOSTRING = Object.prototype.toString,
1823
'undefined' : 'undefined',
1824
'number' : 'number',
1825
'boolean' : 'boolean',
1826
'string' : 'string',
1827
'[object Function]': 'function',
1828
'[object RegExp]' : 'regexp',
1829
'[object Array]' : 'array',
1830
'[object Date]' : 'date',
1831
'[object Error]' : 'error'
1834
SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
1835
TRIMREGEX = /^\s+|\s+$/g,
1837
// If either MooTools or Prototype is on the page, then there's a chance that we
1838
// can't trust "native" language features to actually be native. When this is
1839
// the case, we take the safe route and fall back to our own non-native
1842
unsafeNatives = win && !!(win.MooTools || win.Prototype);
1845
* Determines whether or not the provided item is an array.
1847
* Returns `false` for array-like collections such as the function `arguments`
1848
* collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
1849
* test for an array-like collection.
1852
* @param o The object to test.
1853
* @return {boolean} true if o is an array.
1856
L.isArray = (!unsafeNatives && Array.isArray) || function (o) {
1857
return L.type(o) === 'array';
1861
* Determines whether or not the provided item is a boolean.
1864
* @param o The object to test.
1865
* @return {boolean} true if o is a boolean.
1867
L.isBoolean = function(o) {
1868
return typeof o === 'boolean';
1873
* Determines whether or not the provided item is a function.
1874
* Note: Internet Explorer thinks certain functions are objects:
1878
* var obj = document.createElement("object");
1879
* Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1881
* var input = document.createElement("input"); // append to body
1882
* Y.Lang.isFunction(input.focus) // reports false in IE
1886
* You will have to implement additional tests if these functions
1890
* @method isFunction
1892
* @param o The object to test.
1893
* @return {boolean} true if o is a function.
1895
L.isFunction = function(o) {
1896
return L.type(o) === 'function';
1900
* Determines whether or not the supplied item is a date instance.
1903
* @param o The object to test.
1904
* @return {boolean} true if o is a date.
1906
L.isDate = function(o) {
1907
return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
1911
* Determines whether or not the provided item is null.
1914
* @param o The object to test.
1915
* @return {boolean} true if o is null.
1917
L.isNull = function(o) {
1922
* Determines whether or not the provided item is a legal number.
1925
* @param o The object to test.
1926
* @return {boolean} true if o is a number.
1928
L.isNumber = function(o) {
1929
return typeof o === 'number' && isFinite(o);
1933
* Determines whether or not the provided item is of type object
1934
* or function. Note that arrays are also objects, so
1935
* <code>Y.Lang.isObject([]) === true</code>.
1938
* @param o The object to test.
1939
* @param failfn {boolean} fail if the input is a function.
1940
* @return {boolean} true if o is an object.
1941
* @see isPlainObject
1943
L.isObject = function(o, failfn) {
1945
return (o && (t === 'object' ||
1946
(!failfn && (t === 'function' || L.isFunction(o))))) || false;
1950
* Determines whether or not the provided item is a string.
1953
* @param o The object to test.
1954
* @return {boolean} true if o is a string.
1956
L.isString = function(o) {
1957
return typeof o === 'string';
1961
* Determines whether or not the provided item is undefined.
1962
* @method isUndefined
1964
* @param o The object to test.
1965
* @return {boolean} true if o is undefined.
1967
L.isUndefined = function(o) {
1968
return typeof o === 'undefined';
1972
* Returns a string without any leading or trailing whitespace. If
1973
* the input is not a string, the input will be returned untouched.
1976
* @param s {string} the string to trim.
1977
* @return {string} the trimmed string.
1979
L.trim = STRING_PROTO.trim ? function(s) {
1980
return s && s.trim ? s.trim() : s;
1983
return s.replace(TRIMREGEX, '');
1990
* Returns a string without any leading whitespace.
1993
* @param s {string} the string to trim.
1994
* @return {string} the trimmed string.
1996
L.trimLeft = STRING_PROTO.trimLeft ? function (s) {
1997
return s.trimLeft();
1999
return s.replace(/^\s+/, '');
2003
* Returns a string without any trailing whitespace.
2006
* @param s {string} the string to trim.
2007
* @return {string} the trimmed string.
2009
L.trimRight = STRING_PROTO.trimRight ? function (s) {
2010
return s.trimRight();
2012
return s.replace(/\s+$/, '');
2016
* A convenience method for detecting a legitimate non-null value.
2017
* Returns false for null/undefined/NaN, true for other values,
2018
* including 0/false/''
2021
* @param o The item to test.
2022
* @return {boolean} true if it is not null/undefined/NaN || false.
2024
L.isValue = function(o) {
2031
case 'null': // fallthru
2042
* Returns a string representing the type of the item passed in.
2051
* <code>typeof HTMLElementCollection</code> returns function in Safari, but
2052
* <code>Y.type()</code> reports object, which could be a good thing --
2053
* but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2058
* @param o the item to test.
2059
* @return {string} the detected type.
2062
L.type = function(o) {
2063
return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2067
* Lightweight version of <code>Y.substitute</code>. Uses the same template
2068
* structure as <code>Y.substitute</code>, but doesn't support recursion,
2069
* auto-object coersion, or formats.
2071
* @param {string} s String to be modified.
2072
* @param {object} o Object containing replacement values.
2073
* @return {string} the substitute result.
2077
L.sub = function(s, o) {
2078
return s.replace ? s.replace(SUBREGEX, function (match, key) {
2079
return L.isUndefined(o[key]) ? match : o[key];
2084
* Returns the current time in milliseconds.
2087
* @return {Number} Current time in milliseconds.
2091
L.now = Date.now || function () {
2092
return new Date().getTime();
2100
Native = Array.prototype,
2102
hasOwn = Object.prototype.hasOwnProperty;
2105
Provides utility methods for working with arrays. Additional array helpers can
2106
be found in the `collection` and `array-extras` modules.
2108
`Y.Array(thing)` returns a native array created from _thing_. Depending on
2109
_thing_'s type, one of the following will happen:
2111
* Arrays are returned unmodified unless a non-zero _startIndex_ is
2113
* Array-like collections (see `Array.test()`) are converted to arrays.
2114
* For everything else, a new array is created with _thing_ as the sole
2117
Note: elements that are also collections, such as `<form>` and `<select>`
2118
elements, are not automatically converted to arrays. To force a conversion,
2119
pass `true` as the value of the _force_ parameter.
2123
@param {Any} thing The thing to arrayify.
2124
@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2125
collection, a subset of items starting at the specified index will be
2127
@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2128
array-like collection no matter what.
2129
@return {Array} A native array created from _thing_, according to the rules
2132
function YArray(thing, startIndex, force) {
2135
startIndex || (startIndex = 0);
2137
if (force || YArray.test(thing)) {
2138
// IE throws when trying to slice HTMLElement collections.
2140
return Native.slice.call(thing, startIndex);
2144
for (len = thing.length; startIndex < len; ++startIndex) {
2145
result.push(thing[startIndex]);
2158
Dedupes an array of strings, returning an array that's guaranteed to contain
2159
only one copy of a given string.
2161
This method differs from `Array.unique()` in that it's optimized for use only
2162
with strings, whereas `unique` may be used with other types (but is slower).
2163
Using `dedupe()` with non-string values may result in unexpected behavior.
2166
@param {String[]} array Array of strings to dedupe.
2167
@return {Array} Deduped copy of _array_.
2171
YArray.dedupe = function (array) {
2176
for (i = 0, len = array.length; i < len; ++i) {
2179
if (!hasOwn.call(hash, item)) {
2189
Executes the supplied function on each item in the array. This method wraps
2190
the native ES5 `Array.forEach()` method if available.
2193
@param {Array} array Array to iterate.
2194
@param {Function} fn Function to execute on each item in the array. The function
2195
will receive the following arguments:
2196
@param {Any} fn.item Current array item.
2197
@param {Number} fn.index Current array index.
2198
@param {Array} fn.array Array being iterated.
2199
@param {Object} [thisObj] `this` object to use when calling _fn_.
2200
@return {YUI} The YUI instance.
2203
YArray.each = YArray.forEach = Native.forEach ? function (array, fn, thisObj) {
2204
Native.forEach.call(array || [], fn, thisObj || Y);
2206
} : function (array, fn, thisObj) {
2207
for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2209
fn.call(thisObj || Y, array[i], i, array);
2224
Returns an object using the first array as keys and the second as values. If
2225
the second array is not provided, or if it doesn't contain the same number of
2226
values as the first array, then `true` will be used in place of the missing
2231
Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2232
// => {a: 'foo', b: 'bar', c: true}
2235
@param {String[]} keys Array of strings to use as keys.
2236
@param {Array} [values] Array to use as values.
2237
@return {Object} Hash using the first array as keys and the second as values.
2240
YArray.hash = function (keys, values) {
2242
vlen = (values && values.length) || 0,
2245
for (i = 0, len = keys.length; i < len; ++i) {
2247
hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2255
Returns the index of the first item in the array that's equal (using a strict
2256
equality check) to the specified _value_, or `-1` if the value isn't found.
2258
This method wraps the native ES5 `Array.indexOf()` method if available.
2261
@param {Array} array Array to search.
2262
@param {Any} value Value to search for.
2263
@return {Number} Index of the item strictly equal to _value_, or `-1` if not
2267
YArray.indexOf = Native.indexOf ? function (array, value) {
2268
// TODO: support fromIndex
2269
return Native.indexOf.call(array, value);
2270
} : function (array, value) {
2271
for (var i = 0, len = array.length; i < len; ++i) {
2272
if (i in array && array[i] === value) {
2281
Numeric sort convenience function.
2283
The native `Array.prototype.sort()` function converts values to strings and
2284
sorts them in lexicographic order, which is unsuitable for sorting numeric
2285
values. Provide `Array.numericSort` as a custom sort function when you want
2286
to sort values in numeric order.
2290
[42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2291
// => [4, 8, 15, 16, 23, 42]
2294
@param {Number} a First value to compare.
2295
@param {Number} b Second value to compare.
2296
@return {Number} Difference between _a_ and _b_.
2299
YArray.numericSort = function (a, b) {
2304
Executes the supplied function on each item in the array. Returning a truthy
2305
value from the function will stop the processing of remaining items.
2308
@param {Array} array Array to iterate over.
2309
@param {Function} fn Function to execute on each item. The function will receive
2310
the following arguments:
2311
@param {Any} fn.value Current array item.
2312
@param {Number} fn.index Current array index.
2313
@param {Array} fn.array Array being iterated over.
2314
@param {Object} [thisObj] `this` object to use when calling _fn_.
2315
@return {Boolean} `true` if the function returns a truthy value on any of the
2316
items in the array; `false` otherwise.
2319
YArray.some = Native.some ? function (array, fn, thisObj) {
2320
return Native.some.call(array, fn, thisObj);
2321
} : function (array, fn, thisObj) {
2322
for (var i = 0, len = array.length; i < len; ++i) {
2323
if (i in array && fn.call(thisObj, array[i], i, array)) {
2332
Evaluates _obj_ to determine if it's an array, an array-like collection, or
2333
something else. This is useful when working with the function `arguments`
2334
collection and `HTMLElement` collections.
2336
Note: This implementation doesn't consider elements that are also
2337
collections, such as `<form>` and `<select>`, to be array-like.
2340
@param {Object} obj Object to test.
2341
@return {Number} A number indicating the results of the test:
2343
* 0: Neither an array nor an array-like collection.
2345
* 2: Array-like collection.
2349
YArray.test = function (obj) {
2352
if (Lang.isArray(obj)) {
2354
} else if (Lang.isObject(obj)) {
2356
// indexed, but no tagName (element) or alert (window),
2357
// or functions without apply/call (Safari
2358
// HTMLElementCollection bug).
2359
if ('length' in obj && !obj.tagName && !obj.alert && !obj.apply) {
2368
* The YUI module contains the components required for building the YUI
2369
* seed file. This includes the script loading mechanism, a simple queue,
2370
* and the core utilities for the library.
2372
* @submodule yui-base
2376
* A simple FIFO queue. Items are added to the Queue with add(1..n items) and
2377
* removed using next().
2381
* @param {MIXED} item* 0..n items to seed the queue.
2385
this.add.apply(this, arguments);
2390
* Initialize the queue
2397
* The collection of enqueued items
2407
* Get the next item in the queue. FIFO support
2410
* @return {MIXED} the next item in the queue.
2413
return this._q.shift();
2417
* Get the last in the queue. LIFO support.
2420
* @return {MIXED} the last item in the queue.
2423
return this._q.pop();
2427
* Add 0..n items to the end of the queue.
2430
* @param {MIXED} item* 0..n items.
2431
* @return {object} this queue.
2434
this._q.push.apply(this._q, arguments);
2440
* Returns the current number of queued items.
2443
* @return {Number} The size.
2446
return this._q.length;
2452
YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2455
The YUI module contains the components required for building the YUI seed file.
2456
This includes the script loading mechanism, a simple queue, and the core
2457
utilities for the library.
2463
var CACHED_DELIMITER = '__',
2465
hasOwn = Object.prototype.hasOwnProperty,
2466
isObject = Y.Lang.isObject;
2469
Returns a wrapper for a function which caches the return value of that function,
2470
keyed off of the combined string representation of the argument values provided
2471
when the wrapper is called.
2473
Calling this function again with the same arguments will return the cached value
2474
rather than executing the wrapped function.
2476
Note that since the cache is keyed off of the string representation of arguments
2477
passed to the wrapper function, arguments that aren't strings and don't provide
2478
a meaningful `toString()` method may result in unexpected caching behavior. For
2479
example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
2480
string `[object Object]` when used as a cache key.
2483
@param {Function} source The function to memoize.
2484
@param {Object} [cache={}] Object in which to store cached values. You may seed
2485
this object with pre-existing cached values if desired.
2486
@param {any} [refetch] If supplied, this value is compared with the cached value
2487
using a `==` comparison. If the values are equal, the wrapped function is
2488
executed again even though a cached value exists.
2489
@return {Function} Wrapped function.
2492
Y.cached = function (source, cache, refetch) {
2493
cache || (cache = {});
2495
return function (arg) {
2496
var key = arguments.length > 1 ?
2497
Array.prototype.join.call(arguments, CACHED_DELIMITER) :
2500
if (!(key in cache) || (refetch && cache[key] == refetch)) {
2501
cache[key] = source.apply(source, arguments);
2509
Returns a new object containing all of the properties of all the supplied
2510
objects. The properties from later objects will overwrite those in earlier
2513
Passing in a single object will create a shallow copy of it. For a deep copy,
2517
@param {Object} objects* One or more objects to merge.
2518
@return {Object} A new merged object.
2520
Y.merge = function () {
2521
var args = arguments,
2526
for (; i < len; ++i) {
2527
Y.mix(result, args[i], true);
2534
Mixes _supplier_'s properties into _receiver_.
2536
Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
2537
shadowed unless the _overwrite_ parameter is `true`, and will not be merged
2538
unless the _merge_ parameter is `true`.
2540
In the default mode (0), only properties the supplier owns are copied (prototype
2541
properties are not copied). The following copying modes are available:
2543
* `0`: _Default_. Object to object.
2544
* `1`: Prototype to prototype.
2545
* `2`: Prototype to prototype and object to object.
2546
* `3`: Prototype to object.
2547
* `4`: Object to prototype.
2550
@param {Function|Object} receiver The object or function to receive the mixed
2552
@param {Function|Object} supplier The object or function supplying the
2553
properties to be mixed.
2554
@param {Boolean} [overwrite=false] If `true`, properties that already exist
2555
on the receiver will be overwritten with properties from the supplier.
2556
@param {String[]} [whitelist] An array of property names to copy. If
2557
specified, only the whitelisted properties will be copied, and all others
2559
@param {Number} [mode=0] Mix mode to use. See above for available modes.
2560
@param {Boolean} [merge=false] If `true`, objects and arrays that already
2561
exist on the receiver will have the corresponding object/array from the
2562
supplier merged into them, rather than being skipped or overwritten. When
2563
both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
2564
@return {Function|Object|YUI} The receiver, or the YUI instance if the
2565
specified receiver is falsy.
2567
Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
2568
var alwaysOverwrite, exists, from, i, key, len, to;
2570
// If no supplier is given, we return the receiver. If no receiver is given,
2571
// we return Y. Returning Y doesn't make much sense to me, but it's
2572
// grandfathered in for backcompat reasons.
2573
if (!receiver || !supplier) {
2574
return receiver || Y;
2578
// In mode 2 (prototype to prototype and object to object), we recurse
2579
// once to do the proto to proto mix. The object to object mix will be
2580
// handled later on.
2582
Y.mix(receiver.prototype, supplier.prototype, overwrite,
2583
whitelist, 0, merge);
2586
// Depending on which mode is specified, we may be copying from or to
2587
// the prototypes of the supplier and receiver.
2588
from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
2589
to = mode === 1 || mode === 4 ? receiver.prototype : receiver;
2591
// If either the supplier or receiver doesn't actually have a
2592
// prototype property, then we could end up with an undefined `from`
2593
// or `to`. If that happens, we abort and return the receiver.
2602
// If `overwrite` is truthy and `merge` is falsy, then we can skip a
2603
// property existence check on each iteration and save some time.
2604
alwaysOverwrite = overwrite && !merge;
2607
for (i = 0, len = whitelist.length; i < len; ++i) {
2610
// We call `Object.prototype.hasOwnProperty` instead of calling
2611
// `hasOwnProperty` on the object itself, since the object's
2612
// `hasOwnProperty` method may have been overridden or removed.
2613
// Also, some native objects don't implement a `hasOwnProperty`
2615
if (!hasOwn.call(from, key)) {
2619
// The `key in to` check here is (sadly) intentional for backwards
2620
// compatibility reasons. It prevents undesired shadowing of
2621
// prototype members on `to`.
2622
exists = alwaysOverwrite ? false : key in to;
2624
if (merge && exists && isObject(to[key], true)
2625
&& isObject(from[key], true)) {
2626
// If we're in merge mode, and the key is present on both
2627
// objects, and the value on both objects is either an object or
2628
// an array (but not a function), then we recurse to merge the
2629
// `from` value into the `to` value instead of overwriting it.
2631
// Note: It's intentional that the whitelist isn't passed to the
2632
// recursive call here. This is legacy behavior that lots of
2633
// code still depends on.
2634
Y.mix(to[key], from[key], overwrite, null, 0, merge);
2635
} else if (overwrite || !exists) {
2636
// We're not in merge mode, so we'll only copy the `from` value
2637
// to the `to` value if we're in overwrite mode or if the
2638
// current key doesn't exist on the `to` object.
2639
to[key] = from[key];
2644
// The code duplication here is for runtime performance reasons.
2645
// Combining whitelist and non-whitelist operations into a single
2646
// loop or breaking the shared logic out into a function both result
2647
// in worse performance, and Y.mix is critical enough that the byte
2648
// tradeoff is worth it.
2649
if (!hasOwn.call(from, key)) {
2653
// The `key in to` check here is (sadly) intentional for backwards
2654
// compatibility reasons. It prevents undesired shadowing of
2655
// prototype members on `to`.
2656
exists = alwaysOverwrite ? false : key in to;
2658
if (merge && exists && isObject(to[key], true)
2659
&& isObject(from[key], true)) {
2660
Y.mix(to[key], from[key], overwrite, null, 0, merge);
2661
} else if (overwrite || !exists) {
2662
to[key] = from[key];
2666
// If this is an IE browser with the JScript enumeration bug, force
2667
// enumeration of the buggy properties by making a recursive call with
2668
// the buggy properties as the whitelist.
2669
if (Y.Object._hasEnumBug) {
2670
Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
2677
* The YUI module contains the components required for building the YUI
2678
* seed file. This includes the script loading mechanism, a simple queue,
2679
* and the core utilities for the library.
2681
* @submodule yui-base
2685
* Adds utilities to the YUI instance for working with objects.
2690
var hasOwn = Object.prototype.hasOwnProperty,
2692
// If either MooTools or Prototype is on the page, then there's a chance that we
2693
// can't trust "native" language features to actually be native. When this is
2694
// the case, we take the safe route and fall back to our own non-native
2697
unsafeNatives = win && !!(win.MooTools || win.Prototype),
2699
UNDEFINED, // <-- Note the comma. We're still declaring vars.
2702
* Returns a new object that uses _obj_ as its prototype. This method wraps the
2703
* native ES5 `Object.create()` method if available, but doesn't currently
2704
* pass through `Object.create()`'s second argument (properties) in order to
2705
* ensure compatibility with older browsers.
2708
* @param {Object} obj Prototype object.
2709
* @return {Object} New object using _obj_ as its prototype.
2712
O = Y.Object = (!unsafeNatives && Object.create) ? function (obj) {
2713
// We currently wrap the native Object.create instead of simply aliasing it
2714
// to ensure consistency with our fallback shim, which currently doesn't
2715
// support Object.create()'s second argument (properties). Once we have a
2716
// safe fallback for the properties arg, we can stop wrapping
2718
return Object.create(obj);
2720
// Reusable constructor function for the Object.create() shim.
2724
return function (obj) {
2731
* Property names that IE doesn't enumerate in for..in loops, even when they
2732
* should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
2733
* manually enumerate these properties.
2735
* @property _forceEnum
2740
forceEnum = O._forceEnum = [
2743
'propertyIsEnumerable',
2750
* `true` if this browser has the JScript enumeration bug that prevents
2751
* enumeration of the properties named in the `_forceEnum` array, `false`
2755
* - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
2756
* - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
2758
* @property _hasEnumBug
2763
hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
2766
* `true` if this browser incorrectly considers the `prototype` property of
2767
* functions to be enumerable. Currently known to affect Opera 11.50.
2769
* @property _hasProtoEnumBug
2774
hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
2777
* Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
2778
* exists only on _obj_'s prototype. This is essentially a safer version of
2779
* `obj.hasOwnProperty()`.
2782
* @param {Object} obj Object to test.
2783
* @param {String} key Property name to look for.
2784
* @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2787
owns = O.owns = function (obj, key) {
2788
return !!obj && hasOwn.call(obj, key);
2789
}; // <-- End of var declarations.
2792
* Alias for `owns()`.
2795
* @param {Object} obj Object to test.
2796
* @param {String} key Property name to look for.
2797
* @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2803
* Returns an array containing the object's enumerable keys. Does not include
2804
* prototype keys or non-enumerable keys.
2806
* Note that keys are returned in enumeration order (that is, in the same order
2807
* that they would be enumerated by a `for-in` loop), which may not be the same
2808
* as the order in which they were defined.
2810
* This method is an alias for the native ES5 `Object.keys()` method if
2815
* Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
2816
* // => ['a', 'b', 'c']
2819
* @param {Object} obj An object.
2820
* @return {String[]} Array of keys.
2823
O.keys = (!unsafeNatives && Object.keys) || function (obj) {
2824
if (!Y.Lang.isObject(obj)) {
2825
throw new TypeError('Object.keys called on a non-object');
2831
if (hasProtoEnumBug && typeof obj === 'function') {
2833
if (owns(obj, key) && key !== 'prototype') {
2839
if (owns(obj, key)) {
2846
for (i = 0, len = forceEnum.length; i < len; ++i) {
2849
if (owns(obj, key)) {
2859
* Returns an array containing the values of the object's enumerable keys.
2861
* Note that values are returned in enumeration order (that is, in the same
2862
* order that they would be enumerated by a `for-in` loop), which may not be the
2863
* same as the order in which they were defined.
2867
* Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
2868
* // => ['foo', 'bar', 'baz']
2871
* @param {Object} obj An object.
2872
* @return {Array} Array of values.
2875
O.values = function (obj) {
2876
var keys = O.keys(obj),
2881
for (; i < len; ++i) {
2882
values.push(obj[keys[i]]);
2889
* Returns the number of enumerable keys owned by an object.
2892
* @param {Object} obj An object.
2893
* @return {Number} The object's size.
2896
O.size = function (obj) {
2898
return O.keys(obj).length;
2900
return 0; // Legacy behavior for non-objects.
2905
* Returns `true` if the object owns an enumerable property with the specified
2909
* @param {Object} obj An object.
2910
* @param {any} value The value to search for.
2911
* @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
2914
O.hasValue = function (obj, value) {
2915
return Y.Array.indexOf(O.values(obj), value) > -1;
2919
* Executes a function on each enumerable property in _obj_. The function
2920
* receives the value, the key, and the object itself as parameters (in that
2923
* By default, only properties owned by _obj_ are enumerated. To include
2924
* prototype properties, set the _proto_ parameter to `true`.
2927
* @param {Object} obj Object to enumerate.
2928
* @param {Function} fn Function to execute on each enumerable property.
2929
* @param {mixed} fn.value Value of the current property.
2930
* @param {String} fn.key Key of the current property.
2931
* @param {Object} fn.obj Object being enumerated.
2932
* @param {Object} [thisObj] `this` object to use when calling _fn_.
2933
* @param {Boolean} [proto=false] Include prototype properties.
2934
* @return {YUI} the YUI instance.
2938
O.each = function (obj, fn, thisObj, proto) {
2942
if (proto || owns(obj, key)) {
2943
fn.call(thisObj || Y, obj[key], key, obj);
2951
* Executes a function on each enumerable property in _obj_, but halts if the
2952
* function returns a truthy value. The function receives the value, the key,
2953
* and the object itself as paramters (in that order).
2955
* By default, only properties owned by _obj_ are enumerated. To include
2956
* prototype properties, set the _proto_ parameter to `true`.
2959
* @param {Object} obj Object to enumerate.
2960
* @param {Function} fn Function to execute on each enumerable property.
2961
* @param {mixed} fn.value Value of the current property.
2962
* @param {String} fn.key Key of the current property.
2963
* @param {Object} fn.obj Object being enumerated.
2964
* @param {Object} [thisObj] `this` object to use when calling _fn_.
2965
* @param {Boolean} [proto=false] Include prototype properties.
2966
* @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
2967
* `false` otherwise.
2970
O.some = function (obj, fn, thisObj, proto) {
2974
if (proto || owns(obj, key)) {
2975
if (fn.call(thisObj || Y, obj[key], key, obj)) {
2985
* Retrieves the sub value at the provided path,
2986
* from the value object provided.
2990
* @param o The object from which to extract the property value.
2991
* @param path {Array} A path array, specifying the object traversal path
2992
* from which to obtain the sub value.
2993
* @return {Any} The value stored in the path, undefined if not found,
2994
* undefined if the source is not an object. Returns the source object
2995
* if an empty path is provided.
2997
O.getValue = function(o, path) {
2998
if (!Y.Lang.isObject(o)) {
3006
for (i = 0; o !== UNDEFINED && i < l; i++) {
3014
* Sets the sub-attribute value at the provided path on the
3015
* value object. Returns the modified value object, or
3016
* undefined if the path is invalid.
3020
* @param o The object on which to set the sub value.
3021
* @param path {Array} A path array, specifying the object traversal path
3022
* at which to set the sub value.
3023
* @param val {Any} The new value for the sub-attribute.
3024
* @return {Object} The modified object, with the new sub value set, or
3025
* undefined, if the path was invalid.
3027
O.setValue = function(o, path, val) {
3030
leafIdx = p.length - 1,
3034
for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3038
if (ref !== UNDEFINED) {
3049
* Returns `true` if the object has no enumerable properties of its own.
3052
* @param {Object} obj An object.
3053
* @return {Boolean} `true` if the object is empty.
3057
O.isEmpty = function (obj) {
3058
return !O.keys(obj).length;
3061
* The YUI module contains the components required for building the YUI seed
3062
* file. This includes the script loading mechanism, a simple queue, and the
3063
* core utilities for the library.
3065
* @submodule yui-base
3069
* YUI user agent detection.
3070
* Do not fork for a browser if it can be avoided. Use feature detection when
3071
* you can. Use the user agent as a last resort. For all fields listed
3072
* as @type float, UA stores a version number for the browser engine,
3073
* 0 otherwise. This value may or may not map to the version number of
3074
* the browser using the engine. The value is presented as a float so
3075
* that it can easily be used for boolean evaluation as well as for
3076
* looking for a particular range of versions. Because of this,
3077
* some of the granularity of the version info may be lost. The fields that
3078
* are @type string default to null. The API docs list the values that
3079
* these fields can have.
3085
* Static method on `YUI.Env` for parsing a UA string. Called at instantiation
3086
* to populate `Y.UA`.
3090
* @param {String} [subUA=navigator.userAgent] UA string to parse
3091
* @returns {Object} The Y.UA object
3093
YUI.Env.parseUA = function(subUA) {
3095
var numberify = function(s) {
3097
return parseFloat(s.replace(/\./g, function() {
3098
return (c++ == 1) ? '' : '.';
3104
nav = win && win.navigator,
3109
* Internet Explorer version number or 0. Example: 6
3117
* Opera version number or 0. Example: 9.2
3125
* Gecko engine revision number. Will evaluate to 1 if Gecko
3126
* is detected but the revision could not be found. Other browsers
3127
* will be 0. Example: 1.8
3129
* Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7
3130
* Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3131
* Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3132
* Firefox 3.0 <-- 1.9
3133
* Firefox 3.5 <-- 1.91
3142
* AppleWebKit version. KHTML browsers that are not WebKit browsers
3143
* will evaluate to 1, other browsers 0. Example: 418.9
3145
* Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3146
* latest available for Mac OSX 10.3.
3147
* Safari 2.0.2: 416 <-- hasOwnProperty introduced
3148
* Safari 2.0.4: 418 <-- preventDefault fixed
3149
* Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3150
* different versions of webkit
3151
* Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been
3152
* updated, but not updated
3153
* to the latest patch.
3154
* Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native
3155
* SVG and many major issues fixed).
3156
* Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic
3157
* update from 2.x via the 10.4.11 OS patch.
3158
* Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event.
3159
* yahoo.com user agent hack removed.
3161
* http://en.wikipedia.org/wiki/Safari_version_history
3169
* Safari will be detected as webkit, but this property will also
3170
* be populated with the Safari version number
3178
* Chrome will be detected as webkit, but this property will also
3179
* be populated with the Chrome version number
3187
* The mobile property will be set to a string containing any relevant
3188
* user agent information when a modern mobile browser is detected.
3189
* Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3190
* devices with the WebKit-based browser, and Opera Mini.
3199
* Adobe AIR version number or 0. Only populated if webkit is detected.
3206
* Detects Apple iPad's OS version
3213
* Detects Apple iPhone's OS version
3220
* Detects Apples iPod's OS version
3227
* General truthy check for iPad, iPhone or iPod
3235
* Detects Googles Android OS version
3242
* Detects Palms WebOS version
3250
* Google Caja version number or 0.
3254
caja: nav && nav.cajaVersion,
3257
* Set to true if the page appears to be in SSL
3265
* The operating system. Currently only detecting windows or macintosh
3275
ua = subUA || nav && nav.userAgent,
3277
loc = win && win.location,
3279
href = loc && loc.href,
3284
* The User Agent string that was parsed
3285
* @property userAgent
3292
o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3296
if ((/windows|win32/i).test(ua)) {
3298
} else if ((/macintosh/i).test(ua)) {
3300
} else if ((/rhino/i).test(ua)) {
3304
// Modern KHTML browsers should qualify as Safari X-Grade
3305
if ((/KHTML/).test(ua)) {
3308
// Modern WebKit browsers are at least X-Grade
3309
m = ua.match(/AppleWebKit\/([^\s]*)/);
3311
o.webkit = numberify(m[1]);
3312
o.safari = o.webkit;
3314
// Mobile browser check
3315
if (/ Mobile\//.test(ua)) {
3316
o.mobile = 'Apple'; // iPhone or iPod Touch
3318
m = ua.match(/OS ([^\s]*)/);
3320
m = numberify(m[1].replace('_', '.'));
3323
o.ipad = o.ipod = o.iphone = 0;
3325
m = ua.match(/iPad|iPod|iPhone/);
3327
o[m[0].toLowerCase()] = o.ios;
3330
m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3332
// Nokia N-series, webOS, ex: NokiaN95
3335
if (/webOS/.test(ua)) {
3337
m = ua.match(/webOS\/([^\s]*);/);
3339
o.webos = numberify(m[1]);
3342
if (/ Android/.test(ua)) {
3343
if (/Mobile/.test(ua)) {
3344
o.mobile = 'Android';
3346
m = ua.match(/Android ([^\s]*);/);
3348
o.android = numberify(m[1]);
3354
m = ua.match(/Chrome\/([^\s]*)/);
3356
o.chrome = numberify(m[1]); // Chrome
3357
o.safari = 0; //Reset safari back to 0
3359
m = ua.match(/AdobeAIR\/([^\s]*)/);
3361
o.air = m[0]; // Adobe AIR 1.0 or better
3366
if (!o.webkit) { // not webkit
3367
// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
3368
m = ua.match(/Opera[\s\/]([^\s]*)/);
3370
o.opera = numberify(m[1]);
3371
m = ua.match(/Version\/([^\s]*)/);
3373
o.opera = numberify(m[1]); // opera 10+
3376
m = ua.match(/Opera Mini[^;]*/);
3379
o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
3381
} else { // not opera or webkit
3382
m = ua.match(/MSIE\s([^;]*)/);
3384
o.ie = numberify(m[1]);
3385
} else { // not opera, webkit, or ie
3386
m = ua.match(/Gecko\/([^\s]*)/);
3388
o.gecko = 1; // Gecko detected, look for revision
3389
m = ua.match(/rv:([^\s\)]*)/);
3391
o.gecko = numberify(m[1]);
3399
//It was a parsed UA, do not assign the global value.
3408
Y.UA = YUI.Env.UA || YUI.Env.parseUA();
3410
"anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
3411
"app": ["controller","model","model-list","view"],
3412
"attribute": ["attribute-base","attribute-complex"],
3413
"autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
3414
"base": ["base-base","base-pluginhost","base-build"],
3415
"cache": ["cache-base","cache-offline","cache-plugin"],
3416
"collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
3417
"dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
3418
"datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
3419
"datatable": ["datatable-base","datatable-datasource","datatable-sort","datatable-scroll"],
3420
"datatype": ["datatype-number","datatype-date","datatype-xml"],
3421
"datatype-date": ["datatype-date-parse","datatype-date-format"],
3422
"datatype-number": ["datatype-number-parse","datatype-number-format"],
3423
"datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
3424
"dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
3425
"dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
3426
"editor": ["frame","selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
3427
"event": ["event-base","event-delegate","event-synthetic","event-mousewheel","event-mouseenter","event-key","event-focus","event-resize","event-hover","event-outside"],
3428
"event-custom": ["event-custom-base","event-custom-complex"],
3429
"event-gestures": ["event-flick","event-move"],
3430
"highlight": ["highlight-base","highlight-accentfold"],
3431
"history": ["history-base","history-hash","history-hash-ie","history-html5"],
3432
"io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
3433
"json": ["json-parse","json-stringify"],
3434
"loader": ["loader-base","loader-rollup","loader-yui3"],
3435
"node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
3436
"pluginhost": ["pluginhost-base","pluginhost-config"],
3437
"querystring": ["querystring-parse","querystring-stringify"],
3438
"recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
3439
"resize": ["resize-base","resize-proxy","resize-constrain"],
3440
"slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
3441
"text": ["text-accentfold","text-wordbreak"],
3442
"widget": ["widget-base","widget-htmlparser","widget-uievents","widget-skin"]