2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
9 * The YUI module contains the components required for building the YUI seed
10 * file. This includes the script loading mechanism, a simple queue, and
11 * the core utilities for the library.
16 if (typeof YUI != 'undefined') {
21 * The YUI global namespace object. If YUI is already defined, the
22 * existing YUI object will not be overwritten so that defined
23 * namespaces are preserved. It is the constructor for the object
24 * the end user interacts with. As indicated below, each instance
25 * has full custom event support, but only if the event system
26 * is available. This is a self-instantiable factory function. You
27 * can invoke it directly like this:
29 * YUI().use('*', function(Y) {
33 * But it also works like this:
41 * @param o* {object} 0..n optional configuration objects. these values
42 * are store in Y.config. See config for the list of supported
47 var YUI = function() {
52 instanceOf = function(o, type) {
53 return (o && o.hasOwnProperty && (o instanceof type));
55 gconf = (typeof YUI_config !== 'undefined') && YUI_config;
57 if (!(instanceOf(Y, YUI))) {
60 // set up the core environment
63 // YUI.GlobalConfig is a master configuration that might span
64 // multiple contexts in a non-browser environment. It is applied
65 // first to all instances in all contexts.
66 if (YUI.GlobalConfig) {
67 Y.applyConfig(YUI.GlobalConfig);
70 // YUI_Config is a page-level config. It is applied to all
71 // instances created on the page. This is applied after
72 // YUI.GlobalConfig, and before the instance level configuration
78 // bind the specified additional modules for this instance
85 // Each instance can accept one or more configuration objects.
86 // These are applied after YUI.GlobalConfig and YUI_Config,
87 // overriding values set in those config files if there is a '
90 Y.applyConfig(args[i]);
96 Y.instanceOf = instanceOf;
106 BASE = 'http://yui.yahooapis.com/',
107 DOC_LABEL = 'yui3-js-enabled',
108 NOOP = function() {},
109 SLICE = Array.prototype.slice,
110 APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo
111 'io.xdrResponse': 1, // can call. this should
112 'SWF.eventHandler': 1 }, // be done at build time
113 hasWin = (typeof window != 'undefined'),
114 win = (hasWin) ? window : null,
115 doc = (hasWin) ? win.document : null,
116 docEl = doc && doc.documentElement,
117 docClass = docEl && docEl.className,
119 time = new Date().getTime(),
120 add = function(el, type, fn, capture) {
121 if (el && el.addEventListener) {
122 el.addEventListener(type, fn, capture);
123 } else if (el && el.attachEvent) {
124 el.attachEvent('on' + type, fn);
127 remove = function(el, type, fn, capture) {
128 if (el && el.removeEventListener) {
129 // this can throw an uncaught exception in FF
131 el.removeEventListener(type, fn, capture);
133 } else if (el && el.detachEvent) {
134 el.detachEvent('on' + type, fn);
137 handleLoad = function() {
138 YUI.Env.windowLoaded = true;
139 YUI.Env.DOMReady = true;
141 remove(window, 'load', handleLoad);
144 getLoader = function(Y, o) {
145 var loader = Y.Env._loader;
147 loader.ignoreRegistered = false;
150 loader.required = [];
151 loader.loadType = null;
153 loader = new Y.Loader(Y.config);
154 Y.Env._loader = loader;
160 clobber = function(r, s) {
162 if (s.hasOwnProperty(i)) {
168 ALREADY_DONE = { success: true };
170 // Stamp the documentElement (HTML) with a class of "yui-loaded" to
171 // enable styles that need to key off of JS being enabled.
172 if (docEl && docClass.indexOf(DOC_LABEL) == -1) {
176 docClass += DOC_LABEL;
177 docEl.className = docClass;
180 if (VERSION.indexOf('@') > -1) {
181 VERSION = '3.2.0'; // dev time hack for cdn test
186 * Applies a new configuration object to the YUI instance config.
187 * This will merge new group/module definitions, and will also
188 * update the loader cache if necessary. Updating Y.config directly
189 * will not update the cache.
190 * @method applyConfig
191 * @param {object} the configuration object.
194 applyConfig: function(o) {
201 config = this.config,
202 mods = config.modules,
203 groups = config.groups,
205 loader = this.Env._loader;
208 if (o.hasOwnProperty(name)) {
210 if (mods && name == 'modules') {
212 } else if (groups && name == 'groups') {
213 clobber(groups, attr);
214 } else if (rls && name == 'rls') {
216 } else if (name == 'win') {
217 config[name] = attr.contentWindow || attr;
218 config.doc = config[name].document;
219 } else if (name == '_yuid') {
232 _config: function(o) {
237 * Initialize this YUI instance
248 * The version number of the YUI instance.
256 mods: {}, // flat module map
257 versions: {}, // version module map
259 cdn: BASE + VERSION + '/build/',
260 // bootstrapped: false,
269 getBase: G_ENV && G_ENV.getBase ||
271 function(srcPattern, comboPattern) {
272 var b, nodes, i, src, match;
273 // get from querystring
274 nodes = (doc && doc.getElementsByTagName('script')) || [];
275 for (i = 0; i < nodes.length; i = i + 1) {
279 match = src.match(srcPattern);
280 b = match && match[1];
282 // this is to set up the path to the loader. The file
283 // filter for loader should match the yui include.
287 match = filter.indexOf('js');
290 filter = filter.substr(0, match);
294 // extract correct path for mixed combo urls
295 // http://yuilibrary.com/projects/yui3/ticket/2528423
296 match = src.match(comboPattern);
297 if (match && match[3]) {
298 b = match[1] + match[3];
313 Env._loaded[VERSION] = {};
315 if (G_ENV && Y !== YUI) {
316 Env._yidx = ++G_ENV._yidx;
317 Env._guidp = ('yui_' + VERSION + '_' +
318 Env._yidx + '_' + time).replace(/\./g, '_');
319 } else if (YUI._YUI) {
321 G_ENV = YUI._YUI.Env;
322 Env._yidx += G_ENV._yidx;
323 Env._uidx += G_ENV._uidx;
325 for (prop in G_ENV) {
326 if (!(prop in Env)) {
327 Env[prop] = G_ENV[prop];
341 // configuration defaults
342 Y.config = Y.config || {
346 useBrowserConsole: true,
353 Y.config.base = YUI.config.base ||
354 Y.Env.getBase(/^(.*)yui\/yui([\.\-].*)js(\?.*)?$/,
355 /^(.*\?)(.*\&)(.*)yui\/yui[\.\-].*js(\?.*)?$/);
357 if (!filter || (!('-min.-debug.').indexOf(filter))) {
361 Y.config.loaderPath = YUI.config.loaderPath ||
362 'loader/loader' + (filter || '-min.') + 'js';
367 * Finishes the instance setup. Attaches whatever modules were defined
368 * when the yui modules was registered.
372 _setup: function(o) {
376 extras = Y.config.core || ['get',
384 for (i = 0; i < extras.length; i++) {
385 if (mods[extras[i]]) {
386 core.push(extras[i]);
390 Y._attach(['yui-base']);
396 * Executes a method on a YUI instance with
397 * the specified id if the specified method is whitelisted.
399 * @param id {string} the YUI instance id.
400 * @param method {string} the name of the method to exectute.
402 * @param args {Array} the arguments to apply to the method.
403 * @return {object} the return value from the applied method or null.
405 applyTo: function(id, method, args) {
406 if (!(method in APPLY_TO_AUTH)) {
407 this.log(method + ': applyTo not allowed', 'warn', 'yui');
411 var instance = instances[id], nest, m, i;
413 nest = method.split('.');
415 for (i = 0; i < nest.length; i = i + 1) {
418 this.log('applyTo not found: ' + method, 'warn', 'yui');
421 return m.apply(instance, args);
428 * Registers a module with the YUI global. The easiest way to create a
429 * first-class YUI module is to use the YUI component build tool.
431 * http://yuilibrary.com/projects/builder
433 * The build system will produce the YUI.add wrapper for you module, along
434 * with any configuration info required for the module.
436 * @param name {string} module name.
437 * @param fn {Function} entry point into the module that
438 * is used to bind module to the YUI instance.
439 * @param version {string} version string.
440 * @param details {object} optional config data:
441 * requires: features that must be present before this module can be
443 * optional: optional features that should be present if loadOptional
444 * is defined. Note: modules are not often loaded this way in YUI 3,
445 * but this field is still useful to inform the user that certain
446 * features in the component will require additional dependencies.
447 * use: features that are included within this module which need to
448 * be attached automatically when this module is attached. This
449 * supports the YUI 3 rollup system -- a module with submodules
450 * defined will need to have the submodules listed in the 'use'
451 * config. The YUI component build tool does this for you.
452 * @return {YUI} the YUI instance.
455 add: function(name, fn, version, details) {
456 details = details || {};
465 i, versions = env.versions;
467 env.mods[name] = mod;
468 versions[version] = versions[version] || {};
469 versions[version][name] = mod;
471 for (i in instances) {
472 if (instances.hasOwnProperty(i)) {
473 loader = instances[i].Env._loader;
475 if (!loader.moduleInfo[name]) {
476 loader.addModule(details, name);
486 * Executes the function associated with each required
487 * module, binding the module to the YUI instance.
491 _attach: function(r, fromLoader) {
492 var i, name, mod, details, req, use, after,
495 done = Y.Env._attached,
496 len = r.length, loader;
499 for (i = 0; i < len; i++) {
504 loader = Y.Env._loader;
507 if (!loader || !loader.moduleInfo[name]) {
508 Y.message('NOT loaded: ' + name, 'warn', 'yui');
512 details = mod.details;
513 req = details.requires;
515 after = details.after;
518 for (j = 0; j < req.length; j++) {
520 if (!Y._attach(req)) {
529 for (j = 0; j < after.length; j++) {
530 if (!done[after[j]]) {
531 if (!Y._attach(after)) {
540 for (j = 0; j < use.length; j++) {
542 if (!Y._attach(use)) {
554 Y.error('Attach error: ' + name, e, name);
567 * Attaches one or more modules to the YUI instance. When this
568 * is executed, the requirements are analyzed, and one of
569 * several things can happen:
571 * - All requirements are available on the page -- The modules
572 * are attached to the instance. If supplied, the use callback
573 * is executed synchronously.
575 * - Modules are missing, the Get utility is not available OR
576 * the 'bootstrap' config is false -- A warning is issued about
577 * the missing modules and all available modules are attached.
579 * - Modules are missing, the Loader is not available but the Get
580 * utility is and boostrap is not false -- The loader is bootstrapped
581 * before doing the following....
583 * - Modules are missing and the Loader is available -- The loader
584 * expands the dependency tree and fetches missing modules. When
585 * the loader is finshed the callback supplied to use is executed
588 * @param modules* {string} 1-n modules to bind (uses arguments array).
589 * @param *callback {function} callback function executed when
590 * the instance has the required functionality. If included, it
591 * must be the last parameter.
593 * // loads and attaches drag and drop and its dependencies
594 * YUI().use('dd', function(Y) {});
595 * // attaches all modules that are available on the page
596 * YUI().use('*', function(Y) {});
597 * // intrinsic YUI gallery support (since 3.1.0)
598 * YUI().use('gallery-yql', function(Y) {});
599 * // intrinsic YUI 2in3 support (since 3.1.0)
600 * YUI().use('yui2-datatable', function(Y) {});.
603 * @return {YUI} the YUI instance.
606 var args = SLICE.call(arguments, 0),
607 callback = args[args.length - 1],
611 // The last argument supplied to use can be a load complete callback
612 if (Y.Lang.isFunction(callback)) {
619 Y._useQueue = Y._useQueue || new Y.Queue();
620 Y._useQueue.add([args, callback]);
624 if (Y.config.cacheUse && Y.Env.serviced[key]) {
625 Y._notify(callback, ALREADY_DONE, args);
627 Y._use(args, function(Y, response) {
628 if (Y.config.cacheUse) {
629 Y.Env.serviced[key] = true;
631 Y._notify(callback, response, args);
639 _notify: function(callback, response, args) {
640 if (!response.success && this.config.loadErrorFn) {
641 this.config.loadErrorFn.call(this, this, callback, response, args);
642 } else if (callback) {
644 callback(this, response);
646 this.error('use callback error', e, args);
651 _use: function(args, callback) {
654 this._attach(['yui-base']);
657 var len, loader, handleBoot,
663 queue = G_ENV._loaderQueue,
667 boot = config.bootstrap,
671 fetchCSS = config.fetchCSS,
672 process = function(names, skip) {
678 YArray.each(names, function(name) {
680 // add this module to full list of things to attach
685 // only attach a module once
690 var m = mods[name], req, use;
694 req = m.details.requires;
697 // CSS files don't register themselves, see if it has
699 if (!G_ENV._loaded[VERSION][name]) {
702 used[name] = true; // probably css
706 // make sure requirements are attached
707 if (req && req.length) {
711 // make sure we grab the submodule dependencies too
712 if (use && use.length) {
718 handleLoader = function(fromLoader) {
719 var response = fromLoader || {
725 data = response.data;
731 origMissing = missing;
735 redo = missing.length;
737 if (missing.sort().join() ==
738 origMissing.sort().join()) {
746 Y._use(args, function() {
747 if (Y._attach(data)) {
748 Y._notify(callback, response, data);
753 ret = Y._attach(data);
756 Y._notify(callback, response, args);
760 if (Y._useQueue && Y._useQueue.size() && !Y._loading) {
761 Y._use.apply(Y, Y._useQueue.next());
767 // YUI().use('*'); // bind everything available
768 if (firstArg === '*') {
769 ret = Y._attach(Y.Object.keys(mods));
777 // use loader to expand dependencies and sort the
778 // requirements if it is available.
779 if (boot && Y.Loader && args.length) {
780 loader = getLoader(Y);
781 loader.require(args);
782 loader.ignoreRegistered = true;
783 loader.calculate(null, (fetchCSS) ? null : 'js');
784 args = loader.sorted;
787 // process each requirement and any additional requirements
788 // the module metadata specifies
791 len = missing.length;
794 missing = Y.Object.keys(YArray.hash(missing));
795 len = missing.length;
799 if (boot && len && Y.Loader) {
801 loader = getLoader(Y);
802 loader.onEnd = handleLoader;
805 loader.ignoreRegistered = false;
806 loader.require(args);
807 loader.insert(null, (fetchCSS) ? null : 'js');
808 // loader.partial(missing, (fetchCSS) ? null : 'js');
810 } else if (len && Y.config.use_rls) {
812 // server side loader service
813 Y.Get.script(Y._rls(args), {
820 } else if (boot && len && Y.Get && !Env.bootstrapped) {
824 handleBoot = function() {
826 queue.running = false;
827 Env.bootstrapped = true;
828 if (Y._attach(['loader'])) {
829 Y._use(args, callback);
833 if (G_ENV._bootstrapping) {
834 queue.add(handleBoot);
836 G_ENV._bootstrapping = true;
837 Y.Get.script(config.base + config.loaderPath, {
843 ret = Y._attach(args);
854 * Returns the namespace specified and creates it if it doesn't exist
856 * YUI.namespace("property.package");
857 * YUI.namespace("YAHOO.property.package");
859 * Either of the above would create YUI.property, then
860 * YUI.property.package (YAHOO is scrubbed out, this is
861 * to remain compatible with YUI2)
863 * Be careful when naming packages. Reserved words may work in some browsers
864 * and not others. For instance, the following will fail in Safari:
866 * YUI.namespace("really.long.nested.namespace");
868 * This fails because "long" is a future reserved word in ECMAScript
871 * @param {string*} arguments 1-n namespaces to create.
872 * @return {object} A reference to the last namespace object created.
874 namespace: function() {
875 var a = arguments, o = this, i = 0, j, d, arg;
876 for (; i < a.length; i++) {
877 // d = ('' + a[i]).split('.');
879 if (arg.indexOf(PERIOD)) {
880 d = arg.split(PERIOD);
881 for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
882 o[d[j]] = o[d[j]] || {};
886 o[arg] = o[arg] || {};
892 // this is replaced if the log module is included
897 * Report an error. The reporting mechanism is controled by
898 * the 'throwFail' configuration attribute. If throwFail is
899 * not specified, the message is written to the Logger, otherwise
900 * a JS error is thrown
902 * @param msg {string} the error message.
903 * @param e {Error|string} Optional JS error that was caught, or an error string.
904 * @param data Optional additional info
905 * and throwFail is specified, this error will be re-thrown.
906 * @return {YUI} this YUI instance.
908 error: function(msg, e, data) {
912 if (Y.config.errorFn) {
913 ret = Y.config.errorFn.apply(Y, arguments);
916 if (Y.config.throwFail && !ret) {
917 throw (e || new Error(msg));
919 Y.message(msg, 'error'); // don't scrub this one
926 * Generate an id that is unique among all YUI instances
928 * @param pre {string} optional guid prefix.
929 * @return {string} the guid.
931 guid: function(pre) {
932 var id = this.Env._guidp + (++this.Env._uidx);
933 return (pre) ? (pre + id) : id;
937 * Returns a guid associated with an object. If the object
938 * does not have one, a new one is created unless readOnly
941 * @param o The object to stamp.
942 * @param readOnly {boolean} if true, a valid guid will only
943 * be returned if the object has one assigned to it.
944 * @return {string} The object's guid or null.
946 stamp: function(o, readOnly) {
952 // IE generates its own unique ID for dom nodes
953 // The uniqueID property of a document node returns a new ID
954 if (o.uniqueID && o.nodeType && o.nodeType !== 9) {
957 uid = (typeof o === 'string') ? o : o._yuid;
974 * Destroys the YUI instance
978 destroy: function() {
983 delete instances[Y.id];
989 * instanceof check for objects that works around
990 * memory leak in IE when the item tested is
999 YUI.prototype = proto;
1001 // inheritance utilities are not available yet
1002 for (prop in proto) {
1003 if (proto.hasOwnProperty(prop)) {
1004 YUI[prop] = proto[prop];
1008 // set up the environment
1012 // add a window load event at load time so we can capture
1013 // the case where it fires before dynamic loading is
1015 add(window, 'load', handleLoad);
1021 YUI.Env.remove = remove;
1024 // Support the CommonJS method for exporting our single global
1025 if (typeof exports == 'object') {
1033 * The config object contains all of the configuration options for
1034 * the YUI instance. This object is supplied by the implementer
1035 * when instantiating a YUI instance. Some properties have default
1036 * values if they are not supplied by the implementer. This should
1037 * not be updated directly because some values are cached. Use
1038 * applyConfig() to update the config object on a YUI instance that
1039 * has already been configured.
1046 * Allows the YUI seed file to fetch the loader component and library
1047 * metadata to dynamically load additional dependencies.
1049 * @property bootstrap
1055 * Log to the browser console if debug is on and the browser has a
1056 * supported console.
1058 * @property useBrowserConsole
1064 * A hash of log sources that should be logged. If specified, only
1065 * log messages from these sources will be logged.
1067 * @property logInclude
1072 * A hash of log sources that should be not be logged. If specified,
1073 * all sources are logged if not on this list.
1075 * @property logExclude
1080 * Set to true if the yui seed file was dynamically loaded in
1081 * order to bootstrap components relying on the window load event
1082 * and the 'domready' custom event.
1084 * @property injected
1090 * If throwFail is set, Y.error will generate or re-throw a JS Error.
1091 * Otherwise the failure is logged.
1093 * @property throwFail
1099 * The window/frame that this instance should operate in.
1103 * @default the window hosting YUI
1107 * The document associated with the 'win' configuration.
1111 * @default the document hosting YUI
1115 * A list of modules that defines the YUI core (overrides the default).
1122 * A list of languages in order of preference. This list is matched against
1123 * the list of available languages in modules that the YUI instance uses to
1124 * determine the best possible localization of language sensitive modules.
1125 * Languages are represented using BCP 47 language tags, such as "en-GB" for
1126 * English as used in the United Kingdom, or "zh-Hans-CN" for simplified
1127 * Chinese as used in China. The list can be provided as a comma-separated
1128 * list or as an array.
1131 * @type string|string[]
1135 * The default date format
1136 * @property dateFormat
1138 * @deprecated use configuration in DataType.Date.format() instead.
1142 * The default locale
1145 * @deprecated use config.lang instead.
1149 * The default interval when polling in milliseconds.
1150 * @property pollInterval
1156 * The number of dynamic nodes to insert by default before
1157 * automatically removing them. This applies to script nodes
1158 * because remove the node will not make the evaluated script
1159 * unavailable. Dynamic CSS is not auto purged, because removing
1160 * a linked style sheet will also remove the style definitions.
1161 * @property purgethreshold
1167 * The default interval when polling in milliseconds.
1168 * @property windowResizeDelay
1174 * Base directory for dynamic loading
1180 * The secure base dir (not implemented)
1181 * For dynamic loading.
1182 * @property secureBase
1187 * The YUI combo service base dir. Ex: http://yui.yahooapis.com/combo?
1188 * For dynamic loading.
1189 * @property comboBase
1194 * The root path to prepend to module path for the combo service.
1195 * Ex: 3.0.0b1/build/
1196 * For dynamic loading.
1202 * A filter to apply to result urls. This filter will modify the default
1203 * path for all modules. The default path for the YUI library is the
1204 * minified version of the files (e.g., event-min.js). The filter property
1205 * can be a predefined filter or a custom filter. The valid predefined
1209 * <dd>Selects the debug versions of the library (e.g., event-debug.js).
1210 * This option will automatically include the Logger widget</dd>
1212 * <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
1214 * You can also define a custom filter, which must be an object literal
1215 * containing a search expression and a replace string:
1218 * 'searchExp': "-min\\.js",
1219 * 'replaceStr': "-debug.js"
1223 * For dynamic loading.
1226 * @type string|object
1230 * The 'skin' config let's you configure application level skin
1231 * customizations. It contains the following attributes which
1232 * can be specified to override the defaults:
1234 * // The default skin, which is automatically applied if not
1235 * // overriden by a component-specific skin definition.
1236 * // Change this in to apply a different skin globally
1237 * defaultSkin: 'sam',
1239 * // This is combined with the loader base property to get
1240 * // the default root directory for a skin.
1241 * base: 'assets/skins/',
1243 * // Any component-specific overrides can be specified here,
1244 * // making it possible to load different skins for different
1245 * // components. It is possible to load more than one skin
1246 * // for a given component as well.
1248 * slider: ['capsule', 'round']
1251 * For dynamic loading.
1257 * Hash of per-component filter specification. If specified for a given
1258 * component, this overrides the filter config.
1260 * For dynamic loading.
1266 * Use the YUI combo service to reduce the number of http connections
1267 * required to load your dependencies. Turning this off will
1268 * disable combo handling for YUI and all module groups configured
1269 * with a combo service.
1271 * For dynamic loading.
1275 * @default true if 'base' is not supplied, false if it is.
1279 * A list of modules that should never be dynamically loaded
1286 * A list of modules that should always be loaded when required, even if already
1287 * present on the page.
1294 * Node or id for a node that should be used as the insertion point for new
1295 * nodes. For dynamic loading.
1297 * @property insertBefore
1302 * Object literal containing attributes to add to dynamically loaded script
1304 * @property jsAttributes
1309 * Object literal containing attributes to add to dynamically loaded link
1311 * @property cssAttributes
1316 * Number of milliseconds before a timeout occurs when dynamically
1317 * loading nodes. If not set, there is no timeout.
1323 * Callback for the 'CSSComplete' event. When dynamically loading YUI
1324 * components with CSS, this property fires when the CSS is finished
1325 * loading but script loading is still ongoing. This provides an
1326 * opportunity to enhance the presentation of a loading page a little
1327 * bit before the entire loading process is done.
1334 * A hash of module definitions to add to the list of YUI components.
1335 * These components can then be dynamically loaded side by side with
1336 * YUI via the use() method. This is a hash, the key is the module
1337 * name, and the value is an object literal specifying the metdata
1338 * for the module. * See Loader.addModule for the supported module
1339 * metadata fields. Also @see groups, which provides a way to
1340 * configure the base and combo spec for a set of modules.
1344 * requires: ['node'],
1345 * fullpath: 'http://myserver.mydomain.com/mymod1/mymod1.js'
1348 * requires: ['mymod1'],
1349 * fullpath: 'http://myserver.mydomain.com/mymod2/mymod2.js'
1359 * A hash of module group definitions. It for each group you
1360 * can specify a list of modules and the base path and
1361 * combo spec to use when dynamically loading the modules. @see
1362 * @see modules for the details about the modules part of the
1367 * // specify whether or not this group has a combo service
1368 * combine: true,
1370 * // the base path for non-combo paths
1371 * base: 'http://yui.yahooapis.com/2.8.0r4/build/',
1373 * // the path to the combo service
1374 * comboBase: 'http://yui.yahooapis.com/combo?',
1376 * // a fragment to prepend to the path attribute when
1377 * // when building combo urls
1378 * root: '2.8.0r4/build/',
1380 * // the module definitions
1382 * yui2_yde: {
1383 * path: "yahoo-dom-event/yahoo-dom-event.js"
1385 * yui2_anim: {
1386 * path: "animation/animation.js",
1387 * requires: ['yui2_yde']
1398 * The loader 'path' attribute to the loader itself. This is combined
1399 * with the 'base' attribute to dynamically load the loader component
1400 * when boostrapping with the get utility alone.
1402 * @property loaderPath
1404 * @default loader/loader-min.js
1408 * Specifies whether or not YUI().use(...) will attempt to load CSS
1409 * resources at all. Any truthy value will cause CSS dependencies
1410 * to load when fetching script. The special value 'force' will
1411 * cause CSS dependencies to be loaded even if no script is needed.
1413 * @property fetchCSS
1414 * @type boolean|string
1419 * The default gallery version to build gallery module urls
1426 * The default YUI 2 version to build yui2 module urls. This is for
1427 * intrinsic YUI 2 support via the 2in3 project. Also @see the '2in3'
1428 * config for pulling different revisions of the wrapped YUI 2
1437 * The 2in3 project is a deployment of the various versions of YUI 2
1438 * deployed as first-class YUI 3 modules. Eventually, the wrapper
1439 * for the modules will change (but the underlying YUI 2 code will
1440 * be the same), and you can select a particular version of
1441 * the wrapper modules via this config.
1449 * Alternative console log function for use in environments without
1450 * a supported native console. The function is executed in the
1451 * YUI instance context.
1458 * A callback to execute when Y.error is called. It receives the
1459 * error message and an javascript error object if Y.error was
1460 * executed because a javascript error was caught. The function
1461 * is executed in the YUI instance context.
1469 * A callback to execute when the loader fails to load one or
1470 * more resource. This could be because of a script load
1471 * failure. It can also fail if a javascript module fails
1472 * to register itself, but only when the 'requireRegistration'
1473 * is true. If this function is defined, the use() callback will
1474 * only be called when the loader succeeds, otherwise it always
1475 * executes unless there was a javascript error when attaching
1479 * @property loadErrorFn
1484 * When set to true, the YUI loader will expect that all modules
1485 * it is responsible for loading will be first-class YUI modules
1486 * that register themselves with the YUI global. If this is
1487 * set to true, loader will fail if the module registration fails
1488 * to happen after the script is loaded.
1491 * @property requireRegistration
1497 * Cache serviced use() requests.
1499 * @property cacheUse
1505 * The parameter defaults for the remote loader service.
1506 * Requires the rls submodule. The properties that are
1509 * m: comma separated list of module requirements. This
1510 * must be the param name even for custom implemetations.
1511 * v: the version of YUI to load. Defaults to the version
1512 * of YUI that is being used.
1513 * gv: the version of the gallery to load (@see the gallery config)
1514 * env: comma separated list of modules already on the page.
1515 * this must be the param name even for custom implemetations.
1516 * lang: the languages supported on the page (@see the lang config)
1517 * '2in3v': the version of the 2in3 wrapper to use (@see the 2in3 config).
1518 * '2v': the version of yui2 to use in the yui 2in3 wrappers
1519 * (@see the yui2 config)
1520 * filt: a filter def to apply to the urls (@see the filter config).
1521 * filts: a list of custom filters to apply per module
1522 * (@see the filters config).
1523 * tests: this is a map of conditional module test function id keys
1524 * with the values of 1 if the test passes, 0 if not. This must be
1525 * the name of the querystring param in custom templates.
1533 * The base path to the remote loader service
1536 * @property rls_base
1540 * The template to use for building the querystring portion
1541 * of the remote loader service url. The default is determined
1542 * by the rls config -- each property that has a value will be
1545 * ex: m={m}&v={v}&env={env}&lang={lang}&filt={filt}&tests={tests}
1549 * @property rls_tmpl
1553 * Configure the instance to use a remote loader service instead of
1554 * the client loader.
1559 YUI.add('yui-base', function(Y) {
1564 * @submodule yui-base
1567 * The YUI module contains the components required for building the YUI
1568 * seed file. This includes the script loading mechanism, a simple queue,
1569 * and the core utilities for the library.
1571 * @submodule yui-base
1575 * Provides the language utilites and extensions used by the library
1579 Y.Lang = Y.Lang || {};
1584 BOOLEAN = 'boolean',
1587 FUNCTION = 'function',
1593 STRING_PROTO = String.prototype,
1594 TOSTRING = Object.prototype.toString,
1595 UNDEFINED = 'undefined',
1598 'undefined' : UNDEFINED,
1600 'boolean' : BOOLEAN,
1602 '[object Function]' : FUNCTION,
1603 '[object RegExp]' : REGEX,
1604 '[object Array]' : ARRAY,
1605 '[object Date]' : DATE,
1606 '[object Error]' : ERROR
1609 TRIMREGEX = /^\s+|\s+$/g,
1611 SUBREGEX = /\{\s*([^\|\}]+?)\s*(?:\|([^\}]*))?\s*\}/g;
1614 * Determines whether or not the provided item is an array.
1615 * Returns false for array-like collections such as the
1616 * function arguments collection or HTMLElement collection
1617 * will return false. Use <code>Y.Array.test</code> if you
1618 * want to test for an array-like collection.
1621 * @param o The object to test.
1622 * @return {boolean} true if o is an array.
1624 // L.isArray = Array.isArray || function(o) {
1625 // return L.type(o) === ARRAY;
1628 L.isArray = function(o) {
1629 return L.type(o) === ARRAY;
1633 * Determines whether or not the provided item is a boolean.
1636 * @param o The object to test.
1637 * @return {boolean} true if o is a boolean.
1639 L.isBoolean = function(o) {
1640 return typeof o === BOOLEAN;
1645 * Determines whether or not the provided item is a function.
1646 * Note: Internet Explorer thinks certain functions are objects:
1650 * var obj = document.createElement("object");
1651 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE
1653 * var input = document.createElement("input"); // append to body
1654 * Y.Lang.isFunction(input.focus) // reports false in IE
1658 * You will have to implement additional tests if these functions
1662 * @method isFunction
1664 * @param o The object to test.
1665 * @return {boolean} true if o is a function.
1667 L.isFunction = function(o) {
1668 return L.type(o) === FUNCTION;
1672 * Determines whether or not the supplied item is a date instance.
1675 * @param o The object to test.
1676 * @return {boolean} true if o is a date.
1678 L.isDate = function(o) {
1679 // return o instanceof Date;
1680 return L.type(o) === DATE && o.toString() !== 'Invalid Date' && !isNaN(o);
1684 * Determines whether or not the provided item is null.
1687 * @param o The object to test.
1688 * @return {boolean} true if o is null.
1690 L.isNull = function(o) {
1695 * Determines whether or not the provided item is a legal number.
1698 * @param o The object to test.
1699 * @return {boolean} true if o is a number.
1701 L.isNumber = function(o) {
1702 return typeof o === NUMBER && isFinite(o);
1706 * Determines whether or not the provided item is of type object
1707 * or function. Note that arrays are also objects, so
1708 * <code>Y.Lang.isObject([]) === true</code>.
1711 * @param o The object to test.
1712 * @param failfn {boolean} fail if the input is a function.
1713 * @return {boolean} true if o is an object.
1715 L.isObject = function(o, failfn) {
1717 return (o && (t === OBJECT ||
1718 (!failfn && (t === FUNCTION || L.isFunction(o))))) || false;
1722 * Determines whether or not the provided item is a string.
1725 * @param o The object to test.
1726 * @return {boolean} true if o is a string.
1728 L.isString = function(o) {
1729 return typeof o === STRING;
1733 * Determines whether or not the provided item is undefined.
1734 * @method isUndefined
1736 * @param o The object to test.
1737 * @return {boolean} true if o is undefined.
1739 L.isUndefined = function(o) {
1740 return typeof o === UNDEFINED;
1744 * Returns a string without any leading or trailing whitespace. If
1745 * the input is not a string, the input will be returned untouched.
1748 * @param s {string} the string to trim.
1749 * @return {string} the trimmed string.
1751 L.trim = STRING_PROTO.trim ? function(s) {
1752 return (s && s.trim) ? s.trim() : s;
1755 return s.replace(TRIMREGEX, EMPTYSTRING);
1762 * Returns a string without any leading whitespace.
1765 * @param s {string} the string to trim.
1766 * @return {string} the trimmed string.
1768 L.trimLeft = STRING_PROTO.trimLeft ? function (s) {
1769 return s.trimLeft();
1771 return s.replace(/^\s+/, '');
1775 * Returns a string without any trailing whitespace.
1778 * @param s {string} the string to trim.
1779 * @return {string} the trimmed string.
1781 L.trimRight = STRING_PROTO.trimRight ? function (s) {
1782 return s.trimRight();
1784 return s.replace(/\s+$/, '');
1788 * A convenience method for detecting a legitimate non-null value.
1789 * Returns false for null/undefined/NaN, true for other values,
1790 * including 0/false/''
1793 * @param o The item to test.
1794 * @return {boolean} true if it is not null/undefined/NaN || false.
1796 L.isValue = function(o) {
1811 * Returns a string representing the type of the item passed in.
1820 * <code>typeof HTMLElementCollection</code> returns function in Safari, but
1821 * <code>Y.type()</code> reports object, which could be a good thing --
1822 * but it actually caused the logic in <code>Y.Lang.isObject</code> to fail.
1827 * @param o the item to test.
1828 * @return {string} the detected type.
1831 L.type = function(o) {
1832 return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? OBJECT : NULL);
1836 * Lightweight version of <code>Y.substitute</code>. Uses the same template
1837 * structure as <code>Y.substitute</code>, but doesn't support recursion,
1838 * auto-object coersion, or formats.
1840 * @param {string} s String to be modified.
1841 * @param {object} o Object containing replacement values.
1842 * @return {string} the substitute result.
1846 L.sub = function(s, o) {
1847 return ((s.replace) ? s.replace(SUBREGEX, function(match, key) {
1848 return (!L.isUndefined(o[key])) ? o[key] : match;
1853 * Returns the current time in milliseconds.
1855 * @return {int} the current date
1858 L.now = Date.now || function () {
1859 return new Date().getTime();
1863 * The YUI module contains the components required for building the YUI seed
1864 * file. This includes the script loading mechanism, a simple queue, and the
1865 * core utilities for the library.
1867 * @submodule yui-base
1871 var Native = Array.prototype, LENGTH = 'length',
1874 * Adds the following array utilities to the YUI instance. Additional
1875 * array helpers can be found in the collection component.
1880 * Y.Array(o) returns an array:
1881 * - Arrays are return unmodified unless the start position is specified.
1882 * - "Array-like" collections (@see Array.test) are converted to arrays
1883 * - For everything else, a new array is created with the input as the sole
1885 * - The start position is used if the input is or is like an array to return
1886 * a subset of the collection.
1888 * @todo this will not automatically convert elements that are also
1889 * collections such as forms and selects. Passing true as the third
1890 * param will force a conversion.
1894 * @param {object} o the item to arrayify.
1895 * @param {int} startIdx if an array or array-like, this is the start index.
1896 * @param {boolean} arraylike if true, it forces the array-like fork. This
1897 * can be used to avoid multiple Array.test calls.
1898 * @return {Array} the resulting array.
1900 YArray = function(o, startIdx, arraylike) {
1901 var t = (arraylike) ? 2 : YArray.test(o),
1902 l, a, start = startIdx || 0;
1905 // IE errors when trying to slice HTMLElement collections
1907 return Native.slice.call(o, start);
1911 for (; start < l; start++) {
1924 * Evaluates the input to determine if it is an array, array-like, or
1925 * something else. This is used to handle the arguments collection
1926 * available within functions, and HTMLElement collections
1931 * @todo current implementation (intenionally) will not implicitly
1932 * handle html elements that are array-like (forms, selects, etc).
1934 * @param {object} o the object to test.
1936 * @return {int} a number indicating the results:
1937 * 0: Not an array or an array-like collection
1939 * 2: array-like collection.
1941 YArray.test = function(o) {
1943 if (Y.Lang.isObject(o)) {
1944 if (Y.Lang.isArray(o)) {
1948 // indexed, but no tagName (element) or alert (window),
1949 // or functions without apply/call (Safari
1950 // HTMLElementCollection bug).
1951 if ((LENGTH in o) && !o.tagName && !o.alert && !o.apply) {
1962 * Executes the supplied function on each item in the array.
1964 * @param {Array} a the array to iterate.
1965 * @param {Function} f the function to execute on each item. The
1966 * function receives three arguments: the value, the index, the full array.
1967 * @param {object} o Optional context object.
1969 * @return {YUI} the YUI instance.
1971 YArray.each = (Native.forEach) ?
1973 Native.forEach.call(a || [], f, o || Y);
1977 var l = (a && a.length) || 0, i;
1978 for (i = 0; i < l; i = i + 1) {
1979 f.call(o || Y, a[i], i, a);
1985 * Returns an object using the first array as keys, and
1986 * the second as values. If the second array is not
1987 * provided the value is set to true for each.
1990 * @param {Array} k keyset.
1991 * @param {Array} v optional valueset.
1992 * @return {object} the hash.
1994 YArray.hash = function(k, v) {
1995 var o = {}, l = k.length, vl = v && v.length, i;
1996 for (i = 0; i < l; i = i + 1) {
1997 o[k[i]] = (vl && vl > i) ? v[i] : true;
2004 * Returns the index of the first item in the array
2005 * that contains the specified value, -1 if the
2006 * value isn't found.
2009 * @param {Array} a the array to search.
2010 * @param {any} val the value to search for.
2011 * @return {int} the index of the item that contains the value or -1.
2013 YArray.indexOf = (Native.indexOf) ?
2015 return Native.indexOf.call(a, val);
2018 for (var i = 0; i < a.length; i = i + 1) {
2028 * Numeric sort convenience function.
2029 * Y.ArrayAssert.itemsAreEqual([1,2,3], [3,1,2].sort(Y.Array.numericSort));
2030 * @method numericSort
2032 * @param {number} a a number.
2033 * @param {number} b a number.
2035 YArray.numericSort = function(a, b) {
2040 * Executes the supplied function on each item in the array.
2041 * Returning true from the processing function will stop the
2042 * processing of the remaining items.
2044 * @param {Array} a the array to iterate.
2045 * @param {Function} f the function to execute on each item. The function
2046 * receives three arguments: the value, the index, the full array.
2047 * @param {object} o Optional context object.
2049 * @return {boolean} true if the function returns true on
2050 * any of the items in the array.
2052 YArray.some = (Native.some) ?
2054 return Native.some.call(a, f, o);
2057 var l = a.length, i;
2058 for (i = 0; i < l; i = i + 1) {
2059 if (f.call(o, a[i], i, a)) {
2067 * The YUI module contains the components required for building the YUI
2068 * seed file. This includes the script loading mechanism, a simple queue,
2069 * and the core utilities for the library.
2071 * @submodule yui-base
2075 * A simple FIFO queue. Items are added to the Queue with add(1..n items) and
2076 * removed using next().
2080 * @param {MIXED} item* 0..n items to seed the queue.
2084 this.add.apply(this, arguments);
2089 * Initialize the queue
2096 * The collection of enqueued items
2106 * Get the next item in the queue. FIFO support
2109 * @return {MIXED} the next item in the queue.
2112 return this._q.shift();
2116 * Get the last in the queue. LIFO support.
2119 * @return {MIXED} the last item in the queue.
2122 return this._q.pop();
2126 * Add 0..n items to the end of the queue.
2129 * @param {MIXED} item* 0..n items.
2130 * @return {object} this queue.
2133 this._q.push.apply(this._q, arguments);
2139 * Returns the current number of queued items.
2142 * @return {Number} The size.
2145 return this._q.length;
2151 YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue();
2154 * The YUI module contains the components required for building the YUI
2155 * seed file. This includes the script loading mechanism, a simple queue,
2156 * and the core utilities for the library.
2158 * @submodule yui-base
2161 var CACHED_DELIMITER = '__',
2164 * IE will not enumerate native functions in a derived object even if the
2165 * function was overridden. This is a workaround for specific functions
2166 * we care about on the Object prototype.
2169 * @param {Function} r the object to receive the augmentation
2170 * @param {Function} s the object that supplies the properties to augment
2173 _iefix = function(r, s) {
2174 var fn = s.toString;
2175 if (Y.Lang.isFunction(fn) && fn != Object.prototype.toString) {
2182 * Returns a new object containing all of the properties of
2183 * all the supplied objects. The properties from later objects
2184 * will overwrite those in earlier objects. Passing in a
2185 * single object will create a shallow copy of it. For a deep
2189 * @param arguments {Object*} the objects to merge.
2190 * @return {object} the new merged object.
2192 Y.merge = function() {
2193 var a = arguments, o = {}, i, l = a.length;
2194 for (i = 0; i < l; i = i + 1) {
2195 Y.mix(o, a[i], true);
2201 * Applies the supplier's properties to the receiver. By default
2202 * all prototype and static propertes on the supplier are applied
2203 * to the corresponding spot on the receiver. By default all
2204 * properties are applied, and a property that is already on the
2205 * reciever will not be overwritten. The default behavior can
2206 * be modified by supplying the appropriate parameters.
2208 * @todo add constants for the modes
2211 * @param {Function} r the object to receive the augmentation.
2212 * @param {Function} s the object that supplies the properties to augment.
2213 * @param ov {boolean} if true, properties already on the receiver
2214 * will be overwritten if found on the supplier.
2215 * @param wl {string[]} a whitelist. If supplied, only properties in
2216 * this list will be applied to the receiver.
2217 * @param {int} mode what should be copies, and to where
2218 * default(0): object to object
2219 * 1: prototype to prototype (old augment)
2220 * 2: prototype to prototype and object props (new augment)
2221 * 3: prototype to object
2222 * 4: object to prototype.
2223 * @param merge {boolean/int} merge objects instead of overwriting/ignoring.
2224 * A value of 2 will skip array merge
2225 * Used by Y.aggregate.
2226 * @return {object} the augmented object.
2228 Y.mix = function(r, s, ov, wl, mode, merge) {
2236 case 1: // proto to proto
2237 return Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
2238 case 2: // object to object and proto to proto
2239 Y.mix(r.prototype, s.prototype, ov, wl, 0, merge);
2240 break; // pass through
2241 case 3: // proto to static
2242 return Y.mix(r, s.prototype, ov, wl, 0, merge);
2243 case 4: // static to proto
2244 return Y.mix(r.prototype, s, ov, wl, 0, merge);
2245 default: // object to object is what happens below
2249 // Maybe don't even need this wl && wl.length check anymore??
2252 if (wl && wl.length) {
2253 for (i = 0, l = wl.length; i < l; ++i) {
2255 type = Y.Lang.type(r[p]);
2256 if (s.hasOwnProperty(p)) {
2257 if (merge && type == 'object') {
2259 } else if (ov || !(p in r)) {
2266 // if (s.hasOwnProperty(i) && !(i in FROZEN)) {
2267 if (s.hasOwnProperty(i)) {
2268 // check white list if it was supplied
2269 // if the receiver has this property, it is an object,
2270 // and merge is specified, merge the two objects.
2271 if (merge && Y.Lang.isObject(r[i], true)) {
2272 Y.mix(r[i], s[i], ov, wl, 0, true); // recursive
2273 // otherwise apply the property only if overwrite
2274 // is specified or the receiver doesn't have one.
2275 } else if (ov || !(i in r)) {
2278 // if merge is specified and the receiver is an array,
2279 // append the array item
2280 // } else if (arr) {
2295 * Returns a wrapper for a function which caches the
2296 * return value of that function, keyed off of the combined
2299 * @param source {function} the function to memoize.
2300 * @param cache an optional cache seed.
2301 * @param refetch if supplied, this value is tested against the cached
2302 * value. If the values are equal, the wrapped function is executed again.
2303 * @return {Function} the wrapped function.
2305 Y.cached = function(source, cache, refetch) {
2306 cache = cache || {};
2308 return function(arg1) {
2310 var k = (arguments.length > 1) ?
2311 Array.prototype.join.call(arguments, CACHED_DELIMITER) : arg1;
2313 if (!(k in cache) || (refetch && cache[k] == refetch)) {
2314 cache[k] = source.apply(source, arguments);
2323 * The YUI module contains the components required for building the YUI
2324 * seed file. This includes the script loading mechanism, a simple queue,
2325 * and the core utilities for the library.
2327 * @submodule yui-base
2331 * Adds the following Object utilities to the YUI instance
2336 * Y.Object(o) returns a new object based upon the supplied object.
2339 * @param o the supplier object.
2340 * @return {Object} the new object.
2342 var F = function() {},
2344 // O = Object.create || function(o) {
2354 owns = function(o, k) {
2355 return o && o.hasOwnProperty && o.hasOwnProperty(k);
2356 // return Object.prototype.hasOwnProperty.call(o, k);
2362 * Extracts the keys, values, or size from an object
2365 * @param o the object.
2366 * @param what what to extract (0: keys, 1: values, 2: size).
2367 * @return {boolean|Array} the extracted info.
2371 _extract = function(o, what) {
2372 var count = (what === 2), out = (count) ? 0 : [], i;
2379 out.push((what) ? o[i] : i);
2390 * Returns an array containing the object's keys
2393 * @param o an object.
2394 * @return {string[]} the keys.
2396 // O.keys = Object.keys || function(o) {
2397 // return _extract(o);
2400 O.keys = function(o) {
2405 * Returns an array containing the object's values
2408 * @param o an object.
2409 * @return {Array} the values.
2411 // O.values = Object.values || function(o) {
2412 // return _extract(o, 1);
2415 O.values = function(o) {
2416 return _extract(o, 1);
2420 * Returns the size of an object
2423 * @param o an object.
2424 * @return {int} the size.
2426 O.size = Object.size || function(o) {
2427 return _extract(o, 2);
2431 * Returns true if the object contains a given key
2434 * @param o an object.
2435 * @param k the key to query.
2436 * @return {boolean} true if the object contains the key.
2440 * Returns true if the object contains a given value
2443 * @param o an object.
2444 * @param v the value to query.
2445 * @return {boolean} true if the object contains the value.
2447 O.hasValue = function(o, v) {
2448 return (Y.Array.indexOf(O.values(o), v) > -1);
2452 * Determines whether or not the property was added
2453 * to the object instance. Returns false if the property is not present
2454 * in the object, or was inherited from the prototype.
2458 * @param o {any} The object being testing.
2459 * @param p {string} the property to look for.
2460 * @return {boolean} true if the object has the property on the instance.
2465 * Executes a function on each item. The function
2466 * receives the value, the key, and the object
2467 * as parameters (in that order).
2470 * @param o the object to iterate.
2471 * @param f {Function} the function to execute on each item. The function
2472 * receives three arguments: the value, the the key, the full object.
2473 * @param c the execution context.
2474 * @param proto {boolean} include proto.
2475 * @return {YUI} the YUI instance.
2477 O.each = function(o, f, c, proto) {
2481 if (proto || owns(o, i)) {
2482 f.call(s, o[i], i, o);
2489 * Executes a function on each item, but halts if the
2490 * function returns true. The function
2491 * receives the value, the key, and the object
2492 * as paramters (in that order).
2495 * @param o the object to iterate.
2496 * @param f {Function} the function to execute on each item. The function
2497 * receives three arguments: the value, the the key, the full object.
2498 * @param c the execution context.
2499 * @param proto {boolean} include proto.
2500 * @return {boolean} true if any execution of the function returns true,
2503 O.some = function(o, f, c, proto) {
2507 if (proto || owns(o, i)) {
2508 if (f.call(s, o[i], i, o)) {
2517 * Retrieves the sub value at the provided path,
2518 * from the value object provided.
2522 * @param o The object from which to extract the property value.
2523 * @param path {Array} A path array, specifying the object traversal path
2524 * from which to obtain the sub value.
2525 * @return {Any} The value stored in the path, undefined if not found,
2526 * undefined if the source is not an object. Returns the source object
2527 * if an empty path is provided.
2529 O.getValue = function(o, path) {
2530 if (!Y.Lang.isObject(o)) {
2538 for (i = 0; o !== UNDEF && i < l; i++) {
2546 * Sets the sub-attribute value at the provided path on the
2547 * value object. Returns the modified value object, or
2548 * undefined if the path is invalid.
2552 * @param o The object on which to set the sub value.
2553 * @param path {Array} A path array, specifying the object traversal path
2554 * at which to set the sub value.
2555 * @param val {Any} The new value for the sub-attribute.
2556 * @return {Object} The modified object, with the new sub value set, or
2557 * undefined, if the path was invalid.
2559 O.setValue = function(o, path, val) {
2562 leafIdx = p.length - 1,
2566 for (i = 0; ref !== UNDEF && i < leafIdx; i++) {
2570 if (ref !== UNDEF) {
2581 * Returns true if the object has no properties of its own
2584 * @return {boolean} true if the object is empty.
2587 O.isEmpty = function(o) {
2596 * The YUI module contains the components required for building the YUI seed
2597 * file. This includes the script loading mechanism, a simple queue, and the
2598 * core utilities for the library.
2600 * @submodule yui-base
2604 * YUI user agent detection.
2605 * Do not fork for a browser if it can be avoided. Use feature detection when
2606 * you can. Use the user agent as a last resort. UA stores a version
2607 * number for the browser engine, 0 otherwise. This value may or may not map
2608 * to the version number of the browser using the engine. The value is
2609 * presented as a float so that it can easily be used for boolean evaluation
2610 * as well as for looking for a particular range of versions. Because of this,
2611 * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9
2617 * Static method for parsing the UA string. Defaults to assigning it's value to Y.UA
2619 * @method Env.parseUA
2620 * @param {String} subUA Parse this UA string instead of navigator.userAgent
2621 * @returns {Object} The Y.UA object
2623 YUI.Env.parseUA = function(subUA) {
2625 var numberify = function(s) {
2627 return parseFloat(s.replace(/\./g, function() {
2628 return (c++ == 1) ? '' : '.';
2634 nav = win && win.navigator,
2639 * Internet Explorer version number or 0. Example: 6
2647 * Opera version number or 0. Example: 9.2
2655 * Gecko engine revision number. Will evaluate to 1 if Gecko
2656 * is detected but the revision could not be found. Other browsers
2657 * will be 0. Example: 1.8
2659 * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7
2660 * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8
2661 * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81
2662 * Firefox 3.0 <-- 1.9
2663 * Firefox 3.5 <-- 1.91
2672 * AppleWebKit version. KHTML browsers that are not WebKit browsers
2673 * will evaluate to 1, other browsers 0. Example: 418.9
2675 * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the
2676 * latest available for Mac OSX 10.3.
2677 * Safari 2.0.2: 416 <-- hasOwnProperty introduced
2678 * Safari 2.0.4: 418 <-- preventDefault fixed
2679 * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
2680 * different versions of webkit
2681 * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been
2682 * updated, but not updated
2683 * to the latest patch.
2684 * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native
2685 * SVG and many major issues fixed).
2686 * Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic
2687 * update from 2.x via the 10.4.11 OS patch.
2688 * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event.
2689 * yahoo.com user agent hack removed.
2691 * http://en.wikipedia.org/wiki/Safari_version_history
2699 * Chrome will be detected as webkit, but this property will also
2700 * be populated with the Chrome version number
2708 * The mobile property will be set to a string containing any relevant
2709 * user agent information when a modern mobile browser is detected.
2710 * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
2711 * devices with the WebKit-based browser, and Opera Mini.
2719 * Adobe AIR version number or 0. Only populated if webkit is detected.
2726 * Detects Apple iPad's OS version
2733 * Detects Apple iPhone's OS version
2740 * Detects Apples iPod's OS version
2747 * General truthy check for iPad, iPhone or iPod
2754 * Detects Googles Android OS version
2761 * Detects Palms WebOS version
2769 * Google Caja version number or 0.
2773 caja: nav && nav.cajaVersion,
2776 * Set to true if the page appears to be in SSL
2784 * The operating system. Currently only detecting windows or macintosh
2793 ua = subUA || nav && nav.userAgent,
2795 loc = win && win.location,
2797 href = loc && loc.href,
2801 o.secure = href && (href.toLowerCase().indexOf('https') === 0);
2805 if ((/windows|win32/i).test(ua)) {
2807 } else if ((/macintosh/i).test(ua)) {
2809 } else if ((/rhino/i).test(ua)) {
2813 // Modern KHTML browsers should qualify as Safari X-Grade
2814 if ((/KHTML/).test(ua)) {
2817 // Modern WebKit browsers are at least X-Grade
2818 m = ua.match(/AppleWebKit\/([^\s]*)/);
2820 o.webkit = numberify(m[1]);
2822 // Mobile browser check
2823 if (/ Mobile\//.test(ua)) {
2824 o.mobile = 'Apple'; // iPhone or iPod Touch
2826 m = ua.match(/OS ([^\s]*)/);
2828 m = numberify(m[1].replace('_', '.'));
2831 o.ipad = o.ipod = o.iphone = 0;
2833 m = ua.match(/iPad|iPod|iPhone/);
2835 o[m[0].toLowerCase()] = o.ios;
2838 m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/);
2840 // Nokia N-series, Android, webOS, ex: NokiaN95
2843 if (/webOS/.test(ua)) {
2845 m = ua.match(/webOS\/([^\s]*);/);
2847 o.webos = numberify(m[1]);
2850 if (/ Android/.test(ua)) {
2851 o.mobile = 'Android';
2852 m = ua.match(/Android ([^\s]*);/);
2854 o.android = numberify(m[1]);
2860 m = ua.match(/Chrome\/([^\s]*)/);
2862 o.chrome = numberify(m[1]); // Chrome
2864 m = ua.match(/AdobeAIR\/([^\s]*)/);
2866 o.air = m[0]; // Adobe AIR 1.0 or better
2871 if (!o.webkit) { // not webkit
2872 // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
2873 m = ua.match(/Opera[\s\/]([^\s]*)/);
2875 o.opera = numberify(m[1]);
2876 m = ua.match(/Opera Mini[^;]*/);
2878 o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
2880 } else { // not opera or webkit
2881 m = ua.match(/MSIE\s([^;]*)/);
2883 o.ie = numberify(m[1]);
2884 } else { // not opera, webkit, or ie
2885 m = ua.match(/Gecko\/([^\s]*)/);
2887 o.gecko = 1; // Gecko detected, look for revision
2888 m = ua.match(/rv:([^\s\)]*)/);
2890 o.gecko = numberify(m[1]);
2904 Y.UA = YUI.Env.UA || YUI.Env.parseUA();
2908 YUI.add('get', function(Y) {
2912 * Provides a mechanism to fetch remote resources and
2913 * insert them into a document.
2920 TYPE_JS = 'text/javascript',
2921 TYPE_CSS = 'text/css',
2922 STYLESHEET = 'stylesheet';
2925 * Fetches and inserts one or more script or link nodes into the document
2929 Y.Get = function() {
2932 * hash of queues to manage multiple requests
2936 var _get, _purge, _track,
2941 * queue index used to generate transaction ids
2949 * interal property used to prevent multiple simultaneous purge
2959 * Generates an HTML element, this is not appended to a document
2961 * @param {string} type the type of element.
2962 * @param {string} attr the attributes.
2963 * @param {Window} win optional window to create the element in.
2964 * @return {HTMLElement} the generated node.
2967 _node = function(type, attr, win) {
2968 var w = win || Y.config.win,
2970 n = d.createElement(type),
2974 if (attr[i] && attr.hasOwnProperty(i)) {
2975 n.setAttribute(i, attr[i]);
2983 * Generates a link node
2985 * @param {string} url the url for the css file.
2986 * @param {Window} win optional window to create the node in.
2987 * @param {object} attributes optional attributes collection to apply to the
2989 * @return {HTMLElement} the generated node.
2992 _linkNode = function(url, win, attributes) {
3000 Y.mix(o, attributes);
3002 return _node('link', o, win);
3006 * Generates a script node
3007 * @method _scriptNode
3008 * @param {string} url the url for the script file.
3009 * @param {Window} win optional window to create the node in.
3010 * @param {object} attributes optional attributes collection to apply to the
3012 * @return {HTMLElement} the generated node.
3015 _scriptNode = function(url, win, attributes) {
3022 Y.mix(o, attributes);
3027 return _node('script', o, win);
3031 * Returns the data payload for callback functions.
3032 * @method _returnData
3033 * @param {object} q the queue.
3034 * @param {string} msg the result message.
3035 * @param {string} result the status message from the request.
3036 * @return {object} the state data from the request.
3039 _returnData = function(q, msg, result) {
3054 * The transaction is finished
3056 * @param {string} id the id of the request.
3057 * @param {string} msg the result message.
3058 * @param {string} result the status message from the request.
3061 _end = function(id, msg, result) {
3062 var q = queues[id], sc;
3064 sc = q.context || q;
3065 q.onEnd.call(sc, _returnData(q, msg, result));
3070 * The request failed, execute fail handler with whatever
3071 * was accomplished. There isn't a failure case at the
3072 * moment unless you count aborted transactions
3074 * @param {string} id the id of the request
3077 _fail = function(id, msg) {
3079 var q = queues[id], sc;
3081 // q.timer.cancel();
3082 clearTimeout(q.timer);
3085 // execute failure callback
3087 sc = q.context || q;
3088 q.onFailure.call(sc, _returnData(q, msg));
3091 _end(id, msg, 'failure');
3095 * The request is complete, so executing the requester's callback
3097 * @param {string} id the id of the request.
3100 _finish = function(id) {
3101 var q = queues[id], msg, sc;
3103 // q.timer.cancel();
3104 clearTimeout(q.timer);
3109 msg = 'transaction ' + id + ' was aborted';
3114 // execute success callback
3116 sc = q.context || q;
3117 q.onSuccess.call(sc, _returnData(q));
3120 _end(id, msg, 'OK');
3126 * @param {string} id the id of the request.
3129 _timeout = function(id) {
3130 var q = queues[id], sc;
3132 sc = q.context || q;
3133 q.onTimeout.call(sc, _returnData(q));
3136 _end(id, 'timeout', 'timeout');
3141 * Loads the next item for a given request
3143 * @param {string} id the id of the request.
3144 * @param {string} loaded the url that was just loaded, if any.
3145 * @return {string} the result.
3148 _next = function(id, loaded) {
3149 var q = queues[id], msg, w, d, h, n, url, s,
3153 // q.timer.cancel();
3154 clearTimeout(q.timer);
3158 msg = 'transaction ' + id + ' was aborted';
3169 // This is the first pass: make sure the url is an array
3170 q.url = (L.isString(q.url)) ? [q.url] : q.url;
3172 q.varName = (L.isString(q.varName)) ? [q.varName] : q.varName;
3178 h = d.getElementsByTagName('head')[0];
3180 if (q.url.length === 0) {
3187 // if the url is undefined, this is probably a trailing comma
3196 // q.timer = L.later(q.timeout, q, _timeout, id);
3197 q.timer = setTimeout(function() {
3202 if (q.type === 'script') {
3203 n = _scriptNode(url, w, q.attributes);
3205 n = _linkNode(url, w, q.attributes);
3208 // track this node's load progress
3209 _track(q.type, n, id, url, w, q.url.length);
3211 // add the node to the queue so we can return it to the user supplied
3215 // add it to the head or insert it before 'insertBefore'. Work around
3216 // IE bug if there is a base tag.
3217 insertBefore = q.insertBefore ||
3218 d.getElementsByTagName('base')[0];
3221 s = _get(insertBefore, id);
3223 s.parentNode.insertBefore(n, s);
3230 // FireFox does not support the onload event for link nodes, so
3231 // there is no way to make the css requests synchronous. This means
3232 // that the css rules in multiple files could be applied out of order
3233 // in this browser if a later request returns before an earlier one.
3235 if ((ua.webkit || ua.gecko) && q.type === 'css') {
3241 * Removes processed queues and corresponding nodes
3242 * @method _autoPurge
3245 _autoPurge = function() {
3254 if (queues.hasOwnProperty(i)) {
3256 if (q.autopurge && q.finished) {
3267 * Saves the state for the request and begins loading
3268 * the requested urls
3270 * @param {string} type the type of node to insert.
3271 * @param {string} url the url to load.
3272 * @param {object} opts the hash of options for this request.
3273 * @return {object} transaction object.
3276 _queue = function(type, url, opts) {
3279 var id = 'q' + (qidx++), q,
3280 thresh = opts.purgethreshold || Y.Get.PURGE_THRESH;
3282 if (qidx % thresh === 0) {
3286 queues[id] = Y.merge(opts, {
3295 q.win = q.win || Y.config.win;
3296 q.context = q.context || q;
3297 q.autopurge = ('autopurge' in q) ? q.autopurge :
3298 (type === 'script') ? true : false;
3300 q.attributes = q.attributes || {};
3301 q.attributes.charset = opts.charset || q.attributes.charset || 'utf-8';
3311 * Detects when a node has been loaded. In the case of
3312 * script nodes, this does not guarantee that contained
3313 * script is ready to use.
3315 * @param {string} type the type of node to track.
3316 * @param {HTMLElement} n the node to track.
3317 * @param {string} id the id of the request.
3318 * @param {string} url the url that is being loaded.
3319 * @param {Window} win the targeted window.
3320 * @param {int} qlength the number of remaining items in the queue,
3321 * including this one.
3322 * @param {Function} trackfn function to execute when finished
3323 * the default is _next.
3326 _track = function(type, n, id, url, win, qlength, trackfn) {
3327 var f = trackfn || _next;
3329 // IE supports the readystatechange event for script and css nodes
3330 // Opera only for script nodes. Opera support onload for script
3331 // nodes, but this doesn't fire when there is a load failure.
3332 // The onreadystatechange appears to be a better way to respond
3333 // to both success and failure.
3335 n.onreadystatechange = function() {
3336 var rs = this.readyState;
3337 if ('loaded' === rs || 'complete' === rs) {
3338 n.onreadystatechange = null;
3343 // webkit prior to 3.x is no longer supported
3344 } else if (ua.webkit) {
3345 if (type === 'script') {
3346 // Safari 3.x supports the load event for script nodes (DOM2)
3347 n.addEventListener('load', function() {
3352 // FireFox and Opera support onload (but not DOM2 in FF) handlers for
3353 // script nodes. Opera, but not FF, supports the onload event for link
3356 n.onload = function() {
3360 n.onerror = function(e) {
3361 _fail(id, e + ': ' + url);
3366 _get = function(nId, tId) {
3367 var q = queues[tId],
3368 n = (L.isString(nId)) ? q.win.document.getElementById(nId) : nId;
3370 _fail(tId, 'target node not found: ' + nId);
3377 * Removes the nodes for the specified queue
3379 * @param {string} tId the transaction id.
3382 _purge = function(tId) {
3383 var n, l, d, h, s, i, node, attr, insertBefore,
3390 h = d.getElementsByTagName('head')[0];
3392 insertBefore = q.insertBefore ||
3393 d.getElementsByTagName('base')[0];
3396 s = _get(insertBefore, tId);
3402 for (i = 0; i < l; i = i + 1) {
3404 if (node.clearAttributes) {
3405 node.clearAttributes();
3407 for (attr in node) {
3408 if (node.hasOwnProperty(attr)) {
3414 h.removeChild(node);
3423 * The number of request required before an automatic purge.
3424 * Can be configured via the 'purgethreshold' config
3425 * property PURGE_THRESH
3434 * Called by the the helper for detecting script load in Safari
3437 * @param {string} id the transaction id.
3440 _finalize: function(id) {
3441 setTimeout(function() {
3447 * Abort a transaction
3450 * @param {string|object} o Either the tId or the object returned from
3451 * script() or css().
3453 abort: function(o) {
3454 var id = (L.isString(o)) ? o : o.tId,
3462 * Fetches and inserts one or more script nodes into the head
3463 * of the current document or the document in a specified window.
3467 * @param {string|string[]} url the url or urls to the script(s).
3468 * @param {object} opts Options:
3470 * <dt>onSuccess</dt>
3472 * callback to execute when the script(s) are finished loading
3473 * The callback receives an object back with the following
3477 * <dd>the window the script(s) were inserted into</dd>
3479 * <dd>the data object passed in when the request was made</dd>
3481 * <dd>An array containing references to the nodes that were
3484 * <dd>A function that, when executed, will remove the nodes
3485 * that were inserted</dd>
3489 * <dt>onTimeout</dt>
3491 * callback to execute when a timeout occurs.
3492 * The callback receives an object back with the following
3496 * <dd>the window the script(s) were inserted into</dd>
3498 * <dd>the data object passed in when the request was made</dd>
3500 * <dd>An array containing references to the nodes that were
3503 * <dd>A function that, when executed, will remove the nodes
3504 * that were inserted</dd>
3509 * <dd>a function that executes when the transaction finishes,
3510 * regardless of the exit path</dd>
3511 * <dt>onFailure</dt>
3513 * callback to execute when the script load operation fails
3514 * The callback receives an object back with the following
3518 * <dd>the window the script(s) were inserted into</dd>
3520 * <dd>the data object passed in when the request was made</dd>
3522 * <dd>An array containing references to the nodes that were
3523 * inserted successfully</dd>
3525 * <dd>A function that, when executed, will remove any nodes
3526 * that were inserted</dd>
3531 * <dd>the execution context for the callbacks</dd>
3533 * <dd>a window other than the one the utility occupies</dd>
3534 * <dt>autopurge</dt>
3536 * setting to true will let the utilities cleanup routine purge
3537 * the script once loaded
3539 * <dt>purgethreshold</dt>
3541 * The number of transaction before autopurge should be initiated
3545 * data that is supplied to the callback when the script(s) are
3548 * <dt>insertBefore</dt>
3549 * <dd>node or node id that will become the new node's nextSibling.
3550 * If this is not specified, nodes will be inserted before a base
3551 * tag should it exist. Otherwise, the nodes will be appended to the
3552 * end of the document head.</dd>
3555 * <dd>Node charset, default utf-8 (deprecated, use the attributes
3557 * <dt>attributes</dt>
3558 * <dd>An object literal containing additional attributes to add to
3559 * the link tags</dd>
3561 * <dd>Number of milliseconds to wait before aborting and firing
3562 * the timeout event</dd>
3564 * Y.Get.script(
3565 * ["http://yui.yahooapis.com/2.5.2/build/yahoo/yahoo-min.js",
3566 * "http://yui.yahooapis.com/2.5.2/build/event/event-min.js"],
3568 * onSuccess: function(o) {
3569 * this.log("won't cause error because Y is the context");
3570 * // immediately
3572 * onFailure: function(o) {
3574 * onTimeout: function(o) {
3576 * data: "foo",
3577 * timeout: 10000, // 10 second timeout
3578 * context: Y, // make the YUI instance
3579 * // win: otherframe // target another window/frame
3580 * autopurge: true // allow the utility to choose when to
3581 * // remove the nodes
3582 * purgetheshold: 1 // purge previous transaction before
3583 * // next transaction
3586 * @return {tId: string} an object containing info about the
3589 script: function(url, opts) {
3590 return _queue('script', url, opts);
3594 * Fetches and inserts one or more css link nodes into the
3595 * head of the current document or the document in a specified
3599 * @param {string} url the url or urls to the css file(s).
3600 * @param {object} opts Options:
3602 * <dt>onSuccess</dt>
3604 * callback to execute when the css file(s) are finished loading
3605 * The callback receives an object back with the following
3608 * <dd>the window the link nodes(s) were inserted into</dd>
3610 * <dd>the data object passed in when the request was made</dd>
3612 * <dd>An array containing references to the nodes that were
3615 * <dd>A function that, when executed, will remove the nodes
3616 * that were inserted</dd>
3621 * <dd>the execution context for the callbacks</dd>
3623 * <dd>a window other than the one the utility occupies</dd>
3626 * data that is supplied to the callbacks when the nodes(s) are
3629 * <dt>insertBefore</dt>
3630 * <dd>node or node id that will become the new node's nextSibling</dd>
3632 * <dd>Node charset, default utf-8 (deprecated, use the attributes
3634 * <dt>attributes</dt>
3635 * <dd>An object literal containing additional attributes to add to
3636 * the link tags</dd>
3639 * Y.Get.css("http://localhost/css/menu.css");
3643 * ["http://localhost/css/menu.css",
3644 * insertBefore: 'custom-styles' // nodes will be inserted
3645 * // before the specified node
3648 * @return {tId: string} an object containing info about the
3651 css: function(url, opts) {
3652 return _queue('css', url, opts);
3659 }, '3.3.0' ,{requires:['yui-base']});
3660 YUI.add('features', function(Y) {
3662 var feature_tests = {};
3664 Y.mix(Y.namespace('Features'), {
3666 tests: feature_tests,
3668 add: function(cat, name, o) {
3669 feature_tests[cat] = feature_tests[cat] || {};
3670 feature_tests[cat][name] = o;
3673 all: function(cat, args) {
3674 var cat_o = feature_tests[cat],
3678 Y.Object.each(cat_o, function(v, k) {
3679 // results[k] = Y.Features.test(cat, k, args);
3681 (Y.Features.test(cat, k, args) ? 1 : 0) + ';';
3688 test: function(cat, name, args) {
3690 var result, ua, test,
3691 cat_o = feature_tests[cat],
3692 feature = cat_o && cat_o[name];
3697 result = feature.result;
3699 if (Y.Lang.isUndefined(result)) {
3703 result = (Y.UA[ua]);
3706 test = feature.test;
3707 if (test && ((!ua) || result)) {
3708 result = test.apply(Y, args);
3711 feature.result = result;
3719 // Y.Features.add("load", "1", {});
3720 // Y.Features.test("load", "1");
3721 // caps=1:1;2:0;3:1;
3723 /* This file is auto-generated by src/loader/meta_join.py */
3724 var add = Y.Features.add;
3725 // autocomplete-list-keys-sniff.js
3727 "test": function (Y) {
3728 // Only add keyboard support to autocomplete-list if this doesn't appear to
3729 // be an iOS or Android-based mobile device.
3731 // There's currently no feasible way to actually detect whether a device has
3732 // a hardware keyboard, so this sniff will have to do. It can easily be
3733 // overridden by manually loading the autocomplete-list-keys module.
3735 // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
3736 // doesn't fire the keyboard events used by AutoCompleteList, so there's
3737 // no point loading the -keys module even when a bluetooth keyboard may be
3739 return !(Y.UA.ios || Y.UA.android);
3741 "trigger": "autocomplete-list"
3745 "test": function (Y) {
3747 var testFeature = Y.Features.test,
3748 addFeature = Y.Features.add,
3749 WINDOW = Y.config.win,
3750 DOCUMENT = Y.config.doc,
3751 DOCUMENT_ELEMENT = 'documentElement',
3754 addFeature('style', 'computedStyle', {
3756 return WINDOW && 'getComputedStyle' in WINDOW;
3760 addFeature('style', 'opacity', {
3762 return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
3766 ret = (!testFeature('style', 'opacity') &&
3767 !testFeature('style', 'computedStyle'));
3771 "trigger": "dom-style"
3775 "trigger": "widget-base",
3780 "test": function(Y) {
3781 var imp = Y.config.doc && Y.config.doc.implementation;
3782 return (imp && (!imp.hasFeature('Events', '2.0')));
3784 "trigger": "node-base"
3786 // dd-gestures-test.js
3788 "test": function(Y) {
3789 return (Y.config.win && ('ontouchstart' in Y.config.win && !Y.UA.chrome));
3791 "trigger": "dd-drag"
3793 // history-hash-ie-test.js
3795 "test": function (Y) {
3796 var docMode = Y.config.doc.documentMode;
3798 return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
3799 !docMode || docMode < 8);
3801 "trigger": "history-hash"
3805 }, '3.3.0' ,{requires:['yui-base']});
3806 YUI.add('rls', function(Y) {
3809 * Implentation for building the remote loader service url.
3811 * @param {Array} what the requested modules.
3813 * @return {string} the url for the remote loader service call.
3815 Y._rls = function(what) {
3817 var config = Y.config,
3819 // the configuration
3820 rls = config.rls || {
3821 m: 1, // required in the template
3824 env: 1, // required in the template
3826 '2in3v': config['2in3'],
3828 filt: config.filter,
3829 filts: config.filters,
3830 tests: 1 // required in the template
3833 // The rls base path
3834 rls_base = config.rls_base || 'load?',
3837 rls_tmpl = config.rls_tmpl || function() {
3839 for (param in rls) {
3840 if (param in rls && rls[param]) {
3841 s += param + '={' + param + '}&';
3844 // console.log('rls_tmpl: ' + s);
3850 // update the request
3852 rls.env = Y.Object.keys(YUI.Env.mods);
3853 rls.tests = Y.Features.all('load', [Y]);
3855 url = Y.Lang.sub(rls_base + rls_tmpl, rls);
3858 config.rls_tmpl = rls_tmpl;
3860 // console.log(url);
3866 }, '3.3.0' ,{requires:['get','features']});
3867 YUI.add('intl-base', function(Y) {
3870 * The Intl utility provides a central location for managing sets of
3871 * localized resources (strings and formatting patterns).
3878 var SPLIT_REGEX = /[, ]/;
3880 Y.mix(Y.namespace('Intl'), {
3883 * Returns the language among those available that
3884 * best matches the preferred language list, using the Lookup
3885 * algorithm of BCP 47.
3886 * If none of the available languages meets the user's preferences,
3887 * then "" is returned.
3888 * Extended language ranges are not supported.
3890 * @method lookupBestLang
3891 * @param {String[] | String} preferredLanguages The list of preferred
3892 * languages in descending preference order, represented as BCP 47
3893 * language tags. A string array or a comma-separated list.
3894 * @param {String[]} availableLanguages The list of languages
3895 * that the application supports, represented as BCP 47 language
3898 * @return {String} The available language that best matches the
3899 * preferred language list, or "".
3902 lookupBestLang: function(preferredLanguages, availableLanguages) {
3904 var i, language, result, index;
3906 // check whether the list of available languages contains language;
3908 function scan(language) {
3910 for (i = 0; i < availableLanguages.length; i += 1) {
3911 if (language.toLowerCase() ===
3912 availableLanguages[i].toLowerCase()) {
3913 return availableLanguages[i];
3918 if (Y.Lang.isString(preferredLanguages)) {
3919 preferredLanguages = preferredLanguages.split(SPLIT_REGEX);
3922 for (i = 0; i < preferredLanguages.length; i += 1) {
3923 language = preferredLanguages[i];
3924 if (!language || language === '*') {
3927 // check the fallback sequence for one language
3928 while (language.length > 0) {
3929 result = scan(language);
3933 index = language.lastIndexOf('-');
3935 language = language.substring(0, index);
3936 // one-character subtags get cut along with the
3938 if (index >= 2 && language.charAt(index - 2) === '-') {
3939 language = language.substring(0, index - 2);
3942 // nothing available for this language
3954 }, '3.3.0' ,{requires:['yui-base']});
3955 YUI.add('yui-log', function(Y) {
3958 * Provides console log capability and exposes a custom event for
3959 * console implementations.
3961 * @submodule yui-log
3965 LOGEVENT = 'yui:log',
3966 UNDEFINED = 'undefined',
3967 LEVELS = { debug: 1,
3973 * If the 'debug' config is true, a 'yui:log' event will be
3974 * dispatched, which the Console widget and anything else
3975 * can consume. If the 'useBrowserConsole' config is true, it will
3976 * write to the browser console if available. YUI-specific log
3977 * messages will only be present in the -debug versions of the
3978 * JS files. The build system is supposed to remove log statements
3979 * from the raw and minified versions of the files.
3983 * @param {String} msg The message to log.
3984 * @param {String} cat The log category for the message. Default
3985 * categories are "info", "warn", "error", time".
3986 * Custom categories can be used as well. (opt).
3987 * @param {String} src The source of the the message (opt).
3988 * @param {boolean} silent If true, the log event won't fire.
3989 * @return {YUI} YUI instance.
3991 INSTANCE.log = function(msg, cat, src, silent) {
3992 var bail, excl, incl, m, f,
3995 publisher = (Y.fire) ? Y : YUI.Env.globalEvents;
3996 // suppress log message if the config is off or the event stack
3997 // or the event call stack contains a consumer of the yui:log event
3999 // apply source filters
4001 excl = c.logExclude;
4002 incl = c.logInclude;
4003 if (incl && !(src in incl)) {
4005 } else if (excl && (src in excl)) {
4010 if (c.useBrowserConsole) {
4011 m = (src) ? src + ': ' + msg : msg;
4012 if (Y.Lang.isFunction(c.logFn)) {
4013 c.logFn.call(Y, msg, cat, src);
4014 } else if (typeof console != UNDEFINED && console.log) {
4015 f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log';
4017 } else if (typeof opera != UNDEFINED) {
4022 if (publisher && !silent) {
4024 if (publisher == Y && (!publisher.getEvent(LOGEVENT))) {
4025 publisher.publish(LOGEVENT, {
4030 publisher.fire(LOGEVENT, {
4043 * Write a system message. This message will be preserved in the
4044 * minified and raw versions of the YUI files, unlike log statements.
4047 * @param {String} msg The message to log.
4048 * @param {String} cat The log category for the message. Default
4049 * categories are "info", "warn", "error", time".
4050 * Custom categories can be used as well. (opt).
4051 * @param {String} src The source of the the message (opt).
4052 * @param {boolean} silent If true, the log event won't fire.
4053 * @return {YUI} YUI instance.
4055 INSTANCE.message = function() {
4056 return INSTANCE.log.apply(INSTANCE, arguments);
4060 }, '3.3.0' ,{requires:['yui-base']});
4061 YUI.add('yui-later', function(Y) {
4064 * Provides a setTimeout/setInterval wrapper
4066 * @submodule yui-later
4070 * Executes the supplied function in the context of the supplied
4071 * object 'when' milliseconds later. Executes the function a
4072 * single time unless periodic is set to true.
4075 * @param when {int} the number of milliseconds to wait until the fn
4077 * @param o the context object.
4078 * @param fn {Function|String} the function to execute or the name of
4079 * the method in the 'o' object to execute.
4080 * @param data [Array] data that is provided to the function. This
4081 * accepts either a single item or an array. If an array is provided,
4082 * the function is executed with one parameter for each array item.
4083 * If you need to pass a single array parameter, it needs to be wrapped
4084 * in an array [myarray].
4085 * @param periodic {boolean} if true, executes continuously at supplied
4086 * interval until canceled.
4087 * @return {object} a timer object. Call the cancel() method on this
4088 * object to stop the timer.
4090 Y.later = function(when, o, fn, data, periodic) {
4095 if (o && Y.Lang.isString(fn)) {
4099 f = !Y.Lang.isUndefined(data) ? function() {
4100 m.apply(o, Y.Array(data));
4105 id = (periodic) ? setInterval(f, when) : setTimeout(f, when);
4110 cancel: function() {
4111 if (this.interval) {
4120 Y.Lang.later = Y.later;
4124 }, '3.3.0' ,{requires:['yui-base']});
4125 YUI.add('yui-throttle', function(Y) {
4128 * Provides a throttle/limiter for function calls
4130 * @submodule yui-throttle
4133 /*! Based on work by Simon Willison: http://gist.github.com/292562 */
4135 * Throttles a call to a method based on the time between calls.
4138 * @param fn {function} The function call to throttle.
4139 * @param ms {int} The number of milliseconds to throttle the method call.
4140 * Can set globally with Y.config.throttleTime or by call. Passing a -1 will
4141 * disable the throttle. Defaults to 150.
4142 * @return {function} Returns a wrapped function that calls fn throttled.
4145 Y.throttle = function(fn, ms) {
4146 ms = (ms) ? ms : (Y.config.throttleTime || 150);
4149 return (function() {
4150 fn.apply(null, arguments);
4154 var last = Y.Lang.now();
4156 return (function() {
4157 var now = Y.Lang.now();
4158 if (now - last > ms) {
4160 fn.apply(null, arguments);
4166 }, '3.3.0' ,{requires:['yui-base']});
4169 YUI.add('yui', function(Y){}, '3.3.0' ,{use:['yui-base','get','features','rls','intl-base','yui-log','yui-later','yui-throttle']});