2
YUI 3.13.0 (build 508226d)
3
Copyright 2013 Yahoo! Inc. All rights reserved.
4
Licensed under the BSD License.
5
http://yuilibrary.com/license/
9
The YUI module contains the components required for building the YUI seed file.
10
This includes the script loading mechanism, a simple queue, and the core
11
utilities for the library.
18
/*jshint eqeqeq: false*/
19
if (typeof YUI != 'undefined') {
24
The YUI global namespace object. This is the constructor for all YUI instances.
26
This is a self-instantiable factory function, meaning you don't need to precede
27
it with the `new` operator. You can invoke it directly like this:
29
YUI().use('*', function (Y) {
30
// Y is a new YUI instance.
33
But it also works like this:
37
The `YUI` constructor accepts an optional config object, like this:
42
}).use('node', function (Y) {
43
// Y.Node is ready to use.
46
See the API docs for the <a href="config.html">Config</a> class for the complete
47
list of supported configuration properties accepted by the YUI constuctor.
49
If a global `YUI` object is already defined, the existing YUI object will not be
50
overwritten, to ensure that defined namespaces are preserved.
52
Each YUI instance has full custom event support, but only if the event system is
59
@param {Object} [config]* Zero or more optional configuration objects. Config
60
values are stored in the `Y.config` property. See the
61
<a href="config.html">Config</a> docs for the list of supported properties.
66
var YUI = function() {
71
instanceOf = function(o, type) {
72
return (o && o.hasOwnProperty && (o instanceof type));
74
gconf = (typeof YUI_config !== 'undefined') && YUI_config;
76
if (!(instanceOf(Y, YUI))) {
79
// set up the core environment
83
Master configuration that might span multiple contexts in a non-
84
browser environment. It is applied first to all instances in all
93
YUI().use('node', function (Y) {
94
// debug files used here
99
}).use('node', function (Y) {
100
// min files used here
103
@property {Object} GlobalConfig
107
if (YUI.GlobalConfig) {
108
Y.applyConfig(YUI.GlobalConfig);
112
Page-level config applied to all YUI instances created on the
113
current page. This is applied after `YUI.GlobalConfig` and before
114
any instance-level configuration.
118
// Single global var to include before YUI seed file
123
YUI().use('node', function (Y) {
124
// debug files used here
129
}).use('node', function (Y) {
130
// min files used here
133
@property {Object} YUI_config
137
Y.applyConfig(gconf);
140
// bind the specified additional modules for this instance
147
// Each instance can accept one or more configuration objects.
148
// These are applied after YUI.GlobalConfig and YUI_Config,
149
// overriding values set in those config files if there is a
150
// matching property.
152
Y.applyConfig(args[i]);
158
Y.instanceOf = instanceOf;
168
BASE = 'http://yui.yahooapis.com/',
170
These CSS class names can't be generated by
171
getClassName since it is not available at the
172
time they are being used.
174
DOC_LABEL = 'yui3-js-enabled',
175
CSS_STAMP_EL = 'yui3-css-stamp',
176
NOOP = function() {},
177
SLICE = Array.prototype.slice,
178
APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo
179
'io.xdrResponse': 1, // can call. this should
180
'SWF.eventHandler': 1 }, // be done at build time
181
hasWin = (typeof window != 'undefined'),
182
win = (hasWin) ? window : null,
183
doc = (hasWin) ? win.document : null,
184
docEl = doc && doc.documentElement,
185
docClass = docEl && docEl.className,
187
time = new Date().getTime(),
188
add = function(el, type, fn, capture) {
189
if (el && el.addEventListener) {
190
el.addEventListener(type, fn, capture);
191
} else if (el && el.attachEvent) {
192
el.attachEvent('on' + type, fn);
195
remove = function(el, type, fn, capture) {
196
if (el && el.removeEventListener) {
197
// this can throw an uncaught exception in FF
199
el.removeEventListener(type, fn, capture);
201
} else if (el && el.detachEvent) {
202
el.detachEvent('on' + type, fn);
205
handleLoad = function() {
206
YUI.Env.windowLoaded = true;
207
YUI.Env.DOMReady = true;
209
remove(window, 'load', handleLoad);
212
getLoader = function(Y, o) {
213
var loader = Y.Env._loader,
214
lCore = [ 'loader-base' ],
219
//loader._config(Y.config);
220
loader.ignoreRegistered = false;
223
loader.required = [];
224
loader.loadType = null;
226
loader = new Y.Loader(Y.config);
227
Y.Env._loader = loader;
229
if (mods && mods.loader) {
230
lCore = [].concat(lCore, YUI.Env.loaderExtras);
232
YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
237
clobber = function(r, s) {
239
if (s.hasOwnProperty(i)) {
245
ALREADY_DONE = { success: true };
247
// Stamp the documentElement (HTML) with a class of "yui-loaded" to
248
// enable styles that need to key off of JS being enabled.
249
if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
253
docClass += DOC_LABEL;
254
docEl.className = docClass;
257
if (VERSION.indexOf('@') > -1) {
258
VERSION = '3.5.0'; // dev time hack for cdn test
263
Applies a new configuration object to the config of this YUI instance. This
264
will merge new group/module definitions, and will also update the loader
265
cache if necessary. Updating `Y.config` directly will not update the cache.
268
@param {Object} o the configuration object.
271
applyConfig: function(o) {
278
config = this.config,
279
mods = config.modules,
280
groups = config.groups,
281
aliases = config.aliases,
282
loader = this.Env._loader;
285
if (o.hasOwnProperty(name)) {
287
if (mods && name == 'modules') {
289
} else if (aliases && name == 'aliases') {
290
clobber(aliases, attr);
291
} else if (groups && name == 'groups') {
292
clobber(groups, attr);
293
} else if (name == 'win') {
294
config[name] = (attr && attr.contentWindow) || attr;
295
config.doc = config[name] ? config[name].document : null;
296
} else if (name == '_yuid') {
311
Old way to apply a config to this instance (calls `applyConfig` under the
316
@param {Object} o The config to apply
318
_config: function(o) {
323
Initializes this YUI instance.
336
The version number of this YUI instance.
338
This value is typically updated by a script when a YUI release is built,
339
so it may not reflect the correct version number when YUI is run from
340
the development source tree.
342
@property {String} version
348
core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later'],
349
loaderExtras: ['loader-rollup', 'loader-yui3'],
350
mods: {}, // flat module map
351
versions: {}, // version module map
353
cdn: BASE + VERSION + '/build/',
354
// bootstrapped: false,
365
// I'll start at the \b(yui).
366
// 1. Look in the test string for "yui" or
367
// "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break. That is, it
368
// can't match "foyui" or "i_heart_yui". This can be anywhere in the string.
369
// 2. After #1 must come a forward slash followed by the string matched in #1, so
370
// "yui-base/yui-base" or "yui-pants/yui-pants".
371
// 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
372
// so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
373
// 4. This is followed by ".js", so "yui/yui.js".
374
// 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
375
// then capture the junk between the LAST "&" and the string in 1-4. So
376
// "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
377
// will capture "3.3.0/build/"
381
// (?:[^&]*&) followed by 0..n characters followed by an &
382
// * in fact, find as many sets of characters followed by a & as you can
383
// ([^&]*) capture the stuff after the last & in \1
384
// )? but it's ok if all this ?junk&more_junk stuff isn't even there
385
// \b( after a word break find either the string
386
// yui(?:-\w+)? "yui" optionally followed by a -, then more characters
387
// ) and store the yui-* string in \2
388
// \/\2 then comes a / followed by the yui-* string in \2
389
// (?:-(min|debug))? optionally followed by "-min" or "-debug"
390
// .js and ending in ".js"
391
_BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
392
parseBasePath: function(src, pattern) {
393
var match = src.match(pattern),
397
path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
399
// this is to set up the path to the loader. The file
400
// filter for loader should match the yui include.
403
// extract correct path for mixed combo urls
404
// http://yuilibrary.com/projects/yui3/ticket/2528423
406
path += '?' + match[1];
415
getBase: G_ENV && G_ENV.getBase ||
417
var nodes = (doc && doc.getElementsByTagName('script')) || [],
418
path = Env.cdn, parsed,
421
for (i = 0, len = nodes.length; i < len; ++i) {
424
parsed = Y.Env.parseBasePath(src, pattern);
426
filter = parsed.filter;
441
Env._loaded[VERSION] = {};
443
if (G_ENV && Y !== YUI) {
444
Env._yidx = ++G_ENV._yidx;
445
Env._guidp = ('yui_' + VERSION + '_' +
446
Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
447
} else if (YUI._YUI) {
449
G_ENV = YUI._YUI.Env;
450
Env._yidx += G_ENV._yidx;
451
Env._uidx += G_ENV._uidx;
453
for (prop in G_ENV) {
454
if (!(prop in Env)) {
455
Env[prop] = G_ENV[prop];
469
// configuration defaults
470
Y.config = Y.config || {
477
useBrowserConsole: true,
480
global: Function('return this')()
483
//Register the CSS stamp element
484
if (doc && !doc.getElementById(CSS_STAMP_EL)) {
485
el = doc.createElement('div');
486
el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
487
YUI.Env.cssStampEl = el.firstChild;
489
doc.body.appendChild(YUI.Env.cssStampEl);
491
docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
493
} else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
494
YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
497
Y.config.lang = Y.config.lang || 'en-US';
499
Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
501
if (!filter || (!('mindebug').indexOf(filter))) {
504
filter = (filter) ? '-' + filter : filter;
505
Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
510
Finishes the instance setup. Attaches whatever YUI modules were defined
511
at the time that this instance was created.
520
extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
522
for (i = 0; i < extras.length; i++) {
523
if (mods[extras[i]]) {
524
core.push(extras[i]);
528
Y._attach(['yui-base']);
538
Executes the named method on the specified YUI instance if that method is
542
@param {String} id YUI instance id.
543
@param {String} method Name of the method to execute. For example:
545
@param {Array} args Arguments to apply to the method.
546
@return {Mixed} Return value from the applied method, or `null` if the
547
specified instance was not found or the method was not whitelisted.
549
applyTo: function(id, method, args) {
550
if (!(method in APPLY_TO_AUTH)) {
551
this.log(method + ': applyTo not allowed', 'warn', 'yui');
555
var instance = instances[id], nest, m, i;
557
nest = method.split('.');
559
for (i = 0; i < nest.length; i = i + 1) {
562
this.log('applyTo not found: ' + method, 'warn', 'yui');
565
return m && m.apply(instance, args);
572
Registers a YUI module and makes it available for use in a `YUI().use()` call or
573
as a dependency for other modules.
575
The easiest way to create a first-class YUI module is to use
576
<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
579
Shifter will automatically wrap your module code in a `YUI.add()` call along
580
with any configuration info required for the module.
584
YUI.add('davglass', function (Y) {
585
Y.davglass = function () {
588
requires: ['harley-davidson', 'mt-dew']
592
@param {String} name Module name.
593
@param {Function} fn Function containing module code. This function will be
594
executed whenever the module is attached to a specific YUI instance.
596
@param {YUI} fn.Y The YUI instance to which this module is attached.
597
@param {String} fn.name Name of the module
599
@param {String} version Module version number. This is currently used only for
600
informational purposes, and is not used internally by YUI.
602
@param {Object} [config] Module config.
603
@param {Array} [config.requires] Array of other module names that must be
604
attached before this module can be attached.
605
@param {Array} [config.optional] Array of optional module names that should
606
be attached before this module is attached if they've already been
607
loaded. If the `loadOptional` YUI option is `true`, optional modules
608
that have not yet been loaded will be loaded just as if they were hard
610
@param {Array} [config.use] Array of module names that are included within
611
or otherwise provided by this module, and which should be attached
612
automatically when this module is attached. This makes it possible to
613
create "virtual rollup" modules that simply attach a collection of other
614
modules or submodules.
616
@return {YUI} This YUI instance.
618
add: function(name, fn, version, details) {
619
details = details || {};
627
//Instance hash so we don't apply it to the same instance twice
630
i, versions = env.versions;
632
env.mods[name] = mod;
633
versions[version] = versions[version] || {};
634
versions[version][name] = mod;
636
for (i in instances) {
637
if (instances.hasOwnProperty(i)) {
639
if (!applied[inst.id]) {
640
applied[inst.id] = true;
641
loader = inst.Env._loader;
643
if (!loader.moduleInfo[name] || loader.moduleInfo[name].temp) {
644
loader.addModule(details, name);
655
Executes the callback function associated with each required module,
656
attaching the module to this YUI instance.
659
@param {Array} r The array of modules to attach
660
@param {Boolean} [moot=false] If `true`, don't throw a warning if the module
664
_attach: function(r, moot) {
665
var i, name, mod, details, req, use, after,
667
aliases = YUI.Env.aliases,
669
cache = YUI.Env._renderedMods,
670
loader = Y.Env._loader,
671
done = Y.Env._attached,
672
len = r.length, loader, def, go,
675
//Check for conditional modules (in a second+ instance) and add their requirements
676
//TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
677
for (i = 0; i < len; i++) {
681
if (loader && loader.conditions[name]) {
682
for (j in loader.conditions[name]) {
683
if (loader.conditions[name].hasOwnProperty(j)) {
684
def = loader.conditions[name][j];
685
go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
696
for (i = 0; i < len; i++) {
701
if (aliases && aliases[name] && !mod) {
702
Y._attach(aliases[name]);
706
if (loader && loader.moduleInfo[name]) {
707
mod = loader.moduleInfo[name];
712
//if (!loader || !loader.moduleInfo[name]) {
713
//if ((!loader || !loader.moduleInfo[name]) && !moot) {
715
if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
716
Y.Env._missed.push(name);
717
Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
718
Y.message('NOT loaded: ' + name, 'warn', 'yui');
723
//Don't like this, but in case a mod was asked for once, then we fetch it
724
//We need to remove it from the missed list ^davglass
725
for (j = 0; j < Y.Env._missed.length; j++) {
726
if (Y.Env._missed[j] === name) {
727
Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
728
Y.Env._missed.splice(j, 1);
732
If it's a temp module, we need to redo it's requirements if it's already loaded
733
since it may have been loaded by another instance and it's dependencies might
734
have been redefined inside the fetched file.
736
if (loader && cache && cache[name] && cache[name].temp) {
737
loader.getRequires(cache[name]);
739
for (j in loader.moduleInfo[name].expanded_map) {
740
if (loader.moduleInfo[name].expanded_map.hasOwnProperty(j)) {
747
details = mod.details;
748
req = details.requires;
750
after = details.after;
751
//Force Intl load if there is a language (Loader logic) @todo fix this shit
758
for (j = 0; j < req.length; j++) {
760
if (!Y._attach(req)) {
769
for (j = 0; j < after.length; j++) {
770
if (!done[after[j]]) {
771
if (!Y._attach(after, true)) {
780
if (Y.config.throwFail) {
786
Y.error('Attach error: ' + name, e, name);
793
for (j = 0; j < use.length; j++) {
795
if (!Y._attach(use)) {
813
Delays the `use` callback until another event has taken place such as
814
`window.onload`, `domready`, `contentready`, or `available`.
817
@method _delayCallback
818
@param {Function} cb The original `use` callback.
819
@param {String|Object} until Either an event name ('load', 'domready', etc.)
820
or an object containing event/args keys for contentready/available.
823
_delayCallback: function(cb, until) {
826
mod = ['event-base'];
828
until = (Y.Lang.isObject(until) ? until : { event: until });
830
if (until.event === 'load') {
831
mod.push('event-synthetic');
835
var args = arguments;
836
Y._use(mod, function() {
837
Y.on(until.event, function() {
838
args[1].delayUntil = until.event;
846
Attaches one or more modules to this YUI instance. When this is executed,
847
the requirements of the desired modules are analyzed, and one of several
851
* All required modules have already been loaded, and just need to be
852
attached to this YUI instance. In this case, the `use()` callback will
853
be executed synchronously after the modules are attached.
855
* One or more modules have not yet been loaded, or the Get utility is not
856
available, or the `bootstrap` config option is `false`. In this case,
857
a warning is issued indicating that modules are missing, but all
858
available modules will still be attached and the `use()` callback will
859
be executed synchronously.
861
* One or more modules are missing and the Loader is not available but the
862
Get utility is, and `bootstrap` is not `false`. In this case, the Get
863
utility will be used to load the Loader, and we will then proceed to
866
* One or more modules are missing and the Loader is available. In this
867
case, the Loader will be used to resolve the dependency tree for the
868
missing modules and load them and their dependencies. When the Loader is
869
finished loading modules, the `use()` callback will be executed
874
// Loads and attaches dd and its dependencies.
875
YUI().use('dd', function (Y) {
879
// Loads and attaches dd and node as well as all of their dependencies.
880
YUI().use(['dd', 'node'], function (Y) {
884
// Attaches all modules that have already been loaded.
885
YUI().use('*', function (Y) {
889
// Attaches a gallery module.
890
YUI().use('gallery-yql', function (Y) {
894
// Attaches a YUI 2in3 module.
895
YUI().use('yui2-datatable', function (Y) {
900
@param {String|Array} modules* One or more module names to attach.
901
@param {Function} [callback] Callback function to be executed once all
902
specified modules and their dependencies have been attached.
903
@param {YUI} callback.Y The YUI instance created for this sandbox.
904
@param {Object} callback.status Object containing `success`, `msg` and
909
var args = SLICE.call(arguments, 0),
910
callback = args[args.length - 1],
917
// The last argument supplied to use can be a load complete callback
918
if (Y.Lang.isFunction(callback)) {
920
if (Y.config.delayUntil) {
921
callback = Y._delayCallback(callback, Y.config.delayUntil);
926
if (Y.Lang.isArray(args[0])) {
930
if (Y.config.cacheUse) {
931
while ((name = args[i++])) {
932
if (!Env._attached[name]) {
941
Y._notify(callback, ALREADY_DONE, args);
947
Y._useQueue = Y._useQueue || new Y.Queue();
948
Y._useQueue.add([args, callback]);
950
Y._use(args, function(Y, response) {
951
Y._notify(callback, response, args);
959
Handles Loader notifications about attachment/load errors.
962
@param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
963
@param {Object} response Response returned from Loader.
964
@param {Array} args Arguments passed from Loader.
967
_notify: function(callback, response, args) {
968
if (!response.success && this.config.loadErrorFn) {
969
this.config.loadErrorFn.call(this, this, callback, response, args);
970
} else if (callback) {
971
if (this.Env._missed && this.Env._missed.length) {
972
response.msg = 'Missing modules: ' + this.Env._missed.join();
973
response.success = false;
975
if (this.config.throwFail) {
976
callback(this, response);
979
callback(this, response);
981
this.error('use callback error', e, args);
988
Called from the `use` method queue to ensure that only one set of loading
989
logic is performed at a time.
992
@param {String} args* One or more modules to attach.
993
@param {Function} [callback] Function to call once all required modules have
997
_use: function(args, callback) {
1000
this._attach(['yui-base']);
1003
var len, loader, handleBoot,
1009
aliases = G_ENV.aliases,
1010
queue = G_ENV._loaderQueue,
1014
boot = config.bootstrap,
1019
fetchCSS = config.fetchCSS,
1020
process = function(names, skip) {
1022
var i = 0, a = [], name, len, m, req, use;
1024
if (!names.length) {
1030
for (i = 0; i < len; i++) {
1031
if (aliases[names[i]] && !mods[names[i]]) {
1032
a = [].concat(a, aliases[names[i]]);
1042
for (i = 0; i < len; i++) {
1048
// only attach a module once
1059
req = m.details.requires;
1060
use = m.details.use;
1062
// CSS files don't register themselves, see if it has
1064
if (!G_ENV._loaded[VERSION][name]) {
1067
used[name] = true; // probably css
1071
// make sure requirements are attached
1072
if (req && req.length) {
1076
// make sure we grab the submodule dependencies too
1077
if (use && use.length) {
1084
handleLoader = function(fromLoader) {
1085
var response = fromLoader || {
1091
data = response.data;
1096
origMissing = missing;
1100
redo = missing.length;
1102
if ([].concat(missing).sort().join() ==
1103
origMissing.sort().join()) {
1111
Y._use(missing, function() {
1112
if (Y._attach(data)) {
1113
Y._notify(callback, response, data);
1118
ret = Y._attach(data);
1121
Y._notify(callback, response, args);
1125
if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
1126
Y._use.apply(Y, Y._useQueue.next());
1132
// YUI().use('*'); // bind everything available
1133
if (firstArg === '*') {
1136
if (mods.hasOwnProperty(i)) {
1140
ret = Y._attach(args);
1147
if ((mods.loader || mods['loader-base']) && !Y.Loader) {
1148
Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
1152
// use loader to expand dependencies and sort the
1153
// requirements if it is available.
1154
if (boot && Y.Loader && args.length) {
1155
loader = getLoader(Y);
1156
loader.require(args);
1157
loader.ignoreRegistered = true;
1158
loader._boot = true;
1159
loader.calculate(null, (fetchCSS) ? null : 'js');
1160
args = loader.sorted;
1161
loader._boot = false;
1166
len = missing.length;
1170
missing = YArray.dedupe(missing);
1171
len = missing.length;
1176
if (boot && len && Y.Loader) {
1178
loader = getLoader(Y);
1179
loader.onEnd = handleLoader;
1182
loader.ignoreRegistered = false;
1183
loader.require(missing);
1184
loader.insert(null, (fetchCSS) ? null : 'js');
1186
} else if (boot && len && Y.Get && !Env.bootstrapped) {
1190
handleBoot = function() {
1192
queue.running = false;
1193
Env.bootstrapped = true;
1194
G_ENV._bootstrapping = false;
1195
if (Y._attach(['loader'])) {
1196
Y._use(args, callback);
1200
if (G_ENV._bootstrapping) {
1201
queue.add(handleBoot);
1203
G_ENV._bootstrapping = true;
1204
Y.Get.script(config.base + config.loaderPath, {
1210
ret = Y._attach(args);
1221
Utility method for safely creating namespaces if they don't already exist.
1222
May be called statically on the YUI global object or as a method on a YUI
1225
When called statically, a namespace will be created on the YUI global
1228
// Create `YUI.your.namespace.here` as nested objects, preserving any
1229
// objects that already exist instead of overwriting them.
1230
YUI.namespace('your.namespace.here');
1232
When called as a method on a YUI instance, a namespace will be created on
1235
// Creates `Y.property.package`.
1236
Y.namespace('property.package');
1238
Dots in the input string cause `namespace` to create nested objects for each
1239
token. If any part of the requested namespace already exists, the current
1240
object will be left in place and will not be overwritten. This allows
1241
multiple calls to `namespace` to preserve existing namespaced properties.
1243
If the first token in the namespace string is "YAHOO", that token is
1244
discarded. This is legacy behavior for backwards compatibility with YUI 2.
1246
Be careful with namespace tokens. Reserved words may work in some browsers
1247
and not others. For instance, the following will fail in some browsers
1248
because the supported version of JavaScript reserves the word "long":
1250
Y.namespace('really.long.nested.namespace');
1252
Note: If you pass multiple arguments to create multiple namespaces, only the
1253
last one created is returned from this function.
1256
@param {String} namespace* One or more namespaces to create.
1257
@return {Object} Reference to the last namespace object created.
1259
namespace: function() {
1260
var a = arguments, o, i = 0, j, d, arg;
1262
for (; i < a.length; i++) {
1263
o = this; //Reset base object per argument or it will get reused from the last
1265
if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
1266
d = arg.split(PERIOD);
1267
for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1268
o[d[j]] = o[d[j]] || {};
1272
o[arg] = o[arg] || {};
1273
o = o[arg]; //Reset base object to the new object so it's returned
1279
// this is replaced if the log module is included
1282
// this is replaced if the dump module is included
1283
dump: function (o) { return ''+o; },
1288
The reporting mechanism is controlled by the `throwFail` configuration
1289
attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
1290
truthy, a JS exception is thrown.
1292
If an `errorFn` is specified in the config it must return `true` to indicate
1293
that the exception was handled and keep it from being thrown.
1296
@param {String} msg Error message.
1297
@param {Error|String} [e] JavaScript error object or an error string.
1298
@param {String} [src] Source of the error (such as the name of the module in
1299
which the error occurred).
1302
error: function(msg, e, src) {
1303
//TODO Add check for window.onerror here
1307
if (Y.config.errorFn) {
1308
ret = Y.config.errorFn.apply(Y, arguments);
1312
throw (e || new Error(msg));
1314
Y.message(msg, 'error', ''+src); // don't scrub this one
1321
Generates an id string that is unique among all YUI instances in this
1325
@param {String} [pre] Prefix.
1326
@return {String} Unique id.
1328
guid: function(pre) {
1329
var id = this.Env._guidp + '_' + (++this.Env._uidx);
1330
return (pre) ? (pre + id) : id;
1334
Returns a unique id associated with the given object and (if *readOnly* is
1335
falsy) stamps the object with that id so it can be identified in the future.
1337
Stamping an object involves adding a `_yuid` property to it that contains
1338
the object's id. One exception to this is that in Internet Explorer, DOM
1339
nodes have a `uniqueID` property that contains a browser-generated unique
1340
id, which will be used instead of a YUI-generated id when available.
1343
@param {Object} o Object to stamp.
1344
@param {Boolean} readOnly If truthy and the given object has not already
1345
been stamped, the object will not be modified and `null` will be
1347
@return {String} Object's unique id, or `null` if *readOnly* was truthy and
1348
the given object was not already stamped.
1350
stamp: function(o, readOnly) {
1356
// IE generates its own unique ID for dom nodes
1357
// The uniqueID property of a document node returns a new ID
1358
if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1361
uid = (typeof o === 'string') ? o : o._yuid;
1378
Destroys this YUI instance.
1383
destroy: function() {
1388
delete instances[Y.id];
1394
Safe `instanceof` wrapper that works around a memory leak in IE when the
1395
object being tested is `window` or `document`.
1397
Unless you are testing objects that may be `window` or `document`, you
1398
should use the native `instanceof` operator instead of this method.
1401
@param {Object} o Object to check.
1402
@param {Object} type Class to check against.
1407
YUI.prototype = proto;
1409
// inheritance utilities are not available yet
1410
for (prop in proto) {
1411
if (proto.hasOwnProperty(prop)) {
1412
YUI[prop] = proto[prop];
1417
Applies a configuration to all YUI instances in this execution context.
1419
The main use case for this method is in "mashups" where several third-party
1420
scripts need to write to a global YUI config, but cannot share a single
1421
centrally-managed config object. This way they can all call
1422
`YUI.applyConfig({})` instead of overwriting the single global config.
1429
fullpath: './davglass.js'
1437
fullpath: './foo.js'
1442
YUI().use('davglass', function (Y) {
1443
// Module davglass will be available here.
1447
@param {Object} o Configuration object to apply.
1451
YUI.applyConfig = function(o) {
1455
//If there is a GlobalConfig, apply it first to set the defaults
1456
if (YUI.GlobalConfig) {
1457
this.prototype.applyConfig.call(this, YUI.GlobalConfig);
1459
//Apply this config to it
1460
this.prototype.applyConfig.call(this, o);
1461
//Reset GlobalConfig to the combined config
1462
YUI.GlobalConfig = this.config;
1465
// set up the environment
1469
// add a window load event at load time so we can capture
1470
// the case where it fires before dynamic loading is
1472
add(window, 'load', handleLoad);
1478
YUI.Env.remove = remove;
1481
// Support the CommonJS method for exporting our single global
1482
if (typeof exports == 'object') {
1485
* Set a method to be called when `Get.script` is called in Node.js
1486
* `Get` will open the file, then pass it's content and it's path
1487
* to this method before attaching it. Commonly used for code coverage
1488
* instrumentation. <strong>Calling this multiple times will only
1489
* attach the last hook method</strong>. This method is only
1490
* available in Node.js.
1491
* @method setLoadHook
1493
* @param {Function} fn The function to set
1494
* @param {String} fn.data The content of the file
1495
* @param {String} fn.path The file path of the file
1497
YUI.setLoadHook = function(fn) {
1498
YUI._getLoadHook = fn;
1501
* Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
1502
* @method _getLoadHook
1504
* @param {String} data The content of the file
1505
* @param {String} path The file path of the file
1507
YUI._getLoadHook = null;
1510
YUI.Env[VERSION] = {};
1515
Config object that contains all of the configuration options for
1516
this `YUI` instance.
1518
This object is supplied by the implementer when instantiating YUI. Some
1519
properties have default values if they are not supplied by the implementer.
1521
This object should not be updated directly because some values are cached. Use
1522
`applyConfig()` to update the config object on a YUI instance that has already
1530
If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
1531
if they're needed to load additional dependencies and aren't already available.
1533
Setting this to `false` will prevent YUI from automatically loading the Loader
1534
and module metadata, so you will need to manually ensure that they're available
1535
or handle dependency resolution yourself.
1537
@property {Boolean} bootstrap
1543
@property {Object} aliases
1547
A hash of module group definitions.
1549
For each group you can specify a list of modules and the base path and
1550
combo spec to use when dynamically loading the modules.
1556
// specify whether or not this group has a combo service
1559
// The comboSeperator to use with this group's combo handler
1562
// The maxURLLength for this server
1565
// the base path for non-combo paths
1566
base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1568
// the path to the combo service
1569
comboBase: 'http://yui.yahooapis.com/combo?',
1571
// a fragment to prepend to the path attribute when
1572
// when building combo urls
1573
root: '2.8.0r4/build/',
1575
// the module definitions
1578
path: "yahoo-dom-event/yahoo-dom-event.js"
1581
path: "animation/animation.js",
1582
requires: ['yui2_yde']
1588
@property {Object} groups
1592
Path to the Loader JS file, relative to the `base` path.
1594
This is used to dynamically bootstrap the Loader when it's needed and isn't yet
1597
@property {String} loaderPath
1598
@default "loader/loader-min.js"
1602
If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
1603
`false` to prevent YUI from loading any CSS, or set it to the string `"force"`
1604
to force CSS dependencies to be loaded even if their associated JS modules are
1607
@property {Boolean|String} fetchCSS
1612
Default gallery version used to build gallery module urls.
1614
@property {String} gallery
1619
Default YUI 2 version used to build YUI 2 module urls.
1621
This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
1622
`2in3` config for pulling different revisions of the wrapped YUI 2 modules.
1624
@property {String} yui2
1630
Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
1632
@property {String} 2in3
1638
Alternate console log function that should be used in environments without a
1639
supported native console. This function is executed with the YUI instance as its
1642
@property {Function} logFn
1647
The minimum log level to log messages for. Log levels are defined
1648
incrementally. Messages greater than or equal to the level specified will
1649
be shown. All others will be discarded. The order of log levels in
1650
increasing priority is:
1657
@property {String} logLevel
1663
Callback to execute when `Y.error()` is called. It receives the error message
1664
and a JavaScript error object if one was provided.
1666
This function is executed with the YUI instance as its `this` object.
1668
Returning `true` from this function will prevent an exception from being thrown.
1670
@property {Function} errorFn
1671
@param {String} errorFn.msg Error message
1672
@param {Object} [errorFn.err] Error object (if one was provided).
1677
A callback to execute when Loader fails to load one or more resources.
1679
This could be because of a script load failure. It could also be because a
1680
module fails to register itself when the `requireRegistration` config is `true`.
1682
If this function is defined, the `use()` callback will only be called when the
1683
loader succeeds. Otherwise, `use()` will always executes unless there was a
1684
JavaScript error when attaching a module.
1686
@property {Function} loadErrorFn
1691
If `true`, Loader will expect all loaded scripts to be first-class YUI modules
1692
that register themselves with the YUI global, and will trigger a failure if a
1693
loaded script does not register a YUI module.
1695
@property {Boolean} requireRegistration
1701
Cache serviced use() requests.
1703
@property {Boolean} cacheUse
1706
@deprecated No longer used.
1710
Whether or not YUI should use native ES5 functionality when available for
1711
features like `Y.Array.each()`, `Y.Object()`, etc.
1713
When `false`, YUI will always use its own fallback implementations instead of
1714
relying on ES5 functionality, even when ES5 functionality is available.
1716
@property {Boolean} useNativeES5
1722
* Leverage native JSON stringify if the browser has a native
1723
* implementation. In general, this is a good idea. See the Known Issues
1724
* section in the JSON user guide for caveats. The default value is true
1725
* for browsers with native JSON support.
1727
* @property useNativeJSONStringify
1734
* Leverage native JSON parse if the browser has a native implementation.
1735
* In general, this is a good idea. See the Known Issues section in the
1736
* JSON user guide for caveats. The default value is true for browsers with
1737
* native JSON support.
1739
* @property useNativeJSONParse
1746
Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
1748
@property {Object|String} delayUntil
1752
You can use `load` or `domready` strings by default:
1755
delayUntil: 'domready'
1757
// This will not execute until 'domeready' occurs.
1760
Or you can delay until a node is available (with `available` or `contentready`):
1768
// This will not execute until a node matching the selector "#foo" is
1769
// available in the DOM.
1773
YUI.add('yui-base', function (Y, NAME) {
1778
* @submodule yui-base
1781
* The YUI module contains the components required for building the YUI
1782
* seed file. This includes the script loading mechanism, a simple queue,
1783
* and the core utilities for the library.
1785
* @submodule yui-base
1789
* Provides core language utilites and extensions used throughout YUI.
1795
var L = Y.Lang || (Y.Lang = {}),
1797
STRING_PROTO = String.prototype,
1798
TOSTRING = Object.prototype.toString,
1801
'undefined' : 'undefined',
1802
'number' : 'number',
1803
'boolean' : 'boolean',
1804
'string' : 'string',
1805
'[object Function]': 'function',
1806
'[object RegExp]' : 'regexp',
1807
'[object Array]' : 'array',
1808
'[object Date]' : 'date',
1809
'[object Error]' : 'error'
1812
SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
1814
WHITESPACE = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF",
1815
WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+",
1816
TRIM_LEFT_REGEX = new RegExp("^" + WHITESPACE_CLASS),
1817
TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"),
1818
TRIMREGEX = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"),
1820
NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i;
1822
// -- Protected Methods --------------------------------------------------------
1825
Returns `true` if the given function appears to be implemented in native code,
1826
`false` otherwise. Will always return `false` -- even in ES5-capable browsers --
1827
if the `useNativeES5` YUI config option is set to `false`.
1829
This isn't guaranteed to be 100% accurate and won't work for anything other than
1830
functions, but it can be useful for determining whether a function like
1831
`Array.prototype.forEach` is native or a JS shim provided by another library.
1833
There's a great article by @kangax discussing certain flaws with this technique:
1834
<http://perfectionkills.com/detecting-built-in-host-methods/>
1836
While his points are valid, it's still possible to benefit from this function
1837
as long as it's used carefully and sparingly, and in such a way that false
1838
negatives have minimal consequences. It's used internally to avoid using
1839
potentially broken non-native ES5 shims that have been added to the page by
1843
@param {Function} fn Function to test.
1844
@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
1849
L._isNative = function (fn) {
1850
return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
1853
// -- Public Methods -----------------------------------------------------------
1856
* Determines whether or not the provided item is an array.
1858
* Returns `false` for array-like collections such as the function `arguments`
1859
* collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
1860
* test for an array-like collection.
1863
* @param o The object to test.
1864
* @return {boolean} true if o is an array.
1867
L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
1868
return L.type(o) === 'array';
1872
* Determines whether or not the provided item is a boolean.
1875
* @param o The object to test.
1876
* @return {boolean} true if o is a boolean.
1878
L.isBoolean = function(o) {
1879
return typeof o === 'boolean';
1883
* Determines whether or not the supplied item is a date instance.
1886
* @param o The object to test.
1887
* @return {boolean} true if o is a date.
1889
L.isDate = function(o) {
1890
return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
1895
* Determines whether or not the provided item is a function.
1896
* Note: Internet Explorer thinks certain functions are objects:
1900
* var obj = document.createElement("object");
1901
* Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1903
* var input = document.createElement("input"); // append to body
1904
* Y.Lang.isFunction(input.focus) // reports false in IE
1908
* You will have to implement additional tests if these functions
1912
* @method isFunction
1914
* @param o The object to test.
1915
* @return {boolean} true if o is a function.
1917
L.isFunction = function(o) {
1918
return L.type(o) === 'function';
1922
* Determines whether or not the provided item is null.
1925
* @param o The object to test.
1926
* @return {boolean} true if o is null.
1928
L.isNull = function(o) {
1933
* Determines whether or not the provided item is a legal number.
1936
* @param o The object to test.
1937
* @return {boolean} true if o is a number.
1939
L.isNumber = function(o) {
1940
return typeof o === 'number' && isFinite(o);
1944
* Determines whether or not the provided item is of type object
1945
* or function. Note that arrays are also objects, so
1946
* <code>Y.Lang.isObject([]) === true</code>.
1949
* @param o The object to test.
1950
* @param failfn {boolean} fail if the input is a function.
1951
* @return {boolean} true if o is an object.
1952
* @see isPlainObject
1954
L.isObject = function(o, failfn) {
1956
return (o && (t === 'object' ||
1957
(!failfn && (t === 'function' || L.isFunction(o))))) || false;
1961
* Determines whether or not the provided value is a regexp.
1964
* @param value The value or object to test.
1965
* @return {boolean} true if value is a regexp.
1967
L.isRegExp = function(value) {
1968
return L.type(value) === 'regexp';
1972
* Determines whether or not the provided item is a string.
1975
* @param o The object to test.
1976
* @return {boolean} true if o is a string.
1978
L.isString = function(o) {
1979
return typeof o === 'string';
1983
* Determines whether or not the provided item is undefined.
1984
* @method isUndefined
1986
* @param o The object to test.
1987
* @return {boolean} true if o is undefined.
1989
L.isUndefined = function(o) {
1990
return typeof o === 'undefined';
1994
* A convenience method for detecting a legitimate non-null value.
1995
* Returns false for null/undefined/NaN, true for other values,
1996
* including 0/false/''
1999
* @param o The item to test.
2000
* @return {boolean} true if it is not null/undefined/NaN || false.
2002
L.isValue = function(o) {
2009
case 'null': // fallthru
2019
* Returns the current time in milliseconds.
2022
* @return {Number} Current time in milliseconds.
2026
L.now = Date.now || function () {
2027
return new Date().getTime();
2031
* Lightweight version of <code>Y.substitute</code>. Uses the same template
2032
* structure as <code>Y.substitute</code>, but doesn't support recursion,
2033
* auto-object coersion, or formats.
2035
* @param {string} s String to be modified.
2036
* @param {object} o Object containing replacement values.
2037
* @return {string} the substitute result.
2041
L.sub = function(s, o) {
2042
return s.replace ? s.replace(SUBREGEX, function (match, key) {
2043
return L.isUndefined(o[key]) ? match : o[key];
2048
* Returns a string without any leading or trailing whitespace. If
2049
* the input is not a string, the input will be returned untouched.
2052
* @param s {string} the string to trim.
2053
* @return {string} the trimmed string.
2055
L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) {
2056
return s && s.trim ? s.trim() : s;
2059
return s.replace(TRIMREGEX, '');
2066
* Returns a string without any leading whitespace.
2069
* @param s {string} the string to trim.
2070
* @return {string} the trimmed string.
2072
L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) {
2073
return s.trimLeft();
2075
return s.replace(TRIM_LEFT_REGEX, '');
2079
* Returns a string without any trailing whitespace.
2082
* @param s {string} the string to trim.
2083
* @return {string} the trimmed string.
2085
L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) {
2086
return s.trimRight();
2088
return s.replace(TRIM_RIGHT_REGEX, '');
2092
Returns one of the following strings, representing the type of the item passed
2109
* `typeof HTMLElementCollection` returns function in Safari, but
2110
`Y.Lang.type()` reports "object", which could be a good thing --
2111
but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2114
@param o the item to test.
2115
@return {string} the detected type.
2118
L.type = function(o) {
2119
return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2127
Native = Array.prototype,
2129
hasOwn = Object.prototype.hasOwnProperty;
2132
Provides utility methods for working with arrays. Additional array helpers can
2133
be found in the `collection` and `array-extras` modules.
2135
`Y.Array(thing)` returns a native array created from _thing_. Depending on
2136
_thing_'s type, one of the following will happen:
2138
* Arrays are returned unmodified unless a non-zero _startIndex_ is
2140
* Array-like collections (see `Array.test()`) are converted to arrays.
2141
* For everything else, a new array is created with _thing_ as the sole
2144
Note: elements that are also collections, such as `<form>` and `<select>`
2145
elements, are not automatically converted to arrays. To force a conversion,
2146
pass `true` as the value of the _force_ parameter.
2150
@param {Any} thing The thing to arrayify.
2151
@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2152
collection, a subset of items starting at the specified index will be
2154
@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2155
array-like collection no matter what.
2156
@return {Array} A native array created from _thing_, according to the rules
2159
function YArray(thing, startIndex, force) {
2162
/*jshint expr: true*/
2163
startIndex || (startIndex = 0);
2165
if (force || YArray.test(thing)) {
2166
// IE throws when trying to slice HTMLElement collections.
2168
return Native.slice.call(thing, startIndex);
2172
for (len = thing.length; startIndex < len; ++startIndex) {
2173
result.push(thing[startIndex]);
2186
Dedupes an array of strings, returning an array that's guaranteed to contain
2187
only one copy of a given string.
2189
This method differs from `Array.unique()` in that it's optimized for use only
2190
with arrays consisting entirely of strings or entirely of numbers, whereas
2191
`unique` may be used with other value types (but is slower).
2193
Using `dedupe()` with values other than strings or numbers, or with arrays
2194
containing a mix of strings and numbers, may result in unexpected behavior.
2197
@param {String[]|Number[]} array Array of strings or numbers to dedupe.
2198
@return {Array} Copy of _array_ containing no duplicate values.
2202
YArray.dedupe = Lang._isNative(Object.create) ? function (array) {
2203
var hash = Object.create(null),
2207
for (i = 0, len = array.length; i < len; ++i) {
2217
} : function (array) {
2222
for (i = 0, len = array.length; i < len; ++i) {
2225
if (!hasOwn.call(hash, item)) {
2235
Executes the supplied function on each item in the array. This method wraps
2236
the native ES5 `Array.forEach()` method if available.
2239
@param {Array} array Array to iterate.
2240
@param {Function} fn Function to execute on each item in the array. The function
2241
will receive the following arguments:
2242
@param {Any} fn.item Current array item.
2243
@param {Number} fn.index Current array index.
2244
@param {Array} fn.array Array being iterated.
2245
@param {Object} [thisObj] `this` object to use when calling _fn_.
2246
@return {YUI} The YUI instance.
2249
YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
2250
Native.forEach.call(array || [], fn, thisObj || Y);
2252
} : function (array, fn, thisObj) {
2253
for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2255
fn.call(thisObj || Y, array[i], i, array);
2270
Returns an object using the first array as keys and the second as values. If
2271
the second array is not provided, or if it doesn't contain the same number of
2272
values as the first array, then `true` will be used in place of the missing
2277
Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2278
// => {a: 'foo', b: 'bar', c: true}
2281
@param {String[]} keys Array of strings to use as keys.
2282
@param {Array} [values] Array to use as values.
2283
@return {Object} Hash using the first array as keys and the second as values.
2286
YArray.hash = function (keys, values) {
2288
vlen = (values && values.length) || 0,
2291
for (i = 0, len = keys.length; i < len; ++i) {
2293
hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2301
Returns the index of the first item in the array that's equal (using a strict
2302
equality check) to the specified _value_, or `-1` if the value isn't found.
2304
This method wraps the native ES5 `Array.indexOf()` method if available.
2307
@param {Array} array Array to search.
2308
@param {Any} value Value to search for.
2309
@param {Number} [from=0] The index at which to begin the search.
2310
@return {Number} Index of the item strictly equal to _value_, or `-1` if not
2314
YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
2315
return Native.indexOf.call(array, value, from);
2316
} : function (array, value, from) {
2317
// http://es5.github.com/#x15.4.4.14
2318
var len = array.length;
2321
from = (from > 0 || -1) * Math.floor(Math.abs(from));
2331
for (; from < len; ++from) {
2332
if (from in array && array[from] === value) {
2341
Numeric sort convenience function.
2343
The native `Array.prototype.sort()` function converts values to strings and
2344
sorts them in lexicographic order, which is unsuitable for sorting numeric
2345
values. Provide `Array.numericSort` as a custom sort function when you want
2346
to sort values in numeric order.
2350
[42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2351
// => [4, 8, 15, 16, 23, 42]
2354
@param {Number} a First value to compare.
2355
@param {Number} b Second value to compare.
2356
@return {Number} Difference between _a_ and _b_.
2359
YArray.numericSort = function (a, b) {
2364
Executes the supplied function on each item in the array. Returning a truthy
2365
value from the function will stop the processing of remaining items.
2368
@param {Array} array Array to iterate over.
2369
@param {Function} fn Function to execute on each item. The function will receive
2370
the following arguments:
2371
@param {Any} fn.value Current array item.
2372
@param {Number} fn.index Current array index.
2373
@param {Array} fn.array Array being iterated over.
2374
@param {Object} [thisObj] `this` object to use when calling _fn_.
2375
@return {Boolean} `true` if the function returns a truthy value on any of the
2376
items in the array; `false` otherwise.
2379
YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
2380
return Native.some.call(array, fn, thisObj);
2381
} : function (array, fn, thisObj) {
2382
for (var i = 0, len = array.length; i < len; ++i) {
2383
if (i in array && fn.call(thisObj, array[i], i, array)) {
2392
Evaluates _obj_ to determine if it's an array, an array-like collection, or
2393
something else. This is useful when working with the function `arguments`
2394
collection and `HTMLElement` collections.
2396
Note: This implementation doesn't consider elements that are also
2397
collections, such as `<form>` and `<select>`, to be array-like.
2400
@param {Object} obj Object to test.
2401
@return {Number} A number indicating the results of the test:
2403
* 0: Neither an array nor an array-like collection.
2405
* 2: Array-like collection.
2409
YArray.test = function (obj) {
2412
if (Lang.isArray(obj)) {
2414
} else if (Lang.isObject(obj)) {
2416
// indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
2417
// or functions without apply/call (Safari
2418
// HTMLElementCollection bug).
2419
if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
2428
* The YUI module contains the components required for building the YUI
2429
* seed file. This includes the script loading mechanism, a simple queue,
2430
* and the core utilities for the library.
2432
* @submodule yui-base
2436
* A simple FIFO queue. Items are added to the Queue with add(1..n items) and
2437
* removed using next().
2441
* @param {MIXED} item* 0..n items to seed the queue.
2445
this.add.apply(this, arguments);
2450
* Initialize the queue
2457
* The collection of enqueued items
2467
* Get the next item in the queue. FIFO support
2470
* @return {MIXED} the next item in the queue.
2473
return this._q.shift();
2477
* Get the last in the queue. LIFO support.
2480
* @return {MIXED} the last item in the queue.
2483
return this._q.pop();
2487
* Add 0..n items to the end of the queue.
2490
* @param {MIXED} item* 0..n items.
2491
* @return {object} this queue.
2494
this._q.push.apply(this._q, arguments);
2500
* Returns the current number of queued items.
2503
* @return {Number} The size.
2506
return this._q.length;
2512
YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2515
The YUI module contains the components required for building the YUI seed file.
2516
This includes the script loading mechanism, a simple queue, and the core
2517
utilities for the library.
2523
var CACHED_DELIMITER = '__',
2525
hasOwn = Object.prototype.hasOwnProperty,
2526
isObject = Y.Lang.isObject;
2529
Returns a wrapper for a function which caches the return value of that function,
2530
keyed off of the combined string representation of the argument values provided
2531
when the wrapper is called.
2533
Calling this function again with the same arguments will return the cached value
2534
rather than executing the wrapped function.
2536
Note that since the cache is keyed off of the string representation of arguments
2537
passed to the wrapper function, arguments that aren't strings and don't provide
2538
a meaningful `toString()` method may result in unexpected caching behavior. For
2539
example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
2540
string `[object Object]` when used as a cache key.
2543
@param {Function} source The function to memoize.
2544
@param {Object} [cache={}] Object in which to store cached values. You may seed
2545
this object with pre-existing cached values if desired.
2546
@param {any} [refetch] If supplied, this value is compared with the cached value
2547
using a `==` comparison. If the values are equal, the wrapped function is
2548
executed again even though a cached value exists.
2549
@return {Function} Wrapped function.
2552
Y.cached = function (source, cache, refetch) {
2553
/*jshint expr: true*/
2554
cache || (cache = {});
2556
return function (arg) {
2557
var key = arguments.length > 1 ?
2558
Array.prototype.join.call(arguments, CACHED_DELIMITER) :
2561
/*jshint eqeqeq: false*/
2562
if (!(key in cache) || (refetch && cache[key] == refetch)) {
2563
cache[key] = source.apply(source, arguments);
2571
Returns the `location` object from the window/frame in which this YUI instance
2572
operates, or `undefined` when executing in a non-browser environment
2575
It is _not_ recommended to hold references to the `window.location` object
2576
outside of the scope of a function in which its properties are being accessed or
2577
its methods are being called. This is because of a nasty bug/issue that exists
2578
in both Safari and MobileSafari browsers:
2579
[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
2582
@return {location} The `location` object from the window/frame in which this YUI
2586
Y.getLocation = function () {
2587
// It is safer to look this up every time because yui-base is attached to a
2588
// YUI instance before a user's config is applied; i.e. `Y.config.win` does
2589
// not point the correct window object when this file is loaded.
2590
var win = Y.config.win;
2592
// It is not safe to hold a reference to the `location` object outside the
2593
// scope in which it is being used. The WebKit engine used in Safari and
2594
// MobileSafari will "disconnect" the `location` object from the `window`
2595
// when a page is restored from back/forward history cache.
2596
return win && win.location;
2600
Returns a new object containing all of the properties of all the supplied
2601
objects. The properties from later objects will overwrite those in earlier
2604
Passing in a single object will create a shallow copy of it. For a deep copy,
2608
@param {Object} objects* One or more objects to merge.
2609
@return {Object} A new merged object.
2611
Y.merge = function () {
2613
len = arguments.length,
2618
for (; i < len; ++i) {
2622
if (hasOwn.call(obj, key)) {
2623
result[key] = obj[key];
2632
Mixes _supplier_'s properties into _receiver_.
2634
Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
2635
shadowed unless the _overwrite_ parameter is `true`, and will not be merged
2636
unless the _merge_ parameter is `true`.
2638
In the default mode (0), only properties the supplier owns are copied (prototype
2639
properties are not copied). The following copying modes are available:
2641
* `0`: _Default_. Object to object.
2642
* `1`: Prototype to prototype.
2643
* `2`: Prototype to prototype and object to object.
2644
* `3`: Prototype to object.
2645
* `4`: Object to prototype.
2648
@param {Function|Object} receiver The object or function to receive the mixed
2650
@param {Function|Object} supplier The object or function supplying the
2651
properties to be mixed.
2652
@param {Boolean} [overwrite=false] If `true`, properties that already exist
2653
on the receiver will be overwritten with properties from the supplier.
2654
@param {String[]} [whitelist] An array of property names to copy. If
2655
specified, only the whitelisted properties will be copied, and all others
2657
@param {Number} [mode=0] Mix mode to use. See above for available modes.
2658
@param {Boolean} [merge=false] If `true`, objects and arrays that already
2659
exist on the receiver will have the corresponding object/array from the
2660
supplier merged into them, rather than being skipped or overwritten. When
2661
both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
2662
@return {Function|Object|YUI} The receiver, or the YUI instance if the
2663
specified receiver is falsy.
2665
Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
2666
var alwaysOverwrite, exists, from, i, key, len, to;
2668
// If no supplier is given, we return the receiver. If no receiver is given,
2669
// we return Y. Returning Y doesn't make much sense to me, but it's
2670
// grandfathered in for backcompat reasons.
2671
if (!receiver || !supplier) {
2672
return receiver || Y;
2676
// In mode 2 (prototype to prototype and object to object), we recurse
2677
// once to do the proto to proto mix. The object to object mix will be
2678
// handled later on.
2680
Y.mix(receiver.prototype, supplier.prototype, overwrite,
2681
whitelist, 0, merge);
2684
// Depending on which mode is specified, we may be copying from or to
2685
// the prototypes of the supplier and receiver.
2686
from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
2687
to = mode === 1 || mode === 4 ? receiver.prototype : receiver;
2689
// If either the supplier or receiver doesn't actually have a
2690
// prototype property, then we could end up with an undefined `from`
2691
// or `to`. If that happens, we abort and return the receiver.
2700
// If `overwrite` is truthy and `merge` is falsy, then we can skip a
2701
// property existence check on each iteration and save some time.
2702
alwaysOverwrite = overwrite && !merge;
2705
for (i = 0, len = whitelist.length; i < len; ++i) {
2708
// We call `Object.prototype.hasOwnProperty` instead of calling
2709
// `hasOwnProperty` on the object itself, since the object's
2710
// `hasOwnProperty` method may have been overridden or removed.
2711
// Also, some native objects don't implement a `hasOwnProperty`
2713
if (!hasOwn.call(from, key)) {
2717
// The `key in to` check here is (sadly) intentional for backwards
2718
// compatibility reasons. It prevents undesired shadowing of
2719
// prototype members on `to`.
2720
exists = alwaysOverwrite ? false : key in to;
2722
if (merge && exists && isObject(to[key], true)
2723
&& isObject(from[key], true)) {
2724
// If we're in merge mode, and the key is present on both
2725
// objects, and the value on both objects is either an object or
2726
// an array (but not a function), then we recurse to merge the
2727
// `from` value into the `to` value instead of overwriting it.
2729
// Note: It's intentional that the whitelist isn't passed to the
2730
// recursive call here. This is legacy behavior that lots of
2731
// code still depends on.
2732
Y.mix(to[key], from[key], overwrite, null, 0, merge);
2733
} else if (overwrite || !exists) {
2734
// We're not in merge mode, so we'll only copy the `from` value
2735
// to the `to` value if we're in overwrite mode or if the
2736
// current key doesn't exist on the `to` object.
2737
to[key] = from[key];
2742
// The code duplication here is for runtime performance reasons.
2743
// Combining whitelist and non-whitelist operations into a single
2744
// loop or breaking the shared logic out into a function both result
2745
// in worse performance, and Y.mix is critical enough that the byte
2746
// tradeoff is worth it.
2747
if (!hasOwn.call(from, key)) {
2751
// The `key in to` check here is (sadly) intentional for backwards
2752
// compatibility reasons. It prevents undesired shadowing of
2753
// prototype members on `to`.
2754
exists = alwaysOverwrite ? false : key in to;
2756
if (merge && exists && isObject(to[key], true)
2757
&& isObject(from[key], true)) {
2758
Y.mix(to[key], from[key], overwrite, null, 0, merge);
2759
} else if (overwrite || !exists) {
2760
to[key] = from[key];
2764
// If this is an IE browser with the JScript enumeration bug, force
2765
// enumeration of the buggy properties by making a recursive call with
2766
// the buggy properties as the whitelist.
2767
if (Y.Object._hasEnumBug) {
2768
Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
2775
* The YUI module contains the components required for building the YUI
2776
* seed file. This includes the script loading mechanism, a simple queue,
2777
* and the core utilities for the library.
2779
* @submodule yui-base
2783
* Adds utilities to the YUI instance for working with objects.
2789
hasOwn = Object.prototype.hasOwnProperty,
2791
UNDEFINED, // <-- Note the comma. We're still declaring vars.
2794
* Returns a new object that uses _obj_ as its prototype. This method wraps the
2795
* native ES5 `Object.create()` method if available, but doesn't currently
2796
* pass through `Object.create()`'s second argument (properties) in order to
2797
* ensure compatibility with older browsers.
2800
* @param {Object} obj Prototype object.
2801
* @return {Object} New object using _obj_ as its prototype.
2804
O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
2805
// We currently wrap the native Object.create instead of simply aliasing it
2806
// to ensure consistency with our fallback shim, which currently doesn't
2807
// support Object.create()'s second argument (properties). Once we have a
2808
// safe fallback for the properties arg, we can stop wrapping
2810
return Object.create(obj);
2812
// Reusable constructor function for the Object.create() shim.
2816
return function (obj) {
2823
* Property names that IE doesn't enumerate in for..in loops, even when they
2824
* should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
2825
* manually enumerate these properties.
2827
* @property _forceEnum
2832
forceEnum = O._forceEnum = [
2835
'propertyIsEnumerable',
2842
* `true` if this browser has the JScript enumeration bug that prevents
2843
* enumeration of the properties named in the `_forceEnum` array, `false`
2847
* - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
2848
* - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
2850
* @property _hasEnumBug
2855
hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
2858
* `true` if this browser incorrectly considers the `prototype` property of
2859
* functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x.
2861
* @property _hasProtoEnumBug
2866
hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
2869
* Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
2870
* exists only on _obj_'s prototype. This is essentially a safer version of
2871
* `obj.hasOwnProperty()`.
2874
* @param {Object} obj Object to test.
2875
* @param {String} key Property name to look for.
2876
* @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2879
owns = O.owns = function (obj, key) {
2880
return !!obj && hasOwn.call(obj, key);
2881
}; // <-- End of var declarations.
2884
* Alias for `owns()`.
2887
* @param {Object} obj Object to test.
2888
* @param {String} key Property name to look for.
2889
* @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2895
* Returns an array containing the object's enumerable keys. Does not include
2896
* prototype keys or non-enumerable keys.
2898
* Note that keys are returned in enumeration order (that is, in the same order
2899
* that they would be enumerated by a `for-in` loop), which may not be the same
2900
* as the order in which they were defined.
2902
* This method is an alias for the native ES5 `Object.keys()` method if
2903
* available and non-buggy. The Opera 11.50 and Android 2.3.x versions of
2904
* `Object.keys()` have an inconsistency as they consider `prototype` to be
2905
* enumerable, so a non-native shim is used to rectify the difference.
2909
* Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
2910
* // => ['a', 'b', 'c']
2913
* @param {Object} obj An object.
2914
* @return {String[]} Array of keys.
2917
O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) {
2918
if (!Lang.isObject(obj)) {
2919
throw new TypeError('Object.keys called on a non-object');
2925
if (hasProtoEnumBug && typeof obj === 'function') {
2927
if (owns(obj, key) && key !== 'prototype') {
2933
if (owns(obj, key)) {
2940
for (i = 0, len = forceEnum.length; i < len; ++i) {
2943
if (owns(obj, key)) {
2953
* Returns an array containing the values of the object's enumerable keys.
2955
* Note that values are returned in enumeration order (that is, in the same
2956
* order that they would be enumerated by a `for-in` loop), which may not be the
2957
* same as the order in which they were defined.
2961
* Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
2962
* // => ['foo', 'bar', 'baz']
2965
* @param {Object} obj An object.
2966
* @return {Array} Array of values.
2969
O.values = function (obj) {
2970
var keys = O.keys(obj),
2975
for (; i < len; ++i) {
2976
values.push(obj[keys[i]]);
2983
* Returns the number of enumerable keys owned by an object.
2986
* @param {Object} obj An object.
2987
* @return {Number} The object's size.
2990
O.size = function (obj) {
2992
return O.keys(obj).length;
2994
return 0; // Legacy behavior for non-objects.
2999
* Returns `true` if the object owns an enumerable property with the specified
3003
* @param {Object} obj An object.
3004
* @param {any} value The value to search for.
3005
* @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
3008
O.hasValue = function (obj, value) {
3009
return Y.Array.indexOf(O.values(obj), value) > -1;
3013
* Executes a function on each enumerable property in _obj_. The function
3014
* receives the value, the key, and the object itself as parameters (in that
3017
* By default, only properties owned by _obj_ are enumerated. To include
3018
* prototype properties, set the _proto_ parameter to `true`.
3021
* @param {Object} obj Object to enumerate.
3022
* @param {Function} fn Function to execute on each enumerable property.
3023
* @param {mixed} fn.value Value of the current property.
3024
* @param {String} fn.key Key of the current property.
3025
* @param {Object} fn.obj Object being enumerated.
3026
* @param {Object} [thisObj] `this` object to use when calling _fn_.
3027
* @param {Boolean} [proto=false] Include prototype properties.
3028
* @return {YUI} the YUI instance.
3032
O.each = function (obj, fn, thisObj, proto) {
3036
if (proto || owns(obj, key)) {
3037
fn.call(thisObj || Y, obj[key], key, obj);
3045
* Executes a function on each enumerable property in _obj_, but halts if the
3046
* function returns a truthy value. The function receives the value, the key,
3047
* and the object itself as paramters (in that order).
3049
* By default, only properties owned by _obj_ are enumerated. To include
3050
* prototype properties, set the _proto_ parameter to `true`.
3053
* @param {Object} obj Object to enumerate.
3054
* @param {Function} fn Function to execute on each enumerable property.
3055
* @param {mixed} fn.value Value of the current property.
3056
* @param {String} fn.key Key of the current property.
3057
* @param {Object} fn.obj Object being enumerated.
3058
* @param {Object} [thisObj] `this` object to use when calling _fn_.
3059
* @param {Boolean} [proto=false] Include prototype properties.
3060
* @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
3061
* `false` otherwise.
3064
O.some = function (obj, fn, thisObj, proto) {
3068
if (proto || owns(obj, key)) {
3069
if (fn.call(thisObj || Y, obj[key], key, obj)) {
3079
* Retrieves the sub value at the provided path,
3080
* from the value object provided.
3084
* @param o The object from which to extract the property value.
3085
* @param path {Array} A path array, specifying the object traversal path
3086
* from which to obtain the sub value.
3087
* @return {Any} The value stored in the path, undefined if not found,
3088
* undefined if the source is not an object. Returns the source object
3089
* if an empty path is provided.
3091
O.getValue = function(o, path) {
3092
if (!Lang.isObject(o)) {
3100
for (i = 0; o !== UNDEFINED && i < l; i++) {
3108
* Sets the sub-attribute value at the provided path on the
3109
* value object. Returns the modified value object, or
3110
* undefined if the path is invalid.
3114
* @param o The object on which to set the sub value.
3115
* @param path {Array} A path array, specifying the object traversal path
3116
* at which to set the sub value.
3117
* @param val {Any} The new value for the sub-attribute.
3118
* @return {Object} The modified object, with the new sub value set, or
3119
* undefined, if the path was invalid.
3121
O.setValue = function(o, path, val) {
3124
leafIdx = p.length - 1,
3128
for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3132
if (ref !== UNDEFINED) {
3143
* Returns `true` if the object has no enumerable properties of its own.
3146
* @param {Object} obj An object.
3147
* @return {Boolean} `true` if the object is empty.
3151
O.isEmpty = function (obj) {
3152
return !O.keys(Object(obj)).length;
3155
* The YUI module contains the components required for building the YUI seed
3156
* file. This includes the script loading mechanism, a simple queue, and the
3157
* core utilities for the library.
3159
* @submodule yui-base
3163
* YUI user agent detection.
3164
* Do not fork for a browser if it can be avoided. Use feature detection when
3165
* you can. Use the user agent as a last resort. For all fields listed
3166
* as @type float, UA stores a version number for the browser engine,
3167
* 0 otherwise. This value may or may not map to the version number of
3168
* the browser using the engine. The value is presented as a float so
3169
* that it can easily be used for boolean evaluation as well as for
3170
* looking for a particular range of versions. Because of this,
3171
* some of the granularity of the version info may be lost. The fields that
3172
* are @type string default to null. The API docs list the values that
3173
* these fields can have.
3179
* Static method on `YUI.Env` for parsing a UA string. Called at instantiation
3180
* to populate `Y.UA`.
3184
* @param {String} [subUA=navigator.userAgent] UA string to parse
3185
* @return {Object} The Y.UA object
3187
YUI.Env.parseUA = function(subUA) {
3189
var numberify = function(s) {
3191
return parseFloat(s.replace(/\./g, function() {
3192
return (c++ === 1) ? '' : '.';
3198
nav = win && win.navigator,
3203
* Internet Explorer version number or 0. Example: 6
3211
* Opera version number or 0. Example: 9.2
3219
* Gecko engine revision number. Will evaluate to 1 if Gecko
3220
* is detected but the revision could not be found. Other browsers
3221
* will be 0. Example: 1.8
3223
* Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7
3224
* Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3225
* Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3226
* Firefox 3.0 <-- 1.9
3227
* Firefox 3.5 <-- 1.91
3236
* AppleWebKit version. KHTML browsers that are not WebKit browsers
3237
* will evaluate to 1, other browsers 0. Example: 418.9
3239
* Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3240
* latest available for Mac OSX 10.3.
3241
* Safari 2.0.2: 416 <-- hasOwnProperty introduced
3242
* Safari 2.0.4: 418 <-- preventDefault fixed
3243
* Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3244
* different versions of webkit
3245
* Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been
3246
* updated, but not updated
3247
* to the latest patch.
3248
* Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native
3249
* SVG and many major issues fixed).
3250
* Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic
3251
* update from 2.x via the 10.4.11 OS patch.
3252
* Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event.
3253
* yahoo.com user agent hack removed.
3255
* http://en.wikipedia.org/wiki/Safari_version_history
3263
* Safari will be detected as webkit, but this property will also
3264
* be populated with the Safari version number
3272
* Chrome will be detected as webkit, but this property will also
3273
* be populated with the Chrome version number
3281
* The mobile property will be set to a string containing any relevant
3282
* user agent information when a modern mobile browser is detected.
3283
* Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3284
* devices with the WebKit-based browser, and Opera Mini.
3293
* Adobe AIR version number or 0. Only populated if webkit is detected.
3300
* PhantomJS version number or 0. Only populated if webkit is detected.
3302
* @property phantomjs
3307
* Detects Apple iPad's OS version
3314
* Detects Apple iPhone's OS version
3321
* Detects Apples iPod's OS version
3328
* General truthy check for iPad, iPhone or iPod
3336
* Detects Googles Android OS version
3343
* Detects Kindle Silk
3350
* Detects Kindle Silk Acceleration
3357
* Detects Palms WebOS version
3365
* Google Caja version number or 0.
3369
caja: nav && nav.cajaVersion,
3372
* Set to true if the page appears to be in SSL
3380
* The operating system. Currently only detecting windows or macintosh
3389
* The Nodejs Version
3397
* Window8/IE10 Application host environment
3402
winjs: !!((typeof Windows !== "undefined") && Windows.System),
3404
* Are touch/msPointer events available on this device
3405
* @property touchEnabled
3412
ua = subUA || nav && nav.userAgent,
3414
loc = win && win.location,
3416
href = loc && loc.href,
3421
* The User Agent string that was parsed
3422
* @property userAgent
3429
o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3433
if ((/windows|win32/i).test(ua)) {
3435
} else if ((/macintosh|mac_powerpc/i).test(ua)) {
3437
} else if ((/android/i).test(ua)) {
3439
} else if ((/symbos/i).test(ua)) {
3441
} else if ((/linux/i).test(ua)) {
3443
} else if ((/rhino/i).test(ua)) {
3447
// Modern KHTML browsers should qualify as Safari X-Grade
3448
if ((/KHTML/).test(ua)) {
3451
if ((/IEMobile|XBLWP7/).test(ua)) {
3452
o.mobile = 'windows';
3454
if ((/Fennec/).test(ua)) {
3457
// Modern WebKit browsers are at least X-Grade
3458
m = ua.match(/AppleWebKit\/([^\s]*)/);
3460
o.webkit = numberify(m[1]);
3461
o.safari = o.webkit;
3463
if (/PhantomJS/.test(ua)) {
3464
m = ua.match(/PhantomJS\/([^\s]*)/);
3466
o.phantomjs = numberify(m[1]);
3470
// Mobile browser check
3471
if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
3472
o.mobile = 'Apple'; // iPhone or iPod Touch
3474
m = ua.match(/OS ([^\s]*)/);
3476
m = numberify(m[1].replace('_', '.'));
3480
o.ipad = o.ipod = o.iphone = 0;
3482
m = ua.match(/iPad|iPod|iPhone/);
3484
o[m[0].toLowerCase()] = o.ios;
3487
m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3489
// Nokia N-series, webOS, ex: NokiaN95
3492
if (/webOS/.test(ua)) {
3494
m = ua.match(/webOS\/([^\s]*);/);
3496
o.webos = numberify(m[1]);
3499
if (/ Android/.test(ua)) {
3500
if (/Mobile/.test(ua)) {
3501
o.mobile = 'Android';
3503
m = ua.match(/Android ([^\s]*);/);
3505
o.android = numberify(m[1]);
3509
if (/Silk/.test(ua)) {
3510
m = ua.match(/Silk\/([^\s]*)\)/);
3512
o.silk = numberify(m[1]);
3515
o.android = 2.34; //Hack for desktop mode in Kindle
3518
if (/Accelerated=true/.test(ua)) {
3524
m = ua.match(/OPR\/(\d+\.\d+)/);
3527
// Opera 15+ with Blink (pretends to be both Chrome and Safari)
3528
o.opera = numberify(m[1]);
3530
m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
3532
if (m && m[1] && m[2]) {
3533
o.chrome = numberify(m[2]); // Chrome
3534
o.safari = 0; //Reset safari back to 0
3535
if (m[1] === 'CrMo') {
3536
o.mobile = 'chrome';
3539
m = ua.match(/AdobeAIR\/([^\s]*)/);
3541
o.air = m[0]; // Adobe AIR 1.0 or better
3547
if (!o.webkit) { // not webkit
3548
// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
3549
if (/Opera/.test(ua)) {
3550
m = ua.match(/Opera[\s\/]([^\s]*)/);
3552
o.opera = numberify(m[1]);
3554
m = ua.match(/Version\/([^\s]*)/);
3556
o.opera = numberify(m[1]); // opera 10+
3559
if (/Opera Mobi/.test(ua)) {
3561
m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
3563
o.opera = numberify(m[1]);
3566
m = ua.match(/Opera Mini[^;]*/);
3569
o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
3571
} else { // not opera or webkit
3572
m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/);
3574
if (m && (m[1] || m[2])) {
3575
o.ie = numberify(m[1] || m[2]);
3576
} else { // not opera, webkit, or ie
3577
m = ua.match(/Gecko\/([^\s]*)/);
3580
o.gecko = 1; // Gecko detected, look for revision
3581
m = ua.match(/rv:([^\s\)]*)/);
3583
o.gecko = numberify(m[1]);
3584
if (/Mobile|Tablet/.test(ua)) {
3594
//Check for known properties to tell if touch events are enabled on this device or if
3595
//the number of MSPointer touchpoints on this device is greater than 0.
3596
if (win && nav && !(o.chrome && o.chrome < 6)) {
3597
o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
3600
//It was a parsed UA, do not assign the global value.
3603
if (typeof process === 'object') {
3605
if (process.versions && process.versions.node) {
3607
o.os = process.platform;
3608
o.nodejs = numberify(process.versions.node);
3620
Y.UA = YUI.Env.UA || YUI.Env.parseUA();
3623
Performs a simple comparison between two version numbers, accounting for
3624
standard versioning logic such as the fact that "535.8" is a lower version than
3625
"535.24", even though a simple numerical comparison would indicate that it's
3626
greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
3627
considered equivalent.
3629
Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
3630
1 if _a_ is higher than _b_.
3632
Versions may be numbers or strings containing numbers and dots. For example,
3633
both `535` and `"535.8.10"` are acceptable. A version string containing
3634
non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
3636
@method compareVersions
3637
@param {Number|String} a First version number to compare.
3638
@param {Number|String} b Second version number to compare.
3639
@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
3642
Y.UA.compareVersions = function (a, b) {
3643
var aPart, aParts, bPart, bParts, i, len;
3649
aParts = (a + '').split('.');
3650
bParts = (b + '').split('.');
3652
for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
3653
aPart = parseInt(aParts[i], 10);
3654
bPart = parseInt(bParts[i], 10);
3656
/*jshint expr: true*/
3657
isNaN(aPart) && (aPart = 0);
3658
isNaN(bPart) && (bPart = 0);
3660
if (aPart < bPart) {
3664
if (aPart > bPart) {
3672
"anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
3673
"anim-shape-transform": ["anim-shape"],
3674
"app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"],
3675
"attribute": ["attribute-base","attribute-complex"],
3676
"attribute-events": ["attribute-observable"],
3677
"autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
3678
"axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
3679
"axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
3680
"base": ["base-base","base-pluginhost","base-build"],
3681
"cache": ["cache-base","cache-offline","cache-plugin"],
3682
"charts": ["charts-base"],
3683
"collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
3684
"color": ["color-base","color-hsl","color-harmony"],
3685
"controller": ["router"],
3686
"dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
3687
"datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
3688
"datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
3689
"datatype": ["datatype-date","datatype-number","datatype-xml"],
3690
"datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
3691
"datatype-number": ["datatype-number-parse","datatype-number-format"],
3692
"datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
3693
"dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
3694
"dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
3695
"editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
3696
"event": ["event-base","event-delegate","event-synthetic","event-mousewheel","event-mouseenter","event-key","event-focus","event-resize","event-hover","event-outside","event-touch","event-move","event-flick","event-valuechange","event-tap"],
3697
"event-custom": ["event-custom-base","event-custom-complex"],
3698
"event-gestures": ["event-flick","event-move"],
3699
"handlebars": ["handlebars-compiler"],
3700
"highlight": ["highlight-base","highlight-accentfold"],
3701
"history": ["history-base","history-hash","history-hash-ie","history-html5"],
3702
"io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
3703
"json": ["json-parse","json-stringify"],
3704
"loader": ["loader-base","loader-rollup","loader-yui3"],
3705
"node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
3706
"pluginhost": ["pluginhost-base","pluginhost-config"],
3707
"querystring": ["querystring-parse","querystring-stringify"],
3708
"recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
3709
"resize": ["resize-base","resize-proxy","resize-constrain"],
3710
"slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
3711
"template": ["template-base","template-micro"],
3712
"text": ["text-accentfold","text-wordbreak"],
3713
"widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
3717
}, '3.13.0', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});
3718
YUI.add('get', function (Y, NAME) {
3720
/*jslint boss:true, expr:true, laxbreak: true */
3723
Provides dynamic loading of remote JavaScript and CSS resources.
3732
CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
3737
// -- Public Properties ----------------------------------------------------
3740
Default options for CSS requests. Options specified here will override
3741
global defaults for CSS requests.
3743
See the `options` property for all available options.
3745
@property cssOptions
3755
doc : Y.config.linkDoc || Y.config.doc,
3760
Default options for JS requests. Options specified here will override global
3761
defaults for JS requests.
3763
See the `options` property for all available options.
3772
doc : Y.config.scriptDoc || Y.config.doc
3776
Default options to use for all requests.
3778
Note that while all available options are documented here for ease of
3779
discovery, some options (like callback functions) only make sense at the
3782
Callback functions specified via the options object or the `options`
3783
parameter of the `css()`, `js()`, or `load()` methods will receive the
3784
transaction object as a parameter. See `Y.Get.Transaction` for details on
3785
the properties and methods available on transactions.
3789
@property {Object} options
3791
@property {Boolean} [options.async=false] Whether or not to load scripts
3792
asynchronously, meaning they're requested in parallel and execution
3793
order is not guaranteed. Has no effect on CSS, since CSS is always
3794
loaded asynchronously.
3796
@property {Object} [options.attributes] HTML attribute name/value pairs that
3797
should be added to inserted nodes. By default, the `charset` attribute
3798
will be set to "utf-8" and nodes will be given an auto-generated `id`
3799
attribute, but you can override these with your own values if desired.
3801
@property {Boolean} [options.autopurge] Whether or not to automatically
3802
purge inserted nodes after the purge threshold is reached. This is
3803
`true` by default for JavaScript, but `false` for CSS since purging a
3804
CSS node will also remove any styling applied by the referenced file.
3806
@property {Object} [options.context] `this` object to use when calling
3807
callback functions. Defaults to the transaction object.
3809
@property {Mixed} [options.data] Arbitrary data object to pass to "on*"
3812
@property {Document} [options.doc] Document into which nodes should be
3813
inserted. By default, the current document is used.
3815
@property {HTMLElement|String} [options.insertBefore] HTML element or id
3816
string of an element before which all generated nodes should be
3817
inserted. If not specified, Get will automatically determine the best
3818
place to insert nodes for maximum compatibility.
3820
@property {Function} [options.onEnd] Callback to execute after a transaction
3821
is complete, regardless of whether it succeeded or failed.
3823
@property {Function} [options.onFailure] Callback to execute after a
3824
transaction fails, times out, or is aborted.
3826
@property {Function} [options.onProgress] Callback to execute after each
3827
individual request in a transaction either succeeds or fails.
3829
@property {Function} [options.onSuccess] Callback to execute after a
3830
transaction completes successfully with no errors. Note that in browsers
3831
that don't support the `error` event on CSS `<link>` nodes, a failed CSS
3832
request may still be reported as a success because in these browsers
3833
it can be difficult or impossible to distinguish between success and
3834
failure for CSS resources.
3836
@property {Function} [options.onTimeout] Callback to execute after a
3837
transaction times out.
3839
@property {Number} [options.pollInterval=50] Polling interval (in
3840
milliseconds) for detecting CSS load completion in browsers that don't
3841
support the `load` event on `<link>` nodes. This isn't used for
3844
@property {Number} [options.purgethreshold=20] Number of nodes to insert
3845
before triggering an automatic purge when `autopurge` is `true`.
3847
@property {Number} [options.timeout] Number of milliseconds to wait before
3848
aborting a transaction. When a timeout occurs, the `onTimeout` callback
3849
is called, followed by `onFailure` and finally `onEnd`. By default,
3850
there is no timeout.
3852
@property {String} [options.type] Resource type ("css" or "js"). This option
3853
is set automatically by the `css()` and `js()` functions and will be
3854
ignored there, but may be useful when using the `load()` function. If
3855
not specified, the type will be inferred from the URL, defaulting to
3856
"js" if the URL doesn't contain a recognizable file extension.
3866
// -- Protected Properties -------------------------------------------------
3869
Regex that matches a CSS URL. Used to guess the file type when it's not
3879
REGEX_CSS: /\.css(?:[?;].*)?$/i,
3882
Regex that matches a JS URL. Used to guess the file type when it's not
3892
REGEX_JS : /\.js(?:[?;].*)?$/i,
3895
Contains information about the current environment, such as what script and
3896
link injection features it supports.
3898
This object is created and populated the first time the `_getEnv()` method
3909
Mapping of document _yuid strings to <head> or <base> node references so we
3910
don't have to look the node up each time we want to insert a request node.
3912
@property _insertCache
3921
Information about the currently pending transaction, if any.
3923
This is actually an object with two properties: `callback`, containing the
3924
optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
3925
containing the actual transaction instance.
3936
HTML nodes eligible to be purged next time autopurge is triggered.
3938
@property _purgeNodes
3947
Queued transactions and associated callbacks.
3957
// -- Public Methods -------------------------------------------------------
3960
Aborts the specified transaction.
3962
This will cause the transaction's `onFailure` callback to be called and
3963
will prevent any new script and link nodes from being added to the document,
3964
but any resources that have already been requested will continue loading
3965
(there's no safe way to prevent this, unfortunately).
3967
*Note:* This method is deprecated as of 3.5.0, and will be removed in a
3968
future version of YUI. Use the transaction-level `abort()` method instead.
3971
@param {Get.Transaction} transaction Transaction to abort.
3972
@deprecated Use the `abort()` method on the transaction instead.
3975
abort: function (transaction) {
3976
var i, id, item, len, pending;
3979
if (!transaction.abort) {
3981
pending = this._pending;
3984
if (pending && pending.transaction.id === id) {
3985
transaction = pending.transaction;
3986
this._pending = null;
3988
for (i = 0, len = this._queue.length; i < len; ++i) {
3989
item = this._queue[i].transaction;
3991
if (item.id === id) {
3993
this._queue.splice(i, 1);
4000
transaction && transaction.abort();
4004
Loads one or more CSS files.
4006
The _urls_ parameter may be provided as a URL string, a request object,
4007
or an array of URL strings and/or request objects.
4009
A request object is just an object that contains a `url` property and zero
4010
or more options that should apply specifically to that request.
4011
Request-specific options take priority over transaction-level options and
4014
URLs may be relative or absolute, and do not have to have the same origin
4015
as the current page.
4017
The `options` parameter may be omitted completely and a callback passed in
4018
its place, if desired.
4022
// Load a single CSS file and log a message on completion.
4023
Y.Get.css('foo.css', function (err) {
4029
// Load multiple CSS files and log a message when all have finished
4031
var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
4033
Y.Get.css(urls, function (err) {
4039
// Specify transaction-level options, which will apply to all requests
4040
// within the transaction.
4042
attributes: {'class': 'my-css'},
4046
// Specify per-request options, which override transaction-level and
4049
{url: 'foo.css', attributes: {id: 'foo'}},
4050
{url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4054
@param {String|Object|Array} urls URL string, request object, or array
4055
of URLs and/or request objects to load.
4056
@param {Object} [options] Options for this transaction. See the
4057
`Y.Get.options` property for a complete list of available options.
4058
@param {Function} [callback] Callback function to be called on completion.
4059
This is a general callback and will be called before any more granular
4060
callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4063
@param {Array|null} callback.err Array of errors that occurred during
4064
the transaction, or `null` on success.
4065
@param {Get.Transaction} callback.transaction Transaction object.
4067
@return {Get.Transaction} Transaction object.
4070
css: function (urls, options, callback) {
4071
return this._load('css', urls, options, callback);
4075
Loads one or more JavaScript resources.
4077
The _urls_ parameter may be provided as a URL string, a request object,
4078
or an array of URL strings and/or request objects.
4080
A request object is just an object that contains a `url` property and zero
4081
or more options that should apply specifically to that request.
4082
Request-specific options take priority over transaction-level options and
4085
URLs may be relative or absolute, and do not have to have the same origin
4086
as the current page.
4088
The `options` parameter may be omitted completely and a callback passed in
4089
its place, if desired.
4091
Scripts will be executed in the order they're specified unless the `async`
4092
option is `true`, in which case they'll be loaded in parallel and executed
4093
in whatever order they finish loading.
4097
// Load a single JS file and log a message on completion.
4098
Y.Get.js('foo.js', function (err) {
4104
// Load multiple JS files, execute them in order, and log a message when
4105
// all have finished loading.
4106
var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
4108
Y.Get.js(urls, function (err) {
4114
// Specify transaction-level options, which will apply to all requests
4115
// within the transaction.
4117
attributes: {'class': 'my-js'},
4121
// Specify per-request options, which override transaction-level and
4124
{url: 'foo.js', attributes: {id: 'foo'}},
4125
{url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4129
@param {String|Object|Array} urls URL string, request object, or array
4130
of URLs and/or request objects to load.
4131
@param {Object} [options] Options for this transaction. See the
4132
`Y.Get.options` property for a complete list of available options.
4133
@param {Function} [callback] Callback function to be called on completion.
4134
This is a general callback and will be called before any more granular
4135
callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4138
@param {Array|null} callback.err Array of errors that occurred during
4139
the transaction, or `null` on success.
4140
@param {Get.Transaction} callback.transaction Transaction object.
4142
@return {Get.Transaction} Transaction object.
4146
js: function (urls, options, callback) {
4147
return this._load('js', urls, options, callback);
4151
Loads one or more CSS and/or JavaScript resources in the same transaction.
4153
Use this method when you want to load both CSS and JavaScript in a single
4154
transaction and be notified when all requested URLs have finished loading,
4157
Behavior and options are the same as for the `css()` and `js()` methods. If
4158
a resource type isn't specified in per-request options or transaction-level
4159
options, Get will guess the file type based on the URL's extension (`.css`
4160
or `.js`, with or without a following query string). If the file type can't
4161
be guessed from the URL, a warning will be logged and Get will assume the
4162
URL is a JavaScript resource.
4166
// Load both CSS and JS files in a single transaction, and log a message
4167
// when all files have finished loading.
4168
Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
4175
@param {String|Object|Array} urls URL string, request object, or array
4176
of URLs and/or request objects to load.
4177
@param {Object} [options] Options for this transaction. See the
4178
`Y.Get.options` property for a complete list of available options.
4179
@param {Function} [callback] Callback function to be called on completion.
4180
This is a general callback and will be called before any more granular
4181
callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4184
@param {Array|null} err Array of errors that occurred during the
4185
transaction, or `null` on success.
4186
@param {Get.Transaction} Transaction object.
4188
@return {Get.Transaction} Transaction object.
4192
load: function (urls, options, callback) {
4193
return this._load(null, urls, options, callback);
4196
// -- Protected Methods ----------------------------------------------------
4199
Triggers an automatic purge if the purge threshold has been reached.
4202
@param {Number} threshold Purge threshold to use, in milliseconds.
4207
_autoPurge: function (threshold) {
4208
if (threshold && this._purgeNodes.length >= threshold) {
4209
this._purge(this._purgeNodes);
4214
Populates the `_env` property with information about the current
4218
@return {Object} Environment information.
4223
_getEnv: function () {
4224
var doc = Y.config.doc,
4227
// Note: some of these checks require browser sniffs since it's not
4228
// feasible to load test files on every pageview just to perform a
4229
// feature test. I'm sorry if this makes you sad.
4230
return (this._env = {
4232
// True if this is a browser that supports disabling async mode on
4233
// dynamically created script nodes. See
4234
// https://developer.mozilla.org/En/HTML/Element/Script#Attributes
4236
// IE10 doesn't return true for the MDN feature test, so setting it explicitly,
4237
// because it is async by default, and allows you to disable async by setting it to false
4238
async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
4240
// True if this browser fires an event when a dynamically injected
4241
// link node fails to load. This is currently true for Firefox 9+
4242
// and WebKit 535.24+
4243
cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
4245
// True if this browser fires an event when a dynamically injected
4246
// link node finishes loading. This is currently true for IE, Opera,
4247
// Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
4248
// DOM 0 "onload" event, but not "load". All versions of IE fire
4250
// davglass: Seems that Chrome on Android needs this to be false.
4252
(!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
4253
ua.compareVersions(ua.webkit, 535.24) >= 0
4254
) && !(ua.chrome && ua.chrome <= 18),
4256
// True if this browser preserves script execution order while
4257
// loading scripts in parallel as long as the script node's `async`
4258
// attribute is set to false to explicitly disable async execution.
4259
preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
4263
_getTransaction: function (urls, options) {
4267
if (!Lang.isArray(urls)) {
4271
options = Y.merge(this.options, options);
4273
// Clone the attributes object so we don't end up modifying it by ref.
4274
options.attributes = Y.merge(this.options.attributes,
4275
options.attributes);
4277
for (i = 0, len = urls.length; i < len; ++i) {
4279
req = {attributes: {}};
4281
// If `url` is a string, we create a URL object for it, then mix in
4282
// global options and request-specific options. If it's an object
4283
// with a "url" property, we assume it's a request object containing
4284
// URL-specific options.
4285
if (typeof url === 'string') {
4287
} else if (url.url) {
4288
// URL-specific options override both global defaults and
4289
// request-specific options.
4290
Y.mix(req, url, false, null, 0, true);
4291
url = url.url; // Make url a string so we can use it later.
4296
Y.mix(req, options, false, null, 0, true);
4298
// If we didn't get an explicit type for this URL either in the
4299
// request options or the URL-specific options, try to determine
4300
// one from the file extension.
4302
if (this.REGEX_CSS.test(url)) {
4305
if (!this.REGEX_JS.test(url)) {
4312
// Mix in type-specific default options, but don't overwrite any
4313
// options that have already been set.
4314
Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
4315
false, null, 0, true);
4317
// Give the node an id attribute if it doesn't already have one.
4318
req.attributes.id || (req.attributes.id = Y.guid());
4320
// Backcompat for <3.5.0 behavior.
4322
req.doc = req.win.document;
4324
req.win = req.doc.defaultView || req.doc.parentWindow;
4328
req.attributes.charset = req.charset;
4334
return new Transaction(requests, options);
4337
_load: function (type, urls, options, callback) {
4340
// Allow callback as third param.
4341
if (typeof options === 'function') {
4346
options || (options = {});
4347
options.type = type;
4349
options._onFinish = Get._onTransactionFinish;
4355
transaction = this._getTransaction(urls, options);
4358
callback : callback,
4359
transaction: transaction
4367
_onTransactionFinish : function() {
4368
Get._pending = null;
4372
_next: function () {
4375
if (this._pending) {
4379
item = this._queue.shift();
4382
this._pending = item;
4383
item.transaction.execute(item.callback);
4387
_purge: function (nodes) {
4388
var purgeNodes = this._purgeNodes,
4389
isTransaction = nodes !== purgeNodes,
4392
while (node = nodes.pop()) { // assignment
4393
// Don't purge nodes that haven't finished loading (or errored out),
4394
// since this can hang the transaction.
4395
if (!node._yuiget_finished) {
4399
node.parentNode && node.parentNode.removeChild(node);
4401
// If this is a transaction-level purge and this node also exists in
4402
// the Get-level _purgeNodes array, we need to remove it from
4403
// _purgeNodes to avoid creating a memory leak. The indexOf lookup
4404
// sucks, but until we get WeakMaps, this is the least troublesome
4405
// way to do this (we can't just hold onto node ids because they may
4406
// not be in the same document).
4407
if (isTransaction) {
4408
index = Y.Array.indexOf(purgeNodes, node);
4411
purgeNodes.splice(index, 1);
4424
Get.script = Get.js;
4427
Represents a Get transaction, which may contain requests for one or more JS or
4430
This class should not be instantiated manually. Instances will be created and
4431
returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
4433
@class Get.Transaction
4437
Get.Transaction = Transaction = function (requests, options) {
4440
self.id = Transaction._lastId += 1;
4441
self.data = options.data;
4444
self.options = options;
4445
self.requests = requests;
4447
self._callbacks = []; // callbacks to call after execution finishes
4449
self._reqsWaiting = 0;
4451
// Deprecated pre-3.5.0 properties.
4452
self.tId = self.id; // Use `id` instead.
4453
self.win = options.win || Y.config.win;
4457
Arbitrary data object associated with this transaction.
4459
This object comes from the options passed to `Get.css()`, `Get.js()`, or
4460
`Get.load()`, and will be `undefined` if no data object was specified.
4462
@property {Object} data
4466
Array of errors that have occurred during this transaction, if any.
4469
@property {Object[]} errors
4470
@property {String} errors.error Error message.
4471
@property {Object} errors.request Request object related to the error.
4475
Numeric id for this transaction, unique among all transactions within the same
4476
YUI sandbox in the current pageview.
4478
@property {Number} id
4483
HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
4484
during the current transaction.
4486
@property {HTMLElement[]} nodes
4490
Options associated with this transaction.
4492
See `Get.options` for the full list of available options.
4494
@property {Object} options
4499
Request objects contained in this transaction. Each request object represents
4500
one CSS or JS URL that will be (or has been) requested and loaded into the page.
4502
@property {Object} requests
4507
Id of the most recent transaction.
4514
Transaction._lastId = 0;
4516
Transaction.prototype = {
4517
// -- Public Properties ----------------------------------------------------
4520
Current state of this transaction. One of "new", "executing", or "done".
4526
_state: 'new', // "new", "executing", or "done"
4528
// -- Public Methods -------------------------------------------------------
4531
Aborts this transaction.
4533
This will cause the transaction's `onFailure` callback to be called and
4534
will prevent any new script and link nodes from being added to the document,
4535
but any resources that have already been requested will continue loading
4536
(there's no safe way to prevent this, unfortunately).
4539
@param {String} [msg="Aborted."] Optional message to use in the `errors`
4540
array describing why the transaction was aborted.
4542
abort: function (msg) {
4543
this._pending = null;
4544
this._pendingCSS = null;
4545
this._pollTimer = clearTimeout(this._pollTimer);
4547
this._reqsWaiting = 0;
4549
this.errors.push({error: msg || 'Aborted'});
4554
Begins execting the transaction.
4556
There's usually no reason to call this manually, since Get will call it
4557
automatically when other pending transactions have finished. If you really
4558
want to execute your transaction before Get does, you can, but be aware that
4559
this transaction's scripts may end up executing before the scripts in other
4560
pending transactions.
4562
If the transaction is already executing, the specified callback (if any)
4563
will be queued and called after execution finishes. If the transaction has
4564
already finished, the callback will be called immediately (the transaction
4565
will not be executed again).
4568
@param {Function} callback Callback function to execute after all requests
4569
in the transaction are complete, or after the transaction is aborted.
4571
execute: function (callback) {
4573
requests = self.requests,
4574
state = self._state,
4577
if (state === 'done') {
4578
callback && callback(self.errors.length ? self.errors : null, self);
4581
callback && self._callbacks.push(callback);
4583
if (state === 'executing') {
4588
self._state = 'executing';
4589
self._queue = queue = [];
4591
if (self.options.timeout) {
4592
self._timeout = setTimeout(function () {
4593
self.abort('Timeout');
4594
}, self.options.timeout);
4597
self._reqsWaiting = requests.length;
4599
for (i = 0, len = requests.length; i < len; ++i) {
4602
if (req.async || req.type === 'css') {
4603
// No need to queue CSS or fully async JS.
4614
Manually purges any `<script>` or `<link>` nodes this transaction has
4617
Be careful when purging a transaction that contains CSS requests, since
4618
removing `<link>` nodes will also remove any styles they applied.
4622
purge: function () {
4623
Get._purge(this.nodes);
4626
// -- Protected Methods ----------------------------------------------------
4627
_createNode: function (name, attrs, doc) {
4628
var node = doc.createElement(name),
4631
if (!CUSTOM_ATTRS) {
4632
// IE6 and IE7 expect property names rather than attribute names for
4633
// certain attributes. Rather than sniffing, we do a quick feature
4634
// test the first time _createNode() runs to determine whether we
4635
// need to provide a workaround.
4636
testEl = doc.createElement('div');
4637
testEl.setAttribute('class', 'a');
4639
CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
4641
'class': 'className'
4645
for (attr in attrs) {
4646
if (attrs.hasOwnProperty(attr)) {
4647
node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
4654
_finish: function () {
4655
var errors = this.errors.length ? this.errors : null,
4656
options = this.options,
4657
thisObj = options.context || this,
4660
if (this._state === 'done') {
4664
this._state = 'done';
4666
for (i = 0, len = this._callbacks.length; i < len; ++i) {
4667
this._callbacks[i].call(thisObj, errors, this);
4670
data = this._getEventData();
4673
if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
4674
options.onTimeout.call(thisObj, data);
4677
if (options.onFailure) {
4678
options.onFailure.call(thisObj, data);
4680
} else if (options.onSuccess) {
4681
options.onSuccess.call(thisObj, data);
4684
if (options.onEnd) {
4685
options.onEnd.call(thisObj, data);
4688
if (options._onFinish) {
4689
options._onFinish();
4693
_getEventData: function (req) {
4695
// This merge is necessary for backcompat. I hate it.
4696
return Y.merge(this, {
4697
abort : this.abort, // have to copy these because the prototype isn't preserved
4708
_getInsertBefore: function (req) {
4710
el = req.insertBefore,
4714
return typeof el === 'string' ? doc.getElementById(el) : el;
4717
cache = Get._insertCache;
4718
docStamp = Y.stamp(doc);
4720
if ((el = cache[docStamp])) { // assignment
4724
// Inserting before a <base> tag apparently works around an IE bug
4725
// (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
4726
// bug that is, exactly. Better safe than sorry?
4727
if ((el = doc.getElementsByTagName('base')[0])) { // assignment
4728
return (cache[docStamp] = el);
4731
// Look for a <head> element.
4732
el = doc.head || doc.getElementsByTagName('head')[0];
4735
// Create a marker node at the end of <head> to use as an insertion
4736
// point. Inserting before this node will ensure that all our CSS
4737
// gets inserted in the correct order, to maintain style precedence.
4738
el.appendChild(doc.createTextNode(''));
4739
return (cache[docStamp] = el.lastChild);
4742
// If all else fails, just insert before the first script node on the
4743
// page, which is virtually guaranteed to exist.
4744
return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
4747
_insert: function (req) {
4749
insertBefore = this._getInsertBefore(req),
4750
isScript = req.type === 'js',
4754
cssTimeout, nodeType;
4758
nodeType = 'script';
4759
} else if (!env.cssLoad && ua.gecko) {
4765
node = req.node = this._createNode(nodeType, req.attributes,
4769
function onError() {
4770
self._progress('Failed to load ' + req.url, req);
4775
clearTimeout(cssTimeout);
4778
self._progress(null, req);
4781
// Deal with script asynchronicity.
4783
node.setAttribute('src', req.url);
4786
// Explicitly indicate that we want the browser to execute this
4787
// script asynchronously. This is necessary for older browsers
4792
// This browser treats injected scripts as async by default
4793
// (standard HTML5 behavior) but asynchronous loading isn't
4794
// desired, so tell the browser not to mark this script as
4799
// If this browser doesn't preserve script execution order based
4800
// on insertion order, we'll need to avoid inserting other
4801
// scripts until this one finishes loading.
4802
if (!env.preservesScriptOrder) {
4803
this._pending = req;
4807
if (!env.cssLoad && ua.gecko) {
4808
// In Firefox <9, we can import the requested URL into a <style>
4809
// node and poll for the existence of node.sheet.cssRules. This
4810
// gives us a reliable way to determine CSS load completion that
4811
// also works for cross-domain stylesheets.
4813
// Props to Zach Leatherman for calling my attention to this
4815
node.innerHTML = (req.attributes.charset ?
4816
'@charset "' + req.attributes.charset + '";' : '') +
4817
'@import "' + req.url + '";';
4819
node.setAttribute('href', req.url);
4824
if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
4825
// Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
4826
node.onreadystatechange = function () {
4827
if (/loaded|complete/.test(node.readyState)) {
4828
node.onreadystatechange = null;
4832
} else if (!isScript && !env.cssLoad) {
4833
// CSS on Firefox <9 or WebKit.
4836
// Script or CSS on everything else. Using DOM 0 events because that
4837
// evens the playing field with older IEs.
4841
// We currently need to introduce a timeout for IE10, since it
4842
// calls onerror/onload synchronously for 304s - messing up existing
4845
// Remove this block if the following bug gets fixed by GA
4846
/*jshint maxlen: 1500 */
4847
// https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
4848
node.onerror = function() { setTimeout(onError, 0); };
4849
node.onload = function() { setTimeout(onLoad, 0); };
4851
node.onerror = onError;
4852
node.onload = onLoad;
4855
// If this browser doesn't fire an event when CSS fails to load,
4856
// fail after a timeout to avoid blocking the transaction queue.
4857
if (!env.cssFail && !isScript) {
4858
cssTimeout = setTimeout(onError, req.timeout || 3000);
4862
this.nodes.push(node);
4863
insertBefore.parentNode.insertBefore(node, insertBefore);
4866
_next: function () {
4867
if (this._pending) {
4871
// If there are requests in the queue, insert the next queued request.
4872
// Otherwise, if we're waiting on already-inserted requests to finish,
4873
// wait longer. If there are no queued requests and we're not waiting
4874
// for anything to load, then we're done!
4875
if (this._queue.length) {
4876
this._insert(this._queue.shift());
4877
} else if (!this._reqsWaiting) {
4882
_poll: function (newReq) {
4884
pendingCSS = self._pendingCSS,
4885
isWebKit = Y.UA.webkit,
4886
i, hasRules, j, nodeHref, req, sheets;
4889
pendingCSS || (pendingCSS = self._pendingCSS = []);
4890
pendingCSS.push(newReq);
4892
if (self._pollTimer) {
4893
// A poll timeout is already pending, so no need to create a
4899
self._pollTimer = null;
4901
// Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
4902
// will still be treated as a success. There's no good workaround for
4905
for (i = 0; i < pendingCSS.length; ++i) {
4906
req = pendingCSS[i];
4909
// Look for a stylesheet matching the pending URL.
4910
sheets = req.doc.styleSheets;
4912
nodeHref = req.node.href;
4915
if (sheets[j].href === nodeHref) {
4916
pendingCSS.splice(i, 1);
4918
self._progress(null, req);
4923
// Many thanks to Zach Leatherman for calling my attention to
4924
// the @import-based cross-domain technique used here, and to
4925
// Oleg Slobodskoi for an earlier same-domain implementation.
4927
// See Zach's blog for more details:
4928
// http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
4930
// We don't really need to store this value since we never
4931
// use it again, but if we don't store it, Closure Compiler
4932
// assumes the code is useless and removes it.
4933
hasRules = !!req.node.sheet.cssRules;
4935
// If we get here, the stylesheet has loaded.
4936
pendingCSS.splice(i, 1);
4938
self._progress(null, req);
4940
// An exception means the stylesheet is still loading.
4945
if (pendingCSS.length) {
4946
self._pollTimer = setTimeout(function () {
4947
self._poll.call(self);
4948
}, self.options.pollInterval);
4952
_progress: function (err, req) {
4953
var options = this.options;
4965
req.node._yuiget_finished = req.finished = true;
4967
if (options.onProgress) {
4968
options.onProgress.call(options.context || this,
4969
this._getEventData(req));
4972
if (req.autopurge) {
4973
// Pre-3.5.0 Get always excludes the most recent node from an
4974
// autopurge. I find this odd, but I'm keeping that behavior for
4975
// the sake of backcompat.
4976
Get._autoPurge(this.options.purgethreshold);
4977
Get._purgeNodes.push(req.node);
4980
if (this._pending === req) {
4981
this._pending = null;
4984
this._reqsWaiting -= 1;
4991
}, '3.13.0', {"requires": ["yui-base"]});
4992
YUI.add('features', function (Y, NAME) {
4994
var feature_tests = {};
4997
Contains the core of YUI's feature test architecture.
5007
Y.mix(Y.namespace('Features'), {
5010
* Object hash of all registered feature tests
5014
tests: feature_tests,
5017
* Add a test to the system
5020
* Y.Features.add("load", "1", {});
5024
* @param {String} cat The category, right now only 'load' is supported
5025
* @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
5026
* @param {Object} o Object containing test properties
5027
* @param {String} o.name The name of the test
5028
* @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
5029
* @param {String} o.trigger The module that triggers this test.
5031
add: function(cat, name, o) {
5032
feature_tests[cat] = feature_tests[cat] || {};
5033
feature_tests[cat][name] = o;
5036
* Execute all tests of a given category and return the serialized results
5042
* @param {String} cat The category to execute
5043
* @param {Array} args The arguments to pass to the test function
5044
* @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
5046
all: function(cat, args) {
5047
var cat_o = feature_tests[cat],
5051
Y.Object.each(cat_o, function(v, k) {
5052
result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
5056
return (result.length) ? result.join(';') : '';
5059
* Run a sepecific test and return a Boolean response.
5062
* Y.Features.test("load", "1");
5066
* @param {String} cat The category of the test to run
5067
* @param {String} name The name of the test to run
5068
* @param {Array} args The arguments to pass to the test function
5069
* @return {Boolean} True or false if the test passed/failed.
5071
test: function(cat, name, args) {
5073
var result, ua, test,
5074
cat_o = feature_tests[cat],
5075
feature = cat_o && cat_o[name];
5080
result = feature.result;
5082
if (Y.Lang.isUndefined(result)) {
5086
result = (Y.UA[ua]);
5089
test = feature.test;
5090
if (test && ((!ua) || result)) {
5091
result = test.apply(Y, args);
5094
feature.result = result;
5102
// Y.Features.add("load", "1", {});
5103
// Y.Features.test("load", "1");
5104
// caps=1:1;2:0;3:1;
5106
/* This file is auto-generated by (yogi.js loader --mix --yes) */
5107
/*jshint maxlen:900, eqeqeq: false */
5108
var add = Y.Features.add;
5109
// app-transitions-native
5111
"name": "app-transitions-native",
5112
"test": function (Y) {
5113
var doc = Y.config.doc,
5114
node = doc ? doc.documentElement : null;
5116
if (node && node.style) {
5117
return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5122
"trigger": "app-transitions"
5124
// autocomplete-list-keys
5126
"name": "autocomplete-list-keys",
5127
"test": function (Y) {
5128
// Only add keyboard support to autocomplete-list if this doesn't appear to
5129
// be an iOS or Android-based mobile device.
5131
// There's currently no feasible way to actually detect whether a device has
5132
// a hardware keyboard, so this sniff will have to do. It can easily be
5133
// overridden by manually loading the autocomplete-list-keys module.
5135
// Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
5136
// doesn't fire the keyboard events used by AutoCompleteList, so there's
5137
// no point loading the -keys module even when a bluetooth keyboard may be
5139
return !(Y.UA.ios || Y.UA.android);
5141
"trigger": "autocomplete-list"
5145
"name": "dd-gestures",
5146
"trigger": "dd-drag",
5147
"ua": "touchEnabled"
5151
"name": "dom-style-ie",
5152
"test": function (Y) {
5154
var testFeature = Y.Features.test,
5155
addFeature = Y.Features.add,
5156
WINDOW = Y.config.win,
5157
DOCUMENT = Y.config.doc,
5158
DOCUMENT_ELEMENT = 'documentElement',
5161
addFeature('style', 'computedStyle', {
5163
return WINDOW && 'getComputedStyle' in WINDOW;
5167
addFeature('style', 'opacity', {
5169
return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
5173
ret = (!testFeature('style', 'opacity') &&
5174
!testFeature('style', 'computedStyle'));
5178
"trigger": "dom-style"
5182
"name": "editor-para-ie",
5183
"trigger": "editor-para",
5189
"name": "event-base-ie",
5190
"test": function(Y) {
5191
var imp = Y.config.doc && Y.config.doc.implementation;
5192
return (imp && (!imp.hasFeature('Events', '2.0')));
5194
"trigger": "node-base"
5198
"name": "graphics-canvas",
5199
"test": function(Y) {
5200
var DOCUMENT = Y.config.doc,
5201
useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5202
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5203
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5204
return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5206
"trigger": "graphics"
5208
// graphics-canvas-default
5210
"name": "graphics-canvas-default",
5211
"test": function(Y) {
5212
var DOCUMENT = Y.config.doc,
5213
useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5214
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5215
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5216
return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5218
"trigger": "graphics"
5222
"name": "graphics-svg",
5223
"test": function(Y) {
5224
var DOCUMENT = Y.config.doc,
5225
useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5226
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5227
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5229
return svg && (useSVG || !canvas);
5231
"trigger": "graphics"
5233
// graphics-svg-default
5235
"name": "graphics-svg-default",
5236
"test": function(Y) {
5237
var DOCUMENT = Y.config.doc,
5238
useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5239
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5240
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5242
return svg && (useSVG || !canvas);
5244
"trigger": "graphics"
5248
"name": "graphics-vml",
5249
"test": function(Y) {
5250
var DOCUMENT = Y.config.doc,
5251
canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5252
return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5254
"trigger": "graphics"
5256
// graphics-vml-default
5258
"name": "graphics-vml-default",
5259
"test": function(Y) {
5260
var DOCUMENT = Y.config.doc,
5261
canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5262
return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5264
"trigger": "graphics"
5268
"name": "history-hash-ie",
5269
"test": function (Y) {
5270
var docMode = Y.config.doc && Y.config.doc.documentMode;
5272
return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
5273
!docMode || docMode < 8);
5275
"trigger": "history-hash"
5279
"name": "io-nodejs",
5280
"trigger": "io-base",
5285
"name": "json-parse-shim",
5286
"test": function (Y) {
5287
var _JSON = Y.config.global.JSON,
5288
Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5289
nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
5291
function workingNative( k, v ) {
5292
return k === "ok" ? true : v;
5295
// Double check basic functionality. This is mainly to catch early broken
5296
// implementations of the JSON API in Firefox 3.1 beta1 and beta2
5297
if ( nativeSupport ) {
5299
nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
5302
nativeSupport = false;
5306
return !nativeSupport;
5308
"trigger": "json-parse"
5310
// json-stringify-shim
5312
"name": "json-stringify-shim",
5313
"test": function (Y) {
5314
var _JSON = Y.config.global.JSON,
5315
Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5316
nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
5318
// Double check basic native functionality. This is primarily to catch broken
5319
// early JSON API implementations in Firefox 3.1 beta1 and beta2.
5320
if ( nativeSupport ) {
5322
nativeSupport = ( '0' === Native.stringify(0) );
5324
nativeSupport = false;
5329
return !nativeSupport;
5331
"trigger": "json-stringify"
5333
// scrollview-base-ie
5335
"name": "scrollview-base-ie",
5336
"trigger": "scrollview-base",
5341
"name": "selector-css2",
5342
"test": function (Y) {
5343
var DOCUMENT = Y.config.doc,
5344
ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
5348
"trigger": "selector"
5352
"name": "transition-timer",
5353
"test": function (Y) {
5354
var DOCUMENT = Y.config.doc,
5355
node = (DOCUMENT) ? DOCUMENT.documentElement: null,
5358
if (node && node.style) {
5359
ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5364
"trigger": "transition"
5368
"name": "widget-base-ie",
5369
"trigger": "widget-base",
5374
"name": "yql-jsonp",
5375
"test": function (Y) {
5376
/* Only load the JSONP module when not in nodejs or winjs
5377
TODO Make the winjs module a CORS module
5379
return (!Y.UA.nodejs && !Y.UA.winjs);
5386
"name": "yql-nodejs",
5393
"name": "yql-winjs",
5399
}, '3.13.0', {"requires": ["yui-base"]});
5400
YUI.add('intl-base', function (Y, NAME) {
5403
* The Intl utility provides a central location for managing sets of
5404
* localized resources (strings and formatting patterns).
5411
var SPLIT_REGEX = /[, ]/;
5413
Y.mix(Y.namespace('Intl'), {
5416
* Returns the language among those available that
5417
* best matches the preferred language list, using the Lookup
5418
* algorithm of BCP 47.
5419
* If none of the available languages meets the user's preferences,
5420
* then "" is returned.
5421
* Extended language ranges are not supported.
5423
* @method lookupBestLang
5424
* @param {String[] | String} preferredLanguages The list of preferred
5425
* languages in descending preference order, represented as BCP 47
5426
* language tags. A string array or a comma-separated list.
5427
* @param {String[]} availableLanguages The list of languages
5428
* that the application supports, represented as BCP 47 language
5431
* @return {String} The available language that best matches the
5432
* preferred language list, or "".
5435
lookupBestLang: function(preferredLanguages, availableLanguages) {
5437
var i, language, result, index;
5439
// check whether the list of available languages contains language;
5441
function scan(language) {
5443
for (i = 0; i < availableLanguages.length; i += 1) {
5444
if (language.toLowerCase() ===
5445
availableLanguages[i].toLowerCase()) {
5446
return availableLanguages[i];
5451
if (Y.Lang.isString(preferredLanguages)) {
5452
preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
5455
for (i = 0; i < preferredLanguages.length; i += 1) {
5456
language = preferredLanguages[i];
5457
if (!language || language === '*') {
5460
// check the fallback sequence for one language
5461
while (language.length > 0) {
5462
result = scan(language);
5466
index = language.lastIndexOf('-');
5468
language = language.substring(0, index);
5469
// one-character subtags get cut along with the
5471
if (index >= 2 && language.charAt(index - 2) === '-') {
5472
language = language.substring(0, index - 2);
5475
// nothing available for this language
5487
}, '3.13.0', {"requires": ["yui-base"]});
5488
YUI.add('yui-log', function (Y, NAME) {
5491
* Provides console log capability and exposes a custom event for
5492
* console implementations. This module is a `core` YUI module,
5493
* <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
5496
* @submodule yui-log
5500
LOGEVENT = 'yui:log',
5501
UNDEFINED = 'undefined',
5502
LEVELS = { debug: 1,
5508
* If the 'debug' config is true, a 'yui:log' event will be
5509
* dispatched, which the Console widget and anything else
5510
* can consume. If the 'useBrowserConsole' config is true, it will
5511
* write to the browser console if available. YUI-specific log
5512
* messages will only be present in the -debug versions of the
5513
* JS files. The build system is supposed to remove log statements
5514
* from the raw and minified versions of the files.
5518
* @param {String} msg The message to log.
5519
* @param {String} cat The log category for the message. Default
5520
* categories are "info", "warn", "error", time".
5521
* Custom categories can be used as well. (opt).
5522
* @param {String} src The source of the the message (opt).
5523
* @param {boolean} silent If true, the log event won't fire.
5524
* @return {YUI} YUI instance.
5526
INSTANCE.log = function(msg, cat, src, silent) {
5527
var bail, excl, incl, m, f, minlevel,
5530
publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
5531
// suppress log message if the config is off or the event stack
5532
// or the event call stack contains a consumer of the yui:log event
5534
// apply source filters
5536
if (typeof src !== "undefined") {
5537
excl = c.logExclude;
5538
incl = c.logInclude;
5539
if (incl && !(src in incl)) {
5541
} else if (incl && (src in incl)) {
5543
} else if (excl && (src in excl)) {
5547
// Determine the current minlevel as defined in configuration
5548
Y.config.logLevel = Y.config.logLevel || 'debug';
5549
minlevel = LEVELS[Y.config.logLevel.toLowerCase()];
5551
if (cat in LEVELS && LEVELS[cat] < minlevel) {
5552
// Skip this message if the we don't meet the defined minlevel
5557
if (c.useBrowserConsole) {
5558
m = (src) ? src + ': ' + msg : msg;
5559
if (Y.Lang.isFunction(c.logFn)) {
5560
c.logFn.call(Y, msg, cat, src);
5561
} else if (typeof console !== UNDEFINED && console.log) {
5562
f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
5564
} else if (typeof opera !== UNDEFINED) {
5569
if (publisher && !silent) {
5571
if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
5572
publisher.publish(LOGEVENT, {
5577
publisher.fire(LOGEVENT, {
5590
* Write a system message. This message will be preserved in the
5591
* minified and raw versions of the YUI files, unlike log statements.
5594
* @param {String} msg The message to log.
5595
* @param {String} cat The log category for the message. Default
5596
* categories are "info", "warn", "error", time".
5597
* Custom categories can be used as well. (opt).
5598
* @param {String} src The source of the the message (opt).
5599
* @param {boolean} silent If true, the log event won't fire.
5600
* @return {YUI} YUI instance.
5602
INSTANCE.message = function() {
5603
return INSTANCE.log.apply(INSTANCE, arguments);
5607
}, '3.13.0', {"requires": ["yui-base"]});
5608
YUI.add('yui-later', function (Y, NAME) {
5611
* Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
5612
* <a href="../classes/YUI.html#method_later">it's documentation is located under the YUI class</a>.
5615
* @submodule yui-later
5621
* Executes the supplied function in the context of the supplied
5622
* object 'when' milliseconds later. Executes the function a
5623
* single time unless periodic is set to true.
5626
* @param when {Number} the number of milliseconds to wait until the fn
5628
* @param o the context object.
5629
* @param fn {Function|String} the function to execute or the name of
5630
* the method in the 'o' object to execute.
5631
* @param data [Array] data that is provided to the function. This
5632
* accepts either a single item or an array. If an array is provided,
5633
* the function is executed with one parameter for each array item.
5634
* If you need to pass a single array parameter, it needs to be wrapped
5635
* in an array [myarray].
5637
* Note: native methods in IE may not have the call and apply methods.
5638
* In this case, it will work, but you are limited to four arguments.
5640
* @param periodic {boolean} if true, executes continuously at supplied
5641
* interval until canceled.
5642
* @return {object} a timer object. Call the cancel() method on this
5643
* object to stop the timer.
5645
Y.later = function(when, o, fn, data, periodic) {
5647
data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
5648
o = o || Y.config.win || Y;
5650
var cancelled = false,
5651
method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
5652
wrapper = function() {
5653
// IE 8- may execute a setInterval callback one last time
5654
// after clearInterval was called, so in order to preserve
5655
// the cancel() === no more runny-run, we have to jump through
5658
if (!method.apply) {
5659
method(data[0], data[1], data[2], data[3]);
5661
method.apply(o, data || NO_ARGS);
5665
id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
5670
cancel: function() {
5672
if (this.interval) {
5681
Y.Lang.later = Y.later;
5685
}, '3.13.0', {"requires": ["yui-base"]});
5686
YUI.add('yui', function (Y, NAME) {}, '3.13.0', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});