1
/* YUI 3.9.1 (build 5852) Copyright 2013 Yahoo! Inc. http://yuilibrary.com/license/ */
3
The YUI module contains the components required for building the YUI seed file.
4
This includes the script loading mechanism, a simple queue, and the core
5
utilities for the library.
12
/*jshint eqeqeq: false*/
13
if (typeof YUI != 'undefined') {
18
The YUI global namespace object. This is the constructor for all YUI instances.
20
This is a self-instantiable factory function, meaning you don't need to precede
21
it with the `new` operator. You can invoke it directly like this:
23
YUI().use('*', function (Y) {
24
// Y is a new YUI instance.
27
But it also works like this:
31
The `YUI` constructor accepts an optional config object, like this:
36
}).use('node', function (Y) {
37
// Y.Node is ready to use.
40
See the API docs for the <a href="config.html">Config</a> class for the complete
41
list of supported configuration properties accepted by the YUI constuctor.
43
If a global `YUI` object is already defined, the existing YUI object will not be
44
overwritten, to ensure that defined namespaces are preserved.
46
Each YUI instance has full custom event support, but only if the event system is
53
@param {Object} [config]* Zero or more optional configuration objects. Config
54
values are stored in the `Y.config` property. See the
55
<a href="config.html">Config</a> docs for the list of supported properties.
60
var YUI = function() {
65
instanceOf = function(o, type) {
66
return (o && o.hasOwnProperty && (o instanceof type));
68
gconf = (typeof YUI_config !== 'undefined') && YUI_config;
70
if (!(instanceOf(Y, YUI))) {
73
// set up the core environment
77
Master configuration that might span multiple contexts in a non-
78
browser environment. It is applied first to all instances in all
87
YUI().use('node', function (Y) {
88
// debug files used here
93
}).use('node', function (Y) {
94
// min files used here
97
@property {Object} GlobalConfig
101
if (YUI.GlobalConfig) {
102
Y.applyConfig(YUI.GlobalConfig);
106
Page-level config applied to all YUI instances created on the
107
current page. This is applied after `YUI.GlobalConfig` and before
108
any instance-level configuration.
112
// Single global var to include before YUI seed file
117
YUI().use('node', function (Y) {
118
// debug files used here
123
}).use('node', function (Y) {
124
// min files used here
127
@property {Object} YUI_config
131
Y.applyConfig(gconf);
134
// bind the specified additional modules for this instance
141
// Each instance can accept one or more configuration objects.
142
// These are applied after YUI.GlobalConfig and YUI_Config,
143
// overriding values set in those config files if there is a
144
// matching property.
146
Y.applyConfig(args[i]);
152
Y.instanceOf = instanceOf;
162
BASE = 'http://yui.yahooapis.com/',
164
These CSS class names can't be generated by
165
getClassName since it is not available at the
166
time they are being used.
168
DOC_LABEL = 'yui3-js-enabled',
169
CSS_STAMP_EL = 'yui3-css-stamp',
170
NOOP = function() {},
171
SLICE = Array.prototype.slice,
172
APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo
173
'io.xdrResponse': 1, // can call. this should
174
'SWF.eventHandler': 1 }, // be done at build time
175
hasWin = (typeof window != 'undefined'),
176
win = (hasWin) ? window : null,
177
doc = (hasWin) ? win.document : null,
178
docEl = doc && doc.documentElement,
179
docClass = docEl && docEl.className,
181
time = new Date().getTime(),
182
add = function(el, type, fn, capture) {
183
if (el && el.addEventListener) {
184
el.addEventListener(type, fn, capture);
185
} else if (el && el.attachEvent) {
186
el.attachEvent('on' + type, fn);
189
remove = function(el, type, fn, capture) {
190
if (el && el.removeEventListener) {
191
// this can throw an uncaught exception in FF
193
el.removeEventListener(type, fn, capture);
195
} else if (el && el.detachEvent) {
196
el.detachEvent('on' + type, fn);
199
handleLoad = function() {
200
YUI.Env.windowLoaded = true;
201
YUI.Env.DOMReady = true;
203
remove(window, 'load', handleLoad);
206
getLoader = function(Y, o) {
207
var loader = Y.Env._loader,
208
lCore = [ 'loader-base' ],
213
//loader._config(Y.config);
214
loader.ignoreRegistered = false;
217
loader.required = [];
218
loader.loadType = null;
220
loader = new Y.Loader(Y.config);
221
Y.Env._loader = loader;
223
if (mods && mods.loader) {
224
lCore = [].concat(lCore, YUI.Env.loaderExtras);
226
YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore));
231
clobber = function(r, s) {
233
if (s.hasOwnProperty(i)) {
239
ALREADY_DONE = { success: true };
241
// Stamp the documentElement (HTML) with a class of "yui-loaded" to
242
// enable styles that need to key off of JS being enabled.
243
if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
247
docClass += DOC_LABEL;
248
docEl.className = docClass;
251
if (VERSION.indexOf('@') > -1) {
252
VERSION = '3.5.0'; // dev time hack for cdn test
257
Applies a new configuration object to the config of this YUI instance. This
258
will merge new group/module definitions, and will also update the loader
259
cache if necessary. Updating `Y.config` directly will not update the cache.
262
@param {Object} o the configuration object.
265
applyConfig: function(o) {
272
config = this.config,
273
mods = config.modules,
274
groups = config.groups,
275
aliases = config.aliases,
276
loader = this.Env._loader;
279
if (o.hasOwnProperty(name)) {
281
if (mods && name == 'modules') {
283
} else if (aliases && name == 'aliases') {
284
clobber(aliases, attr);
285
} else if (groups && name == 'groups') {
286
clobber(groups, attr);
287
} else if (name == 'win') {
288
config[name] = (attr && attr.contentWindow) || attr;
289
config.doc = config[name] ? config[name].document : null;
290
} else if (name == '_yuid') {
305
Old way to apply a config to this instance (calls `applyConfig` under the
310
@param {Object} o The config to apply
312
_config: function(o) {
317
Initializes this YUI instance.
330
The version number of this YUI instance.
332
This value is typically updated by a script when a YUI release is built,
333
so it may not reflect the correct version number when YUI is run from
334
the development source tree.
336
@property {String} version
342
core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later'],
343
loaderExtras: ['loader-rollup', 'loader-yui3'],
344
mods: {}, // flat module map
345
versions: {}, // version module map
347
cdn: BASE + VERSION + '/build/',
348
// bootstrapped: false,
359
// I'll start at the \b(simpleyui).
360
// 1. Look in the test string for "simpleyui" or "yui" or
361
// "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break. That is, it
362
// can't match "foyui" or "i_heart_simpleyui". This can be anywhere in the string.
363
// 2. After #1 must come a forward slash followed by the string matched in #1, so
364
// "yui-base/yui-base" or "simpleyui/simpleyui" or "yui-pants/yui-pants".
365
// 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min",
366
// so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt".
367
// 4. This is followed by ".js", so "yui/yui.js", "simpleyui/simpleyui-min.js"
368
// 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string,
369
// then capture the junk between the LAST "&" and the string in 1-4. So
370
// "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js"
371
// will capture "3.3.0/build/"
375
// (?:[^&]*&) followed by 0..n characters followed by an &
376
// * in fact, find as many sets of characters followed by a & as you can
377
// ([^&]*) capture the stuff after the last & in \1
378
// )? but it's ok if all this ?junk&more_junk stuff isn't even there
379
// \b(simpleyui| after a word break find either the string "simpleyui" or
380
// yui(?:-\w+)? the string "yui" optionally followed by a -, then more characters
381
// ) and store the simpleyui or yui-* string in \2
382
// \/\2 then comes a / followed by the simpleyui or yui-* string in \2
383
// (?:-(min|debug))? optionally followed by "-min" or "-debug"
384
// .js and ending in ".js"
385
_BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(simpleyui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,
386
parseBasePath: function(src, pattern) {
387
var match = src.match(pattern),
391
path = RegExp.leftContext || src.slice(0, src.indexOf(match[0]));
393
// this is to set up the path to the loader. The file
394
// filter for loader should match the yui include.
397
// extract correct path for mixed combo urls
398
// http://yuilibrary.com/projects/yui3/ticket/2528423
400
path += '?' + match[1];
409
getBase: G_ENV && G_ENV.getBase ||
411
var nodes = (doc && doc.getElementsByTagName('script')) || [],
412
path = Env.cdn, parsed,
415
for (i = 0, len = nodes.length; i < len; ++i) {
418
parsed = Y.Env.parseBasePath(src, pattern);
420
filter = parsed.filter;
435
Env._loaded[VERSION] = {};
437
if (G_ENV && Y !== YUI) {
438
Env._yidx = ++G_ENV._yidx;
439
Env._guidp = ('yui_' + VERSION + '_' +
440
Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_');
441
} else if (YUI._YUI) {
443
G_ENV = YUI._YUI.Env;
444
Env._yidx += G_ENV._yidx;
445
Env._uidx += G_ENV._uidx;
447
for (prop in G_ENV) {
448
if (!(prop in Env)) {
449
Env[prop] = G_ENV[prop];
463
// configuration defaults
464
Y.config = Y.config || {
471
useBrowserConsole: true,
474
global: Function('return this')()
477
//Register the CSS stamp element
478
if (doc && !doc.getElementById(CSS_STAMP_EL)) {
479
el = doc.createElement('div');
480
el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>';
481
YUI.Env.cssStampEl = el.firstChild;
483
doc.body.appendChild(YUI.Env.cssStampEl);
485
docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild);
487
} else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) {
488
YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL);
491
Y.config.lang = Y.config.lang || 'en-US';
493
Y.config.base = YUI.config.base || Y.Env.getBase(Y.Env._BASE_RE);
495
if (!filter || (!('mindebug').indexOf(filter))) {
498
filter = (filter) ? '-' + filter : filter;
499
Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js';
504
Finishes the instance setup. Attaches whatever YUI modules were defined
505
at the time that this instance was created.
514
extras = Y.config.core || [].concat(YUI.Env.core); //Clone it..
516
for (i = 0; i < extras.length; i++) {
517
if (mods[extras[i]]) {
518
core.push(extras[i]);
522
Y._attach(['yui-base']);
532
Executes the named method on the specified YUI instance if that method is
536
@param {String} id YUI instance id.
537
@param {String} method Name of the method to execute. For example:
539
@param {Array} args Arguments to apply to the method.
540
@return {Mixed} Return value from the applied method, or `null` if the
541
specified instance was not found or the method was not whitelisted.
543
applyTo: function(id, method, args) {
544
if (!(method in APPLY_TO_AUTH)) {
545
this.log(method + ': applyTo not allowed', 'warn', 'yui');
549
var instance = instances[id], nest, m, i;
551
nest = method.split('.');
553
for (i = 0; i < nest.length; i = i + 1) {
556
this.log('applyTo not found: ' + method, 'warn', 'yui');
559
return m && m.apply(instance, args);
566
Registers a YUI module and makes it available for use in a `YUI().use()` call or
567
as a dependency for other modules.
569
The easiest way to create a first-class YUI module is to use
570
<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build
573
Shifter will automatically wrap your module code in a `YUI.add()` call along
574
with any configuration info required for the module.
578
YUI.add('davglass', function (Y) {
579
Y.davglass = function () {
582
requires: ['harley-davidson', 'mt-dew']
586
@param {String} name Module name.
587
@param {Function} fn Function containing module code. This function will be
588
executed whenever the module is attached to a specific YUI instance.
590
@param {YUI} fn.Y The YUI instance to which this module is attached.
591
@param {String} fn.name Name of the module
593
@param {String} version Module version number. This is currently used only for
594
informational purposes, and is not used internally by YUI.
596
@param {Object} [config] Module config.
597
@param {Array} [config.requires] Array of other module names that must be
598
attached before this module can be attached.
599
@param {Array} [config.optional] Array of optional module names that should
600
be attached before this module is attached if they've already been
601
loaded. If the `loadOptional` YUI option is `true`, optional modules
602
that have not yet been loaded will be loaded just as if they were hard
604
@param {Array} [config.use] Array of module names that are included within
605
or otherwise provided by this module, and which should be attached
606
automatically when this module is attached. This makes it possible to
607
create "virtual rollup" modules that simply attach a collection of other
608
modules or submodules.
610
@return {YUI} This YUI instance.
612
add: function(name, fn, version, details) {
613
details = details || {};
621
//Instance hash so we don't apply it to the same instance twice
624
i, versions = env.versions;
626
env.mods[name] = mod;
627
versions[version] = versions[version] || {};
628
versions[version][name] = mod;
630
for (i in instances) {
631
if (instances.hasOwnProperty(i)) {
633
if (!applied[inst.id]) {
634
applied[inst.id] = true;
635
loader = inst.Env._loader;
637
if (!loader.moduleInfo[name] || loader.moduleInfo[name].temp) {
638
loader.addModule(details, name);
649
Executes the callback function associated with each required module,
650
attaching the module to this YUI instance.
653
@param {Array} r The array of modules to attach
654
@param {Boolean} [moot=false] If `true`, don't throw a warning if the module
658
_attach: function(r, moot) {
659
var i, name, mod, details, req, use, after,
661
aliases = YUI.Env.aliases,
663
cache = YUI.Env._renderedMods,
664
loader = Y.Env._loader,
665
done = Y.Env._attached,
666
len = r.length, loader, def, go,
669
//Check for conditional modules (in a second+ instance) and add their requirements
670
//TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass
671
for (i = 0; i < len; i++) {
675
if (loader && loader.conditions[name]) {
676
for (j in loader.conditions[name]) {
677
if (loader.conditions[name].hasOwnProperty(j)) {
678
def = loader.conditions[name][j];
679
go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y)));
690
for (i = 0; i < len; i++) {
695
if (aliases && aliases[name] && !mod) {
696
Y._attach(aliases[name]);
700
if (loader && loader.moduleInfo[name]) {
701
mod = loader.moduleInfo[name];
706
//if (!loader || !loader.moduleInfo[name]) {
707
//if ((!loader || !loader.moduleInfo[name]) && !moot) {
709
if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) {
710
Y.Env._missed.push(name);
711
Y.Env._missed = Y.Array.dedupe(Y.Env._missed);
712
Y.message('NOT loaded: ' + name, 'warn', 'yui');
717
//Don't like this, but in case a mod was asked for once, then we fetch it
718
//We need to remove it from the missed list ^davglass
719
for (j = 0; j < Y.Env._missed.length; j++) {
720
if (Y.Env._missed[j] === name) {
721
Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui');
722
Y.Env._missed.splice(j, 1);
726
If it's a temp module, we need to redo it's requirements if it's already loaded
727
since it may have been loaded by another instance and it's dependencies might
728
have been redefined inside the fetched file.
730
if (loader && cache && cache[name] && cache[name].temp) {
731
loader.getRequires(cache[name]);
733
for (j in loader.moduleInfo[name].expanded_map) {
734
if (loader.moduleInfo[name].expanded_map.hasOwnProperty(j)) {
741
details = mod.details;
742
req = details.requires;
744
after = details.after;
745
//Force Intl load if there is a language (Loader logic) @todo fix this shit
752
for (j = 0; j < req.length; j++) {
754
if (!Y._attach(req)) {
763
for (j = 0; j < after.length; j++) {
764
if (!done[after[j]]) {
765
if (!Y._attach(after, true)) {
774
if (Y.config.throwFail) {
780
Y.error('Attach error: ' + name, e, name);
787
for (j = 0; j < use.length; j++) {
789
if (!Y._attach(use)) {
807
Delays the `use` callback until another event has taken place such as
808
`window.onload`, `domready`, `contentready`, or `available`.
811
@method _delayCallback
812
@param {Function} cb The original `use` callback.
813
@param {String|Object} until Either an event name ('load', 'domready', etc.)
814
or an object containing event/args keys for contentready/available.
817
_delayCallback: function(cb, until) {
820
mod = ['event-base'];
822
until = (Y.Lang.isObject(until) ? until : { event: until });
824
if (until.event === 'load') {
825
mod.push('event-synthetic');
829
var args = arguments;
830
Y._use(mod, function() {
831
Y.on(until.event, function() {
832
args[1].delayUntil = until.event;
840
Attaches one or more modules to this YUI instance. When this is executed,
841
the requirements of the desired modules are analyzed, and one of several
845
* All required modules have already been loaded, and just need to be
846
attached to this YUI instance. In this case, the `use()` callback will
847
be executed synchronously after the modules are attached.
849
* One or more modules have not yet been loaded, or the Get utility is not
850
available, or the `bootstrap` config option is `false`. In this case,
851
a warning is issued indicating that modules are missing, but all
852
available modules will still be attached and the `use()` callback will
853
be executed synchronously.
855
* One or more modules are missing and the Loader is not available but the
856
Get utility is, and `bootstrap` is not `false`. In this case, the Get
857
utility will be used to load the Loader, and we will then proceed to
860
* One or more modules are missing and the Loader is available. In this
861
case, the Loader will be used to resolve the dependency tree for the
862
missing modules and load them and their dependencies. When the Loader is
863
finished loading modules, the `use()` callback will be executed
868
// Loads and attaches dd and its dependencies.
869
YUI().use('dd', function (Y) {
873
// Loads and attaches dd and node as well as all of their dependencies.
874
YUI().use(['dd', 'node'], function (Y) {
878
// Attaches all modules that have already been loaded.
879
YUI().use('*', function (Y) {
883
// Attaches a gallery module.
884
YUI().use('gallery-yql', function (Y) {
888
// Attaches a YUI 2in3 module.
889
YUI().use('yui2-datatable', function (Y) {
894
@param {String|Array} modules* One or more module names to attach.
895
@param {Function} [callback] Callback function to be executed once all
896
specified modules and their dependencies have been attached.
897
@param {YUI} callback.Y The YUI instance created for this sandbox.
898
@param {Object} callback.status Object containing `success`, `msg` and
903
var args = SLICE.call(arguments, 0),
904
callback = args[args.length - 1],
911
// The last argument supplied to use can be a load complete callback
912
if (Y.Lang.isFunction(callback)) {
914
if (Y.config.delayUntil) {
915
callback = Y._delayCallback(callback, Y.config.delayUntil);
920
if (Y.Lang.isArray(args[0])) {
924
if (Y.config.cacheUse) {
925
while ((name = args[i++])) {
926
if (!Env._attached[name]) {
935
Y._notify(callback, ALREADY_DONE, args);
941
Y._useQueue = Y._useQueue || new Y.Queue();
942
Y._useQueue.add([args, callback]);
944
Y._use(args, function(Y, response) {
945
Y._notify(callback, response, args);
953
Handles Loader notifications about attachment/load errors.
956
@param {Function} callback Callback to pass to `Y.config.loadErrorFn`.
957
@param {Object} response Response returned from Loader.
958
@param {Array} args Arguments passed from Loader.
961
_notify: function(callback, response, args) {
962
if (!response.success && this.config.loadErrorFn) {
963
this.config.loadErrorFn.call(this, this, callback, response, args);
964
} else if (callback) {
965
if (this.Env._missed && this.Env._missed.length) {
966
response.msg = 'Missing modules: ' + this.Env._missed.join();
967
response.success = false;
969
if (this.config.throwFail) {
970
callback(this, response);
973
callback(this, response);
975
this.error('use callback error', e, args);
982
Called from the `use` method queue to ensure that only one set of loading
983
logic is performed at a time.
986
@param {String} args* One or more modules to attach.
987
@param {Function} [callback] Function to call once all required modules have
991
_use: function(args, callback) {
994
this._attach(['yui-base']);
997
var len, loader, handleBoot,
1003
aliases = G_ENV.aliases,
1004
queue = G_ENV._loaderQueue,
1008
boot = config.bootstrap,
1013
fetchCSS = config.fetchCSS,
1014
process = function(names, skip) {
1016
var i = 0, a = [], name, len, m, req, use;
1018
if (!names.length) {
1024
for (i = 0; i < len; i++) {
1025
if (aliases[names[i]] && !mods[names[i]]) {
1026
a = [].concat(a, aliases[names[i]]);
1036
for (i = 0; i < len; i++) {
1042
// only attach a module once
1053
req = m.details.requires;
1054
use = m.details.use;
1056
// CSS files don't register themselves, see if it has
1058
if (!G_ENV._loaded[VERSION][name]) {
1061
used[name] = true; // probably css
1065
// make sure requirements are attached
1066
if (req && req.length) {
1070
// make sure we grab the submodule dependencies too
1071
if (use && use.length) {
1078
handleLoader = function(fromLoader) {
1079
var response = fromLoader || {
1085
data = response.data;
1090
origMissing = missing;
1094
redo = missing.length;
1096
if ([].concat(missing).sort().join() ==
1097
origMissing.sort().join()) {
1105
Y._use(missing, function() {
1106
if (Y._attach(data)) {
1107
Y._notify(callback, response, data);
1112
ret = Y._attach(data);
1115
Y._notify(callback, response, args);
1119
if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
1120
Y._use.apply(Y, Y._useQueue.next());
1126
// YUI().use('*'); // bind everything available
1127
if (firstArg === '*') {
1130
if (mods.hasOwnProperty(i)) {
1134
ret = Y._attach(args);
1141
if ((mods.loader || mods['loader-base']) && !Y.Loader) {
1142
Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]);
1146
// use loader to expand dependencies and sort the
1147
// requirements if it is available.
1148
if (boot && Y.Loader && args.length) {
1149
loader = getLoader(Y);
1150
loader.require(args);
1151
loader.ignoreRegistered = true;
1152
loader._boot = true;
1153
loader.calculate(null, (fetchCSS) ? null : 'js');
1154
args = loader.sorted;
1155
loader._boot = false;
1160
len = missing.length;
1164
missing = YArray.dedupe(missing);
1165
len = missing.length;
1170
if (boot && len && Y.Loader) {
1172
loader = getLoader(Y);
1173
loader.onEnd = handleLoader;
1176
loader.ignoreRegistered = false;
1177
loader.require(missing);
1178
loader.insert(null, (fetchCSS) ? null : 'js');
1180
} else if (boot && len && Y.Get && !Env.bootstrapped) {
1184
handleBoot = function() {
1186
queue.running = false;
1187
Env.bootstrapped = true;
1188
G_ENV._bootstrapping = false;
1189
if (Y._attach(['loader'])) {
1190
Y._use(args, callback);
1194
if (G_ENV._bootstrapping) {
1195
queue.add(handleBoot);
1197
G_ENV._bootstrapping = true;
1198
Y.Get.script(config.base + config.loaderPath, {
1204
ret = Y._attach(args);
1215
Utility method for safely creating namespaces if they don't already exist.
1216
May be called statically on the YUI global object or as a method on a YUI
1219
When called statically, a namespace will be created on the YUI global
1222
// Create `YUI.your.namespace.here` as nested objects, preserving any
1223
// objects that already exist instead of overwriting them.
1224
YUI.namespace('your.namespace.here');
1226
When called as a method on a YUI instance, a namespace will be created on
1229
// Creates `Y.property.package`.
1230
Y.namespace('property.package');
1232
Dots in the input string cause `namespace` to create nested objects for each
1233
token. If any part of the requested namespace already exists, the current
1234
object will be left in place and will not be overwritten. This allows
1235
multiple calls to `namespace` to preserve existing namespaced properties.
1237
If the first token in the namespace string is "YAHOO", that token is
1238
discarded. This is legacy behavior for backwards compatibility with YUI 2.
1240
Be careful with namespace tokens. Reserved words may work in some browsers
1241
and not others. For instance, the following will fail in some browsers
1242
because the supported version of JavaScript reserves the word "long":
1244
Y.namespace('really.long.nested.namespace');
1246
Note: If you pass multiple arguments to create multiple namespaces, only the
1247
last one created is returned from this function.
1250
@param {String} namespace* One or more namespaces to create.
1251
@return {Object} Reference to the last namespace object created.
1253
namespace: function() {
1254
var a = arguments, o, i = 0, j, d, arg;
1256
for (; i < a.length; i++) {
1257
o = this; //Reset base object per argument or it will get reused from the last
1259
if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
1260
d = arg.split(PERIOD);
1261
for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
1262
o[d[j]] = o[d[j]] || {};
1266
o[arg] = o[arg] || {};
1267
o = o[arg]; //Reset base object to the new object so it's returned
1273
// this is replaced if the log module is included
1276
// this is replaced if the dump module is included
1277
dump: function (o) { return ''+o; },
1282
The reporting mechanism is controlled by the `throwFail` configuration
1283
attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is
1284
truthy, a JS exception is thrown.
1286
If an `errorFn` is specified in the config it must return `true` to indicate
1287
that the exception was handled and keep it from being thrown.
1290
@param {String} msg Error message.
1291
@param {Error|String} [e] JavaScript error object or an error string.
1292
@param {String} [src] Source of the error (such as the name of the module in
1293
which the error occurred).
1296
error: function(msg, e, src) {
1297
//TODO Add check for window.onerror here
1301
if (Y.config.errorFn) {
1302
ret = Y.config.errorFn.apply(Y, arguments);
1306
throw (e || new Error(msg));
1308
Y.message(msg, 'error', ''+src); // don't scrub this one
1315
Generates an id string that is unique among all YUI instances in this
1319
@param {String} [pre] Prefix.
1320
@return {String} Unique id.
1322
guid: function(pre) {
1323
var id = this.Env._guidp + '_' + (++this.Env._uidx);
1324
return (pre) ? (pre + id) : id;
1328
Returns a unique id associated with the given object and (if *readOnly* is
1329
falsy) stamps the object with that id so it can be identified in the future.
1331
Stamping an object involves adding a `_yuid` property to it that contains
1332
the object's id. One exception to this is that in Internet Explorer, DOM
1333
nodes have a `uniqueID` property that contains a browser-generated unique
1334
id, which will be used instead of a YUI-generated id when available.
1337
@param {Object} o Object to stamp.
1338
@param {Boolean} readOnly If truthy and the given object has not already
1339
been stamped, the object will not be modified and `null` will be
1341
@return {String} Object's unique id, or `null` if *readOnly* was truthy and
1342
the given object was not already stamped.
1344
stamp: function(o, readOnly) {
1350
// IE generates its own unique ID for dom nodes
1351
// The uniqueID property of a document node returns a new ID
1352
if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
1355
uid = (typeof o === 'string') ? o : o._yuid;
1372
Destroys this YUI instance.
1377
destroy: function() {
1382
delete instances[Y.id];
1388
Safe `instanceof` wrapper that works around a memory leak in IE when the
1389
object being tested is `window` or `document`.
1391
Unless you are testing objects that may be `window` or `document`, you
1392
should use the native `instanceof` operator instead of this method.
1395
@param {Object} o Object to check.
1396
@param {Object} type Class to check against.
1401
YUI.prototype = proto;
1403
// inheritance utilities are not available yet
1404
for (prop in proto) {
1405
if (proto.hasOwnProperty(prop)) {
1406
YUI[prop] = proto[prop];
1411
Applies a configuration to all YUI instances in this execution context.
1413
The main use case for this method is in "mashups" where several third-party
1414
scripts need to write to a global YUI config, but cannot share a single
1415
centrally-managed config object. This way they can all call
1416
`YUI.applyConfig({})` instead of overwriting the single global config.
1423
fullpath: './davglass.js'
1431
fullpath: './foo.js'
1436
YUI().use('davglass', function (Y) {
1437
// Module davglass will be available here.
1441
@param {Object} o Configuration object to apply.
1445
YUI.applyConfig = function(o) {
1449
//If there is a GlobalConfig, apply it first to set the defaults
1450
if (YUI.GlobalConfig) {
1451
this.prototype.applyConfig.call(this, YUI.GlobalConfig);
1453
//Apply this config to it
1454
this.prototype.applyConfig.call(this, o);
1455
//Reset GlobalConfig to the combined config
1456
YUI.GlobalConfig = this.config;
1459
// set up the environment
1463
// add a window load event at load time so we can capture
1464
// the case where it fires before dynamic loading is
1466
add(window, 'load', handleLoad);
1472
YUI.Env.remove = remove;
1475
// Support the CommonJS method for exporting our single global
1476
if (typeof exports == 'object') {
1479
* Set a method to be called when `Get.script` is called in Node.js
1480
* `Get` will open the file, then pass it's content and it's path
1481
* to this method before attaching it. Commonly used for code coverage
1482
* instrumentation. <strong>Calling this multiple times will only
1483
* attach the last hook method</strong>. This method is only
1484
* available in Node.js.
1485
* @method setLoadHook
1487
* @param {Function} fn The function to set
1488
* @param {String} fn.data The content of the file
1489
* @param {String} fn.path The file path of the file
1491
YUI.setLoadHook = function(fn) {
1492
YUI._getLoadHook = fn;
1495
* Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook`
1496
* @method _getLoadHook
1498
* @param {String} data The content of the file
1499
* @param {String} path The file path of the file
1501
YUI._getLoadHook = null;
1508
Config object that contains all of the configuration options for
1509
this `YUI` instance.
1511
This object is supplied by the implementer when instantiating YUI. Some
1512
properties have default values if they are not supplied by the implementer.
1514
This object should not be updated directly because some values are cached. Use
1515
`applyConfig()` to update the config object on a YUI instance that has already
1523
If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata
1524
if they're needed to load additional dependencies and aren't already available.
1526
Setting this to `false` will prevent YUI from automatically loading the Loader
1527
and module metadata, so you will need to manually ensure that they're available
1528
or handle dependency resolution yourself.
1530
@property {Boolean} bootstrap
1536
@property {Object} aliases
1540
A hash of module group definitions.
1542
For each group you can specify a list of modules and the base path and
1543
combo spec to use when dynamically loading the modules.
1549
// specify whether or not this group has a combo service
1552
// The comboSeperator to use with this group's combo handler
1555
// The maxURLLength for this server
1558
// the base path for non-combo paths
1559
base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1561
// the path to the combo service
1562
comboBase: 'http://yui.yahooapis.com/combo?',
1564
// a fragment to prepend to the path attribute when
1565
// when building combo urls
1566
root: '2.8.0r4/build/',
1568
// the module definitions
1571
path: "yahoo-dom-event/yahoo-dom-event.js"
1574
path: "animation/animation.js",
1575
requires: ['yui2_yde']
1581
@property {Object} groups
1585
Path to the Loader JS file, relative to the `base` path.
1587
This is used to dynamically bootstrap the Loader when it's needed and isn't yet
1590
@property {String} loaderPath
1591
@default "loader/loader-min.js"
1595
If `true`, YUI will attempt to load CSS dependencies and skins. Set this to
1596
`false` to prevent YUI from loading any CSS, or set it to the string `"force"`
1597
to force CSS dependencies to be loaded even if their associated JS modules are
1600
@property {Boolean|String} fetchCSS
1605
Default gallery version used to build gallery module urls.
1607
@property {String} gallery
1612
Default YUI 2 version used to build YUI 2 module urls.
1614
This is used for intrinsic YUI 2 support via the 2in3 project. Also see the
1615
`2in3` config for pulling different revisions of the wrapped YUI 2 modules.
1617
@property {String} yui2
1623
Revision number of YUI 2in3 modules that should be used when loading YUI 2in3.
1625
@property {String} 2in3
1631
Alternate console log function that should be used in environments without a
1632
supported native console. This function is executed with the YUI instance as its
1635
@property {Function} logFn
1640
Callback to execute when `Y.error()` is called. It receives the error message
1641
and a JavaScript error object if one was provided.
1643
This function is executed with the YUI instance as its `this` object.
1645
Returning `true` from this function will prevent an exception from being thrown.
1647
@property {Function} errorFn
1648
@param {String} errorFn.msg Error message
1649
@param {Object} [errorFn.err] Error object (if one was provided).
1654
A callback to execute when Loader fails to load one or more resources.
1656
This could be because of a script load failure. It could also be because a
1657
module fails to register itself when the `requireRegistration` config is `true`.
1659
If this function is defined, the `use()` callback will only be called when the
1660
loader succeeds. Otherwise, `use()` will always executes unless there was a
1661
JavaScript error when attaching a module.
1663
@property {Function} loadErrorFn
1668
If `true`, Loader will expect all loaded scripts to be first-class YUI modules
1669
that register themselves with the YUI global, and will trigger a failure if a
1670
loaded script does not register a YUI module.
1672
@property {Boolean} requireRegistration
1678
Cache serviced use() requests.
1680
@property {Boolean} cacheUse
1683
@deprecated No longer used.
1687
Whether or not YUI should use native ES5 functionality when available for
1688
features like `Y.Array.each()`, `Y.Object()`, etc.
1690
When `false`, YUI will always use its own fallback implementations instead of
1691
relying on ES5 functionality, even when ES5 functionality is available.
1693
@property {Boolean} useNativeES5
1699
* Leverage native JSON stringify if the browser has a native
1700
* implementation. In general, this is a good idea. See the Known Issues
1701
* section in the JSON user guide for caveats. The default value is true
1702
* for browsers with native JSON support.
1704
* @property useNativeJSONStringify
1711
* Leverage native JSON parse if the browser has a native implementation.
1712
* In general, this is a good idea. See the Known Issues section in the
1713
* JSON user guide for caveats. The default value is true for browsers with
1714
* native JSON support.
1716
* @property useNativeJSONParse
1723
Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`)
1724
@property delayUntil
1729
You can use `load` or `domready` strings by default:
1732
delayUntil: 'domready'
1734
// This will not execute until 'domeready' occurs.
1737
Or you can delay until a node is available (with `available` or `contentready`):
1745
// This will not execute until a node matching the selector "#foo" is
1746
// available in the DOM.
1749
@property {Object|String} delayUntil
1752
YUI.add('yui-base', function (Y, NAME) {
1757
* @submodule yui-base
1760
* The YUI module contains the components required for building the YUI
1761
* seed file. This includes the script loading mechanism, a simple queue,
1762
* and the core utilities for the library.
1764
* @submodule yui-base
1768
* Provides core language utilites and extensions used throughout YUI.
1774
var L = Y.Lang || (Y.Lang = {}),
1776
STRING_PROTO = String.prototype,
1777
TOSTRING = Object.prototype.toString,
1780
'undefined' : 'undefined',
1781
'number' : 'number',
1782
'boolean' : 'boolean',
1783
'string' : 'string',
1784
'[object Function]': 'function',
1785
'[object RegExp]' : 'regexp',
1786
'[object Array]' : 'array',
1787
'[object Date]' : 'date',
1788
'[object Error]' : 'error'
1791
SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
1792
TRIMREGEX = /^\s+|\s+$/g,
1793
NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i;
1795
// -- Protected Methods --------------------------------------------------------
1798
Returns `true` if the given function appears to be implemented in native code,
1799
`false` otherwise. Will always return `false` -- even in ES5-capable browsers --
1800
if the `useNativeES5` YUI config option is set to `false`.
1802
This isn't guaranteed to be 100% accurate and won't work for anything other than
1803
functions, but it can be useful for determining whether a function like
1804
`Array.prototype.forEach` is native or a JS shim provided by another library.
1806
There's a great article by @kangax discussing certain flaws with this technique:
1807
<http://perfectionkills.com/detecting-built-in-host-methods/>
1809
While his points are valid, it's still possible to benefit from this function
1810
as long as it's used carefully and sparingly, and in such a way that false
1811
negatives have minimal consequences. It's used internally to avoid using
1812
potentially broken non-native ES5 shims that have been added to the page by
1816
@param {Function} fn Function to test.
1817
@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise.
1822
L._isNative = function (fn) {
1823
return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn));
1826
// -- Public Methods -----------------------------------------------------------
1829
* Determines whether or not the provided item is an array.
1831
* Returns `false` for array-like collections such as the function `arguments`
1832
* collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to
1833
* test for an array-like collection.
1836
* @param o The object to test.
1837
* @return {boolean} true if o is an array.
1840
L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) {
1841
return L.type(o) === 'array';
1845
* Determines whether or not the provided item is a boolean.
1848
* @param o The object to test.
1849
* @return {boolean} true if o is a boolean.
1851
L.isBoolean = function(o) {
1852
return typeof o === 'boolean';
1856
* Determines whether or not the supplied item is a date instance.
1859
* @param o The object to test.
1860
* @return {boolean} true if o is a date.
1862
L.isDate = function(o) {
1863
return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o);
1868
* Determines whether or not the provided item is a function.
1869
* Note: Internet Explorer thinks certain functions are objects:
1873
* var obj = document.createElement("object");
1874
* Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1876
* var input = document.createElement("input"); // append to body
1877
* Y.Lang.isFunction(input.focus) // reports false in IE
1881
* You will have to implement additional tests if these functions
1885
* @method isFunction
1887
* @param o The object to test.
1888
* @return {boolean} true if o is a function.
1890
L.isFunction = function(o) {
1891
return L.type(o) === 'function';
1895
* Determines whether or not the provided item is null.
1898
* @param o The object to test.
1899
* @return {boolean} true if o is null.
1901
L.isNull = function(o) {
1906
* Determines whether or not the provided item is a legal number.
1909
* @param o The object to test.
1910
* @return {boolean} true if o is a number.
1912
L.isNumber = function(o) {
1913
return typeof o === 'number' && isFinite(o);
1917
* Determines whether or not the provided item is of type object
1918
* or function. Note that arrays are also objects, so
1919
* <code>Y.Lang.isObject([]) === true</code>.
1922
* @param o The object to test.
1923
* @param failfn {boolean} fail if the input is a function.
1924
* @return {boolean} true if o is an object.
1925
* @see isPlainObject
1927
L.isObject = function(o, failfn) {
1929
return (o && (t === 'object' ||
1930
(!failfn && (t === 'function' || L.isFunction(o))))) || false;
1934
* Determines whether or not the provided item is a string.
1937
* @param o The object to test.
1938
* @return {boolean} true if o is a string.
1940
L.isString = function(o) {
1941
return typeof o === 'string';
1945
* Determines whether or not the provided item is undefined.
1946
* @method isUndefined
1948
* @param o The object to test.
1949
* @return {boolean} true if o is undefined.
1951
L.isUndefined = function(o) {
1952
return typeof o === 'undefined';
1956
* A convenience method for detecting a legitimate non-null value.
1957
* Returns false for null/undefined/NaN, true for other values,
1958
* including 0/false/''
1961
* @param o The item to test.
1962
* @return {boolean} true if it is not null/undefined/NaN || false.
1964
L.isValue = function(o) {
1971
case 'null': // fallthru
1981
* Returns the current time in milliseconds.
1984
* @return {Number} Current time in milliseconds.
1988
L.now = Date.now || function () {
1989
return new Date().getTime();
1993
* Lightweight version of <code>Y.substitute</code>. Uses the same template
1994
* structure as <code>Y.substitute</code>, but doesn't support recursion,
1995
* auto-object coersion, or formats.
1997
* @param {string} s String to be modified.
1998
* @param {object} o Object containing replacement values.
1999
* @return {string} the substitute result.
2003
L.sub = function(s, o) {
2004
return s.replace ? s.replace(SUBREGEX, function (match, key) {
2005
return L.isUndefined(o[key]) ? match : o[key];
2010
* Returns a string without any leading or trailing whitespace. If
2011
* the input is not a string, the input will be returned untouched.
2014
* @param s {string} the string to trim.
2015
* @return {string} the trimmed string.
2017
L.trim = STRING_PROTO.trim ? function(s) {
2018
return s && s.trim ? s.trim() : s;
2021
return s.replace(TRIMREGEX, '');
2028
* Returns a string without any leading whitespace.
2031
* @param s {string} the string to trim.
2032
* @return {string} the trimmed string.
2034
L.trimLeft = STRING_PROTO.trimLeft ? function (s) {
2035
return s.trimLeft();
2037
return s.replace(/^\s+/, '');
2041
* Returns a string without any trailing whitespace.
2044
* @param s {string} the string to trim.
2045
* @return {string} the trimmed string.
2047
L.trimRight = STRING_PROTO.trimRight ? function (s) {
2048
return s.trimRight();
2050
return s.replace(/\s+$/, '');
2054
Returns one of the following strings, representing the type of the item passed
2071
* `typeof HTMLElementCollection` returns function in Safari, but
2072
`Y.Lang.type()` reports "object", which could be a good thing --
2073
but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
2076
@param o the item to test.
2077
@return {string} the detected type.
2080
L.type = function(o) {
2081
return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
2089
Native = Array.prototype,
2091
hasOwn = Object.prototype.hasOwnProperty;
2094
Provides utility methods for working with arrays. Additional array helpers can
2095
be found in the `collection` and `array-extras` modules.
2097
`Y.Array(thing)` returns a native array created from _thing_. Depending on
2098
_thing_'s type, one of the following will happen:
2100
* Arrays are returned unmodified unless a non-zero _startIndex_ is
2102
* Array-like collections (see `Array.test()`) are converted to arrays.
2103
* For everything else, a new array is created with _thing_ as the sole
2106
Note: elements that are also collections, such as `<form>` and `<select>`
2107
elements, are not automatically converted to arrays. To force a conversion,
2108
pass `true` as the value of the _force_ parameter.
2112
@param {Any} thing The thing to arrayify.
2113
@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like
2114
collection, a subset of items starting at the specified index will be
2116
@param {Boolean} [force=false] If `true`, _thing_ will be treated as an
2117
array-like collection no matter what.
2118
@return {Array} A native array created from _thing_, according to the rules
2121
function YArray(thing, startIndex, force) {
2124
/*jshint expr: true*/
2125
startIndex || (startIndex = 0);
2127
if (force || YArray.test(thing)) {
2128
// IE throws when trying to slice HTMLElement collections.
2130
return Native.slice.call(thing, startIndex);
2134
for (len = thing.length; startIndex < len; ++startIndex) {
2135
result.push(thing[startIndex]);
2148
Dedupes an array of strings, returning an array that's guaranteed to contain
2149
only one copy of a given string.
2151
This method differs from `Array.unique()` in that it's optimized for use only
2152
with strings, whereas `unique` may be used with other types (but is slower).
2153
Using `dedupe()` with non-string values may result in unexpected behavior.
2156
@param {String[]} array Array of strings to dedupe.
2157
@return {Array} Deduped copy of _array_.
2161
YArray.dedupe = function (array) {
2166
for (i = 0, len = array.length; i < len; ++i) {
2169
if (!hasOwn.call(hash, item)) {
2179
Executes the supplied function on each item in the array. This method wraps
2180
the native ES5 `Array.forEach()` method if available.
2183
@param {Array} array Array to iterate.
2184
@param {Function} fn Function to execute on each item in the array. The function
2185
will receive the following arguments:
2186
@param {Any} fn.item Current array item.
2187
@param {Number} fn.index Current array index.
2188
@param {Array} fn.array Array being iterated.
2189
@param {Object} [thisObj] `this` object to use when calling _fn_.
2190
@return {YUI} The YUI instance.
2193
YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) {
2194
Native.forEach.call(array || [], fn, thisObj || Y);
2196
} : function (array, fn, thisObj) {
2197
for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
2199
fn.call(thisObj || Y, array[i], i, array);
2214
Returns an object using the first array as keys and the second as values. If
2215
the second array is not provided, or if it doesn't contain the same number of
2216
values as the first array, then `true` will be used in place of the missing
2221
Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
2222
// => {a: 'foo', b: 'bar', c: true}
2225
@param {String[]} keys Array of strings to use as keys.
2226
@param {Array} [values] Array to use as values.
2227
@return {Object} Hash using the first array as keys and the second as values.
2230
YArray.hash = function (keys, values) {
2232
vlen = (values && values.length) || 0,
2235
for (i = 0, len = keys.length; i < len; ++i) {
2237
hash[keys[i]] = vlen > i && i in values ? values[i] : true;
2245
Returns the index of the first item in the array that's equal (using a strict
2246
equality check) to the specified _value_, or `-1` if the value isn't found.
2248
This method wraps the native ES5 `Array.indexOf()` method if available.
2251
@param {Array} array Array to search.
2252
@param {Any} value Value to search for.
2253
@param {Number} [from=0] The index at which to begin the search.
2254
@return {Number} Index of the item strictly equal to _value_, or `-1` if not
2258
YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) {
2259
return Native.indexOf.call(array, value, from);
2260
} : function (array, value, from) {
2261
// http://es5.github.com/#x15.4.4.14
2262
var len = array.length;
2265
from = (from > 0 || -1) * Math.floor(Math.abs(from));
2275
for (; from < len; ++from) {
2276
if (from in array && array[from] === value) {
2285
Numeric sort convenience function.
2287
The native `Array.prototype.sort()` function converts values to strings and
2288
sorts them in lexicographic order, which is unsuitable for sorting numeric
2289
values. Provide `Array.numericSort` as a custom sort function when you want
2290
to sort values in numeric order.
2294
[42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
2295
// => [4, 8, 15, 16, 23, 42]
2298
@param {Number} a First value to compare.
2299
@param {Number} b Second value to compare.
2300
@return {Number} Difference between _a_ and _b_.
2303
YArray.numericSort = function (a, b) {
2308
Executes the supplied function on each item in the array. Returning a truthy
2309
value from the function will stop the processing of remaining items.
2312
@param {Array} array Array to iterate over.
2313
@param {Function} fn Function to execute on each item. The function will receive
2314
the following arguments:
2315
@param {Any} fn.value Current array item.
2316
@param {Number} fn.index Current array index.
2317
@param {Array} fn.array Array being iterated over.
2318
@param {Object} [thisObj] `this` object to use when calling _fn_.
2319
@return {Boolean} `true` if the function returns a truthy value on any of the
2320
items in the array; `false` otherwise.
2323
YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) {
2324
return Native.some.call(array, fn, thisObj);
2325
} : function (array, fn, thisObj) {
2326
for (var i = 0, len = array.length; i < len; ++i) {
2327
if (i in array && fn.call(thisObj, array[i], i, array)) {
2336
Evaluates _obj_ to determine if it's an array, an array-like collection, or
2337
something else. This is useful when working with the function `arguments`
2338
collection and `HTMLElement` collections.
2340
Note: This implementation doesn't consider elements that are also
2341
collections, such as `<form>` and `<select>`, to be array-like.
2344
@param {Object} obj Object to test.
2345
@return {Number} A number indicating the results of the test:
2347
* 0: Neither an array nor an array-like collection.
2349
* 2: Array-like collection.
2353
YArray.test = function (obj) {
2356
if (Lang.isArray(obj)) {
2358
} else if (Lang.isObject(obj)) {
2360
// indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here),
2361
// or functions without apply/call (Safari
2362
// HTMLElementCollection bug).
2363
if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) {
2372
* The YUI module contains the components required for building the YUI
2373
* seed file. This includes the script loading mechanism, a simple queue,
2374
* and the core utilities for the library.
2376
* @submodule yui-base
2380
* A simple FIFO queue. Items are added to the Queue with add(1..n items) and
2381
* removed using next().
2385
* @param {MIXED} item* 0..n items to seed the queue.
2389
this.add.apply(this, arguments);
2394
* Initialize the queue
2401
* The collection of enqueued items
2411
* Get the next item in the queue. FIFO support
2414
* @return {MIXED} the next item in the queue.
2417
return this._q.shift();
2421
* Get the last in the queue. LIFO support.
2424
* @return {MIXED} the last item in the queue.
2427
return this._q.pop();
2431
* Add 0..n items to the end of the queue.
2434
* @param {MIXED} item* 0..n items.
2435
* @return {object} this queue.
2438
this._q.push.apply(this._q, arguments);
2444
* Returns the current number of queued items.
2447
* @return {Number} The size.
2450
return this._q.length;
2456
YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2459
The YUI module contains the components required for building the YUI seed file.
2460
This includes the script loading mechanism, a simple queue, and the core
2461
utilities for the library.
2467
var CACHED_DELIMITER = '__',
2469
hasOwn = Object.prototype.hasOwnProperty,
2470
isObject = Y.Lang.isObject;
2473
Returns a wrapper for a function which caches the return value of that function,
2474
keyed off of the combined string representation of the argument values provided
2475
when the wrapper is called.
2477
Calling this function again with the same arguments will return the cached value
2478
rather than executing the wrapped function.
2480
Note that since the cache is keyed off of the string representation of arguments
2481
passed to the wrapper function, arguments that aren't strings and don't provide
2482
a meaningful `toString()` method may result in unexpected caching behavior. For
2483
example, the objects `{}` and `{foo: 'bar'}` would both be converted to the
2484
string `[object Object]` when used as a cache key.
2487
@param {Function} source The function to memoize.
2488
@param {Object} [cache={}] Object in which to store cached values. You may seed
2489
this object with pre-existing cached values if desired.
2490
@param {any} [refetch] If supplied, this value is compared with the cached value
2491
using a `==` comparison. If the values are equal, the wrapped function is
2492
executed again even though a cached value exists.
2493
@return {Function} Wrapped function.
2496
Y.cached = function (source, cache, refetch) {
2497
/*jshint expr: true*/
2498
cache || (cache = {});
2500
return function (arg) {
2501
var key = arguments.length > 1 ?
2502
Array.prototype.join.call(arguments, CACHED_DELIMITER) :
2505
/*jshint eqeqeq: false*/
2506
if (!(key in cache) || (refetch && cache[key] == refetch)) {
2507
cache[key] = source.apply(source, arguments);
2515
Returns the `location` object from the window/frame in which this YUI instance
2516
operates, or `undefined` when executing in a non-browser environment
2519
It is _not_ recommended to hold references to the `window.location` object
2520
outside of the scope of a function in which its properties are being accessed or
2521
its methods are being called. This is because of a nasty bug/issue that exists
2522
in both Safari and MobileSafari browsers:
2523
[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679).
2526
@return {location} The `location` object from the window/frame in which this YUI
2530
Y.getLocation = function () {
2531
// It is safer to look this up every time because yui-base is attached to a
2532
// YUI instance before a user's config is applied; i.e. `Y.config.win` does
2533
// not point the correct window object when this file is loaded.
2534
var win = Y.config.win;
2536
// It is not safe to hold a reference to the `location` object outside the
2537
// scope in which it is being used. The WebKit engine used in Safari and
2538
// MobileSafari will "disconnect" the `location` object from the `window`
2539
// when a page is restored from back/forward history cache.
2540
return win && win.location;
2544
Returns a new object containing all of the properties of all the supplied
2545
objects. The properties from later objects will overwrite those in earlier
2548
Passing in a single object will create a shallow copy of it. For a deep copy,
2552
@param {Object} objects* One or more objects to merge.
2553
@return {Object} A new merged object.
2555
Y.merge = function () {
2557
len = arguments.length,
2562
for (; i < len; ++i) {
2566
if (hasOwn.call(obj, key)) {
2567
result[key] = obj[key];
2576
Mixes _supplier_'s properties into _receiver_.
2578
Properties on _receiver_ or _receiver_'s prototype will not be overwritten or
2579
shadowed unless the _overwrite_ parameter is `true`, and will not be merged
2580
unless the _merge_ parameter is `true`.
2582
In the default mode (0), only properties the supplier owns are copied (prototype
2583
properties are not copied). The following copying modes are available:
2585
* `0`: _Default_. Object to object.
2586
* `1`: Prototype to prototype.
2587
* `2`: Prototype to prototype and object to object.
2588
* `3`: Prototype to object.
2589
* `4`: Object to prototype.
2592
@param {Function|Object} receiver The object or function to receive the mixed
2594
@param {Function|Object} supplier The object or function supplying the
2595
properties to be mixed.
2596
@param {Boolean} [overwrite=false] If `true`, properties that already exist
2597
on the receiver will be overwritten with properties from the supplier.
2598
@param {String[]} [whitelist] An array of property names to copy. If
2599
specified, only the whitelisted properties will be copied, and all others
2601
@param {Number} [mode=0] Mix mode to use. See above for available modes.
2602
@param {Boolean} [merge=false] If `true`, objects and arrays that already
2603
exist on the receiver will have the corresponding object/array from the
2604
supplier merged into them, rather than being skipped or overwritten. When
2605
both _overwrite_ and _merge_ are `true`, _merge_ takes precedence.
2606
@return {Function|Object|YUI} The receiver, or the YUI instance if the
2607
specified receiver is falsy.
2609
Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) {
2610
var alwaysOverwrite, exists, from, i, key, len, to;
2612
// If no supplier is given, we return the receiver. If no receiver is given,
2613
// we return Y. Returning Y doesn't make much sense to me, but it's
2614
// grandfathered in for backcompat reasons.
2615
if (!receiver || !supplier) {
2616
return receiver || Y;
2620
// In mode 2 (prototype to prototype and object to object), we recurse
2621
// once to do the proto to proto mix. The object to object mix will be
2622
// handled later on.
2624
Y.mix(receiver.prototype, supplier.prototype, overwrite,
2625
whitelist, 0, merge);
2628
// Depending on which mode is specified, we may be copying from or to
2629
// the prototypes of the supplier and receiver.
2630
from = mode === 1 || mode === 3 ? supplier.prototype : supplier;
2631
to = mode === 1 || mode === 4 ? receiver.prototype : receiver;
2633
// If either the supplier or receiver doesn't actually have a
2634
// prototype property, then we could end up with an undefined `from`
2635
// or `to`. If that happens, we abort and return the receiver.
2644
// If `overwrite` is truthy and `merge` is falsy, then we can skip a
2645
// property existence check on each iteration and save some time.
2646
alwaysOverwrite = overwrite && !merge;
2649
for (i = 0, len = whitelist.length; i < len; ++i) {
2652
// We call `Object.prototype.hasOwnProperty` instead of calling
2653
// `hasOwnProperty` on the object itself, since the object's
2654
// `hasOwnProperty` method may have been overridden or removed.
2655
// Also, some native objects don't implement a `hasOwnProperty`
2657
if (!hasOwn.call(from, key)) {
2661
// The `key in to` check here is (sadly) intentional for backwards
2662
// compatibility reasons. It prevents undesired shadowing of
2663
// prototype members on `to`.
2664
exists = alwaysOverwrite ? false : key in to;
2666
if (merge && exists && isObject(to[key], true)
2667
&& isObject(from[key], true)) {
2668
// If we're in merge mode, and the key is present on both
2669
// objects, and the value on both objects is either an object or
2670
// an array (but not a function), then we recurse to merge the
2671
// `from` value into the `to` value instead of overwriting it.
2673
// Note: It's intentional that the whitelist isn't passed to the
2674
// recursive call here. This is legacy behavior that lots of
2675
// code still depends on.
2676
Y.mix(to[key], from[key], overwrite, null, 0, merge);
2677
} else if (overwrite || !exists) {
2678
// We're not in merge mode, so we'll only copy the `from` value
2679
// to the `to` value if we're in overwrite mode or if the
2680
// current key doesn't exist on the `to` object.
2681
to[key] = from[key];
2686
// The code duplication here is for runtime performance reasons.
2687
// Combining whitelist and non-whitelist operations into a single
2688
// loop or breaking the shared logic out into a function both result
2689
// in worse performance, and Y.mix is critical enough that the byte
2690
// tradeoff is worth it.
2691
if (!hasOwn.call(from, key)) {
2695
// The `key in to` check here is (sadly) intentional for backwards
2696
// compatibility reasons. It prevents undesired shadowing of
2697
// prototype members on `to`.
2698
exists = alwaysOverwrite ? false : key in to;
2700
if (merge && exists && isObject(to[key], true)
2701
&& isObject(from[key], true)) {
2702
Y.mix(to[key], from[key], overwrite, null, 0, merge);
2703
} else if (overwrite || !exists) {
2704
to[key] = from[key];
2708
// If this is an IE browser with the JScript enumeration bug, force
2709
// enumeration of the buggy properties by making a recursive call with
2710
// the buggy properties as the whitelist.
2711
if (Y.Object._hasEnumBug) {
2712
Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge);
2719
* The YUI module contains the components required for building the YUI
2720
* seed file. This includes the script loading mechanism, a simple queue,
2721
* and the core utilities for the library.
2723
* @submodule yui-base
2727
* Adds utilities to the YUI instance for working with objects.
2733
hasOwn = Object.prototype.hasOwnProperty,
2735
UNDEFINED, // <-- Note the comma. We're still declaring vars.
2738
* Returns a new object that uses _obj_ as its prototype. This method wraps the
2739
* native ES5 `Object.create()` method if available, but doesn't currently
2740
* pass through `Object.create()`'s second argument (properties) in order to
2741
* ensure compatibility with older browsers.
2744
* @param {Object} obj Prototype object.
2745
* @return {Object} New object using _obj_ as its prototype.
2748
O = Y.Object = Lang._isNative(Object.create) ? function (obj) {
2749
// We currently wrap the native Object.create instead of simply aliasing it
2750
// to ensure consistency with our fallback shim, which currently doesn't
2751
// support Object.create()'s second argument (properties). Once we have a
2752
// safe fallback for the properties arg, we can stop wrapping
2754
return Object.create(obj);
2756
// Reusable constructor function for the Object.create() shim.
2760
return function (obj) {
2767
* Property names that IE doesn't enumerate in for..in loops, even when they
2768
* should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
2769
* manually enumerate these properties.
2771
* @property _forceEnum
2776
forceEnum = O._forceEnum = [
2779
'propertyIsEnumerable',
2786
* `true` if this browser has the JScript enumeration bug that prevents
2787
* enumeration of the properties named in the `_forceEnum` array, `false`
2791
* - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
2792
* - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
2794
* @property _hasEnumBug
2799
hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
2802
* `true` if this browser incorrectly considers the `prototype` property of
2803
* functions to be enumerable. Currently known to affect Opera 11.50.
2805
* @property _hasProtoEnumBug
2810
hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
2813
* Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
2814
* exists only on _obj_'s prototype. This is essentially a safer version of
2815
* `obj.hasOwnProperty()`.
2818
* @param {Object} obj Object to test.
2819
* @param {String} key Property name to look for.
2820
* @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2823
owns = O.owns = function (obj, key) {
2824
return !!obj && hasOwn.call(obj, key);
2825
}; // <-- End of var declarations.
2828
* Alias for `owns()`.
2831
* @param {Object} obj Object to test.
2832
* @param {String} key Property name to look for.
2833
* @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
2839
* Returns an array containing the object's enumerable keys. Does not include
2840
* prototype keys or non-enumerable keys.
2842
* Note that keys are returned in enumeration order (that is, in the same order
2843
* that they would be enumerated by a `for-in` loop), which may not be the same
2844
* as the order in which they were defined.
2846
* This method is an alias for the native ES5 `Object.keys()` method if
2851
* Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
2852
* // => ['a', 'b', 'c']
2855
* @param {Object} obj An object.
2856
* @return {String[]} Array of keys.
2859
O.keys = Lang._isNative(Object.keys) ? Object.keys : function (obj) {
2860
if (!Lang.isObject(obj)) {
2861
throw new TypeError('Object.keys called on a non-object');
2867
if (hasProtoEnumBug && typeof obj === 'function') {
2869
if (owns(obj, key) && key !== 'prototype') {
2875
if (owns(obj, key)) {
2882
for (i = 0, len = forceEnum.length; i < len; ++i) {
2885
if (owns(obj, key)) {
2895
* Returns an array containing the values of the object's enumerable keys.
2897
* Note that values are returned in enumeration order (that is, in the same
2898
* order that they would be enumerated by a `for-in` loop), which may not be the
2899
* same as the order in which they were defined.
2903
* Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
2904
* // => ['foo', 'bar', 'baz']
2907
* @param {Object} obj An object.
2908
* @return {Array} Array of values.
2911
O.values = function (obj) {
2912
var keys = O.keys(obj),
2917
for (; i < len; ++i) {
2918
values.push(obj[keys[i]]);
2925
* Returns the number of enumerable keys owned by an object.
2928
* @param {Object} obj An object.
2929
* @return {Number} The object's size.
2932
O.size = function (obj) {
2934
return O.keys(obj).length;
2936
return 0; // Legacy behavior for non-objects.
2941
* Returns `true` if the object owns an enumerable property with the specified
2945
* @param {Object} obj An object.
2946
* @param {any} value The value to search for.
2947
* @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
2950
O.hasValue = function (obj, value) {
2951
return Y.Array.indexOf(O.values(obj), value) > -1;
2955
* Executes a function on each enumerable property in _obj_. The function
2956
* receives the value, the key, and the object itself as parameters (in that
2959
* By default, only properties owned by _obj_ are enumerated. To include
2960
* prototype properties, set the _proto_ parameter to `true`.
2963
* @param {Object} obj Object to enumerate.
2964
* @param {Function} fn Function to execute on each enumerable property.
2965
* @param {mixed} fn.value Value of the current property.
2966
* @param {String} fn.key Key of the current property.
2967
* @param {Object} fn.obj Object being enumerated.
2968
* @param {Object} [thisObj] `this` object to use when calling _fn_.
2969
* @param {Boolean} [proto=false] Include prototype properties.
2970
* @return {YUI} the YUI instance.
2974
O.each = function (obj, fn, thisObj, proto) {
2978
if (proto || owns(obj, key)) {
2979
fn.call(thisObj || Y, obj[key], key, obj);
2987
* Executes a function on each enumerable property in _obj_, but halts if the
2988
* function returns a truthy value. The function receives the value, the key,
2989
* and the object itself as paramters (in that order).
2991
* By default, only properties owned by _obj_ are enumerated. To include
2992
* prototype properties, set the _proto_ parameter to `true`.
2995
* @param {Object} obj Object to enumerate.
2996
* @param {Function} fn Function to execute on each enumerable property.
2997
* @param {mixed} fn.value Value of the current property.
2998
* @param {String} fn.key Key of the current property.
2999
* @param {Object} fn.obj Object being enumerated.
3000
* @param {Object} [thisObj] `this` object to use when calling _fn_.
3001
* @param {Boolean} [proto=false] Include prototype properties.
3002
* @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
3003
* `false` otherwise.
3006
O.some = function (obj, fn, thisObj, proto) {
3010
if (proto || owns(obj, key)) {
3011
if (fn.call(thisObj || Y, obj[key], key, obj)) {
3021
* Retrieves the sub value at the provided path,
3022
* from the value object provided.
3026
* @param o The object from which to extract the property value.
3027
* @param path {Array} A path array, specifying the object traversal path
3028
* from which to obtain the sub value.
3029
* @return {Any} The value stored in the path, undefined if not found,
3030
* undefined if the source is not an object. Returns the source object
3031
* if an empty path is provided.
3033
O.getValue = function(o, path) {
3034
if (!Lang.isObject(o)) {
3042
for (i = 0; o !== UNDEFINED && i < l; i++) {
3050
* Sets the sub-attribute value at the provided path on the
3051
* value object. Returns the modified value object, or
3052
* undefined if the path is invalid.
3056
* @param o The object on which to set the sub value.
3057
* @param path {Array} A path array, specifying the object traversal path
3058
* at which to set the sub value.
3059
* @param val {Any} The new value for the sub-attribute.
3060
* @return {Object} The modified object, with the new sub value set, or
3061
* undefined, if the path was invalid.
3063
O.setValue = function(o, path, val) {
3066
leafIdx = p.length - 1,
3070
for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3074
if (ref !== UNDEFINED) {
3085
* Returns `true` if the object has no enumerable properties of its own.
3088
* @param {Object} obj An object.
3089
* @return {Boolean} `true` if the object is empty.
3093
O.isEmpty = function (obj) {
3094
return !O.keys(Object(obj)).length;
3097
* The YUI module contains the components required for building the YUI seed
3098
* file. This includes the script loading mechanism, a simple queue, and the
3099
* core utilities for the library.
3101
* @submodule yui-base
3105
* YUI user agent detection.
3106
* Do not fork for a browser if it can be avoided. Use feature detection when
3107
* you can. Use the user agent as a last resort. For all fields listed
3108
* as @type float, UA stores a version number for the browser engine,
3109
* 0 otherwise. This value may or may not map to the version number of
3110
* the browser using the engine. The value is presented as a float so
3111
* that it can easily be used for boolean evaluation as well as for
3112
* looking for a particular range of versions. Because of this,
3113
* some of the granularity of the version info may be lost. The fields that
3114
* are @type string default to null. The API docs list the values that
3115
* these fields can have.
3121
* Static method on `YUI.Env` for parsing a UA string. Called at instantiation
3122
* to populate `Y.UA`.
3126
* @param {String} [subUA=navigator.userAgent] UA string to parse
3127
* @return {Object} The Y.UA object
3129
YUI.Env.parseUA = function(subUA) {
3131
var numberify = function(s) {
3133
return parseFloat(s.replace(/\./g, function() {
3134
return (c++ === 1) ? '' : '.';
3140
nav = win && win.navigator,
3145
* Internet Explorer version number or 0. Example: 6
3153
* Opera version number or 0. Example: 9.2
3161
* Gecko engine revision number. Will evaluate to 1 if Gecko
3162
* is detected but the revision could not be found. Other browsers
3163
* will be 0. Example: 1.8
3165
* Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7
3166
* Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
3167
* Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
3168
* Firefox 3.0 <-- 1.9
3169
* Firefox 3.5 <-- 1.91
3178
* AppleWebKit version. KHTML browsers that are not WebKit browsers
3179
* will evaluate to 1, other browsers 0. Example: 418.9
3181
* Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
3182
* latest available for Mac OSX 10.3.
3183
* Safari 2.0.2: 416 <-- hasOwnProperty introduced
3184
* Safari 2.0.4: 418 <-- preventDefault fixed
3185
* Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
3186
* different versions of webkit
3187
* Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been
3188
* updated, but not updated
3189
* to the latest patch.
3190
* Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native
3191
* SVG and many major issues fixed).
3192
* Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic
3193
* update from 2.x via the 10.4.11 OS patch.
3194
* Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event.
3195
* yahoo.com user agent hack removed.
3197
* http://en.wikipedia.org/wiki/Safari_version_history
3205
* Safari will be detected as webkit, but this property will also
3206
* be populated with the Safari version number
3214
* Chrome will be detected as webkit, but this property will also
3215
* be populated with the Chrome version number
3223
* The mobile property will be set to a string containing any relevant
3224
* user agent information when a modern mobile browser is detected.
3225
* Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
3226
* devices with the WebKit-based browser, and Opera Mini.
3235
* Adobe AIR version number or 0. Only populated if webkit is detected.
3242
* PhantomJS version number or 0. Only populated if webkit is detected.
3244
* @property phantomjs
3249
* Detects Apple iPad's OS version
3256
* Detects Apple iPhone's OS version
3263
* Detects Apples iPod's OS version
3270
* General truthy check for iPad, iPhone or iPod
3278
* Detects Googles Android OS version
3285
* Detects Kindle Silk
3292
* Detects Kindle Silk Acceleration
3299
* Detects Palms WebOS version
3307
* Google Caja version number or 0.
3311
caja: nav && nav.cajaVersion,
3314
* Set to true if the page appears to be in SSL
3322
* The operating system. Currently only detecting windows or macintosh
3331
* The Nodejs Version
3339
* Window8/IE10 Application host environment
3344
winjs: !!((typeof Windows !== "undefined") && Windows.System),
3346
* Are touch/msPointer events available on this device
3347
* @property touchEnabled
3354
ua = subUA || nav && nav.userAgent,
3356
loc = win && win.location,
3358
href = loc && loc.href,
3363
* The User Agent string that was parsed
3364
* @property userAgent
3371
o.secure = href && (href.toLowerCase().indexOf('https') === 0);
3375
if ((/windows|win32/i).test(ua)) {
3377
} else if ((/macintosh|mac_powerpc/i).test(ua)) {
3379
} else if ((/android/i).test(ua)) {
3381
} else if ((/symbos/i).test(ua)) {
3383
} else if ((/linux/i).test(ua)) {
3385
} else if ((/rhino/i).test(ua)) {
3389
// Modern KHTML browsers should qualify as Safari X-Grade
3390
if ((/KHTML/).test(ua)) {
3393
if ((/IEMobile|XBLWP7/).test(ua)) {
3394
o.mobile = 'windows';
3396
if ((/Fennec/).test(ua)) {
3399
// Modern WebKit browsers are at least X-Grade
3400
m = ua.match(/AppleWebKit\/([^\s]*)/);
3402
o.webkit = numberify(m[1]);
3403
o.safari = o.webkit;
3405
if (/PhantomJS/.test(ua)) {
3406
m = ua.match(/PhantomJS\/([^\s]*)/);
3408
o.phantomjs = numberify(m[1]);
3412
// Mobile browser check
3413
if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) {
3414
o.mobile = 'Apple'; // iPhone or iPod Touch
3416
m = ua.match(/OS ([^\s]*)/);
3418
m = numberify(m[1].replace('_', '.'));
3422
o.ipad = o.ipod = o.iphone = 0;
3424
m = ua.match(/iPad|iPod|iPhone/);
3426
o[m[0].toLowerCase()] = o.ios;
3429
m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/);
3431
// Nokia N-series, webOS, ex: NokiaN95
3434
if (/webOS/.test(ua)) {
3436
m = ua.match(/webOS\/([^\s]*);/);
3438
o.webos = numberify(m[1]);
3441
if (/ Android/.test(ua)) {
3442
if (/Mobile/.test(ua)) {
3443
o.mobile = 'Android';
3445
m = ua.match(/Android ([^\s]*);/);
3447
o.android = numberify(m[1]);
3451
if (/Silk/.test(ua)) {
3452
m = ua.match(/Silk\/([^\s]*)\)/);
3454
o.silk = numberify(m[1]);
3457
o.android = 2.34; //Hack for desktop mode in Kindle
3460
if (/Accelerated=true/.test(ua)) {
3466
m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/);
3467
if (m && m[1] && m[2]) {
3468
o.chrome = numberify(m[2]); // Chrome
3469
o.safari = 0; //Reset safari back to 0
3470
if (m[1] === 'CrMo') {
3471
o.mobile = 'chrome';
3474
m = ua.match(/AdobeAIR\/([^\s]*)/);
3476
o.air = m[0]; // Adobe AIR 1.0 or better
3481
if (!o.webkit) { // not webkit
3482
// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
3483
if (/Opera/.test(ua)) {
3484
m = ua.match(/Opera[\s\/]([^\s]*)/);
3486
o.opera = numberify(m[1]);
3488
m = ua.match(/Version\/([^\s]*)/);
3490
o.opera = numberify(m[1]); // opera 10+
3493
if (/Opera Mobi/.test(ua)) {
3495
m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/);
3497
o.opera = numberify(m[1]);
3500
m = ua.match(/Opera Mini[^;]*/);
3503
o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
3505
} else { // not opera or webkit
3506
m = ua.match(/MSIE\s([^;]*)/);
3508
o.ie = numberify(m[1]);
3509
} else { // not opera, webkit, or ie
3510
m = ua.match(/Gecko\/([^\s]*)/);
3512
o.gecko = 1; // Gecko detected, look for revision
3513
m = ua.match(/rv:([^\s\)]*)/);
3515
o.gecko = numberify(m[1]);
3523
//Check for known properties to tell if touch events are enabled on this device or if
3524
//the number of MSPointer touchpoints on this device is greater than 0.
3525
if (win && nav && !(o.chrome && o.chrome < 6)) {
3526
o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0)));
3529
//It was a parsed UA, do not assign the global value.
3532
if (typeof process === 'object') {
3534
if (process.versions && process.versions.node) {
3536
o.os = process.platform;
3537
o.nodejs = numberify(process.versions.node);
3549
Y.UA = YUI.Env.UA || YUI.Env.parseUA();
3552
Performs a simple comparison between two version numbers, accounting for
3553
standard versioning logic such as the fact that "535.8" is a lower version than
3554
"535.24", even though a simple numerical comparison would indicate that it's
3555
greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are
3556
considered equivalent.
3558
Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent,
3559
1 if _a_ is higher than _b_.
3561
Versions may be numbers or strings containing numbers and dots. For example,
3562
both `535` and `"535.8.10"` are acceptable. A version string containing
3563
non-numeric characters, like `"535.8.beta"`, may produce unexpected results.
3565
@method compareVersions
3566
@param {Number|String} a First version number to compare.
3567
@param {Number|String} b Second version number to compare.
3568
@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is
3571
Y.UA.compareVersions = function (a, b) {
3572
var aPart, aParts, bPart, bParts, i, len;
3578
aParts = (a + '').split('.');
3579
bParts = (b + '').split('.');
3581
for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) {
3582
aPart = parseInt(aParts[i], 10);
3583
bPart = parseInt(bParts[i], 10);
3585
/*jshint expr: true*/
3586
isNaN(aPart) && (aPart = 0);
3587
isNaN(bPart) && (bPart = 0);
3589
if (aPart < bPart) {
3593
if (aPart > bPart) {
3601
"anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],
3602
"anim-shape-transform": ["anim-shape"],
3603
"app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","router","view","view-node-map"],
3604
"attribute": ["attribute-base","attribute-complex"],
3605
"attribute-events": ["attribute-observable"],
3606
"autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],
3607
"axes": ["axis-numeric","axis-category","axis-time","axis-stacked"],
3608
"axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"],
3609
"base": ["base-base","base-pluginhost","base-build"],
3610
"cache": ["cache-base","cache-offline","cache-plugin"],
3611
"charts": ["charts-base"],
3612
"collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],
3613
"color": ["color-base","color-hsl","color-harmony"],
3614
"controller": ["router"],
3615
"dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],
3616
"datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],
3617
"datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"],
3618
"datatype": ["datatype-date","datatype-number","datatype-xml"],
3619
"datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"],
3620
"datatype-number": ["datatype-number-parse","datatype-number-format"],
3621
"datatype-xml": ["datatype-xml-parse","datatype-xml-format"],
3622
"dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],
3623
"dom": ["dom-base","dom-screen","dom-style","selector-native","selector"],
3624
"editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],
3625
"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"],
3626
"event-custom": ["event-custom-base","event-custom-complex"],
3627
"event-gestures": ["event-flick","event-move"],
3628
"handlebars": ["handlebars-compiler"],
3629
"highlight": ["highlight-base","highlight-accentfold"],
3630
"history": ["history-base","history-hash","history-hash-ie","history-html5"],
3631
"io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],
3632
"json": ["json-parse","json-stringify"],
3633
"loader": ["loader-base","loader-rollup","loader-yui3"],
3634
"node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],
3635
"pluginhost": ["pluginhost-base","pluginhost-config"],
3636
"querystring": ["querystring-parse","querystring-stringify"],
3637
"recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],
3638
"resize": ["resize-base","resize-proxy","resize-constrain"],
3639
"slider": ["slider-base","slider-value-range","clickable-rail","range-slider"],
3640
"template": ["template-base","template-micro"],
3641
"text": ["text-accentfold","text-wordbreak"],
3642
"widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"]
3646
}, '3.9.1', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});
3647
YUI.add('get', function (Y, NAME) {
3649
/*jslint boss:true, expr:true, laxbreak: true */
3652
Provides dynamic loading of remote JavaScript and CSS resources.
3661
CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode()
3666
// -- Public Properties ----------------------------------------------------
3669
Default options for CSS requests. Options specified here will override
3670
global defaults for CSS requests.
3672
See the `options` property for all available options.
3674
@property cssOptions
3684
doc : Y.config.linkDoc || Y.config.doc,
3689
Default options for JS requests. Options specified here will override global
3690
defaults for JS requests.
3692
See the `options` property for all available options.
3701
doc : Y.config.scriptDoc || Y.config.doc
3705
Default options to use for all requests.
3707
Note that while all available options are documented here for ease of
3708
discovery, some options (like callback functions) only make sense at the
3711
Callback functions specified via the options object or the `options`
3712
parameter of the `css()`, `js()`, or `load()` methods will receive the
3713
transaction object as a parameter. See `Y.Get.Transaction` for details on
3714
the properties and methods available on transactions.
3718
@property {Object} options
3720
@property {Boolean} [options.async=false] Whether or not to load scripts
3721
asynchronously, meaning they're requested in parallel and execution
3722
order is not guaranteed. Has no effect on CSS, since CSS is always
3723
loaded asynchronously.
3725
@property {Object} [options.attributes] HTML attribute name/value pairs that
3726
should be added to inserted nodes. By default, the `charset` attribute
3727
will be set to "utf-8" and nodes will be given an auto-generated `id`
3728
attribute, but you can override these with your own values if desired.
3730
@property {Boolean} [options.autopurge] Whether or not to automatically
3731
purge inserted nodes after the purge threshold is reached. This is
3732
`true` by default for JavaScript, but `false` for CSS since purging a
3733
CSS node will also remove any styling applied by the referenced file.
3735
@property {Object} [options.context] `this` object to use when calling
3736
callback functions. Defaults to the transaction object.
3738
@property {Mixed} [options.data] Arbitrary data object to pass to "on*"
3741
@property {Document} [options.doc] Document into which nodes should be
3742
inserted. By default, the current document is used.
3744
@property {HTMLElement|String} [options.insertBefore] HTML element or id
3745
string of an element before which all generated nodes should be
3746
inserted. If not specified, Get will automatically determine the best
3747
place to insert nodes for maximum compatibility.
3749
@property {Function} [options.onEnd] Callback to execute after a transaction
3750
is complete, regardless of whether it succeeded or failed.
3752
@property {Function} [options.onFailure] Callback to execute after a
3753
transaction fails, times out, or is aborted.
3755
@property {Function} [options.onProgress] Callback to execute after each
3756
individual request in a transaction either succeeds or fails.
3758
@property {Function} [options.onSuccess] Callback to execute after a
3759
transaction completes successfully with no errors. Note that in browsers
3760
that don't support the `error` event on CSS `<link>` nodes, a failed CSS
3761
request may still be reported as a success because in these browsers
3762
it can be difficult or impossible to distinguish between success and
3763
failure for CSS resources.
3765
@property {Function} [options.onTimeout] Callback to execute after a
3766
transaction times out.
3768
@property {Number} [options.pollInterval=50] Polling interval (in
3769
milliseconds) for detecting CSS load completion in browsers that don't
3770
support the `load` event on `<link>` nodes. This isn't used for
3773
@property {Number} [options.purgethreshold=20] Number of nodes to insert
3774
before triggering an automatic purge when `autopurge` is `true`.
3776
@property {Number} [options.timeout] Number of milliseconds to wait before
3777
aborting a transaction. When a timeout occurs, the `onTimeout` callback
3778
is called, followed by `onFailure` and finally `onEnd`. By default,
3779
there is no timeout.
3781
@property {String} [options.type] Resource type ("css" or "js"). This option
3782
is set automatically by the `css()` and `js()` functions and will be
3783
ignored there, but may be useful when using the `load()` function. If
3784
not specified, the type will be inferred from the URL, defaulting to
3785
"js" if the URL doesn't contain a recognizable file extension.
3795
// -- Protected Properties -------------------------------------------------
3798
Regex that matches a CSS URL. Used to guess the file type when it's not
3808
REGEX_CSS: /\.css(?:[?;].*)?$/i,
3811
Regex that matches a JS URL. Used to guess the file type when it's not
3821
REGEX_JS : /\.js(?:[?;].*)?$/i,
3824
Contains information about the current environment, such as what script and
3825
link injection features it supports.
3827
This object is created and populated the first time the `_getEnv()` method
3838
Mapping of document _yuid strings to <head> or <base> node references so we
3839
don't have to look the node up each time we want to insert a request node.
3841
@property _insertCache
3850
Information about the currently pending transaction, if any.
3852
This is actually an object with two properties: `callback`, containing the
3853
optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
3854
containing the actual transaction instance.
3865
HTML nodes eligible to be purged next time autopurge is triggered.
3867
@property _purgeNodes
3876
Queued transactions and associated callbacks.
3886
// -- Public Methods -------------------------------------------------------
3889
Aborts the specified transaction.
3891
This will cause the transaction's `onFailure` callback to be called and
3892
will prevent any new script and link nodes from being added to the document,
3893
but any resources that have already been requested will continue loading
3894
(there's no safe way to prevent this, unfortunately).
3896
*Note:* This method is deprecated as of 3.5.0, and will be removed in a
3897
future version of YUI. Use the transaction-level `abort()` method instead.
3900
@param {Get.Transaction} transaction Transaction to abort.
3901
@deprecated Use the `abort()` method on the transaction instead.
3904
abort: function (transaction) {
3905
var i, id, item, len, pending;
3908
if (!transaction.abort) {
3910
pending = this._pending;
3913
if (pending && pending.transaction.id === id) {
3914
transaction = pending.transaction;
3915
this._pending = null;
3917
for (i = 0, len = this._queue.length; i < len; ++i) {
3918
item = this._queue[i].transaction;
3920
if (item.id === id) {
3922
this._queue.splice(i, 1);
3929
transaction && transaction.abort();
3933
Loads one or more CSS files.
3935
The _urls_ parameter may be provided as a URL string, a request object,
3936
or an array of URL strings and/or request objects.
3938
A request object is just an object that contains a `url` property and zero
3939
or more options that should apply specifically to that request.
3940
Request-specific options take priority over transaction-level options and
3943
URLs may be relative or absolute, and do not have to have the same origin
3944
as the current page.
3946
The `options` parameter may be omitted completely and a callback passed in
3947
its place, if desired.
3951
// Load a single CSS file and log a message on completion.
3952
Y.Get.css('foo.css', function (err) {
3958
// Load multiple CSS files and log a message when all have finished
3960
var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
3962
Y.Get.css(urls, function (err) {
3968
// Specify transaction-level options, which will apply to all requests
3969
// within the transaction.
3971
attributes: {'class': 'my-css'},
3975
// Specify per-request options, which override transaction-level and
3978
{url: 'foo.css', attributes: {id: 'foo'}},
3979
{url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
3983
@param {String|Object|Array} urls URL string, request object, or array
3984
of URLs and/or request objects to load.
3985
@param {Object} [options] Options for this transaction. See the
3986
`Y.Get.options` property for a complete list of available options.
3987
@param {Function} [callback] Callback function to be called on completion.
3988
This is a general callback and will be called before any more granular
3989
callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
3992
@param {Array|null} callback.err Array of errors that occurred during
3993
the transaction, or `null` on success.
3994
@param {Get.Transaction} callback.transaction Transaction object.
3996
@return {Get.Transaction} Transaction object.
3999
css: function (urls, options, callback) {
4000
return this._load('css', urls, options, callback);
4004
Loads one or more JavaScript resources.
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.
4020
Scripts will be executed in the order they're specified unless the `async`
4021
option is `true`, in which case they'll be loaded in parallel and executed
4022
in whatever order they finish loading.
4026
// Load a single JS file and log a message on completion.
4027
Y.Get.js('foo.js', function (err) {
4033
// Load multiple JS files, execute them in order, and log a message when
4034
// all have finished loading.
4035
var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
4037
Y.Get.js(urls, function (err) {
4043
// Specify transaction-level options, which will apply to all requests
4044
// within the transaction.
4046
attributes: {'class': 'my-js'},
4050
// Specify per-request options, which override transaction-level and
4053
{url: 'foo.js', attributes: {id: 'foo'}},
4054
{url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
4058
@param {String|Object|Array} urls URL string, request object, or array
4059
of URLs and/or request objects to load.
4060
@param {Object} [options] Options for this transaction. See the
4061
`Y.Get.options` property for a complete list of available options.
4062
@param {Function} [callback] Callback function to be called on completion.
4063
This is a general callback and will be called before any more granular
4064
callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4067
@param {Array|null} callback.err Array of errors that occurred during
4068
the transaction, or `null` on success.
4069
@param {Get.Transaction} callback.transaction Transaction object.
4071
@return {Get.Transaction} Transaction object.
4075
js: function (urls, options, callback) {
4076
return this._load('js', urls, options, callback);
4080
Loads one or more CSS and/or JavaScript resources in the same transaction.
4082
Use this method when you want to load both CSS and JavaScript in a single
4083
transaction and be notified when all requested URLs have finished loading,
4086
Behavior and options are the same as for the `css()` and `js()` methods. If
4087
a resource type isn't specified in per-request options or transaction-level
4088
options, Get will guess the file type based on the URL's extension (`.css`
4089
or `.js`, with or without a following query string). If the file type can't
4090
be guessed from the URL, a warning will be logged and Get will assume the
4091
URL is a JavaScript resource.
4095
// Load both CSS and JS files in a single transaction, and log a message
4096
// when all files have finished loading.
4097
Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
4104
@param {String|Object|Array} urls URL string, request object, or array
4105
of URLs and/or request objects to load.
4106
@param {Object} [options] Options for this transaction. See the
4107
`Y.Get.options` property for a complete list of available options.
4108
@param {Function} [callback] Callback function to be called on completion.
4109
This is a general callback and will be called before any more granular
4110
callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
4113
@param {Array|null} err Array of errors that occurred during the
4114
transaction, or `null` on success.
4115
@param {Get.Transaction} Transaction object.
4117
@return {Get.Transaction} Transaction object.
4121
load: function (urls, options, callback) {
4122
return this._load(null, urls, options, callback);
4125
// -- Protected Methods ----------------------------------------------------
4128
Triggers an automatic purge if the purge threshold has been reached.
4131
@param {Number} threshold Purge threshold to use, in milliseconds.
4136
_autoPurge: function (threshold) {
4137
if (threshold && this._purgeNodes.length >= threshold) {
4138
this._purge(this._purgeNodes);
4143
Populates the `_env` property with information about the current
4147
@return {Object} Environment information.
4152
_getEnv: function () {
4153
var doc = Y.config.doc,
4156
// Note: some of these checks require browser sniffs since it's not
4157
// feasible to load test files on every pageview just to perform a
4158
// feature test. I'm sorry if this makes you sad.
4159
return (this._env = {
4161
// True if this is a browser that supports disabling async mode on
4162
// dynamically created script nodes. See
4163
// https://developer.mozilla.org/En/HTML/Element/Script#Attributes
4165
// IE10 doesn't return true for the MDN feature test, so setting it explicitly,
4166
// because it is async by default, and allows you to disable async by setting it to false
4167
async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10),
4169
// True if this browser fires an event when a dynamically injected
4170
// link node fails to load. This is currently true for Firefox 9+
4171
// and WebKit 535.24+
4172
cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0,
4174
// True if this browser fires an event when a dynamically injected
4175
// link node finishes loading. This is currently true for IE, Opera,
4176
// Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the
4177
// DOM 0 "onload" event, but not "load". All versions of IE fire
4179
// davglass: Seems that Chrome on Android needs this to be false.
4181
(!ua.gecko && !ua.webkit) || ua.gecko >= 9 ||
4182
ua.compareVersions(ua.webkit, 535.24) >= 0
4183
) && !(ua.chrome && ua.chrome <= 18),
4185
// True if this browser preserves script execution order while
4186
// loading scripts in parallel as long as the script node's `async`
4187
// attribute is set to false to explicitly disable async execution.
4188
preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10))
4192
_getTransaction: function (urls, options) {
4196
if (!Lang.isArray(urls)) {
4200
options = Y.merge(this.options, options);
4202
// Clone the attributes object so we don't end up modifying it by ref.
4203
options.attributes = Y.merge(this.options.attributes,
4204
options.attributes);
4206
for (i = 0, len = urls.length; i < len; ++i) {
4208
req = {attributes: {}};
4210
// If `url` is a string, we create a URL object for it, then mix in
4211
// global options and request-specific options. If it's an object
4212
// with a "url" property, we assume it's a request object containing
4213
// URL-specific options.
4214
if (typeof url === 'string') {
4216
} else if (url.url) {
4217
// URL-specific options override both global defaults and
4218
// request-specific options.
4219
Y.mix(req, url, false, null, 0, true);
4220
url = url.url; // Make url a string so we can use it later.
4225
Y.mix(req, options, false, null, 0, true);
4227
// If we didn't get an explicit type for this URL either in the
4228
// request options or the URL-specific options, try to determine
4229
// one from the file extension.
4231
if (this.REGEX_CSS.test(url)) {
4234
if (!this.REGEX_JS.test(url)) {
4241
// Mix in type-specific default options, but don't overwrite any
4242
// options that have already been set.
4243
Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
4244
false, null, 0, true);
4246
// Give the node an id attribute if it doesn't already have one.
4247
req.attributes.id || (req.attributes.id = Y.guid());
4249
// Backcompat for <3.5.0 behavior.
4251
req.doc = req.win.document;
4253
req.win = req.doc.defaultView || req.doc.parentWindow;
4257
req.attributes.charset = req.charset;
4263
return new Transaction(requests, options);
4266
_load: function (type, urls, options, callback) {
4269
// Allow callback as third param.
4270
if (typeof options === 'function') {
4275
options || (options = {});
4276
options.type = type;
4278
options._onFinish = Get._onTransactionFinish;
4284
transaction = this._getTransaction(urls, options);
4287
callback : callback,
4288
transaction: transaction
4296
_onTransactionFinish : function() {
4297
Get._pending = null;
4301
_next: function () {
4304
if (this._pending) {
4308
item = this._queue.shift();
4311
this._pending = item;
4312
item.transaction.execute(item.callback);
4316
_purge: function (nodes) {
4317
var purgeNodes = this._purgeNodes,
4318
isTransaction = nodes !== purgeNodes,
4321
while (node = nodes.pop()) { // assignment
4322
// Don't purge nodes that haven't finished loading (or errored out),
4323
// since this can hang the transaction.
4324
if (!node._yuiget_finished) {
4328
node.parentNode && node.parentNode.removeChild(node);
4330
// If this is a transaction-level purge and this node also exists in
4331
// the Get-level _purgeNodes array, we need to remove it from
4332
// _purgeNodes to avoid creating a memory leak. The indexOf lookup
4333
// sucks, but until we get WeakMaps, this is the least troublesome
4334
// way to do this (we can't just hold onto node ids because they may
4335
// not be in the same document).
4336
if (isTransaction) {
4337
index = Y.Array.indexOf(purgeNodes, node);
4340
purgeNodes.splice(index, 1);
4353
Get.script = Get.js;
4356
Represents a Get transaction, which may contain requests for one or more JS or
4359
This class should not be instantiated manually. Instances will be created and
4360
returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
4362
@class Get.Transaction
4366
Get.Transaction = Transaction = function (requests, options) {
4369
self.id = Transaction._lastId += 1;
4370
self.data = options.data;
4373
self.options = options;
4374
self.requests = requests;
4376
self._callbacks = []; // callbacks to call after execution finishes
4378
self._reqsWaiting = 0;
4380
// Deprecated pre-3.5.0 properties.
4381
self.tId = self.id; // Use `id` instead.
4382
self.win = options.win || Y.config.win;
4386
Arbitrary data object associated with this transaction.
4388
This object comes from the options passed to `Get.css()`, `Get.js()`, or
4389
`Get.load()`, and will be `undefined` if no data object was specified.
4391
@property {Object} data
4395
Array of errors that have occurred during this transaction, if any.
4398
@property {Object[]} errors
4399
@property {String} errors.error Error message.
4400
@property {Object} errors.request Request object related to the error.
4404
Numeric id for this transaction, unique among all transactions within the same
4405
YUI sandbox in the current pageview.
4407
@property {Number} id
4412
HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
4413
during the current transaction.
4415
@property {HTMLElement[]} nodes
4419
Options associated with this transaction.
4421
See `Get.options` for the full list of available options.
4423
@property {Object} options
4428
Request objects contained in this transaction. Each request object represents
4429
one CSS or JS URL that will be (or has been) requested and loaded into the page.
4431
@property {Object} requests
4436
Id of the most recent transaction.
4443
Transaction._lastId = 0;
4445
Transaction.prototype = {
4446
// -- Public Properties ----------------------------------------------------
4449
Current state of this transaction. One of "new", "executing", or "done".
4455
_state: 'new', // "new", "executing", or "done"
4457
// -- Public Methods -------------------------------------------------------
4460
Aborts this transaction.
4462
This will cause the transaction's `onFailure` callback to be called and
4463
will prevent any new script and link nodes from being added to the document,
4464
but any resources that have already been requested will continue loading
4465
(there's no safe way to prevent this, unfortunately).
4468
@param {String} [msg="Aborted."] Optional message to use in the `errors`
4469
array describing why the transaction was aborted.
4471
abort: function (msg) {
4472
this._pending = null;
4473
this._pendingCSS = null;
4474
this._pollTimer = clearTimeout(this._pollTimer);
4476
this._reqsWaiting = 0;
4478
this.errors.push({error: msg || 'Aborted'});
4483
Begins execting the transaction.
4485
There's usually no reason to call this manually, since Get will call it
4486
automatically when other pending transactions have finished. If you really
4487
want to execute your transaction before Get does, you can, but be aware that
4488
this transaction's scripts may end up executing before the scripts in other
4489
pending transactions.
4491
If the transaction is already executing, the specified callback (if any)
4492
will be queued and called after execution finishes. If the transaction has
4493
already finished, the callback will be called immediately (the transaction
4494
will not be executed again).
4497
@param {Function} callback Callback function to execute after all requests
4498
in the transaction are complete, or after the transaction is aborted.
4500
execute: function (callback) {
4502
requests = self.requests,
4503
state = self._state,
4506
if (state === 'done') {
4507
callback && callback(self.errors.length ? self.errors : null, self);
4510
callback && self._callbacks.push(callback);
4512
if (state === 'executing') {
4517
self._state = 'executing';
4518
self._queue = queue = [];
4520
if (self.options.timeout) {
4521
self._timeout = setTimeout(function () {
4522
self.abort('Timeout');
4523
}, self.options.timeout);
4526
self._reqsWaiting = requests.length;
4528
for (i = 0, len = requests.length; i < len; ++i) {
4531
if (req.async || req.type === 'css') {
4532
// No need to queue CSS or fully async JS.
4543
Manually purges any `<script>` or `<link>` nodes this transaction has
4546
Be careful when purging a transaction that contains CSS requests, since
4547
removing `<link>` nodes will also remove any styles they applied.
4551
purge: function () {
4552
Get._purge(this.nodes);
4555
// -- Protected Methods ----------------------------------------------------
4556
_createNode: function (name, attrs, doc) {
4557
var node = doc.createElement(name),
4560
if (!CUSTOM_ATTRS) {
4561
// IE6 and IE7 expect property names rather than attribute names for
4562
// certain attributes. Rather than sniffing, we do a quick feature
4563
// test the first time _createNode() runs to determine whether we
4564
// need to provide a workaround.
4565
testEl = doc.createElement('div');
4566
testEl.setAttribute('class', 'a');
4568
CUSTOM_ATTRS = testEl.className === 'a' ? {} : {
4570
'class': 'className'
4574
for (attr in attrs) {
4575
if (attrs.hasOwnProperty(attr)) {
4576
node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]);
4583
_finish: function () {
4584
var errors = this.errors.length ? this.errors : null,
4585
options = this.options,
4586
thisObj = options.context || this,
4589
if (this._state === 'done') {
4593
this._state = 'done';
4595
for (i = 0, len = this._callbacks.length; i < len; ++i) {
4596
this._callbacks[i].call(thisObj, errors, this);
4599
data = this._getEventData();
4602
if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
4603
options.onTimeout.call(thisObj, data);
4606
if (options.onFailure) {
4607
options.onFailure.call(thisObj, data);
4609
} else if (options.onSuccess) {
4610
options.onSuccess.call(thisObj, data);
4613
if (options.onEnd) {
4614
options.onEnd.call(thisObj, data);
4617
if (options._onFinish) {
4618
options._onFinish();
4622
_getEventData: function (req) {
4624
// This merge is necessary for backcompat. I hate it.
4625
return Y.merge(this, {
4626
abort : this.abort, // have to copy these because the prototype isn't preserved
4637
_getInsertBefore: function (req) {
4639
el = req.insertBefore,
4643
return typeof el === 'string' ? doc.getElementById(el) : el;
4646
cache = Get._insertCache;
4647
docStamp = Y.stamp(doc);
4649
if ((el = cache[docStamp])) { // assignment
4653
// Inserting before a <base> tag apparently works around an IE bug
4654
// (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
4655
// bug that is, exactly. Better safe than sorry?
4656
if ((el = doc.getElementsByTagName('base')[0])) { // assignment
4657
return (cache[docStamp] = el);
4660
// Look for a <head> element.
4661
el = doc.head || doc.getElementsByTagName('head')[0];
4664
// Create a marker node at the end of <head> to use as an insertion
4665
// point. Inserting before this node will ensure that all our CSS
4666
// gets inserted in the correct order, to maintain style precedence.
4667
el.appendChild(doc.createTextNode(''));
4668
return (cache[docStamp] = el.lastChild);
4671
// If all else fails, just insert before the first script node on the
4672
// page, which is virtually guaranteed to exist.
4673
return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
4676
_insert: function (req) {
4678
insertBefore = this._getInsertBefore(req),
4679
isScript = req.type === 'js',
4683
cssTimeout, nodeType;
4687
nodeType = 'script';
4688
} else if (!env.cssLoad && ua.gecko) {
4694
node = req.node = this._createNode(nodeType, req.attributes,
4698
function onError() {
4699
self._progress('Failed to load ' + req.url, req);
4704
clearTimeout(cssTimeout);
4707
self._progress(null, req);
4710
// Deal with script asynchronicity.
4712
node.setAttribute('src', req.url);
4715
// Explicitly indicate that we want the browser to execute this
4716
// script asynchronously. This is necessary for older browsers
4721
// This browser treats injected scripts as async by default
4722
// (standard HTML5 behavior) but asynchronous loading isn't
4723
// desired, so tell the browser not to mark this script as
4728
// If this browser doesn't preserve script execution order based
4729
// on insertion order, we'll need to avoid inserting other
4730
// scripts until this one finishes loading.
4731
if (!env.preservesScriptOrder) {
4732
this._pending = req;
4736
if (!env.cssLoad && ua.gecko) {
4737
// In Firefox <9, we can import the requested URL into a <style>
4738
// node and poll for the existence of node.sheet.cssRules. This
4739
// gives us a reliable way to determine CSS load completion that
4740
// also works for cross-domain stylesheets.
4742
// Props to Zach Leatherman for calling my attention to this
4744
node.innerHTML = (req.attributes.charset ?
4745
'@charset "' + req.attributes.charset + '";' : '') +
4746
'@import "' + req.url + '";';
4748
node.setAttribute('href', req.url);
4753
if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) {
4754
// Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode.
4755
node.onreadystatechange = function () {
4756
if (/loaded|complete/.test(node.readyState)) {
4757
node.onreadystatechange = null;
4761
} else if (!isScript && !env.cssLoad) {
4762
// CSS on Firefox <9 or WebKit.
4765
// Script or CSS on everything else. Using DOM 0 events because that
4766
// evens the playing field with older IEs.
4770
// We currently need to introduce a timeout for IE10, since it
4771
// calls onerror/onload synchronously for 304s - messing up existing
4774
// Remove this block if the following bug gets fixed by GA
4775
/*jshint maxlen: 1500 */
4776
// https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload
4777
node.onerror = function() { setTimeout(onError, 0); };
4778
node.onload = function() { setTimeout(onLoad, 0); };
4780
node.onerror = onError;
4781
node.onload = onLoad;
4784
// If this browser doesn't fire an event when CSS fails to load,
4785
// fail after a timeout to avoid blocking the transaction queue.
4786
if (!env.cssFail && !isScript) {
4787
cssTimeout = setTimeout(onError, req.timeout || 3000);
4791
this.nodes.push(node);
4792
insertBefore.parentNode.insertBefore(node, insertBefore);
4795
_next: function () {
4796
if (this._pending) {
4800
// If there are requests in the queue, insert the next queued request.
4801
// Otherwise, if we're waiting on already-inserted requests to finish,
4802
// wait longer. If there are no queued requests and we're not waiting
4803
// for anything to load, then we're done!
4804
if (this._queue.length) {
4805
this._insert(this._queue.shift());
4806
} else if (!this._reqsWaiting) {
4811
_poll: function (newReq) {
4813
pendingCSS = self._pendingCSS,
4814
isWebKit = Y.UA.webkit,
4815
i, hasRules, j, nodeHref, req, sheets;
4818
pendingCSS || (pendingCSS = self._pendingCSS = []);
4819
pendingCSS.push(newReq);
4821
if (self._pollTimer) {
4822
// A poll timeout is already pending, so no need to create a
4828
self._pollTimer = null;
4830
// Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
4831
// will still be treated as a success. There's no good workaround for
4834
for (i = 0; i < pendingCSS.length; ++i) {
4835
req = pendingCSS[i];
4838
// Look for a stylesheet matching the pending URL.
4839
sheets = req.doc.styleSheets;
4841
nodeHref = req.node.href;
4844
if (sheets[j].href === nodeHref) {
4845
pendingCSS.splice(i, 1);
4847
self._progress(null, req);
4852
// Many thanks to Zach Leatherman for calling my attention to
4853
// the @import-based cross-domain technique used here, and to
4854
// Oleg Slobodskoi for an earlier same-domain implementation.
4856
// See Zach's blog for more details:
4857
// http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
4859
// We don't really need to store this value since we never
4860
// use it again, but if we don't store it, Closure Compiler
4861
// assumes the code is useless and removes it.
4862
hasRules = !!req.node.sheet.cssRules;
4864
// If we get here, the stylesheet has loaded.
4865
pendingCSS.splice(i, 1);
4867
self._progress(null, req);
4869
// An exception means the stylesheet is still loading.
4874
if (pendingCSS.length) {
4875
self._pollTimer = setTimeout(function () {
4876
self._poll.call(self);
4877
}, self.options.pollInterval);
4881
_progress: function (err, req) {
4882
var options = this.options;
4894
req.node._yuiget_finished = req.finished = true;
4896
if (options.onProgress) {
4897
options.onProgress.call(options.context || this,
4898
this._getEventData(req));
4901
if (req.autopurge) {
4902
// Pre-3.5.0 Get always excludes the most recent node from an
4903
// autopurge. I find this odd, but I'm keeping that behavior for
4904
// the sake of backcompat.
4905
Get._autoPurge(this.options.purgethreshold);
4906
Get._purgeNodes.push(req.node);
4909
if (this._pending === req) {
4910
this._pending = null;
4913
this._reqsWaiting -= 1;
4920
}, '3.9.1', {"requires": ["yui-base"]});
4921
YUI.add('features', function (Y, NAME) {
4923
var feature_tests = {};
4926
Contains the core of YUI's feature test architecture.
4936
Y.mix(Y.namespace('Features'), {
4939
* Object hash of all registered feature tests
4943
tests: feature_tests,
4946
* Add a test to the system
4949
* Y.Features.add("load", "1", {});
4953
* @param {String} cat The category, right now only 'load' is supported
4954
* @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
4955
* @param {Object} o Object containing test properties
4956
* @param {String} o.name The name of the test
4957
* @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
4958
* @param {String} o.trigger The module that triggers this test.
4960
add: function(cat, name, o) {
4961
feature_tests[cat] = feature_tests[cat] || {};
4962
feature_tests[cat][name] = o;
4965
* Execute all tests of a given category and return the serialized results
4971
* @param {String} cat The category to execute
4972
* @param {Array} args The arguments to pass to the test function
4973
* @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
4975
all: function(cat, args) {
4976
var cat_o = feature_tests[cat],
4980
Y.Object.each(cat_o, function(v, k) {
4981
result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
4985
return (result.length) ? result.join(';') : '';
4988
* Run a sepecific test and return a Boolean response.
4991
* Y.Features.test("load", "1");
4995
* @param {String} cat The category of the test to run
4996
* @param {String} name The name of the test to run
4997
* @param {Array} args The arguments to pass to the test function
4998
* @return {Boolean} True or false if the test passed/failed.
5000
test: function(cat, name, args) {
5002
var result, ua, test,
5003
cat_o = feature_tests[cat],
5004
feature = cat_o && cat_o[name];
5009
result = feature.result;
5011
if (Y.Lang.isUndefined(result)) {
5015
result = (Y.UA[ua]);
5018
test = feature.test;
5019
if (test && ((!ua) || result)) {
5020
result = test.apply(Y, args);
5023
feature.result = result;
5031
// Y.Features.add("load", "1", {});
5032
// Y.Features.test("load", "1");
5033
// caps=1:1;2:0;3:1;
5035
/* This file is auto-generated by (yogi loader --yes --mix --start ../) */
5036
/*jshint maxlen:900, eqeqeq: false */
5037
var add = Y.Features.add;
5038
// app-transitions-native
5040
"name": "app-transitions-native",
5041
"test": function (Y) {
5042
var doc = Y.config.doc,
5043
node = doc ? doc.documentElement : null;
5045
if (node && node.style) {
5046
return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5051
"trigger": "app-transitions"
5053
// autocomplete-list-keys
5055
"name": "autocomplete-list-keys",
5056
"test": function (Y) {
5057
// Only add keyboard support to autocomplete-list if this doesn't appear to
5058
// be an iOS or Android-based mobile device.
5060
// There's currently no feasible way to actually detect whether a device has
5061
// a hardware keyboard, so this sniff will have to do. It can easily be
5062
// overridden by manually loading the autocomplete-list-keys module.
5064
// Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
5065
// doesn't fire the keyboard events used by AutoCompleteList, so there's
5066
// no point loading the -keys module even when a bluetooth keyboard may be
5068
return !(Y.UA.ios || Y.UA.android);
5070
"trigger": "autocomplete-list"
5074
"name": "dd-gestures",
5075
"trigger": "dd-drag",
5076
"ua": "touchEnabled"
5080
"name": "dom-style-ie",
5081
"test": function (Y) {
5083
var testFeature = Y.Features.test,
5084
addFeature = Y.Features.add,
5085
WINDOW = Y.config.win,
5086
DOCUMENT = Y.config.doc,
5087
DOCUMENT_ELEMENT = 'documentElement',
5090
addFeature('style', 'computedStyle', {
5092
return WINDOW && 'getComputedStyle' in WINDOW;
5096
addFeature('style', 'opacity', {
5098
return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
5102
ret = (!testFeature('style', 'opacity') &&
5103
!testFeature('style', 'computedStyle'));
5107
"trigger": "dom-style"
5111
"name": "editor-para-ie",
5112
"trigger": "editor-para",
5118
"name": "event-base-ie",
5119
"test": function(Y) {
5120
var imp = Y.config.doc && Y.config.doc.implementation;
5121
return (imp && (!imp.hasFeature('Events', '2.0')));
5123
"trigger": "node-base"
5127
"name": "graphics-canvas",
5128
"test": function(Y) {
5129
var DOCUMENT = Y.config.doc,
5130
useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5131
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5132
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5133
return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5135
"trigger": "graphics"
5137
// graphics-canvas-default
5139
"name": "graphics-canvas-default",
5140
"test": function(Y) {
5141
var DOCUMENT = Y.config.doc,
5142
useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
5143
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5144
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5145
return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
5147
"trigger": "graphics"
5151
"name": "graphics-svg",
5152
"test": function(Y) {
5153
var DOCUMENT = Y.config.doc,
5154
useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5155
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5156
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5158
return svg && (useSVG || !canvas);
5160
"trigger": "graphics"
5162
// graphics-svg-default
5164
"name": "graphics-svg-default",
5165
"test": function(Y) {
5166
var DOCUMENT = Y.config.doc,
5167
useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
5168
canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
5169
svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
5171
return svg && (useSVG || !canvas);
5173
"trigger": "graphics"
5177
"name": "graphics-vml",
5178
"test": function(Y) {
5179
var DOCUMENT = Y.config.doc,
5180
canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5181
return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5183
"trigger": "graphics"
5185
// graphics-vml-default
5187
"name": "graphics-vml-default",
5188
"test": function(Y) {
5189
var DOCUMENT = Y.config.doc,
5190
canvas = DOCUMENT && DOCUMENT.createElement("canvas");
5191
return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
5193
"trigger": "graphics"
5197
"name": "history-hash-ie",
5198
"test": function (Y) {
5199
var docMode = Y.config.doc && Y.config.doc.documentMode;
5201
return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
5202
!docMode || docMode < 8);
5204
"trigger": "history-hash"
5208
"name": "io-nodejs",
5209
"trigger": "io-base",
5214
"name": "json-parse-shim",
5215
"test": function (Y) {
5216
var _JSON = Y.config.global.JSON,
5217
Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5218
nativeSupport = Y.config.useNativeJSONParse !== false && !!Native;
5220
function workingNative( k, v ) {
5221
return k === "ok" ? true : v;
5224
// Double check basic functionality. This is mainly to catch early broken
5225
// implementations of the JSON API in Firefox 3.1 beta1 and beta2
5226
if ( nativeSupport ) {
5228
nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
5231
nativeSupport = false;
5235
return !nativeSupport;
5237
"trigger": "json-parse"
5239
// json-stringify-shim
5241
"name": "json-stringify-shim",
5242
"test": function (Y) {
5243
var _JSON = Y.config.global.JSON,
5244
Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON,
5245
nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native;
5247
// Double check basic native functionality. This is primarily to catch broken
5248
// early JSON API implementations in Firefox 3.1 beta1 and beta2.
5249
if ( nativeSupport ) {
5251
nativeSupport = ( '0' === Native.stringify(0) );
5253
nativeSupport = false;
5258
return !nativeSupport;
5260
"trigger": "json-stringify"
5262
// scrollview-base-ie
5264
"name": "scrollview-base-ie",
5265
"trigger": "scrollview-base",
5270
"name": "selector-css2",
5271
"test": function (Y) {
5272
var DOCUMENT = Y.config.doc,
5273
ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
5277
"trigger": "selector"
5281
"name": "transition-timer",
5282
"test": function (Y) {
5283
var DOCUMENT = Y.config.doc,
5284
node = (DOCUMENT) ? DOCUMENT.documentElement: null,
5287
if (node && node.style) {
5288
ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style);
5293
"trigger": "transition"
5297
"name": "widget-base-ie",
5298
"trigger": "widget-base",
5303
"name": "yql-jsonp",
5304
"test": function (Y) {
5305
/* Only load the JSONP module when not in nodejs or winjs
5306
TODO Make the winjs module a CORS module
5308
return (!Y.UA.nodejs && !Y.UA.winjs);
5315
"name": "yql-nodejs",
5322
"name": "yql-winjs",
5328
}, '3.9.1', {"requires": ["yui-base"]});
5329
YUI.add('intl-base', function (Y, NAME) {
5332
* The Intl utility provides a central location for managing sets of
5333
* localized resources (strings and formatting patterns).
5340
var SPLIT_REGEX = /[, ]/;
5342
Y.mix(Y.namespace('Intl'), {
5345
* Returns the language among those available that
5346
* best matches the preferred language list, using the Lookup
5347
* algorithm of BCP 47.
5348
* If none of the available languages meets the user's preferences,
5349
* then "" is returned.
5350
* Extended language ranges are not supported.
5352
* @method lookupBestLang
5353
* @param {String[] | String} preferredLanguages The list of preferred
5354
* languages in descending preference order, represented as BCP 47
5355
* language tags. A string array or a comma-separated list.
5356
* @param {String[]} availableLanguages The list of languages
5357
* that the application supports, represented as BCP 47 language
5360
* @return {String} The available language that best matches the
5361
* preferred language list, or "".
5364
lookupBestLang: function(preferredLanguages, availableLanguages) {
5366
var i, language, result, index;
5368
// check whether the list of available languages contains language;
5370
function scan(language) {
5372
for (i = 0; i < availableLanguages.length; i += 1) {
5373
if (language.toLowerCase() ===
5374
availableLanguages[i].toLowerCase()) {
5375
return availableLanguages[i];
5380
if (Y.Lang.isString(preferredLanguages)) {
5381
preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
5384
for (i = 0; i < preferredLanguages.length; i += 1) {
5385
language = preferredLanguages[i];
5386
if (!language || language === '*') {
5389
// check the fallback sequence for one language
5390
while (language.length > 0) {
5391
result = scan(language);
5395
index = language.lastIndexOf('-');
5397
language = language.substring(0, index);
5398
// one-character subtags get cut along with the
5400
if (index >= 2 && language.charAt(index - 2) === '-') {
5401
language = language.substring(0, index - 2);
5404
// nothing available for this language
5416
}, '3.9.1', {"requires": ["yui-base"]});
5417
YUI.add('yui-log', function (Y, NAME) {
5420
* Provides console log capability and exposes a custom event for
5421
* console implementations. This module is a `core` YUI module,
5422
* <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>.
5425
* @submodule yui-log
5429
LOGEVENT = 'yui:log',
5430
UNDEFINED = 'undefined',
5431
LEVELS = { debug: 1,
5437
* If the 'debug' config is true, a 'yui:log' event will be
5438
* dispatched, which the Console widget and anything else
5439
* can consume. If the 'useBrowserConsole' config is true, it will
5440
* write to the browser console if available. YUI-specific log
5441
* messages will only be present in the -debug versions of the
5442
* JS files. The build system is supposed to remove log statements
5443
* from the raw and minified versions of the files.
5447
* @param {String} msg The message to log.
5448
* @param {String} cat The log category for the message. Default
5449
* categories are "info", "warn", "error", time".
5450
* Custom categories can be used as well. (opt).
5451
* @param {String} src The source of the the message (opt).
5452
* @param {boolean} silent If true, the log event won't fire.
5453
* @return {YUI} YUI instance.
5455
INSTANCE.log = function(msg, cat, src, silent) {
5456
var bail, excl, incl, m, f,
5459
publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
5460
// suppress log message if the config is off or the event stack
5461
// or the event call stack contains a consumer of the yui:log event
5463
// apply source filters
5465
if (typeof src !== "undefined") {
5466
excl = c.logExclude;
5467
incl = c.logInclude;
5468
if (incl && !(src in incl)) {
5470
} else if (incl && (src in incl)) {
5472
} else if (excl && (src in excl)) {
5477
if (c.useBrowserConsole) {
5478
m = (src) ? src + ': ' + msg : msg;
5479
if (Y.Lang.isFunction(c.logFn)) {
5480
c.logFn.call(Y, msg, cat, src);
5481
} else if (typeof console !== UNDEFINED && console.log) {
5482
f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
5484
} else if (typeof opera !== UNDEFINED) {
5489
if (publisher && !silent) {
5491
if (publisher === Y && (!publisher.getEvent(LOGEVENT))) {
5492
publisher.publish(LOGEVENT, {
5497
publisher.fire(LOGEVENT, {
5510
* Write a system message. This message will be preserved in the
5511
* minified and raw versions of the YUI files, unlike log statements.
5514
* @param {String} msg The message to log.
5515
* @param {String} cat The log category for the message. Default
5516
* categories are "info", "warn", "error", time".
5517
* Custom categories can be used as well. (opt).
5518
* @param {String} src The source of the the message (opt).
5519
* @param {boolean} silent If true, the log event won't fire.
5520
* @return {YUI} YUI instance.
5522
INSTANCE.message = function() {
5523
return INSTANCE.log.apply(INSTANCE, arguments);
5527
}, '3.9.1', {"requires": ["yui-base"]});
5528
YUI.add('yui-later', function (Y, NAME) {
5531
* Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module,
5532
* <a href="../classes/YUI.html#method_later">it's documentation is located under the YUI class</a>.
5535
* @submodule yui-later
5541
* Executes the supplied function in the context of the supplied
5542
* object 'when' milliseconds later. Executes the function a
5543
* single time unless periodic is set to true.
5546
* @param when {int} the number of milliseconds to wait until the fn
5548
* @param o the context object.
5549
* @param fn {Function|String} the function to execute or the name of
5550
* the method in the 'o' object to execute.
5551
* @param data [Array] data that is provided to the function. This
5552
* accepts either a single item or an array. If an array is provided,
5553
* the function is executed with one parameter for each array item.
5554
* If you need to pass a single array parameter, it needs to be wrapped
5555
* in an array [myarray].
5557
* Note: native methods in IE may not have the call and apply methods.
5558
* In this case, it will work, but you are limited to four arguments.
5560
* @param periodic {boolean} if true, executes continuously at supplied
5561
* interval until canceled.
5562
* @return {object} a timer object. Call the cancel() method on this
5563
* object to stop the timer.
5565
Y.later = function(when, o, fn, data, periodic) {
5567
data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS;
5568
o = o || Y.config.win || Y;
5570
var cancelled = false,
5571
method = (o && Y.Lang.isString(fn)) ? o[fn] : fn,
5572
wrapper = function() {
5573
// IE 8- may execute a setInterval callback one last time
5574
// after clearInterval was called, so in order to preserve
5575
// the cancel() === no more runny-run, we have to jump through
5578
if (!method.apply) {
5579
method(data[0], data[1], data[2], data[3]);
5581
method.apply(o, data || NO_ARGS);
5585
id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when);
5590
cancel: function() {
5592
if (this.interval) {
5601
Y.Lang.later = Y.later;
5605
}, '3.9.1', {"requires": ["yui-base"]});
5606
YUI.add('yui', function (Y, NAME) {}, '3.9.1', {"use": ["get", "features", "intl-base", "yui-log", "yui-later"]});