1/** 2The YUI module contains the components required for building the YUI seed file. 3This includes the script loading mechanism, a simple queue, and the core 4utilities for the library. 5 6@module yui 7@main yui 8@submodule yui-base 9**/ 10 11/*jshint eqeqeq: false*/ 12if (typeof YUI != 'undefined') { 13 YUI._YUI = YUI; 14} 15 16/** 17The YUI global namespace object. This is the constructor for all YUI instances. 18 19This is a self-instantiable factory function, meaning you don't need to precede 20it with the `new` operator. You can invoke it directly like this: 21 22 YUI().use('*', function (Y) { 23 // Y is a new YUI instance. 24 }); 25 26But it also works like this: 27 28 var Y = YUI(); 29 30The `YUI` constructor accepts an optional config object, like this: 31 32 YUI({ 33 debug: true, 34 combine: false 35 }).use('node', function (Y) { 36 // Y.Node is ready to use. 37 }); 38 39See the API docs for the <a href="config.html">Config</a> class for the complete 40list of supported configuration properties accepted by the YUI constuctor. 41 42If a global `YUI` object is already defined, the existing YUI object will not be 43overwritten, to ensure that defined namespaces are preserved. 44 45Each YUI instance has full custom event support, but only if the event system is 46available. 47 48@class YUI 49@uses EventTarget 50@constructor 51@global 52@param {Object} [config]* Zero or more optional configuration objects. Config 53 values are stored in the `Y.config` property. See the 54 <a href="config.html">Config</a> docs for the list of supported properties. 55**/ 56 57 /*global YUI*/ 58 /*global YUI_config*/ 59 var YUI = function() { 60 var i = 0, 61 Y = this, 62 args = arguments, 63 l = args.length, 64 instanceOf = function(o, type) { 65 return (o && o.hasOwnProperty && (o instanceof type)); 66 }, 67 gconf = (typeof YUI_config !== 'undefined') && YUI_config; 68 69 if (!(instanceOf(Y, YUI))) { 70 Y = new YUI(); 71 } else { 72 // set up the core environment 73 Y._init(); 74 75 /** 76 Master configuration that might span multiple contexts in a non- 77 browser environment. It is applied first to all instances in all 78 contexts. 79 80 @example 81 82 YUI.GlobalConfig = { 83 filter: 'debug' 84 }; 85 86 YUI().use('node', function (Y) { 87 // debug files used here 88 }); 89 90 YUI({ 91 filter: 'min' 92 }).use('node', function (Y) { 93 // min files used here 94 }); 95 96 @property {Object} GlobalConfig 97 @global 98 @static 99 **/ 100 if (YUI.GlobalConfig) { 101 Y.applyConfig(YUI.GlobalConfig); 102 } 103 104 /** 105 Page-level config applied to all YUI instances created on the 106 current page. This is applied after `YUI.GlobalConfig` and before 107 any instance-level configuration. 108 109 @example 110 111 // Single global var to include before YUI seed file 112 YUI_config = { 113 filter: 'debug' 114 }; 115 116 YUI().use('node', function (Y) { 117 // debug files used here 118 }); 119 120 YUI({ 121 filter: 'min' 122 }).use('node', function (Y) { 123 // min files used here 124 }); 125 126 @property {Object} YUI_config 127 @global 128 **/ 129 if (gconf) { 130 Y.applyConfig(gconf); 131 } 132 133 // bind the specified additional modules for this instance 134 if (!l) { 135 Y._afterConfig(); 136 Y._setup(); 137 } 138 } 139 140 if (l) { 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. 145 for (; i < l; i++) { 146 Y.applyConfig(args[i]); 147 } 148 149 Y._afterConfig(); 150 Y._setup(); 151 } 152 153 Y.instanceOf = instanceOf; 154 155 return Y; 156 }; 157 158(function() { 159 160 var proto, prop, 161 VERSION = 'patched-v3.18.1', 162 PERIOD = '.', 163 BASE = 'http://yui.yahooapis.com/', 164 /* 165 These CSS class names can't be generated by 166 getClassName since it is not available at the 167 time they are being used. 168 */ 169 DOC_LABEL = 'yui3-js-enabled', 170 CSS_STAMP_EL = 'yui3-css-stamp', 171 NOOP = function() {}, 172 SLICE = Array.prototype.slice, 173 APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo 174 'io.xdrResponse': 1, // can call. this should 175 'SWF.eventHandler': 1 }, // be done at build time 176 hasWin = (typeof window != 'undefined'), 177 win = (hasWin) ? window : null, 178 doc = (hasWin) ? win.document : null, 179 docEl = doc && doc.documentElement, 180 docClass = docEl && docEl.className, 181 instances = {}, 182 time = new Date().getTime(), 183 add = function(el, type, fn, capture) { 184 if (el && el.addEventListener) { 185 el.addEventListener(type, fn, capture); 186 } else if (el && el.attachEvent) { 187 el.attachEvent('on' + type, fn); 188 } 189 }, 190 remove = function(el, type, fn, capture) { 191 if (el && el.removeEventListener) { 192 // this can throw an uncaught exception in FF 193 try { 194 el.removeEventListener(type, fn, capture); 195 } catch (ex) {} 196 } else if (el && el.detachEvent) { 197 el.detachEvent('on' + type, fn); 198 } 199 }, 200 handleReady = function() { 201 YUI.Env.DOMReady = true; 202 if (hasWin) { 203 remove(doc, 'DOMContentLoaded', handleReady); 204 } 205 if (doc && doc.body && YUI.Env.cssStampEl && (!doc.body.contains(YUI.Env.cssStampEl))) { 206 doc.body.appendChild(YUI.Env.cssStampEl); 207 } 208 }, 209 handleLoad = function() { 210 YUI.Env.windowLoaded = true; 211 YUI.Env.DOMReady = true; 212 if (hasWin) { 213 remove(window, 'load', handleLoad); 214 } 215 }, 216 getLoader = function(Y, o) { 217 var loader = Y.Env._loader, 218 lCore = [ 'loader-base' ], 219 G_ENV = YUI.Env, 220 mods = G_ENV.mods; 221 222 if (loader) { 223 //loader._config(Y.config); 224 loader.ignoreRegistered = false;
225 loader.onEnd = null; 226 loader.data = null; 227 loader.required = []; 228 loader.loadType = null; 229 } else { 230 loader = new Y.Loader(Y.config); 231 Y.Env._loader = loader; 232 } 233 if (mods && mods.loader) { 234 lCore = [].concat(lCore, YUI.Env.loaderExtras); 235 } 236 YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore)); 237 238 return loader; 239 }, 240 241 clobber = function(r, s) { 242 for (var i in s) { 243 if (s.hasOwnProperty(i)) { 244 r[i] = s[i]; 245 } 246 } 247 }, 248 249 ALREADY_DONE = { success: true }; 250 251// Stamp the documentElement (HTML) with a class of "yui-loaded" to 252// enable styles that need to key off of JS being enabled. 253if (docEl && docClass.indexOf(DOC_LABEL) == -1) { 254 if (docClass) { 255 docClass += ' '; 256 } 257 docClass += DOC_LABEL; 258 docEl.className = docClass; 259} 260 261if (VERSION.indexOf('@') > -1) { 262 VERSION = '3.5.0'; // dev time hack for cdn test 263} 264 265proto = { 266 /** 267 Applies a new configuration object to the config of this YUI instance. This 268 will merge new group/module definitions, and will also update the loader 269 cache if necessary. Updating `Y.config` directly will not update the cache. 270 271 @method applyConfig 272 @param {Object} o the configuration object. 273 @since 3.2.0 274 **/ 275 applyConfig: function(o) { 276 277 o = o || NOOP; 278 279 var attr, 280 name, 281 // detail, 282 config = this.config, 283 mods = config.modules, 284 groups = config.groups, 285 aliases = config.aliases, 286 loader = this.Env._loader; 287 288 for (name in o) { 289 if (o.hasOwnProperty(name)) { 290 attr = o[name]; 291 if (mods && name == 'modules') { 292 clobber(mods, attr); 293 } else if (aliases && name == 'aliases') { 294 clobber(aliases, attr); 295 } else if (groups && name == 'groups') { 296 clobber(groups, attr); 297 } else if (name == 'win') { 298 config[name] = (attr && attr.contentWindow) || attr; 299 config.doc = config[name] ? config[name].document : null; 300 } else if (name == '_yuid') { 301 // preserve the guid 302 } else { 303 config[name] = attr; 304 } 305 } 306 } 307 308 if (loader) { 309 loader._config(o); 310 } 311 312 }, 313 314 /** 315 Old way to apply a config to this instance (calls `applyConfig` under the 316 hood). 317 318 @private 319 @method _config 320 @param {Object} o The config to apply 321 **/ 322 _config: function(o) { 323 this.applyConfig(o); 324 }, 325 326 /** 327 Initializes this YUI instance. 328 329 @private 330 @method _init 331 **/ 332 _init: function() { 333 var filter, el, 334 Y = this, 335 G_ENV = YUI.Env, 336 Env = Y.Env, 337 prop; 338 339 /** 340 The version number of this YUI instance. 341 342 This value is typically updated by a script when a YUI release is built, 343 so it may not reflect the correct version number when YUI is run from 344 the development source tree. 345 346 @property {String} version 347 **/ 348 Y.version = VERSION; 349 350 if (!Env) { 351 Y.Env = { 352 core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3'], 353 loaderExtras: ['loader-rollup', 'loader-yui3'], 354 mods: {}, // flat module map 355 versions: {}, // version module map 356 base: BASE, 357 cdn: BASE + VERSION + '/', 358 // bootstrapped: false, 359 _idx: 0, 360 _used: {}, 361 _attached: {}, 362 _exported: {}, 363 _missed: [], 364 _yidx: 0, 365 _uidx: 0, 366 _guidp: 'y', 367 _loaded: {}, 368 // serviced: {},
369 // Regex in English: 370 // I'll start at the \b(yui). 371 // 1. Look in the test string for "yui" or 372 // "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break. That is, it 373 // can't match "foyui" or "i_heart_yui". This can be anywhere in the string. 374 // 2. After #1 must come a forward slash followed by the string matched in #1, so 375 // "yui-base/yui-base" or "yui-pants/yui-pants". 376 // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min", 377 // so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt". 378 // 4. This is followed by ".js", so "yui/yui.js". 379 // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string, 380 // then capture the junk between the LAST "&" and the string in 1-4. So 381 // "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js" 382 // will capture "3.3.0/build/" 383 // 384 // Regex Exploded: 385 // (?:\? Find a ? 386 // (?:[^&]*&) followed by 0..n characters followed by an & 387 // * in fact, find as many sets of characters followed by a & as you can 388 // ([^&]*) capture the stuff after the last & in \1 389 // )? but it's ok if all this ?junk&more_junk stuff isn't even there 390 // \b( after a word break find either the string 391 // yui(?:-\w+)? "yui" optionally followed by a -, then more characters 392 // ) and store the yui-* string in \2 393 // \/\2 then comes a / followed by the yui-* string in \2 394 // (?:-(min|debug))? optionally followed by "-min" or "-debug" 395 // .js and ending in ".js" 396 _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(aui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/, 397 parseBasePath: function(src, pattern) { 398 var match = src.match(pattern), 399 path, filter; 400 401 if (match) { 402 path = RegExp.leftContext || src.slice(0, src.indexOf(match[0])); 403 404 // this is to set up the path to the loader. The file 405 // filter for loader should match the yui include. 406 filter = match[3]; 407 408 // extract correct path for mixed combo urls 409 // http://yuilibrary.com/projects/yui3/ticket/2528423 410 if (match[1]) { 411 path += '?' + match[1]; 412 } 413 path = { 414 filter: filter, 415 path: path 416 }; 417 } 418 return path; 419 }, 420 getBase: G_ENV && G_ENV.getBase || 421 function(pattern) { 422 var nodes = (doc && doc.getElementsByTagName('script')) || [], 423 path = Env.cdn, parsed, 424 i, len, src; 425 426 for (i = 0, len = nodes.length; i < len; ++i) { 427 src = nodes[i].src; 428 if (src) { 429 parsed = Y.Env.parseBasePath(src, pattern); 430 if (parsed) { 431 filter = parsed.filter; 432 path = parsed.path; 433 break; 434 } 435 } 436 } 437 438 // use CDN default 439 return path; 440 } 441 442 }; 443 444 Env = Y.Env; 445 446 Env._loaded[VERSION] = {}; 447 448 if (G_ENV && Y !== YUI) { 449 Env._yidx = ++G_ENV._yidx; 450 Env._guidp = ('yui_' + VERSION + '_' + 451 Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_'); 452 } else if (YUI._YUI) { 453 454 G_ENV = YUI._YUI.Env; 455 Env._yidx += G_ENV._yidx; 456 Env._uidx += G_ENV._uidx; 457 458 for (prop in G_ENV) {
459 if (!(prop in Env)) { 460 Env[prop] = G_ENV[prop]; 461 } 462 } 463 464 delete YUI._YUI; 465 } 466 467 Y.id = Y.stamp(Y); 468 instances[Y.id] = Y; 469 470 } 471 472 Y.constructor = YUI; 473 474 // configuration defaults 475 Y.config = Y.config || { 476 bootstrap: true, 477 cacheUse: true, 478 debug: true, 479 doc: doc, 480 fetchCSS: true, 481 throwFail: true, 482 useBrowserConsole: true, 483 useNativeES5: true, 484 win: win 485 }; 486 487 //Register the CSS stamp element 488 if (doc && !doc.getElementById(CSS_STAMP_EL)) { 489 el = doc.createElement('div'); 490 el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>'; 491 YUI.Env.cssStampEl = el.firstChild; 492 if (doc.body) { 493 doc.body.appendChild(YUI.Env.cssStampEl); 494 } else { 495 docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild); 496 } 497 } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) { 498 YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL); 499 } 500 501 Y.config.lang = Y.config.lang || 'en-US'; 502 503 Y.config.base = YUI.config.base || 504 (YUI.config.defaultBase && YUI.config.root && YUI.config.defaultBase + YUI.config.root) || 505 Y.Env.getBase(Y.Env._BASE_RE); 506 507 if (!filter || (!('mindebug').indexOf(filter))) { 508 filter = 'min'; 509 } 510 filter = (filter) ? '-' + filter : filter; 511 Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js'; 512 513 }, 514 515 /** 516 This method is called after all other configuration has been applied to 517 the YUI instance. 518 519 @method _afterConfig 520 @private 521 **/ 522 _afterConfig: function () { 523 var Y = this; 524 525 // We need to set up Y.config.global after the rest of the configuration 526 // so that setting it in user configuration prevents the library from 527 // using eval(). This is critical for Content Security Policy enabled 528 // sites and other environments like Chrome extensions 529 if (!Y.config.hasOwnProperty('global')) { 530 Y.config.global = Function('return this')(); 531 } 532 }, 533 534 /** 535 Finishes the instance setup. Attaches whatever YUI modules were defined 536 at the time that this instance was created. 537 538 @method _setup 539 @private 540 **/ 541 _setup: function() { 542 var i, Y = this, 543 core = [], 544 mods = YUI.Env.mods, 545 extendedCore = Y.config.extendedCore || [], 546 extras = Y.config.core || [].concat(YUI.Env.core).concat(extendedCore); //Clone it.. 547 548 for (i = 0; i < extras.length; i++) { 549 if (mods[extras[i]]) { 550 core.push(extras[i]); 551 } 552 } 553 554 Y._attach(['yui-base']); 555 Y._attach(core); 556 557 if (Y.Loader) { 558 getLoader(Y); 559 } 560 561 }, 562 563 /** 564 Executes the named method on the specified YUI instance if that method is 565 whitelisted. 566 567 @method applyTo 568 @param {String} id YUI instance id. 569 @param {String} method Name of the method to execute. For example: 570 'Object.keys'. 571 @param {Array} args Arguments to apply to the method. 572 @return {Mixed} Return value from the applied method, or `null` if the 573 specified instance was not found or the method was not whitelisted. 574 **/ 575 applyTo: function(id, method, args) { 576 if (!(method in APPLY_TO_AUTH)) { 577 this.log(method + ': applyTo not allowed', 'warn', 'yui'); 578 return null; 579 } 580 581 var instance = instances[id], nest, m, i; 582 if (instance) { 583 nest = method.split('.'); 584 m = instance; 585 for (i = 0; i < nest.length; i = i + 1) { 586 m = m[nest[i]]; 587 if (!m) { 588 this.log('applyTo not found: ' + method, 'warn', 'yui'); 589 } 590 } 591 return m && m.apply(instance, args); 592 } 593 594 return null; 595 }, 596 597/** 598Registers a YUI module and makes it available for use in a `YUI().use()` call or 599as a dependency for other modules. 600 601The easiest way to create a first-class YUI module is to use 602<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build 603tool. 604 605Shifter will automatically wrap your module code in a `YUI.add()` call along 606with any configuration info required for the module. 607 608@example 609 610 YUI.add('davglass', function (Y) { 611 Y.davglass = function () { 612 }; 613 }, '3.4.0', { 614 requires: ['harley-davidson', 'mt-dew'] 615 }); 616 617@method add 618@param {String} name Module name. 619@param {Function} fn Function containing module code. This function will be 620 executed whenever the module is attached to a specific YUI instance. 621 622 @param {YUI} fn.Y The YUI instance to which this module is attached.
623 @param {String} fn.name Name of the module 624 625@param {String} version Module version number. This is currently used only for 626 informational purposes, and is not used internally by YUI. 627 628@param {Object} [details] Module config. 629 @param {Array} [details.requires] Array of other module names that must be 630 attached before this module can be attached. 631 @param {Array} [details.optional] Array of optional module names that should 632 be attached before this module is attached if they've already been 633 loaded. If the `loadOptional` YUI option is `true`, optional modules 634 that have not yet been loaded will be loaded just as if they were hard 635 requirements. 636 @param {Array} [details.use] Array of module names that are included within 637 or otherwise provided by this module, and which should be attached 638 automatically when this module is attached. This makes it possible to 639 create "virtual rollup" modules that simply attach a collection of other 640 modules or submodules. 641 642@return {YUI} This YUI instance. 643**/ 644 add: function(name, fn, version, details) { 645 details = details || {}; 646 var env = YUI.Env, 647 mod = { 648 name: name, 649 fn: fn, 650 version: version, 651 details: details 652 }, 653 //Instance hash so we don't apply it to the same instance twice 654 applied = {}, 655 loader, inst, modInfo, 656 i, versions = env.versions; 657 658 env.mods[name] = mod; 659 versions[version] = versions[version] || {}; 660 versions[version][name] = mod; 661 662 for (i in instances) { 663 if (instances.hasOwnProperty(i)) { 664 inst = instances[i]; 665 if (!applied[inst.id]) { 666 applied[inst.id] = true; 667 loader = inst.Env._loader; 668 if (loader) { 669 modInfo = loader.getModuleInfo(name); 670 if (!modInfo || modInfo.temp) { 671 loader.addModule(details, name); 672 } 673 } 674 } 675 } 676 } 677 678 return this; 679 }, 680 681 /** 682 Executes the callback function associated with each required module, 683 attaching the module to this YUI instance. 684 685 @method _attach 686 @param {Array} r The array of modules to attach 687 @param {Boolean} [moot=false] If `true`, don't throw a warning if the module 688 is not attached. 689 @private 690 **/ 691 _attach: function(r, moot) { 692 var i, name, mod, details, req, use, after, 693 mods = YUI.Env.mods, 694 aliases = YUI.Env.aliases, 695 Y = this, j, 696 cache = YUI.Env._renderedMods, 697 loader = Y.Env._loader, 698 done = Y.Env._attached, 699 exported = Y.Env._exported, 700 len = r.length, loader, def, go, 701 c = [], 702 modArgs, esCompat, reqlen, modInfo, 703 condition, 704 __exports__, __imports__; 705 706 //Check for conditional modules (in a second+ instance) and add their requirements 707 //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass 708 for (i = 0; i < len; i++) { 709 name = r[i]; 710 mod = mods[name]; 711 c.push(name); 712 if (loader && loader.conditions[name]) { 713 for (j in loader.conditions[name]) { 714 if (loader.conditions[name].hasOwnProperty(j)) { 715 def = loader.conditions[name][j]; 716 go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y))); 717 if (go) { 718 c.push(def.name); 719 } 720 } 721 } 722 } 723 } 724 r = c; 725 len = r.length; 726 727 for (i = 0; i < len; i++) { 728 if (!done[r[i]]) { 729 name = r[i]; 730 mod = mods[name]; 731 732 if (aliases && aliases[name] && !mod) { 733 Y._attach(aliases[name]); 734 continue; 735 } 736 if (!mod) { 737 modInfo = loader && loader.getModuleInfo(name); 738 if (modInfo) { 739 mod = modInfo; 740 moot = true; 741 } 742 743 744 //if (!loader || !loader.moduleInfo[name]) { 745 //if ((!loader || !loader.moduleInfo[name]) && !moot) { 746 if (!moot && name) { 747 if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) { 748 Y.Env._missed.push(name); 749 Y.Env._missed = Y.Array.dedupe(Y.Env._missed); 750 Y.message('NOT loaded: ' + name, 'warn', 'yui'); 751 } 752 } 753 } else { 754 done[name] = true; 755 //Don't like this, but in case a mod was asked for once, then we fetch it 756 //We need to remove it from the missed list ^davglass 757 for (j = 0; j < Y.Env._missed.length; j++) { 758 if (Y.Env._missed[j] === name) {
759 Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui'); 760 Y.Env._missed.splice(j, 1); 761 } 762 } 763 764 // Optional dependencies normally work by modifying the 765 // dependency list of a module. If the dependency's test 766 // passes it is added to the list. If not, it's not loaded. 767 // This following check ensures that optional dependencies 768 // are not attached when they were already loaded into the 769 // page (when bundling for example) 770 if (loader && !loader._canBeAttached(name)) { 771 return true; 772 } 773 774 /* 775 If it's a temp module, we need to redo it's requirements if it's already loaded 776 since it may have been loaded by another instance and it's dependencies might 777 have been redefined inside the fetched file. 778 */ 779 if (loader && cache && cache[name] && cache[name].temp) { 780 loader.getRequires(cache[name]); 781 req = []; 782 modInfo = loader.getModuleInfo(name); 783 for (j in modInfo.expanded_map) { 784 if (modInfo.expanded_map.hasOwnProperty(j)) { 785 req.push(j); 786 } 787 } 788 Y._attach(req); 789 } 790 791 details = mod.details; 792 req = details.requires; 793 esCompat = details.es; 794 use = details.use; 795 after = details.after; 796 //Force Intl load if there is a language (Loader logic) @todo fix this shit 797 if (details.lang) { 798 req = req || []; 799 req.unshift('intl'); 800 } 801 802 if (req) { 803 reqlen = req.length; 804 for (j = 0; j < reqlen; j++) { 805 if (!done[req[j]]) { 806 if (!Y._attach(req)) { 807 return false; 808 } 809 break; 810 } 811 } 812 } 813 814 if (after) { 815 for (j = 0; j < after.length; j++) { 816 if (!done[after[j]]) { 817 if (!Y._attach(after, true)) { 818 return false; 819 } 820 break; 821 } 822 } 823 } 824 825 if (mod.fn) { 826 modArgs = [Y, name]; 827 if (esCompat) { 828 __imports__ = {}; 829 __exports__ = {}; 830 // passing `exports` and `imports` onto the module function 831 modArgs.push(__imports__, __exports__); 832 if (req) { 833 reqlen = req.length; 834 for (j = 0; j < reqlen; j++) { 835 __imports__[req[j]] = exported.hasOwnProperty(req[j]) ? exported[req[j]] : Y; 836 } 837 } 838 } 839 if (Y.config.throwFail) { 840 __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs); 841 } else { 842 try { 843 __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs); 844 } catch (e) { 845 Y.error('Attach error: ' + name, e, name); 846 return false;
847 } 848 } 849 if (esCompat) { 850 // store the `exports` in case others `es` modules requires it 851 exported[name] = __exports__; 852 853 // If an ES module is conditionally loaded and set 854 // to be used "instead" another module, replace the 855 // trigger module's content with the conditionally 856 // loaded one so the values returned by require() 857 // still makes sense 858 condition = mod.details.condition; 859 if (condition && condition.when === 'instead') { 860 exported[condition.trigger] = __exports__; 861 } 862 } 863 } 864 865 if (use) { 866 for (j = 0; j < use.length; j++) { 867 if (!done[use[j]]) { 868 if (!Y._attach(use)) { 869 return false; 870 } 871 break; 872 } 873 } 874 } 875 876 877 878 } 879 } 880 } 881 882 return true; 883 }, 884 885 /** 886 Delays the `use` callback until another event has taken place such as 887 `window.onload`, `domready`, `contentready`, or `available`. 888 889 @private 890 @method _delayCallback 891 @param {Function} cb The original `use` callback. 892 @param {String|Object} until Either an event name ('load', 'domready', etc.) 893 or an object containing event/args keys for contentready/available. 894 @return {Function} 895 **/ 896 _delayCallback: function(cb, until) { 897 898 var Y = this, 899 mod = ['event-base']; 900 901 until = (Y.Lang.isObject(until) ? until : { event: until }); 902 903 if (until.event === 'load') { 904 mod.push('event-synthetic'); 905 } 906 907 return function() { 908 var args = arguments; 909 Y._use(mod, function() { 910 Y.on(until.event, function() { 911 args[1].delayUntil = until.event; 912 cb.apply(Y, args); 913 }, until.args); 914 }); 915 }; 916 }, 917 918 /** 919 Attaches one or more modules to this YUI instance. When this is executed, 920 the requirements of the desired modules are analyzed, and one of several 921 things can happen: 922 923 924 * All required modules have already been loaded, and just need to be 925 attached to this YUI instance. In this case, the `use()` callback will 926 be executed synchronously after the modules are attached. 927 928 * One or more modules have not yet been loaded, or the Get utility is not 929 available, or the `bootstrap` config option is `false`. In this case, 930 a warning is issued indicating that modules are missing, but all 931 available modules will still be attached and the `use()` callback will 932 be executed synchronously. 933 934 * One or more modules are missing and the Loader is not available but the 935 Get utility is, and `bootstrap` is not `false`. In this case, the Get 936 utility will be used to load the Loader, and we will then proceed to 937 the following state: 938 939 * One or more modules are missing and the Loader is available. In this 940 case, the Loader will be used to resolve the dependency tree for the 941 missing modules and load them and their dependencies. When the Loader is 942 finished loading modules, the `use()` callback will be executed 943 asynchronously. 944 945 @example 946 947 // Loads and attaches dd and its dependencies. 948 YUI().use('dd', function (Y) { 949 // ... 950 }); 951 952 // Loads and attaches dd and node as well as all of their dependencies. 953 YUI().use(['dd', 'node'], function (Y) { 954 // ... 955 }); 956 957 // Attaches all modules that have already been loaded. 958 YUI().use('*', function (Y) { 959 // ... 960 }); 961 962 // Attaches a gallery module. 963 YUI().use('gallery-yql', function (Y) { 964 // ... 965 }); 966 967 // Attaches a YUI 2in3 module. 968 YUI().use('yui2-datatable', function (Y) { 969 // ... 970 }); 971 972 @method use 973 @param {String|Array} modules* One or more module names to attach. 974 @param {Function} [callback] Callback function to be executed once all 975 specified modules and their dependencies have been attached.
976 @param {YUI} callback.Y The YUI instance created for this sandbox. 977 @param {Object} callback.status Object containing `success`, `msg` and 978 `data` properties. 979 @chainable 980 **/ 981 use: function() { 982 var args = SLICE.call(arguments, 0), 983 callback = args[args.length - 1], 984 Y = this, 985 i = 0, 986 name, 987 Env = Y.Env, 988 provisioned = true; 989 990 // The last argument supplied to use can be a load complete callback 991 if (Y.Lang.isFunction(callback)) { 992 args.pop(); 993 if (Y.config.delayUntil) { 994 callback = Y._delayCallback(callback, Y.config.delayUntil); 995 } 996 } else { 997 callback = null; 998 } 999 if (Y.Lang.isArray(args[0])) { 1000 args = args[0]; 1001 } 1002 1003 if (Y.config.cacheUse) { 1004 while ((name = args[i++])) { 1005 if (!Env._attached[name]) { 1006 provisioned = false; 1007 break; 1008 } 1009 } 1010 1011 if (provisioned) { 1012 if (args.length) { 1013 } 1014 Y._notify(callback, ALREADY_DONE, args); 1015 return Y; 1016 } 1017 } 1018 1019 if (Y._loading) { 1020 Y._useQueue = Y._useQueue || new Y.Queue(); 1021 Y._useQueue.add([args, callback]); 1022 } else { 1023 Y._use(args, function(Y, response) { 1024 Y._notify(callback, response, args); 1025 }); 1026 } 1027 1028 return Y; 1029 }, 1030 1031 /** 1032 Sugar for loading both legacy and ES6-based YUI modules. 1033 1034 @method require 1035 @param {String} [modules*] List of module names to import or a single 1036 module name. 1037 @param {Function} callback Callback that gets called once all the modules 1038 were loaded. Each parameter of the callback is the export value of the 1039 corresponding module in the list. If the module is a legacy YUI module, 1040 the YUI instance is used instead of the module exports. 1041 @example 1042 ``` 1043 YUI().require(['es6-set'], function (Y, imports) { 1044 var Set = imports.Set, 1045 set = new Set(); 1046 }); 1047 ``` 1048 **/ 1049 require: function () { 1050 var args = SLICE.call(arguments), 1051 callback; 1052 1053 if (typeof args[args.length - 1] === 'function') { 1054 callback = args.pop(); 1055 1056 // only add the callback if one was provided 1057 // YUI().require('foo'); is valid 1058 args.push(function (Y) { 1059 var i, length = args.length, 1060 exported = Y.Env._exported, 1061 __imports__ = {}; 1062 1063 // Get only the imports requested as arguments 1064 for (i = 0; i < length; i++) { 1065 if (exported.hasOwnProperty(args[i])) { 1066 __imports__[args[i]] = exported[args[i]]; 1067 } 1068 } 1069 1070 // Using `undefined` because: 1071 // - Using `Y.config.global` would force the value of `this` to be 1072 // the global object even in strict mode 1073 // - Using `Y` goes against the goal of moving away from a shared 1074 // object and start thinking in terms of imported and exported 1075 // objects 1076 callback.call(undefined, Y, __imports__); 1077 }); 1078 } 1079 // Do not return the Y object. This makes it hard to follow this 1080 // traditional pattern: 1081 // var Y = YUI().use(...); 1082 // This is a good idea in the light of ES6 modules, to avoid working 1083 // in the global scope. 1084 // This also leaves the door open for returning a promise, once the 1085 // YUI loader is based on the ES6 loader which uses 1086 // loader.import(...).then(...) 1087 this.use.apply(this, args); 1088 }, 1089 1090 /** 1091 Handles Loader notifications about attachment/load errors. 1092 1093 @method _notify 1094 @param {Function} callback Callback to pass to `Y.config.loadErrorFn`. 1095 @param {Object} response Response returned from Loader. 1096 @param {Array} args Arguments passed from Loader. 1097 @private 1098 **/ 1099 _notify: function(callback, response, args) { 1100 if (!response.success && this.config.loadErrorFn) { 1101 this.config.loadErrorFn.call(this, this, callback, response, args); 1102 } else if (callback) { 1103 if (this.Env._missed && this.Env._missed.length) { 1104 response.msg = 'Missing modules: ' + this.Env._missed.join(); 1105 response.success = false;
1106 } 1107 if (this.config.throwFail) { 1108 callback(this, response); 1109 } else { 1110 try { 1111 callback(this, response); 1112 } catch (e) { 1113 this.error('use callback error', e, args); 1114 } 1115 } 1116 } 1117 }, 1118 1119 /** 1120 Called from the `use` method queue to ensure that only one set of loading 1121 logic is performed at a time. 1122 1123 @method _use 1124 @param {String} args* One or more modules to attach. 1125 @param {Function} [callback] Function to call once all required modules have 1126 been attached. 1127 @private 1128 **/ 1129 _use: function(args, callback) { 1130 1131 if (!this.Array) { 1132 this._attach(['yui-base']); 1133 } 1134 1135 var len, loader, handleBoot, 1136 Y = this, 1137 G_ENV = YUI.Env, 1138 mods = G_ENV.mods, 1139 Env = Y.Env, 1140 used = Env._used, 1141 aliases = G_ENV.aliases, 1142 queue = G_ENV._loaderQueue, 1143 firstArg = args[0], 1144 YArray = Y.Array, 1145 config = Y.config, 1146 boot = config.bootstrap, 1147 missing = [], 1148 i, 1149 r = [], 1150 ret = true, 1151 fetchCSS = config.fetchCSS, 1152 process = function(names, skip) { 1153 1154 var i = 0, a = [], name, len, m, req, use; 1155 1156 if (!names.length) { 1157 return; 1158 } 1159 1160 if (aliases) { 1161 len = names.length; 1162 for (i = 0; i < len; i++) { 1163 if (aliases[names[i]] && !mods[names[i]]) { 1164 a = [].concat(a, aliases[names[i]]); 1165 } else { 1166 a.push(names[i]); 1167 } 1168 } 1169 names = a; 1170 } 1171 1172 len = names.length; 1173 1174 for (i = 0; i < len; i++) { 1175 name = names[i]; 1176 if (!skip) { 1177 r.push(name); 1178 } 1179 1180 // only attach a module once 1181 if (used[name]) { 1182 continue; 1183 } 1184 1185 m = mods[name]; 1186 req = null; 1187 use = null; 1188 1189 if (m) { 1190 used[name] = true; 1191 req = m.details.requires; 1192 use = m.details.use; 1193 } else { 1194 // CSS files don't register themselves, see if it has 1195 // been loaded 1196 if (!G_ENV._loaded[VERSION][name]) { 1197 missing.push(name); 1198 } else { 1199 used[name] = true; // probably css 1200 } 1201 } 1202 1203 // make sure requirements are attached 1204 if (req && req.length) { 1205 process(req); 1206 } 1207 1208 // make sure we grab the submodule dependencies too 1209 if (use && use.length) { 1210 process(use, 1); 1211 } 1212 } 1213 1214 }, 1215 1216 handleLoader = function(fromLoader) { 1217 var response = fromLoader || { 1218 success: true, 1219 msg: 'not dynamic' 1220 }, 1221 redo, origMissing, 1222 ret = true, 1223 data = response.data; 1224 1225 Y._loading = false; 1226 1227 if (data) { 1228 origMissing = missing; 1229 missing = []; 1230 r = []; 1231 process(data); 1232 redo = missing.length; 1233 if (redo) { 1234 if ([].concat(missing).sort().join() == 1235 origMissing.sort().join()) { 1236 redo = false; 1237 } 1238 } 1239 } 1240 1241 if (redo && data) { 1242 Y._loading = true; 1243 Y._use(missing, function() { 1244 if (Y._attach(data)) { 1245 Y._notify(callback, response, data); 1246 } 1247 }); 1248 } else { 1249 if (data) { 1250 ret = Y._attach(data); 1251 } 1252 if (ret) { 1253 Y._notify(callback, response, args); 1254 } 1255 } 1256 1257 if (Y._useQueue && Y._useQueue.size() && !Y._loading) { 1258 Y._use.apply(Y, Y._useQueue.next()); 1259 } 1260 1261 }; 1262 1263 1264 // YUI().use('*'); // bind everything available 1265 if (firstArg === '*') { 1266 args = []; 1267 for (i in mods) { 1268 if (mods.hasOwnProperty(i)) { 1269 args.push(i); 1270 } 1271 } 1272 ret = Y._attach(args); 1273 if (ret) { 1274 handleLoader(); 1275 } 1276 return Y; 1277 } 1278 1279 if ((mods.loader || mods['loader-base']) && !Y.Loader) { 1280 Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]); 1281 } 1282 1283 1284 // use loader to expand dependencies and sort the 1285 // requirements if it is available.
1286 if (boot && Y.Loader && args.length) { 1287 loader = getLoader(Y); 1288 loader.require(args); 1289 loader.ignoreRegistered = true; 1290 loader._boot = true; 1291 loader.calculate(null, (fetchCSS) ? null : 'js'); 1292 args = loader.sorted; 1293 loader._boot = false; 1294 } 1295 1296 process(args); 1297 1298 len = missing.length; 1299 1300 1301 if (len) { 1302 missing = YArray.dedupe(missing); 1303 len = missing.length; 1304 } 1305 1306 1307 // dynamic load 1308 if (boot && len && Y.Loader) { 1309 Y._loading = true; 1310 loader = getLoader(Y); 1311 loader.onEnd = handleLoader; 1312 loader.context = Y; 1313 loader.data = args; 1314 loader.ignoreRegistered = false; 1315 loader.require(missing); 1316 loader.insert(null, (fetchCSS) ? null : 'js'); 1317 1318 } else if (boot && len && Y.Get && !Env.bootstrapped) { 1319 1320 Y._loading = true; 1321 1322 handleBoot = function() { 1323 Y._loading = false; 1324 queue.running = false; 1325 Env.bootstrapped = true; 1326 G_ENV._bootstrapping = false; 1327 if (Y._attach(['loader'])) { 1328 Y._use(args, callback); 1329 } 1330 }; 1331 1332 if (G_ENV._bootstrapping) { 1333 queue.add(handleBoot); 1334 } else { 1335 G_ENV._bootstrapping = true; 1336 Y.Get.script(config.base + config.loaderPath, { 1337 onEnd: handleBoot 1338 }); 1339 } 1340 1341 } else { 1342 ret = Y._attach(args); 1343 if (ret) { 1344 handleLoader(); 1345 } 1346 } 1347 1348 return Y; 1349 }, 1350 1351 1352 /** 1353 Utility method for safely creating namespaces if they don't already exist. 1354 May be called statically on the YUI global object or as a method on a YUI 1355 instance. 1356 1357 When called statically, a namespace will be created on the YUI global 1358 object: 1359 1360 // Create `YUI.your.namespace.here` as nested objects, preserving any 1361 // objects that already exist instead of overwriting them. 1362 YUI.namespace('your.namespace.here'); 1363 1364 When called as a method on a YUI instance, a namespace will be created on 1365 that instance: 1366 1367 // Creates `Y.property.package`. 1368 Y.namespace('property.package'); 1369 1370 Dots in the input string cause `namespace` to create nested objects for each 1371 token. If any part of the requested namespace already exists, the current 1372 object will be left in place and will not be overwritten. This allows 1373 multiple calls to `namespace` to preserve existing namespaced properties. 1374 1375 If the first token in the namespace string is "YAHOO", that token is 1376 discarded. This is legacy behavior for backwards compatibility with YUI 2. 1377 1378 Be careful with namespace tokens. Reserved words may work in some browsers 1379 and not others. For instance, the following will fail in some browsers 1380 because the supported version of JavaScript reserves the word "long": 1381 1382 Y.namespace('really.long.nested.namespace'); 1383 1384 Note: If you pass multiple arguments to create multiple namespaces, only the 1385 last one created is returned from this function. 1386
1387 @method namespace 1388 @param {String} namespace* One or more namespaces to create. 1389 @return {Object} Reference to the last namespace object created. 1390 **/ 1391 namespace: function() { 1392 var a = arguments, o, i = 0, j, d, arg; 1393 1394 for (; i < a.length; i++) { 1395 o = this; //Reset base object per argument or it will get reused from the last 1396 arg = a[i]; 1397 if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present 1398 d = arg.split(PERIOD); 1399 for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) { 1400 o[d[j]] = o[d[j]] || {}; 1401 o = o[d[j]]; 1402 } 1403 } else { 1404 o[arg] = o[arg] || {}; 1405 o = o[arg]; //Reset base object to the new object so it's returned 1406 } 1407 } 1408 return o; 1409 }, 1410 1411 // this is replaced if the log module is included 1412 log: NOOP, 1413 message: NOOP, 1414 // this is replaced if the dump module is included 1415 dump: function (o) { return ''+o; }, 1416 1417 /** 1418 Reports an error. 1419 1420 The reporting mechanism is controlled by the `throwFail` configuration 1421 attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is 1422 truthy, a JS exception is thrown. 1423 1424 If an `errorFn` is specified in the config it must return `true` to indicate 1425 that the exception was handled and keep it from being thrown. 1426 1427 @method error 1428 @param {String} msg Error message. 1429 @param {Error|String} [e] JavaScript error object or an error string. 1430 @param {String} [src] Source of the error (such as the name of the module in 1431 which the error occurred). 1432 @chainable 1433 **/ 1434 error: function(msg, e, src) { 1435 //TODO Add check for window.onerror here 1436 1437 var Y = this, ret; 1438 1439 if (Y.config.errorFn) { 1440 ret = Y.config.errorFn.apply(Y, arguments); 1441 } 1442 1443 if (!ret) { 1444 throw (e || new Error(msg)); 1445 } else { 1446 Y.message(msg, 'error', ''+src); // don't scrub this one 1447 } 1448 1449 return Y; 1450 }, 1451 1452 /** 1453 Generates an id string that is unique among all YUI instances in this 1454 execution context. 1455 1456 @method guid 1457 @param {String} [pre] Prefix. 1458 @return {String} Unique id. 1459 **/ 1460 guid: function(pre) { 1461 var id = this.Env._guidp + '_' + (++this.Env._uidx); 1462 return (pre) ? (pre + id) : id; 1463 }, 1464 1465 /** 1466 Returns a unique id associated with the given object and (if *readOnly* is 1467 falsy) stamps the object with that id so it can be identified in the future. 1468 1469 Stamping an object involves adding a `_yuid` property to it that contains 1470 the object's id. One exception to this is that in Internet Explorer, DOM 1471 nodes have a `uniqueID` property that contains a browser-generated unique 1472 id, which will be used instead of a YUI-generated id when available. 1473 1474 @method stamp 1475 @param {Object} o Object to stamp. 1476 @param {Boolean} readOnly If truthy and the given object has not already 1477 been stamped, the object will not be modified and `null` will be 1478 returned. 1479 @return {String} Object's unique id, or `null` if *readOnly* was truthy and 1480 the given object was not already stamped. 1481 **/ 1482 stamp: function(o, readOnly) { 1483 var uid; 1484 if (!o) { 1485 return o; 1486 } 1487 1488 // IE generates its own unique ID for dom nodes 1489 // The uniqueID property of a document node returns a new ID 1490 if (o.uniqueID && o.nodeType && o.nodeType !== 9) { 1491 uid = o.uniqueID; 1492 } else { 1493 uid = (typeof o === 'string') ? o : o._yuid; 1494 } 1495 1496 if (!uid) { 1497 uid = this.guid(); 1498 if (!readOnly) { 1499 try { 1500 o._yuid = uid; 1501 } catch (e) { 1502 uid = null; 1503 } 1504 } 1505 } 1506 return uid; 1507 }, 1508 1509 /** 1510 Destroys this YUI instance. 1511 1512 @method destroy 1513 @since 3.3.0 1514 **/ 1515 destroy: function() { 1516 var Y = this; 1517 if (Y.Event) { 1518 Y.Event._unload(); 1519 } 1520 delete instances[Y.id]; 1521 delete Y.Env; 1522 delete Y.config; 1523 } 1524 1525 /** 1526 Safe `instanceof` wrapper that works around a memory leak in IE when the 1527 object being tested is `window` or `document`. 1528 1529 Unless you are testing objects that may be `window` or `document`, you 1530 should use the native `instanceof` operator instead of this method. 1531 1532 @method instanceOf 1533 @param {Object} o Object to check. 1534 @param {Object} type Class to check against. 1535 @since 3.3.0 1536 **/ 1537}; 1538 1539 YUI.prototype = proto; 1540 1541 // inheritance utilities are not available yet 1542 for (prop in proto) { 1543 if (proto.hasOwnProperty(prop)) { 1544 YUI[prop] = proto[prop]; 1545 } 1546 } 1547 1548 /** 1549 Applies a configuration to all YUI instances in this execution context. 1550 1551 The main use case for this method is in "mashups" where several third-party 1552 scripts need to write to a global YUI config, but cannot share a single 1553 centrally-managed config object. This way they can all call 1554 `YUI.applyConfig({})` instead of overwriting the single global config. 1555 1556 @example 1557 1558 YUI.applyConfig({ 1559 modules: { 1560 davglass: { 1561 fullpath: './davglass.js' 1562 } 1563 } 1564 }); 1565 1566 YUI.applyConfig({ 1567 modules: { 1568 foo: { 1569 fullpath: './foo.js' 1570 } 1571 } 1572 }); 1573 1574 YUI().use('davglass', function (Y) { 1575 // Module davglass will be available here. 1576 }); 1577 1578 @method applyConfig 1579 @param {Object} o Configuration object to apply. 1580 @static 1581 @since 3.5.0 1582 **/ 1583 YUI.applyConfig = function(o) { 1584 if (!o) { 1585 return; 1586 } 1587 //If there is a GlobalConfig, apply it first to set the defaults 1588 if (YUI.GlobalConfig) { 1589 this.prototype.applyConfig.call(this, YUI.GlobalConfig); 1590 } 1591 //Apply this config to it 1592 this.prototype.applyConfig.call(this, o); 1593 //Reset GlobalConfig to the combined config 1594 YUI.GlobalConfig = this.config; 1595 }; 1596 1597 // set up the environment 1598 YUI._init(); 1599 1600 if (hasWin) { 1601 add(doc, 'DOMContentLoaded', handleReady); 1602 1603 // add a window load event at load time so we can capture 1604 // the case where it fires before dynamic loading is 1605 // complete. 1606 add(window, 'load', handleLoad); 1607 } else { 1608 handleReady(); 1609 handleLoad(); 1610 } 1611 1612 YUI.Env.add = add; 1613 YUI.Env.remove = remove; 1614 1615 /*global exports*/
1616 // Support the CommonJS method for exporting our single global 1617 if (typeof exports == 'object') { 1618 exports.YUI = YUI; 1619 /** 1620 * Set a method to be called when `Get.script` is called in Node.js 1621 * `Get` will open the file, then pass it's content and it's path 1622 * to this method before attaching it. Commonly used for code coverage 1623 * instrumentation. <strong>Calling this multiple times will only 1624 * attach the last hook method</strong>. This method is only 1625 * available in Node.js. 1626 * @method setLoadHook 1627 * @static 1628 * @param {Function} fn The function to set 1629 * @param {String} fn.data The content of the file 1630 * @param {String} fn.path The file path of the file 1631 */ 1632 YUI.setLoadHook = function(fn) { 1633 YUI._getLoadHook = fn; 1634 }; 1635 /** 1636 * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook` 1637 * @method _getLoadHook 1638 * @private 1639 * @param {String} data The content of the file 1640 * @param {String} path The file path of the file 1641 */ 1642 YUI._getLoadHook = null; 1643 } 1644 1645 YUI.Env[VERSION] = {}; 1646}()); 1647 1648 1649/** 1650Config object that contains all of the configuration options for 1651this `YUI` instance. 1652 1653This object is supplied by the implementer when instantiating YUI. Some 1654properties have default values if they are not supplied by the implementer. 1655 1656This object should not be updated directly because some values are cached. Use 1657`applyConfig()` to update the config object on a YUI instance that has already 1658been configured. 1659 1660@class config 1661@static 1662**/ 1663 1664/** 1665If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata 1666if they're needed to load additional dependencies and aren't already available. 1667 1668Setting this to `false` will prevent YUI from automatically loading the Loader 1669and module metadata, so you will need to manually ensure that they're available 1670or handle dependency resolution yourself. 1671 1672@property {Boolean} bootstrap 1673@default true 1674**/ 1675 1676/** 1677 1678@property {Object} filters 1679**/ 1680 1681/** 1682If `true`, YUI will use a combo handler to load multiple modules in as few 1683requests as possible. 1684 1685The YUI CDN (which YUI uses by default) supports combo handling, but other 1686servers may not. If the server from which you're loading YUI does not support 1687combo handling, set this to `false`. 1688 1689Providing a value for the `base` config property will cause `combine` to default 1690to `false` instead of `true`. 1691 1692@property {Boolean} combine 1693@default true 1694*/ 1695 1696/** 1697Array of module names that should never be dynamically loaded. 1698 1699@property {String[]} ignore 1700**/ 1701 1702/** 1703Array of module names that should always be loaded when required, even if 1704already present on the page. 1705 1706@property {String[]} force
1707**/ 1708 1709/** 1710DOM element or id that should be used as the insertion point for dynamically 1711added `<script>` and `<link>` nodes. 1712 1713@property {HTMLElement|String} insertBefore 1714**/ 1715 1716/** 1717Object hash containing attributes to add to dynamically added `<script>` nodes. 1718 1719@property {Object} jsAttributes 1720**/ 1721 1722/** 1723Object hash containing attributes to add to dynamically added `<link>` nodes. 1724 1725@property {Object} cssAttributes 1726**/ 1727 1728/** 1729Timeout in milliseconds before a dynamic JS or CSS request will be considered a 1730failure. If not set, no timeout will be enforced. 1731 1732@property {Number} timeout 1733**/ 1734 1735/** 1736A hash of module definitions to add to the list of available YUI modules. These 1737modules can then be dynamically loaded via the `use()` method. 1738 1739This is a hash in which keys are module names and values are objects containing 1740module metadata. 1741 1742See `Loader.addModule()` for the supported module metadata fields. Also see 1743`groups`, which provides a way to configure the base and combo spec for a set of 1744modules. 1745 1746@example 1747 1748 modules: { 1749 mymod1: { 1750 requires: ['node'], 1751 fullpath: '/mymod1/mymod1.js' 1752 }, 1753 1754 mymod2: { 1755 requires: ['mymod1'], 1756 fullpath: '/mymod2/mymod2.js' 1757 }, 1758 1759 mymod3: '/js/mymod3.js', 1760 mycssmod: '/css/mycssmod.css' 1761 } 1762 1763@property {Object} modules 1764**/ 1765 1766/** 1767Aliases are dynamic groups of modules that can be used as shortcuts. 1768 1769@example 1770 1771 YUI({ 1772 aliases: { 1773 davglass: [ 'node', 'yql', 'dd' ], 1774 mine: [ 'davglass', 'autocomplete'] 1775 } 1776 }).use('mine', function (Y) { 1777 // Node, YQL, DD & AutoComplete available here. 1778 }); 1779 1780@property {Object} aliases 1781**/ 1782 1783/** 1784A hash of module group definitions. 1785 1786For each group you can specify a list of modules and the base path and 1787combo spec to use when dynamically loading the modules. 1788 1789@example 1790 1791 groups: { 1792 yui2: { 1793 // specify whether or not this group has a combo service 1794 combine: true, 1795 1796 // The comboSeperator to use with this group's combo handler 1797 comboSep: ';', 1798 1799 // The maxURLLength for this server 1800 maxURLLength: 500, 1801 1802 // the base path for non-combo paths 1803 base: 'http://yui.yahooapis.com/2.8.0r4/build/', 1804 1805 // the path to the combo service 1806 comboBase: 'http://yui.yahooapis.com/combo?', 1807 1808 // a fragment to prepend to the path attribute when 1809 // when building combo urls 1810 root: '2.8.0r4/build/', 1811 1812 // the module definitions 1813 modules: { 1814 yui2_yde: { 1815 path: "yahoo-dom-event/yahoo-dom-event.js" 1816 }, 1817 yui2_anim: { 1818 path: "animation/animation.js", 1819 requires: ['yui2_yde'] 1820 } 1821 } 1822 } 1823 } 1824 1825@property {Object} groups 1826**/ 1827 1828/** 1829Path to the Loader JS file, relative to the `base` path. 1830 1831This is used to dynamically bootstrap the Loader when it's needed and isn't yet 1832available. 1833 1834@property {String} loaderPath 1835@default "loader/loader-min.js" 1836**/ 1837 1838/** 1839If `true`, YUI will attempt to load CSS dependencies and skins. Set this to 1840`false` to prevent YUI from loading any CSS, or set it to the string `"force"` 1841to force CSS dependencies to be loaded even if their associated JS modules are 1842already loaded. 1843 1844@property {Boolean|String} fetchCSS 1845@default true 1846**/ 1847 1848/** 1849Default gallery version used to build gallery module urls. 1850 1851@property {String} gallery 1852@since 3.1.0 1853**/ 1854 1855/** 1856Default YUI 2 version used to build YUI 2 module urls. 1857 1858This is used for intrinsic YUI 2 support via the 2in3 project. Also see the 1859`2in3` config for pulling different revisions of the wrapped YUI 2 modules. 1860 1861@property {String} yui2 1862@default "2.9.0" 1863@since 3.1.0 1864**/ 1865 1866/** 1867Revision number of YUI 2in3 modules that should be used when loading YUI 2in3. 1868 1869@property {String} 2in3 1870@default "4" 1871@since 3.1.0 1872**/ 1873 1874/** 1875Alternate console log function that should be used in environments without a 1876supported native console. This function is executed with the YUI instance as its 1877`this` object. 1878 1879@property {Function} logFn 1880@since 3.1.0
1881**/ 1882 1883/** 1884The minimum log level to log messages for. Log levels are defined 1885incrementally. Messages greater than or equal to the level specified will 1886be shown. All others will be discarded. The order of log levels in 1887increasing priority is: 1888 1889 debug 1890 info 1891 warn 1892 error 1893 1894@property {String} logLevel 1895@default 'debug' 1896@since 3.10.0 1897**/ 1898 1899/** 1900Callback to execute when `Y.error()` is called. It receives the error message 1901and a JavaScript error object if one was provided. 1902 1903This function is executed with the YUI instance as its `this` object. 1904 1905Returning `true` from this function will prevent an exception from being thrown. 1906 1907@property {Function} errorFn 1908@param {String} errorFn.msg Error message 1909@param {Object} [errorFn.err] Error object (if one was provided). 1910@since 3.2.0 1911**/ 1912 1913/** 1914A callback to execute when Loader fails to load one or more resources. 1915 1916This could be because of a script load failure. It could also be because a 1917module fails to register itself when the `requireRegistration` config is `true`. 1918 1919If this function is defined, the `use()` callback will only be called when the 1920loader succeeds. Otherwise, `use()` will always executes unless there was a 1921JavaScript error when attaching a module. 1922 1923@property {Function} loadErrorFn 1924@since 3.3.0 1925**/ 1926 1927/** 1928If `true`, Loader will expect all loaded scripts to be first-class YUI modules 1929that register themselves with the YUI global, and will trigger a failure if a 1930loaded script does not register a YUI module. 1931 1932@property {Boolean} requireRegistration 1933@default false 1934@since 3.3.0 1935**/ 1936 1937/** 1938Cache serviced use() requests. 1939 1940@property {Boolean} cacheUse 1941@default true 1942@since 3.3.0 1943@deprecated No longer used. 1944**/ 1945 1946/** 1947Whether or not YUI should use native ES5 functionality when available for 1948features like `Y.Array.each()`, `Y.Object()`, etc. 1949 1950When `false`, YUI will always use its own fallback implementations instead of 1951relying on ES5 functionality, even when ES5 functionality is available. 1952 1953@property {Boolean} useNativeES5 1954@default true 1955@since 3.5.0 1956**/ 1957 1958/** 1959 * Leverage native JSON stringify if the browser has a native 1960 * implementation. In general, this is a good idea. See the Known Issues 1961 * section in the JSON user guide for caveats. The default value is true 1962 * for browsers with native JSON support. 1963 * 1964 * @property useNativeJSONStringify 1965 * @type Boolean 1966 * @default true 1967 * @since 3.8.0 1968 */ 1969 1970 /** 1971 * Leverage native JSON parse if the browser has a native implementation. 1972 * In general, this is a good idea. See the Known Issues section in the 1973 * JSON user guide for caveats. The default value is true for browsers with 1974 * native JSON support. 1975 * 1976 * @property useNativeJSONParse 1977 * @type Boolean 1978 * @default true 1979 * @since 3.8.0 1980 */ 1981 1982/** 1983Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`) 1984 1985@property {Object|String} delayUntil 1986@since 3.6.0 1987@example 1988 1989You can use `load` or `domready` strings by default: 1990 1991 YUI({ 1992 delayUntil: 'domready' 1993 }, function (Y) { 1994 // This will not execute until 'domeready' occurs. 1995 }); 1996 1997Or you can delay until a node is available (with `available` or `contentready`): 1998 1999 YUI({ 2000 delayUntil: { 2001 event: 'available', 2002 args : '#foo' 2003 } 2004 }, function (Y) { 2005 // This will not execute until a node matching the selector "#foo" is 2006 // available in the DOM. 2007 }); 2008 2009**/ 2010YUI.add('yui-base', function (Y, NAME) { 2011 2012/* 2013 * YUI stub 2014 * @module yui 2015 * @submodule yui-base 2016 */ 2017/** 2018 * The YUI module contains the components required for building the YUI 2019 * seed file. This includes the script loading mechanism, a simple queue, 2020 * and the core utilities for the library. 2021 * @module yui 2022 * @submodule yui-base 2023 */ 2024 2025/** 2026 * Provides core language utilites and extensions used throughout YUI. 2027 * 2028 * @class Lang 2029 * @static 2030 */ 2031 2032var L = Y.Lang || (Y.Lang = {}), 2033 2034STRING_PROTO = String.prototype, 2035TOSTRING = Object.prototype.toString, 2036 2037TYPES = { 2038 'undefined' : 'undefined', 2039 'number' : 'number', 2040 'boolean' : 'boolean', 2041 'string' : 'string', 2042 '[object Function]': 'function', 2043 '[object RegExp]' : 'regexp', 2044 '[object Array]' : 'array', 2045 '[object Date]' : 'date', 2046 '[object Error]' : 'error' 2047}, 2048 2049SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g, 2050 2051WHITESPACE = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF", 2052WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+", 2053TRIM_LEFT_REGEX = new RegExp("^" + WHITESPACE_CLASS), 2054TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"), 2055TRIMREGEX = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"), 2056 2057NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i; 2058 2059// -- Protected Methods -------------------------------------------------------- 2060 2061/** 2062Returns `true` if the given function appears to be implemented in native code, 2063`false` otherwise. Will always return `false` -- even in ES5-capable browsers -- 2064if the `useNativeES5` YUI config option is set to `false`. 2065 2066This isn't guaranteed to be 100% accurate and won't work for anything other than 2067functions, but it can be useful for determining whether a function like 2068`Array.prototype.forEach` is native or a JS shim provided by another library. 2069 2070There's a great article by @kangax discussing certain flaws with this technique: 2071<http://perfectionkills.com/detecting-built-in-host-methods/> 2072 2073While his points are valid, it's still possible to benefit from this function 2074as long as it's used carefully and sparingly, and in such a way that false 2075negatives have minimal consequences. It's used internally to avoid using 2076potentially broken non-native ES5 shims that have been added to the page b
2076y 2077other libraries. 2078 2079@method _isNative 2080@param {Function} fn Function to test. 2081@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise. 2082@static 2083@protected 2084@since 3.5.0 2085**/ 2086L._isNative = function (fn) { 2087 return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn)); 2088}; 2089 2090// -- Public Methods ----------------------------------------------------------- 2091 2092/** 2093 * Determines whether or not the provided item is an array. 2094 * 2095 * Returns `false` for array-like collections such as the function `arguments` 2096 * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to 2097 * test for an array-like collection. 2098 * 2099 * @method isArray 2100 * @param o The object to test. 2101 * @return {boolean} true if o is an array. 2102 * @static 2103 */ 2104L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) { 2105 return L.type(o) === 'array'; 2106}; 2107 2108/** 2109 * Determines whether or not the provided item is a boolean. 2110 * @method isBoolean 2111 * @static 2112 * @param o The object to test. 2113 * @return {boolean} true if o is a boolean. 2114 */ 2115L.isBoolean = function(o) { 2116 return typeof o === 'boolean'; 2117}; 2118 2119/** 2120 * Determines whether or not the supplied item is a date instance. 2121 * @method isDate 2122 * @static 2123 * @param o The object to test. 2124 * @return {boolean} true if o is a date. 2125 */ 2126L.isDate = function(o) { 2127 return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o); 2128}; 2129 2130/** 2131 * <p> 2132 * Determines whether or not the provided item is a function. 2133 * Note: Internet Explorer thinks certain functions are objects: 2134 * </p> 2135 * 2136 * <pre> 2137 * var obj = document.createElement("object"); 2138 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE 2139 * 2140 * var input = document.createElement("input"); // append to body 2141 * Y.Lang.isFunction(input.focus) // reports false in IE 2142 * </pre> 2143 * 2144 * <p> 2145 * You will have to implement additional tests if these functions 2146 * matter to you. 2147 * </p> 2148 * 2149 * @method isFunction 2150 * @static 2151 * @param o The object to test. 2152 * @return {boolean} true if o is a function. 2153 */ 2154L.isFunction = function(o) { 2155 return L.type(o) === 'function'; 2156}; 2157 2158/** 2159 * Determines whether or not the provided item is null. 2160 * @method isNull 2161 * @static 2162 * @param o The object to test. 2163 * @return {boolean} true if o is null. 2164 */ 2165L.isNull = function(o) { 2166 return o === null; 2167}; 2168 2169/** 2170 * Determines whether or not the provided item is a legal number. 2171 * @method isNumber 2172 * @static 2173 * @param o The object to test. 2174 * @return {boolean} true if o is a number. 2175 */ 2176L.isNumber = function(o) { 2177 return typeof o === 'number' && isFinite(o); 2178}; 2179 2180/** 2181 * Determines whether or not the provided item is of type object 2182 * or function. Note that arrays are also objects, so 2183 * <code>Y.Lang.isObject([]) === true</code>. 2184 * @method isObject 2185 * @static 2186 * @param o The object to test. 2187 * @param failfn {boolean} fail if the input is a function. 2188 * @return {boolean} true if o is an object. 2189 * @see isPlainObject 2190 */ 2191L.isObject = function(o, failfn) { 2192 var t = typeof o; 2193 return (o && (t === 'object' || 2194 (!failfn && (t === 'function' || L.isFunction(o))))) || false; 2195}; 2196 2197/** 2198 * Determines whether or not the provided value is a regexp. 2199 * @method isRegExp 2200 * @static 2201 * @param value The value or object to test. 2202 * @return {boolean} true if value is a regexp. 2203 */ 2204L.isRegExp = function(value) { 2205 return L.type(value) === 'regexp'; 2206}; 2207 2208/** 2209 * Determines whether or not the provided item is a string. 2210 * @method isString 2211 * @static 2212 * @param o The object to test. 2213 * @return {boolean} true if o is a string. 2214 */ 2215L.isString = function(o) { 2216 return typeof o === 'string'; 2217}; 2218 2219/** 2220 * Determines whether or not the provided item is undefined. 2221 * @method isUndefined 2222 * @static 2223 * @param o The object to test. 2224 * @return {boolean} true if o is undefined. 2225 */ 2226L.isUndefined = function(o) { 2227 return typeof o === 'undefined'; 2228}; 2229 2230/** 2231 * A convenience method for detecting a legitimate non-null value. 2232 * Returns false for null/undefined/NaN, true for other values, 2233 * including 0/false/'' 2234 * @method isValue 2235 * @static 2236 * @param o The item to test. 2237 * @return {boolean} true if it is not null/undefined/NaN || false. 2238 */ 2239L.isValue = function(o) { 2240 var t = L.type(o); 2241 2242 switch (t) { 2243 case 'number': 2244 return isFinite(o); 2245 2246 case 'null': // fallthru 2247 case 'undefined': 2248 return false;
2249 2250 default: 2251 return !!t; 2252 } 2253}; 2254 2255/** 2256 * Returns the current time in milliseconds. 2257 * 2258 * @method now 2259 * @return {Number} Current time in milliseconds. 2260 * @static 2261 * @since 3.3.0 2262 */ 2263L.now = Date.now || function () { 2264 return new Date().getTime(); 2265}; 2266 2267/** 2268 * Performs `{placeholder}` substitution on a string. The object passed as the 2269 * second parameter provides values to replace the `{placeholder}`s. 2270 * `{placeholder}` token names must match property names of the object. For example, 2271 * 2272 *`var greeting = Y.Lang.sub("Hello, {who}!", { who: "World" });` 2273 * 2274 * `{placeholder}` tokens that are undefined on the object map will be left 2275 * in tact (leaving unsightly `{placeholder}`'s in the output string). 2276 * 2277 * @method sub 2278 * @param {string} s String to be modified. 2279 * @param {object} o Object containing replacement values. 2280 * @return {string} the substitute result. 2281 * @static 2282 * @since 3.2.0 2283 */ 2284L.sub = function(s, o) { 2285 2286 /** 2287 Finds the value of `key` in given object. 2288 If the key has a 'dot' notation e.g. 'foo.bar.baz', the function will 2289 try to resolve this path if it doesn't exist as a property 2290 @example 2291 value({ 'a.b': 1, a: { b: 2 } }, 'a.b'); // 1 2292 value({ a: { b: 2 } } , 'a.b'); // 2 2293 @param {Object} obj A key/value pairs object 2294 @param {String} key 2295 @return {Any} 2296 @private 2297 **/ 2298 function value(obj, key) { 2299 2300 var subkey; 2301 2302 if ( typeof obj[key] !== 'undefined' ) { 2303 return obj[key]; 2304 } 2305 2306 key = key.split('.'); // given 'a.b.c' 2307 subkey = key.slice(1).join('.'); // 'b.c' 2308 key = key[0]; // 'a' 2309 2310 // special case for null as typeof returns object and we don't want that. 2311 if ( subkey && typeof obj[key] === 'object' && obj[key] !== null ) { 2312 return value(obj[key], subkey); 2313 } 2314 } 2315 2316 return s.replace ? s.replace(SUBREGEX, function (match, key) { 2317 var val = key.indexOf('.')>-1 ? value(o, key) : o[key]; 2318 return typeof val === 'undefined' ? match : val; 2319 }) : s; 2320}; 2321 2322/** 2323 * Returns a string without any leading or trailing whitespace. If 2324 * the input is not a string, the input will be returned untouched. 2325 * @method trim 2326 * @static 2327 * @param s {string} the string to trim. 2328 * @return {string} the trimmed string. 2329 */ 2330L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) { 2331 return s && s.trim ? s.trim() : s; 2332} : function (s) { 2333 try { 2334 return s.replace(TRIMREGEX, ''); 2335 } catch (e) { 2336 return s; 2337 } 2338}; 2339 2340/** 2341 * Returns a string without any leading whitespace. 2342 * @method trimLeft 2343 * @static 2344 * @param s {string} the string to trim. 2345 * @return {string} the trimmed string. 2346 */ 2347L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) { 2348 return s.trimLeft(); 2349} : function (s) { 2350 return s.replace(TRIM_LEFT_REGEX, ''); 2351}; 2352 2353/** 2354 * Returns a string without any trailing whitespace. 2355 * @method trimRight 2356 * @static 2357 * @param s {string} the string to trim. 2358 * @return {string} the trimmed string. 2359 */ 2360L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) { 2361 return s.trimRight(); 2362} : function (s) { 2363 return s.replace(TRIM_RIGHT_REGEX, ''); 2364}; 2365 2366/** 2367Returns one of the following strings, representing the type of the item passed 2368in: 2369 2370 * "array" 2371 * "boolean" 2372 * "date" 2373 * "error" 2374 * "function" 2375 * "null" 2376 * "number" 2377 * "object" 2378 * "regexp" 2379 * "string" 2380 * "undefined" 2381 2382Known issues: 2383 2384 * `typeof HTMLElementCollection` returns function in Safari, but 2385 `Y.Lang.type()` reports "object", which could be a good thing -- 2386 but it actually caused the logic in <code>Y.Lang.isObject</code> to fail. 2387 2388@method type 2389@param o the item to test. 2390@return {string} the detected type. 2391@static 2392**/ 2393L.type = function(o) { 2394 return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null'); 2395}; 2396/** 2397@module yui 2398@submodule yui-base 2399*/ 2400 2401var Lang = Y.Lang, 2402 Native = Array.prototype, 2403 2404 hasOwn = Object.prototype.hasOwnProperty; 2405 2406/** 2407Provides utility methods for working with arrays. Additional array helpers can 2408be found in the `collection` and `array-extras` modules. 2409 2410`Y.Array(thing)` returns a native array created from _thing_. Depending on 2411_thing_'s type, one of the following will happen: 2412 2413 * Arrays are returned unmodified unless a non-zero _startIndex_ is 2414 specified. 2415 * Array-like collections (see `Array.test()`) are converted to arrays. 2416 * For everything else, a new array is created with _thing_ as the sole 2417 item. 2418 2419Note: elements that are also collections, such as `<form>` and `<select>` 2420elements, are not automatically converted to arrays. To force a conversion, 2421pass `true` as the value of the _force_ parameter. 2422 2423@class Array 2424@constructor 2425@param {Any} thing The thing to arrayify. 2426@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like 2427 collection, a subset of items starting at the specified index will be 2428 returned. 2429@param {Boolean} [force=false] If `true`, _thing_ will be treated as an 2430 array-like collection no matter what. 2431@return {Array} A native array created from _thing_, according to the rules 2432 described above. 2433**/ 2434function YArray(thing, startIndex, force) { 2435 var len, result; 2436 2437 /*jshint expr: true*/ 2438 startIndex || (startIndex = 0); 2439 2440 if (force || YArray.test(thing)) { 2441 // IE throws when trying to slice HTMLElement collections. 2442 try { 2443 return Native.slice.call(thing, startIndex); 2444 } catch (ex) { 2445 result = []; 2446 2447 for (len = thing.length; startIndex < len; ++startIndex) { 2448 result.push(thing[startIndex]); 2449 } 2450 2451 return result; 2452 } 2453 } 2454 2455 return [thing]; 2456} 2457 2458Y.Array = YArray; 2459 2460/**
2461Dedupes an array of strings, returning an array that's guaranteed to contain 2462only one copy of a given string. 2463 2464This method differs from `Array.unique()` in that it's optimized for use only 2465with arrays consisting entirely of strings or entirely of numbers, whereas 2466`unique` may be used with other value types (but is slower). 2467 2468Using `dedupe()` with values other than strings or numbers, or with arrays 2469containing a mix of strings and numbers, may result in unexpected behavior. 2470 2471@method dedupe 2472@param {String[]|Number[]} array Array of strings or numbers to dedupe. 2473@return {Array} Copy of _array_ containing no duplicate values. 2474@static 2475@since 3.4.0 2476**/ 2477YArray.dedupe = Lang._isNative(Object.create) ? function (array) { 2478 var hash = Object.create(null), 2479 results = [], 2480 i, item, len; 2481 2482 for (i = 0, len = array.length; i < len; ++i) { 2483 item = array[i]; 2484 2485 if (!hash[item]) { 2486 hash[item] = 1; 2487 results.push(item); 2488 } 2489 } 2490 2491 return results; 2492} : function (array) { 2493 var hash = {}, 2494 results = [], 2495 i, item, len; 2496 2497 for (i = 0, len = array.length; i < len; ++i) { 2498 item = array[i]; 2499 2500 if (!hasOwn.call(hash, item)) { 2501 hash[item] = 1; 2502 results.push(item); 2503 } 2504 } 2505 2506 return results; 2507}; 2508 2509/** 2510Executes the supplied function on each item in the array. This method wraps 2511the native ES5 `Array.forEach()` method if available. 2512 2513@method each 2514@param {Array} array Array to iterate. 2515@param {Function} fn Function to execute on each item in the array. The function 2516 will receive the following arguments: 2517 @param {Any} fn.item Current array item. 2518 @param {Number} fn.index Current array index. 2519 @param {Array} fn.array Array being iterated. 2520@param {Object} [thisObj] `this` object to use when calling _fn_. 2521@return {YUI} The YUI instance. 2522@static 2523**/ 2524YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) { 2525 Native.forEach.call(array || [], fn, thisObj || Y); 2526 return Y; 2527} : function (array, fn, thisObj) { 2528 for (var i = 0, len = (array && array.length) || 0; i < len; ++i) { 2529 if (i in array) { 2530 fn.call(thisObj || Y, array[i], i, array); 2531 } 2532 } 2533 2534 return Y; 2535}; 2536 2537/** 2538Alias for `each()`. 2539 2540@method forEach 2541@static 2542**/ 2543 2544/** 2545Returns an object using the first array as keys and the second as values. If 2546the second array is not provided, or if it doesn't contain the same number of 2547values as the first array, then `true` will be used in place of the missing 2548values. 2549 2550@example 2551 2552 Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']); 2553 // => {a: 'foo', b: 'bar', c: true} 2554 2555@method hash 2556@param {String[]} keys Array of strings to use as keys. 2557@param {Array} [values] Array to use as values. 2558@return {Object} Hash using the first array as keys and the second as values. 2559@static 2560**/ 2561YArray.hash = function (keys, values) { 2562 var hash = {}, 2563 vlen = (values && values.length) || 0, 2564 i, len; 2565 2566 for (i = 0, len = keys.length; i < len; ++i) { 2567 if (i in keys) { 2568 hash[keys[i]] = vlen > i && i in values ? values[i] : true; 2569 } 2570 } 2571 2572 return hash; 2573}; 2574 2575/** 2576Returns the index of the first item in the array that's equal (using a strict 2577equality check) to the specified _value_, or `-1` if the value isn't found. 2578 2579This method wraps the native ES5 `Array.indexOf()` method if available. 2580 2581@method indexOf 2582@param {Array} array Array to search. 2583@param {Any} value Value to search for. 2584@param {Number} [from=0] The index at which to begin the search. 2585@return {Number} Index of the item strictly equal to _value_, or `-1` if not 2586 found. 2587@static 2588**/ 2589YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) { 2590 return Native.indexOf.call(array, value, from); 2591} : function (array, value, from) { 2592 // http://es5.github.com/#x15.4.4.14 2593 var len = array.length; 2594 2595 from = +from || 0; 2596 from = (from > 0 || -1) * Math.floor(Math.abs(from)); 2597 2598 if (from < 0) { 2599 from += len; 2600 2601 if (from < 0) { 2602 from = 0; 2603 } 2604 } 2605 2606 for (; from < len; ++from) { 2607 if (from in array && array[from] === value) { 2608 return from; 2609 } 2610 } 2611 2612 return -1; 2613}; 2614 2615/** 2616Numeric sort convenience function. 2617 2618The native `Array.prototype.sort()` function converts values to strings and 2619sorts them in lexicographic order, which is unsuitable for sorting numeric 2620values. Provide `Array.numericSort` as a custom sort function when you want 2621to sort values in numeric order. 2622 2623@example 2624 2625 [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort); 2626 // => [4, 8, 15, 16, 23, 42] 2627 2628@method numericSort 2629@param {Number} a First value to compare. 2630@param {Number} b Second value to compare. 2631@return {Number} Difference between _a_ and _b_. 2632@static 2633**/ 2634YArray.numericSort = function (a, b) { 2635 return a - b; 2636}; 2637 2638/** 2639Executes the supplied function on each item in the array. Returning a truthy 2640value from the function will stop the processing of remaining items. 2641 2642@method some 2643@param {Array} array Array to iterate over. 2644@param {Function} fn Function to execute on each item. The function will receive 2645 the following arguments: 2646 @param {Any} fn.value Current array item. 2647 @param {Number} fn.index Current array index. 2648 @param {Array} fn.array Array being iterated over. 2649@param {Object} [thisObj] `this` object to use when calling _fn_. 2650@return {Boolean} `true` if the function returns a truthy value on any of the 2651 items in the array; `false` otherwise. 2652@static 2653**/ 2654YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) { 2655 return Native.some.call(array, fn, thisObj); 2656} : function (array, fn, thisObj) { 2657 for (var i = 0, len = array.length; i < len; ++i) { 2658 if (i in array && fn.call(thisObj, array[i], i, array)) { 2659 return true; 2660 } 2661 } 2662 2663 return false;
2664}; 2665 2666/** 2667Evaluates _obj_ to determine if it's an array, an array-like collection, or 2668something else. This is useful when working with the function `arguments` 2669collection and `HTMLElement` collections. 2670 2671Note: This implementation doesn't consider elements that are also 2672collections, such as `<form>` and `<select>`, to be array-like. 2673 2674@method test 2675@param {Object} obj Object to test. 2676@return {Number} A number indicating the results of the test: 2677 2678 * 0: Neither an array nor an array-like collection. 2679 * 1: Real array. 2680 * 2: Array-like collection. 2681 2682@static 2683**/ 2684YArray.test = function (obj) { 2685 var result = 0; 2686 2687 if (Lang.isArray(obj)) { 2688 result = 1; 2689 } else if (Lang.isObject(obj)) { 2690 try { 2691 // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here), 2692 // or functions without apply/call (Safari 2693 // HTMLElementCollection bug). 2694 if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) { 2695 result = 2; 2696 } 2697 } catch (ex) {} 2698 } 2699 2700 return result; 2701}; 2702/** 2703 * The YUI module contains the components required for building the YUI 2704 * seed file. This includes the script loading mechanism, a simple queue, 2705 * and the core utilities for the library. 2706 * @module yui 2707 * @submodule yui-base 2708 */ 2709 2710/** 2711 * A simple FIFO queue. Items are added to the Queue with add(1..n items) and 2712 * removed using next(). 2713 * 2714 * @class Queue 2715 * @constructor 2716 * @param {MIXED} item* 0..n items to seed the queue. 2717 */ 2718function Queue() { 2719 this._init(); 2720 this.add.apply(this, arguments); 2721} 2722 2723Queue.prototype = { 2724 /** 2725 * Initialize the queue 2726 * 2727 * @method _init 2728 * @protected 2729 */ 2730 _init: function() { 2731 /** 2732 * The collection of enqueued items 2733 * 2734 * @property _q 2735 * @type Array 2736 * @protected 2737 */ 2738 this._q = []; 2739 }, 2740 2741 /** 2742 * Get the next item in the queue. FIFO support 2743 * 2744 * @method next 2745 * @return {MIXED} the next item in the queue. 2746 */ 2747 next: function() { 2748 return this._q.shift(); 2749 }, 2750 2751 /** 2752 * Get the last in the queue. LIFO support. 2753 * 2754 * @method last 2755 * @return {MIXED} the last item in the queue. 2756 */ 2757 last: function() { 2758 return this._q.pop(); 2759 }, 2760 2761 /** 2762 * Add 0..n items to the end of the queue. 2763 * 2764 * @method add 2765 * @param {MIXED} item* 0..n items. 2766 * @return {object} this queue. 2767 */ 2768 add: function() { 2769 this._q.push.apply(this._q, arguments); 2770 2771 return this; 2772 }, 2773 2774 /** 2775 * Returns the current number of queued items. 2776 * 2777 * @method size 2778 * @return {Number} The size. 2779 */ 2780 size: function() { 2781 return this._q.length; 2782 } 2783}; 2784 2785Y.Queue = Queue; 2786 2787YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue(); 2788 2789/** 2790The YUI module contains the components required for building the YUI seed file. 2791This includes the script loading mechanism, a simple queue, and the core 2792utilities for the library. 2793 2794@module yui 2795@submodule yui-base 2796**/ 2797 2798var CACHED_DELIMITER = '__', 2799 2800 hasOwn = Object.prototype.hasOwnProperty, 2801 isObject = Y.Lang.isObject; 2802 2803/** 2804Returns a wrapper for a function which caches the return value of that function, 2805keyed off of the combined string representation of the argument values provided 2806when the wrapper is called. 2807 2808Calling this function again with the same arguments will return the cached value 2809rather than executing the wrapped function. 2810 2811Note that since the cache is keyed off of the string representation of arguments 2812passed to the wrapper function, arguments that aren't strings and don't provide 2813a meaningful `toString()` method may result in unexpected caching behavior. For 2814example, the objects `{}` and `{foo: 'bar'}` would both be converted to the 2815string `[object Object]` when used as a cache key. 2816 2817@method cached 2818@param {Function} source The function to memoize. 2819@param {Object} [cache={}] Object in which to store cached values. You may seed 2820 this object with pre-existing cached values if desired. 2821@param {any} [refetch] If supplied, this value is compared with the cached value 2822 using a `==` comparison. If the values are equal, the wrapped function is 2823 executed again even though a cached value exists. 2824@return {Function} Wrapped function. 2825@for YUI
2826**/ 2827Y.cached = function (source, cache, refetch) { 2828 /*jshint expr: true*/ 2829 cache || (cache = {}); 2830 2831 return function (arg) { 2832 var key = arguments.length > 1 ? 2833 Array.prototype.join.call(arguments, CACHED_DELIMITER) : 2834 String(arg); 2835 2836 /*jshint eqeqeq: false*/ 2837 if (!(key in cache) || (refetch && cache[key] == refetch)) { 2838 cache[key] = source.apply(source, arguments); 2839 } 2840 2841 return cache[key]; 2842 }; 2843}; 2844 2845/** 2846Returns the `location` object from the window/frame in which this YUI instance 2847operates, or `undefined` when executing in a non-browser environment 2848(e.g. Node.js). 2849 2850It is _not_ recommended to hold references to the `window.location` object 2851outside of the scope of a function in which its properties are being accessed or 2852its methods are being called. This is because of a nasty bug/issue that exists 2853in both Safari and MobileSafari browsers: 2854[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679). 2855 2856@method getLocation 2857@return {location} The `location` object from the window/frame in which this YUI 2858 instance operates. 2859@since 3.5.0 2860**/ 2861Y.getLocation = function () { 2862 // It is safer to look this up every time because yui-base is attached to a 2863 // YUI instance before a user's config is applied; i.e. `Y.config.win` does 2864 // not point the correct window object when this file is loaded. 2865 var win = Y.config.win; 2866 2867 // It is not safe to hold a reference to the `location` object outside the 2868 // scope in which it is being used. The WebKit engine used in Safari and 2869 // MobileSafari will "disconnect" the `location` object from the `window` 2870 // when a page is restored from back/forward history cache. 2871 return win && win.location; 2872}; 2873 2874/** 2875Returns a new object containing all of the properties of all the supplied 2876objects. The properties from later objects will overwrite those in earlier 2877objects. 2878 2879Passing in a single object will create a shallow copy of it. For a deep copy, 2880use `clone()`. 2881 2882@method merge 2883@param {Object} objects* One or more objects to merge. 2884@return {Object} A new merged object. 2885**/ 2886Y.merge = function () { 2887 var i = 0, 2888 len = arguments.length, 2889 result = {}, 2890 key, 2891 obj; 2892 2893 for (; i < len; ++i) { 2894 obj = arguments[i]; 2895 2896 for (key in obj) { 2897 if (hasOwn.call(obj, key)) { 2898 result[key] = obj[key]; 2899 } 2900 } 2901 } 2902 2903 return result; 2904}; 2905 2906/** 2907Mixes _supplier_'s properties into _receiver_. 2908 2909Properties on _receiver_ or _receiver_'s prototype will not be overwritten or 2910shadowed unless the _overwrite_ parameter is `true`, and will not be merged 2911unless the _merge_ parameter is `true`. 2912 2913In the default mode (0), only properties the supplier owns are copied (prototype 2914properties are not copied). The following copying modes are available: 2915 2916 * `0`: _Default_. Object to object. 2917 * `1`: Prototype to prototype. 2918 * `2`: Prototype to prototype and object to object. 2919 * `3`: Prototype to object. 2920 * `4`: Object to prototype. 2921 2922@method mix 2923@param {Function|Object} receiver The object or function to receive the mixed 2924 properties. 2925@param {Function|Object} supplier The object or function supplying the 2926 properties to be mixed. 2927@param {Boolean} [overwrite=false] If `true`, properties that already exist 2928 on the receiver will be overwritten with properties from the supplier. 2929@param {String[]} [whitelist] An array of property names to copy. If 2930 specified, only the whitelisted properties will be copied, and all others 2931 will be ignored. 2932@param {Number} [mode=0] Mix mode to use. See above for available modes. 2933@param {Boolean} [merge=false] If `true`, objects and arrays that already 2934 exist on the receiver will have the corresponding object/array from the 2935 supplier merged into them, rather than being skipped or overwritten. When 2936 both _overwrite_ and _merge_ are `true`, _merge_ takes precedence. 2937@return {Function|Object|YUI} The receiver, or the YUI instance if the 2938 specified receiver is falsy. 2939**/ 2940Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) { 2941 var alwaysOverwrite, exists, from, i, key, len, to; 2942 2943 // If no supplier is given, we return the receiver. If no receiver is given, 2944 // we return Y. Returning Y doesn't make much sense to me, but it's 2945 // grandfathered in for backcompat reasons. 2946 if (!receiver || !supplier) { 2947 return receiver || Y; 2948 } 2949 2950 if (mode) { 2951 // In mode 2 (prototype to prototype and object to object), we recurse 2952 // once to do the proto to proto mix. The object to object mix will be 2953 // handled later on. 2954 if (mode === 2) { 2955 Y.mix(receiver.prototype, supplier.prototype, overwrite, 2956 whitelist, 0, merge); 2957 } 2958 2959 // Depending on which mode is specified, we may be copying from or to 2960 // the prototypes of the supplier and receiver. 2961 from = mode === 1 || mode === 3 ? supplier.prototype : supplier; 2962 to = mode === 1 || mode === 4 ? receiver.prototype : receiver; 2963 2964 // If either the supplier or receiver doesn't actually have a 2965 // prototype property, then we could end up with an undefined `from` 2966 // or `to`. If that happens, we abort and return the receiver. 2967 if (!from || !to) { 2968 return receiver; 2969 } 2970 } else { 2971 from = supplier; 2972 to = receiver; 2973 } 2974 2975 // If `overwrite` is truthy and `merge` is falsy, then we can skip a 2976 // property existence check on each iteration and save some time. 2977 alwaysOverwrite = overwrite && !merge; 2978 2979 if (whitelist) { 2980 for (i = 0, len = whitelist.length; i < len; ++i) { 2981 key = whitelist[i]; 2982 2983 // We call `Object.prototype.hasOwnProperty` instead of calling 2984 // `hasOwnProperty` on the object itself, since the object's 2985 // `hasOwnProperty` method may have been overridden or removed. 2986 // Also, some native objects don't implement a `hasOwnProperty` 2987 // method. 2988 if (!hasOwn.call(from, key)) { 2989 continue; 2990 } 2991 2992 // The `key in to` check here is (sadly) intentional for backwards 2993 // compatibility reasons. It prevents undesired shadowing of 2994 // prototype members on `to`. 2995 exists = alwaysOverwrite ? false : key in to; 2996 2997 if (merge && exists && isObject(to[key], true) 2998 && isObject(from[key], true)) { 2999 // If we're in merge mode, and the key is present on both 3000 // objects, and the value on both objects is either an object or 3001 // an array (but not a function), then we recurse to merge the 3002 // `from` value into the `to` value instead of overwriting it. 3003 // 3004 // Note: It's intentional that the whitelist isn't passed to the 3005 // recursive call here. This is legacy behavior that lots of 3006 // code still depends on. 3007 Y.mix(to[key], from[key], overwrite, null, 0, merge); 3008 } else if (overwrite || !exists) { 3009 // We're not in merge mode, so we'll only copy the `from` value 3010 // to the `to` value if we're in overwrite mode or if the 3011 // current key doesn't exist on the `to` object. 3012 to[key] = from[key]; 3013 } 3014 } 3015 } else { 3016 for (key in from) { 3017 // The code duplication here is for runtime performance reasons. 3018 // Combining whitelist and non-whitelist operations into a single 3019 // loop or breaking the shared logic out into a function both result 3020 // in worse performance, and Y.mix is critical enough that the byte 3021 // tradeoff is worth it. 3022 if (!hasOwn.call(from, key)) { 3023 continue; 3024 } 3025 3026 // The `key in to` check here is (sadly) intentional for backwards 3027 // compatibility reasons. It prevents undesired shadowing of 3028 // prototype members on `to`. 3029 exists = alwaysOverwrite ? false : key in to; 3030 3031 if (merge && exists && isObject(to[key], true) 3032 && isObject(from[key], true)) { 3033 Y.mix(to[key], from[key], overwrite, null, 0, merge); 3034 } else if (overwrite || !exists) { 3035 to[key] = from[key]; 3036 } 3037 } 3038 3039 // If this is an IE browser with the JScript enumeration bug, force 3040 // enumeration of the buggy properties by making a recursive call with 3041 // the buggy properties as the whitelist. 3042 if (Y.Object._hasEnumBug) { 3043 Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge); 3044 } 3045 } 3046 3047 return receiver; 3048}; 3049/** 3050 * The YUI module contains the components required for building the YUI 3051 * seed file. This includes the script loading mechanism, a simple queue, 3052 * and the core utilities for the library. 3053 * @module yui 3054 * @submodule yui-base 3055 */ 3056 3057/** 3058 * Adds utilities to the YUI instance for working with objects. 3059 * 3060 * @class Object 3061 */ 3062 3063var Lang = Y.Lang, 3064 hasOwn = Object.prototype.hasOwnProperty, 3065 3066 UNDEFINED, // <-- Note the comma. We're still declaring vars. 3067 3068/** 3069 * Returns a new object that uses _obj_ as its prototype. This method wraps the 3070 * native ES5 `Object.create()` method if available, but doesn't currently 3071 * pass through `Object.create()`'s second argument (properties) in order to 3072 * ensure compatibility with older browsers. 3073 * 3074 * @method () 3075 * @param {Object} obj Prototype object. 3076 * @return {Object} New object using _obj_ as its prototype. 3077 * @static 3078 */ 3079O = Y.Object = Lang._isNative(Object.create) ? function (obj) { 3080 // We currently wrap the native Object.create instead of simply aliasing it 3081 // to ensure consistency with our fallback shim, which currently doesn't 3082 // support Object.create()'s second argument (properties). Once we have a 3083 // safe fallback for the properties arg, we can stop wrapping 3084 // Object.create(). 3085 return Object.create(obj); 3086} : (function () { 3087 // Reusable constructor function for the Object.create() shim. 3088 function F() {} 3089 3090 // The actual shim. 3091 return function (obj) { 3092 F.prototype = obj; 3093 return new F(); 3094 }; 3095}()), 3096 3097/** 3098 * Property names that IE doesn't enumerate in for..in loops, even when they 3099 * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to 3100 * manually enumerate these properties. 3101 * 3102 * @property _forceEnum
3103 * @type String[] 3104 * @protected 3105 * @static 3106 */ 3107forceEnum = O._forceEnum = [ 3108 'hasOwnProperty', 3109 'isPrototypeOf', 3110 'propertyIsEnumerable', 3111 'toString', 3112 'toLocaleString', 3113 'valueOf' 3114], 3115 3116/** 3117 * `true` if this browser has the JScript enumeration bug that prevents 3118 * enumeration of the properties named in the `_forceEnum` array, `false` 3119 * otherwise. 3120 * 3121 * See: 3122 * - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug> 3123 * - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation> 3124 * 3125 * @property _hasEnumBug 3126 * @type Boolean 3127 * @protected 3128 * @static 3129 */ 3130hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'), 3131 3132/** 3133 * `true` if this browser incorrectly considers the `prototype` property of 3134 * functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x. 3135 * 3136 * @property _hasProtoEnumBug 3137 * @type Boolean 3138 * @protected 3139 * @static 3140 */ 3141hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), 3142 3143/** 3144 * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or 3145 * exists only on _obj_'s prototype. This is essentially a safer version of 3146 * `obj.hasOwnProperty()`. 3147 * 3148 * @method owns 3149 * @param {Object} obj Object to test. 3150 * @param {String} key Property name to look for. 3151 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise. 3152 * @static 3153 */ 3154owns = O.owns = function (obj, key) { 3155 return !!obj && hasOwn.call(obj, key); 3156}; // <-- End of var declarations. 3157 3158/** 3159 * Alias for `owns()`. 3160 * 3161 * @method hasKey 3162 * @param {Object} obj Object to test. 3163 * @param {String} key Property name to look for. 3164 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise. 3165 * @static 3166 */ 3167O.hasKey = owns; 3168 3169/** 3170 * Returns an array containing the object's enumerable keys. Does not include 3171 * prototype keys or non-enumerable keys. 3172 * 3173 * Note that keys are returned in enumeration order (that is, in the same order 3174 * that they would be enumerated by a `for-in` loop), which may not be the same 3175 * as the order in which they were defined. 3176 * 3177 * This method is an alias for the native ES5 `Object.keys()` method if 3178 * available and non-buggy. The Opera 11.50 and Android 2.3.x versions of 3179 * `Object.keys()` have an inconsistency as they consider `prototype` to be 3180 * enumerable, so a non-native shim is used to rectify the difference. 3181 * 3182 * @example 3183 * 3184 * Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'}); 3185 * // => ['a', 'b', 'c'] 3186 * 3187 * @method keys 3188 * @param {Object} obj An object. 3189 * @return {String[]} Array of keys. 3190 * @static 3191 */ 3192O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) { 3193 if (!Lang.isObject(obj)) { 3194 throw new TypeError('Object.keys called on a non-object'); 3195 } 3196 3197 var keys = [], 3198 i, key, len; 3199 3200 if (hasProtoEnumBug && typeof obj === 'function') { 3201 for (key in obj) { 3202 if (owns(obj, key) && key !== 'prototype') { 3203 keys.push(key); 3204 } 3205 } 3206 } else { 3207 for (key in obj) { 3208 if (owns(obj, key)) { 3209 keys.push(key); 3210 } 3211 } 3212 } 3213 3214 if (hasEnumBug) { 3215 for (i = 0, len = forceEnum.length; i < len; ++i) { 3216 key = forceEnum[i]; 3217 3218 if (owns(obj, key)) { 3219 keys.push(key); 3220 } 3221 } 3222 } 3223 3224 return keys; 3225}; 3226 3227/** 3228 * Returns an array containing the values of the object's enumerable keys. 3229 * 3230 * Note that values are returned in enumeration order (that is, in the same 3231 * order that they would be enumerated by a `for-in` loop), which may not be the 3232 * same as the order in which they were defined. 3233 * 3234 * @example 3235 * 3236 * Y.Object.values({a: 'foo', b: 'bar', c: 'baz'}); 3237 * // => ['foo', 'bar', 'baz'] 3238 * 3239 * @method values 3240 * @param {Object} obj An object. 3241 * @return {Array} Array of values. 3242 * @static 3243 */ 3244O.values = function (obj) { 3245 var keys = O.keys(obj), 3246 i = 0, 3247 len = keys.length, 3248 values = []; 3249 3250 for (; i < len; ++i) { 3251 values.push(obj[keys[i]]); 3252 } 3253 3254 return values; 3255}; 3256 3257/** 3258 * Returns the number of enumerable keys owned by an object. 3259 * 3260 * @method size 3261 * @param {Object} obj An object. 3262 * @return {Number} The object's size. 3263 * @static 3264 */ 3265O.size = function (obj) { 3266 try { 3267 return O.keys(obj).length; 3268 } catch (ex) { 3269 return 0; // Legacy behavior for non-objects. 3270 } 3271}; 3272 3273/** 3274 * Returns `true` if the object owns an enumerable property with the specified 3275 * value. 3276 * 3277 * @method hasValue 3278 * @param {Object} obj An object. 3279 * @param {any} value The value to search for. 3280 * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise. 3281 * @static 3282 */ 3283O.hasValue = function (obj, value) { 3284 return Y.Array.indexOf(O.values(obj), value) > -1; 3285}; 3286 3287/** 3288 * Executes a function on each enumerable property in _obj_. The function 3289 * receives the value, the key, and the object itself as parameters (in that 3290 * order). 3291 * 3292 * By default, only properties owned by _obj_ are enumerated. To include 3293 * prototype properties, set the _proto_ parameter to `true`. 3294 * 3295 * @method each 3296 * @param {Object} obj Object to enumerate. 3297 * @param {Function} fn Function to execute on each enumerable property. 3298 * @param {mixed} fn.value Value of the current property. 3299 * @param {String} fn.key Key of the current property. 3300 * @param {Object} fn.obj Object being enumerated. 3301 * @param {Object} [thisObj] `this` object to use when calling _fn_. 3302 * @param {Boolean} [proto=false] Include prototype properties. 3303 * @return {YUI} the YUI instance. 3304 * @chainable
3305 * @static 3306 */ 3307O.each = function (obj, fn, thisObj, proto) { 3308 var key; 3309 3310 for (key in obj) { 3311 if (proto || owns(obj, key)) { 3312 fn.call(thisObj || Y, obj[key], key, obj); 3313 } 3314 } 3315 3316 return Y; 3317}; 3318 3319/** 3320 * Executes a function on each enumerable property in _obj_, but halts if the 3321 * function returns a truthy value. The function receives the value, the key, 3322 * and the object itself as paramters (in that order). 3323 * 3324 * By default, only properties owned by _obj_ are enumerated. To include 3325 * prototype properties, set the _proto_ parameter to `true`. 3326 * 3327 * @method some 3328 * @param {Object} obj Object to enumerate. 3329 * @param {Function} fn Function to execute on each enumerable property. 3330 * @param {mixed} fn.value Value of the current property. 3331 * @param {String} fn.key Key of the current property. 3332 * @param {Object} fn.obj Object being enumerated. 3333 * @param {Object} [thisObj] `this` object to use when calling _fn_. 3334 * @param {Boolean} [proto=false] Include prototype properties. 3335 * @return {Boolean} `true` if any execution of _fn_ returns a truthy value, 3336 * `false` otherwise. 3337 * @static 3338 */ 3339O.some = function (obj, fn, thisObj, proto) { 3340 var key; 3341 3342 for (key in obj) { 3343 if (proto || owns(obj, key)) { 3344 if (fn.call(thisObj || Y, obj[key], key, obj)) { 3345 return true; 3346 } 3347 } 3348 } 3349 3350 return false; 3351}; 3352 3353/** 3354 * Retrieves the sub value at the provided path, 3355 * from the value object provided. 3356 * 3357 * @method getValue 3358 * @static 3359 * @param o The object from which to extract the property value. 3360 * @param path {Array} A path array, specifying the object traversal path 3361 * from which to obtain the sub value. 3362 * @return {Any} The value stored in the path, undefined if not found, 3363 * undefined if the source is not an object. Returns the source object 3364 * if an empty path is provided. 3365 */ 3366O.getValue = function(o, path) { 3367 if (!Lang.isObject(o)) { 3368 return UNDEFINED; 3369 } 3370 3371 var i, 3372 p = Y.Array(path), 3373 l = p.length; 3374 3375 for (i = 0; o !== UNDEFINED && i < l; i++) { 3376 o = o[p[i]]; 3377 } 3378 3379 return o; 3380}; 3381 3382/** 3383 * Sets the sub-attribute value at the provided path on the 3384 * value object. Returns the modified value object, or 3385 * undefined if the path is invalid. 3386 * 3387 * @method setValue 3388 * @static 3389 * @param o The object on which to set the sub value. 3390 * @param path {Array} A path array, specifying the object traversal path 3391 * at which to set the sub value. 3392 * @param val {Any} The new value for the sub-attribute. 3393 * @return {Object} The modified object, with the new sub value set, or 3394 * undefined, if the path was invalid. 3395 */ 3396O.setValue = function(o, path, val) { 3397 var i, 3398 p = Y.Array(path), 3399 leafIdx = p.length - 1, 3400 ref = o; 3401 3402 if (leafIdx >= 0) { 3403 for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) { 3404 ref = ref[p[i]]; 3405 } 3406 3407 if (ref !== UNDEFINED) { 3408 ref[p[i]] = val; 3409 } else { 3410 return UNDEFINED; 3411 } 3412 } 3413 3414 return o; 3415}; 3416 3417/** 3418 * Returns `true` if the object has no enumerable properties of its own. 3419 * 3420 * @method isEmpty 3421 * @param {Object} obj An object. 3422 * @return {Boolean} `true` if the object is empty. 3423 * @static 3424 * @since 3.2.0 3425 */ 3426O.isEmpty = function (obj) { 3427 return !O.keys(Object(obj)).length; 3428}; 3429/** 3430 * The YUI module contains the components required for building the YUI seed 3431 * file. This includes the script loading mechanism, a simple queue, and the 3432 * core utilities for the library. 3433 * @module yui 3434 * @submodule yui-base 3435 */ 3436 3437/** 3438 * YUI user agent detection. 3439 * Do not fork for a browser if it can be avoided. Use feature detection when 3440 * you can. Use the user agent as a last resort. For all fields listed 3441 * as @type float, UA stores a version number for the browser engine, 3442 * 0 otherwise. This value may or may not map to the version number of 3443 * the browser using the engine. The value is presented as a float so 3444 * that it can easily be used for boolean evaluation as well as for 3445 * looking for a particular range of versions. Because of this, 3446 * some of the granularity of the version info may be lost. The fields that 3447 * are @type string default to null. The API docs list the values that 3448 * these fields can have. 3449 * @class UA 3450 * @static 3451 */ 3452 3453/** 3454* Static method on `YUI.Env` for parsing a UA string. Called at instantiation 3455* to populate `Y.UA`. 3456* 3457* @static 3458* @method parseUA 3459* @param {String} [subUA=navigator.userAgent] UA string to parse 3460* @return {Object} The Y.UA object 3461*/ 3462YUI.Env.parseUA = function(subUA) { 3463 3464 var numberify = function(s) { 3465 var c = 0; 3466 return parseFloat(s.replace(/\./g, function() { 3467 return (c++ === 1) ? '' : '.'; 3468 })); 3469 }, 3470 3471 win = Y.config.win, 3472 3473 nav = win && win.navigator, 3474 3475 o = { 3476 3477 /** 3478 * Internet Explorer version number or 0. Example: 6 3479 * @property ie 3480 * @type float 3481 * @static 3482 */ 3483 ie: 0, 3484 3485 /** 3486 * Opera version number or 0. Example: 9.2 3487 * @property opera 3488 * @type float 3489 * @static 3490 */ 3491 opera: 0, 3492 3493 /** 3494 * Gecko engine revision number. Will evaluate to 1 if Gecko 3495 * is detected but the revision could not be found. Other browsers 3496 * will be 0. Example: 1.8 3497 * <pre> 3498 * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7 3499 * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8 3500 * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81 3501 * Firefox 3.0 <-- 1.9 3502 * Firefox 3.5 <-- 1.91 3503 * </pre> 3504 * @property gecko 3505 * @type float 3506 * @static 3507 */ 3508 gecko: 0, 3509 3510 /** 3511 * AppleWebKit version. KHTML browsers that are not WebKit browsers 3512 * will evaluate to 1, other browsers 0. Example: 418.9 3513 * <pre> 3514 * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the 3515 * latest available for Mac OSX 10.3. 3516 * Safari 2.0.2: 416 <-- hasOwnProperty introduced 3517 * Safari 2.0.4: 418 <-- preventDefault fixed 3518 * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run 3519 * different versions of webkit 3520 * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been 3521 * updated, but not updated 3522 * to the latest patch. 3523 * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native 3524 * SVG and many major issues fixed). 3525 * Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic 3526 * update from 2.x via the 10.4.11 OS patch. 3527 * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event. 3528 * yahoo.com user agent hack removed. 3529 * </pre> 3530 * http://en.wikipedia.org/wiki/Safari_version_history 3531 * @property webkit 3532 * @type float 3533 * @static 3534 */ 3535 webkit: 0, 3536 3537 /** 3538 * Safari will be detected as webkit, but this property will also 3539 * be populated with the Safari version number 3540 * @property safari 3541 * @type float 3542 * @static 3543 */ 3544 safari: 0, 3545 3546 /** 3547 * Chrome will be detected as webkit, but this property will also 3548 * be populated with the Chrome version number 3549 * @property chrome 3550 * @type float 3551 * @static 3552 */ 3553 chrome: 0, 3554 3555 /** 3556 * The mobile property will be set to a string containing any relevant 3557 * user agent information when a modern mobile browser is detected. 3558 * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series 3559 * devices with the WebKit-based browser, and Opera Mini. 3560 * @property mobile 3561 * @type string 3562 * @default null 3563 * @static 3564 */ 3565 mobile: null, 3566 3567 /** 3568 * Adobe AIR version number or 0. Only populated if webkit is detected. 3569 * Example: 1.0 3570 * @property air 3571 * @type float 3572 */ 3573 air: 0, 3574 /** 3575 * PhantomJS version number or 0. Only populated if webkit is detected. 3576 * Example: 1.0 3577 * @property phantomjs 3578 * @type float 3579 */ 3580 phantomjs: 0, 3581 /** 3582 * Detects Apple iPad's OS version 3583 * @property ipad 3584 * @type float 3585 * @static 3586 */ 3587 ipad: 0, 3588 /** 3589 * Detects Apple iPhone's OS version 3590 * @property iphone 3591 * @type float 3592 * @static 3593 */ 3594 iphone: 0, 3595 /** 3596 * Detects Apples iPod's OS version 3597 * @property ipod 3598 * @type float 3599 * @static 3600 */ 3601 ipod: 0, 3602 /** 3603 * General truthy check for iPad, iPhone or iPod 3604 * @property ios 3605 * @type Boolean 3606 * @default null 3607 * @static 3608 */ 3609 ios: null, 3610 /** 3611 * Detects Googles Android OS version 3612 * @property android 3613 * @type float 3614 * @static 3615 */ 3616 android: 0, 3617 /** 3618 * Detects Kindle Silk 3619 * @property silk 3620 * @type float 3621 * @static 3622 */ 3623 silk: 0, 3624 /** 3625 * Detects Ubuntu version 3626 * @property ubuntu 3627 * @type float 3628 * @static 3629 */ 3630 ubuntu: 0, 3631 /** 3632 * Detects Kindle Silk Acceleration 3633 * @property accel 3634 * @type Boolean 3635 * @static 3636 */ 3637 accel: false, 3638 /** 3639 * Detects Palms WebOS version 3640 * @property webos 3641 * @type float 3642 * @static 3643 */ 3644 webos: 0, 3645 3646 /** 3647 * Google Caja version number or 0. 3648 * @property caja 3649 * @type float 3650 */ 3651 caja: nav && nav.cajaVersion, 3652 3653 /** 3654 * Set to true if the page appears to be in SSL 3655 * @property secure 3656 * @type boolean 3657 * @static 3658 */ 3659 secure: false, 3660 3661 /** 3662 * The operating system. 3663 * 3664 * Possible values are `windows`, `macintosh`, `android`, `symbos`, `linux`, `rhino` and `ios`. 3665 * 3666 * @property os 3667 * @type string 3668 * @default null 3669 * @static 3670 */ 3671 os: null, 3672 3673 /** 3674 * The Nodejs Version 3675 * @property nodejs 3676 * @type float 3677 * @default 0 3678 * @static 3679 */ 3680 nodejs: 0, 3681 /** 3682 * Window8/IE10 Application host environment 3683 * @property winjs 3684 * @type Boolean 3685 * @static 3686 */ 3687 winjs: !!((typeof Windows !== "undefined") && Windows.System), 3688 /** 3689 * Are touch/msPointer events available on this device 3690 * @property touchEnabled 3691 * @type Boolean 3692 * @static 3693 */ 3694 touchEnabled: false 3695 }, 3696 3697 ua = subUA || nav && nav.userAgent, 3698 3699 loc = win && win.location, 3700 3701 href = loc && loc.href, 3702 3703 m; 3704 3705 /** 3706 * The User Agent string that was parsed 3707 * @property userAgent
3708 * @type String 3709 * @static 3710 */ 3711 o.userAgent = ua; 3712 3713 3714 o.secure = href && (href.toLowerCase().indexOf('https') === 0); 3715 3716 if (ua) { 3717 3718 if ((/windows|win32/i).test(ua)) { 3719 o.os = 'windows'; 3720 } else if ((/macintosh|mac_powerpc/i).test(ua)) { 3721 o.os = 'macintosh'; 3722 } else if ((/android/i).test(ua)) { 3723 o.os = 'android'; 3724 } else if ((/symbos/i).test(ua)) { 3725 o.os = 'symbos'; 3726 } else if ((/linux/i).test(ua)) { 3727 o.os = 'linux'; 3728 } else if ((/rhino/i).test(ua)) { 3729 o.os = 'rhino'; 3730 } 3731 3732 // Modern KHTML browsers should qualify as Safari X-Grade 3733 if ((/KHTML/).test(ua)) { 3734 o.webkit = 1; 3735 } 3736 if ((/IEMobile|XBLWP7/).test(ua)) { 3737 o.mobile = 'windows'; 3738 } 3739 if ((/Fennec/).test(ua)) { 3740 o.mobile = 'gecko'; 3741 } 3742 // Modern WebKit browsers are at least X-Grade 3743 m = ua.match(/AppleWebKit\/([^\s]*)/); 3744 if (m && m[1]) { 3745 o.webkit = numberify(m[1]); 3746 o.safari = o.webkit; 3747 3748 if (/PhantomJS/.test(ua)) { 3749 m = ua.match(/PhantomJS\/([^\s]*)/); 3750 if (m && m[1]) { 3751 o.phantomjs = numberify(m[1]); 3752 } 3753 } 3754 3755 // Mobile browser check 3756 if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) { 3757 o.mobile = 'Apple'; // iPhone or iPod Touch 3758 3759 m = ua.match(/OS ([^\s]*)/); 3760 if (m && m[1]) { 3761 m = numberify(m[1].replace('_', '.')); 3762 } 3763 o.ios = m; 3764 o.os = 'ios'; 3765 o.ipad = o.ipod = o.iphone = 0; 3766 3767 m = ua.match(/iPad|iPod|iPhone/); 3768 if (m && m[0]) { 3769 o[m[0].toLowerCase()] = o.ios; 3770 } 3771 } else { 3772 m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/); 3773 if (m) { 3774 // Nokia N-series, webOS, ex: NokiaN95 3775 o.mobile = m[0]; 3776 } 3777 if (/webOS/.test(ua)) { 3778 o.mobile = 'WebOS'; 3779 m = ua.match(/webOS\/([^\s]*);/); 3780 if (m && m[1]) { 3781 o.webos = numberify(m[1]); 3782 } 3783 } 3784 if (/ Android/.test(ua)) { 3785 o.mobile = 'Android'; 3786 m = ua.match(/Android ([^\s]*);/); 3787 if (m && m[1]) { 3788 o.android = numberify(m[1]); 3789 } 3790 3791 } 3792 if (/Silk/.test(ua)) { 3793 m = ua.match(/Silk\/([^\s]*)/); 3794 if (m && m[1]) { 3795 o.silk = numberify(m[1]); 3796 } 3797 if (!o.android) { 3798 o.android = 2.34; //Hack for desktop mode in Kindle 3799 o.os = 'Android'; 3800 } 3801 if (/Accelerated=true/.test(ua)) { 3802 o.accel = true; 3803 } 3804 } 3805 } 3806 3807 m = ua.match(/OPR\/(\d+\.\d+)/); 3808 3809 if (m && m[1]) { 3810 // Opera 15+ with Blink (pretends to be both Chrome and Safari) 3811 o.opera = numberify(m[1]); 3812 } else { 3813 m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/); 3814 3815 if (m && m[1] && m[2]) { 3816 o.chrome = numberify(m[2]); // Chrome 3817 o.safari = 0; //Reset safari back to 0 3818 if (m[1] === 'CrMo') { 3819 o.mobile = 'chrome'; 3820 } 3821 } else { 3822 m = ua.match(/AdobeAIR\/([^\s]*)/); 3823 if (m) { 3824 o.air = m[0]; // Adobe AIR 1.0 or better 3825 } 3826 } 3827 } 3828 } 3829 3830 m = ua.match(/Ubuntu\ (\d+\.\d+)/); 3831 if (m && m[1]) { 3832 3833 o.os = 'linux'; 3834 o.ubuntu = numberify(m[1]); 3835 3836 m = ua.match(/\ WebKit\/([^\s]*)/); 3837 if (m && m[1]) { 3838 o.webkit = numberify(m[1]); 3839 } 3840 m = ua.match(/\ Chromium\/([^\s]*)/); 3841 if (m && m[1]) { 3842 o.chrome = numberify(m[1]); 3843 } 3844 if (/ Mobile$/.test(ua)) { 3845 o.mobile = 'Ubuntu'; 3846 } 3847 } 3848 3849 if (!o.webkit) { // not webkit 3850// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr) 3851 if (/Opera/.test(ua)) { 3852 m = ua.match(/Opera[\s\/]([^\s]*)/); 3853 if (m && m[1]) { 3854 o.opera = numberify(m[1]); 3855 } 3856 m = ua.match(/Version\/([^\s]*)/); 3857 if (m && m[1]) { 3858 o.opera = numberify(m[1]); // opera 10+ 3859 } 3860 3861 if (/Opera Mobi/.test(ua)) { 3862 o.mobile = 'opera'; 3863 m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/); 3864 if (m && m[1]) { 3865 o.opera = numberify(m[1]); 3866 } 3867 } 3868 m = ua.match(/Opera Mini[^;]*/); 3869 3870 if (m) { 3871 o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316 3872 } 3873 } else { // not opera or webkit 3874 m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/); 3875 3876 if (m && (m[1] || m[2])) { 3877 o.ie = numberify(m[1] || m[2]); 3878 } else { // not opera, webkit, or ie 3879 m = ua.match(/Gecko\/([^\s]*)/); 3880 3881 if (m) { 3882 o.gecko = 1; // Gecko detected, look for revision 3883 m = ua.match(/rv:([^\s\)]*)/); 3884 if (m && m[1]) { 3885 o.gecko = numberify(m[1]); 3886 if (/Mobile|Tablet/.test(ua)) { 3887 o.mobile = "ffos"; 3888 } 3889 } 3890 } 3891 } 3892 } 3893 } 3894 } 3895 3896 //Check for known properties to tell if touch events are enabled on this device or if 3897 //the number of MSPointer touchpoints on this device is greater than 0. 3898 if (win && nav && !(o.chrome && o.chrome < 6)) { 3899 o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0))); 3900 } 3901 3902 //It was a parsed UA, do not assign the global value. 3903 if (!subUA) { 3904 3905 if (typeof process === 'object') { 3906 3907 if (process.versions && process.versions.node) { 3908 //NodeJS 3909 o.os = process.platform; 3910 o.nodejs = numberify(process.versions.node); 3911 } 3912 } 3913 3914 YUI.Env.UA = o; 3915 3916 } 3917 3918 return o; 3919}; 3920 3921 3922Y.UA = YUI.Env.UA || YUI.Env.parseUA(); 3923 3924/**
3925Performs a simple comparison between two version numbers, accounting for 3926standard versioning logic such as the fact that "535.8" is a lower version than 3927"535.24", even though a simple numerical comparison would indicate that it's 3928greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are 3929considered equivalent. 3930 3931Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent, 39321 if _a_ is higher than _b_. 3933 3934Versions may be numbers or strings containing numbers and dots. For example, 3935both `535` and `"535.8.10"` are acceptable. A version string containing 3936non-numeric characters, like `"535.8.beta"`, may produce unexpected results. 3937 3938@method compareVersions 3939@param {Number|String} a First version number to compare. 3940@param {Number|String} b Second version number to compare. 3941@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is 3942 higher than _b_. 3943**/ 3944Y.UA.compareVersions = function (a, b) { 3945 var aPart, aParts, bPart, bParts, i, len; 3946 3947 if (a === b) { 3948 return 0; 3949 } 3950 3951 aParts = (a + '').split('.'); 3952 bParts = (b + '').split('.'); 3953 3954 for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) { 3955 aPart = parseInt(aParts[i], 10); 3956 bPart = parseInt(bParts[i], 10); 3957 3958 /*jshint expr: true*/ 3959 isNaN(aPart) && (aPart = 0); 3960 isNaN(bPart) && (bPart = 0); 3961 3962 if (aPart < bPart) { 3963 return -1; 3964 } 3965 3966 if (aPart > bPart) { 3967 return 1; 3968 } 3969 } 3970 3971 return 0; 3972}; 3973YUI.Env.aliases = { 3974 "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"], 3975 "anim-shape-transform": ["anim-shape"], 3976 "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"], 3977 "attribute": ["attribute-base","attribute-complex"], 3978 "attribute-events": ["attribute-observable"], 3979 "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"], 3980 "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"], 3981 "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"], 3982 "base": ["base-base","base-pluginhost","base-build"], 3983 "cache": ["cache-base","cache-offline","cache-plugin"], 3984 "charts": ["charts-base"], 3985 "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"], 3986 "color": ["color-base","color-hsl","color-harmony"], 3987 "controller": ["router"], 3988 "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"], 3989 "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"], 3990 "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"], 3991 "datatype": ["datatype-date","datatype-number","datatype-xml"], 3992 "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"], 3993 "datatype-number": ["datatype-number-parse","datatype-number-format"], 3994 "datatype-xml": ["datatype-xml-parse","datatype-xml-format"], 3995 "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"], 3996 "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"], 3997 "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"], 3998 "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"], 3999 "event-custom": ["event-custom-base","event-custom-complex"], 4000 "event-gestures": ["event-flick","event-move"], 4001 "handlebars": ["handlebars-compiler"], 4002 "highlight": ["highlight-base","highlight-accentfold"], 4003 "history": ["history-base","history-hash","history-html5"], 4004 "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"], 4005 "json": ["json-parse","json-stringify"], 4006 "loader": ["loader-base","loader-rollup","loader-yui3"], 4007 "loader-pathogen-encoder": ["loader-base","loader-rollup","loader-yui3","loader-pathogen-combo
4007handler"], 4008 "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"], 4009 "pluginhost": ["pluginhost-base","pluginhost-config"], 4010 "querystring": ["querystring-parse","querystring-stringify"], 4011 "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"], 4012 "resize": ["resize-base","resize-proxy","resize-constrain"], 4013 "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"], 4014 "template": ["template-base","template-micro"], 4015 "text": ["text-accentfold","text-wordbreak"], 4016 "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"] 4017}; 4018 4019 4020}, 'patched-v3.18.1', { 4021 "use": [ 4022 "yui-base", 4023 "get", 4024 "features", 4025 "intl-base", 4026 "yui-log", 4027 "yui-later", 4028 "loader-base", 4029 "loader-rollup", 4030 "loader-yui3" 4031 ] 4032}); 4033YUI.add('get', function (Y, NAME) { 4034 4035/*jslint boss:true, expr:true, laxbreak: true */ 4036 4037/** 4038Provides dynamic loading of remote JavaScript and CSS resources. 4039 4040@module get 4041@class Get 4042@static 4043**/ 4044 4045var Lang = Y.Lang, 4046 4047 CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode() 4048 4049 Get, Transaction; 4050 4051Y.Get = Get = { 4052 // -- Public Properties ---------------------------------------------------- 4053 4054 /** 4055 Default options for CSS requests. Options specified here will override 4056 global defaults for CSS requests. 4057 4058 See the `options` property for all available options. 4059 4060 @property cssOptions 4061 @type Object 4062 @static 4063 @since 3.5.0 4064 **/ 4065 cssOptions: { 4066 attributes: { 4067 rel: 'stylesheet' 4068 }, 4069 4070 doc : Y.config.linkDoc || Y.config.doc, 4071 pollInterval: 50 4072 }, 4073 4074 /** 4075 Default options for JS requests. Options specified here will override global 4076 defaults for JS requests. 4077 4078 See the `options` property for all available options. 4079 4080 @property jsOptions 4081 @type Object 4082 @static 4083 @since 3.5.0 4084 **/ 4085 jsOptions: { 4086 autopurge: true, 4087 doc : Y.config.scriptDoc || Y.config.doc 4088 }, 4089 4090 /** 4091 Default options to use for all requests. 4092 4093 Note that while all available options are documented here for ease of 4094 discovery, some options (like callback functions) only make sense at the 4095 transaction level. 4096 4097 Callback functions specified via the options object or the `options` 4098 parameter of the `css()`, `js()`, or `load()` methods will receive the 4099 transaction object as a parameter. See `Y.Get.Transaction` for details on 4100 the properties and methods available on transactions. 4101 4102 @static 4103 @since 3.5.0 4104 @property {Object} options 4105 4106 @property {Boolean} [options.async=false] Whether or not to load scripts 4107 asynchronously, meaning they're requested in parallel and execution 4108 order is not guaranteed. Has no effect on CSS, since CSS is always 4109 loaded asynchronously. 4110 4111 @property {Object} [options.attributes] HTML attribute name/value pairs that 4112 should be added to inserted nodes. By default, the `charset` attribute 4113 will be set to "utf-8" and nodes will be given an auto-generated `id` 4114 attribute, but you can override these with your own values if desired. 4115 4116 @property {Boolean} [options.autopurge] Whether or not to automatically 4117 purge inserted nodes after the purge threshold is reached. This is 4118 `true` by default for JavaScript, but `false` for CSS since purging a
4119 CSS node will also remove any styling applied by the referenced file. 4120 4121 @property {Object} [options.context] `this` object to use when calling 4122 callback functions. Defaults to the transaction object. 4123 4124 @property {Mixed} [options.data] Arbitrary data object to pass to "on*" 4125 callbacks. 4126 4127 @property {Document} [options.doc] Document into which nodes should be 4128 inserted. By default, the current document is used. 4129 4130 @property {HTMLElement|String} [options.insertBefore] HTML element or id 4131 string of an element before which all generated nodes should be 4132 inserted. If not specified, Get will automatically determine the best 4133 place to insert nodes for maximum compatibility. 4134 4135 @property {Function} [options.onEnd] Callback to execute after a transaction 4136 is complete, regardless of whether it succeeded or failed. 4137 4138 @property {Function} [options.onFailure] Callback to execute after a 4139 transaction fails, times out, or is aborted. 4140 4141 @property {Function} [options.onProgress] Callback to execute after each 4142 individual request in a transaction either succeeds or fails. 4143 4144 @property {Function} [options.onSuccess] Callback to execute after a 4145 transaction completes successfully with no errors. Note that in browsers 4146 that don't support the `error` event on CSS `<link>` nodes, a failed CSS 4147 request may still be reported as a success because in these browsers 4148 it can be difficult or impossible to distinguish between success and 4149 failure for CSS resources. 4150 4151 @property {Function} [options.onTimeout] Callback to execute after a 4152 transaction times out. 4153 4154 @property {Number} [options.pollInterval=50] Polling interval (in 4155 milliseconds) for detecting CSS load completion in browsers that don't 4156 support the `load` event on `<link>` nodes. This isn't used for 4157 JavaScript. 4158 4159 @property {Number} [options.purgethreshold=20] Number of nodes to insert 4160 before triggering an automatic purge when `autopurge` is `true`. 4161 4162 @property {Number} [options.timeout] Number of milliseconds to wait before 4163 aborting a transaction. When a timeout occurs, the `onTimeout` callback 4164 is called, followed by `onFailure` and finally `onEnd`. By default, 4165 there is no timeout. 4166 4167 @property {String} [options.type] Resource type ("css" or "js"). This option 4168 is set automatically by the `css()` and `js()` functions and will be 4169 ignored there, but may be useful when using the `load()` function. If 4170 not specified, the type will be inferred from the URL, defaulting to 4171 "js" if the URL doesn't contain a recognizable file extension. 4172 **/ 4173 options: { 4174 attributes: { 4175 charset: 'utf-8' 4176 }, 4177 4178 purgethreshold: 20 4179 }, 4180 4181 // -- Protected Properties ------------------------------------------------- 4182 4183 /** 4184 Regex that matches a CSS URL. Used to guess the file type when it's not 4185 specified. 4186 4187 @property REGEX_CSS 4188 @type RegExp 4189 @final 4190 @protected 4191 @static 4192 @since 3.5.0 4193 **/ 4194 REGEX_CSS: /\.css(?:[?;].*)?$/i, 4195 4196 /** 4197 Regex that matches a JS URL. Used to guess the file type when it's not 4198 specified. 4199 4200 @property REGEX_JS 4201 @type RegExp 4202 @final 4203 @protected 4204 @static 4205 @since 3.5.0 4206 **/ 4207 REGEX_JS : /\.js(?:[?;].*)?$/i, 4208 4209 /** 4210 Contains information about the current environment, such as what script and 4211 link injection features it supports. 4212 4213 This object is created and populated the first time the `_getEnv()` method 4214 is called. 4215 4216 @property _env 4217 @type Object 4218 @protected 4219 @static 4220 @since 3.5.0 4221 **/ 4222 4223 /** 4224 Mapping of document _yuid strings to <head> or <base> node references so we 4225 don't have to look the node up each time we want to insert a request node. 4226 4227 @property _insertCache 4228 @type Object 4229 @protected 4230 @static 4231 @since 3.5.0 4232 **/ 4233 _insertCache: {}, 4234 4235 /** 4236 Information about the currently pending transaction, if any. 4237 4238 This is actually an object with two properties: `callback`, containing the 4239 optional callback passed to `css()`, `load()`, or `js()`; and `transaction`, 4240 containing the actual transaction instance. 4241 4242 @property _pending 4243 @type Object 4244 @protected 4245 @static 4246 @since 3.5.0 4247 **/ 4248 _pending: null, 4249 4250 /** 4251 HTML nodes eligible to be purged next time autopurge is triggered. 4252 4253 @property _purgeNodes 4254 @type HTMLElement[] 4255 @protected 4256 @static 4257 @since 3.5.0 4258 **/ 4259 _purgeNodes: [], 4260 4261 /** 4262 Queued transactions and associated callbacks. 4263 4264 @property _queue 4265 @type Object[] 4266 @protected 4267 @static 4268 @since 3.5.0 4269 **/ 4270 _queue: [], 4271 4272 // -- Public Methods ------------------------------------------------------- 4273 4274 /** 4275 Aborts the specified transaction. 4276 4277 This will cause the transaction's `onFailure` callback to be called and 4278 will prevent any new script and link nodes from being added to the document, 4279 but any resources that have already been requested will continue loading 4280 (there's no safe way to prevent this, unfortunately). 4281 4282 *Note:* This method is deprecated as of 3.5.0, and will be removed in a 4283 future version of YUI. Use the transaction-level `abort()` method instead. 4284 4285 @method abort 4286 @param {Get.Transaction} transaction Transaction to abort. 4287 @deprecated Use the `abort()` method on the transaction instead. 4288 @static 4289 **/ 4290 abort: function (transaction) { 4291 var i, id, item, len, pending; 4292 4293 4294 if (!transaction.abort) { 4295 id = transaction; 4296 pending = this._pending; 4297 transaction = null; 4298 4299 if (pending && pending.transaction.id === id) { 4300 transaction = pending.transaction; 4301 this._pending = null; 4302 } else { 4303 for (i = 0, len = this._queue.length; i < len; ++i) { 4304 item = this._queue[i].transaction; 4305 4306 if (item.id === id) { 4307 transaction = item; 4308 this._queue.splice(i, 1); 4309 break; 4310 } 4311 } 4312 } 4313 } 4314 4315 transaction && transaction.abort(); 4316 }, 4317 4318 /** 4319 Loads one or more CSS files. 4320 4321 The _urls_ parameter may be provided as a URL string, a request object, 4322 or an array of URL strings and/or request objects. 4323 4324 A request object is just an object that contains a `url` property and zero 4325 or more options that should apply specifically to that request. 4326 Request-specific options take priority over transaction-level options and 4327 default options. 4328 4329 URLs may be relative or absolute, and do not have to have the same origin 4330 as the current page. 4331 4332 The `options` parameter may be omitted completely and a callback passed in 4333 its place, if desired. 4334 4335 @example 4336 4337 // Load a single CSS file and log a message on completion. 4338 Y.Get.css('foo.css', function (err) { 4339 if (err) { 4340 } else { 4341 } 4342 }); 4343 4344 // Load multiple CSS files and log a message when all have finished 4345 // loading. 4346 var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css']; 4347 4348 Y.Get.css(urls, function (err) { 4349 if (err) { 4350 } else { 4351 } 4352 }); 4353 4354 // Specify transaction-level options, which will apply to all requests 4355 // within the transaction. 4356 Y.Get.css(urls, { 4357 attributes: {'class': 'my-css'}, 4358 timeout : 5000 4359 }); 4360 4361 // Specify per-request options, which override transaction-level and 4362 // default options. 4363 Y.Get.css([ 4364 {url: 'foo.css', attributes: {id: 'foo'}}, 4365 {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}} 4366 ]); 4367 4368 @method css 4369 @param {String|Object|Array}
4369 urls URL string, request object, or array 4370 of URLs and/or request objects to load. 4371 @param {Object} [options] Options for this transaction. See the 4372 `Y.Get.options` property for a complete list of available options. 4373 @param {Function} [callback] Callback function to be called on completion. 4374 This is a general callback and will be called before any more granular 4375 callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options` 4376 object. 4377 4378 @param {Array|null} callback.err Array of errors that occurred during 4379 the transaction, or `null` on success. 4380 @param {Get.Transaction} callback.transaction Transaction object. 4381 4382 @return {Get.Transaction} Transaction object. 4383 @static 4384 **/ 4385 css: function (urls, options, callback) { 4386 return this._load('css', urls, options, callback); 4387 }, 4388 4389 /** 4390 Loads one or more JavaScript resources. 4391 4392 The _urls_ parameter may be provided as a URL string, a request object, 4393 or an array of URL strings and/or request objects. 4394 4395 A request object is just an object that contains a `url` property and zero 4396 or more options that should apply specifically to that request. 4397 Request-specific options take priority over transaction-level options and 4398 default options. 4399 4400 URLs may be relative or absolute, and do not have to have the same origin 4401 as the current page. 4402 4403 The `options` parameter may be omitted completely and a callback passed in 4404 its place, if desired. 4405 4406 Scripts will be executed in the order they're specified unless the `async` 4407 option is `true`, in which case they'll be loaded in parallel and executed 4408 in whatever order they finish loading. 4409 4410 @example 4411 4412 // Load a single JS file and log a message on completion. 4413 Y.Get.js('foo.js', function (err) { 4414 if (err) { 4415 } else { 4416 } 4417 }); 4418 4419 // Load multiple JS files, execute them in order, and log a message when 4420 // all have finished loading. 4421 var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js']; 4422 4423 Y.Get.js(urls, function (err) { 4424 if (err) { 4425 } else { 4426 } 4427 }); 4428 4429 // Specify transaction-level options, which will apply to all requests 4430 // within the transaction. 4431 Y.Get.js(urls, { 4432 attributes: {'class': 'my-js'}, 4433 timeout : 5000 4434 }); 4435 4436 // Specify per-request options, which override transaction-level and 4437 // default options. 4438 Y.Get.js([ 4439 {url: 'foo.js', attributes: {id: 'foo'}}, 4440 {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}} 4441 ]); 4442 4443 @method js 4444 @param {String|Object|Array} urls URL string, request object, or array 4445 of URLs and/or request objects to load. 4446 @param {Object} [options] Options for this transaction. See the 4447 `Y.Get.options` property for a complete list of available options. 4448 @param {Function} [callback] Callback function to be called on completion. 4449 This is a general callback and will be called before any more granular 4450 callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options` 4451 object. 4452 4453 @param {Array|null} callback.err Array of errors that occurred during 4454 the transaction, or `null` on success. 4455 @param {Get.Transaction} callback.transaction Transaction object. 4456 4457 @return {Get.Transaction} Transaction object. 4458 @since 3.5.0 4459 @static 4460 **/ 4461 js: function (urls, options, callback) { 4462 return this._load('js', urls, options, callback); 4463 }, 4464 4465 /** 4466 Loads one or more CSS and/or JavaScript resources in the same transaction. 4467 4468 Use this method when you want to load both CSS and JavaScript in a single 4469 transaction and be notified when all requested URLs have finished loading, 4470 regardless of type. 4471 4472 Behavior and options are the same as for the `css()` and `js()` methods. If 4473 a resource type isn't specified in per-request options or transaction-level 4474 options, Get will guess the file type based on the URL's extension (`.css` 4475 or `.js`, with or without a following query string). If the file type can't 4476 be guessed from the URL, a warning will be logged and Get will assume the 4477 URL is a JavaScript resource. 4478 4479 @example 4480 4481 // Load both CSS and JS files in a single transaction, and log a message 4482 // when all files have finished loading. 4483 Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) { 4484 if (err) { 4485 } else { 4486 } 4487 }); 4488 4489 @method load 4490 @param {String|Object|Array}
4490 urls URL string, request object, or array 4491 of URLs and/or request objects to load. 4492 @param {Object} [options] Options for this transaction. See the 4493 `Y.Get.options` property for a complete list of available options. 4494 @param {Function} [callback] Callback function to be called on completion. 4495 This is a general callback and will be called before any more granular 4496 callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options` 4497 object. 4498 4499 @param {Array|null} err Array of errors that occurred during the 4500 transaction, or `null` on success. 4501 @param {Get.Transaction} Transaction object. 4502 4503 @return {Get.Transaction} Transaction object. 4504 @since 3.5.0 4505 @static 4506 **/ 4507 load: function (urls, options, callback) { 4508 return this._load(null, urls, options, callback); 4509 }, 4510 4511 // -- Protected Methods ---------------------------------------------------- 4512 4513 /** 4514 Triggers an automatic purge if the purge threshold has been reached. 4515 4516 @method _autoPurge 4517 @param {Number} threshold Purge threshold to use, in milliseconds. 4518 @protected 4519 @since 3.5.0 4520 @static 4521 **/ 4522 _autoPurge: function (threshold) { 4523 if (threshold && this._purgeNodes.length >= threshold) { 4524 this._purge(this._purgeNodes); 4525 } 4526 }, 4527 4528 /** 4529 Populates the `_env` property with information about the current 4530 environment. 4531 4532 @method _getEnv 4533 @return {Object} Environment information. 4534 @protected 4535 @since 3.5.0 4536 @static 4537 **/ 4538 _getEnv: function () { 4539 var doc = Y.config.doc, 4540 ua = Y.UA; 4541 4542 // Note: some of these checks require browser sniffs since it's not 4543 // feasible to load test files on every pageview just to perform a 4544 // feature test. I'm sorry if this makes you sad. 4545 return (this._env = { 4546 4547 // True if this is a browser that supports disabling async mode on 4548 // dynamically created script nodes. See 4549 // https://developer.mozilla.org/En/HTML/Element/Script#Attributes 4550 4551 // IE10 doesn't return true for the MDN feature test, so setting it explicitly, 4552 // because it is async by default, and allows you to disable async by setting it to false 4553 async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10), 4554 4555 // True if this browser fires an event when a dynamically injected 4556 // link node fails to load. This is currently true for Firefox 9+ 4557 // and WebKit 535.24+ 4558 cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0, 4559 4560 // True if this browser fires an event when a dynamically injected 4561 // link node finishes loading. This is currently true for IE, Opera, 4562 // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the 4563 // DOM 0 "onload" event, but not "load". All versions of IE fire 4564 // "onload". 4565 // davglass: Seems that Chrome on Android needs this to be false. 4566 cssLoad: ( 4567 (!ua.gecko && !ua.webkit) || ua.gecko >= 9 || 4568 ua.compareVersions(ua.webkit, 535.24) >= 0 4569 ) && !(ua.chrome && ua.chrome <= 18), 4570 4571 // True if this browser preserves script execution order while 4572 // loading scripts in parallel as long as the script node's `async` 4573 // attribute is set to false to explicitly disable async execution. 4574 preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10)) 4575 }); 4576 }, 4577 4578 _getTransaction: function (urls, options) { 4579 var requests = [], 4580 i, len, req, url; 4581 4582 if (!Lang.isArray(urls)) { 4583 urls = [urls]; 4584 } 4585 4586 options = Y.merge(this.options, options); 4587 4588 // Clone the attributes object so we don't end up modifying it by ref. 4589 options.attributes = Y.merge(this.options.attributes, 4590 options.attributes); 4591 4592 for (i = 0, len = urls.length; i < len; ++i) { 4593 url = urls[i]; 4594 req = {attributes: {}}; 4595 4596 // If `url` is a string, we create a URL object for it, then mix in 4597 // global options and request-specific options. If it's an object 4598 // with a "url" property, we assume it's a request object c
4598ontaining 4599 // URL-specific options. 4600 if (typeof url === 'string') { 4601 req.url = url; 4602 } else if (url.url) { 4603 // URL-specific options override both global defaults and 4604 // request-specific options. 4605 Y.mix(req, url, false, null, 0, true); 4606 url = url.url; // Make url a string so we can use it later. 4607 } else { 4608 continue; 4609 } 4610 4611 Y.mix(req, options, false, null, 0, true); 4612 4613 // If we didn't get an explicit type for this URL either in the 4614 // request options or the URL-specific options, try to determine 4615 // one from the file extension. 4616 if (!req.type) { 4617 if (this.REGEX_CSS.test(url)) { 4618 req.type = 'css'; 4619 } else { 4620 if (!this.REGEX_JS.test(url)) { 4621 } 4622 4623 req.type = 'js'; 4624 } 4625 } 4626 4627 // Mix in type-specific default options, but don't overwrite any 4628 // options that have already been set. 4629 Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions, 4630 false, null, 0, true); 4631 4632 // Give the node an id attribute if it doesn't already have one. 4633 req.attributes.id || (req.attributes.id = Y.guid()); 4634 4635 // Backcompat for <3.5.0 behavior. 4636 if (req.win) { 4637 req.doc = req.win.document; 4638 } else { 4639 req.win = req.doc.defaultView || req.doc.parentWindow; 4640 } 4641 4642 if (req.charset) { 4643 req.attributes.charset = req.charset; 4644 } 4645 4646 requests.push(req); 4647 } 4648 4649 return new Transaction(requests, options); 4650 }, 4651 4652 _load: function (type, urls, options, callback) { 4653 var transaction; 4654 4655 // Allow callback as third param. 4656 if (typeof options === 'function') { 4657 callback = options; 4658 options = {}; 4659 } 4660 4661 options || (options = {}); 4662 options.type = type; 4663 4664 options._onFinish = Get._onTransactionFinish; 4665 4666 if (!this._env) { 4667 this._getEnv(); 4668 } 4669 4670 transaction = this._getTransaction(urls, options); 4671 4672 this._queue.push({ 4673 callback : callback, 4674 transaction: transaction 4675 }); 4676 4677 this._next(); 4678 4679 return transaction; 4680 }, 4681 4682 _onTransactionFinish : function() { 4683 Get._pending = null; 4684 Get._next(); 4685 }, 4686 4687 _next: function () { 4688 var item; 4689 4690 if (this._pending) { 4691 return; 4692 } 4693 4694 item = this._queue.shift(); 4695 4696 if (item) { 4697 this._pending = item; 4698 item.transaction.execute(item.callback); 4699 } 4700 }, 4701 4702 _purge: function (nodes) { 4703 var purgeNodes = this._purgeNodes, 4704 isTransaction = nodes !== purgeNodes, 4705 index, node; 4706 4707 while (node = nodes.pop()) { // assignment 4708 // Don't purge nodes that haven't finished loading (or errored out), 4709 // since this can hang the transaction. 4710 if (!node._yuiget_finished) { 4711 continue; 4712 } 4713 4714 node.parentNode && node.parentNode.removeChild(node); 4715 4716 // If this is a transaction-level purge and this node also exists in 4717 // the Get-level _purgeNodes array, we need to remove it from 4718 // _purgeNodes to avoid creating a memory leak. The indexOf lookup 4719 // sucks, but until we get WeakMaps, this is the least troublesome 4720 // way to do this (we can't just hold onto node ids because they may 4721 // not be in the same document). 4722 if (isTransaction) { 4723 index = Y.Array.indexOf(purgeNodes, node); 4724 4725 if (index > -1) { 4726 purgeNodes.splice(index, 1); 4727 } 4728 } 4729 } 4730 } 4731}; 4732 4733/** 4734Alias for `js()`. 4735 4736@method script 4737@static 4738**/ 4739Get.script = Get.js; 4740 4741/** 4742Represents a Get transaction, which may contain requests for one or more JS or 4743CSS files. 4744 4745This class should not be instantiated manually. Instances will be created and
4746returned as needed by Y.Get's `css()`, `js()`, and `load()` methods. 4747 4748@class Get.Transaction 4749@constructor 4750@since 3.5.0 4751**/ 4752Get.Transaction = Transaction = function (requests, options) { 4753 var self = this; 4754 4755 self.id = Transaction._lastId += 1; 4756 self.data = options.data; 4757 self.errors = []; 4758 self.nodes = []; 4759 self.options = options; 4760 self.requests = requests; 4761 4762 self._callbacks = []; // callbacks to call after execution finishes 4763 self._queue = []; 4764 self._reqsWaiting = 0; 4765 4766 // Deprecated pre-3.5.0 properties. 4767 self.tId = self.id; // Use `id` instead. 4768 self.win = options.win || Y.config.win; 4769}; 4770 4771/** 4772Arbitrary data object associated with this transaction. 4773 4774This object comes from the options passed to `Get.css()`, `Get.js()`, or 4775`Get.load()`, and will be `undefined` if no data object was specified. 4776 4777@property {Object} data 4778**/ 4779 4780/** 4781Array of errors that have occurred during this transaction, if any. Each error 4782object has the following properties: 4783`errors.error`: Error message. 4784`errors.request`: Request object related to the error. 4785 4786@since 3.5.0 4787@property {Object[]} errors 4788**/ 4789 4790/** 4791Numeric id for this transaction, unique among all transactions within the same 4792YUI sandbox in the current pageview. 4793 4794@property {Number} id 4795@since 3.5.0 4796**/ 4797 4798/**
4799HTMLElement nodes (native ones, not YUI Node instances) that have been inserted 4800during the current transaction. 4801 4802@property {HTMLElement[]} nodes 4803**/ 4804 4805/** 4806Options associated with this transaction. 4807 4808See `Get.options` for the full list of available options. 4809 4810@property {Object} options 4811@since 3.5.0 4812**/ 4813 4814/** 4815Request objects contained in this transaction. Each request object represents 4816one CSS or JS URL that will be (or has been) requested and loaded into the page. 4817 4818@property {Object} requests 4819@since 3.5.0 4820**/ 4821 4822/** 4823Id of the most recent transaction. 4824 4825@property _lastId 4826@type Number 4827@protected 4828@static 4829**/ 4830Transaction._lastId = 0; 4831 4832Transaction.prototype = { 4833 // -- Public Properties ---------------------------------------------------- 4834 4835 /** 4836 Current state of this transaction. One of "new", "executing", or "done". 4837 4838 @property _state 4839 @type String 4840 @protected 4841 **/ 4842 _state: 'new', // "new", "executing", or "done" 4843 4844 // -- Public Methods ------------------------------------------------------- 4845 4846 /** 4847 Aborts this transaction. 4848 4849 This will cause the transaction's `onFailure` callback to be called and 4850 will prevent any new script and link nodes from being added to the document, 4851 but any resources that have already been requested will continue loading 4852 (there's no safe way to prevent this, unfortunately). 4853 4854 @method abort 4855 @param {String} [msg="Aborted."] Optional message to use in the `errors` 4856 array describing why the transaction was aborted. 4857 **/ 4858 abort: function (msg) { 4859 this._pending = null; 4860 this._pendingCSS = null; 4861 this._pollTimer = clearTimeout(this._pollTimer); 4862 this._queue = []; 4863 this._reqsWaiting = 0; 4864 4865 this.errors.push({error: msg || 'Aborted'}); 4866 this._finish(); 4867 }, 4868 4869 /** 4870 Begins execting the transaction. 4871 4872 There's usually no reason to call this manually, since Get will call it 4873 automatically when other pending transactions have finished. If you really 4874 want to execute your transaction before Get does, you can, but be aware that 4875 this transaction's scripts may end up executing before the scripts in other 4876 pending transactions. 4877 4878 If the transaction is already executing, the specified callback (if any) 4879 will be queued and called after execution finishes. If the transaction has 4880 already finished, the callback will be called immediately (the transaction 4881 will not be executed again). 4882 4883 @method execute 4884 @param {Function} callback Callback function to execute after all requests 4885 in the transaction are complete, or after the transaction is aborted. 4886 **/ 4887 execute: function (callback) { 4888 var self = this, 4889 requests = self.requests, 4890 state = self._state, 4891 i, len, queue, req; 4892 4893 if (state === 'done') { 4894 callback && callback(self.errors.length ? self.errors : null, self); 4895 return; 4896 } else { 4897 callback && self._callbacks.push(callback); 4898 4899 if (state === 'executing') { 4900 return; 4901 } 4902 } 4903 4904 self._state = 'executing'; 4905 self._queue = queue = []; 4906 4907 if (self.options.timeout) { 4908 self._timeout = setTimeout(function () { 4909 self.abort('Timeout'); 4910 }, self.options.timeout); 4911 } 4912 4913 self._reqsWaiting = requests.length; 4914 4915 for (i = 0, len = requests.length; i < len; ++i) { 4916 req = requests[i]; 4917 4918 if (req.async || req.type === 'css') { 4919 // No need to queue CSS or fully async JS. 4920 self._insert(req); 4921 } else { 4922 queue.push(req); 4923 } 4924 } 4925 4926 self._next(); 4927 }, 4928 4929 /** 4930 Manually purges any `<script>` or `<link>` nodes this transaction has 4931 created. 4932 4933 Be careful when purging a transaction that contains CSS requests, since 4934 removing `<link>` nodes will also remove any styles they applied. 4935 4936 @method purge 4937 **/ 4938 purge: function () { 4939 Get._purge(this.nodes); 4940 }, 4941 4942 // -- Protected Methods ---------------------------------------------------- 4943 _createNode: function (name, attrs, doc) { 4944 var node = doc.createElement(name), 4945 attr, testEl; 4946 4947 if (!CUSTOM_ATTRS) { 4948 // IE6 and IE7 expect property names rather than attribute names for 4949 // certain attributes. Rather than sniffing, we do a quick feature 4950 // test the first time _createNode() runs to determine whether we 4951 // need to provide a workaround. 4952 testEl = doc.createElement('div'); 4953 testEl.setAttribute('class', 'a'); 4954 4955 CUSTOM_ATTRS = testEl.className === 'a' ? {} : { 4956 'for' : 'htmlFor', 4957 'class': 'className' 4958 }; 4959 } 4960 4961 for (attr in attrs) { 4962 if (attrs.hasOwnProperty(attr)) { 4963 node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]); 4964 } 4965 } 4966 4967 return node; 4968 }, 4969 4970 _finish: function () { 4971 var errors = this.errors.length ? this.errors : null, 4972 options = this.options, 4973 thisObj = options.context || this, 4974 data, i, len; 4975 4976 if (this._state === 'done') { 4977 return; 4978 } 4979 4980 this._state = 'done'; 4981 4982 for (i = 0, len = this._callbacks.length; i < len; ++i) { 4983 this._callbacks[i].call(thisObj, errors, this); 4984 } 4985 4986 data = this._getEventData(); 4987 4988 if (errors) {
4989 if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') { 4990 options.onTimeout.call(thisObj, data); 4991 } 4992 4993 if (options.onFailure) { 4994 options.onFailure.call(thisObj, data); 4995 } 4996 } else if (options.onSuccess) { 4997 options.onSuccess.call(thisObj, data); 4998 } 4999 5000 if (options.onEnd) { 5001 options.onEnd.call(thisObj, data); 5002 } 5003 5004 if (options._onFinish) { 5005 options._onFinish(); 5006 } 5007 }, 5008 5009 _getEventData: function (req) { 5010 if (req) { 5011 // This merge is necessary for backcompat. I hate it. 5012 return Y.merge(this, { 5013 abort : this.abort, // have to copy these because the prototype isn't preserved 5014 purge : this.purge, 5015 request: req, 5016 url : req.url, 5017 win : req.win 5018 }); 5019 } else { 5020 return this; 5021 } 5022 }, 5023 5024 _getInsertBefore: function (req) { 5025 var doc = req.doc, 5026 el = req.insertBefore, 5027 cache, docStamp; 5028 5029 if (el) { 5030 return typeof el === 'string' ? doc.getElementById(el) : el; 5031 } 5032 5033 cache = Get._insertCache; 5034 docStamp = Y.stamp(doc); 5035 5036 if ((el = cache[docStamp])) { // assignment 5037 return el; 5038 } 5039 5040 // Inserting before a <base> tag apparently works around an IE bug 5041 // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what 5042 // bug that is, exactly. Better safe than sorry? 5043 if ((el = doc.getElementsByTagName('base')[0])) { // assignment 5044 return (cache[docStamp] = el); 5045 } 5046 5047 // Look for a <head> element. 5048 el = doc.head || doc.getElementsByTagName('head')[0]; 5049 5050 if (el) { 5051 // Create a marker node at the end of <head> to use as an insertion 5052 // point. Inserting before this node will ensure that all our CSS 5053 // gets inserted in the correct order, to maintain style precedence. 5054 el.appendChild(doc.createTextNode('')); 5055 return (cache[docStamp] = el.lastChild); 5056 } 5057 5058 // If all else fails, just insert before the first script node on the 5059 // page, which is virtually guaranteed to exist. 5060 return (cache[docStamp] = doc.getElementsByTagName('script')[0]); 5061 }, 5062 5063 _insert: function (req) { 5064 var env = Get._env, 5065 insertBefore = this._getInsertBefore(req), 5066 isScript = req.type === 'js', 5067 node = req.node, 5068 self = this, 5069 ua = Y.UA, 5070 cssTimeout, nodeType; 5071 5072 if (!node) { 5073 if (isScript) { 5074 nodeType = 'script'; 5075 } else if (!env.cssLoad && ua.gecko) { 5076 nodeType = 'style'; 5077 } else { 5078 nodeType = 'link'; 5079 delete req.attributes['charset']; 5080 } 5081 5082 node = req.node = this._createNode(nodeType, req.attributes, 5083 req.doc); 5084 } 5085 5086 function onError() { 5087 self._progress('Failed to load ' + req.url, req); 5088 } 5089 5090 function onLoad() { 5091 if (cssTimeout) { 5092 clearTimeout(cssTimeout); 5093 } 5094 5095 self._progress(null, req); 5096 } 5097 5098 // Deal with script asynchronicity. 5099 if (isScript) { 5100 node.setAttribute('src', req.url); 5101 5102 if (req.async) { 5103 // Explicitly indicate that we want the browser to execute this 5104 // script asynchronously. This is necessary for older browsers 5105 // like Firefox <4. 5106 node.async = true; 5107 } else { 5108 if (env.async) { 5109 // This browser treats injected scripts as async by default 5110 // (standard HTML5 behavior) but asynchronous loading isn't 5111 // desired, so tell the browser not to mark this script as 5112 // async. 5113 node.async = false;
5114 } 5115 5116 // If this browser doesn't preserve script execution order based 5117 // on insertion order, we'll need to avoid inserting other 5118 // scripts until this one finishes loading. 5119 if (!env.preservesScriptOrder) { 5120 this._pending = req; 5121 } 5122 } 5123 } else { 5124 if (!env.cssLoad && ua.gecko) { 5125 // In Firefox <9, we can import the requested URL into a <style> 5126 // node and poll for the existence of node.sheet.cssRules. This 5127 // gives us a reliable way to determine CSS load completion that 5128 // also works for cross-domain stylesheets. 5129 // 5130 // Props to Zach Leatherman for calling my attention to this 5131 // technique. 5132 node.innerHTML = (req.attributes.charset ? 5133 '@charset "' + req.attributes.charset + '";' : '') + 5134 '@import "' + req.url + '";'; 5135 } else { 5136 node.setAttribute('href', req.url); 5137 } 5138 } 5139 5140 // Inject the node. 5141 if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) { 5142 // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode. 5143 node.onreadystatechange = function () { 5144 if (/loaded|complete/.test(node.readyState)) { 5145 node.onreadystatechange = null; 5146 onLoad(); 5147 } 5148 }; 5149 } else if (!isScript && !env.cssLoad) { 5150 // CSS on Firefox <9 or WebKit. 5151 this._poll(req); 5152 } else { 5153 // Script or CSS on everything else. Using DOM 0 events because that 5154 // evens the playing field with older IEs. 5155 5156 if (ua.ie >= 10) { 5157 5158 // We currently need to introduce a timeout for IE10, since it 5159 // calls onerror/onload synchronously for 304s - messing up existing 5160 // program flow. 5161 5162 // Remove this block if the following bug gets fixed by GA 5163 /*jshint maxlen: 1500 */ 5164 // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload 5165 node.onerror = function() { setTimeout(onError, 0); }; 5166 node.onload = function() { setTimeout(onLoad, 0); }; 5167 } else { 5168 node.onerror = onError; 5169 node.onload = onLoad; 5170 } 5171 5172 // If this browser doesn't fire an event when CSS fails to load, 5173 // fail after a timeout to avoid blocking the transaction queue. 5174 if (!env.cssFail && !isScript) { 5175 cssTimeout = setTimeout(onError, req.timeout || 3000); 5176 } 5177 } 5178 5179 this.nodes.push(node); 5180 insertBefore.parentNode.insertBefore(node, insertBefore); 5181 }, 5182 5183 _next: function () { 5184 if (this._pending) { 5185 return; 5186 } 5187 5188 // If there are requests in the queue, insert the next queued request. 5189 // Otherwise, if we're waiting on already-inserted requests to finish, 5190 // wait longer. If there are no queued requests and we're not waiting 5191 // for anything to load, then we're done! 5192 if (this._queue.length) { 5193 this._insert(this._queue.shift()); 5194 } else if (!this._reqsWaiting) { 5195 this._finish(); 5196 } 5197 }, 5198 5199 _poll: function (newReq) { 5200 var self = this, 5201 pendingCSS = self._pendingCSS, 5202 isWebKit = Y.UA.webkit, 5203 i, hasRules, j, nodeHref, req, sheets; 5204 5205 if (newReq) { 5206 pendingCSS || (pendingCSS = self._pendingCSS = []); 5207 pendingCSS.push(newReq); 5208 5209 if (self._pollTimer) { 5210 // A poll timeout is already pending, so no need to create a 5211 // new one. 5212 return; 5213 } 5214 } 5215 5216 self._pollTimer = null; 5217 5218 // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s 5219 // will still be treated as a success. There's no good workaround for 5220 // this. 5221 5222 for (i = 0; i < pendingCSS.length; ++i) { 5223 req = pendingCSS[i]; 5224 5225 if (isWebKit) { 5226 // Look for a stylesheet matching the pending URL. 5227 sheets = req.doc.styleSheets; 5228 j = sheets.length; 5229 nodeHref = req.node.href; 5230 5231 while (--j >= 0) { 5232 if (sheets[j].href === nodeHref) { 5233 pendingCSS.splice(i, 1); 5234 i -= 1; 5235 self._progress(null, req); 5236 break; 5237 } 5238 } 5239 } else { 5240 // Many thanks to Zach Leatherman for calling my attention to 5241 // the @import-based cross-domain technique used here, and to 5242 // Oleg Slobodskoi for an earlier same-domain implementation. 5243 // 5244 // See Zach's blog for more details: 5245 // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/ 5246 try { 5247 // We don't really need to store this value since we never 5248 // use it again, but if we don't store it, Closure Compiler 5249 // assumes the code is useless and removes it.
5250 hasRules = !!req.node.sheet.cssRules; 5251 5252 // If we get here, the stylesheet has loaded. 5253 pendingCSS.splice(i, 1); 5254 i -= 1; 5255 self._progress(null, req); 5256 } catch (ex) { 5257 // An exception means the stylesheet is still loading. 5258 } 5259 } 5260 } 5261 5262 if (pendingCSS.length) { 5263 self._pollTimer = setTimeout(function () { 5264 self._poll.call(self); 5265 }, self.options.pollInterval); 5266 } 5267 }, 5268 5269 _progress: function (err, req) { 5270 var options = this.options; 5271 5272 if (err) { 5273 req.error = err; 5274 5275 this.errors.push({ 5276 error : err, 5277 request: req 5278 }); 5279 5280 } 5281 5282 req.node._yuiget_finished = req.finished = true; 5283 5284 if (options.onProgress) { 5285 options.onProgress.call(options.context || this, 5286 this._getEventData(req)); 5287 } 5288 5289 if (req.autopurge) { 5290 // Pre-3.5.0 Get always excludes the most recent node from an 5291 // autopurge. I find this odd, but I'm keeping that behavior for 5292 // the sake of backcompat. 5293 Get._autoPurge(this.options.purgethreshold); 5294 Get._purgeNodes.push(req.node); 5295 } 5296 5297 if (this._pending === req) { 5298 this._pending = null; 5299 } 5300 5301 this._reqsWaiting -= 1; 5302 5303 this._next(); 5304 } 5305}; 5306 5307 5308}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5309YUI.add('features', function (Y, NAME) { 5310 5311var feature_tests = {}; 5312 5313/** 5314Contains the core of YUI's feature test architecture. 5315@module features 5316*/ 5317 5318/** 5319* Feature detection 5320* @class Features 5321* @static 5322*/ 5323 5324Y.mix(Y.namespace('Features'), { 5325 5326 /** 5327 * Object hash of all registered feature tests 5328 * @property tests 5329 * @type Object 5330 */ 5331 tests: feature_tests, 5332 5333 /** 5334 * Add a test to the system 5335 * 5336 * ``` 5337 * Y.Features.add("load", "1", {}); 5338 * ``` 5339 * 5340 * @method add 5341 * @param {String} cat The category, right now only 'load' is supported 5342 * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3 5343 * @param {Object} o Object containing test properties 5344 * @param {String} o.name The name of the test 5345 * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance 5346 * @param {String} o.trigger The module that triggers this test. 5347 */ 5348 add: function(cat, name, o) { 5349 feature_tests[cat] = feature_tests[cat] || {}; 5350 feature_tests[cat][name] = o; 5351 }, 5352 /** 5353 * Execute all tests of a given category and return the serialized results 5354 * 5355 * ``` 5356 * caps=1:1;2:1;3:0 5357 * ``` 5358 * @method all 5359 * @param {String} cat The category to execute 5360 * @param {Array} args The arguments to pass to the test function 5361 * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0 5362 */ 5363 all: function(cat, args) { 5364 var cat_o = feature_tests[cat], 5365 // results = {}; 5366 result = []; 5367 if (cat_o) { 5368 Y.Object.each(cat_o, function(v, k) { 5369 result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0)); 5370 }); 5371 } 5372 5373 return (result.length) ? result.join(';') : ''; 5374 }, 5375 /** 5376 * Run a specific test and return a Boolean response. 5377 * 5378 * ``` 5379 * Y.Features.test("load", "1"); 5380 * ``` 5381 * 5382 * @method test 5383 * @param {String} cat The category of the test to run 5384 * @param {String} name The name of the test to run 5385 * @param {Array} args The arguments to pass to the test function 5386 * @return {Boolean} True or false if the test passed/failed. 5387 */ 5388 test: function(cat, name, args) { 5389 args = args || []; 5390 var result, ua, test, 5391 cat_o = feature_tests[cat], 5392 feature = cat_o && cat_o[name]; 5393 5394 if (!feature) { 5395 } else { 5396 5397 result = feature.result; 5398 5399 if (Y.Lang.isUndefined(result)) { 5400 5401 ua = feature.ua; 5402 if (ua) { 5403 result = (Y.UA[ua]); 5404 } 5405 5406 test = feature.test; 5407 if (test && ((!ua) || result)) { 5408 result = test.apply(Y, args); 5409 } 5410 5411 feature.result = result; 5412 } 5413 } 5414 5415 return result; 5416 } 5417}); 5418 5419// Y.Features.add("load", "1", {}); 5420// Y.Features.test("load", "1"); 5421// caps=1:1;2:0;3:1; 5422 5423/* This file is auto-generated by (yogi loader --yes --mix --start ../) */ 5424/*jshint maxlen:900, eqeqeq: false */ 5425var add = Y.Features.add; 5426// app-transitions-native 5427add('load', '0', { 5428 "name": "app-transitions-native", 5429 "test": function (Y) { 5430 var doc = Y.config.doc, 5431 node = doc ? doc.documentElement : null; 5432 5433 if (node && node.style) { 5434 return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 5435 } 5436 5437 return false;
5438}, 5439 "trigger": "app-transitions" 5440}); 5441// autocomplete-list-keys 5442add('load', '1', { 5443 "name": "autocomplete-list-keys", 5444 "test": function (Y) { 5445 // Only add keyboard support to autocomplete-list if this doesn't appear to 5446 // be an iOS or Android-based mobile device. 5447 // 5448 // There's currently no feasible way to actually detect whether a device has 5449 // a hardware keyboard, so this sniff will have to do. It can easily be 5450 // overridden by manually loading the autocomplete-list-keys module. 5451 // 5452 // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari 5453 // doesn't fire the keyboard events used by AutoCompleteList, so there's 5454 // no point loading the -keys module even when a bluetooth keyboard may be 5455 // available. 5456 return !(Y.UA.ios || Y.UA.android); 5457}, 5458 "trigger": "autocomplete-list" 5459}); 5460// dd-gestures 5461add('load', '2', { 5462 "name": "dd-gestures", 5463 "trigger": "dd-drag", 5464 "ua": "touchEnabled" 5465}); 5466// dom-style-ie 5467add('load', '3', { 5468 "name": "dom-style-ie", 5469 "test": function (Y) { 5470 5471 var testFeature = Y.Features.test, 5472 addFeature = Y.Features.add, 5473 WINDOW = Y.config.win, 5474 DOCUMENT = Y.config.doc, 5475 DOCUMENT_ELEMENT = 'documentElement', 5476 ret = false;
5477 5478 addFeature('style', 'computedStyle', { 5479 test: function() { 5480 return WINDOW && 'getComputedStyle' in WINDOW; 5481 } 5482 }); 5483 5484 addFeature('style', 'opacity', { 5485 test: function() { 5486 return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style; 5487 } 5488 }); 5489 5490 ret = (!testFeature('style', 'opacity') && 5491 !testFeature('style', 'computedStyle')); 5492 5493 return ret; 5494}, 5495 "trigger": "dom-style" 5496}); 5497// editor-para-ie 5498add('load', '4', { 5499 "name": "editor-para-ie", 5500 "trigger": "editor-para", 5501 "ua": "ie", 5502 "when": "instead" 5503}); 5504// event-base-ie 5505add('load', '5', { 5506 "name": "event-base-ie", 5507 "test": function(Y) { 5508 var imp = Y.config.doc && Y.config.doc.implementation; 5509 return (imp && (!imp.hasFeature('Events', '2.0'))); 5510}, 5511 "trigger": "node-base" 5512}); 5513// graphics-canvas 5514add('load', '6', { 5515 "name": "graphics-canvas", 5516 "test": function(Y) { 5517 var DOCUMENT = Y.config.doc, 5518 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", 5519 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5520 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5521 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 5522}, 5523 "trigger": "graphics" 5524}); 5525// graphics-canvas-default 5526add('load', '7', { 5527 "name": "graphics-canvas-default", 5528 "test": function(Y) { 5529 var DOCUMENT = Y.config.doc, 5530 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", 5531 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5532 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5533 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 5534}, 5535 "trigger": "graphics" 5536}); 5537// graphics-svg 5538add('load', '8', { 5539 "name": "graphics-svg", 5540 "test": function(Y) { 5541 var DOCUMENT = Y.config.doc, 5542 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 5543 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5544 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5545 5546 return svg && (useSVG || !canvas); 5547}, 5548 "trigger": "graphics" 5549}); 5550// graphics-svg-default 5551add('load', '9', { 5552 "name": "graphics-svg-default", 5553 "test": function(Y) { 5554 var DOCUMENT = Y.config.doc, 5555 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 5556 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5557 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5558 5559 return svg && (useSVG || !canvas); 5560}, 5561 "trigger": "graphics" 5562}); 5563// graphics-vml 5564add('load', '10', { 5565 "name": "graphics-vml", 5566 "test": function(Y) { 5567 var DOCUMENT = Y.config.doc, 5568 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 5569 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 5570}, 5571 "trigger": "graphics" 5572}); 5573// graphics-vml-default 5574add('load', '11', { 5575 "name": "graphics-vml-default", 5576 "test": function(Y) { 5577 var DOCUMENT = Y.config.doc, 5578 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 5579 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 5580}, 5581 "trigger": "graphics" 5582}); 5583// history-hash-ie 5584add('load', '12', { 5585 "name": "history-hash-ie", 5586 "test": function (Y) { 5587 var docMode = Y.config.doc && Y.config.doc.documentMode; 5588 5589 return Y.UA.ie && (!('onhashchange' in Y.config.win) || 5590 !docMode || docMode < 8); 5591}, 5592 "trigger": "history-hash" 5593}); 5594// io-nodejs 5595add('load', '13', { 5596 "name": "io-nodejs", 5597 "trigger": "io-base", 5598 "ua": "nodejs" 5599}); 5600// json-parse-shim 5601add('load', '14', { 5602 "name": "json-parse-shim", 5603 "test": function (Y) { 5604 var _JSON = Y.config.global.JSON, 5605 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 5606 nativeSupport = Y.config.useNativeJSONParse !== false && !!Native; 5607 5608 function workingNative( k, v ) { 5609 return k === "ok" ? true : v; 5610 } 5611 5612 // Double check basic functionality. This is mainly to catch early broken 5613 // implementations of the JSON API in Firefox 3.1 beta1 and beta2
5614 if ( nativeSupport ) { 5615 try { 5616 nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok; 5617 } 5618 catch ( e ) { 5619 nativeSupport = false; 5620 } 5621 } 5622 5623 return !nativeSupport; 5624}, 5625 "trigger": "json-parse" 5626}); 5627// json-stringify-shim 5628add('load', '15', { 5629 "name": "json-stringify-shim", 5630 "test": function (Y) { 5631 var _JSON = Y.config.global.JSON, 5632 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 5633 nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native; 5634 5635 // Double check basic native functionality. This is primarily to catch broken 5636 // early JSON API implementations in Firefox 3.1 beta1 and beta2. 5637 if ( nativeSupport ) { 5638 try { 5639 nativeSupport = ( '0' === Native.stringify(0) ); 5640 } catch ( e ) { 5641 nativeSupport = false; 5642 } 5643 } 5644 5645 5646 return !nativeSupport; 5647}, 5648 "trigger": "json-stringify" 5649}); 5650// scrollview-base-ie 5651add('load', '16', { 5652 "name": "scrollview-base-ie", 5653 "trigger": "scrollview-base", 5654 "ua": "ie" 5655}); 5656// selector-css2 5657add('load', '17', { 5658 "name": "selector-css2", 5659 "test": function (Y) { 5660 var DOCUMENT = Y.config.doc, 5661 ret = DOCUMENT && !('querySelectorAll' in DOCUMENT); 5662 5663 return ret; 5664}, 5665 "trigger": "selector" 5666}); 5667// transition-timer 5668add('load', '18', { 5669 "name": "transition-timer", 5670 "test": function (Y) { 5671 var DOCUMENT = Y.config.doc, 5672 node = (DOCUMENT) ? DOCUMENT.documentElement: null, 5673 ret = true; 5674 5675 if (node && node.style) { 5676 ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 5677 } 5678 5679 return ret; 5680}, 5681 "trigger": "transition" 5682}); 5683// widget-base-ie 5684add('load', '19', { 5685 "name": "widget-base-ie", 5686 "trigger": "widget-base", 5687 "ua": "ie" 5688}); 5689// yql-jsonp 5690add('load', '20', { 5691 "name": "yql-jsonp", 5692 "test": function (Y) { 5693 /* Only load the JSONP module when not in nodejs or winjs 5694 TODO Make the winjs module a CORS module 5695 */ 5696 return (!Y.UA.nodejs && !Y.UA.winjs); 5697}, 5698 "trigger": "yql" 5699}); 5700// yql-nodejs 5701add('load', '21', { 5702 "name": "yql-nodejs", 5703 "trigger": "yql", 5704 "ua": "nodejs" 5705}); 5706// yql-winjs 5707add('load', '22', { 5708 "name": "yql-winjs", 5709 "trigger": "yql", 5710 "ua": "winjs" 5711}); 5712 5713}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5714YUI.add('intl-base', function (Y, NAME) { 5715 5716/** 5717 * The Intl utility provides a central location for managing sets of 5718 * localized resources (strings and formatting patterns). 5719 * 5720 * @class Intl 5721 * @uses EventTarget 5722 * @static 5723 */ 5724 5725var SPLIT_REGEX = /[, ]/; 5726 5727Y.mix(Y.namespace('Intl'), { 5728 5729 /** 5730 * Returns the language among those available that 5731 * best matches the preferred language list, using the Lookup 5732 * algorithm of BCP 47. 5733 * If none of the available languages meets the user's preferences, 5734 * then "" is returned. 5735 * Extended language ranges are not supported. 5736 * 5737 * @method lookupBestLang 5738 * @param {String[] | String} preferredLanguages The list of preferred 5739 * languages in descending preference order, represented as BCP 47 5740 * language tags. A string array or a comma-separated list. 5741 * @param {String[]} availableLanguages The list of languages 5742 * that the application supports, represented as BCP 47 language 5743 * tags. 5744 * 5745 * @return {String} The available language that best matches the 5746 * preferred language list, or "". 5747 * @since 3.1.0 5748 */ 5749 lookupBestLang: function(preferredLanguages, availableLanguages) { 5750 5751 var i, language, result, index; 5752 5753 // check whether the list of available languages contains language; 5754 // if so return it 5755 function scan(language) { 5756 var i; 5757 for (i = 0; i < availableLanguages.length; i += 1) { 5758 if (language.toLowerCase() === 5759 availableLanguages[i].toLowerCase()) { 5760 return availableLanguages[i]; 5761 } 5762 } 5763 } 5764
5765 if (Y.Lang.isString(preferredLanguages)) { 5766 preferredLanguages = preferredLanguages.split(SPLIT_REGEX); 5767 } 5768 5769 for (i = 0; i < preferredLanguages.length; i += 1) { 5770 language = preferredLanguages[i]; 5771 if (!language || language === '*') { 5772 continue; 5773 } 5774 // check the fallback sequence for one language 5775 while (language.length > 0) { 5776 result = scan(language); 5777 if (result) { 5778 return result; 5779 } else { 5780 index = language.lastIndexOf('-'); 5781 if (index >= 0) { 5782 language = language.substring(0, index); 5783 // one-character subtags get cut along with the 5784 // following subtag 5785 if (index >= 2 && language.charAt(index - 2) === '-') { 5786 language = language.substring(0, index - 2); 5787 } 5788 } else { 5789 // nothing available for this language 5790 break; 5791 } 5792 } 5793 } 5794 } 5795 5796 return ''; 5797 } 5798}); 5799 5800 5801}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5802YUI.add('yui-log', function (Y, NAME) { 5803 5804/** 5805 * Provides console log capability and exposes a custom event for 5806 * console implementations. This module is a `core` YUI module, 5807 * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>. 5808 * 5809 * @module yui 5810 * @submodule yui-log 5811 */ 5812 5813var INSTANCE = Y, 5814 LOGEVENT = 'yui:log', 5815 UNDEFINED = 'undefined', 5816 LEVELS = { debug: 1, 5817 info: 2, 5818 warn: 4, 5819 error: 8 }; 5820 5821/** 5822 * If the 'debug' config is true, a 'yui:log' event will be 5823 * dispatched, which the Console widget and anything else 5824 * can consume. If the 'useBrowserConsole' config is true, it will 5825 * write to the browser console if available. YUI-specific log 5826 * messages will only be present in the -debug versions of the 5827 * JS files. The build system is supposed to remove log statements 5828 * from the raw and minified versions of the files. 5829 * 5830 * @method log 5831 * @for YUI 5832 * @param {String} msg The message to log. 5833 * @param {String} cat The log category for the message. Default 5834 * categories are "info", "warn", "error", "debug". 5835 * Custom categories can be used as well. (opt). 5836 * @param {String} src The source of the the message (opt). 5837 * @param {boolean} silent If true, the log event won't fire. 5838 * @return {YUI} YUI instance. 5839 */ 5840INSTANCE.log = function(msg, cat, src, silent) { 5841 var bail, excl, incl, m, f, minlevel, 5842 Y = INSTANCE, 5843 c = Y.config, 5844 publisher = (Y.fire) ? Y : YUI.Env.globalEvents; 5845 // suppress log message if the config is off or the event stack 5846 // or the event call stack contains a consumer of the yui:log event 5847 if (c.debug) { 5848 // apply source filters 5849 src = src || ""; 5850 if (typeof src !== "undefined") { 5851 excl = c.logExclude; 5852 incl = c.logInclude; 5853 if (incl && !(src in incl)) { 5854 bail = 1; 5855 } else if (incl && (src in incl)) { 5856 bail = !incl[src]; 5857 } else if (excl && (src in excl)) { 5858 bail = excl[src]; 5859 } 5860 5861 // Set a default category of info if the category was not defined. 5862 if ((typeof cat === 'undefined')) { 5863 cat = 'info'; 5864 } 5865 5866 // Determine the current minlevel as defined in configuration 5867 Y.config.logLevel = Y.config.logLevel || 'debug'; 5868 minlevel = LEVELS[Y.config.logLevel.toLowerCase()]; 5869 5870 if (cat in LEVELS && LEVELS[cat] < minlevel) { 5871 // Skip this message if the we don't meet the defined minlevel 5872 bail = 1; 5873 } 5874 } 5875 if (!bail) { 5876 if (c.useBrowserConsole) { 5877 m = (src) ? src + ': ' + msg : msg; 5878 if (Y.Lang.isFunction(c.logFn)) { 5879 c.logFn.call(Y, msg, cat, src); 5880 } else if (typeof console !== UNDEFINED && console.log) { 5881 f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log'; 5882 console[f](m); 5883 } else if (typeof opera !== UNDEFINED) { 5884 opera.postError(m); 5885 } 5886 } 5887 5888 if (publisher && !silent) { 5889 5890 if (publisher === Y && (!publisher.getEvent(LOGEVENT))) { 5891 publisher.publish(LOGEVENT, { 5892 broadcast: 2 5893 }); 5894 } 5895 5896 publisher.fire(LOGEVENT, { 5897 msg: msg, 5898 cat: cat, 5899 src: src 5900 }); 5901 } 5902 } 5903 } 5904 5905 return Y; 5906}; 5907 5908/** 5909 * Write a system message. This message will be preserved in the 5910 * minified and raw versions of the YUI files, unlike log statements. 5911 * @method message 5912 * @for YUI 5913 * @param {String} msg The message to log. 5914 * @param {String} cat The log category for the message. Default 5915 * categories are "info", "warn", "error", "debug". 5916 * Custom categories can be used as well. (opt). 5917 * @param {String} src The source of the the message (opt). 5918 * @param {boolean} silent If true, the log event won't fire. 5919 * @return {YUI} YUI instance. 5920 */ 5921INSTANCE.message = function() { 5922 return INSTANCE.log.apply(INSTANCE, arguments); 5923}; 5924 5925 5926}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5927YUI.add('yui-later', function (Y, NAME) { 5928 5929/** 5930 * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module, 5931 * <a href="../classes/YUI.html#method_later">
5931it's documentation is located under the YUI class</a>. 5932 * 5933 * @module yui 5934 * @submodule yui-later 5935 */ 5936 5937var NO_ARGS = []; 5938 5939/** 5940 * Executes the supplied function in the context of the supplied 5941 * object 'when' milliseconds later. Executes the function a 5942 * single time unless periodic is set to true. 5943 * @for YUI 5944 * @method later 5945 * @param when {Number} the number of milliseconds to wait until the fn 5946 * is executed. 5947 * @param o the context object. 5948 * @param fn {Function|String} the function to execute or the name of 5949 * the method in the 'o' object to execute. 5950 * @param data [Array] data that is provided to the function. This 5951 * accepts either a single item or an array. If an array is provided, 5952 * the function is executed with one parameter for each array item. 5953 * If you need to pass a single array parameter, it needs to be wrapped 5954 * in an array [myarray]. 5955 * 5956 * Note: native methods in IE may not have the call and apply methods. 5957 * In this case, it will work, but you are limited to four arguments. 5958 * 5959 * @param periodic {boolean} if true, executes continuously at supplied 5960 * interval until canceled. 5961 * @return {object} a timer object. Call the cancel() method on this 5962 * object to stop the timer. 5963 */ 5964Y.later = function(when, o, fn, data, periodic) { 5965 when = when || 0; 5966 data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS; 5967 o = o || Y.config.win || Y; 5968 5969 var cancelled = false, 5970 method = (o && Y.Lang.isString(fn)) ? o[fn] : fn, 5971 wrapper = function() { 5972 // IE 8- may execute a setInterval callback one last time 5973 // after clearInterval was called, so in order to preserve 5974 // the cancel() === no more runny-run, we have to jump through 5975 // an extra hoop. 5976 if (!cancelled) { 5977 if (!method.apply) { 5978 method(data[0], data[1], data[2], data[3]); 5979 } else { 5980 method.apply(o, data || NO_ARGS); 5981 } 5982 } 5983 }, 5984 id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when); 5985 5986 return { 5987 id: id, 5988 interval: periodic, 5989 cancel: function() { 5990 cancelled = true; 5991 if (this.interval) { 5992 clearInterval(id); 5993 } else { 5994 clearTimeout(id); 5995 } 5996 } 5997 }; 5998}; 5999 6000Y.Lang.later = Y.later; 6001 6002 6003 6004}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 6005YUI.add('loader-base', function (Y, NAME) { 6006 6007/** 6008 * The YUI loader core 6009 * @module loader 6010 * @submodule loader-base 6011 */ 6012 6013(function() { 6014 var VERSION = Y.version, 6015 BUILD = '/build/', 6016 ROOT = VERSION + '/', 6017 CDN_BASE = Y.Env.base, 6018 GALLERY_VERSION = 'gallery-2014.06.04-21-38', 6019 TNT = '2in3', 6020 TNT_VERSION = '4', 6021 YUI2_VERSION = '2.9.0', 6022 COMBO_BASE = CDN_BASE + 'combo?', 6023 META = { 6024 version: VERSION, 6025 root: ROOT, 6026 base: Y.Env.base, 6027 comboBase: COMBO_BASE, 6028 skin: { 6029 defaultSkin: 'sam', 6030 base: 'assets/skins/', 6031 path: 'skin.css', 6032 after: [ 6033 'cssreset', 6034 'cssfonts', 6035 'cssgrids', 6036 'cssbase', 6037 'cssreset-context', 6038 'cssfonts-context' 6039 ] 6040 }, 6041 groups: {}, 6042 patterns: {} 6043 }, 6044 groups = META.groups, 6045 yui2Update = function(tnt, yui2, config) { 6046 var root = TNT + '.' + 6047 (tnt || TNT_VERSION) + '/' + 6048 (yui2 || YUI2_VERSION) + BUILD, 6049 base = (config && config.base) ? config.base : CDN_BASE, 6050 combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE; 6051 6052 groups.yui2.base = base + root; 6053 groups.yui2.root = root; 6054 groups.yui2.comboBase = combo; 6055 }, 6056 galleryUpdate = function(tag, config) { 6057 var root = (tag || GALLERY_VERSION) + BUILD, 6058 base = (config && config.base) ? config.base : CDN_BASE, 6059 combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE; 6060 6061 groups.gallery.base = base + root; 6062 groups.gallery.root = root; 6063 groups.gallery.comboBase = combo; 6064 }; 6065 6066 6067 groups[VERSION] = {}; 6068 6069 groups.gallery = { 6070 ext: false, 6071 combine: true, 6072 comboBase: COMBO_BASE, 6073 update: galleryUpdate, 6074 patterns: { 6075 'gallery-': {}, 6076 'lang/gallery-': {}, 6077 'gallerycss-': { 6078 type: 'css' 6079 } 6080 } 6081 }; 6082 6083 groups.yui2 = { 6084 combine: true, 6085 ext: false, 6086 comboBase: COMBO_BASE, 6087 update: yui2Update, 6088 patterns: { 6089 'yui2-': { 6090 configFn: function(me) { 6091 if (/-skin|reset|fonts|grids|base/.test(me.name)) { 6092 me.type = 'css'; 6093 me.path = me.path.replace(/\.js/, '.css'); 6094 // this makes skins in builds earlier than 6095 // 2.6.0 work as long as combine is false 6096 me.path = me.path.replace(/\/yui2-skin/, 6097 '/assets/skins/sam/yui2-skin'); 6098 } 6099 } 6100 } 6101 } 6102 }; 6103 6104 galleryUpdate(); 6105 yui2Update(); 6106 6107 if (YUI.Env[VERSION]) { 6108 Y.mix(META, YUI.Env[VERSION], false, [ 6109 'modules', 6110 'groups', 6111 'skin' 6112 ], 0, true); 6113 } 6114 6115 YUI.Env[VERSION] = META; 6116}()); 6117/*jslint forin: true, maxlen: 350 */ 6118 6119/** 6120 * Loader dynamically loads script and css files. It includes the dependency 6121 * information for the version of the library in use, and will automatically pull in 6122 * dependencies for the modules requested. It can also load the 6123 * files from the Yahoo! CDN, and it can utilize the combo service provided on 6124 * this network to reduce the number of http connections required to download 6125 * YUI files. 6126 * 6127 * @module loader 6128 * @main loader 6129 * @submodule loader-base 6130 */ 6131 6132var NOT_FOUND = {}, 6133 NO_REQUIREMENTS = [], 6134 MAX_URL_LENGTH = 1024, 6135 GLOBAL_ENV = YUI.Env, 6136 GLOBAL_LOADED = GLOBAL_ENV._loaded, 6137 CSS = 'css', 6138 JS = 'js', 6139 INTL = 'intl', 6140 DEFAULT_SKIN = 'sam',
6141 VERSION = Y.version, 6142 ROOT_LANG = '', 6143 YObject = Y.Object, 6144 oeach = YObject.each, 6145 yArray = Y.Array, 6146 _queue = GLOBAL_ENV._loaderQueue, 6147 META = GLOBAL_ENV[VERSION], 6148 SKIN_PREFIX = 'skin-', 6149 L = Y.Lang, 6150 ON_PAGE = GLOBAL_ENV.mods, 6151 modulekey, 6152 _path = function(dir, file, type, nomin) { 6153 var path = dir + '/' + file; 6154 if (!nomin) { 6155 path += '-min'; 6156 } 6157 path += '.' + (type || CSS); 6158 6159 return path; 6160 }; 6161 6162 6163 if (!YUI.Env._cssLoaded) { 6164 YUI.Env._cssLoaded = {}; 6165 } 6166 6167 6168/** 6169 * The component metadata is stored in Y.Env.meta. 6170 * Part of the loader module. 6171 * @property meta 6172 * @for YUI 6173 */ 6174Y.Env.meta = META; 6175 6176/** 6177 * Loader dynamically loads script and css files. It includes the dependency 6178 * info for the version of the library in use, and will automatically pull in 6179 * dependencies for the modules requested. It can load the 6180 * files from the Yahoo! CDN, and it can utilize the combo service provided on 6181 * this network to reduce the number of http connections required to download 6182 * YUI files. You can also specify an external, custom combo service to host 6183 * your modules as well. 6184 6185 var Y = YUI(); 6186 var loader = new Y.Loader({ 6187 filter: 'debug', 6188 base: '../../', 6189 root: 'build/', 6190 combine: true, 6191 require: ['node', 'dd', 'console'] 6192 }); 6193 var out = loader.resolve(true); 6194 6195 * If the Loader needs to be patched before it is used for the first time, it 6196 * should be done through the `doBeforeLoader` hook. Simply make the patch 6197 * available via configuration before YUI is loaded: 6198 6199 YUI_config = YUI_config || {}; 6200 YUI_config.doBeforeLoader = function (config) { 6201 var resolve = this.context.Loader.prototype.resolve; 6202 this.context.Loader.prototype.resolve = function () { 6203 // do something here 6204 return resolve.apply(this, arguments); 6205 }; 6206 }; 6207 6208 * @constructor 6209 * @class Loader 6210 * @param {Object} config an optional set of configuration options. 6211 * @param {String} config.base The base dir which to fetch this module from 6212 * @param {String} config.comboBase The Combo service base path. Ex: `http://yui.yahooapis.com/combo?` 6213 * @param {String} config.root The root path to prepend to module names for the combo service. Ex: `2.5.2/build/` 6214 * @param {String|Object} config.filter A filter to apply to result urls. <a href="#property_filter">See filter property</a> 6215 * @param {Object} config.filters Per-component filter specification. If specified for a given component, this overrides the filter config. 6216 * @param {Boolean} config.combine Use a combo service to reduce the number of http connections required to load your dependencies 6217 * @param {Boolean} [config.async=true] Fetch files in async 6218 * @param {Array} config.ignore: A list of modules that should never be dynamically loaded 6219 * @param {Array} config.force A list of modules that should always be loaded when required, even if already present on the page 6220 * @param {HTMLElement|String} config.insertBefore Node or id for a node that should be used as the insertion point for new nodes 6221 * @param {Object} config.jsAttributes Object literal containing attributes to add to script nodes 6222 * @param {Object} config.cssAttributes Object literal containing attributes to add to link nodes 6223 * @param {Number} config.timeout The number of milliseconds before a timeout occurs when dynamically loading nodes. If not set, there is no timeout 6224 * @param {Object} config.context Execution context for all callbacks 6225 * @param {Function} config.onSuccess Callback for the 'success' event 6226 * @param {Function} config.onFailure Callback for the 'failure' event 6227 * @param {Function} config.onTimeout Callback for the 'timeout' event 6228 * @param {Function} config.onProgress Callback executed each time a script or css file is loaded 6229 * @param {Object} config.modules A list of module definitions. See <a href="#method_addModule">Loader.addModule</a> for the supported module metadata 6230 * @param {Object} config.groups A list of group definitions. Each group can contain specific definitions for `base`, `comboBase`, `combine`, and accepts a list of `modules`. 6231 * @param {String} config.2in3 The version of the YUI 2 in 3 wrapper to use. The intrinsic support for YUI 2 modules in YUI 3 relies on versions of the YUI 2 components inside YUI 3 module wrappers. These wrappers change over time to accomodate the issues that arise from running YUI 2 in a YUI 3 sandbox. 6232 * @param {String} config.yui2 When using the 2in3 project, you can select the version of YUI 2 to use. V
6232alid values are `2.2.2`, `2.3.1`, `2.4.1`, `2.5.2`, `2.6.0`, `2.7.0`, `2.8.0`, `2.8.1` and `2.9.0` [default] -- plus all versions of YUI 2 going forward. 6233 * @param {Function} config.doBeforeLoader An optional hook that allows for the patching of the loader instance. The `Y` instance is available as `this.context` and the only argument to the function is the Loader configuration object. 6234 */ 6235Y.Loader = function(o) { 6236 6237 var self = this; 6238 6239 //Catch no config passed. 6240 o = o || {}; 6241 6242 modulekey = META.md5; 6243 6244 /** 6245 * Internal callback to handle multiple internal insert() calls 6246 * so that css is inserted prior to js 6247 * @property _internalCallback 6248 * @private 6249 */ 6250 // self._internalCallback = null; 6251 6252 /** 6253 * Callback that will be executed when the loader is finished 6254 * with an insert 6255 * @method onSuccess 6256 * @type function 6257 */ 6258 // self.onSuccess = null; 6259 6260 /** 6261 * Callback that will be executed if there is a failure 6262 * @method onFailure 6263 * @type function 6264 */ 6265 // self.onFailure = null; 6266 6267 /** 6268 * Callback executed each time a script or css file is loaded 6269 * @method onProgress 6270 * @type function 6271 */ 6272 // self.onProgress = null; 6273 6274 /** 6275 * Callback that will be executed if a timeout occurs 6276 * @method onTimeout 6277 * @type function 6278 */ 6279 // self.onTimeout = null; 6280 6281 /** 6282 * The execution context for all callbacks 6283 * @property context 6284 * @default {YUI} the YUI instance 6285 */ 6286 self.context = Y; 6287 6288 // Hook that allows the patching of loader 6289 if (o.doBeforeLoader) { 6290 o.doBeforeLoader.apply(self, arguments); 6291 } 6292 6293 /** 6294 * Data that is passed to all callbacks 6295 * @property data 6296 */ 6297 // self.data = null; 6298 6299 /** 6300 * Node reference or id where new nodes should be inserted before 6301 * @property insertBefore 6302 * @type string|HTMLElement 6303 */ 6304 // self.insertBefore = null; 6305 6306 /** 6307 * The charset attribute for inserted nodes 6308 * @property charset 6309 * @type string 6310 * @deprecated , use cssAttributes or jsAttributes. 6311 */ 6312 // self.charset = null; 6313 6314 /** 6315 * An object literal containing attributes to add to link nodes 6316 * @property cssAttributes 6317 * @type object 6318 */ 6319 // self.cssAttributes = null; 6320 6321 /** 6322 * An object literal containing attributes to add to script nodes 6323 * @property jsAttributes 6324 * @type object 6325 */ 6326 // self.jsAttributes = null; 6327 6328 /** 6329 * The base directory. 6330 * @property base 6331 * @type string 6332 * @default http://yui.yahooapis.com/[YUI VERSION]/build/ 6333 */ 6334 self.base = Y.Env.meta.base + Y.Env.meta.root; 6335 6336 /** 6337 * Base path for the combo service 6338 * @property comboBase 6339 * @type string 6340 * @default http://yui.yahooapis.com/combo? 6341 */ 6342 self.comboBase = Y.Env.meta.comboBase; 6343 6344 /* 6345 * Base path for language packs. 6346 */ 6347 // self.langBase = Y.Env.meta.langBase; 6348 // self.lang = ""; 6349 6350 /** 6351 * If configured, the loader will attempt to use the combo 6352 * service for YUI resources and configured external resources. 6353 * @property combine 6354 * @type boolean 6355 * @default true if a base dir isn't in the config 6356 */ 6357 self.combine = o.base && 6358 (o.base.indexOf(self.comboBase.substr(0, 20)) > -1); 6359 6360 /** 6361 * The default seperator to use between files in a combo URL 6362 * @property comboSep 6363 * @type {String} 6364 * @default Ampersand 6365 */ 6366 self.comboSep = '&'; 6367 /** 6368 * Max url length for combo urls. The default is 1024. This is the URL 6369 * limit for the Yahoo! hosted combo servers. If consuming 6370 * a different combo service that has a different URL limit 6371 * it is possible to override this default by supplying 6372 * the maxURLLength config option. The config option will 6373 * only take effect if lower than the default. 6374 * 6375 * @property maxURLLength 6376 * @type int 6377 */ 6378 self.maxURLLength = MAX_URL_LENGTH; 6379 6380 /** 6381 * Ignore modules registered on the YUI global 6382 * @property ignoreRegistered 6383 * @default false 6384 */ 6385 self.ignoreRegistered = o.ignoreRegistered; 6386 6387 /**
6388 * Root path to prepend to module path for the combo 6389 * service 6390 * @property root 6391 * @type string 6392 * @default [YUI VERSION]/build/ 6393 */ 6394 self.root = Y.Env.meta.root; 6395 6396 /** 6397 * Timeout value in milliseconds. If set, self value will be used by 6398 * the get utility. the timeout event will fire if 6399 * a timeout occurs. 6400 * @property timeout 6401 * @type int 6402 */ 6403 self.timeout = 0; 6404 6405 /** 6406 * A list of modules that should not be loaded, even if 6407 * they turn up in the dependency tree 6408 * @property ignore 6409 * @type string[] 6410 */ 6411 // self.ignore = null; 6412 6413 /** 6414 * A list of modules that should always be loaded, even 6415 * if they have already been inserted into the page. 6416 * @property force 6417 * @type string[] 6418 */ 6419 // self.force = null; 6420 6421 self.forceMap = {}; 6422 6423 /** 6424 * Should we allow rollups 6425 * @property allowRollup 6426 * @type boolean 6427 * @default false 6428 */ 6429 self.allowRollup = false; 6430 6431 /** 6432 * A filter to apply to result urls. This filter will modify the default 6433 * path for all modules. The default path for the YUI library is the 6434 * minified version of the files (e.g., event-min.js). The filter property 6435 * can be a predefined filter or a custom filter. The valid predefined 6436 * filters are: 6437 * <dl> 6438 * <dt>DEBUG</dt> 6439 * <dd>Selects the debug versions of the library (e.g., event-debug.js). 6440 * This option will automatically include the Logger widget</dd> 6441 * <dt>RAW</dt> 6442 * <dd>Selects the non-minified version of the library (e.g., event.js). 6443 * </dd> 6444 * </dl> 6445 * You can also define a custom filter, which must be an object literal 6446 * containing a search expression and a replace string: 6447 * 6448 * myFilter: { 6449 * 'searchExp': "-min\\.js", 6450 * 'replaceStr': "-debug.js" 6451 * } 6452 * 6453 * @property filter 6454 * @type string| {searchExp: string, replaceStr: string} 6455 */ 6456 // self.filter = null; 6457 6458 /** 6459 * per-component filter specification. If specified for a given 6460 * component, this overrides the filter config. 6461 * @property filters 6462 * @type object 6463 */ 6464 self.filters = {}; 6465 6466 /** 6467 * The list of requested modules 6468 * @property required 6469 * @type {string: boolean} 6470 */ 6471 self.required = {}; 6472 6473 /** 6474 * If a module name is predefined when requested, it is checked againsts 6475 * the patterns provided in this property. If there is a match, the 6476 * module is added with the default configuration. 6477 * 6478 * At the moment only supporting module prefixes, but anticipate 6479 * supporting at least regular expressions. 6480 * @property patterns 6481 * @type Object 6482 */ 6483 // self.patterns = Y.merge(Y.Env.meta.patterns); 6484 self.patterns = {}; 6485 6486 /** 6487 * Internal loader instance metadata. Use accessor `getModuleInfo()` instead. 6488 */ 6489 self.moduleInfo = {}; 6490 6491 self.groups = Y.merge(Y.Env.meta.groups); 6492 6493 /** 6494 * Provides the information used to skin the skinnable components. 6495 * The following skin definition would result in 'skin1' and 'skin2' 6496 * being loaded for calendar (if calendar was requested), and 6497 * 'sam' for all other skinnable components: 6498 * 6499 * skin: { 6500 * // The default skin, which is automatically applied if not 6501 * // overriden by a component-specific skin definition. 6502 * // Change this in to apply a different skin globally 6503 * defaultSkin: 'sam', 6504 * 6505 * // This is combined with the loader base property to get 6506 * // the default root directory for a skin. ex: 6507 * // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/ 6508 * base: 'assets/skins/', 6509 * 6510 * // Any component-specific overrides can be specified here, 6511 * // making it possible to load different skins for different 6512 * // components. It is possible to load more than one skin 6513 * // for a given component as well. 6514 * overrides: { 6515 * calendar: ['skin1', 'skin2'] 6516 * } 6517 * } 6518 * @property skin 6519 * @type {Object} 6520 */ 6521 self.skin = Y.merge(Y.Env.meta.skin); 6522 6523 /* 6524 * Map of conditional modules 6525 * @since 3.2.0 6526 */ 6527 self.conditions = {}; 6528 6529 // map of modules with a hash of modules that meet the requirement 6530 // self.provides = {}; 6531 6532 self.config = o; 6533 self._internal = true; 6534 6535 self._populateConditionsCache(); 6536 6537 /** 6538 * Set when beginning to compute the dependency tree. 6539 * Composed of what YUI reports to be loaded combined 6540 * with what has been loaded by any instance on the page 6541 * with the version number specified in the metadata. 6542 * @property loaded 6543 * @type {string: boolean} 6544 */ 6545 self.loaded = GLOBAL_LOADED[VERSION]; 6546 6547 6548 /** 6549 * Should Loader fetch scripts in `async`, defaults to `true` 6550 * @property async 6551 */ 6552 6553 self.async = true; 6554 6555 self._inspectPage(); 6556 6557 self._internal = false;
6558 6559 self._config(o); 6560 6561 self.forceMap = (self.force) ? Y.Array.hash(self.force) : {}; 6562 6563 self.testresults = null; 6564 6565 if (Y.config.tests) { 6566 self.testresults = Y.config.tests; 6567 } 6568 6569 /** 6570 * List of rollup files found in the library metadata 6571 * @property rollups 6572 */ 6573 // self.rollups = null; 6574 6575 /** 6576 * Whether or not to load optional dependencies for 6577 * the requested modules 6578 * @property loadOptional 6579 * @type boolean 6580 * @default false 6581 */ 6582 // self.loadOptional = false; 6583 6584 /** 6585 * All of the derived dependencies in sorted order, which 6586 * will be populated when either calculate() or insert() 6587 * is called 6588 * @property sorted 6589 * @type string[] 6590 */ 6591 self.sorted = []; 6592 6593 /* 6594 * A list of modules to attach to the YUI instance when complete. 6595 * If not supplied, the sorted list of dependencies are applied. 6596 * @property attaching 6597 */ 6598 // self.attaching = null; 6599 6600 /** 6601 * Flag to indicate the dependency tree needs to be recomputed 6602 * if insert is called again. 6603 * @property dirty 6604 * @type boolean 6605 * @default true 6606 */ 6607 self.dirty = true; 6608 6609 /** 6610 * List of modules inserted by the utility 6611 * @property inserted 6612 * @type {string: boolean} 6613 */ 6614 self.inserted = {}; 6615 6616 /** 6617 * List of skipped modules during insert() because the module 6618 * was not defined 6619 * @property skipped 6620 */ 6621 self.skipped = {}; 6622 6623 // Y.on('yui:load', self.loadNext, self); 6624 6625 self.tested = {}; 6626 6627 /* 6628 * Cached sorted calculate results 6629 * @property results 6630 * @since 3.2.0 6631 */ 6632 //self.results = {}; 6633 6634 if (self.ignoreRegistered) { 6635 //Clear inpage already processed modules. 6636 self._resetModules(); 6637 } 6638 6639}; 6640 6641Y.Loader.prototype = { 6642 /** 6643 * Gets the module info from the local moduleInfo hash, or from the 6644 * default metadata and populate the local moduleInfo hash. 6645 * @method getModuleInfo 6646 * @param {string} name of the module 6647 * @public 6648 */ 6649 getModuleInfo: function(name) { 6650 6651 var m = this.moduleInfo[name], 6652 rawMetaModules, globalRenderedMods, internal, v; 6653 6654 if (m) { 6655 return m; 6656 } 6657 6658 rawMetaModules = META.modules; 6659 globalRenderedMods = GLOBAL_ENV._renderedMods; 6660 internal = this._internal; 6661 6662 /* 6663 The logic here is: 6664 6665 - if the `moduleInfo[name]` is avilable, 6666 then short circuit 6667 - otherwise, if the module is in the globalCache (cross Y instance), 6668 then port it from the global registry into `moduleInfo[name]` 6669 - otherwise, if the module has raw metadata (from meta modules) 6670 then add it to the global registry and to `moduleInfo[name]` 6671 6672 */ 6673 if (globalRenderedMods && globalRenderedMods.hasOwnProperty(name) && !this.ignoreRegistered) { 6674 this.moduleInfo[name] = Y.merge(globalRenderedMods[name]); 6675 } else { 6676 if (rawMetaModules.hasOwnProperty(name)) { 6677 this._internal = true; // making sure that modules from raw data are marked as internal 6678 v = this.addModule(rawMetaModules[name], name); 6679 // Inspect the page for the CSS module and mark it as loaded. 6680 if (v && v.type === CSS) { 6681 if (this.isCSSLoaded(v.name, true)) { 6682 this.loaded[v.name] = true; 6683 } 6684 } 6685 this._internal = internal; 6686 } 6687 } 6688 return this.moduleInfo[name]; 6689 }, 6690 /** 6691 * Expand the names that are aliases to other modules. 6692 * @method _expandAliases 6693 * @param {string[]} list a module name or a list of names to be expanded 6694 * @private 6695 * @return {array} 6696 */ 6697 _expandAliases: function(list) { 6698 var expanded = [], 6699 aliases = YUI.Env.aliases, 6700 i, name; 6701 list = Y.Array(list); 6702 for (i = 0; i < list.length; i += 1) { 6703 name = list[i]; 6704 expanded.push.apply(expanded, aliases[name] ? aliases[name] : [name]); 6705 } 6706 return expanded; 6707 }, 6708 /** 6709 * Populate the conditions cache from raw modules, this is necessary 6710 * because no other module will require a conditional module, instead 6711 * the condition has to be executed and then the module is analyzed 6712 * to be included in the final requirement list. Without this cache 6713 * conditional modules will be simply ignored. 6714 * @method _populateConditionsCache 6715 * @private 6716 */ 6717 _populateConditionsCache: function() { 6718 var rawMetaModules = META.modules,
6719 cache = GLOBAL_ENV._conditions, 6720 i, j, t, trigger; 6721 6722 // if we have conditions in cache and cache is enabled 6723 // we should port them to this loader instance 6724 if (cache && !this.ignoreRegistered) { 6725 for (i in cache) { 6726 if (cache.hasOwnProperty(i)) { 6727 this.conditions[i] = Y.merge(cache[i]); 6728 } 6729 } 6730 } else { 6731 for (i in rawMetaModules) { 6732 if (rawMetaModules.hasOwnProperty(i) && rawMetaModules[i].condition) { 6733 t = this._expandAliases(rawMetaModules[i].condition.trigger); 6734 for (j = 0; j < t.length; j += 1) { 6735 trigger = t[j]; 6736 this.conditions[trigger] = this.conditions[trigger] || {}; 6737 this.conditions[trigger][rawMetaModules[i].name || i] = rawMetaModules[i].condition; 6738 } 6739 } 6740 } 6741 GLOBAL_ENV._conditions = this.conditions; 6742 } 6743 }, 6744 /** 6745 * Reset modules in the module cache to a pre-processed state so additional 6746 * computations with a different skin or language will work as expected. 6747 * @method _resetModules 6748 * @private 6749 */ 6750 _resetModules: function() { 6751 var self = this, i, o, 6752 mod, name, details; 6753 for (i in self.moduleInfo) { 6754 if (self.moduleInfo.hasOwnProperty(i) && self.moduleInfo[i]) { 6755 mod = self.moduleInfo[i]; 6756 name = mod.name; 6757 details = (YUI.Env.mods[name] ? YUI.Env.mods[name].details : null); 6758 6759 if (details) { 6760 self.moduleInfo[name]._reset = true; 6761 self.moduleInfo[name].requires = details.requires || []; 6762 self.moduleInfo[name].optional = details.optional || []; 6763 self.moduleInfo[name].supersedes = details.supercedes || []; 6764 } 6765 6766 if (mod.defaults) { 6767 for (o in mod.defaults) { 6768 if (mod.defaults.hasOwnProperty(o)) { 6769 if (mod[o]) { 6770 mod[o] = mod.defaults[o]; 6771 } 6772 } 6773 } 6774 } 6775 mod.langCache = undefined; 6776 mod.skinCache = undefined; 6777 if (mod.skinnable) { 6778 self._addSkin(self.skin.defaultSkin, mod.name); 6779 } 6780 } 6781 } 6782 }, 6783 /** 6784 Regex that matches a CSS URL. Used to guess the file type when it's not 6785 specified. 6786 6787 @property REGEX_CSS 6788 @type RegExp 6789 @final 6790 @protected 6791 @since 3.5.0 6792 **/ 6793 REGEX_CSS: /\.css(?:[?;].*)?$/i, 6794 6795 /** 6796 * Default filters for raw and debug 6797 * @property FILTER_DEFS 6798 * @type Object 6799 * @final 6800 * @protected 6801 */ 6802 FILTER_DEFS: { 6803 RAW: { 6804 'searchExp': '-min\\.js', 6805 'replaceStr': '.js' 6806 }, 6807 DEBUG: { 6808 'searchExp': '-min\\.js', 6809 'replaceStr': '-debug.js' 6810 }, 6811 COVERAGE: { 6812 'searchExp': '-min\\.js', 6813 'replaceStr': '-coverage.js' 6814 } 6815 }, 6816 /* 6817 * Check the pages meta-data and cache the result. 6818 * @method _inspectPage 6819 * @private 6820 */ 6821 _inspectPage: function() { 6822 var self = this, v, m, req, mr, i; 6823 6824 for (i in ON_PAGE) { 6825 if (ON_PAGE.hasOwnProperty(i)) { 6826 v = ON_PAGE[i]; 6827 if (v.details) { 6828 m = self.getModuleInfo(v.name); 6829 req = v.details.requires; 6830 mr = m && m.requires; 6831 6832 if (m) { 6833 if (!m._inspected && req && mr.length !== req.length) { 6834 // console.log('deleting ' + m.name); 6835 delete m.expanded; 6836 } 6837 } else { 6838 m = self.addModule(v.details, i); 6839 } 6840 m._inspected = true; 6841 } 6842 } 6843 } 6844 }, 6845 /* 6846 * returns true if b is not loaded, and is required directly or by means of modules it supersedes. 6847 * @private 6848 * @method _requires 6849 * @param {String} mod1 The first module to compare 6850 * @param {String} mod2 The second module to compare 6851 */ 6852 _requires: function(mod1, mod2) { 6853 6854 var i, rm, after_map, s, 6855 m = this.getModuleInfo(mod1), 6856 other = this.getModuleInfo(mod2); 6857
6858 if (!m || !other) { 6859 return false; 6860 } 6861 6862 rm = m.expanded_map; 6863 after_map = m.after_map; 6864 6865 // check if this module should be sorted after the other 6866 // do this first to short circut circular deps 6867 if (after_map && (mod2 in after_map)) { 6868 return true; 6869 } 6870 6871 after_map = other.after_map; 6872 6873 // and vis-versa 6874 if (after_map && (mod1 in after_map)) { 6875 return false; 6876 } 6877 6878 // check if this module requires one the other supersedes 6879 s = other.supersedes; 6880 if (s) { 6881 for (i = 0; i < s.length; i++) { 6882 if (this._requires(mod1, s[i])) { 6883 return true; 6884 } 6885 } 6886 } 6887 6888 s = m.supersedes; 6889 if (s) { 6890 for (i = 0; i < s.length; i++) { 6891 if (this._requires(mod2, s[i])) { 6892 return false; 6893 } 6894 } 6895 } 6896 6897 // check if this module requires the other directly 6898 // if (r && yArray.indexOf(r, mod2) > -1) { 6899 if (rm && (mod2 in rm)) { 6900 return true; 6901 } 6902 6903 // external css files should be sorted below yui css 6904 if (m.ext && m.type === CSS && !other.ext && other.type === CSS) { 6905 return true; 6906 } 6907 6908 return false; 6909 }, 6910 /** 6911 * Apply a new config to the Loader instance 6912 * @method _config 6913 * @private 6914 * @param {Object} o The new configuration 6915 */ 6916 _config: function(o) { 6917 var i, j, val, a, f, group, groupName, self = this, 6918 mods = [], mod, modInfo; 6919 // apply config values 6920 if (o) { 6921 for (i in o) { 6922 if (o.hasOwnProperty(i)) { 6923 val = o[i]; 6924 //TODO This should be a case 6925 if (i === 'require') { 6926 self.require(val); 6927 } else if (i === 'skin') { 6928 //If the config.skin is a string, format to the expected object 6929 if (typeof val === 'string') { 6930 self.skin.defaultSkin = o.skin; 6931 val = { 6932 defaultSkin: val 6933 }; 6934 } 6935 6936 Y.mix(self.skin, val, true); 6937 } else if (i === 'groups') { 6938 for (j in val) { 6939 if (val.hasOwnProperty(j)) { 6940 groupName = j; 6941 group = val[j]; 6942 self.addGroup(group, groupName); 6943 if (group.aliases) { 6944 for (a in group.aliases) { 6945 if (group.aliases.hasOwnProperty(a)) { 6946 self.addAlias(group.aliases[a], a); 6947 } 6948 } 6949 } 6950 } 6951 } 6952 6953 } else if (i === 'modules') { 6954 // add a hash of module definitions 6955 for (j in val) { 6956 if (val.hasOwnProperty(j)) { 6957 self.addModule(val[j], j); 6958 } 6959 } 6960 } else if (i === 'aliases') { 6961 for (j in val) { 6962 if (val.hasOwnProperty(j)) { 6963 self.addAlias(val[j], j); 6964 } 6965 } 6966 } else if (i === 'gallery') { 6967 if (this.groups.gallery.update) { 6968 this.groups.gallery.update(val, o); 6969 } 6970 } else if (i === 'yui2' || i === '2in3') { 6971 if (this.groups.yui2.update) { 6972 this.groups.yui2.update(o['2in3'], o.yui2, o); 6973 } 6974 } else { 6975 self[i] = val; 6976 } 6977 } 6978 } 6979 } 6980 6981 // fix filter 6982 f = self.filter; 6983 6984 if (L.isString(f)) { 6985 f = f.toUpperCase(); 6986 self.filterName = f; 6987 self.filter = self.FILTER_DEFS[f]; 6988 if (f === 'DEBUG') { 6989 self.require('yui-log', 'dump'); 6990 } 6991 } 6992 6993 if (self.filterName && self.coverage) { 6994 if (self.filterName === 'COVERAGE' && L.isArray(self.coverage) && self.coverage.length) { 6995 for (i = 0; i < self.coverage.length; i++) { 6996 mod = self.coverage[i]; 6997 modInfo = self.getModuleInfo(mod); 6998 if (modInfo && modInfo.use) {
6999 mods = mods.concat(modInfo.use); 7000 } else { 7001 mods.push(mod); 7002 } 7003 } 7004 self.filters = self.filters || {}; 7005 Y.Array.each(mods, function(mod) { 7006 self.filters[mod] = self.FILTER_DEFS.COVERAGE; 7007 }); 7008 self.filterName = 'RAW'; 7009 self.filter = self.FILTER_DEFS[self.filterName]; 7010 } 7011 } 7012 7013 }, 7014 7015 /** 7016 * Returns the skin module name for the specified skin name. If a 7017 * module name is supplied, the returned skin module name is 7018 * specific to the module passed in. 7019 * @method formatSkin 7020 * @param {string} skin the name of the skin. 7021 * @param {string} mod optional: the name of a module to skin. 7022 * @return {string} the full skin module name. 7023 */ 7024 formatSkin: function(skin, mod) { 7025 var s = SKIN_PREFIX + skin; 7026 if (mod) { 7027 s = s + '-' + mod; 7028 } 7029 7030 return s; 7031 }, 7032 7033 /** 7034 * Adds the skin def to the module info 7035 * @method _addSkin 7036 * @param {string} skin the name of the skin. 7037 * @param {string} mod the name of the module. 7038 * @param {string} parent parent module if this is a skin of a 7039 * submodule or plugin. 7040 * @return {string} the module name for the skin. 7041 * @private 7042 */ 7043 _addSkin: function(skin, mod, parent) { 7044 var pkg, name, nmod, 7045 sinf = this.skin, 7046 mdef = mod && this.getModuleInfo(mod), 7047 ext = mdef && mdef.ext; 7048 7049 // Add a module definition for the module-specific skin css 7050 if (mod) { 7051 name = this.formatSkin(skin, mod); 7052 if (!this.getModuleInfo(name)) { 7053 pkg = mdef.pkg || mod; 7054 nmod = { 7055 skin: true, 7056 name: name, 7057 group: mdef.group, 7058 type: 'css', 7059 after: sinf.after, 7060 path: (parent || pkg) + '/' + sinf.base + skin + 7061 '/' + mod + '.css', 7062 ext: ext 7063 }; 7064 if (mdef.base) { 7065 nmod.base = mdef.base; 7066 } 7067 if (mdef.configFn) { 7068 nmod.configFn = mdef.configFn; 7069 } 7070 this.addModule(nmod, name); 7071 7072 } 7073 } 7074 7075 return name; 7076 }, 7077 /** 7078 * Adds an alias module to the system 7079 * @method addAlias 7080 * @param {Array} use An array of modules that makes up this alias 7081 * @param {String} name The name of the alias 7082 * @example 7083 * var loader = new Y.Loader({}); 7084 * loader.addAlias([ 'node', 'yql' ], 'davglass'); 7085 * loader.require(['davglass']); 7086 * var out = loader.resolve(true); 7087 * 7088 * //out.js will contain Node and YQL modules 7089 */ 7090 addAlias: function(use, name) { 7091 YUI.Env.aliases[name] = use; 7092 this.addModule({ 7093 name: name, 7094 use: use 7095 }); 7096 }, 7097 /** 7098 * Add a new module group 7099 * @method addGroup 7100 * @param {Object} config An object containing the group configuration data 7101 * @param {String} config.name required, the group name 7102 * @param {String} config.base The base directory for this module group 7103 * @param {String} config.root The root path to add to each combo resource path 7104 * @param {Boolean} config.combine Should the request be combined 7105 * @param {String} config.comboBase Combo service base path 7106 * @param {Object} config.modules The group of modules 7107 * @param {String} name the group name. 7108 * @example 7109 * var loader = new Y.Loader({}); 7110 * loader.addGroup({ 7111 * name: 'davglass', 7112 * combine: true, 7113 * comboBase: '/combo?', 7114 * root: '', 7115 * modules: { 7116 * //Module List here 7117 * } 7118 * }, 'davglass'); 7119 */ 7120 addGroup: function(o, name) { 7121 var mods = o.modules, 7122 self = this, 7123 defaultBase = o.defaultBase || Y.config.defaultBase, 7124 i, v; 7125 7126 name = name || o.name; 7127 o.name = name; 7128 self.groups[name] = o; 7129 7130 if (!o.base && defaultBase && o.root) { 7131 o.base = defaultBase + o.root; 7132 } 7133 7134 if (o.patterns) { 7135 for (i in o.patterns) { 7136 if (o.patterns.hasOwnProperty(i)) { 7137 o.patterns[i].group = name; 7138 self.patterns[i] = o.patterns[i]; 7139 } 7140 } 7141 } 7142 7143 if (mods) { 7144 for (i in mods) { 7145 if (mods.hasOwnProperty(i)) { 7146 v = mods[i]; 7147 if (typeof v === 'string') { 7148 v = { name: i, fullpath: v }; 7149 } 7150 v.group = name; 7151 self.addModule(v, i); 7152 } 7153 } 7154 } 7155 }, 7156 7157 /** 7158 * Add a new module to the component metadata. 7159 * @method addModule 7160 * @param {Object}
7160 config An object containing the module data. 7161 * @param {String} config.name Required, the component name 7162 * @param {String} config.type Required, the component type (js or css) 7163 * @param {String} config.path Required, the path to the script from `base` 7164 * @param {Array} config.requires Array of modules required by this component 7165 * @param {Array} [config.optional] Array of optional modules for this component 7166 * @param {Array} [config.supersedes] Array of the modules this component replaces 7167 * @param {Array} [config.after] Array of modules the components which, if present, should be sorted above this one 7168 * @param {Object} [config.after_map] Faster alternative to 'after' -- supply a hash instead of an array 7169 * @param {Number} [config.rollup] The number of superseded modules required for automatic rollup 7170 * @param {String} [config.fullpath] If `fullpath` is specified, this is used instead of the configured `base + path` 7171 * @param {Boolean} [config.skinnable] Flag to determine if skin assets should automatically be pulled in 7172 * @param {Object} [config.submodules] Hash of submodules 7173 * @param {String} [config.group] The group the module belongs to -- this is set automatically when it is added as part of a group configuration. 7174 * @param {Array} [config.lang] Array of BCP 47 language tags of languages for which this module has localized resource bundles, e.g., `["en-GB", "zh-Hans-CN"]` 7175 * @param {Object} [config.condition] Specifies that the module should be loaded automatically if a condition is met. This is an object with up to four fields: 7176 * @param {String} [config.condition.trigger] The name of a module that can trigger the auto-load 7177 * @param {Function} [config.condition.test] A function that returns true when the module is to be loaded. 7178 * @param {String} [config.condition.ua] The UA name of <a href="UA.html">Y.UA</a> object that returns true when the module is to be loaded. e.g., `"ie"`, `"nodejs"`. 7179 * @param {String} [config.condition.when] Specifies the load order of the conditional module 7180 * with regard to the position of the trigger module. 7181 * This should be one of three values: `before`, `after`, or `instead`. The default is `after`. 7182 * @param {Object} [config.testresults] A hash of test results from `Y.Features.all()` 7183 * @param {Function} [config.configFn] A function to exectute when configuring this module 7184 * @param {Object} config.configFn.mod The module config, modifying this object will modify it's config. Returning false will delete the module's config. 7185 * @param {String[]} [config.optionalRequires] List of dependencies that 7186 may optionally be loaded by this loader. This is targeted mostly at 7187 polyfills, since they should not be in the list of requires because 7188 polyfills are assumed to be available in the global scope. 7189 * @param {Function} [config.test] Test to be called when this module is 7190 added as an optional dependency of another module. If the test function 7191 returns `false`, the module will be ignored and will not be attached to 7192 this YUI instance. 7193 * @param {String} [name] The module name, required if not in the module data. 7194 * @return {Object} the module definition or null if the object passed in did not provide all required attributes. 7195 */ 7196 addModule: function(o, name) { 7197 name = name || o.name; 7198 7199 if (typeof o === 'string') { 7200 o = { name: name, fullpath: o }; 7201 } 7202 7203 7204 var subs, i, l, t, sup, s, smod, plugins, plug, 7205 j, langs, packName, supName, flatSup, flatLang, lang, ret, 7206 overrides, skinname, when, g, p, 7207 modInfo = this.moduleInfo[name], 7208 conditions = this.conditions, trigger; 7209 7210 //Only merge this data if the temp flag is set 7211 //from an earlier pass from a pattern or else 7212 //an override module (YUI_config) can not be used to 7213 //replace a default module. 7214 if (modInfo && modInfo.temp) { 7215 //This catches temp modules loaded via a pattern 7216 // The module will be added twice, once from the pattern and 7217 // Once from the actual add call, this ensures that properties 7218 // that were added to the module the first time around (group: gallery) 7219 // are also added the second time around too. 7220 o = Y.merge(modInfo, o); 7221 } 7222 7223 o.name = name; 7224 7225 if (!o || !o.name) { 7226 return null; 7227 } 7228 7229 if (!o.type) { 7230 //Always assume it's javascript unless the CSS pattern is matched. 7231 o.type = JS; 7232 p = o.path || o.fullpath; 7233 if (p && this.REGEX_CSS.test(p)) { 7234 o.type = CSS; 7235 } 7236 } 7237 7238 if (!o.path && !o.fullpath) { 7239 o.path = _path(name, name, o.type); 7240 } 7241 o.supersedes = o.supersedes || o.use; 7242 7243 o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true; 7244 7245 // Handle submodule logic 7246 subs = o.submodules; 7247 7248 this.moduleInfo[name] = o; 7249 7250 o.requires = o.requires || []; 7251 7252 /* 7253 Only allowing the cascade of requires information, since 7254 optional and supersedes are far more fine grained than 7255 a blanket requires is. 7256 */ 7257 if (this.requires) { 7258 for (i = 0; i < this.requires.length; i++) { 7259 o.requires.push(this.requires[i]); 7260 } 7261 } 7262 if (o.group && this.groups && this.groups[o.group]) { 7263 g = this.groups[o.group]; 7264 if (g.requires) { 7265 for (i = 0; i < g.requires.length; i++) { 7266 o.requires.push(g.requires[i]); 7267 } 7268 } 7269 } 7270 7271 7272 if (!o.defaults) { 7273 o.defaults = { 7274 requires: o.requires ? [].concat(o.requires) : null, 7275 supersedes: o.supersedes ? [].concat(o.supersedes) : null, 7276 optional: o.optional ? [].concat(o.optional) : null 7277 }; 7278 } 7279 7280 if (o.skinnable && o.ext && o.temp) { 7281 skinname = this._addSkin(this.skin.defaultSkin, name); 7282 o.requires.unshift(skinname); 7283 } 7284 7285 if (o.requires.length) { 7286 o.requires = this.filterRequires(o.requires) || []; 7287 } 7288 7289 if (!o.langPack && o.lang) { 7290 // Setup root package by default as a fallback 7291 // for languages that are not defined 7292 packName = this.getLangPackName(ROOT_LANG, name); 7293 smod = this.getModuleInfo(packName); 7294 7295 if (!smod) { 7296 this._addLangPack(null, o, packName); 7297 } 7298 7299 langs = yArray(o.lang); 7300 7301 for (j = 0; j < langs.length; j++) { 7302 lang = langs[j]; 7303 packName = this.getLangPackName(lang, name); 7304 smod = this.getModuleInfo(packName); 7305 if (!smod) { 7306 smod = this._addLangPack(lang, o, packName); 7307 } 7308 } 7309 } 7310 7311 7312 if (subs) { 7313 sup = o.supersedes || []; 7314 l = 0; 7315 7316 for (i in subs) { 7317 if (subs.hasOwnProperty(i)) { 7318 s = subs[i]; 7319 7320 s.path = s.path || _path(name, i, o.type); 7321 s.pkg = name; 7322 s.group = o.group; 7323 7324 if (s.supersedes) { 7325 sup = sup.concat(s.supersedes); 7326 } 7327 7328 smod = this.addModule(s, i); 7329 sup.push(i); 7330 7331 if (smod.skinnable) { 7332 o.skinnable = true; 7333 overrides = this.skin.overrides; 7334 if (overrides && overrides[i]) { 7335 for (j = 0; j < overrides[i].length; j++) { 7336 skinname = this._addSkin(overrides[i][j], 7337 i, name); 7338 sup.push(skinname); 7339 } 7340 } 7341 skinname = this._addSkin(this.skin.defaultSkin, 7342 i, name); 7343 sup.push(skinname); 7344 } 7345 7346 // looks like we are expected to work out the metadata 7347 // for the parent module language packs from what is 7348 // specified in the child modules. 7349 if (s.lang && s.lang.length) { 7350 // Setup root package by default as a fallback 7351 // for languages that are not defined 7352 packName = this.getLangPackName(ROOT_LANG, name); 7353 smod = this.getModuleInfo(packName); 7354 7355 if (!smod) { 7356 this._addLangPack(null, o, packName); 7357 } 7358 7359 langs = yArray(s.lang); 7360 7361 for (j = 0; j < langs.length; j++) { 7362 lang = langs[j]; 7363 packName = this.getLangPackName(lang, name); 7364 supName = this.getLangPackName(lang, i); 7365 smod = this.getModuleInfo(packName); 7366 7367 if (!smod) { 7368 smod = this._addLangPack(lang, o, packName); 7369 } 7370 7371 flatSup = flatSup || yArray.hash(smod.supersedes); 7372 7373 if (!(supName in flatSup)) { 7374 smod.supersedes.push(supName); 7375 } 7376 7377 o.lang = o.lang || []; 7378 7379 flatLang = flatLang || yArray.hash(o.lang); 7380 7381 if (!(lang in flatLang)) { 7382 o.lang.push(lang); 7383 } 7384 7385// Add rollup file, need to add to supersedes list too 7386 7387 // default packages 7388 packName = this.getLangPackName(ROOT_LANG, name); 7389 supName = this.getLangPackName(ROOT_LANG, i); 7390 7391 smod = this.getModuleInfo(packName); 7392 7393 if (!smod) { 7394 smod = this._addLangPack(lang, o, packName); 7395 } 7396 7397 if (!(supName in flatSup)) { 7398 smod.supersedes.push(supName); 7399 } 7400 7401// Add rollup file, need to add to supersedes list too 7402 7403 } 7404 } 7405 7406 l++; 7407 } 7408 } 7409 //o.supersedes = YObject.keys(yArray.hash(sup)); 7410 o.supersedes = yArray.dedupe(sup); 7411 if (this.allowRollup) { 7412 o.rollup = (l < 4) ? l : Math.min(l - 1, 4); 7413 } 7414 } 7415 7416 plugins = o.plugins; 7417 if (plugins) { 7418 for (i in plugins) { 7419 if (plugins.hasOwnProperty(i)) { 7420 plug = plugins[i]; 7421 plug.pkg = name; 7422 plug.path = plug.path || _path(name, i, o.type); 7423 plug.requires = plug.requires || []; 7424 plug.group = o.group; 7425 this.addModule(plug, i); 7426 if (o.skinnable) { 7427 this._addSkin(this.skin.defaultSkin, i, name); 7428 } 7429 7430 } 7431 } 7432 } 7433 7434 if (o.condition) { 7435 t = this._expandAliases(o.condition.trigger); 7436 for (i = 0; i < t.length; i++) { 7437 trigger = t[i]; 7438 when = o.condition.when; 7439 conditions[trigger] = conditions[trigger] || {}; 7440 conditions[trigger][name] = o.condition; 7441 // the 'when' attribute can be 'before', 'after', or 'instead' 7442 // the default is after. 7443 if (when && when !== 'after') { 7444 if (when === 'instead') { // replace the trigger 7445 o.supersedes = o.supersedes || []; 7446 o.supersedes.push(trigger); 7447 } 7448 // before the trigger 7449 // the trigger requires the conditional mod, 7450 // so it should appear before the conditional 7451 // mod if we do not intersede. 7452 } else { // after the trigger 7453 o.after = o.after || []; 7454 o.after.push(trigger); 7455 } 7456 } 7457 } 7458 7459 if (o.supersedes) { 7460 o.supersedes = this.filterRequires(o.supersedes); 7461 } 7462 7463 if (o.after) { 7464 o.after = this.filterRequires(o.after); 7465 o.after_map = yArray.hash(o.after); 7466 } 7467 7468 // this.dirty = true; 7469 7470 if (o.configFn) { 7471 ret = o.configFn(o); 7472 if (ret === false) { 7473 delete this.moduleInfo[name]; 7474 delete GLOBAL_ENV._renderedMods[name]; 7475 o = null; 7476 } 7477 } 7478 //Add to global cache 7479 if (o) { 7480 if (!GLOBAL_ENV._renderedMods) { 7481 GLOBAL_ENV._renderedMods = {}; 7482 } 7483 GLOBAL_ENV._renderedMods[name] = Y.mix(GLOBAL_ENV._renderedMods[name] || {}, o);
7484 GLOBAL_ENV._conditions = conditions; 7485 } 7486 7487 return o; 7488 }, 7489 7490 /** 7491 * Add a requirement for one or more module 7492 * @method require 7493 * @param {string[] | string*} what the modules to load. 7494 */ 7495 require: function(what) { 7496 var a = (typeof what === 'string') ? yArray(arguments) : what; 7497 this.dirty = true; 7498 this.required = Y.merge(this.required, yArray.hash(this.filterRequires(a))); 7499 7500 this._explodeRollups(); 7501 }, 7502 /** 7503 * Grab all the items that were asked for, check to see if the Loader 7504 * meta-data contains a "use" array. If it doesm remove the asked item and replace it with 7505 * the content of the "use". 7506 * This will make asking for: "dd" 7507 * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin" 7508 * @private 7509 * @method _explodeRollups 7510 */ 7511 _explodeRollups: function() { 7512 var self = this, m, m2, i, a, v, len, len2, 7513 r = self.required; 7514 7515 if (!self.allowRollup) { 7516 for (i in r) { 7517 if (r.hasOwnProperty(i)) { 7518 m = self.getModule(i); 7519 if (m && m.use) { 7520 len = m.use.length; 7521 for (a = 0; a < len; a++) { 7522 m2 = self.getModule(m.use[a]); 7523 if (m2 && m2.use) { 7524 len2 = m2.use.length; 7525 for (v = 0; v < len2; v++) { 7526 r[m2.use[v]] = true; 7527 } 7528 } else { 7529 r[m.use[a]] = true; 7530 } 7531 } 7532 } 7533 } 7534 } 7535 self.required = r; 7536 } 7537 7538 }, 7539 /** 7540 * Explodes the required array to remove aliases and replace them with real modules 7541 * @method filterRequires 7542 * @param {Array} r The original requires array 7543 * @return {Array} The new array of exploded requirements 7544 */ 7545 filterRequires: function(r) { 7546 if (r) { 7547 if (!Y.Lang.isArray(r)) { 7548 r = [r]; 7549 } 7550 r = Y.Array(r); 7551 var c = [], i, mod, o, m; 7552 7553 for (i = 0; i < r.length; i++) { 7554 mod = this.getModule(r[i]); 7555 if (mod && mod.use) { 7556 for (o = 0; o < mod.use.length; o++) { 7557 //Must walk the other modules in case a module is a rollup of rollups (datatype) 7558 m = this.getModule(mod.use[o]); 7559 if (m && m.use && (m.name !== mod.name)) { 7560 c = Y.Array.dedupe([].concat(c, this.filterRequires(m.use))); 7561 } else { 7562 c.push(mod.use[o]); 7563 } 7564 } 7565 } else { 7566 c.push(r[i]); 7567 } 7568 } 7569 r = c; 7570 } 7571 return r; 7572 }, 7573 7574 /** 7575 Returns `true` if the module can be attached to the YUI instance. Runs 7576 the module's test if there is one and caches its result. 7577 7578 @method _canBeAttached 7579 @param {String} module Name of the module to check. 7580 @return {Boolean} Result of the module's test if it has one, or `true`. 7581 **/ 7582 _canBeAttached: function (m) { 7583 m = this.getModule(m); 7584 if (m && m.test) { 7585 if (!m.hasOwnProperty('_testResult')) { 7586 m._testResult = m.test(Y); 7587 } 7588 return m._testResult; 7589 } 7590 // return `true` for modules not registered as Loader will know what 7591 // to do with them later on 7592 return true; 7593 }, 7594 7595 /**
7596 * Returns an object containing properties for all modules required 7597 * in order to load the requested module 7598 * @method getRequires 7599 * @param {object} mod The module definition from moduleInfo. 7600 * @return {array} the expanded requirement list. 7601 */ 7602 getRequires: function(mod) { 7603 7604 if (!mod) { 7605 //console.log('returning no reqs for ' + mod.name); 7606 return NO_REQUIREMENTS; 7607 } 7608 7609 if (mod._parsed) { 7610 //console.log('returning requires for ' + mod.name, mod.requires); 7611 return mod.expanded || NO_REQUIREMENTS; 7612 } 7613 7614 //TODO add modue cache here out of scope.. 7615 7616 var i, m, j, length, add, packName, lang, testresults = this.testresults, 7617 name = mod.name, cond, 7618 adddef = ON_PAGE[name] && ON_PAGE[name].details, 7619 optReqs = mod.optionalRequires, 7620 d, go, def, 7621 r, old_mod, 7622 o, skinmod, skindef, skinpar, skinname, 7623 intl = mod.lang || mod.intl, 7624 ftests = Y.Features && Y.Features.tests.load, 7625 hash, reparse; 7626 7627 // console.log(name); 7628 7629 // pattern match leaves module stub that needs to be filled out 7630 if (mod.temp && adddef) { 7631 old_mod = mod; 7632 mod = this.addModule(adddef, name); 7633 mod.group = old_mod.group; 7634 mod.pkg = old_mod.pkg; 7635 delete mod.expanded; 7636 } 7637 7638 // console.log('cache: ' + mod.langCache + ' == ' + this.lang); 7639 7640 //If a skin or a lang is different, reparse.. 7641 reparse = !((!this.lang || mod.langCache === this.lang) && (mod.skinCache === this.skin.defaultSkin)); 7642 7643 if (mod.expanded && !reparse) { 7644 return mod.expanded; 7645 } 7646 7647 // Optional dependencies are dependencies that may or may not be 7648 // available. 7649 // This feature was designed specifically to be used when transpiling 7650 // ES6 modules, in order to use polyfills and regular scripts that define 7651 // global variables without having to import them since they should be 7652 // available in the global scope. 7653 if (optReqs) { 7654 for (i = 0, length = optReqs.length; i < length; i++) { 7655 if (this._canBeAttached(optReqs[i])) { 7656 mod.requires.push(optReqs[i]); 7657 } 7658 } 7659 } 7660 7661 d = []; 7662 hash = {}; 7663 r = this.filterRequires(mod.requires); 7664 if (mod.lang) { 7665 //If a module has a lang attribute, auto add the intl requirement. 7666 d.unshift('intl'); 7667 r.unshift('intl'); 7668 intl = true; 7669 } 7670 o = this.filterRequires(mod.optional); 7671 7672 7673 mod._parsed = true; 7674 mod.langCache = this.lang; 7675 mod.skinCache = this.skin.defaultSkin; 7676 7677 for (i = 0; i < r.length; i++) { 7678 if (!hash[r[i]]) { 7679 d.push(r[i]); 7680 hash[r[i]] = true; 7681 m = this.getModule(r[i]); 7682 if (m) { 7683 add = this.getRequires(m); 7684 intl = intl || (m.expanded_map && 7685 (INTL in m.expanded_map)); 7686 for (j = 0; j < add.length; j++) { 7687 d.push(add[j]); 7688 } 7689 } 7690 } 7691 } 7692 7693 // get the requirements from superseded modules, if any 7694 r = this.filterRequires(mod.supersedes); 7695 if (r) { 7696 for (i = 0; i < r.length; i++) { 7697 if (!hash[r[i]]) { 7698 // if this module has submodules, the requirements list is 7699 // expanded to include the submodules. This is so we can 7700 // prevent dups when a submodule is already loaded and the 7701 // parent is requested. 7702 if (mod.submodules) { 7703 d.push(r[i]); 7704 } 7705 7706 hash[r[i]] = true; 7707 m = this.getModule(r[i]); 7708 7709 if (m) { 7710 add = this.getRequires(m); 7711 intl = intl || (m.expanded_map && 7712 (INTL in m.expanded_map)); 7713 for (j = 0; j < add.length; j++) { 7714 d.push(add[j]); 7715 } 7716 } 7717 } 7718 } 7719 } 7720 7721 if (o && this.loadOptional) { 7722 for (i = 0; i < o.length; i++) { 7723 if (!hash[o[i]]) { 7724 d.push(o[i]); 7725 hash[o[i]] = true; 7726 m = this.getModuleInfo(o[i]); 7727 if (m) { 7728 add = this.getRequires(m); 7729 intl = intl || (m.expanded_map && 7730 (INTL in m.expanded_map)); 7731 for (j = 0; j < add.length; j++) { 7732 d.push(add[j]); 7733 } 7734 } 7735 } 7736 } 7737 } 7738 7739 cond = this.conditions[name]; 7740 7741 if (cond) { 7742 //Set the module to not parsed since we have conditionals and this could change the dependency tree. 7743 mod._parsed = false;
7744 if (testresults && ftests) { 7745 oeach(testresults, function(result, id) { 7746 var condmod = ftests[id].name; 7747 if (!hash[condmod] && ftests[id].trigger === name) { 7748 if (result && ftests[id]) { 7749 hash[condmod] = true; 7750 d.push(condmod); 7751 } 7752 } 7753 }); 7754 } else { 7755 for (i in cond) { 7756 if (cond.hasOwnProperty(i)) { 7757 if (!hash[i]) { 7758 def = cond[i]; 7759 //first see if they've specfied a ua check 7760 //then see if they've got a test fn & if it returns true 7761 //otherwise just having a condition block is enough 7762 go = def && ((!def.ua && !def.test) || (def.ua && Y.UA[def.ua]) || 7763 (def.test && def.test(Y, r))); 7764 7765 if (go) { 7766 hash[i] = true; 7767 d.push(i); 7768 m = this.getModule(i); 7769 if (m) { 7770 add = this.getRequires(m); 7771 for (j = 0; j < add.length; j++) { 7772 d.push(add[j]); 7773 } 7774 7775 } 7776 } 7777 } 7778 } 7779 } 7780 } 7781 } 7782 7783 // Create skin modules 7784 if (mod.skinnable) { 7785 skindef = this.skin.overrides; 7786 for (i in YUI.Env.aliases) { 7787 if (YUI.Env.aliases.hasOwnProperty(i)) { 7788 if (Y.Array.indexOf(YUI.Env.aliases[i], name) > -1) { 7789 skinpar = i; 7790 } 7791 } 7792 } 7793 if (skindef && (skindef[name] || (skinpar && skindef[skinpar]))) { 7794 skinname = name; 7795 if (skindef[skinpar]) { 7796 skinname = skinpar; 7797 } 7798 for (i = 0; i < skindef[skinname].length; i++) { 7799 skinmod = this._addSkin(skindef[skinname][i], name); 7800 if (!this.isCSSLoaded(skinmod, this._boot)) { 7801 d.push(skinmod); 7802 } 7803 } 7804 } else { 7805 skinmod = this._addSkin(this.skin.defaultSkin, name); 7806 if (!this.isCSSLoaded(skinmod, this._boot)) { 7807 d.push(skinmod); 7808 } 7809 } 7810 } 7811 7812 mod._parsed = false; 7813 7814 if (intl) { 7815 7816 if (mod.lang && !mod.langPack && Y.Intl) { 7817 lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang); 7818 packName = this.getLangPackName(lang, name); 7819 if (packName) { 7820 d.unshift(packName); 7821 } 7822 } 7823 d.unshift(INTL); 7824 } 7825 7826 mod.expanded_map = yArray.hash(d); 7827 7828 mod.expanded = YObject.keys(mod.expanded_map); 7829 7830 return mod.expanded; 7831 }, 7832 /** 7833 * Check to see if named css module is already loaded on the page 7834 * @method isCSSLoaded 7835 * @param {String} name The name of the css file 7836 * @param {Boolean} skip To skip the short-circuit for ignoreRegister 7837 * @return Boolean 7838 */ 7839 isCSSLoaded: function(name, skip) { 7840 //TODO - Make this call a batching call with name being an array 7841 if (!name || !YUI.Env.cssStampEl || (!skip && this.ignoreRegistered)) { 7842 return false; 7843 } 7844 var el = YUI.Env.cssStampEl, 7845 ret = false, 7846 mod = YUI.Env._cssLoaded[name], 7847 style = el.currentStyle; //IE 7848 7849 7850 if (mod !== undefined) { 7851 return mod; 7852 } 7853 7854 //Add the classname to the element 7855 el.className = name; 7856 7857 if (!style) { 7858 style = Y.config.doc.defaultView.getComputedStyle(el, null); 7859 } 7860 7861 if (style && style.display === 'none') { 7862 ret = true; 7863 } 7864 7865 7866 el.className = ''; //Reset the classname to '' 7867 7868 YUI.Env._cssLoaded[name] = ret; 7869 7870 return ret; 7871 }, 7872 7873 /** 7874 * Returns a hash of module names the supplied module satisfies. 7875 * @method getProvides 7876 * @param {string} name The name of the module. 7877 * @return {object} what this module provides. 7878 */ 7879 getProvides: function(name) { 7880 var m = this.getModule(name), o, s; 7881 // supmap = this.provides; 7882 7883 if (!m) { 7884 return NOT_FOUND; 7885 } 7886 7887 if (m && !m.provides) { 7888 o = {}; 7889 s = m.supersedes; 7890 7891 if (s) { 7892 yArray.each(s, function(v) { 7893 Y.mix(o, this.getProvides(v)); 7894 }, this); 7895 } 7896 7897 o[name] = true; 7898 m.provides = o; 7899 7900 } 7901 7902 return m.provides; 7903 }, 7904 7905 /** 7906 * Calculates the dependency tree, the result is stored in the sorted 7907 * property. 7908 * @method calculate 7909 * @param {object} o optional options object. 7910 * @param {string} type optional argument to prune modules. 7911 */ 7912 calculate: function(o, type) { 7913 if (o || type || this.dirty) { 7914 7915 if (o) { 7916 this._config(o); 7917 } 7918 7919 if (!this._init) { 7920 this._setup(); 7921 } 7922 7923 this._explode(); 7924 7925 if (this.allowRollup) { 7926 this._rollup(); 7927 } else { 7928 this._explodeRollups(); 7929 } 7930 this._reduce(); 7931 this._sort(); 7932 } 7933 }, 7934 /** 7935 * Creates a "psuedo" package for languages provided in the lang array 7936 * @method _addLangPack 7937 * @private 7938 * @param {String} lang The language to create 7939 * @param {Object} m The module definition to create the language pack around 7940 * @param {String} packName The name of the package (e.g: lang/datatype-date-en-US) 7941 * @return {Object} The module definition 7942 */ 7943 _addLangPack: function(lang, m, packName) { 7944 var name = m.name, 7945 packPath, conf, 7946 existing = this.getModuleInfo(packName); 7947 7948 if (!existing) { 7949 7950 packPath = _path((m.pkg || name), packName, JS, true); 7951 7952 conf = { 7953 path: packPath, 7954 intl: true, 7955 langPack: true, 7956 ext: m.ext, 7957 group: m.group, 7958 supersedes: [] 7959 }; 7960 if (m.root) { 7961 conf.root = m.root; 7962 } 7963 if (m.base) { 7964 conf.base = m.base; 7965 } 7966 7967 if (m.configFn) { 7968 conf.configFn = m.configFn; 7969 } 7970 7971 this.addModule(conf, packName); 7972 7973 if (lang) { 7974 Y.Env.lang = Y.Env.lang || {};
7975 Y.Env.lang[lang] = Y.Env.lang[lang] || {}; 7976 Y.Env.lang[lang][name] = true; 7977 } 7978 } 7979 7980 return this.getModuleInfo(packName); 7981 }, 7982 7983 /** 7984 * Investigates the current YUI configuration on the page. By default, 7985 * modules already detected will not be loaded again unless a force 7986 * option is encountered. Called by calculate() 7987 * @method _setup 7988 * @private 7989 */ 7990 _setup: function() { 7991 var info = this.moduleInfo, name, i, j, m, l, 7992 packName; 7993 7994 for (name in info) { 7995 if (info.hasOwnProperty(name)) { 7996 m = info[name]; 7997 if (m) { 7998 7999 // remove dups 8000 //m.requires = YObject.keys(yArray.hash(m.requires)); 8001 m.requires = yArray.dedupe(m.requires); 8002 8003 // Create lang pack modules 8004 //if (m.lang && m.lang.length) { 8005 if (m.lang) { 8006 // Setup root package if the module has lang defined, 8007 // it needs to provide a root language pack 8008 packName = this.getLangPackName(ROOT_LANG, name); 8009 this._addLangPack(null, m, packName); 8010 } 8011 8012 } 8013 } 8014 } 8015 8016 8017 //l = Y.merge(this.inserted); 8018 l = {}; 8019 8020 // available modules 8021 if (!this.ignoreRegistered) { 8022 Y.mix(l, GLOBAL_ENV.mods); 8023 } 8024 8025 // add the ignore list to the list of loaded packages 8026 if (this.ignore) { 8027 Y.mix(l, yArray.hash(this.ignore)); 8028 } 8029 8030 // expand the list to include superseded modules 8031 for (j in l) { 8032 if (l.hasOwnProperty(j)) { 8033 Y.mix(l, this.getProvides(j)); 8034 } 8035 } 8036 8037 // remove modules on the force list from the loaded list 8038 if (this.force) { 8039 for (i = 0; i < this.force.length; i++) { 8040 if (this.force[i] in l) { 8041 delete l[this.force[i]]; 8042 } 8043 } 8044 } 8045 8046 Y.mix(this.loaded, l); 8047 8048 this._init = true; 8049 }, 8050 8051 /** 8052 * Builds a module name for a language pack 8053 * @method getLangPackName 8054 * @param {string} lang the language code. 8055 * @param {string} mname the module to build it for. 8056 * @return {string} the language pack module name. 8057 */ 8058 getLangPackName: function(lang, mname) { 8059 return ('lang/' + mname + ((lang) ? '_' + lang : '')); 8060 }, 8061 /** 8062 * Inspects the required modules list looking for additional 8063 * dependencies. Expands the required list to include all 8064 * required modules. Called by calculate() 8065 * @method _explode 8066 * @private 8067 */ 8068 _explode: function() { 8069 //TODO Move done out of scope 8070 var r = this.required, m, reqs, done = {}, 8071 self = this, name, expound; 8072 8073 // the setup phase is over, all modules have been created 8074 self.dirty = false; 8075 8076 self._explodeRollups(); 8077 r = self.required; 8078 8079 for (name in r) { 8080 if (r.hasOwnProperty(name)) { 8081 if (!done[name]) { 8082 done[name] = true; 8083 m = self.getModule(name); 8084 if (m) { 8085 expound = m.expound; 8086 8087 if (expound) { 8088 r[expound] = self.getModule(expound); 8089 reqs = self.getRequires(r[expound]); 8090 Y.mix(r, yArray.hash(reqs)); 8091 } 8092 8093 reqs = self.getRequires(m); 8094 Y.mix(r, yArray.hash(reqs)); 8095 } 8096 } 8097 } 8098 } 8099 8100 }, 8101 /** 8102 * The default method used to test a module against a pattern 8103 * @method _patternTest 8104 * @private 8105 * @param {String} mname The module being tested 8106 * @param {String} pname The pattern to match 8107 */ 8108 _patternTest: function(mname, pname) { 8109 return (mname.indexOf(pname) > -1); 8110 }, 8111 /** 8112 * Get's the loader meta data for the requested module 8113 * @method getModule 8114 * @param {String} mname The module name to get 8115 * @return {Object} The module metadata 8116 */
8117 getModule: function(mname) { 8118 //TODO: Remove name check - it's a quick hack to fix pattern WIP 8119 if (!mname) { 8120 return null; 8121 } 8122 8123 var p, found, pname, 8124 m = this.getModuleInfo(mname), 8125 patterns = this.patterns; 8126 8127 // check the patterns library to see if we should automatically add 8128 // the module with defaults 8129 if (!m || (m && m.ext)) { 8130 for (pname in patterns) { 8131 if (patterns.hasOwnProperty(pname)) { 8132 p = patterns[pname]; 8133 8134 //There is no test method, create a default one that tests 8135 // the pattern against the mod name 8136 if (!p.test) { 8137 p.test = this._patternTest; 8138 } 8139 8140 if (p.test(mname, pname)) { 8141 // use the metadata supplied for the pattern 8142 // as the module definition. 8143 found = p; 8144 break; 8145 } 8146 } 8147 } 8148 } 8149 8150 if (!m) { 8151 if (found) { 8152 if (p.action) { 8153 p.action.call(this, mname, pname); 8154 } else { 8155 // ext true or false? 8156 m = this.addModule(Y.merge(found, { 8157 test: void 0, 8158 temp: true 8159 }), mname); 8160 if (m && found.configFn) { 8161 m.configFn = found.configFn; 8162 } 8163 } 8164 } 8165 } else { 8166 if (found && m && found.configFn && !m.configFn) { 8167 m.configFn = found.configFn; 8168 m.configFn(m); 8169 } 8170 } 8171 8172 return m; 8173 }, 8174 8175 // impl in rollup submodule 8176 _rollup: function() { }, 8177 8178 /** 8179 * Remove superceded modules and loaded modules. Called by 8180 * calculate() after we have the mega list of all dependencies 8181 * @method _reduce 8182 * @return {object} the reduced dependency hash. 8183 * @private 8184 */ 8185 _reduce: function(r) { 8186 8187 r = r || this.required; 8188 8189 var i, j, s, m, type = this.loadType, 8190 ignore = this.ignore ? yArray.hash(this.ignore) : false; 8191 8192 for (i in r) { 8193 if (r.hasOwnProperty(i)) { 8194 m = this.getModule(i); 8195 // remove if already loaded 8196 if (((this.loaded[i] || ON_PAGE[i]) && 8197 !this.forceMap[i] && !this.ignoreRegistered) || 8198 (type && m && m.type !== type)) { 8199 delete r[i]; 8200 } 8201 if (ignore && ignore[i]) { 8202 delete r[i]; 8203 } 8204 // remove anything this module supersedes 8205 s = m && m.supersedes; 8206 if (s) { 8207 for (j = 0; j < s.length; j++) { 8208 if (s[j] in r) { 8209 delete r[s[j]]; 8210 } 8211 } 8212 } 8213 } 8214 } 8215 8216 return r; 8217 }, 8218 /** 8219 * Handles the queue when a module has been loaded for all cases 8220 * @method _finish 8221 * @private 8222 * @param {String} msg The message from Loader 8223 * @param {Boolean} success A boolean denoting success or failure 8224 */ 8225 _finish: function(msg, success) { 8226 8227 _queue.running = false; 8228 8229 var onEnd = this.onEnd; 8230 if (onEnd) { 8231 onEnd.call(this.context, { 8232 msg: msg, 8233 data: this.data, 8234 success: success 8235 }); 8236 } 8237 this._continue(); 8238 }, 8239 /** 8240 * The default Loader onSuccess handler, calls this.onSuccess with a payload 8241 * @method _onSuccess 8242 * @private 8243 */ 8244 _onSuccess: function() { 8245 var self = this, skipped = Y.merge(self.skipped), fn, 8246 failed = [], rreg = self.requireRegistration, 8247 success, msg, i, mod; 8248 8249 for (i in skipped) { 8250 if (skipped.hasOwnProperty(i)) { 8251 delete self.inserted[i]; 8252 } 8253 } 8254 8255 self.skipped = {}; 8256 8257 for (i in self.inserted) { 8258 if (self.inserted.hasOwnProperty(i)) { 8259 mod = self.getModule(i); 8260 if (mod && rreg && mod.type === JS && !(i in YUI.Env.mods)) { 8261 failed.push(i); 8262 } else { 8263 Y.mix(self.loaded, self.getProvides(i)); 8264 } 8265 } 8266 } 8267 8268 fn = self.onSuccess; 8269 msg = (failed.length) ? 'notregistered' : 'success'; 8270 success = !(failed.length); 8271 if (fn) { 8272 fn.call(self.context, { 8273 msg: msg, 8274 data: self.data, 8275 success: success, 8276 failed: failed, 8277 skipped: skipped 8278 }); 8279 } 8280 self._finish(msg, success); 8281 }, 8282 /** 8283 * The default Loader onProgress handler, calls this.onProgress with a payload 8284 * @method _onProgress 8285 * @private 8286 */ 8287 _onProgress: function(e) { 8288 var self = this, i;
8289 //set the internal cache to what just came in. 8290 if (e.data && e.data.length) { 8291 for (i = 0; i < e.data.length; i++) { 8292 e.data[i] = self.getModule(e.data[i].name); 8293 } 8294 } 8295 if (self.onProgress) { 8296 self.onProgress.call(self.context, { 8297 name: e.url, 8298 data: e.data 8299 }); 8300 } 8301 }, 8302 /** 8303 * The default Loader onFailure handler, calls this.onFailure with a payload 8304 * @method _onFailure 8305 * @private 8306 */ 8307 _onFailure: function(o) { 8308 var f = this.onFailure, msg = [], i = 0, len = o.errors.length; 8309 8310 for (i; i < len; i++) { 8311 msg.push(o.errors[i].error); 8312 } 8313 8314 msg = msg.join(','); 8315 8316 8317 if (f) { 8318 f.call(this.context, { 8319 msg: msg, 8320 data: this.data, 8321 success: false 8322 }); 8323 } 8324 8325 this._finish(msg, false); 8326 8327 }, 8328 8329 /** 8330 * The default Loader onTimeout handler, calls this.onTimeout with a payload 8331 * @method _onTimeout 8332 * @param {Get.Transaction} transaction The Transaction object from `Y.Get` 8333 * @private 8334 */ 8335 _onTimeout: function(transaction) { 8336 var f = this.onTimeout; 8337 if (f) { 8338 f.call(this.context, { 8339 msg: 'timeout', 8340 data: this.data, 8341 success: false, 8342 transaction: transaction 8343 }); 8344 } 8345 }, 8346 8347 /** 8348 * Sorts the dependency tree. The last step of calculate() 8349 * @method _sort 8350 * @private 8351 */ 8352 _sort: function() { 8353 var name, 8354 8355 // Object containing module names. 8356 required = this.required, 8357 8358 // Keep track of whether we've visited a module. 8359 visited = {}; 8360 8361 // Will contain modules names, in the correct order, 8362 // according to dependencies. 8363 this.sorted = []; 8364 8365 for (name in required) { 8366 if (!visited[name] && required.hasOwnProperty(name)) { 8367 this._visit(name, visited); 8368 } 8369 } 8370 }, 8371 8372 /** 8373 * Recursively visits the dependencies of the module name 8374 * passed in, and appends each module name to the `sorted` property. 8375 * @param {String} name The name of a module. 8376 * @param {Object} visited Keeps track of whether a module was visited. 8377 * @method _visit 8378 * @private 8379 */ 8380 _visit: function (name, visited) { 8381 var required, condition, moduleInfo, dependency, dependencies, 8382 trigger, isAfter, i, l; 8383 8384 visited[name] = true; 8385 required = this.required; 8386 moduleInfo = this.moduleInfo[name]; 8387 condition = this.conditions[name] || {}; 8388 8389 if (moduleInfo) { 8390 // Recurse on each dependency of this module, 8391 // figuring out its dependencies, and so on. 8392 dependencies = moduleInfo.expanded || moduleInfo.requires; 8393 8394 for (i = 0, l = dependencies.length; i < l; ++i) { 8395 dependency = dependencies[i]; 8396 trigger = condition[dependency]; 8397 8398 // We cannot process this dependency yet if it must 8399 // appear after our current module. 8400 isAfter = trigger && (!trigger.when || trigger.when === "after"); 8401 8402 // Is this module name in the required list of modules, 8403 // and have we not already visited it? 8404 if (required[dependency] && !visited[dependency] && !isAfter) { 8405 this._visit(dependency, visited); 8406 } 8407 } 8408 } 8409 8410 this.sorted.push(name); 8411 }, 8412 8413 /** 8414 * Handles the actual insertion of script/link tags 8415 * @method _insert 8416 * @private 8417 * @param {Object} source The YUI instance the request came from 8418 * @param {Object} o The metadata to include 8419 * @param {String} type JS or CSS 8420 * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta 8421 */ 8422 _insert: function(source, o, type, skipcalc) { 8423 8424 8425 // restore the state at the time of the request 8426 if (source) { 8427 this._config(source); 8428 } 8429 8430 // build the dependency list 8431 // don't include type so we can process CSS and script in 8432 // one pass when the type is not specified. 8433 8434 var modules = this.resolve(!skipcalc),
8435 self = this, comp = 0, actions = 0, 8436 mods = {}, deps, complete; 8437 8438 self._refetch = []; 8439 8440 if (type) { 8441 //Filter out the opposite type and reset the array so the checks later work 8442 modules[((type === JS) ? CSS : JS)] = []; 8443 } 8444 if (!self.fetchCSS) { 8445 modules.css = []; 8446 } 8447 if (modules.js.length) { 8448 comp++; 8449 } 8450 if (modules.css.length) { 8451 comp++; 8452 } 8453 8454 //console.log('Resolved Modules: ', modules); 8455 8456 complete = function(d) { 8457 actions++; 8458 var errs = {}, i = 0, o = 0, u = '', fn, 8459 modName, resMods; 8460 8461 if (d && d.errors) { 8462 for (i = 0; i < d.errors.length; i++) { 8463 if (d.errors[i].request) { 8464 u = d.errors[i].request.url; 8465 } else { 8466 u = d.errors[i]; 8467 } 8468 errs[u] = u; 8469 } 8470 } 8471 8472 if (d && d.data && d.data.length && (d.type === 'success')) { 8473 for (i = 0; i < d.data.length; i++) { 8474 self.inserted[d.data[i].name] = true; 8475 //If the external module has a skin or a lang, reprocess it 8476 if (d.data[i].lang || d.data[i].skinnable) { 8477 delete self.inserted[d.data[i].name]; 8478 self._refetch.push(d.data[i].name); 8479 } 8480 } 8481 } 8482 8483 if (actions === comp) { 8484 self._loading = null; 8485 if (self._refetch.length) { 8486 //Get the deps for the new meta-data and reprocess 8487 for (i = 0; i < self._refetch.length; i++) { 8488 deps = self.getRequires(self.getModule(self._refetch[i])); 8489 for (o = 0; o < deps.length; o++) { 8490 if (!self.inserted[deps[o]]) { 8491 //We wouldn't be to this point without the module being here 8492 mods[deps[o]] = deps[o]; 8493 } 8494 } 8495 } 8496 mods = Y.Object.keys(mods); 8497 if (mods.length) { 8498 self.require(mods); 8499 resMods = self.resolve(true);
8500 if (resMods.cssMods.length) { 8501 for (i=0; i < resMods.cssMods.length; i++) { 8502 modName = resMods.cssMods[i].name; 8503 delete YUI.Env._cssLoaded[modName]; 8504 if (self.isCSSLoaded(modName)) { 8505 self.inserted[modName] = true; 8506 delete self.required[modName]; 8507 } 8508 } 8509 self.sorted = []; 8510 self._sort(); 8511 } 8512 d = null; //bail 8513 self._insert(); //insert the new deps 8514 } 8515 } 8516 if (d && d.fn) { 8517 fn = d.fn; 8518 delete d.fn; 8519 fn.call(self, d); 8520 } 8521 } 8522 }; 8523 8524 this._loading = true; 8525 8526 if (!modules.js.length && !modules.css.length) { 8527 actions = -1; 8528 complete({ 8529 fn: self._onSuccess 8530 }); 8531 return; 8532 } 8533 8534 8535 if (modules.css.length) { //Load CSS first 8536 Y.Get.css(modules.css, { 8537 data: modules.cssMods, 8538 attributes: self.cssAttributes, 8539 insertBefore: self.insertBefore, 8540 charset: self.charset, 8541 timeout: self.timeout, 8542 context: self, 8543 onProgress: function(e) { 8544 self._onProgress.call(self, e); 8545 }, 8546 onTimeout: function(d) { 8547 self._onTimeout.call(self, d); 8548 }, 8549 onSuccess: function(d) { 8550 d.type = 'success'; 8551 d.fn = self._onSuccess; 8552 complete.call(self, d); 8553 }, 8554 onFailure: function(d) { 8555 d.type = 'failure'; 8556 d.fn = self._onFailure; 8557 complete.call(self, d); 8558 } 8559 }); 8560 } 8561 8562 if (modules.js.length) { 8563 Y.Get.js(modules.js, { 8564 data: modules.jsMods, 8565 insertBefore: self.insertBefore, 8566 attributes: self.jsAttributes, 8567 charset: self.charset, 8568 timeout: self.timeout, 8569 autopurge: false, 8570 context: self, 8571 async: self.async, 8572 onProgress: function(e) { 8573 self._onProgress.call(self, e); 8574 }, 8575 onTimeout: function(d) { 8576 self._onTimeout.call(self, d); 8577 }, 8578 onSuccess: function(d) { 8579 d.type = 'success'; 8580 d.fn = self._onSuccess; 8581 complete.call(self, d); 8582 }, 8583 onFailure: function(d) { 8584 d.type = 'failure'; 8585 d.fn = self._onFailure; 8586 complete.call(self, d); 8587 } 8588 }); 8589 } 8590 }, 8591 /** 8592 * Once a loader operation is completely finished, process any additional queued items. 8593 * @method _continue 8594 * @private 8595 */ 8596 _continue: function() { 8597 if (!(_queue.running) && _queue.size() > 0) { 8598 _queue.running = true; 8599 _queue.next()(); 8600 } 8601 }, 8602 8603 /** 8604 * inserts the requested modules and their dependencies. 8605 * <code>type</code> can be "js" or "css". Both script and 8606 * css are inserted if type is not provided. 8607 * @method insert 8608 * @param {object} o optional options object. 8609 * @param {string} type the type of dependency to insert. 8610 */ 8611 insert: function(o, type, skipsort) { 8612 var self = this, copy = Y.merge(this); 8613 delete copy.require; 8614 delete copy.dirty; 8615 _queue.add(function() { 8616 self._insert(copy, o, type, skipsort); 8617 }); 8618 this._continue(); 8619 }, 8620 8621 /** 8622 * Executed every time a module is loaded, and if we are in a load 8623 * cycle, we attempt to load the next script. Public so that it 8624 * is possible to call this if using a method other than 8625 * Y.register to determine when scripts are fully loaded 8626 * @method loadNext 8627 * @deprecated 8628 * @param {string} mname optional the name of the module that has 8629 * been loaded (which is usually why it is time to load the next 8630 * one). 8631 */ 8632 loadNext: function() { 8633 return; 8634 }, 8635 8636 /** 8637 * Apply filter defined for this instance to a url/path 8638 * @method _filter 8639 * @param {string} u the string to filter. 8640 * @param {string} name the name of the module, if we are processing 8641 * a single module as opposed to a combined url. 8642 * @return {string} the filtered string. 8643 * @private 8644 */ 8645 _filter: function(u, name, group) { 8646 var f = this.filter, 8647 hasFilter = name && (name in this.filters), 8648 modFilter = hasFilter && this.filters[name], 8649 groupName = group || (this.getModuleInfo(name) || {}).group || null; 8650 8651 if (groupName && this.groups[groupName] && this.groups[groupName].filter) { 8652 modFilter = this.groups[groupName].filter; 8653 hasFilter = true; 8654 } 8655 8656 if (u) { 8657 if (hasFilter) { 8658 f = (L.isString(modFilter)) ? this.FILTER_DEFS[modFilter.toUpperCase()] || null : modFilter; 8659 } 8660 if (f) { 8661 u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr); 8662 } 8663 } 8664 return u; 8665 }, 8666 8667 /** 8668 * Generates the full url for a module 8669 * @method _url 8670 * @param {string} path the path fragment. 8671 * @param {String} name The name of the module 8672 * @param {String} [base] The base url to use. Defaults to self.base 8673 * @return {string} the full url. 8674 * @private 8675 */ 8676 _url: function(path, name, base) { 8677 return this._filter((base || this.base || '') + path, name); 8678 }, 8679 /** 8680 * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules. 8681 * @method resolve 8682 * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else 8683 * @param {Array} [sorted=loader.sorted] An override for the loader.sorted array 8684 * @return {Object} Object hash (js and css) of two arrays of file lists 8685 * @example This method can be used as an off-line dep calculator 8686 * 8687 * var Y = YUI(); 8688 * var loader = new Y.Loader({ 8689 * filter: 'debug', 8690 * base: '../../', 8691 * root: 'build/', 8692 * combine: true, 8693 * require: ['node', 'dd', 'console'] 8694 * }); 8695 * var out = loader.resolve(true); 8696 * 8697 */ 8698 resolve: function(calc, sorted) { 8699 var self = this, 8700 resolved = { js: [], jsMods: [], css: [], cssMods: [] }, 8701 addSingle, 8702 usePathogen = Y.config.comboLoader && Y.config.customComboBase; 8703 8704 if (self.skin.overrides || self.skin.defaultSkin !== DEFAULT_SKIN || self.ignoreRegistered) { 8705 self._resetModules(); 8706 } 8707 8708 if (calc) { 8709 self.calculate(); 8710 } 8711 sorted = sorted || self.sorted; 8712 8713 addSingle = function(mod) { 8714 if (mod) { 8715 var group = (mod.group && self.groups[mod.group]) || NOT_FOUND, 8716 url; 8717 8718 //Always assume it's async 8719 if (group.async === false) { 8720 mod.async = group.async; 8721 } 8722 8723 url = (mod.fullpath) ? self._filter(mod.fullpath, mod.name) : 8724 self._url(mod.path, mod.name, group.base || mod.base); 8725 8726 if (mod.attributes || mod.async === false) { 8727 url = { 8728 url: url, 8729 async: mod.async 8730 }; 8731 if (mod.attributes) { 8732 url.attributes = mod.attributes; 8733 } 8734 } 8735 resolved[mod.type].push(url); 8736 resolved[mod.type + 'Mods'].push(mod); 8737 } else { 8738 } 8739 8740 }; 8741 8742 /*jslint vars: true */ 8743 var inserted = (self.ignoreRegistered) ? {}
8743 : self.inserted, 8744 comboSources, 8745 maxURLLength, 8746 comboMeta, 8747 comboBase, 8748 comboSep, 8749 group, 8750 mod, 8751 len, 8752 i, 8753 hasComboModule = false; 8754 8755 /*jslint vars: false */ 8756 8757 for (i = 0, len = sorted.length; i < len; i++) { 8758 mod = self.getModule(sorted[i]); 8759 if (!mod || inserted[mod.name]) { 8760 continue; 8761 } 8762 8763 group = self.groups[mod.group]; 8764 8765 comboBase = self.comboBase; 8766 8767 if (group) { 8768 if (!group.combine || mod.fullpath) { 8769 //This is not a combo module, skip it and load it singly later. 8770 addSingle(mod); 8771 continue; 8772 } 8773 mod.combine = true; 8774 8775 if (typeof group.root === 'string') { 8776 mod.root = group.root; 8777 } 8778 8779 comboBase = group.comboBase || comboBase; 8780 comboSep = group.comboSep; 8781 maxURLLength = group.maxURLLength; 8782 } else { 8783 if (!self.combine) { 8784 //This is not a combo module, skip it and load it singly later. 8785 addSingle(mod); 8786 continue; 8787 } 8788 } 8789 8790 if (!mod.combine && mod.ext) { 8791 addSingle(mod); 8792 continue; 8793 } 8794 hasComboModule = true; 8795 comboSources = comboSources || {}; 8796 comboSources[comboBase] = comboSources[comboBase] || 8797 { js: [], jsMods: [], css: [], cssMods: [] }; 8798 8799 comboMeta = comboSources[comboBase]; 8800 comboMeta.group = mod.group; 8801 comboMeta.comboSep = comboSep || self.comboSep; 8802 comboMeta.maxURLLength = maxURLLength || self.maxURLLength; 8803 8804 comboMeta[mod.type + 'Mods'].push(mod); 8805 if (mod.type === JS || mod.type === CSS) { 8806 resolved[mod.type + 'Mods'].push(mod); 8807 } 8808 } 8809 //only encode if we have something to encode 8810 if (hasComboModule) { 8811 if (usePathogen) { 8812 resolved = this._pathogenEncodeComboSources(resolved); 8813 } else { 8814 resolved = this._encodeComboSources(resolved, comboSources); 8815 } 8816 } 8817 return resolved; 8818 }, 8819 8820 /** 8821 * Encodes combo sources and appends them to an object hash of arrays from `loader.resolve`. 8822 * 8823 * @method _encodeComboSources 8824 * @param {Object} resolved The object hash of arrays in which to attach the encoded combo sources. 8825 * @param {Object} comboSources An object containing relevant data about modules. 8826 * @return Object 8827 * @private 8828 */ 8829 _encodeComboSources: function(resolved, comboSources) { 8830 var fragSubset, 8831 modules, 8832 tmpBase, 8833 baseLen, 8834 frags, 8835 frag, 8836 type, 8837 mod, 8838 maxURLLength, 8839 comboBase, 8840 comboMeta, 8841 comboSep, 8842 i, 8843 len, 8844 self = this; 8845 8846 for (comboBase in comboSources) { 8847 if (comboSources.hasOwnProperty(comboBase)) { 8848 comboMeta = comboSources[comboBase]; 8849 comboSep = comboMeta.comboSep; 8850 maxURLLength = comboMeta.maxURLLength; 8851 for (type in comboMeta) { 8852 if (type === JS || type === CSS) { 8853 modules = comboMeta[type + 'Mods']; 8854 frags = []; 8855 for (i = 0, len = modules.length; i < len; i += 1) { 8856 mod = modules[i]; 8857 frag = ((typeof mod.root === 'string') ? mod.root : self.root) + (mod.path || mod.fullpath); 8858 frags.push( 8859 self._filter(frag, mod.name) 8860 ); 8861 } 8862 tmpBase = comboBase + frags.join(comboSep); 8863 baseLen = tmpBase.length; 8864 if (maxURLLength <= comboBase.length) { 8865 maxURLLength = MAX_URL_LENGTH; 8866 } 8867 8868 if (frags.length) { 8869 if (baseLen > maxURLLength) { 8870 fragSubset = []; 8871 for (i = 0, len = frags.length; i < len; i++) { 8872 fragSubset.push(frags[i]); 8873 tmpBase = comboBase + fragSubset.join(comboSep); 8874 8875 if (tmpBase.length > maxURLLength) { 8876 frag = fragSubset.pop(); 8877 tmpBase = comboBase + fragSubset.join(comboSep); 8878 resolved[type].push(self._filter(tmpBase, null, comboMeta.group)); 8879 fragSubset = []; 8880 if (frag) { 8881 fragSubset.push(frag); 8882 } 8883 } 8884 } 8885 if (fragSubset.length) { 8886 tmpBase = comboBase + fragSubset.join(comboSep); 8887 resolved[type].push(self._filter(tmpBase, null, comboMeta.group)); 8888 } 8889 } else { 8890 resolved[type].push(self._filter(tmpBase, null, comboMeta.group)); 8891 } 8892 } 8893 } 8894 } 8895 } 8896 } 8897 return resolved; 8898 }, 8899 8900 /** 8901 Shortcut to calculate, resolve and load all modules. 8902 8903 var loader = new Y.Loader({ 8904 ignoreRegistered: true, 8905 modules: { 8906 mod: { 8907 path: 'mod.js' 8908 } 8909 }, 8910 requires: [ 'mod' ] 8911 }); 8912 loader.load(function() { 8913 console.log('All modules have loaded..'); 8914 }); 8915 8916 8917 @method load 8918 @param {Function} cb Executed after all load operations are complete 8919 */ 8920 load: function(cb) { 8921 if (!cb) { 8922 return; 8923 } 8924 var self = this, 8925 out = self.resolve(true); 8926 8927 self.data = out; 8928 8929 self.onEnd = function() { 8930 cb.apply(self.context || self, arguments); 8931 }; 8932 8933 self.insert(); 8934 } 8935}; 8936 8937 8938}, 'patched-v3.18.1', {"requires": ["get", "features"]}); 8939YUI.add('loader-rollup', function (Y, NAME) { 8940 8941/** 8942 * Optional automatic rollup logic for reducing http connections 8943 * when not using a combo service. 8944 * @module loader 8945 * @submodule rollup 8946 */ 8947 8948/** 8949 * Look for rollup packages to determine if all of the modules a 8950 * rollup supersedes are required. If so, include the rollup to 8951 * help reduce the total number of connections required. Called 8952 * by calculate(). This is an optional feature, and requires the 8953 * appropriate submodule to function. 8954 * @method _rollup 8955 * @for Loader 8956 * @private 8957 */ 8958Y.Loader.prototype._rollup = function() { 8959 var i, j, m, s, r = this.required, roll, 8960 info = this.moduleInfo, rolled, c, smod; 8961 8962 // find and cache rollup modules 8963 if (this.dirty || !this.rollups) { 8964 this.rollups = {}; 8965 for (i in info) { 8966 if (info.hasOwnProperty(i)) { 8967 m = this.getModule(i); 8968 // if (m && m.rollup && m.supersedes) { 8969 if (m && m.rollup) { 8970 this.rollups[i] = m; 8971 } 8972 } 8973 } 8974 } 8975 8976 // make as many passes as needed to pick up rollup rollups 8977 for (;;) { 8978 rolled = false;
8979 8980 // go through the rollup candidates 8981 for (i in this.rollups) { 8982 if (this.rollups.hasOwnProperty(i)) { 8983 // there can be only one, unless forced 8984 if (!r[i] && ((!this.loaded[i]) || this.forceMap[i])) { 8985 m = this.getModule(i); 8986 s = m.supersedes || []; 8987 roll = false; 8988 8989 // @TODO remove continue 8990 if (!m.rollup) { 8991 continue; 8992 } 8993 8994 c = 0; 8995 8996 // check the threshold 8997 for (j = 0; j < s.length; j++) { 8998 smod = info[s[j]]; 8999 9000 // if the superseded module is loaded, we can't 9001 // load the rollup unless it has been forced. 9002 if (this.loaded[s[j]] && !this.forceMap[s[j]]) { 9003 roll = false; 9004 break; 9005 // increment the counter if this module is required. 9006 // if we are beyond the rollup threshold, we will 9007 // use the rollup module 9008 } else if (r[s[j]] && m.type === smod.type) { 9009 c++; 9010 roll = (c >= m.rollup); 9011 if (roll) { 9012 break; 9013 } 9014 } 9015 } 9016 9017 if (roll) { 9018 // add the rollup 9019 r[i] = true; 9020 rolled = true; 9021 9022 // expand the rollup's dependencies 9023 this.getRequires(m); 9024 } 9025 } 9026 } 9027 } 9028 9029 // if we made it here w/o rolling up something, we are done 9030 if (!rolled) { 9031 break; 9032 } 9033 } 9034}; 9035 9036 9037}, 'patched-v3.18.1', {"requires": ["loader-base"]}); 9038YUI.add('loader-yui3', function (Y, NAME) { 9039 9040/* This file is auto-generated by (yogi loader --yes --mix --start ../) */ 9041 9042/*jshint maxlen:900, eqeqeq: false */ 9043 9044/** 9045 * YUI 3 module metadata 9046 * @module loader 9047 * @submodule loader-yui3 9048 */ 9049YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {}; 9050Y.mix(YUI.Env[Y.version].modules, { 9051 "align-plugin": { 9052 "requires": [ 9053 "node-screen", 9054 "node-pluginhost" 9055 ] 9056 }, 9057 "anim": { 9058 "use": [ 9059 "anim-base", 9060 "anim-color", 9061 "anim-curve", 9062 "anim-easing", 9063 "anim-node-plugin", 9064 "anim-scroll", 9065 "anim-xy" 9066 ] 9067 }, 9068 "anim-base": { 9069 "requires": [ 9070 "base-base", 9071 "node-style", 9072 "color-base" 9073 ] 9074 }, 9075 "anim-color": { 9076 "requires": [ 9077 "anim-base" 9078 ] 9079 }, 9080 "anim-curve": { 9081 "requires": [ 9082 "anim-xy" 9083 ] 9084 }, 9085 "anim-easing": { 9086 "requires": [ 9087 "anim-base" 9088 ] 9089 }, 9090 "anim-node-plugin": { 9091 "requires": [ 9092 "node-pluginhost", 9093 "anim-base" 9094 ] 9095 }, 9096 "anim-scroll": { 9097 "requires": [ 9098 "anim-base" 9099 ] 9100 }, 9101 "anim-shape": { 9102 "requires": [ 9103 "anim-base", 9104 "anim-easing", 9105 "anim-color", 9106 "matrix" 9107 ] 9108 }, 9109 "anim-shape-transform": { 9110 "use": [ 9111 "anim-shape" 9112 ] 9113 }, 9114 "anim-xy": { 9115 "requires": [ 9116 "anim-base", 9117 "node-screen" 9118 ] 9119 }, 9120 "app": { 9121 "use": [ 9122 "app-base", 9123 "app-content", 9124 "app-transitions", 9125 "lazy-model-list", 9126 "model", 9127 "model-list", 9128 "model-sync-rest", 9129 "model-sync-local", 9130 "router", 9131 "view", 9132 "view-node-map" 9133 ] 9134 }, 9135 "app-base": { 9136 "requires": [ 9137 "classnamemanager", 9138 "pjax-base", 9139 "router", 9140 "view" 9141 ] 9142 }, 9143 "app-content": { 9144 "requires": [ 9145 "app-base", 9146 "pjax-content" 9147 ] 9148 }, 9149 "app-transitions": { 9150 "requires": [ 9151 "app-base" 9152 ] 9153 }, 9154 "app-transitions-css": { 9155 "type": "css" 9156 }, 9157 "app-transitions-native": { 9158 "condition": { 9159 "name": "app-transitions-native", 9160 "test": function (Y) { 9161 var doc = Y.config.doc, 9162 node = doc ? doc.documentElement : null; 9163 9164 if (node && node.style) { 9165 return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 9166 } 9167 9168 return false;
9169}, 9170 "trigger": "app-transitions" 9171 }, 9172 "requires": [ 9173 "app-transitions", 9174 "app-transitions-css", 9175 "parallel", 9176 "transition" 9177 ] 9178 }, 9179 "array-extras": { 9180 "requires": [ 9181 "yui-base" 9182 ] 9183 }, 9184 "array-invoke": { 9185 "requires": [ 9186 "yui-base" 9187 ] 9188 }, 9189 "arraylist": { 9190 "requires": [ 9191 "yui-base" 9192 ] 9193 }, 9194 "arraylist-add": { 9195 "requires": [ 9196 "arraylist" 9197 ] 9198 }, 9199 "arraylist-filter": { 9200 "requires": [ 9201 "arraylist" 9202 ] 9203 }, 9204 "arraysort": { 9205 "requires": [ 9206 "yui-base" 9207 ] 9208 }, 9209 "async-queue": { 9210 "requires": [ 9211 "event-custom" 9212 ] 9213 }, 9214 "attribute": { 9215 "use": [ 9216 "attribute-base", 9217 "attribute-complex" 9218 ] 9219 }, 9220 "attribute-base": { 9221 "requires": [ 9222 "attribute-core", 9223 "attribute-observable", 9224 "attribute-extras" 9225 ] 9226 }, 9227 "attribute-complex": { 9228 "requires": [ 9229 "attribute-base" 9230 ] 9231 }, 9232 "attribute-core": { 9233 "requires": [ 9234 "oop" 9235 ] 9236 }, 9237 "attribute-events": { 9238 "use": [ 9239 "attribute-observable" 9240 ] 9241 }, 9242 "attribute-extras": { 9243 "requires": [ 9244 "oop" 9245 ] 9246 }, 9247 "attribute-observable": { 9248 "requires": [ 9249 "event-custom" 9250 ] 9251 }, 9252 "autocomplete": { 9253 "use": [ 9254 "autocomplete-base", 9255 "autocomplete-sources", 9256 "autocomplete-list", 9257 "autocomplete-plugin" 9258 ] 9259 }, 9260 "autocomplete-base": { 9261 "optional": [ 9262 "autocomplete-sources" 9263 ], 9264 "requires": [ 9265 "array-extras", 9266 "base-build", 9267 "escape", 9268 "event-valuechange", 9269 "node-base" 9270 ] 9271 }, 9272 "autocomplete-filters": { 9273 "requires": [ 9274 "array-extras", 9275 "text-wordbreak" 9276 ] 9277 }, 9278 "autocomplete-filters-accentfold": { 9279 "requires": [ 9280 "array-extras", 9281 "text-accentfold", 9282 "text-wordbreak" 9283 ] 9284 }, 9285 "autocomplete-highlighters": { 9286 "requires": [ 9287 "array-extras", 9288 "highlight-base" 9289 ] 9290 }, 9291 "autocomplete-highlighters-accentfold": { 9292 "requires": [ 9293 "array-extras", 9294 "highlight-accentfold" 9295 ] 9296 }, 9297 "autocomplete-list": { 9298 "after": [ 9299 "autocomplete-sources" 9300 ], 9301 "lang": [ 9302 "en", 9303 "es", 9304 "hu", 9305 "it" 9306 ], 9307 "requires": [ 9308 "autocomplete-base", 9309 "event-resize", 9310 "node-screen", 9311 "selector-css3", 9312 "shim-plugin", 9313 "widget", 9314 "widget-position", 9315 "widget-position-align" 9316 ], 9317 "skinnable": true 9318 }, 9319 "autocomplete-list-keys": { 9320 "condition": { 9321 "name": "autocomplete-list-keys", 9322 "test": function (Y) { 9323 // Only add keyboard support to autocomplete-list if this doesn't appear to 9324 // be an iOS or Android-based mobile device. 9325 // 9326 // There's currently no feasible way to actually detect whether a device has 9327 // a hardware keyboard, so this sniff will have to do. It can easily be 9328 // overridden by manually loading the autocomplete-list-keys module. 9329 // 9330 // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari 9331 // doesn't fire the keyboard events used by AutoCompleteList, so there's 9332 // no point loading the -keys module even when a bluetooth keyboard may be 9333 // available. 9334 return !(Y.UA.ios || Y.UA.android); 9335}, 9336 "trigger": "autocomplete-list" 9337 }, 9338 "requires": [ 9339 "autocomplete-list", 9340 "base-build" 9341 ] 9342 }, 9343 "autocomplete-plugin": { 9344 "requires": [ 9345 "autocomplete-list", 9346 "node-pluginhost" 9347 ] 9348 }, 9349 "autocomplete-sources": { 9350 "optional": [ 9351 "io-base", 9352 "json-parse", 9353 "jsonp", 9354 "yql" 9355 ], 9356 "requires": [ 9357 "autocomplete-base" 9358 ] 9359 }, 9360 "axes": { 9361 "use": [ 9362 "axis-numeric", 9363 "axis-category", 9364 "axis-time", 9365 "axis-stacked" 9366 ] 9367 }, 9368 "axes-base": { 9369 "use": [ 9370 "axis-numeric-base", 9371 "axis-category-base", 9372 "axis-time-base", 9373 "axis-stacked-base" 9374 ] 9375 }, 9376 "axis": { 9377 "requires": [ 9378 "dom", 9379 "widget", 9380 "widget-position", 9381 "widget-stack", 9382 "graphics", 9383 "axis-base" 9384 ] 9385 }, 9386 "axis-base": { 9387 "requires": [ 9388 "classnamemanager", 9389 "datatype-number", 9390 "datatype-date", 9391 "base", 9392 "event-custom" 9393 ] 9394 }, 9395 "axis-category": { 9396 "requires": [ 9397 "axis", 9398 "axis-category-base" 9399 ] 9400 }, 9401 "axis-category-base": { 9402 "requires": [ 9403 "axis-base" 9404 ] 9405 }, 9406 "axis-numeric": { 9407 "requires": [ 9408 "axis", 9409 "axis-numeric-base" 9410 ] 9411 }, 9412 "axis-numeric-base": { 9413 "requires": [ 9414 "axis-base" 9415 ] 9416 }, 9417 "axis-stacked": { 9418 "requires": [ 9419 "axis-numeric", 9420 "axis-stacked-base" 9421 ] 9422 }, 9423 "axis-stacked-base": { 9424 "requires": [ 9425 "axis-numeric-base" 9426 ] 9427 }, 9428 "axis-time": { 9429 "requires": [ 9430 "axis", 9431 "axis-time-base" 9432 ] 9433 }, 9434 "axis-time-base": { 9435 "requires": [ 9436 "axis-base" 9437 ] 9438 }, 9439 "base": { 9440 "use": [ 9441 "base-base", 9442 "base-pluginhost", 9443 "base-build" 9444 ] 9445 }, 9446 "base-base": { 9447 "requires": [ 9448 "attribute-base", 9449 "base-core", 9450 "base-observable" 9451 ] 9452 }, 9453 "base-build": { 9454 "requires": [ 9455 "base-base" 9456 ] 9457 }, 9458 "base-core": { 9459 "requires": [ 9460 "attribute-core" 9461 ] 9462 }, 9463 "base-observable": { 9464 "requires": [ 9465 "attribute-observable", 9466 "base-core" 9467 ] 9468 }, 9469 "base-pluginhost": { 9470 "requires": [ 9471 "base-base", 9472 "pluginhost" 9473 ] 9474 }, 9475 "button": { 9476 "requires": [ 9477 "button-core", 9478 "cssbutton", 9479 "widget" 9480 ] 9481 }, 9482 "button-core": { 9483 "requires": [ 9484 "attribute-core", 9485 "classnamemanager", 9486 "node-base", 9487 "escape" 9488 ] 9489 }, 9490 "button-group": { 9491 "requires": [ 9492 "button-plugin", 9493 "cssbutton", 9494 "widget" 9495 ] 9496 }, 9497 "button-plugin": { 9498 "requires": [ 9499 "button-core", 9500 "cssbutton", 9501 "node-pluginhost" 9502 ] 9503 }, 9504 "cache": { 9505 "use": [ 9506 "cache-base", 9507 "cache-offline", 9508 "cache-plugin" 9509 ] 9510 }, 9511 "cache-base": { 9512 "requires": [ 9513 "base" 9514 ] 9515 }, 9516 "cache-offline": { 9517 "requires": [ 9518 "cache-base", 9519 "json" 9520 ] 9521 }, 9522 "cache-plugin": { 9523 "requires": [ 9524 "plugin", 9525 "cache-base" 9526 ] 9527 }, 9528 "calendar": { 9529 "requires": [ 9530 "calendar-base", 9531 "calendarnavigator" 9532 ], 9533 "skinnable": true 9534 }, 9535 "calendar-base": { 9536 "lang": [ 9537 "ca", 9538 "ca-ES", 9539 "de", 9540 "en", 9541 "es", 9542 "es-AR", 9543 "eu-ES", 9544 "fr", 9545 "hu", 9546 "it", 9547 "ja", 9548 "nb-NO", 9549 "nl", 9550 "pt-BR", 9551 "ru", 9552 "zh-Hans", 9553 "zh-Hans-CN", 9554 "zh-Hant", 9555 "zh-Hant-HK", 9556 "zh-HANT-TW" 9557 ], 9558 "requires": [ 9559 "widget", 9560 "datatype-date", 9561 "datatype-date-math", 9562 "cssgrids" 9563 ], 9564 "skinnable": true 9565 }, 9566 "calendarnavigator": { 9567 "lang": [ 9568 "en", 9569 "es", 9570 "es-AR", 9571 "eu-ES" 9572 ], 9573 "requires": [ 9574 "plugin", 9575 "classnamemanager", 9576 "datatype-date", 9577 "node" 9578 ], 9579 "skinnable": true 9580 }, 9581 "charts": { 9582 "use": [ 9583 "charts-base" 9584 ] 9585 }, 9586 "charts-base": { 9587 "requires": [ 9588 "dom", 9589 "event-mouseenter", 9590 "event-touch", 9591 "graphics-group", 9592 "axes", 9593 "series-pie", 9594 "series-line", 9595 "series-marker", 9596 "series-area", 9597 "series-spline", 9598 "series-column", 9599 "series-bar", 9600 "series-areaspline", 9601 "series-combo", 9602 "series-combospline", 9603 "series-line-stacked", 9604 "series-marker-stacked", 9605 "series-area-stacked", 9606 "series-spline-stacked", 9607 "series-column-stacked", 9608 "series-bar-stacked", 9609 "series-areaspline-stacked", 9610 "series-combo-stacked", 9611 "series-combospline-stacked" 9612 ] 9613 }, 9614 "charts-legend": { 9615 "requires": [ 9616 "charts-base" 9617 ] 9618 }, 9619 "classnamemanager": { 9620 "requires": [ 9621 "yui-base" 9622 ] 9623 }, 9624 "clickable-rail": { 9625 "requires": [ 9626 "slider-base" 9627 ] 9628 }, 9629 "collection": { 9630 "use": [ 9631 "array-extras", 9632 "arraylist", 9633 "arraylist-add", 9634 "arraylist-filter", 9635 "array-invoke" 9636 ] 9637 }, 9638 "color": { 9639 "use": [ 9640 "color-base", 9641 "color-hsl", 9642 "color-harmony" 9643 ] 9644 }, 9645 "color-base": { 9646 "requires": [ 9647 "yui-base" 9648 ] 9649 }, 9650 "color-harmony": { 9651 "requires": [ 9652 "color-hsl" 9653 ] 9654 }, 9655 "color-hsl": { 9656 "requires": [ 9657 "color-base" 9658 ] 9659 }, 9660 "color-hsv": { 9661 "requires": [ 9662 "color-base" 9663 ] 9664 }, 9665 "console": { 9666 "lang": [ 9667 "en", 9668 "es", 9669 "hu", 9670 "it", 9671 "ja" 9672 ], 9673 "requires": [ 9674 "yui-log", 9675 "widget" 9676 ], 9677 "skinnable": true 9678 }, 9679 "console-filters": { 9680 "requires": [ 9681 "plugin", 9682 "console" 9683 ], 9684 "skinnable": true 9685 }, 9686 "content-editable": { 9687 "requires": [ 9688 "node-base", 9689 "editor-selection", 9690 "stylesheet", 9691 "plugin" 9692 ] 9693 }, 9694 "controller": { 9695 "use": [ 9696 "router" 9697 ] 9698 }, 9699 "cookie": { 9700 "requires": [ 9701 "yui-base" 9702 ] 9703 }, 9704 "createlink-base": { 9705 "requires": [ 9706 "editor-base" 9707 ] 9708 }, 9709 "cssbase": { 9710 "after": [ 9711 "cssreset", 9712 "cssfonts", 9713 "cssgrids", 9714 "cssreset-context", 9715 "cssfonts-context", 9716 "cssgrids-context" 9717 ], 9718 "type": "css" 9719 }, 9720 "cssbase-context": { 9721 "after": [ 9722 "cssreset", 9723 "cssfonts", 9724 "cssgrids", 9725 "cssreset-context", 9726 "cssfonts-context", 9727 "cssgrids-context" 9728 ], 9729 "type": "css" 9730 }, 9731 "cssbutton": { 9732 "type": "css" 9733 }, 9734 "cssfonts": { 9735 "type": "css" 9736 }, 9737 "cssfonts-context": { 9738 "type": "css" 9739 }, 9740 "cssgrids": { 9741 "optional": [ 9742 "cssnormalize" 9743 ], 9744 "type": "css" 9745 }, 9746 "cssgrids-base": { 9747 "optional": [ 9748 "cssnormalize" 9749 ], 9750 "type": "css" 9751 }, 9752 "cssgrids-responsive": { 9753 "optional": [ 9754 "cssnormalize" 9755 ], 9756 "requires": [ 9757 "cssgrids", 9758 "cssgrids-responsive-base" 9759 ], 9760 "type": "css" 9761 }, 9762 "cssgrids-units": { 9763 "optional": [ 9764 "cssnormalize" 9765 ], 9766 "requires": [ 9767 "cssgrids-base" 9768 ], 9769 "type": "css" 9770 }, 9771 "cssnormalize": { 9772 "type": "css" 9773 }, 9774 "cssnormalize-context": { 9775 "type": "css" 9776 }, 9777 "cssreset": { 9778 "type": "css" 9779 }, 9780 "cssreset-context": { 9781 "type": "css" 9782 }, 9783 "dataschema": { 9784 "use": [ 9785 "dataschema-base", 9786 "dataschema-json", 9787 "dataschema-xml", 9788 "dataschema-array", 9789 "dataschema-text" 9790 ] 9791 }, 9792 "dataschema-array": { 9793 "requires": [ 9794 "dataschema-base" 9795 ] 9796 }, 9797 "dataschema-base": { 9798 "requires": [ 9799 "base" 9800 ] 9801 }, 9802 "dataschema-json": { 9803 "requires": [ 9804 "dataschema-base", 9805 "json" 9806 ] 9807 }, 9808 "dataschema-text": { 9809 "requires": [ 9810 "dataschema-base" 9811 ] 9812 }, 9813 "dataschema-xml": { 9814 "requires": [ 9815 "dataschema-base" 9816 ] 9817 }, 9818 "datasource": { 9819 "use": [ 9820 "datasource-local", 9821 "datasource-io", 9822 "datasource-get", 9823 "datasource-function", 9824 "datasource-cache", 9825 "datasource-jsonschema", 9826 "datasource-xmlschema", 9827 "datasource-arrayschema", 9828 "datasource-textschema", 9829 "datasource-polling" 9830 ] 9831 }, 9832 "datasource-arrayschema": { 9833 "requires": [ 9834 "datasource-local", 9835 "plugin", 9836 "dataschema-array" 9837 ] 9838 }, 9839 "datasource-cache": { 9840 "requires": [ 9841 "datasource-local", 9842 "plugin", 9843 "cache-base" 9844 ] 9845 }, 9846 "datasource-function": { 9847 "requires": [ 9848 "datasource-local" 9849 ] 9850 }, 9851 "datasource-get": { 9852 "requires": [ 9853 "datasource-local", 9854 "get" 9855 ] 9856 }, 9857 "datasource-io": { 9858 "requires": [ 9859 "datasource-local", 9860 "io-base" 9861 ] 9862 }, 9863 "datasource-jsonschema": { 9864 "requires": [ 9865 "datasource-local", 9866 "plugin", 9867 "dataschema-json" 9868 ] 9869 }, 9870 "datasource-local": { 9871 "requires": [ 9872 "base" 9873 ] 9874 }, 9875 "datasource-polling": { 9876 "requires": [ 9877 "datasource-local" 9878 ] 9879 }, 9880 "datasource-textschema": { 9881 "requires": [ 9882 "datasource-local", 9883 "plugin", 9884 "dataschema-text" 9885 ] 9886 }, 9887 "datasource-xmlschema": { 9888 "requires": [ 9889 "datasource-local", 9890 "plugin", 9891 "datatype-xml", 9892 "dataschema-xml" 9893 ] 9894 }, 9895 "datatable": { 9896 "use": [ 9897 "datatable-core", 9898 "datatable-table", 9899 "datatable-head", 9900 "datatable-body", 9901 "datatable-base", 9902 "datatable-column-widths", 9903 "datatable-message", 9904 "datatable-mutable", 9905 "datatable-sort", 9906 "datatable-datasource" 9907 ] 9908 }, 9909 "datatable-base": { 9910 "requires": [ 9911 "datatable-core", 9912 "datatable-table", 9913 "datatable-head", 9914 "datatable-body", 9915 "base-build", 9916 "widget" 9917 ], 9918 "skinnable": true 9919 }, 9920 "datatable-body": { 9921 "requires": [ 9922 "datatable-core", 9923 "view", 9924 "classnamemanager" 9925 ] 9926 }, 9927 "datatable-column-widths": { 9928 "requires": [ 9929 "datatable-base" 9930 ] 9931 }, 9932 "datatable-core": { 9933 "requires": [ 9934 "escape", 9935 "model-list", 9936 "node-event-delegate" 9937 ] 9938 }, 9939 "datatable-datasource": { 9940 "requires": [ 9941 "datatable-base", 9942 "plugin", 9943 "datasource-local" 9944 ] 9945 }, 9946 "datatable-foot": { 9947 "requires": [ 9948 "datatable-core", 9949 "vi
9949ew" 9950 ] 9951 }, 9952 "datatable-formatters": { 9953 "requires": [ 9954 "datatable-body", 9955 "datatype-number-format", 9956 "datatype-date-format", 9957 "escape" 9958 ] 9959 }, 9960 "datatable-head": { 9961 "requires": [ 9962 "datatable-core", 9963 "view", 9964 "classnamemanager" 9965 ] 9966 }, 9967 "datatable-highlight": { 9968 "requires": [ 9969 "datatable-base", 9970 "event-hover" 9971 ], 9972 "skinnable": true 9973 }, 9974 "datatable-keynav": { 9975 "requires": [ 9976 "datatable-base" 9977 ] 9978 }, 9979 "datatable-message": { 9980 "lang": [ 9981 "en", 9982 "fr", 9983 "es", 9984 "hu", 9985 "it" 9986 ], 9987 "requires": [ 9988 "datatable-base" 9989 ], 9990 "skinnable": true 9991 }, 9992 "datatable-mutable": { 9993 "requires": [ 9994 "datatable-base" 9995 ] 9996 }, 9997 "datatable-paginator": { 9998 "lang": [ 9999 "en", 10000 "fr" 10001 ], 10002 "requires": [ 10003 "model", 10004 "view", 10005 "paginator-core", 10006 "datatable-foot", 10007 "datatable-paginator-templates" 10008 ], 10009 "skinnable": true 10010 }, 10011 "datatable-paginator-templates": { 10012 "requires": [ 10013 "template" 10014 ] 10015 }, 10016 "datatable-scroll": { 10017 "requires": [ 10018 "datatable-base", 10019 "datatable-column-widths", 10020 "dom-screen" 10021 ], 10022 "skinnable": true 10023 }, 10024 "datatable-sort": { 10025 "lang": [ 10026 "en", 10027 "fr", 10028 "es", 10029 "hu" 10030 ], 10031 "requires": [ 10032 "datatable-base" 10033 ], 10034 "skinnable": true 10035 }, 10036 "datatable-table": { 10037 "requires": [ 10038 "datatable-core", 10039 "datatable-head", 10040 "datatable-body", 10041 "view", 10042 "classnamemanager" 10043 ] 10044 }, 10045 "datatype": { 10046 "use": [ 10047 "datatype-date", 10048 "datatype-number", 10049 "datatype-xml" 10050 ] 10051 }, 10052 "datatype-date": { 10053 "use": [ 10054 "datatype-date-parse", 10055 "datatype-date-format", 10056 "datatype-date-math" 10057 ] 10058 }, 10059 "datatype-date-format": { 10060 "lang": [ 10061 "ar", 10062 "ar-JO", 10063 "ca", 10064 "ca-ES", 10065 "da", 10066 "da-DK", 10067 "de", 10068 "de-AT", 10069 "de-DE", 10070 "el", 10071 "el-GR", 10072 "en", 10073 "en-AU", 10074 "en-CA", 10075 "en-GB", 10076 "en-IE", 10077 "en-IN", 10078 "en-JO", 10079 "en-MY", 10080 "en-NZ", 10081 "en-PH", 10082 "en-SG", 10083 "en-US", 10084 "es", 10085 "es-AR", 10086 "es-BO", 10087 "es-CL", 10088 "es-CO", 10089 "es-EC", 10090 "es-ES", 10091 "es-MX", 10092 "es-PE", 10093 "es-PY", 10094 "es-US", 10095 "es-UY", 10096 "es-VE", 10097 "fi", 10098 "fi-FI", 10099 "fr", 10100 "fr-BE", 10101 "fr-CA", 10102 "fr-FR", 10103 "hi", 10104 "hi-IN", 10105 "hu", 10106 "id", 10107 "id-ID", 10108 "it", 10109 "it-IT", 10110 "ja", 10111 "ja-JP", 10112 "ko", 10113 "ko-KR", 10114 "ms", 10115 "ms-MY", 10116 "nb", 10117 "nb-NO", 10118 "nl", 10119 "nl-BE", 10120 "nl-NL", 10121 "pl", 10122 "pl-PL", 10123 "pt", 10124 "pt-BR", 10125 "ro", 10126 "ro-RO", 10127 "ru", 10128 "ru-RU", 10129 "sv", 10130 "sv-SE", 10131 "th", 10132 "th-TH", 10133 "tr", 10134 "tr-TR", 10135 "vi", 10136 "vi-VN", 10137 "zh-Hans", 10138 "zh-Hans-CN", 10139 "zh-Hant", 10140 "zh-Hant-HK", 10141 "zh-Hant-TW" 10142 ] 10143 }, 10144 "datatype-date-math": { 10145 "requires": [ 10146 "yui-base" 10147 ] 10148 }, 10149 "datatype-date-parse": {}, 10150 "datatype-number": { 10151 "use": [ 10152 "datatype-number-parse", 10153 "datatype-number-format" 10154 ] 10155 }, 10156 "datatype-number-format": {}, 10157 "datatype-number-parse": { 10158 "requires": [ 10159 "escape" 10160 ] 10161 }, 10162 "datatype-xml": { 10163 "use": [ 10164 "datatype-xml-parse", 10165 "datatype-xml-format" 10166 ] 10167 }, 10168 "datatype-xml-format": {}, 10169 "datatype-xml-parse": {}, 10170 "dd": { 10171 "use": [ 10172 "dd-ddm-base", 10173 "dd-ddm", 10174 "dd-ddm-drop", 10175 "dd-drag", 10176 "dd-proxy", 10177 "dd-constrain", 10178 "dd-drop", 10179 "dd-scroll", 10180 "dd-delegate" 10181 ] 10182 }, 10183 "dd-constrain": { 10184 "requires": [ 10185 "dd-drag" 10186 ] 10187 }, 10188 "dd-ddm": { 10189 "requires": [ 10190 "dd-ddm-base", 10191 "event-resize" 10192 ] 10193 }, 10194 "dd-ddm-base": { 10195 "requires": [ 10196 "node", 10197 "base", 10198 "yui-throttle", 10199 "classnamemanager" 10200 ] 10201 }, 10202 "dd-ddm-drop": { 10203 "requires": [ 10204 "dd-ddm" 10205 ] 10206 }, 10207 "dd-delegate": { 10208 "requires": [ 10209 "dd-drag", 10210 "dd-drop-plugin", 10211 "event-mouseenter" 10212 ] 10213 }, 10214 "dd-drag": { 10215 "requires": [ 10216 "dd-ddm-base", 10217 "selector-css2" 10218 ] 10219 }, 10220 "dd-drop": { 10221 "requires": [ 10222 "dd-drag", 10223 "dd-ddm-drop" 10224 ] 10225 }, 10226 "dd-drop-plugin": { 10227 "requires": [ 10228 "dd-drop" 10229 ] 10230 }, 10231 "dd-gestures": { 10232 "condition": { 10233 "name": "dd-gestures", 10234 "trigger": "dd-drag", 10235 "ua": "touchEnabled" 10236 }, 10237 "requires": [ 10238 "dd-drag", 10239 "event-synthetic", 10240 "event-gestures" 10241 ] 10242 }, 10243 "dd-plugin": { 10244 "optional": [ 10245 "dd-constrain", 10246 "dd-proxy" 10247 ], 10248 "requires": [ 10249 "dd-drag" 10250 ] 10251 }, 10252 "dd-proxy": { 10253 "requires": [ 10254 "dd-drag" 10255 ] 10256 }, 10257 "dd-scroll": { 10258 "requires": [ 10259 "dd-drag" 10260 ] 10261 }, 10262 "dial": { 10263 "lang": [ 10264 "en", 10265 "es", 10266 "hu" 10267 ], 10268 "requires": [ 10269 "widget", 10270 "dd-drag", 10271 "event-mouseenter", 10272 "event-move", 10273 "event-key", 10274 "transition", 10275 "intl" 10276 ], 10277 "skinnable": true 10278 }, 10279 "dom": { 10280 "use": [ 10281 "dom-base", 10282 "dom-screen", 10283 "dom-style", 10284 "selector-native", 10285 "selector" 10286 ] 10287 },
10288 "dom-base": { 10289 "requires": [ 10290 "dom-core" 10291 ] 10292 }, 10293 "dom-core": { 10294 "requires": [ 10295 "oop", 10296 "features" 10297 ] 10298 }, 10299 "dom-screen": { 10300 "requires": [ 10301 "dom-base", 10302 "dom-style" 10303 ] 10304 }, 10305 "dom-style": { 10306 "requires": [ 10307 "dom-base" 10308 ] 10309 }, 10310 "dom-style-ie": { 10311 "condition": { 10312 "name": "dom-style-ie", 10313 "test": function (Y) { 10314 10315 var testFeature = Y.Features.test, 10316 addFeature = Y.Features.add, 10317 WINDOW = Y.config.win, 10318 DOCUMENT = Y.config.doc, 10319 DOCUMENT_ELEMENT = 'documentElement', 10320 ret = false; 10321 10322 addFeature('style', 'computedStyle', { 10323 test: function() { 10324 return WINDOW && 'getComputedStyle' in WINDOW; 10325 } 10326 }); 10327 10328 addFeature('style', 'opacity', { 10329 test: function() { 10330 return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style; 10331 } 10332 }); 10333 10334 ret = (!testFeature('style', 'opacity') && 10335 !testFeature('style', 'computedStyle')); 10336 10337 return ret; 10338}, 10339 "trigger": "dom-style" 10340 }, 10341 "requires": [ 10342 "dom-style", 10343 "color-base" 10344 ] 10345 }, 10346 "dump": { 10347 "requires": [ 10348 "yui-base" 10349 ] 10350 }, 10351 "editor": { 10352 "use": [ 10353 "frame", 10354 "editor-selection", 10355 "exec-command", 10356 "editor-base", 10357 "editor-para", 10358 "editor-br", 10359 "editor-bidi", 10360 "editor-tab", 10361 "createlink-base" 10362 ] 10363 }, 10364 "editor-base": { 10365 "requires": [ 10366 "base", 10367 "frame", 10368 "node", 10369 "exec-command", 10370 "editor-selection" 10371 ] 10372 }, 10373 "editor-bidi": { 10374 "requires": [ 10375 "editor-base" 10376 ] 10377 }, 10378 "editor-br": { 10379 "requires": [ 10380 "editor-base" 10381 ] 10382 }, 10383 "editor-inline": { 10384 "requires": [ 10385 "editor-base", 10386 "content-editable" 10387 ] 10388 }, 10389 "editor-lists": { 10390 "requires": [ 10391 "editor-base" 10392 ] 10393 }, 10394 "editor-para": { 10395 "requires": [ 10396 "editor-para-base" 10397 ] 10398 }, 10399 "editor-para-base": { 10400 "requires": [ 10401 "editor-base" 10402 ] 10403 }, 10404 "editor-para-ie": { 10405 "condition": { 10406 "name": "editor-para-ie", 10407 "trigger": "editor-para", 10408 "ua": "ie", 10409 "when": "instead" 10410 }, 10411 "requires": [ 10412 "editor-para-base" 10413 ] 10414 }, 10415 "editor-selection": { 10416 "requires": [ 10417 "node" 10418 ] 10419 }, 10420 "editor-tab": { 10421 "requires": [ 10422 "editor-base" 10423 ] 10424 }, 10425 "escape": { 10426 "requires": [ 10427 "yui-base" 10428 ] 10429 }, 10430 "event": { 10431 "after": [ 10432 "node-base" 10433 ], 10434 "use": [ 10435 "event-base", 10436 "event-delegate", 10437 "event-synthetic", 10438 "event-mousewheel", 10439 "event-mouseenter", 10440 "event-key", 10441 "event-focus", 10442 "event-resize", 10443 "event-hover", 10444 "event-outside", 10445 "event-touch", 10446 "event-move", 10447 "event-flick", 10448 "event-valuechange", 10449 "event-tap" 10450 ] 10451 }, 10452 "event-base": { 10453 "after": [ 10454 "node-base" 10455 ], 10456 "requires": [ 10457 "event-custom-base" 10458 ] 10459 }, 10460 "event-base-ie": { 10461 "after": [ 10462 "event-base" 10463 ], 10464 "condition": { 10465 "name": "event-base-ie", 10466 "test": function(Y) { 10467 var imp = Y.config.doc && Y.config.doc.implementation; 10468 return (imp && (!imp.hasFeature('Events', '2.0'))); 10469}, 10470 "trigger": "node-base" 10471 }, 10472 "requires": [ 10473 "node-base" 10474 ] 10475 }, 10476 "event-contextmenu": { 10477 "requires": [ 10478 "event-synthetic", 10479 "dom-screen" 10480 ] 10481 }, 10482 "event-custom": { 10483 "use": [ 10484 "event-custom-base", 10485 "event-custom-complex" 10486 ] 10487 }, 10488 "event-custom-base": { 10489 "requires": [ 10490 "oop" 10491 ] 10492 }, 10493 "event-custom-complex": { 10494 "requires": [ 10495 "event-custom-base" 10496 ] 10497 }, 10498 "event-delegate": { 10499 "requires": [ 10500 "node-base" 10501 ] 10502 }, 10503 "event-flick": { 10504 "requires": [ 10505 "node-base", 10506 "event-touch", 10507 "event-synthetic" 10508 ] 10509 }, 10510 "event-focus": { 10511 "requires": [ 10512 "event-synthetic" 10513 ] 10514 }, 10515 "event-gestures": { 10516 "use": [ 10517 "event-flick", 10518 "event-move" 10519 ] 10520 }, 10521 "event-hover": { 10522 "requires": [ 10523 "event-mouseenter" 10524 ] 10525 }, 10526 "event-key": { 10527 "requires": [ 10528 "event-synthetic" 10529 ] 10530 }, 10531 "event-mouseenter": { 10532 "requires": [ 10533 "event-synthetic" 10534 ] 10535 }, 10536 "event-mousewheel": { 10537 "requires": [ 10538 "node-base" 10539 ] 10540 }, 10541 "event-move": { 10542 "requires": [ 10543 "node-base", 10544 "event-touch", 10545 "event-synthetic" 10546 ] 10547 }, 10548 "event-outside": { 10549 "requires": [ 10550 "event-synthetic" 10551 ] 10552 }, 10553 "event-resize": { 10554 "requires": [ 10555 "node-base", 10556 "event-synthetic" 10557 ] 10558 }, 10559 "event-simulate": { 10560 "requires": [ 10561 "event-base" 10562 ] 10563 }, 10564 "event-synthetic": { 10565 "requires": [ 10566 "node-base", 10567 "event-custom-complex" 10568 ] 10569 }, 10570 "event-tap": { 10571 "requires": [ 10572 "node-base", 10573 "event-base", 10574 "event-touch", 10575 "event-synthetic" 10576 ] 10577 }, 10578 "event-touch": { 10579 "requires": [ 10580 "node-base" 10581 ] 10582 }, 10583 "event-valuechange": { 10584 "requires": [ 10585 "event-focus", 10586 "event-synthetic" 10587 ] 10588 }, 10589 "exec-command": { 10590 "requires": [ 10591 "frame" 10592 ] 10593 }, 10594 "features": { 10595 "requires": [ 10596 "yui-base" 10597 ] 10598 }, 10599 "file": { 10600 "requires": [ 10601 "file-flash", 10602 "file-html5" 10603 ] 10604 }, 10605 "file-flash": { 10606 "requires": [ 10607 "base" 10608 ] 10609 }, 10610 "file-html5": { 10611 "requires": [ 10612 "base" 10613 ] 10614 }, 10615 "frame": { 10616 "requires": [ 10617 "base", 10618 "node", 10619 "plugin", 10620 "selector-css3", 10621 "yui-throttle" 10622 ] 10623 }, 10624 "gesture-simulate": { 10625 "requires": [ 10626 "async-queue", 10627 "event-simulate", 10628 "node-screen" 10629 ] 10630 }, 10631 "get": { 10632 "requires": [ 10633 "yui-base" 10634 ] 10635 }, 10636 "graphics": { 10637 "requires": [ 10638 "node", 10639 "event-custom", 10640 "pluginhost", 10641 "matrix", 10642 "classnamemanager" 10643 ] 10644 }, 10645 "graphics-canvas": { 10646 "condition": { 10647 "name": "graphics-canvas", 10648 "test": function(Y) { 10649 var DOCUMENT = Y.config.doc, 10650 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10651 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10652 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10653 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 10654}, 10655 "trigger": "graphics" 10656 }, 10657 "requires": [ 10658 "graphics", 10659 "color-base" 10660 ] 10661 }, 10662 "graphics-canvas-default": { 10663 "condition": { 10664 "name": "graphics-canvas-default", 10665 "test": function(Y) { 10666 var DOCUMENT = Y.config.doc, 10667 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", 10668 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10669 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10670 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 10671}, 10672 "trigger": "graphics" 10673 } 10674 }, 10675 "graphics-group": { 10676 "requires": [ 10677 "graphics" 10678 ] 10679 }, 10680 "graphics-svg": { 10681 "condition": { 10682 "name": "graphics-svg", 10683 "test": function(Y) { 10684 var DOCUMENT = Y.config.doc, 10685 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 10686 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10687 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10688 10689 return svg && (useSVG || !canvas); 10690}, 10691 "trigger": "graphics" 10692 }, 10693 "requires": [ 10694 "graphics" 10695 ] 10696 }, 10697 "graphics-svg-default": { 10698 "condition": { 10699 "name": "graphics-svg-default", 10700 "test": function(Y) { 10701 var DOCUMENT = Y.config.doc, 10702 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 10703 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10704 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10705 10706 return svg && (useSVG || !canvas); 10707}, 10708 "trigger": "graphics" 10709 } 10710 }, 10711 "graphics-vml": { 10712 "condition": { 10713 "name": "graphics-vml", 10714 "test": function(Y) { 10715 var DOCUMENT = Y.config.doc, 10716 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 10717 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 10718}, 10719 "trigger": "graphics" 10720 }, 10721 "requires": [ 10722 "graphics", 10723 "color-base" 10724 ] 10725 }, 10726 "graphics-vml-default": { 10727 "condition": { 10728 "name": "graphics-vml-default", 10729 "test": function(Y) { 10730 var DOCUMENT = Y.config.doc, 10731 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 10732 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 10733}, 10734 "trigger": "graphics" 10735 } 10736 }, 10737 "handlebars": { 10738 "use": [ 10739 "handlebars-compiler" 10740 ] 10741 }, 10742 "handlebars-base": { 10743 "requires": [] 10744 }, 10745 "handlebars-compiler": { 10746 "requires": [ 10747 "handlebars-base" 10748 ] 10749 }, 10750 "highlight": { 10751 "use": [ 10752 "highlight-base", 10753 "highlight-accentfold" 10754 ] 10755 }, 10756 "highlight-accentfold": { 10757 "requires": [ 10758 "highlight-base", 10759 "text-accentfold" 10760 ] 10761 }, 10762 "highlight-base": { 10763 "requires": [ 10764 "array-extras", 10765 "classnamemanager", 10766 "escape", 10767 "text-wordbreak" 10768 ] 10769 }, 10770 "history": { 10771 "use": [ 10772 "history-base", 10773 "history-hash", 10774 "history-html5" 10775 ] 10776 }, 10777 "history-base": { 10778 "requires": [ 10779 "event-custom-complex" 10780 ] 10781 }, 10782 "history-hash": { 10783 "after": [ 10784 "history-html5" 10785 ], 10786 "requires": [ 10787 "event-synthetic", 10788 "history-base", 10789 "yui-later" 10790 ] 10791 }, 10792 "history-hash-ie": { 10793 "condition": { 10794 "name": "history-hash-ie", 10795 "test": function (Y) { 10796 var docMode = Y.config.doc && Y.config.doc.documentMode; 10797 10798 return Y.UA.ie && (!('onhashchange' in Y.config.win) || 10799 !docMode || docMode < 8); 10800}, 10801 "trigger": "history-hash" 10802 }, 10803 "requires": [ 10804 "history-hash", 10805 "node-base" 10806 ] 10807 }, 10808 "history-html5": { 10809 "optional": [ 10810 "json" 10811 ], 10812 "requires": [ 10813 "event-base", 10814 "history-base", 10815 "node-base" 10816 ] 10817 }, 10818 "imageloader": { 10819 "requires": [ 10820 "base-base", 10821 "node-style", 10822 "node-screen" 10823 ] 10824 }, 10825 "intl": { 10826 "requires": [ 10827 "intl-base", 10828 "event-custom" 10829 ] 10830 }, 10831 "intl-base": { 10832 "requires": [ 10833 "yui-base" 10834 ] 10835 }, 10836 "io": { 10837 "use": [ 10838 "io-base", 10839 "io-xdr", 10840 "io-form", 10841 "io-upload-iframe", 10842 "io-queue" 10843 ] 10844 }, 10845 "io-base": { 10846 "requires": [ 10847 "event-custom-base", 10848 "querystring-stringify-simple" 10849 ] 10850 }, 10851 "io-form": { 10852 "requires": [ 10853 "io-base", 10854 "node-base" 10855 ] 10856 }, 10857 "io-nodejs": { 10858 "condition": { 10859 "name": "io-nodejs", 10860 "trigger": "io-base", 10861 "ua": "nodejs" 10862 }, 10863 "requires": [ 10864 "io-base" 10865 ] 10866 }, 10867 "io-queue": { 10868 "requires": [ 10869 "io-base", 10870 "queue-promote" 10871 ] 10872 }, 10873 "io-upload-iframe": { 10874 "requires": [ 10875 "io-base", 10876 "node-base" 10877 ] 10878 }, 10879 "io-xdr": { 10880 "requires": [ 10881 "io-base", 10882 "datatype-xml-parse" 10883 ] 10884 }, 10885 "json": { 10886 "use": [ 10887 "json-parse", 10888 "json-stringify" 10889 ] 10890 }, 10891 "json-parse": { 10892 "requires": [ 10893 "yui-base" 10894 ] 10895 }, 10896 "json-parse-shim": { 10897 "condition": { 10898 "name": "json-parse-shim", 10899 "test": function (Y) { 10900 var _JSON = Y.config.global.JSON, 10901 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 10902 nativeSupport = Y.config.useNativeJSONParse !== false && !!Native; 10903 10904 function workingNative( k, v ) { 10905 return k === "ok" ? true : v; 10906 } 10907 10908 // Double check basic functionality. This is mainly to catch early broken 10909 // implementations of the JSON API in Firefox 3.1 beta1 and beta2
10910 if ( nativeSupport ) { 10911 try { 10912 nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok; 10913 } 10914 catch ( e ) { 10915 nativeSupport = false; 10916 } 10917 } 10918 10919 return !nativeSupport; 10920}, 10921 "trigger": "json-parse" 10922 }, 10923 "requires": [ 10924 "json-parse" 10925 ] 10926 }, 10927 "json-stringify": { 10928 "requires": [ 10929 "yui-base" 10930 ] 10931 }, 10932 "json-stringify-shim": { 10933 "condition": { 10934 "name": "json-stringify-shim", 10935 "test": function (Y) { 10936 var _JSON = Y.config.global.JSON, 10937 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 10938 nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native; 10939 10940 // Double check basic native functionality. This is primarily to catch broken 10941 // early JSON API implementations in Firefox 3.1 beta1 and beta2. 10942 if ( nativeSupport ) { 10943 try { 10944 nativeSupport = ( '0' === Native.stringify(0) ); 10945 } catch ( e ) { 10946 nativeSupport = false; 10947 } 10948 } 10949 10950 10951 return !nativeSupport; 10952}, 10953 "trigger": "json-stringify" 10954 }, 10955 "requires": [ 10956 "json-stringify" 10957 ] 10958 }, 10959 "jsonp": { 10960 "requires": [ 10961 "get", 10962 "oop" 10963 ] 10964 }, 10965 "jsonp-url": { 10966 "requires": [ 10967 "jsonp" 10968 ] 10969 }, 10970 "lazy-model-list": { 10971 "requires": [ 10972 "model-list" 10973 ] 10974 }, 10975 "loader": { 10976 "use": [ 10977 "loader-base", 10978 "loader-rollup", 10979 "loader-yui3" 10980 ] 10981 }, 10982 "loader-base": { 10983 "requires": [ 10984 "get", 10985 "features" 10986 ] 10987 }, 10988 "loader-pathogen-combohandler": {}, 10989 "loader-pathogen-encoder": { 10990 "use": [ 10991 "loader-base", 10992 "loader-rollup", 10993 "loader-yui3", 10994 "loader-pathogen-combohandler" 10995 ] 10996 }, 10997 "loader-rollup": { 10998 "requires": [ 10999 "loader-base" 11000 ] 11001 }, 11002 "loader-yui3": { 11003 "requires": [ 11004 "loader-base" 11005 ] 11006 }, 11007 "matrix": { 11008 "requires": [ 11009 "yui-base" 11010 ] 11011 }, 11012 "model": { 11013 "requires": [ 11014 "base-build", 11015 "escape", 11016 "json-parse" 11017 ] 11018 }, 11019 "model-list": { 11020 "requires": [ 11021 "array-extras", 11022 "array-invoke", 11023 "arraylist", 11024 "base-build", 11025 "escape", 11026 "json-parse", 11027 "model" 11028 ] 11029 }, 11030 "model-sync-local": { 11031 "requires": [ 11032 "model", 11033 "json-stringify" 11034 ] 11035 }, 11036 "model-sync-rest": { 11037 "requires": [ 11038 "model", 11039 "io-base", 11040 "json-stringify" 11041 ] 11042 }, 11043 "node": { 11044 "use": [ 11045 "node-base", 11046 "node-event-delegate", 11047 "node-pluginhost", 11048 "node-screen", 11049 "node-style" 11050 ] 11051 }, 11052 "node-base": { 11053 "requires": [ 11054 "event-base", 11055 "node-core", 11056 "dom-base", 11057 "dom-style" 11058 ] 11059 }, 11060 "node-core": { 11061 "requires": [ 11062 "dom-core", 11063 "selector" 11064 ] 11065 }, 11066 "node-event-delegate": { 11067 "requires": [ 11068 "node-base", 11069 "event-delegate" 11070 ] 11071 }, 11072 "node-event-html5": { 11073 "requires": [ 11074 "node-base" 11075 ] 11076 }, 11077 "node-event-simulate": { 11078 "requires": [ 11079 "node-base", 11080 "event-simulate", 11081 "gesture-simulate" 11082 ] 11083 }, 11084 "node-flick": { 11085 "requires": [ 11086 "classnamemanager", 11087 "transition", 11088 "event-flick", 11089 "plugin" 11090 ], 11091 "skinnable": true 11092 }, 11093 "node-focusmanager": { 11094 "requires": [ 11095 "attribute", 11096 "node", 11097 "plugin", 11098 "node-event-simulate", 11099 "event-key", 11100 "event-focus" 11101 ] 11102 }, 11103 "node-load": { 11104 "requires": [ 11105 "node-base", 11106 "io-base" 11107 ] 11108 }, 11109 "node-menunav": { 11110 "requires": [ 11111 "node", 11112 "classnamemanager", 11113 "plugin", 11114 "node-focusmanager" 11115 ], 11116 "skinnable": true 11117 }, 11118 "node-pluginhost": { 11119 "requires": [ 11120 "node-base", 11121 "pluginhost" 11122 ] 11123 }, 11124 "node-screen": { 11125 "requires": [ 11126 "dom-screen", 11127 "node-base" 11128 ] 11129 }, 11130 "node-scroll-info": { 11131 "requires": [ 11132 "array-extras", 11133 "base-build", 11134 "event-resize", 11135 "node-pluginhost", 11136 "plugin", 11137 "selector" 11138 ] 11139 }, 11140 "node-style": { 11141 "requires": [ 11142 "dom-style", 11143 "node-base" 11144 ] 11145 }, 11146 "oop": { 11147 "requires": [ 11148 "yui-base" 11149 ] 11150 }, 11151 "overlay": { 11152 "requires": [ 11153 "widget", 11154 "widget-stdmod", 11155 "widget-position", 11156 "widget-position-align", 11157 "widget-stack", 11158 "widget-position-constrain" 11159 ], 11160 "skinnable": true 11161 }, 11162 "paginator": { 11163 "requires": [ 11164 "paginator-core" 11165 ] 11166 }, 11167 "paginator-core": { 11168 "requires": [ 11169 "base" 11170 ] 11171 }, 11172 "paginator-url": { 11173 "requires": [ 11174 "paginator" 11175 ] 11176 }, 11177 "panel": { 11178 "requires": [ 11179 "widget", 11180 "widget-autohide", 11181 "widget-buttons", 11182 "widget-modality", 11183 "widget-position", 11184 "widget-position-align", 11185 "widget-position-constrain", 11186 "widget-stack", 11187 "widget-stdmod" 11188 ], 11189 "skinnable": true 11190 }, 11191 "parallel": { 11192 "requires": [ 11193 "yui-base" 11194 ] 11195 }, 11196 "pjax": { 11197 "requires": [ 11198 "pjax-base", 11199 "pjax-content" 11200 ] 11201 }, 11202 "pjax-base": { 11203 "requires": [ 11204 "classnamemanager", 11205 "node-event-delegate", 11206 "router" 11207 ] 11208 }, 11209 "pjax-content": { 11210 "requires": [ 11211 "io-base", 11212 "node-base", 11213 "router" 11214 ] 11215 }, 11216 "pjax-plugin": { 11217 "requires": [ 11218 "node-pluginhost", 11219 "pjax", 11220 "plugin" 11221 ] 11222 }, 11223 "plugin": { 11224 "requires": [ 11225 "base-base" 11226 ] 11227 }, 11228 "pluginhost": { 11229 "use": [ 11230 "pluginhost-base", 11231 "pluginhost-config" 11232 ] 11233 }, 11234 "pluginhost-base": { 11235 "requires": [ 11236 "yui-base" 11237 ] 11238 }, 11239 "pluginhost-config": { 11240 "requires": [ 11241 "pluginhost-base" 11242 ] 11243 }, 11244 "promise": { 11245 "requires": [ 11246 "timers" 11247 ] 11248 }, 11249 "querystring": { 11250 "use": [ 11251 "querystring-parse", 11252 "querystring-stringify" 11253 ] 11254 }, 11255 "querystring-parse": { 11256 "requires": [ 11257 "yui-base", 11258 "array-extras" 11259 ] 11260 }, 11261 "querystring-parse-simple": { 11262 "requires": [ 11263 "yui-base" 11264 ] 11265 }, 11266 "querystring-stringify": { 11267 "requires": [ 11268 "yui-base" 11269 ] 11270 }, 11271 "querystring-stringify-simple": { 11272 "requires": [ 11273 "yui-base" 11274 ] 11275 }, 11276 "queue-promote": { 11277 "requires": [ 11278 "yui-base" 11279 ] 11280 }, 11281 "range-slider": { 11282 "requires": [ 11283 "slider-base", 11284 "slider-value-range", 11285 "clickable-rail" 11286 ] 11287 }, 11288 "recordset": { 11289 "use": [ 11290 "recordset-base", 11291 "recordset-sort", 11292 "recordset-filter", 11293 "recordset-indexer" 11294 ] 11295 }, 11296 "recordset-base": { 11297 "requires": [ 11298 "base", 11299 "arraylist" 11300 ] 11301 }, 11302 "recordset-filter": { 11303 "requires": [ 11304 "recordset-base", 11305 "array-extras", 11306 "plugin" 11307 ] 11308 }, 11309 "recordset-indexer": { 11310 "requires": [ 11311 "recordset-base", 11312 "plugin" 11313 ] 11314 }, 11315 "recordset-sort": { 11316 "requires": [ 11317 "arraysort", 11318 "recordset-base", 11319 "plugin" 11320 ] 11321 }, 11322 "resize": { 11323 "use": [ 11324 "resize-base", 11325 "resize-proxy", 11326 "resize-constrain" 11327 ] 11328 }, 11329 "resize-base": { 11330 "requires": [ 11331 "base", 11332 "widget", 11333 "event", 11334 "oop", 11335 "dd-drag", 11336 "dd-delegate", 11337 "dd-drop" 11338 ], 11339 "skinnable": true 11340 }, 11341 "resize-constrain": { 11342 "requires": [ 11343 "plugin", 11344 "resize-base" 11345 ] 11346 }, 11347 "resize-plugin": { 11348 "optional": [ 11349 "resize-constrain" 11350 ], 11351 "requires": [ 11352 "resize-base", 11353 "plugin" 11354 ] 11355 }, 11356 "resize-proxy": { 11357 "requires": [ 11358 "plugin", 11359 "resize-base" 11360 ] 11361 }, 11362 "router": { 11363 "optional": [ 11364 "querystring-parse" 11365 ], 11366 "requires": [ 11367 "array-extras", 11368 "base-build", 11369 "history" 11370 ] 11371 }, 11372 "scrollview": { 11373 "requires": [ 11374 "scrollview-base", 11375 "scrollview-scrollbars" 11376 ] 11377 }, 11378 "scrollview-base": { 11379 "requires": [ 11380 "widget", 11381 "event-gestures", 11382 "event-mousewheel", 11383 "transition" 11384 ], 11385 "skinnable": true 11386 }, 11387 "scrollview-base-ie": { 11388 "condition": { 11389 "name": "scrollview-base-ie", 11390 "trigger": "scrollview-base", 11391 "ua": "ie" 11392 }, 11393 "requires": [ 11394 "scrollview-base" 11395 ] 11396 }, 11397 "scrollview-list": { 11398 "requires": [ 11399 "plugin", 11400 "classnamemanager" 11401 ], 11402 "skinnable": true 11403 }, 11404 "scrollview-paginator": { 11405 "requires": [ 11406 "plugin", 11407 "classnamemanager" 11408 ] 11409 }, 11410 "scrollview-scrollbars": { 11411 "requires": [ 11412 "classnamemanager", 11413 "transition", 11414 "plugin" 11415 ], 11416 "skinnable": true 11417 }, 11418 "selector": { 11419 "requires": [ 11420 "selector-native" 11421 ] 11422 }, 11423 "selector-css2": { 11424 "condition": { 11425 "name": "selector-css2", 11426 "test": function (Y) { 11427 var DOCUMENT = Y.config.doc, 11428 ret = DOCUMENT && !('querySelectorAll' in DOCUMENT); 11429 11430 return ret; 11431}, 11432 "trigger": "selector" 11433 }, 11434 "requires": [ 11435 "selector-native" 11436 ] 11437 }, 11438 "selector-css3": { 11439 "requires": [ 11440 "selector-native", 11441 "selector-css2" 11442 ] 11443 }, 11444 "selector-native": { 11445 "requires": [ 11446 "dom-base" 11447 ] 11448 }, 11449 "series-area": { 11450 "requires": [ 11451 "series-cartesian", 11452 "series-fill-util" 11453 ] 11454 }, 11455 "series-area-stacked": { 11456 "requires": [ 11457 "series-stacked", 11458 "series-area" 11459 ] 11460 }, 11461 "series-areaspline": { 11462 "requires": [ 11463 "series-area", 11464 "series-curve-util" 11465 ] 11466 }, 11467 "series-areaspline-stacked": { 11468 "requires": [ 11469 "series-stacked", 11470 "series-areaspline" 11471 ] 11472 }, 11473 "series-bar": { 11474 "requires": [ 11475 "series-marker", 11476 "series-histogram-base" 11477 ] 11478 }, 11479 "series-bar-stacked": { 11480 "requires": [ 11481 "series-stacked", 11482 "series-bar" 11483 ] 11484 }, 11485 "series-base": { 11486 "requires": [ 11487 "graphics", 11488 "axis-base" 11489 ] 11490 }, 11491 "series-candlestick": { 11492 "requires": [ 11493 "series-range" 11494 ] 11495 }, 11496 "series-cartesian": { 11497 "requires": [ 11498 "series-base" 11499 ] 11500 }, 11501 "series-column": { 11502 "requires": [ 11503 "series-marker", 11504 "series-histogram-base" 11505 ] 11506 }, 11507 "series-column-stacked": { 11508 "requires": [ 11509 "series-stacked", 11510 "series-column" 11511 ] 11512 }, 11513 "series-combo": { 11514 "requires": [ 11515 "series-cartesian", 11516 "series-line-util", 11517 "series-plot-util", 11518 "series-fill-util" 11519 ] 11520 }, 11521 "series-combo-stacked": { 11522 "requires": [ 11523 "series-stacked", 11524 "series-combo" 11525 ] 11526 }, 11527 "series-combospline": { 11528 "requires": [ 11529 "series-combo", 11530 "series-curve-util" 11531 ] 11532 }, 11533 "series-combospline-stacked": { 11534 "requires": [ 11535 "series-combo-stacked", 11536 "series-curve-util" 11537 ] 11538 }, 11539 "series-curve-util": {}, 11540 "series-fill-util": {}, 11541 "series-histogram-base": { 11542 "requires": [ 11543 "series-cartesian", 11544 "series-plot-util" 11545 ] 11546 }, 11547 "series-line": { 11548 "requires": [ 11549 "series-cartesian", 11550 "series-line-util" 11551 ] 11552 }, 11553 "series-line-stacked": { 11554 "requires": [ 11555 "series-stacked", 11556 "series-line" 11557 ] 11558 }, 11559 "series-line-util": {}, 11560 "series-marker": { 11561 "requires": [ 11562 "series-cartesian", 11563 "series-plot-util" 11564 ] 11565 }, 11566 "series-marker-stacked": { 11567 "requires": [ 11568 "series-stacked", 11569 "series-marker" 11570 ] 11571 }, 11572 "series-ohlc": { 11573 "requires": [ 11574 "series-range" 11575 ] 11576 }, 11577 "series-pie": { 11578 "requires": [ 11579 "series-base", 11580 "series-plot-util" 11581 ] 11582 }, 11583 "series-plot-util": {}, 11584 "series-range": { 11585 "requires": [ 11586 "series-cartesian" 11587 ] 11588 }, 11589 "series-spline": { 11590 "requires": [ 11591 "series-line", 11592 "series-curve-util" 11593 ] 11594 }, 11595 "series-spline-stacked": { 11596 "requires": [ 11597 "series-stacked", 11598 "series-spline" 11599 ] 11600 }, 11601 "series-stacked": { 11602 "requires": [ 11603 "axis-stacked" 11604 ] 11605 }, 11606 "shim-plugin": { 11607 "requires": [ 11608 "node-style", 11609 "node-pluginhost" 11610 ] 11611 }, 11612 "slider": { 11613 "use": [ 11614 "slider-base", 11615 "slider-value-range", 11616 "clickable-rail", 11617 "range-slider" 11618 ] 11619 }, 11620 "slider-base": { 11621 "requires": [ 11622 "widget", 11623 "dd-constrain", 11624 "event-key" 11625 ], 11626 "skinnable": true 11627 }, 11628 "slider-value-range": { 11629 "requires": [ 11630 "slider-base" 11631 ] 11632 }, 11633 "sortable": { 11634 "requires": [ 11635 "dd-delegate", 11636 "dd-drop-plugin", 11637 "dd-proxy" 11638 ] 11639 }, 11640 "sortable-scroll": { 11641 "requires": [ 11642 "dd-scroll", 11643 "sortable" 11644 ] 11645 }, 11646 "stylesheet": { 11647 "requires": [ 11648 "yui-base" 11649 ] 11650 }, 11651 "substitute": { 11652 "optional": [ 11653 "dump" 11654 ], 11655 "requires": [ 11656 "yui-base" 11657 ] 11658 }, 11659 "swf": { 11660 "requires": [ 11661 "event-custom", 11662 "node", 11663 "swfdetect", 11664 "escape" 11665 ] 11666 }, 11667 "swfdetect": { 11668 "requires": [ 11669 "yui-base" 11670 ] 11671 }, 11672 "tabview": { 11673 "requires": [ 11674 "widget", 11675 "widget-parent", 11676 "widget-child", 11677 "tabview-base", 11678 "node-pluginhost", 11679 "node-focusmanager" 11680 ], 11681 "skinnable": true 11682 }, 11683 "tabview-base": { 11684 "requires": [ 11685 "node-event-delegate", 11686 "classnamemanager" 11687 ] 11688 }, 11689 "tabview-plugin": { 11690 "requires": [ 11691 "tabview-base" 11692 ] 11693 }, 11694 "template": { 11695 "use": [ 11696 "template-base", 11697 "template-micro" 11698 ] 11699 }, 11700 "template-base": { 11701 "requires": [ 11702 "yui-base" 11703 ] 11704 }, 11705 "template-micro": { 11706 "requires": [ 11707 "escape" 11708 ] 11709 }, 11710 "test": { 11711 "requires": [ 11712 "event-simulate", 11713 "event-custom", 11714 "json-stringify" 11715 ] 11716 }, 11717
11717 "test-console": { 11718 "requires": [ 11719 "console-filters", 11720 "test", 11721 "array-extras" 11722 ], 11723 "skinnable": true 11724 }, 11725 "text": { 11726 "use": [ 11727 "text-accentfold", 11728 "text-wordbreak" 11729 ] 11730 }, 11731 "text-accentfold": { 11732 "requires": [ 11733 "array-extras", 11734 "text-data-accentfold" 11735 ] 11736 }, 11737 "text-data-accentfold": { 11738 "requires": [ 11739 "yui-base" 11740 ] 11741 }, 11742 "text-data-wordbreak": { 11743 "requires": [ 11744 "yui-base" 11745 ] 11746 }, 11747 "text-wordbreak": { 11748 "requires": [ 11749 "array-extras", 11750 "text-data-wordbreak" 11751 ] 11752 }, 11753 "timers": { 11754 "requires": [ 11755 "yui-base" 11756 ] 11757 }, 11758 "transition": { 11759 "requires": [ 11760 "node-style" 11761 ] 11762 }, 11763 "transition-timer": { 11764 "condition": { 11765 "name": "transition-timer", 11766 "test": function (Y) { 11767 var DOCUMENT = Y.config.doc, 11768 node = (DOCUMENT) ? DOCUMENT.documentElement: null, 11769 ret = true; 11770 11771 if (node && node.style) { 11772 ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 11773 } 11774 11775 return ret; 11776}, 11777 "trigger": "transition" 11778 }, 11779 "requires": [ 11780 "transition" 11781 ] 11782 }, 11783 "tree": { 11784 "requires": [ 11785 "base-build", 11786 "tree-node" 11787 ] 11788 }, 11789 "tree-labelable": { 11790 "requires": [ 11791 "tree" 11792 ] 11793 }, 11794 "tree-lazy": { 11795 "requires": [ 11796 "base-pluginhost", 11797 "plugin", 11798 "tree" 11799 ] 11800 }, 11801 "tree-node": {}, 11802 "tree-openable": { 11803 "requires": [ 11804 "tree" 11805 ] 11806 }, 11807 "tree-selectable": { 11808 "requires": [ 11809 "tree" 11810 ] 11811 }, 11812 "tree-sortable": { 11813 "requires": [ 11814 "tree" 11815 ] 11816 }, 11817 "uploader": { 11818 "requires": [ 11819 "uploader-html5", 11820 "uploader-flash" 11821 ] 11822 }, 11823 "uploader-flash": { 11824 "requires": [ 11825 "swfdetect", 11826 "escape", 11827 "widget", 11828 "base", 11829 "cssbutton", 11830 "node", 11831 "event-custom", 11832 "uploader-queue" 11833 ] 11834 }, 11835 "uploader-html5": { 11836 "requires": [ 11837 "widget", 11838 "node-event-simulate", 11839 "file-html5", 11840 "uploader-queue" 11841 ] 11842 }, 11843 "uploader-queue": { 11844 "requires": [ 11845 "base" 11846 ] 11847 }, 11848 "view": { 11849 "requires": [ 11850 "base-build", 11851 "node-event-delegate" 11852 ] 11853 }, 11854 "view-node-map": { 11855 "requires": [ 11856 "view" 11857 ] 11858 }, 11859 "widget": { 11860 "use": [ 11861 "widget-base", 11862 "widget-htmlparser", 11863 "widget-skin", 11864 "widget-uievents" 11865 ] 11866 }, 11867 "widget-anim": { 11868 "requires": [ 11869 "anim-base", 11870 "plugin", 11871 "widget" 11872 ] 11873 }, 11874 "widget-autohide": { 11875 "requires": [ 11876 "base-build", 11877 "event-key", 11878 "event-outside", 11879 "widget" 11880 ] 11881 }, 11882 "widget-base": { 11883 "requires": [ 11884 "attribute", 11885 "base-base", 11886 "base-pluginhost", 11887 "classnamemanager", 11888 "event-focus", 11889 "node-base", 11890 "node-style" 11891 ], 11892 "skinnable": true 11893 }, 11894 "widget-base-ie": { 11895 "condition": { 11896 "name": "widget-base-ie", 11897 "trigger": "widget-base", 11898 "ua": "ie" 11899 }, 11900 "requires": [ 11901 "widget-base" 11902 ] 11903 }, 11904 "widget-buttons": { 11905 "requires": [ 11906 "button-plugin", 11907 "cssbutton", 11908 "widget-stdmod" 11909 ] 11910 }, 11911 "widget-child": { 11912 "requires": [ 11913 "base-build", 11914 "widget" 11915 ] 11916 }, 11917 "widget-htmlparser": { 11918 "requires": [ 11919 "widget-base" 11920 ] 11921 }, 11922 "widget-modality": { 11923 "requires": [ 11924 "base-build", 11925 "event-outside", 11926 "widget" 11927 ], 11928 "skinnable": true 11929 }, 11930 "widget-parent": { 11931 "requires": [ 11932 "arraylist", 11933 "base-build", 11934 "widget" 11935 ] 11936 }, 11937 "widget-position": { 11938 "requires": [ 11939 "base-build", 11940 "node-screen", 11941 "widget" 11942 ] 11943 }, 11944 "widget-position-align": { 11945 "requires": [ 11946 "widget-position" 11947 ] 11948 }, 11949 "widget-position-constrain": { 11950 "requires": [ 11951 "widget-position" 11952 ] 11953 }, 11954 "widget-skin": { 11955 "requires": [ 11956 "widget-base" 11957 ] 11958 }, 11959 "widget-stack": { 11960 "requires": [ 11961 "base-build", 11962 "widget" 11963 ], 11964 "skinnable": true 11965 }, 11966 "widget-stdmod": { 11967 "requires": [ 11968 "base-build", 11969 "widget" 11970 ] 11971 }, 11972 "widget-uievents": { 11973 "requires": [ 11974 "node-event-delegate", 11975 "widget-base" 11976 ] 11977 }, 11978 "yql": { 11979 "requires": [ 11980 "oop" 11981 ] 11982 }, 11983 "yql-jsonp": { 11984 "condition": { 11985 "name": "yql-jsonp", 11986 "test": function (Y) { 11987 /* Only load the JSONP module when not in nodejs or winjs 11988 TODO Make the winjs module a CORS module 11989 */ 11990 return (!Y.UA.nodejs && !Y.UA.winjs); 11991}, 11992 "trigger": "yql" 11993 }, 11994 "requires": [ 11995 "yql", 11996 "jsonp", 11997 "jsonp-url" 11998 ] 11999 }, 12000 "yql-nodejs": { 12001 "condition": { 12002 "name": "yql-nodejs", 12003 "trigger": "yql", 12004 "ua": "nodejs" 12005 }, 12006 "requires": [ 12007 "yql" 12008 ] 12009 }, 12010 "yql-winjs": { 12011 "condition": { 12012 "name": "yql-winjs", 12013 "trigger": "yql", 12014 "ua": "winjs" 12015 }, 12016 "requires": [ 12017 "yql" 12018 ] 12019 }, 12020 "yui": {}, 12021 "yui-base": {}, 12022 "yui-later": { 12023 "requires": [ 12024 "yui-base" 12025 ] 12026 }, 12027 "yui-log": { 12028 "requires": [ 12029 "yui-base" 12030 ] 12031 }, 12032 "yui-throttle": { 12033 "requires": [ 12034 "yui-base" 12035 ] 12036 } 12037}); 12038YUI.Env[Y.version].md5 = '95eb05a1b097773b5af03e0680e7dda4'; 12039 12040 12041}, 'patched-v3.18.1', {"requires": ["loader-base"]}); 12042YUI.add('yui', function (Y, NAME) {}, 'patched-v3.18.1', { 12043 "use": [ 12044 "yui-base", 12045 "get", 12046 "features", 12047 "intl-base", 12048 "yui-log", 12049 "yui-later", 12050 "loader-base", 12051 "loader-rollup", 12052 "loader-yui3" 12053 ] 12054}); 12055YUI.add('aui-base-core', function (A, NAME) { 12056 12057var Y = A; 12058YUI.Env.aliases = YUI.Env.aliases || {}; 12059Y.mix(YUI.Env.aliases, { 12060 "aui-autosize": ["aui-autosize-iframe"], 12061 "aui-base": ["oop","yui-throttle","aui-classnamemanager","aui-debounce","aui-base-core","aui-base-lang","aui-node-base"], 12062 "aui-base-deprecated": ["aui-base","aui-node","aui-component","aui-delayed-task-deprecated","aui-selector","aui-event-base"], 12063 "aui-button": ["aui-button-core"], 12064 "aui-collection": ["aui-map","aui-set","aui-linkedset"], 12065 "aui-color-picker-deprecated": ["aui-color-picker-base-deprecated","aui-color-picker-grid-plugin-deprecated"], 12066 "aui-datasource-control-deprecated": ["aui-datasource-control-base-deprecated","aui-input-text-control-deprecated"], 12067 "aui-datatable": ["aui-datatable-edit","aui-datatable-highlight","aui-datatable-selection","aui-datatable-property-list"], 12068 "aui-datatable-edit": ["datatable-base","calendar","overlay","sortable","aui-datatype","aui-toolbar","aui-form-validator","aui-datatable-base-cell-editor","aui-datatable-base-options-cell-editor","aui-datatable-cell-editor-support","aui-datatable-core","aui-datatable-checkbox-cell-editor","aui-datatable-date-cell-editor","aui-datatable-dropdown-cell-editor","aui-datatable-radio-cell-editor","aui-datatable-text-cell-editor","aui-datatable-text-area-cell-editor"], 12069 "aui-datepicker-deprecated": ["aui-datepicker-base-deprecated","aui-datepicker-select-deprecated"], 12070 "aui-event": ["aui-event-base"], 12071 "aui-form-deprecated": ["aui-form-base-deprecated","aui-form-combobox-deprecated","aui-form-field-deprecated","aui-form-select-deprecated","aui-form-textarea-deprecated","aui-form-textfield-deprecated"], 12072 "aui-io": ["aui-io-request"], 12073 "aui-io-deprecated": ["aui-io-request","aui-io-plugin-deprecated"], 12074 "aui-node": ["aui-node-base"], 12075 "aui-overlay-deprecated": ["aui-overlay-base-deprecated","aui-overlay-context-deprecated","aui-overlay-context-panel-deprecated","aui-overlay-manager-deprecated","aui-overlay-mask-deprecated"], 12076 "aui-rating": ["aui-rating-base","aui-rating-thumb"], 12077 "aui-resize-deprecated": ["aui-resize-base-deprecated","aui-resize-constrain-deprecated"], 12078 "aui-scheduler": ["event-gestures","aui-scheduler-base","aui-scheduler-event-recorder","aui-scheduler-view-agenda","aui-scheduler-view-day","aui-scheduler-view-month","aui-scheduler-view-table-dd","aui-scheduler-view-table","aui-scheduler-view-week","aui-viewport"], 12079 "aui-search": ["aui-search-tst"], 12080 "aui-sortable": ["aui-sortable-layout","aui-sortable-list"], 12081 "aui-surface": ["aui-surface-app","aui-surface-screen"], 12082 "aui-toggler": ["aui-toggler-base","aui-toggler-delegate"], 12083 "aui-tooltip": ["aui-tooltip-base","aui-tooltip-delegate"], 12084 "aui-tpl-snippets-deprecated": ["aui-tpl-snippets-base-deprecated","aui-tpl-snippets-checkbox-deprecated","aui-tpl-snippets-input-deprecated","aui-tpl-snippets-select-deprecated","aui-tpl-snippets-textarea-deprecated"], 12085 "aui-tree": ["aui-tree-data","aui-tree-io","aui-tree-node","aui-tree-paginator","aui-tree-view"], 12086 "aui-widget": ["aui-widget-cssclass","aui-widget-toolbars"], 12087 "aui-widget-core": ["aui-widget-cssclass"] 12088}); 12089/* This file is auto-generated by (yogi loader --yes --mix --js js/aui-loader.js --json js/aui-loader.json --start ../) */ 12090 12091/*jshint maxlen:900, eqeqeq: false */ 12092 12093/** 12094 * YUI 3 module metadata 12095 * @module loader 12096 * @submodule loader-yui3 12097 */ 12098YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {}; 12099Y.mix(YUI.Env[Y.version].modules, { 12100 "aui-ace-autocomplete-base": { 12101 "requires": [ 12102 "aui-ace-editor" 12103 ] 12104 }, 12105 "aui-ace-autocomplete-freemarker": { 12106 "requires": [ 12107 "aui-ace-autocomplete-templateprocessor" 12108 ] 12109 }, 12110 "aui-ace-autocomplete-list": { 12111 "requires": [ 12112 "aui-ace-autocomplete-base", 12113 "overlay", 12114 "widget-autohide" 12115 ], 12116 "skinnable": true 12117 }, 12118 "aui-ace-autocomplete-plugin": { 12119 "requires": [ 12120 "aui-ace-autocomplete-list", 12121 "plugin" 12122 ] 12123 }, 12124 "aui-ace-autocomplete-templateprocessor": { 12125 "requires": [ 12126 "aui-ace-autocomplete-base" 12127 ] 12128 }, 12129 "aui-ace-autocomplete-velocity": { 12130 "requires": [ 12131 "aui-ace-autocomplete-templateprocessor" 12132 ] 12133 }, 12134 "aui-ace-editor": { 12135 "requires": [ 12136 "aui-node", 12137 "aui-component" 12138 ] 12139 }, 12140 "aui-affix": { 12141 "requires": [ 12142 "base", 12143 "node-screen", 12144 "aui-node" 12145 ] 12146 }, 12147 "aui-alert": { 12148 "requires": [ 12149 "aui-aria", 12150 "aui-classnamemanager", 12151 "aui-widget-cssclass", 12152 "aui-widget-transition", 12153 "timers", 12154 "widget", 12155 "widget-stdmod" 12156 ], 12157 "skinnable": true 12158 }, 12159 "aui-aria": { 12160 "requires": [ 12161 "plugin", 12162 "aui-component" 12163 ] 12164 }, 12165 "aui-aria-table-sortable": { 12166 "requires": [ 12167 "aui-aria" 12168 ] 12169 }, 12170 "aui-arraysort": { 12171 "requires": [ 12172 "arraysort" 12173 ] 12174 }, 12175 "aui-audio": { 12176 "requires": [ 12177 "aui-aria", 12178 "aui-node", 12179 "aui-component", 12180 "node-event-html5", 12181 "querystring-stringify-simple" 12182 ], 12183 "skinnable": true 12184 }, 12185 "aui-autocomplete-deprecated": { 12186 "requires": [ 12187 "aui-base-deprecated", 12188 "aui-overlay-base-deprecated", 12189 "datasource", 12190 "dataschema", 12191 "aui-form-combobox-deprecated" 12192 ], 12193 "skinnable": true 12194 }, 12195 "aui-autosize": { 12196 "use": [ 12197 "aui-autosize-iframe" 12198 ] 12199 }, 12200 "aui-autosize-deprecated": { 12201 "requires": [ 12202 "event-valuechange", 12203 "plugin", 12204 "aui-base-deprecated" 12205 ], 12206 "skinnable": true 12207 }, 12208 "aui-autosize-iframe": { 12209 "requires": [ 12210 "plugin", 12211 "aui-component", 12212 "aui-timer", 12213 "aui-node-base" 12214 ] 12215 }, 12216 "aui-base": { 12217 "use": [ 12218 "oop", 12219 "yui-throttle", 12220 "aui-classnamemanager", 12221 "aui-debounce", 12222 "aui-base-core", 12223 "aui-base-lang", 12224 "aui-node-base" 12225 ] 12226 }, 12227 "aui-base-core": {}, 12228 "aui-base-deprecated": { 12229 "use": [ 12230 "aui-base", 12231 "aui-node", 12232 "aui-component", 12233 "aui-delayed-task-deprecated", 12234 "aui-selector", 12235 "aui-event-base" 12236 ] 12237 }, 12238 "aui-base-html5-shiv": { 12239 "condition": { 12240 "name": "aui-base-html5-shiv", 12241 "trigger": "node-base", 12242 "ua": "ie" 12243 } 12244 }, 12245 "aui-base-lang": {}, 12246 "aui-boolean-data-editor": { 12247 "requires": [ 12248 "aui-button-switch", 12249 "aui-data-editor" 12250 ] 12251 }, 12252 "aui-button": { 12253 "use": [ 12254 "aui-button-core" 12255 ] 12256 }, 12257 "aui-button-core": { 12258 "requires": [ 12259 "button", 12260 "button-group", 12261 "button-plugin", 12262 "aui-component", 12263 "aui-widget-cssclass", 12264 "aui-widget-toggle" 12265 ], 12266 "skinnable": true 12267 }, 12268 "aui-button-item-deprecated": { 12269 "requires": [ 12270 "aui-base-deprecated", 12271 "aui-state-interaction-deprecated", 12272 "widget-child" 12273 ], 12274 "skinnable": true 12275 }, 12276 "aui-button-search-cancel": { 12277 "requires": [ 12278 "array-invoke", 12279 "base", 12280 "base-build", 12281 "event-focus", 12282 "event-move", 12283 "event-resize", 12284 "node-screen", 12285 "node-event-delegate", 12286 "aui-node-base", 12287 "aui-classnamemanager", 12288 "aui-event-input" 12289 ] 12290 }, 12291 "aui-button-switch": { 12292 "requires": [ 12293 "aui-node-base", 12294 "base-build", 12295 "event-key", 12296 "transition", 12297 "widget" 12298 ], 12299 "skinnable": true 12300 }, 12301 "aui-carousel": { 12302 "requires": [ 12303 "anim", 12304 "aui-event", 12305 "aui-image-viewer-base", 12306 "aui-image-viewer-slideshow", 12307 "node-event-delegate", 12308 "node-focusmanager" 12309 ], 12310 "skinnable": true 12311 }, 12312 "aui-carousel-mobile-touch": { 12313 "condition": { 12314 "name": "aui-carousel-mobile-touch", 12315 "test": function(A) { 12316 return A.UA.mobile && A.UA.touchEnabled; 12317}, 12318 "trigger": "aui-carousel" 12319 }, 12320 "requires": [ 12321 "base-build", 12322 "aui-carousel" 12323 ] 12324 }, 12325 "aui-carousel-swipe": { 12326 "condition": { 12327 "name": "aui-carousel-swipe", 12328 "trigger": "aui-carousel", 12329 "ua": "touchEnabled" 12330 }, 12331 "requires": [ 12332 "aui-carousel", 12333 "aui-widget-swipe", 12334 "base-build" 12335 ], 12336 "skinnable": true 12337 },
12338 "aui-char-counter": { 12339 "requires": [ 12340 "aui-aria", 12341 "aui-node", 12342 "aui-event-input", 12343 "aui-component" 12344 ] 12345 }, 12346 "aui-chart-deprecated": { 12347 "requires": [ 12348 "datasource", 12349 "json", 12350 "aui-swf-deprecated" 12351 ] 12352 }, 12353 "aui-classnamemanager": { 12354 "requires": [ 12355 "classnamemanager" 12356 ] 12357 }, 12358 "aui-collection": { 12359 "use": [ 12360 "aui-map", 12361 "aui-set", 12362 "aui-linkedset" 12363 ] 12364 }, 12365 "aui-color-palette": { 12366 "requires": [ 12367 "array-extras", 12368 "aui-palette", 12369 "color-base", 12370 "node-core", 12371 "aui-widget-cssclass", 12372 "aui-widget-toggle" 12373 ], 12374 "skinnable": true 12375 }, 12376 "aui-color-picker-base": { 12377 "requires": [ 12378 "aui-color-palette", 12379 "aui-hsva-palette-modal", 12380 "event-outside" 12381 ], 12382 "skinnable": true 12383 }, 12384 "aui-color-picker-base-deprecated": { 12385 "requires": [ 12386 "dd-drag", 12387 "panel", 12388 "slider", 12389 "aui-button-item-deprecated", 12390 "aui-color-util-deprecated", 12391 "aui-form-base-deprecated", 12392 "aui-overlay-context-deprecated" 12393 ], 12394 "skinnable": true 12395 }, 12396 "aui-color-picker-deprecated": { 12397 "use": [ 12398 "aui-color-picker-base-deprecated", 12399 "aui-color-picker-grid-plugin-deprecated" 12400 ] 12401 }, 12402 "aui-color-picker-grid-plugin-deprecated": { 12403 "requires": [ 12404 "plugin", 12405 "aui-color-picker-base-deprecated" 12406 ], 12407 "skinnable": true 12408 }, 12409 "aui-color-picker-popover": { 12410 "requires": [ 12411 "aui-color-picker-base", 12412 "aui-popover", 12413 "aui-widget-cssclass", 12414 "aui-widget-toggle" 12415 ], 12416 "skinnable": true 12417 }, 12418 "aui-color-util-deprecated": { 12419 "requires": [] 12420 }, 12421 "aui-component": { 12422 "requires": [ 12423 "aui-classnamemanager", 12424 "aui-widget-cssclass", 12425 "aui-widget-toggle", 12426 "base-build", 12427 "widget-base" 12428 ] 12429 }, 12430 "aui-css": { 12431 "type": "css" 12432 }, 12433 "aui-data-editor": { 12434 "requires": [ 12435 "aui-classnamemanager", 12436 "base-build", 12437 "node-base" 12438 ], 12439 "skinnable": true 12440 }, 12441 "aui-data-set-deprecated": { 12442 "requires": [ 12443 "oop", 12444 "collection", 12445 "base" 12446 ] 12447 }, 12448 "aui-datasource-control-base-deprecated": { 12449 "requires": [ 12450 "datasource", 12451 "dataschema", 12452 "aui-base-deprecated" 12453 ] 12454 }, 12455 "aui-datasource-control-deprecated": { 12456 "use": [ 12457 "aui-datasource-control-base-deprecated", 12458 "aui-input-text-control-deprecated" 12459 ] 12460 }, 12461 "aui-datatable": { 12462 "use": [ 12463 "aui-datatable-edit", 12464 "aui-datatable-highlight", 12465 "aui-datatable-selection", 12466 "aui-datatable-property-list" 12467 ] 12468 }, 12469 "aui-datatable-base-cell-editor": { 12470 "requires": [ 12471 "datatable-base", 12472 "overlay" 12473 ], 12474 "skinnable": true 12475 }, 12476 "aui-datatable-base-options-cell-editor": { 12477 "requires": [ 12478 "aui-datatable-base-cell-editor", 12479 "escape" 12480 ], 12481 "skinnable": true 12482 }, 12483 "aui-datatable-body": { 12484 "requires": [ 12485 "aui-classnamemanager", 12486 "datatable-base", 12487 "event-key", 12488 "aui-event-base" 12489 ] 12490 }, 12491 "aui-datatable-cell-editor-support": { 12492 "requires": [ 12493 "datatable-base" 12494 ] 12495 }, 12496 "aui-datatable-checkbox-cell-editor": { 12497 "requires": [ 12498 "aui-datatable-base-options-cell-editor" 12499 ] 12500 }, 12501 "aui-datatable-core": { 12502 "requires": [ 12503 "aui-datatable-body", 12504 "datatable-base", 12505 "event-key", 12506 "aui-event-base" 12507 ], 12508 "skinnable": true 12509 }, 12510 "aui-datatable-date-cell-editor": { 12511 "requires": [ 12512 "aui-datatable-base-options-cell-editor" 12513 ] 12514 }, 12515 "aui-datatable-dropdown-cell-editor": { 12516 "requires": [ 12517 "aui-datatable-base-options-cell-editor" 12518 ] 12519 }, 12520 "aui-datatable-edit": { 12521 "use": [ 12522 "datatable-base", 12523 "calendar", 12524 "overlay", 12525 "sortable", 12526 "aui-datatype", 12527 "aui-toolbar", 12528 "aui-form-validator", 12529 "aui-datatable-base-cell-editor", 12530 "aui-datatable-base-options-cell-editor", 12531 "aui-datatable-cell-editor-support", 12532 "aui-datatable-core", 12533 "aui-datatable-checkbox-cell-editor", 12534 "aui-datatable-date-cell-editor", 12535 "aui-datatable-dropdown-cell-editor", 12536 "aui-datatable-radio-cell-editor", 12537 "aui-datatable-text-cell-editor", 12538 "aui-datatable-text-area-cell-editor" 12539 ] 12540 }, 12541 "aui-datatable-highlight": { 12542 "requires": [ 12543 "aui-datatable-selection" 12544 ], 12545 "skinnable": true 12546 }, 12547 "aui-datatable-property-list": { 12548 "requires": [ 12549 "datatable-scroll", 12550 "datatable-sort", 12551 "aui-datatable-core", 12552 "aui-datatable-edit", 12553 "aui-datatable-highlight", 12554 "aui-datatable-selection", 12555 "aui-widget-cssclass", 12556 "aui-widget-toggle" 12557 ], 12558 "skinnable": true 12559 }, 12560 "aui-datatable-radio-cell-editor": { 12561 "requires": [ 12562 "aui-datatable-base-options-cell-editor" 12563 ] 12564 }, 12565 "aui-datatable-selection": { 12566 "requires": [ 12567 "aui-datatable-core" 12568 ], 12569 "skinnable": true 12570 }, 12571 "aui-datatable-text-area-cell-editor": { 12572 "requires": [ 12573 "aui-datatable-base-options-cell-editor" 12574 ] 12575 }, 12576 "aui-datatable-text-cell-editor": { 12577 "requires": [ 12578 "aui-datatable-base-options-cell-editor" 12579 ] 12580 }, 12581 "aui-datatype": { 12582 "requires": [ 12583 "datatype", 12584 "aui-datatype-date-parse" 12585 ] 12586 }, 12587 "aui-datatype-date-parse": { 12588 "requires": [ 12589 "aui-base-lang", 12590 "datatype-date-format", 12591 "datatype-date-parse", 12592 "intl" 12593 ] 12594 }, 12595 "aui-datepicker": { 12596 "requires": [ 12597 "aui-aria", 12598 "aui-datepicker-delegate", 12599 "aui-datepicker-popover", 12600 "base", 12601 "base-build", 12602 "calendar" 12603 ], 12604 "skinnable": true 12605 }, 12606 "aui-datepicker-base-deprecated": { 12607 "requires": [ 12608 "calendar", 12609 "aui-datatype", 12610 "aui-overlay-context-deprecated" 12611 ], 12612 "skinnable": true 12613 }, 12614 "aui-datepicker-delegate": { 12615 "requires": [ 12616 "aui-datatype-date-parse", 12617 "aui-event-input", 12618 "event-focus", 12619 "node-event-delegate" 12620 ] 12621 }, 12622 "aui-datepicker-deprecated": { 12623 "skinnable": true, 12624 "use": [ 12625 "aui-datepicker-base-deprecated", 12626 "aui-datepicker-select-deprecated" 12627 ] 12628 }, 12629 "aui-datepicker-native": { 12630 "requires": [ 12631 "aui-datepicker-delegate", 12632 "aui-node-base", 12633 "base", 12634 "base-build" 12635 ] 12636 }, 12637 "aui-datepicker-popover": { 12638 "requires": [ 12639 "aui-classnamemanager", 12640 "aui-popover" 12641 ] 12642 }, 12643 "aui-datepicker-select-deprecated": { 12644 "requires": [ 12645 "aui-datepicker-base-deprecated", 12646 "aui-button-item-deprecated" 12647 ], 12648 "skinnable": true 12649 }, 12650 "aui-debounce": {}, 12651 "aui-delayed-task-deprecated": { 12652 "requires": [ 12653 "yui-base" 12654 ] 12655 }, 12656 "aui-diagram-builder": { 12657 "requires": [ 12658 "aui-aria", 12659 "aui-map", 12660 "aui-property-builder",
12661 "aui-diagram-builder-connector", 12662 "aui-property-builder-settings", 12663 "aui-diagram-node-condition", 12664 "aui-diagram-node-end", 12665 "aui-diagram-node-fork", 12666 "aui-diagram-node-join", 12667 "aui-diagram-node-start", 12668 "aui-diagram-node-state", 12669 "aui-diagram-node-task", 12670 "overlay" 12671 ], 12672 "skinnable": true 12673 }, 12674 "aui-diagram-builder-connector": { 12675 "requires": [ 12676 "arraylist-add", 12677 "arraylist-filter", 12678 "escape", 12679 "json", 12680 "graphics", 12681 "dd" 12682 ], 12683 "skinnable": true 12684 }, 12685 "aui-diagram-node": { 12686 "requires": [ 12687 "aui-aria", 12688 "aui-diagram-node-manager-base", 12689 "escape", 12690 "overlay" 12691 ] 12692 }, 12693 "aui-diagram-node-condition": { 12694 "requires": [ 12695 "aui-diagram-node-state" 12696 ] 12697 }, 12698 "aui-diagram-node-end": { 12699 "requires": [ 12700 "aui-diagram-node-state" 12701 ] 12702 }, 12703 "aui-diagram-node-fork": { 12704 "requires": [ 12705 "aui-diagram-node-state" 12706 ] 12707 }, 12708 "aui-diagram-node-join": { 12709 "requires": [ 12710 "aui-diagram-node-state" 12711 ] 12712 }, 12713 "aui-diagram-node-manager-base": { 12714 "requires": [ 12715 "base" 12716 ] 12717 }, 12718 "aui-diagram-node-start": { 12719 "requires": [ 12720 "aui-diagram-node-state" 12721 ] 12722 }, 12723 "aui-diagram-node-state": { 12724 "requires": [ 12725 "aui-diagram-node" 12726 ] 12727 }, 12728 "aui-diagram-node-task": { 12729 "requires": [ 12730 "aui-diagram-node-state" 12731 ] 12732 }, 12733 "aui-dialog-iframe-deprecated": { 12734 "requires": [ 12735 "plugin", 12736 "array-invoke", 12737 "aui-base-deprecated", 12738 "aui-loading-mask-deprecated" 12739 ], 12740 "skinnable": true 12741 }, 12742 "aui-dropdown": { 12743 "requires": [ 12744 "event-delegate", 12745 "event-key", 12746 "event-outside", 12747 "node-focusmanager", 12748 "widget", 12749 "widget-stack", 12750 "aui-classnamemanager", 12751 "aui-node", 12752 "aui-widget-cssclass", 12753 "aui-widget-toggle", 12754 "aui-widget-trigger" 12755 ], 12756 "skinnable": true 12757 }, 12758 "aui-editable-deprecated": { 12759 "requires": [ 12760 "aui-base-deprecated", 12761 "aui-form-combobox-deprecated", 12762 "escape", 12763 "event-resize" 12764 ], 12765 "skinnable": true 12766 }, 12767 "aui-event": { 12768 "use": [ 12769 "aui-event-base" 12770 ] 12771 }, 12772 "aui-event-base": { 12773 "requires": [ 12774 "event-base" 12775 ] 12776 }, 12777 "aui-event-delegate-change": { 12778 "condition": { 12779 "name": "aui-event-delegate-change", 12780 "trigger": "event-base-ie", 12781 "ua": "ie" 12782 }, 12783 "requires": [ 12784 "aui-event-base", 12785 "event-delegate", 12786 "event-synthetic" 12787 ] 12788 }, 12789 "aui-event-delegate-submit": { 12790 "condition": { 12791 "name": "aui-event-delegate-submit", 12792 "trigger": "event-base-ie", 12793 "ua": "ie" 12794 }, 12795 "requires": [ 12796 "aui-event-base", 12797 "event-delegate", 12798 "event-synthetic" 12799 ] 12800 }, 12801 "aui-event-input": { 12802 "condition": { 12803 "name": "aui-event-input", 12804 "test": function(A) { 12805 var supportsDOMEvent = A.supportsDOMEvent, 12806 testFeature = A.Features.test, 12807 addFeature = A.Features.add; 12808 12809 if (testFeature('event', 'input') === undefined) { 12810 addFeature('event', 'input', { 12811 test: function() { 12812 return supportsDOMEvent(document.createElement('textarea'), 'input') && (!A.UA.ie || A.UA.ie > 9); 12813 } 12814 }); 12815 } 12816 12817 return !testFeature('event', 'input'); 12818}, 12819 "trigger": "aui-event-base" 12820 }, 12821 "requires": [ 12822 "aui-event-base", 12823 "event-delegate", 12824 "event-synthetic", 12825 "timers" 12826 ] 12827 }, 12828 "aui-form-base-deprecated": { 12829 "requires": [ 12830 "io-form", 12831 "querystring-parse", 12832 "aui-base-deprecated", 12833 "aui-data-set-deprecated", 12834 "aui-form-field-deprecated" 12835 ] 12836 }, 12837 "aui-form-builder": { 12838 "requires": [ 12839 "aui-modal", 12840 "aui-layout",
12841 "aui-form-builder-field-list", 12842 "aui-form-builder-field-toolbar", 12843 "aui-form-builder-field-type", 12844 "aui-form-builder-field-types", 12845 "aui-form-builder-layout-builder", 12846 "aui-form-builder-page-manager", 12847 "aui-form-builder-settings-modal", 12848 "event-focus", 12849 "event-tap" 12850 ], 12851 "skinnable": true 12852 }, 12853 "aui-form-builder-available-field-deprecated": { 12854 "requires": [ 12855 "aui-property-builder-available-field" 12856 ] 12857 }, 12858 "aui-form-builder-deprecated": { 12859 "requires": [ 12860 "aui-button", 12861 "aui-collection", 12862 "aui-form-builder-available-field-deprecated", 12863 "aui-form-builder-field-deprecated", 12864 "aui-form-builder-field-button-deprecated", 12865 "aui-form-builder-field-checkbox-deprecated", 12866 "aui-form-builder-field-fieldset-deprecated", 12867 "aui-form-builder-field-file-upload-deprecated", 12868 "aui-form-builder-field-multiple-choice-deprecated", 12869 "aui-form-builder-field-radio-deprecated", 12870 "aui-form-builder-field-select-deprecated", 12871 "aui-form-builder-field-text-deprecated", 12872 "aui-form-builder-field-textarea-deprecated", 12873 "aui-property-builder", 12874 "aui-property-builder-settings", 12875 "aui-sortable-list", 12876 "aui-tabview", 12877 "aui-tooltip-base", 12878 "escape", 12879 "transition" 12880 ], 12881 "skinnable": true 12882 }, 12883 "aui-form-builder-field-base": { 12884 "requires": [ 12885 "aui-classnamemanager", 12886 "aui-node-base", 12887 "aui-text-data-editor", 12888 "aui-toggler", 12889 "base", 12890 "node-base" 12891 ], 12892 "skinnable": true 12893 }, 12894 "aui-form-builder-field-button-deprecated": { 12895 "requires": [ 12896 "aui-form-builder-field-deprecated" 12897 ] 12898 }, 12899 "aui-form-builder-field-checkbox-deprecated": { 12900 "requires": [ 12901 "aui-form-builder-field-deprecated" 12902 ] 12903 }, 12904 "aui-form-builder-field-choice": { 12905 "requires": [ 12906 "aui-boolean-data-editor", 12907 "aui-options-data-editor", 12908 "aui-tabs-data-editor", 12909 "aui-form-builder-field-base", 12910 "aui-form-field-choice" 12911 ] 12912 }, 12913 "aui-form-builder-field-deprecated": { 12914 "requires": [ 12915 "panel", 12916 "aui-datatype", 12917 "aui-datatable-edit", 12918 "aui-property-builder-field-support" 12919 ], 12920 "skinnable": true 12921 }, 12922 "aui-form-builder-field-fieldset-deprecated": { 12923 "requires": [ 12924 "aui-form-builder-field-deprecated" 12925 ] 12926 }, 12927 "aui-form-builder-field-file-upload-deprecated": { 12928 "requires": [ 12929 "aui-form-builder-field-deprecated" 12930 ] 12931 }, 12932 "aui-form-builder-field-list": { 12933 "requires": [ 12934 "aui-form-builder-field-type", 12935 "aui-form-builder-field-types", 12936 "aui-form-builder-layout-builder" 12937 ], 12938 "skinnable": true 12939 }, 12940 "aui-form-builder-field-multiple-choice-deprecated": { 12941 "requires": [ 12942 "aui-form-builder-field-deprecated" 12943 ] 12944 }, 12945 "aui-form-builder-field-radio-deprecated": { 12946 "requires": [ 12947 "aui-form-builder-field-deprecated" 12948 ] 12949 }, 12950 "aui-form-builder-field-select-deprecated": { 12951 "requires": [ 12952 "aui-form-builder-field-deprecated" 12953 ] 12954 }, 12955 "aui-form-builder-field-sentence": { 12956 "requires": [ 12957 "aui-form-builder-field-base", 12958 "aui-form-field" 12959 ] 12960 }, 12961 "aui-form-builder-field-text": { 12962 "requires": [ 12963 "aui-boolean-data-editor", 12964 "aui-radio-group-data-editor", 12965 "aui-form-builder-field-base", 12966 "aui-form-field-text" 12967 ] 12968 }, 12969 "aui-form-builder-field-text-deprecated": { 12970 "requires": [ 12971 "aui-form-builder-field-deprecated" 12972 ] 12973 },
12974 "aui-form-builder-field-textarea-deprecated": { 12975 "requires": [ 12976 "aui-form-builder-field-deprecated" 12977 ] 12978 }, 12979 "aui-form-builder-field-toolbar": { 12980 "requires": [ 12981 "aui-classnamemanager", 12982 "base", 12983 "node-base" 12984 ], 12985 "skinnable": true 12986 }, 12987 "aui-form-builder-field-type": { 12988 "requires": [ 12989 "base", 12990 "node-base" 12991 ], 12992 "skinnable": true 12993 }, 12994 "aui-form-builder-field-types": { 12995 "requires": [ 12996 "aui-classnamemanager", 12997 "aui-form-builder-field-types-modal", 12998 "base", 12999 "node-base" 13000 ], 13001 "skinnable": true 13002 }, 13003 "aui-form-builder-field-types-modal": { 13004 "requires": [ 13005 "aui-modal" 13006 ], 13007 "skinnable": true 13008 }, 13009 "aui-form-builder-layout-builder": { 13010 "requires": [ 13011 "aui-classnamemanager", 13012 "aui-layout-builder", 13013 "aui-modal", 13014 "base", 13015 "node-base" 13016 ], 13017 "skinnable": true 13018 }, 13019 "aui-form-builder-page-manager": { 13020 "requires": [ 13021 "aui-pagination", 13022 "aui-popover", 13023 "aui-tabview", 13024 "base", 13025 "event-valuechange", 13026 "node-base" 13027 ], 13028 "skinnable": true 13029 }, 13030 "aui-form-builder-settings-modal": { 13031 "requires": [ 13032 "aui-classnamemanager", 13033 "aui-modal", 13034 "base", 13035 "node-base" 13036 ], 13037 "skinnable": true 13038 }, 13039 "aui-form-combobox-deprecated": { 13040 "requires": [ 13041 "aui-form-textarea-deprecated", 13042 "aui-toolbar" 13043 ], 13044 "skinnable": true 13045 }, 13046 "aui-form-deprecated": { 13047 "use": [ 13048 "aui-form-base-deprecated", 13049 "aui-form-combobox-deprecated", 13050 "aui-form-field-deprecated", 13051 "aui-form-select-deprecated", 13052 "aui-form-textarea-deprecated", 13053 "aui-form-textfield-deprecated" 13054 ] 13055 }, 13056 "aui-form-field": { 13057 "requires": [ 13058 "aui-classnamemanager", 13059 "aui-node-base", 13060 "base-build" 13061 ], 13062 "skinnable": true 13063 }, 13064 "aui-form-field-choice": { 13065 "requires": [ 13066 "aui-form-field-required" 13067 ], 13068 "skinnable": true 13069 }, 13070 "aui-form-field-deprecated": { 13071 "requires": [ 13072 "aui-base-deprecated", 13073 "aui-component" 13074 ] 13075 }, 13076 "aui-form-field-required": { 13077 "requires": [ 13078 "aui-form-field" 13079 ] 13080 }, 13081 "aui-form-field-text": { 13082 "requires": [ 13083 "aui-form-field-required" 13084 ], 13085 "skinnable": true 13086 }, 13087 "aui-form-select-deprecated": { 13088 "requires": [ 13089 "aui-form-field-deprecated" 13090 ] 13091 }, 13092 "aui-form-textarea-deprecated": { 13093 "requires": [ 13094 "node-pluginhost", 13095 "aui-autosize-deprecated", 13096 "aui-form-textfield-deprecated" 13097 ] 13098 }, 13099 "aui-form-textfield-deprecated": { 13100 "requires": [ 13101 "aui-form-field-deprecated" 13102 ] 13103 }, 13104 "aui-form-validator": { 13105 "requires": [ 13106 "escape", 13107 "selector-css3", 13108 "node-event-delegate", 13109 "aui-node", 13110 "aui-component", 13111 "aui-event-input" 13112 ] 13113 }, 13114 "aui-hsv-palette": { 13115 "requires": [ 13116 "aui-classnamemanager", 13117 "aui-widget-cssclass", 13118 "aui-widget-toggle", 13119 "aui-event-input", 13120 "base-build", 13121 "clickable-rail", 13122 "color-hsv", 13123 "dd-constrain", 13124 "slider", 13125 "widget" 13126 ], 13127 "skinnable": true 13128 }, 13129 "aui-hsva-palette": { 13130 "requires": [ 13131 "aui-hsv-palette" 13132 ], 13133 "skinnable": true 13134 }, 13135 "aui-hsva-palette-modal": { 13136 "requires": [ 13137 "aui-hsva-palette", 13138 "aui-modal" 13139 ], 13140 "skinnable": true 13141 }, 13142 "aui-image-cropper": { 13143 "requires": [ 13144 "resize-base", 13145 "resize-constrain", 13146 "dd-constrain", 13147 "aui-node-base", 13148 "aui-component" 13149 ], 13150 "skinnable": true 13151 }, 13152 "aui-image-viewer": { 13153 "requires": [ 13154 "widget", 13155 "widget-modality", 13156 "widget-position", 13157 "widget-position-align", 13158 "widget-position-constrain", 13159 "widget-stack", 13160 "widget-stdmod", 13161 "aui-event", 13162 "aui-image-viewer-base", 13163 "aui-image-viewer-multiple", 13164 "aui-image-viewer-slideshow", 13165 "aui-node-base", 13166 "aui-widget-cssclass", 13167 "aui-widget-toggle" 13168 ], 13169 "skinnable": true 13170 }, 13171 "aui-image-viewer-base": { 13172 "requires": [ 13173 "anim", 13174 "aui-aria", 13175 "aui-classnamemanager", 13176 "aui-node", 13177 "aui-widget-responsive", 13178 "base-build", 13179 "imageloader", 13180 "node-base", 13181 "widget", 13182 "widget-stack" 13183 ], 13184 "skinnable": true 13185 }, 13186 "aui-image-viewer-media": { 13187 "requires": [ 13188 "plugin", 13189 "aui-component", 13190 "aui-image-viewer" 13191 ] 13192 }, 13193 "aui-image-viewer-multiple": { 13194 "requires": [ 13195 "base-build", 13196 "node-base", 13197 "aui-classnamemanager", 13198 "aui-image-viewer-base" 13199 ], 13200 "skinnable": true 13201 }, 13202 "aui-image-viewer-multiple-swipe": { 13203 "condition": { 13204 "name": "aui-image-viewer-multiple-swipe", 13205 "trigger": "aui-image-viewer-multiple", 13206 "ua": "touchEnabled" 13207 }, 13208 "requires": [ 13209 "aui-image-viewer-multiple",
13210 "aui-image-viewer-swipe" 13211 ] 13212 }, 13213 "aui-image-viewer-slideshow": { 13214 "requires": [ 13215 "node", 13216 "aui-classnamemanager" 13217 ] 13218 }, 13219 "aui-image-viewer-swipe": { 13220 "condition": { 13221 "name": "aui-image-viewer-swipe", 13222 "trigger": "aui-image-viewer-base", 13223 "ua": "touchEnabled" 13224 }, 13225 "requires": [ 13226 "event-resize", 13227 "aui-image-viewer-base", 13228 "aui-widget-swipe" 13229 ] 13230 }, 13231 "aui-input-text-control-deprecated": { 13232 "requires": [ 13233 "aui-base-deprecated", 13234 "aui-datasource-control-base-deprecated", 13235 "aui-form-combobox-deprecated" 13236 ] 13237 }, 13238 "aui-io": { 13239 "use": [ 13240 "aui-io-request" 13241 ] 13242 }, 13243 "aui-io-deprecated": { 13244 "use": [ 13245 "aui-io-request", 13246 "aui-io-plugin-deprecated" 13247 ] 13248 }, 13249 "aui-io-plugin-deprecated": { 13250 "requires": [ 13251 "aui-overlay-base-deprecated", 13252 "aui-parse-content", 13253 "aui-io-request", 13254 "aui-loading-mask-deprecated" 13255 ] 13256 }, 13257 "aui-io-request": { 13258 "requires": [ 13259 "io-base", 13260 "json", 13261 "plugin", 13262 "querystring-stringify", 13263 "aui-component" 13264 ] 13265 }, 13266 "aui-io-request-deprecated": { 13267 "requires": [ 13268 "io-base", 13269 "json", 13270 "plugin", 13271 "querystring-stringify", 13272 "aui-base-deprecated" 13273 ] 13274 }, 13275 "aui-layout": { 13276 "requires": [ 13277 "aui-layout-col", 13278 "aui-layout-row", 13279 "aui-node-base", 13280 "base-build", 13281 "datatype-number-parse", 13282 "event-resize" 13283 ] 13284 }, 13285 "aui-layout-builder": { 13286 "requires": [ 13287 "aui-classnamemanager", 13288 "aui-layout", 13289 "aui-layout-builder-add-col", 13290 "aui-layout-builder-add-row", 13291 "aui-layout-builder-move", 13292 "aui-layout-builder-remove-row", 13293 "aui-layout-builder-resize-col", 13294 "aui-node-base", 13295 "base-build", 13296 "node-event-delegate", 13297 "node-screen", 13298 "node-style" 13299 ] 13300 }, 13301 "aui-layout-builder-add-col": { 13302 "requires": [ 13303 "event-key", 13304 "node-base" 13305 ], 13306 "skinnable": true 13307 }, 13308 "aui-layout-builder-add-row": { 13309 "requires": [ 13310 "aui-node-base", 13311 "base-build", 13312 "node-scroll-info" 13313 ], 13314 "skinnable": true 13315 }, 13316 "aui-layout-builder-move": { 13317 "requires": [ 13318 "aui-node-base", 13319 "base-build" 13320 ], 13321 "skinnable": true 13322 }, 13323 "aui-layout-builder-remove-row": { 13324 "requires": [ 13325 "aui-node-base", 13326 "base-build" 13327 ], 13328 "skinnable": true 13329 }, 13330 "aui-layout-builder-resize-col": { 13331 "requires": [ 13332 "dd-constrain", 13333 "dd-delegate", 13334 "dd-drop-plugin", 13335 "dd-proxy", 13336 "event-mouseenter", 13337 "node-base" 13338 ], 13339 "skinnable": true 13340 }, 13341 "aui-layout-col": { 13342 "requires": [ 13343 "aui-classnamemanager", 13344 "aui-node-base", 13345 "base-build" 13346 ], 13347 "skinnable": true 13348 }, 13349 "aui-layout-row": { 13350 "requires": [ 13351 "array-invoke", 13352 "aui-node-base", 13353 "base-build" 13354 ], 13355 "skinnable": true 13356 }, 13357 "aui-linkedset": { 13358 "requires": [ 13359 "aui-set" 13360 ] 13361 }, 13362 "aui-live-search-deprecated": { 13363 "requires": [ 13364 "aui-base-deprecated" 13365 ] 13366 }, 13367 "aui-loading-mask-deprecated": { 13368 "requires": [ 13369 "plugin", 13370 "aui-overlay-mask-deprecated" 13371 ], 13372 "skinnable": true 13373 }, 13374 "aui-map": { 13375 "requires": [ 13376 "base-build" 13377 ] 13378 }, 13379 "aui-menu": { 13380 "requires": [ 13381 "base-build", 13382 "event-mouseenter", 13383 "event-resize", 13384 "widget", 13385 "widget-position", 13386 "widget-position-align", 13387 "widget-position-constrain", 13388 "widget-stack", 13389 "aui-classnamemanager", 13390 "aui-debounce", 13391 "aui-dropdown", 13392 "aui-menu-item" 13393 ], 13394 "skinnable": true 13395 }, 13396 "aui-menu-item": { 13397 "requires": [ 13398 "base-build", 13399 "node-base", 13400 "aui-classnamemanager", 13401 "aui-node", 13402 "aui-widget-shortcut" 13403 ] 13404 }, 13405 "aui-messaging": { 13406 "requires": [ 13407 "querystring", 13408 "aui-timer" 13409 ] 13410 }, 13411 "aui-modal": { 13412 "requires": [ 13413 "widget", 13414 "widget-autohide", 13415 "widget-buttons", 13416 "widget-modality", 13417 "widget-position", 13418 "widget-position-align", 13419 "widget-position-constrain", 13420 "widget-stack", 13421 "widget-stdmod", 13422 "dd-plugin", 13423 "dd-constrain", 13424 "timers", 13425 "aui-classnamemanager", 13426 "aui-widget-cssclass", 13427 "aui-widget-toggle", 13428 "aui-widget-toolbars" 13429 ], 13430 "skinnable": true 13431 }, 13432 "aui-modal-resize": { 13433 "condition": { 13434 "name": "aui-modal-resize", 13435 "test": function(A) { 13436 return !A.UA.mobile; 13437}, 13438 "trigger": "aui-modal" 13439 }, 13440 "requires": [ 13441 "aui-modal", 13442 "resize-plugin" 13443 ] 13444 }, 13445 "aui-node": { 13446 "use": [ 13447 "aui-node-base" 13448 ] 13449 }, 13450 "aui-node-accessible": { 13451 "requires": [ 13452 "aui-node-base", 13453 "event-custom-base" 13454 ] 13455 }, 13456 "aui-node-base": { 13457 "requires": [ 13458 "array-extras", 13459 "aui-base-lang", 13460 "aui-classnamemanager", 13461 "aui-debounce", 13462 "node" 13463 ] 13464 }, 13465 "aui-node-html5": { 13466 "condition": { 13467 "name": "aui-node-html5", 13468 "trigger": "aui-node", 13469 "ua": "ie" 13470 }, 13471 "requires": [ 13472 "collection", 13473 "aui-node-base" 13474 ] 13475 }, 13476 "aui-options-data-editor": { 13477 "requires": [ 13478 "aui-data-editor", 13479 "dd-constrain", 13480 "dd-delegate", 13481 "dd-drop-plugin", 13482 "dd-proxy", 13483 "event-valuechange", 13484 "node-event-delegate" 13485 ], 13486 "skinnable": true 13487 }, 13488 "aui-overlay-base-deprecated": { 13489 "requires": [ 13490 "widget-position", 13491 "widget-stack", 13492 "widget-position-align", 13493 "widget-position-constrain", 13494 "widget-stdmod", 13495 "aui-component" 13496 ] 13497 }, 13498 "aui-overlay-context-deprecated": { 13499 "requires": [ 13500 "aui-overlay-manager-deprecated", 13501 "aui-delayed-task-deprecated", 13502 "aui-aria" 13503 ] 13504 }, 13505 "aui-overlay-context-panel-deprecated": { 13506 "requires": [ 13507 "anim", 13508 "aui-overlay-context-deprecated" 13509 ], 13510 "skinnable": true 13511 }, 13512 "aui-overlay-deprecated": { 13513 "use": [ 13514 "aui-overlay-base-deprecated", 13515 "aui-overlay-context-deprecated", 13516 "aui-overlay-context-panel-deprecated", 13517 "aui-overlay-manager-deprecated", 13518 "aui-overlay-mask-deprecated" 13519 ] 13520 }, 13521 "aui-overlay-manager-deprecated": { 13522 "requires": [ 13523 "overlay", 13524 "plugin", 13525 "aui-base-deprecated", 13526 "aui-overlay-base-deprecated" 13527 ] 13528 }, 13529 "aui-overlay-mask-deprecated": { 13530 "requires": [ 13531 "event-resize", 13532 "aui-base-deprecated", 13533 "aui-overlay-base-deprecated" 13534 ], 13535 "skinnable": true 13536 }, 13537 "aui-pagination": { 13538 "requires": [ 13539 "node-event-delegate", 13540 "aui-node", 13541 "aui-component", 13542 "widget-htmlparser" 13543 ], 13544 "skinnable": true 13545 }, 13546 "aui-palette": { 13547 "requires": [ 13548 "base-build", 13549 "event-hover", 13550 "widget", 13551 "aui-classnamemanager", 13552 "aui-base", 13553 "aui-widget-cssclass", 13554 "aui-widget-toggle" 13555 ], 13556 "skinnable": true 13557 }, 13558 "aui-parse-content": { 13559 "requires": [ 13560 "async-queue", 13561 "plugin", 13562 "io-base", 13563 "aui-component", 13564 "aui-node-base" 13565 ] 13566 }, 13567 "aui-popover": { 13568 "requires": [ 13569 "event-resize", 13570 "widget", 13571 "widget-autohide", 13572 "widget-buttons", 13573 "widget-modality", 13574 "widget-position", 13575 "widget-position-align", 13576 "widget-position-constrain", 13577 "widget-stack", 13578 "widget-stdmod", 13579 "aui-classnamemanager", 13580 "aui-widget-cssclass", 13581 "aui-widget-toggle", 13582 "aui-widget-toolbars", 13583 "aui-widget-transition", 13584 "aui-widget-trigger", 13585 "aui-widget-position-align-suggestion", 13586 "aui-component", 13587 "aui-node-base" 13588 ], 13589 "skinnable": true 13590 }, 13591 "aui-progressbar": { 13592 "requires": [ 13593 "aui-node", 13594 "aui-component", 13595 "aui-aria" 13596 ], 13597 "skinnable": true 13598 }, 13599 "aui-promise": { 13600 "requires": [ 13601 "array-invoke", 13602 "promise", 13603 "oop" 13604 ] 13605 }, 13606 "aui-property-builder": { 13607 "requires": [ 13608 "dd", 13609 "collection", 13610 "aui-property-builder-available-field", 13611 "aui-property-builder-field-support", 13612 "aui-property-builder-settings", 13613 "aui-tabview" 13614 ], 13615 "skinnable": true 13616 }, 13617 "aui-property-builder-available-field": { 13618 "requires": [ 13619 "base", 13620 "aui-component", 13621 "aui-node" 13622 ] 13623 }, 13624 "aui-property-builder-field-support": {}, 13625 "aui-property-builder-settings": { 13626 "requires": [ 13627 "aui-tabview", 13628 "aui-datatable-property-list" 13629 ] 13630 }, 13631 "aui-radio-group-data-editor": { 13632 "requires": [ 13633 "aui-data-editor", 13634 "node-event-delegate" 13635 ], 13636 "skinnable": true 13637 }, 13638 "aui-rating": { 13639 "use": [ 13640 "aui-rating-base", 13641 "aui-rating-thumb" 13642 ] 13643 }, 13644 "aui-rating-base": { 13645 "requires": [ 13646 "aui-component", 13647 "aui-node-base", 13648 "widget-htmlparser", 13649 "widget-uievents" 13650 ], 13651 "skinnable": true 13652 }, 13653 "aui-rating-thumb": { 13654 "requires": [ 13655 "aui-rating-base" 13656 ] 13657 }, 13658 "aui-resize-base-deprecated": { 13659 "requires": [ 13660 "dd-drag", 13661 "dd-delegate", 13662 "dd-drop", 13663 "aui-base-deprecated" 13664 ], 13665 "skinnable": true 13666 }, 13667 "aui-resize-constrain-deprecated": { 13668 "requires": [ 13669 "dd-constrain", 13670 "plugin", 13671 "aui-resize-base-deprecated" 13672 ] 13673 }, 13674 "aui-resize-deprecated": { 13675 "skinnable": true, 13676 "use": [ 13677 "aui-resize-base-deprecated", 13678 "aui-resize-constrain-deprecated" 13679 ] 13680 }, 13681 "aui-scale-data-editor": { 13682 "requires": [ 13683 "aui-classnamemanager", 13684 "aui-data-editor", 13685 "event-valuechange" 13686 ] 13687 }, 13688 "aui-scheduler": { 13689 "use": [ 13690 "event-gestures", 13691 "aui-scheduler-base", 13692 "aui-scheduler-event-recorder", 13693 "aui-scheduler-view-agenda", 13694 "aui-scheduler-view-day", 13695 "aui-scheduler-view-month", 13696 "aui-scheduler-view-table-dd", 13697 "aui-scheduler-view-table", 13698 "aui-scheduler-view-week", 13699 "aui-viewport" 13700 ] 13701 }, 13702 "aui-scheduler-base": { 13703 "requires": [ 13704 "model", 13705 "model-list", 13706 "widget-stdmod", 13707 "color-hsl", 13708 "aui-event-base", 13709 "aui-node-base", 13710 "aui-component", 13711 "aui-datatype", 13712 "aui-button", 13713 "node-focusmanager" 13714 ], 13715 "skinnable": true 13716 }, 13717 "aui-scheduler-event-recorder": { 13718 "requires": [ 13719 "querystring", 13720 "io-form", 13721 "overlay", 13722 "aui-scheduler-base", 13723 "aui-popover" 13724 ], 13725 "skinnable": true 13726 }, 13727 "aui-scheduler-touch": { 13728 "condition": { 13729 "name": "aui-scheduler-touch", 13730 "trigger": "aui-scheduler", 13731 "ua": "touchEnabled" 13732 }, 13733 "requires": [ 13734 "base-build", 13735 "aui-scheduler" 13736 ], 13737 "skinnable": true 13738 }, 13739 "aui-scheduler-view-agenda": { 13740 "requires": [ 13741 "aui-scheduler-base" 13742 ], 13743 "skinnable": true 13744 }, 13745 "aui-scheduler-view-day": { 13746 "requires": [ 13747 "dd-drag", 13748 "dd-delegate", 13749 "dd-drop", 13750 "dd-constrain", 13751 "aui-scheduler-view-table" 13752 ], 13753 "skinnable": true 13754 }, 13755 "aui-scheduler-view-month": { 13756 "requires": [ 13757 "aui-scheduler-view-table" 13758 ], 13759 "skinnable": true 13760 }, 13761 "aui-scheduler-view-table": { 13762 "requires": [ 13763 "overlay", 13764 "aui-scheduler-base" 13765 ], 13766 "skinnable": true 13767 }, 13768 "aui-scheduler-view-table-dd": { 13769 "requires": [ 13770 "dd-drag", 13771 "dd-delegate", 13772 "dd-drop", 13773 "aui-scheduler-view-table" 13774 ] 13775 }, 13776 "aui-scheduler-view-week": { 13777 "requires": [ 13778 "aui-scheduler-view-day" 13779 ], 13780 "skinnable": true 13781 }, 13782 "aui-scroller-deprecated": { 13783 "requires": [ 13784 "event-mouseenter", 13785 "aui-base-deprecated", 13786 "aui-simple-anim-deprecated" 13787 ], 13788 "skinnable": true 13789 }, 13790 "aui-scrollspy": { 13791 "requires": [ 13792 "base-build", 13793 "node-screen", 13794 "aui-classnamemanager" 13795 ] 13796 }, 13797 "aui-search": { 13798 "use": [ 13799 "aui-search-tst" 13800 ] 13801 }, 13802 "aui-search-tst": { 13803 "requires": [ 13804 "aui-component" 13805 ] 13806 }, 13807 "aui-selector": { 13808 "requires": [ 13809 "selector-css3", 13810 "aui-classnamemanager" 13811 ] 13812 }, 13813 "aui-set": { 13814 "requires": [ 13815 "aui-map" 13816 ] 13817 }, 13818 "aui-simple-anim-deprecated": { 13819 "requires": [ 13820 "aui-base-deprecated" 13821 ] 13822 }, 13823 "aui-skin-deprecated": { 13824 "type": "css" 13825 }, 13826 "aui-sortable": { 13827 "use": [ 13828 "aui-sortable-layout", 13829 "aui-sortable-list" 13830 ] 13831 }, 13832 "aui-sortable-layout": { 13833 "requires": [ 13834 "dd-delegate", 13835 "dd-drag", 13836 "dd-drop", 13837 "dd-proxy", 13838 "aui-node", 13839 "aui-component" 13840 ], 13841 "skinnable": true 13842 }, 13843 "aui-sortable-list": { 13844 "requires": [ 13845 "dd-drag", 13846 "dd-drop", 13847 "dd-proxy", 13848 "dd-scroll", 13849 "aui-node", 13850 "aui-component" 13851 ] 13852 }, 13853 "aui-state-interaction-deprecated": { 13854 "requires": [ 13855 "aui-base-deprecated", 13856 "plugin" 13857 ] 13858 }, 13859 "aui-surface": { 13860 "use": [ 13861 "aui-surface-app", 13862 "aui-surface-screen" 13863 ] 13864 }, 13865 "aui-surface-app": { 13866 "requires": [ 13867 "event-delegate", 13868 "node-event-html5", 13869 "aui-surface-base", 13870 "aui-surface-screen", 13871 "aui-surface-screen-route" 13872 ] 13873 }, 13874 "aui-surface-base": { 13875 "requires": [ 13876 "base-build", 13877 "node-style", 13878 "timers", 13879 "aui-debounce", 13880 "aui-promise", 13881 "aui-parse-content" 13882 ] 13883 }, 13884 "aui-surface-screen": { 13885 "requires": [ 13886 "base-build" 13887 ] 13888 }, 13889 "aui-surface-screen-html": { 13890 "requires": [ 13891 "aui-base", 13892 "aui-io-request", 13893 "aui-promise", 13894
13894 "aui-surface-screen", 13895 "aui-url" 13896 ] 13897 }, 13898 "aui-surface-screen-route": { 13899 "requires": [ 13900 "base-build" 13901 ] 13902 }, 13903 "aui-swf-deprecated": { 13904 "requires": [ 13905 "querystring-parse-simple", 13906 "querystring-stringify-simple", 13907 "aui-base-deprecated" 13908 ] 13909 }, 13910 "aui-tabs-data-editor": { 13911 "requires": [ 13912 "aui-data-editor", 13913 "aui-tabview" 13914 ] 13915 }, 13916 "aui-tabview": { 13917 "requires": [ 13918 "selector-css3", 13919 "tabview", 13920 "aui-component", 13921 "aui-widget-css" 13922 ], 13923 "skinnable": true 13924 }, 13925 "aui-template-deprecated": { 13926 "requires": [ 13927 "aui-base-deprecated" 13928 ] 13929 }, 13930 "aui-text-data-editor": { 13931 "requires": [ 13932 "aui-data-editor", 13933 "event-valuechange" 13934 ], 13935 "skinnable": true 13936 }, 13937 "aui-text-data-unicode": { 13938 "requires": [ 13939 "text" 13940 ] 13941 }, 13942 "aui-text-unicode": { 13943 "requires": [ 13944 "aui-text-data-unicode" 13945 ] 13946 }, 13947 "aui-textboxlist-deprecated": { 13948 "requires": [ 13949 "anim-node-plugin", 13950 "aui-autocomplete-deprecated", 13951 "aui-button-item-deprecated", 13952 "aui-data-set-deprecated", 13953 "escape", 13954 "node-focusmanager" 13955 ], 13956 "skinnable": true 13957 }, 13958 "aui-timepicker": { 13959 "requires": [ 13960 "autocomplete", 13961 "aui-datepicker-delegate", 13962 "aui-datepicker-popover" 13963 ], 13964 "skinnable": true 13965 }, 13966 "aui-timepicker-native": { 13967 "requires": [ 13968 "base", 13969 "base-build", 13970 "aui-node-base", 13971 "aui-datepicker-delegate", 13972 "aui-datepicker-native" 13973 ] 13974 }, 13975 "aui-timer": { 13976 "requires": [ 13977 "oop" 13978 ] 13979 }, 13980 "aui-toggler": { 13981 "use": [ 13982 "aui-toggler-base", 13983 "aui-toggler-delegate" 13984 ] 13985 }, 13986 "aui-toggler-accessibility": { 13987 "requires": [ 13988 "aui-toggler-base" 13989 ] 13990 }, 13991 "aui-toggler-base": { 13992 "requires": [ 13993 "transition", 13994 "aui-selector", 13995 "aui-event-base", 13996 "aui-node", 13997 "aui-component", 13998 "event-tap" 13999 ], 14000 "skinnable": true 14001 }, 14002 "aui-toggler-delegate": { 14003 "requires": [ 14004 "array-invoke", 14005 "node-event-delegate", 14006 "aui-toggler-base" 14007 ] 14008 }, 14009 "aui-toolbar": { 14010 "requires": [ 14011 "arraylist", 14012 "arraylist-add", 14013 "aui-component", 14014 "aui-button-core" 14015 ] 14016 }, 14017 "aui-tooltip": { 14018 "use": [ 14019 "aui-tooltip-base", 14020 "aui-tooltip-delegate" 14021 ] 14022 }, 14023 "aui-tooltip-base": { 14024 "requires": [ 14025 "aui-aria", 14026 "aui-classnamemanager", 14027 "aui-component", 14028 "aui-debounce", 14029 "aui-node-base", 14030 "aui-widget-cssclass", 14031 "aui-widget-toggle", 14032 "aui-widget-transition", 14033 "aui-widget-trigger", 14034 "aui-widget-position-align-suggestion", 14035 "event-hover", 14036 "event-resize", 14037 "escape", 14038 "widget", 14039 "widget-autohide", 14040 "widget-position", 14041 "widget-position-align", 14042 "widget-position-constrain", 14043 "widget-stack", 14044 "widget-stdmod" 14045 ], 14046 "skinnable": true 14047 }, 14048 "aui-tooltip-delegate": { 14049 "requires": [ 14050 "aui-tooltip-base", 14051 "node-event-delegate" 14052 ] 14053 }, 14054 "aui-tooltip-deprecated": { 14055 "requires": [ 14056 "aui-overlay-context-panel-deprecated" 14057 ], 14058 "skinnable": true 14059 }, 14060 "aui-tpl-snippets-base-deprecated": { 14061 "requires": [ 14062 "aui-template-deprecated" 14063 ] 14064 }, 14065 "aui-tpl-snippets-checkbox-deprecated": { 14066 "requires": [ 14067 "aui-tpl-snippets-base-deprecated" 14068 ] 14069 }, 14070 "aui-tpl-snippets-deprecated": { 14071 "use": [ 14072 "aui-tpl-snippets-base-deprecated", 14073 "aui-tpl-snippets-checkbox-deprecated", 14074 "aui-tpl-snippets-input-deprecated", 14075 "aui-tpl-snippets-select-deprecated", 14076 "aui-tpl-snippets-textarea-deprecated" 14077 ] 14078 }, 14079 "aui-tpl-snippets-input-deprecated": { 14080 "requires": [ 14081 "aui-tpl-snippets-base-deprecated" 14082 ] 14083 }, 14084 "aui-tpl-snippets-select-deprecated": { 14085 "requires": [ 14086 "aui-tpl-snippets-base-deprecated" 14087 ] 14088 }, 14089 "aui-tpl-snippets-textarea-deprecated": { 14090 "requires": [ 14091 "aui-tpl-snippets-base-deprecated" 14092 ] 14093 }, 14094 "aui-tree": { 14095 "use": [ 14096 "aui-tree-data", 14097 "aui-tree-io", 14098 "aui-tree-node", 14099 "aui-tree-paginator", 14100 "aui-tree-view" 14101 ] 14102 }, 14103 "aui-tree-data": { 14104 "requires": [ 14105 "aui-base-core", 14106 "aui-base-lang", 14107 "aui-node-base", 14108 "aui-timer", 14109 "aui-component" 14110 ] 14111 }, 14112 "aui-tree-io": { 14113 "requires": [ 14114 "aui-component", 14115 "aui-io" 14116 ] 14117 }, 14118 "aui-tree-node": { 14119 "requires": [ 14120 "json", 14121 "querystring-stringify", 14122 "aui-tree-data", 14123 "aui-tree-io", 14124 "aui-tree-paginator", 14125 "event-key" 14126 ] 14127 }, 14128 "aui-tree-paginator": { 14129 "requires": [ 14130 "yui-base" 14131 ] 14132 }, 14133 "aui-tree-view": { 14134 "requires": [ 14135 "dd-delegate", 14136 "dd-proxy", 14137 "widget", 14138 "aui-tree-node", 14139 "aui-tree-paginator", 14140 "aui-tree-io" 14141 ], 14142 "skinnable": true 14143 }, 14144 "aui-undo-redo": { 14145 "requires": [ 14146 "aui-base", 14147 "base", 14148 "base-build", 14149 "event-key", 14150 "promise" 14151 ] 14152 }, 14153 "aui-url": { 14154 "requires": [ 14155 "oop", 14156 "querystring-parse", 14157 "querystring-stringify" 14158 ] 14159 }, 14160 "aui-video": { 14161 "requires": [ 14162 "event-resize", 14163 "node-event-html5", 14164 "querystring-stringify-simple", 14165 "aui-aria", 14166 "aui-node", 14167 "aui-component", 14168 "aui-debounce" 14169 ], 14170 "skinnable": true 14171 }, 14172 "aui-viewport": { 14173 "requires": [ 14174 "aui-node", 14175 "aui-component" 14176 ] 14177 }, 14178 "aui-widget": { 14179 "use": [ 14180 "aui-widget-cssclass", 14181 "aui-widget-toolbars" 14182 ] 14183 }, 14184 "aui-widget-core": { 14185 "use": [ 14186 "aui-widget-cssclass" 14187 ] 14188 }, 14189 "aui-widget-cssclass": { 14190 "requires": [ 14191 "widget-base" 14192 ] 14193 }, 14194 "aui-widget-position-align-suggestion": { 14195 "requires": [ 14196 "widget-position-align", 14197 "widget-stdmod" 14198 ] 14199 }, 14200 "aui-widget-responsive": { 14201 "requires": [ 14202 "event-resize", 14203 "widget-base" 14204 ] 14205 }, 14206 "aui-widget-shortcut": { 14207 "requires": [ 14208 "base" 14209 ] 14210 }, 14211 "aui-widget-swipe": { 14212 "requires": [ 14213 "classnamemanager", 14214 "scrollview-base", 14215 "scrollview-paginator", 14216 "timers" 14217 ] 14218 }, 14219 "aui-widget-toggle": {}, 14220 "aui-widget-toolbars": { 14221 "requires": [ 14222 "widget-stdmod", 14223 "aui-toolbar" 14224 ] 14225 }, 14226 "aui-widget-transition": { 14227 "requires": [ 14228 "transition" 14229 ] 14230 }, 14231 "aui-widget-trigger": { 14232 "requires": [ 14233 "node" 14234 ] 14235 } 14236}); 14237YUI.Env[Y.version].md5 = 'd7c627eb00edd6b6f054d8f6e7147480'; 14238/* 14239 * Alloy JavaScript Library 14240 * http://alloy.liferay.com/ 14241 * 14242 * Copyright (c) 2010 Liferay Inc. 14243 * http://alloy.liferay.com/LICENSE.txt 14244 * 14245 * Nate Cavanaugh ([email protected]) 14246 * Eduardo Lundgren ([email protected]) 14247 * 14248 * Attribution/Third-party licenses 14249 * http://alloy.liferay.com/ATTRIBUTION.txt 14250 */ 14251 14252// Simple version of 14253// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ 14254 14255A.UA.edge = (function() { 14256 var edgeVersion = A.UA.userAgent.match(/Edge\/(.[0-9.]+)/); 14257 14258 if (edgeVersion) { 14259 return edgeVersion[1]; 14260 } 14261 14262 return 0; 14263})(); 14264 14265A.supportsDOMEvent = function(domNode, eventName) { 14266 eventName = 'on' + eventName; 14267 14268 if (!(eventName in domNode)) { 14269 if (!domNode.setAttribute) { 14270 domNode = A.config.doc.createElement('div'); 14271 } 14272 14273 if (domNode.setAttribute) { 14274 domNode.setAttribute(eventName, ''); 14275 return (typeof domNode[eventName] === 'function'); 14276 } 14277 } 14278 14279 domNode = null; 14280 14281 return true; 14282}; 14283(function() { 14284 var slice = Array.prototype.slice; 14285 14286 YUI.prototype.ready = function() { 14287 var instance = this, 14288 xargs = arguments, 14289 index = xargs.length - 1, 14290 modules = slice.call(arguments, 0, index); 14291 14292 modules.unshift('event-base'); 14293 modules.push(function(instance) { 14294 var args = arguments; 14295 14296 instance.on('domready', function() { 14297 xargs[index].apply(this, args); 14298 }); 14299 }); 14300 instance.use.apply(instance, modules); 14301 }; 14302}()); 14303 14304 14305}, '3.1.0-deprecated.77'); 14306YUI.add('aui', function (A, NAME) {}, '3.1.0-deprecated.77'); 14307YUI.Env.core.push.apply(YUI.Env.core, ["aui-base-core"]); 14308/** 14309 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 14310 * 14311 * This library is free software; you can redistribute it and/or modify it under 14312 * the terms of the GNU Lesser General Public License as published by the Free 14313 * Software Foundation; either version 2.1 of the License, or (at your option) 14314 * any later version. 14315 * 14316 * This library is distributed in the hope that it will be useful, but WITHOUT 14317 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14318 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14319 * details. 14320 */ 14321 14322/** 14323 * @deprecated As of Athanasius (7.3.x), with no direct replacement 14324 */ 14325(function () { 14326 var LiferayAUI = Liferay.AUI; 14327 var COMBINE = LiferayAUI.getCombine(); 14328 var CORE_MODULES = YUI.Env.core; 14329 var INPUT_EL = document.createElement('input'); 14330 var PATH_EDITOR_CKEDITOR = LiferayAUI.getEditorCKEditorPath(); 14331 var PATH_JAVASCRIPT = '/o/frontend-js-aui-web'; 14332 var SUPPORTS_INPUT_SELECTION = typeof INPUT_EL.selectionStart === 'number' && typeof INPUT_EL.selectionEnd === 'number'; 14333 14334 var testHistory = function testHistory(A) { 14335 var WIN = A.config.win; 14336 var HISTORY = WIN.history; 14337 return HISTORY && HISTORY.pushState && HISTORY.replaceState && ('onpopstate' in WIN || A.UA.gecko >= 2); 14338 }; 14339 14340 window.YUI_config = { 14341 base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/aui/', 14342 combine: COMBINE, 14343 comboBase: LiferayAUI.getComboPath(), 14344 filter: Liferay.AUI.getFilter(), 14345 groups: { 14346 editor: { 14347 base: PATH_EDITOR_CKEDITOR, 14348 combine: COMBINE, 14349 modules: { 14350 'inline-editor-ckeditor': { 14351 path: 'ckeditor/main.js' 14352 } 14353 }, 14354 root: PATH_EDITOR_CKEDITOR 14355 }, 14356 liferay: { 14357 base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/liferay/', 14358 combine: COMBINE, 14359 filter: Liferay.AUI.getFilterConfig(), 14360 modules: { 14361 'liferay-address': { 14362 path: 'address.js', 14363 requires: [] 14364 }, 14365 'liferay-alert': { 14366 path: 'alert.js', 14367 requires: ['aui-alert', 'aui-component', 'event-mouseenter', 'liferay-portlet-base', 'timers'] 14368 }, 14369 'liferay-asset-addon-entry-selector': { 14370 path: 'asset_addon_entry_selector.js', 14371 requires: ['aui-component', 'liferay-portlet-base', 'liferay-util-window'] 14372 }, 14373 'liferay-asset-categories-selector': { 14374 path: 'asset_categories_selector.js', 14375 requires: ['aui-tree', 'liferay-asset-tags-selector'] 14376 }, 14377 'liferay-asset-tags-selector': { 14378 path: 'asset_tags_selector.js',
14379 requires: ['array-extras', 'async-queue', 'aui-autocomplete-deprecated', 'aui-io-plugin-deprecated', 'aui-live-search-deprecated', 'aui-modal', 'aui-template-deprecated', 'aui-textboxlist-deprecated', 'datasource-cache', 'liferay-service-datasource'] 14380 }, 14381 'liferay-auto-fields': { 14382 path: 'auto_fields.js', 14383 requires: ['aui-base', 'aui-data-set-deprecated', 'aui-parse-content', 'base', 'liferay-form', 'liferay-menu', 'liferay-portlet-base', 'liferay-undo-manager', 'sortable'] 14384 }, 14385 'liferay-autocomplete-input': { 14386 path: 'autocomplete_input.js', 14387 requires: ['aui-base', 'autocomplete', 'autocomplete-filters', 'autocomplete-highlighters'] 14388 }, 14389 'liferay-autocomplete-input-caretindex': { 14390 condition: { 14391 name: 'liferay-autocomplete-input-caretindex', 14392 test: function test() { 14393 return SUPPORTS_INPUT_SELECTION; 14394 }, 14395 trigger: 'liferay-autocomplete-textarea' 14396 }, 14397 path: 'autocomplete_input_caretindex.js', 14398 requires: ['liferay-autocomplete-textarea'] 14399 }, 14400 'liferay-autocomplete-input-caretindex-sel': { 14401 condition: { 14402 name: 'liferay-autocomplete-input-caretindex-sel', 14403 test: function test() { 14404 return !SUPPORTS_INPUT_SELECTION; 14405 }, 14406 trigger: 'liferay-autocomplete-textarea' 14407 }, 14408 path: 'autocomplete_input_caretindex_sel.js', 14409 requires: ['liferay-autocomplete-textarea'] 14410 }, 14411 'liferay-autocomplete-input-caretoffset': { 14412 condition: { 14413 name: 'liferay-autocomplete-input-caretoffset', 14414 test: function test(A) { 14415 return !(A.UA.ie && A.UA.ie < 9); 14416 }, 14417 trigger: 'liferay-autocomplete-textarea' 14418 }, 14419 path: 'autocomplete_input_caretoffset.js', 14420 requires: ['liferay-autocomplete-textarea'] 14421 }, 14422 'liferay-autocomplete-input-caretoffset-sel': { 14423 condition: { 14424 name: 'liferay-autocomplete-input-caretoffset-sel', 14425 test: function test(A) { 14426 return A.UA.ie && A.UA.ie < 9; 14427 }, 14428 trigger: 'liferay-autocomplete-textarea' 14429 }, 14430 path: 'autocomplete_input_caretoffset_sel.js', 14431 requires: ['liferay-autocomplete-textarea'] 14432 }, 14433 'liferay-autocomplete-textarea': { 14434 path: 'autocomplete_textarea.js', 14435 requires: ['liferay-autocomplete-input'] 14436 }, 14437 'liferay-browser-selectors': { 14438 path: 'browser_selectors.js', 14439 requires: ['yui-base'] 14440 }, 14441 'liferay-cover-cropper': { 14442 path: 'cover_cropper.js', 14443 requires: ['aui-base', 'aui-component', 'dd-constrain', 'dd-drag', 'plugin'] 14444 }, 14445 'liferay-crop-region': { 14446 path: 'crop_region.js', 14447 requires: ['aui-base'] 14448 }, 14449 'liferay-dd-proxy': { 14450 path: 'dd_proxy.js', 14451 requires: ['dd-proxy'] 14452 }, 14453 'liferay-dynamic-select': {
14454 path: 'dynamic_select.js', 14455 requires: ['aui-base'] 14456 }, 14457 'liferay-form': { 14458 path: 'form.js', 14459 requires: ['aui-base', 'aui-form-validator'] 14460 }, 14461 'liferay-form-placeholders': { 14462 condition: { 14463 name: 'liferay-form-placeholders', 14464 test: function test() { 14465 return !('placeholder' in INPUT_EL); 14466 }, 14467 trigger: 'liferay-form' 14468 }, 14469 path: 'form_placeholders.js', 14470 requires: ['liferay-form', 'plugin'] 14471 }, 14472 'liferay-fullscreen-source-editor': { 14473 path: 'fullscreen_source_editor.js', 14474 requires: ['liferay-source-editor'] 14475 }, 14476 'liferay-history': { 14477 path: 'history.js', 14478 requires: ['history-hash', 'querystring-parse-simple'] 14479 }, 14480 'liferay-history-html5': { 14481 condition: { 14482 name: 'liferay-history-html5', 14483 test: testHistory, 14484 trigger: 'liferay-history' 14485 }, 14486 path: 'history_html5.js', 14487 requires: ['history-html5', 'liferay-history', 'querystring-stringify-simple'] 14488 }, 14489 'liferay-history-manager': { 14490 path: 'history_manager.js', 14491 requires: ['liferay-history'] 14492 }, 14493 'liferay-hudcrumbs': { 14494 path: 'hudcrumbs.js', 14495 requires: ['aui-base', 'aui-debounce', 'event-resize'] 14496 }, 14497 'liferay-icon': { 14498 path: 'icon.js', 14499 requires: ['aui-base'] 14500 }, 14501 'liferay-inline-editor-base': { 14502 path: 'inline_editor_base.js', 14503 requires: ['aui-base', 'aui-overlay-base-deprecated'] 14504 }, 14505 'liferay-input-localized': { 14506 path: 'input_localized.js', 14507 requires: ['aui-base', 'aui-component', 'aui-event-input', 'aui-palette', 'aui-set', 'portal-available-languages'] 14508 }, 14509 'liferay-input-move-boxes': { 14510 path: 'input_move_boxes.js', 14511 plugins: { 14512 'liferay-input-move-boxes-touch': { 14513 condition: { 14514 name: 'liferay-input-move-boxes-touch', 14515 test: function test(A) { 14516 return A.UA.touchEnabled && !!A.UA.mobile; 14517 }, 14518 trigger: 'liferay-input-move-boxes' 14519 } 14520 } 14521 }, 14522 requires: ['aui-base', 'aui-toolbar'] 14523 }, 14524 'liferay-input-move-boxes-touch': { 14525 path: 'input_move_boxes_touch.js', 14526 requires: ['aui-base', 'aui-template-deprecated', 'liferay-input-move-boxes', 'sortable'] 14527 }, 14528 'liferay-item-selector-dialog': { 14529 path: 'item_selector_dialog.js', 14530 requires: ['aui-component'] 14531 }, 14532 'liferay-item-selector-repository-entry-browser': { 14533 path: 'item_selector_repository_entry_browser.js', 14534 requires: ['liferay-item-selector-uploader', 'liferay-item-viewer', 'liferay-notice', 'liferay-portlet-base'] 14535 }, 14536 'liferay-item-selector-uploader': { 14537 path: 'item_selector_uploader.js', 14538 requires: ['aui-base', 'aui-progressbar', 'liferay-portlet-base', 'uploader'] 14539 }, 14540 'liferay-item-selector-url': { 14541 path: 'item_selector_url.js', 14542 requires: ['aui-event-input', 'liferay-item-viewer', 'liferay-portlet-base'] 14543 }, 14544 'liferay-item-viewer': { 14545 path: 'item_viewer.js', 14546 requires: ['aui-component', 'aui-image-viewer', 'liferay-portlet-url'] 14547 }, 14548 'liferay-language': { 14549 path: 'language.js' 14550 }, 14551 'liferay-layout': { 14552 path: 'layout.js' 14553 }, 14554 'liferay-layout-column': { 14555 path: 'layout_column.js', 14556 requires: ['aui-sortable-layout', 'dd'] 14557 }, 14558 'liferay-list-view': { 14559 path: 'list_view.js', 14560 requires: ['aui-base', 'transition'] 14561 }, 14562 'liferay-logo-editor': { 14563 path: 'logo_editor.js', 14564 requires: ['aui-image-cropper', 'liferay-portlet-base'] 14565 }, 14566 'liferay-logo-selector': { 14567 path: 'logo_selector.js', 14568 requires: ['aui-base'] 14569 }, 14570 'liferay-menu': { 14571 path: 'menu.js', 14572 requires: ['aui-debounce', 'aui-node'] 14573 }, 14574 'liferay-menu-filter': { 14575 path: 'menu_filter.js', 14576 requires: ['autocomplete-base', 'autocomplete-filters', 'autocomplete-highlighters'] 14577 }, 14578 'liferay-menu-toggle': { 14579 path: 'menu_toggle.js', 14580 requires: ['aui-node', 'event-outside', 'event-tap', 'liferay-menu-filter'] 14581 }, 14582 'liferay-message': { 14583 path: 'message.js', 14584 requires: ['aui-base'] 14585 }, 14586 'liferay-navigation': { 14587 path: 'navigation.js', 14588 requires: ['aui-component', 'event-mouseenter'] 14589 }, 14590 'liferay-navigation-interaction': { 14591 path: 'navigation_interaction.js', 14592 plugins: { 14593 'liferay-navigation-interaction-touch': { 14594 condition: { 14595 name: 'liferay-navigation-interaction-touch', 14596 test: function test(A) { 14597 return A.UA.touchEnabled; 14598 }, 14599 trigger: 'liferay-navigation-interaction' 14600 } 14601 } 14602 }, 14603 requires: ['aui-base', 'aui-component', 'event-mouseenter', 'node-focusmanager', 'plugin'] 14604 }, 14605 'liferay-navigation-interaction-touch': { 14606 path: 'navigation_interaction_touch.js', 14607 requires: ['event-tap', 'event-touch', 'liferay-navigation-interaction'] 14608 },
14609 'liferay-node': { 14610 path: 'node.js', 14611 requires: ['dom-base'] 14612 }, 14613 'liferay-notice': { 14614 path: 'notice.js', 14615 requires: ['aui-base', 'transition'] 14616 }, 14617 'liferay-notification': { 14618 path: 'notification.js', 14619 requires: ['liferay-alert'] 14620 }, 14621 'liferay-pagination': { 14622 path: 'pagination.js', 14623 requires: ['aui-pagination'] 14624 }, 14625 'liferay-panel-search': { 14626 path: 'panel_search.js', 14627 requires: ['aui-base', 'liferay-search-filter'] 14628 }, 14629 'liferay-poller': { 14630 path: 'poller.js', 14631 requires: ['aui-base', 'json'] 14632 }, 14633 'liferay-portlet-base': { 14634 path: 'portlet_base.js', 14635 requires: ['aui-base'] 14636 }, 14637 'liferay-portlet-url': { 14638 path: 'portlet_url.js', 14639 requires: ['aui-base'] 14640 }, 14641 'liferay-preview': { 14642 path: 'preview.js', 14643 requires: ['aui-base', 'aui-overlay-mask-deprecated', 'aui-toolbar', 'liferay-widget-zindex'] 14644 }, 14645 'liferay-progress': { 14646 path: 'progress.js', 14647 requires: ['aui-progressbar'] 14648 }, 14649 'liferay-ratings': { 14650 path: 'ratings.js', 14651 requires: ['aui-rating'] 14652 }, 14653 'liferay-resize-rtl': { 14654 condition: { 14655 test: function test() { 14656 return document.documentElement.dir === 'rtl'; 14657 }, 14658 trigger: 'resize-base' 14659 }, 14660 path: 'resize_rtl.js' 14661 }, 14662 'liferay-restore-entry': { 14663 path: 'restore_entry.js', 14664 requires: ['aui-io-plugin-deprecated', 'aui-modal', 'liferay-portlet-base'] 14665 }, 14666 'liferay-search-container': { 14667 path: 'search_container.js', 14668 requires: ['aui-base', 'aui-datatable-core'] 14669 }, 14670 'liferay-search-container-move': { 14671 path: 'search_container_move.js', 14672 requires: ['aui-component', 'dd-constrain', 'dd-delegate', 'dd-drag', 'dd-drop', 'dd-proxy', 'plugin'] 14673 }, 14674 'liferay-search-container-select': { 14675 path: 'search_container_select.js', 14676 requires: ['aui-component', 'aui-url', 'plugin'] 14677 }, 14678 'liferay-search-filter': { 14679 path: 'search_filter.js', 14680 requires: ['aui-base', 'autocomplete-base', 'autocomplete-filters'] 14681 }, 14682 'liferay-service-datasource': { 14683 path: 'service_datasource.js', 14684 requires: ['aui-base', 'datasource-local'] 14685 }, 14686 'liferay-session': { 14687 path: 'session.js', 14688 requires: ['aui-base', 'aui-component', 'aui-timer', 'cookie', 'plugin'] 14689 }, 14690 'liferay-sign-in-modal': { 14691 path: 'sign_in_modal.js', 14692 requires: ['aui-base', 'aui-component', 'aui-parse-content', 'liferay-form', 'liferay-portlet-url', 'liferay-util-window', 'plugin'] 14693 }, 14694 'liferay-social-bookmarks': { 14695 path: 'social_bookmarks.js', 14696 requires: ['aui-component', 'aui-node'] 14697 }, 14698 'liferay-sortable': { 14699 path: 'sortable.js', 14700 requires: ['liferay-dd-proxy', 'sortable'] 14701 }, 14702 'liferay-source-editor': { 14703 path: 'source_editor.js', 14704 requires: ['aui-ace-editor'] 14705 }, 14706 'liferay-storage-formatter': { 14707 path: 'storage_formatter.js', 14708 requires: ['aui-base', 'datatype-number-format'] 14709 }, 14710 'liferay-store': { 14711 path: 'store.js' 14712 }, 14713 'liferay-toggler-interaction': { 14714 path: 'toggler_interaction.js', 14715 requires: ['liferay-toggler-key-filter'] 14716 }, 14717 'liferay-toggler-key-filter': { 14718 path: 'toggler_key_filter.js', 14719 requires: ['aui-event-base'] 14720 }, 14721 'liferay-token-list': { 14722 path: 'token_list.js', 14723 requires: ['aui-base', 'aui-template-deprecated'] 14724 }, 14725 'liferay-translation-manager': { 14726 path: 'translation_manager.js', 14727 requires: ['aui-base'] 14728 }, 14729 'liferay-tree-view-icons': { 14730 condition: { 14731 name: 'liferay-tree-view-icons', 14732 trigger: 'aui-tree-view' 14733 }, 14734 path: 'tree_view_icons.js', 14735 requires: ['aui-tree-view'] 14736 }, 14737 'liferay-undo-manager': { 14738 path: 'undo_manager.js', 14739 requires: ['aui-data-set-deprecated', 'base'] 14740 }, 14741 'liferay-upload': { 14742 path: 'upload.js', 14743 requires: ['aui-template-deprecated', 'collection', 'liferay-portlet-base', 'uploader'] 14744 }, 14745 'liferay-util-window': { 14746 path: 'util_window.js', 14747 requires: ['aui-dialog-iframe-deprecated', 'aui-modal', 'aui-url', 'event-resize', 'liferay-widget-zindex'] 14748 }, 14749 'liferay-widget-size-animation-plugin': { 14750 path: 'widget_size_animation_plugin.js', 14751 requires: ['anim-easing', 'plugin', 'widget'] 14752 }, 14753 'liferay-widget-zindex': { 14754 path: 'widget_zindex.js', 14755 requires: ['aui-modal', 'plugin'] 14756 }, 14757 'liferay-xml-formatter': { 14758 path: 'xml_formatter.js', 14759 requires: ['aui-base'] 14760 } 14761 }, 14762 root: PATH_JAVASCRIPT + '/liferay/' 14763 }, 14764 misc: { 14765 base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/misc/', 14766 combine: COMBINE, 14767 modules: { 14768 swfobject: { 14769 path: 'swfobject.js' 14770 }, 14771 swfupload: { 14772 path: 'swfupload/swfupload.js' 14773 } 14774 }, 14775 root: PATH_JAVASCRIPT + '/misc/' 14776 }, 14777 portal: { 14778 base: Liferay.ThemeDisplay.getCDNBaseURL() + LiferayAUI.getJavaScriptRootPath() + '/liferay/', 14779 combine: false, 14780 modules: { 14781 'portal-available-languages': { 14782 path: LiferayAUI.getAvailableLangPath(), 14783 requires: ['liferay-language'] 14784 } 14785 }, 14786 root: PATH_JAVASCRIPT + '/liferay/' 14787 } 14788 }, 14789 insertBefore: 'liferayPortalCSS', 14790 lang: themeDisplay.getBCP47LanguageId(), 14791 root: PATH_JAVASCRIPT + '/aui/', 14792 useBrowserConsole: false 14793 }; 14794 CORE_MODULES.push('liferay-browser-selectors'); 14795})(); 14796//# sourceMappingURL=modules.js.map 14797/** 14798 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 14799 * 14800 * This library is free software; you can redistribute it and/or modify it under 14801 * the terms of the GNU Lesser General Public License as published by the Free 14802 * Software Foundation; either version 2.1 of the License, or (at your option) 14803 * any later version. 14804 * 14805 * This library is distributed in the hope that it will be useful, but WITHOUT 14806 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14807 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14808 * details. 14809 */ 14810 14811/** 14812 * @deprecated As of Athanasius (7.3.x), with no direct replacement 14813 */ 14814(function () { 14815 var ALLOY = YUI(); 14816 14817 if (ALLOY.html5shiv) { 14818 ALLOY.html5shiv(); 14819 } 14820 14821 var originalUse = ALLOY.use; 14822 14823 ALLOY.use = function () { 14824 var args = Array.prototype.slice.call(arguments, 0); 14825 var currentURL = Liferay.currentURL; 14826 var originalCallback = args[args.length - 1]; 14827 14828 if (typeof originalCallback === 'function') { 14829 args[args.length - 1] = function () { 14830 if (Liferay.currentURL === currentURL) { 14831 originalCallback.apply(this, arguments); 14832 } 14833 }; 14834 } 14835 14836 return originalUse.apply(this, args); 14837 }; 14838 14839 window.AUI = function () { 14840 return ALLOY; 14841 }; 14842 14843 ALLOY.mix(AUI, YUI); 14844 AUI.$ = window.jQuery; 14845 AUI._ = window._; 14846})(); 14847//# sourceMappingURL=aui_sandbox.js.map 14848YUI.add('attribute-base', function (Y, NAME) { 14849 14850 /** 14851 * The attribute module provides an augmentable Attribute implementation, which 14852 * adds configurable attributes and attribute change events to the class being 14853 * augmented. It also provides a State class, which is used internally by Attribute, 14854 * but can also be used independently to provide a name/property/value data structure to 14855 * store state. 14856 * 14857 * @module attribute 14858 */ 14859 14860 /** 14861 * The attribute-base submodule provides core attribute handling support, with everything 14862 * aside from complex attribute handling in the provider's constructor. 14863 * 14864 * @module attribute 14865 * @submodule attribute-base 14866 */ 14867 14868 /** 14869 * <p> 14870 * Attribute provides configurable attribute support along with attribute change events. It is designed to be 14871 * augmented on to a host class, and provides the host with the ability to configure attributes to store and retrieve state, 14872 * along with attribute change events. 14873 * </p> 14874 * <p>For example, attributes added to the host can be configured:</p> 14875 * <ul> 14876 * <li>As read only.</li> 14877 * <li>As write once.</li> 14878 * <li>With a setter function, which can be used to manipulate 14879 * values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li> 14880 * <li>With a getter function, which can be used to manipulate stored values, 14881 * before they are returned by Attribute's <a href="#method_get">get</a> method.</li> 14882 * <li>With a validator function, to validate values before they are stored.</li> 14883 * </ul> 14884 * 14885 * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration 14886 * options available for attributes.</p> 14887 * 14888 * <p><strong>NOTE:</strong> Most implementations will be better off extending the <a href="Base.html">Base</a> class, 14889 * instead of augmenting Attribute directly. Base augments Attribute and will handle the initial configuration 14890 * of attributes for derived classes, accounting for values passed into the constructor.</p> 14891 * 14892 * @class Attribute 14893 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 14894 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 14895 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 14896 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 14897 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 14898 * @uses AttributeCore 14899 * @uses AttributeObservable 14900 * @uses EventTarget 14901 * @uses AttributeExtras 14902 */ 14903 function Attribute() { 14904 Y.AttributeCore.apply(this, arguments); 14905 Y.AttributeObservable.apply(this, arguments); 14906 Y.AttributeExtras.apply(this, arguments); 14907 } 14908 14909 Y.mix(Attribute, Y.AttributeCore, false, null, 1); 14910 Y.mix(Attribute, Y.AttributeExtras, false, null, 1); 14911 14912 // Needs to be `true`, to overwrite methods from AttributeCore 14913 Y.mix(Attribute, Y.AttributeObservable, true, null, 1); 14914 14915 /** 14916 * <p>The value to return from an attribute setter in order to prevent the set from going through.</p> 14917 * 14918 * <p>You can return this value from your setter if you wish to combine validator and setter 14919 * functionality into a single setter function, which either returns the massaged value to be stored or 14920 * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p> 14921 * 14922 * @property INVALID_VALUE 14923 * @type Object 14924 * @static 14925 * @final 14926 */ 14927 Attribute.INVALID_VALUE = Y.AttributeCore.INVALID_VALUE; 14928 14929 /** 14930 * The list of properties which can be configured for 14931 * each attribute (e.g. setter, getter, writeOnce etc.). 14932 * 14933 * This property is used internally as a whitelist for faster 14934 * Y.mix operations. 14935 * 14936 * @property _ATTR_CFG 14937 * @type Array 14938 * @static 14939 * @protected 14940 */ 14941 Attribute._ATTR_CFG = Y.AttributeCore._ATTR_CFG.concat(Y.AttributeObservable._ATTR_CFG); 14942 14943 /** 14944 * Utility method to protect an attribute configuration hash, by merging the 14945 * entire object and the individual attr config objects. 14946 * 14947 * @method protectAttrs 14948 * @static 14949 * @param {Object} attrs A hash of attribute to configuration object pairs. 14950 * @return {Object} A protected version of the `attrs` argument. 14951 */ 14952 Attribute.protectAttrs = Y.AttributeCore.protectAttrs; 14953 14954 Y.Attribute = Attribute; 14955 14956 14957}, 'patched-v3.18.1', {"requires": ["attribute-core", "attribute-observable", "attribute-extras"]}); 14958 14959YUI.add('attribute-complex', function (Y, NAME) { 14960 14961 /** 14962 * Adds support for attribute providers to handle complex attributes in the constructor 14963 * 14964 * @module attribute 14965 * @submodule attribute-complex 14966 * @for Attribute 14967 * @deprecated AttributeComplex's overrides are now part of AttributeCore. 14968 */ 14969 14970 var Attribute = Y.Attribute; 14971 14972 Attribute.Complex = function() {}; 14973 Attribute.Complex.prototype = { 14974 14975 /** 14976 * Utility method to split out simple attribute name/value pairs ("x") 14977 * from complex attribute name/value pairs ("x.y.z"), so that complex 14978 * attributes can be keyed by the top level attribute name. 14979 * 14980 * @method _normAttrVals 14981 * @param {Object} valueHash An object with attribute name/value pairs 14982 * 14983 * @return {Object} An object literal with 2 properties - "simple" and "complex", 14984 * containing simple and complex attribute values respectively keyed 14985 * by the top level attribute name, or null, if valueHash is falsey. 14986 * 14987 * @private 14988 */ 14989 _normAttrVals : Attribute.prototype._normAttrVals, 14990 14991 /** 14992 * Returns the initial value of the given attribute from 14993 * either the default configuration provided, or the 14994 * over-ridden value if it exists in the set of initValues 14995 * provided and the attribute is not read-only. 14996 * 14997 * @param {String} attr The name of the attribute 14998 * @param {Object} cfg The attribute configuration object 14999 * @param {Object}
14999 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals 15000 * 15001 * @return {Any} The initial value of the attribute. 15002 * 15003 * @method _getAttrInitVal 15004 * @private 15005 */ 15006 _getAttrInitVal : Attribute.prototype._getAttrInitVal 15007 15008 }; 15009 15010 // Consistency with the rest of the Attribute addons for now. 15011 Y.AttributeComplex = Attribute.Complex; 15012 15013 15014}, 'patched-v3.18.1', {"requires": ["attribute-base"]}); 15015 15016YUI.add('attribute-core', function (Y, NAME) { 15017 15018 /** 15019 * The State class maintains state for a collection of named items, with 15020 * a varying number of properties defined. 15021 * 15022 * It avoids the need to create a separate class for the item, and separate instances 15023 * of these classes for each item, by storing the state in a 2 level hash table, 15024 * improving performance when the number of items is likely to be large. 15025 * 15026 * @constructor 15027 * @class State 15028 */ 15029 Y.State = function() { 15030 /** 15031 * Hash of attributes 15032 * @property data 15033 */ 15034 this.data = {}; 15035 }; 15036 15037 Y.State.prototype = { 15038 15039 /** 15040 * Adds a property to an item. 15041 * 15042 * @method add 15043 * @param name {String} The name of the item. 15044 * @param key {String} The name of the property. 15045 * @param val {Any} The value of the property. 15046 */ 15047 add: function(name, key, val) { 15048 var item = this.data[name]; 15049 15050 if (!item) { 15051 item = this.data[name] = {}; 15052 } 15053 15054 item[key] = val; 15055 }, 15056 15057 /** 15058 * Adds multiple properties to an item. 15059 * 15060 * @method addAll 15061 * @param name {String} The name of the item. 15062 * @param obj {Object} A hash of property/value pairs. 15063 */ 15064 addAll: function(name, obj) { 15065 var item = this.data[name], 15066 key; 15067 15068 if (!item) { 15069 item = this.data[name] = {}; 15070 } 15071 15072 for (key in obj) { 15073 if (obj.hasOwnProperty(key)) { 15074 item[key] = obj[key]; 15075 } 15076 } 15077 }, 15078 15079 /** 15080 * Removes a property from an item. 15081 * 15082 * @method remove 15083 * @param name {String} The name of the item. 15084 * @param key {String} The property to remove. 15085 */ 15086 remove: function(name, key) { 15087 var item = this.data[name]; 15088 15089 if (item) { 15090 delete item[key]; 15091 } 15092 }, 15093 15094 /** 15095 * Removes multiple properties from an item, or removes the item completely. 15096 * 15097 * @method removeAll 15098 * @param name {String} The name of the item. 15099 * @param obj {Object|Array} Collection of properties to delete. If not provided, the entire item is removed. 15100 */ 15101 removeAll: function(name, obj) { 15102 var data; 15103 15104 if (!obj) { 15105 data = this.data; 15106 15107 if (name in data) { 15108 delete data[name]; 15109 } 15110 } else { 15111 Y.each(obj, function(value, key) { 15112 this.remove(name, typeof key === 'string' ? key : value); 15113 }, this); 15114 } 15115 }, 15116 15117 /** 15118 * For a given item, returns the value of the property requested, or undefined if not found. 15119 * 15120 * @method get 15121 * @param name {String} The name of the item 15122 * @param key {String} Optional. The property value to retrieve. 15123 * @return {Any} The value of the supplied property. 15124 */ 15125 get: function(name, key) { 15126 var item = this.data[name]; 15127 15128 if (item) { 15129 return item[key]; 15130 } 15131 }, 15132 15133 /** 15134 * For the given item, returns an object with all of the 15135 * item's property/value pairs. By default the object returned 15136 * is a shallow copy of the stored data, but passing in true 15137 * as the second parameter will return a reference to the stored 15138 * data. 15139 * 15140 * @method getAll 15141 * @param name {String} The name of the item 15142 * @param reference {boolean} true, if you want a reference to the stored 15143 * object 15144 * @return {Object} An object with property/value pairs for the item. 15145 */ 15146 getAll : function(name, reference) { 15147 var item = this.data[name], 15148 key, obj; 15149 15150 if (reference) { 15151 obj = item; 15152 } else if (item) { 15153 obj = {}; 15154 15155 for (key in item) { 15156 if (item.hasOwnProperty(key)) { 15157 obj[key] = item[key]; 15158 } 15159 } 15160 } 15161 15162 return obj; 15163 } 15164 }; 15165 /*For log lines*/ 15166 /*jshint maxlen:200*/ 15167 15168 /** 15169 * The attribute module provides an augmentable Attribute implementation, which 15170 * adds configurable attributes and attribute change events to the class being 15171 * augmented. It also provides a State class, which is used internally by Attribute, 15172 * but can also be used independently to provide a name/property/value data structure to 15173 * store state. 15174 * 15175 * @module attribute 15176 */ 15177 15178 /** 15179 * The attribute-core submodule provides the lightest level of attribute handling support 15180 * without Attribute change events, or lesser used methods such as reset(), modifyAttrs(), 15181 * and removeAttr(). 15182 * 15183 * @module attribute 15184 * @submodule attribute-core 15185 */ 15186 var O = Y.Object, 15187 Lang = Y.Lang, 15188 15189 DOT = ".", 15190 15191 // Externally configurable props 15192 GETTER = "getter", 15193 SETTER = "setter", 15194 READ_ONLY = "readOnly", 15195 WRITE_ONCE = "writeOnce", 15196 INIT_ONLY = "initOnly", 15197 VALIDATOR = "validator", 15198 VALUE = "value", 15199 VALUE_FN = "valueFn", 15200 LAZY_ADD = "lazyAdd", 15201 15202 // Used for internal state management 15203 ADDED = "added", 15204 BYPASS_PROXY = "_bypassProxy", 15205 INIT_VALUE = "initValue", 15206 LAZY = "lazy", 15207 15208 INVALID_VALUE; 15209 15210 /** 15211 * <p> 15212 * AttributeCore provides the lightest level of configurable attribute support. It is designed to be 15213 * augmented on to a host class, and provides the host with the ability to configure 15214 * attributes to store and retrieve state, <strong>but without support for attribute change events</strong>. 15215 * </p> 15216 * <p>For example, attributes added to the host can be configured:</p> 15217 * <ul> 15218 * <li>As read only.</li> 15219 * <li>As write once.</li> 15220 * <li>With a setter function, which can be used to manipulate 15221 * values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li> 15222 * <li>With a getter function, which can be used to manipulate stored values, 15223 * before they are returned by Attribute's <a href="#method_get">get</a> method.</li> 15224 * <li>With a validator function, to validate values before they are stored.</li> 15225 * </ul> 15226 * 15227 * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration 15228 * options available for attributes.</p> 15229 * 15230 * <p>Object/Classes based on AttributeCore can augment <a href="AttributeObservable.html">AttributeObservable</a>
15231 * (with true for overwrite) and <a href="AttributeExtras.html">AttributeExtras</a> to add attribute event and 15232 * additional, less commonly used attribute methods, such as `modifyAttr`, `removeAttr` and `reset`.</p> 15233 * 15234 * @class AttributeCore 15235 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 15236 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 15237 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 15238 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 15239 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 15240 */ 15241 function AttributeCore(attrs, values, lazy) { 15242 // HACK: Fix #2531929 15243 // Complete hack, to make sure the first clone of a node value in IE doesn't doesn't hurt state - maintains 3.4.1 behavior. 15244 // Too late in the release cycle to do anything about the core problem. 15245 // The root issue is that cloning a Y.Node instance results in an object which barfs in IE, when you access it's properties (since 3.3.0). 15246 this._yuievt = null; 15247 15248 this._initAttrHost(attrs, values, lazy); 15249 } 15250 15251 /** 15252 * <p>The value to return from an attribute setter in order to prevent the set from going through.</p> 15253 * 15254 * <p>You can return this value from your setter if you wish to combine validator and setter 15255 * functionality into a single setter function, which either returns the massaged value to be stored or 15256 * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p> 15257 * 15258 * @property INVALID_VALUE 15259 * @type Object 15260 * @static 15261 * @final 15262 */ 15263 AttributeCore.INVALID_VALUE = {}; 15264 INVALID_VALUE = AttributeCore.INVALID_VALUE; 15265 15266 /** 15267 * The list of properties which can be configured for 15268 * each attribute (e.g. setter, getter, writeOnce etc.). 15269 * 15270 * This property is used internally as a whitelist for faster 15271 * Y.mix operations. 15272 * 15273 * @property _ATTR_CFG 15274 * @type Array 15275 * @static 15276 * @protected 15277 */ 15278 AttributeCore._ATTR_CFG = [SETTER, GETTER, VALIDATOR, VALUE, VALUE_FN, WRITE_ONCE, READ_ONLY, LAZY_ADD, BYPASS_PROXY]; 15279 15280 /** 15281 * Utility method to protect an attribute configuration hash, by merging the 15282 * entire object and the individual attr config objects. 15283 * 15284 * @method protectAttrs 15285 * @static 15286 * @param {Object} attrs A hash of attribute to configuration object pairs. 15287 * @return {Object} A protected version of the `attrs` argument. 15288 */ 15289 AttributeCore.protectAttrs = function (attrs) { 15290 if (attrs) { 15291 attrs = Y.merge(attrs); 15292 for (var attr in attrs) { 15293 if (attrs.hasOwnProperty(attr)) { 15294 attrs[attr] = Y.merge(attrs[attr]); 15295 } 15296 } 15297 } 15298 15299 return attrs; 15300 }; 15301 15302 AttributeCore.prototype = { 15303 15304 /** 15305 * Constructor logic for attributes. Initializes the host state, and sets up the inital attributes passed to the 15306 * constructor. 15307 * 15308 * @method _initAttrHost 15309 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 15310 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 15311 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 15312 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 15313 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 15314 * @private 15315 */ 15316 _initAttrHost : function(attrs, values, lazy) { 15317 this._state = new Y.State(); 15318 this._initAttrs(attrs, values, lazy); 15319 }, 15320 15321 /** 15322 * <p> 15323 * Adds an attribute with the provided configuration to the host object. 15324 * </p> 15325 * <p> 15326 * The config argument object supports the following properties: 15327 * </p> 15328 * 15329 * <dl> 15330 * <dt>value <Any></dt> 15331 * <dd>The initial value to set on the attribute</dd> 15332 * 15333 * <dt>valueFn <Function | String></dt> 15334 * <dd> 15335 * <p>A function, which will return the initial value to set on the attribute. This is useful 15336 * for cases where the attribute configuration is defined statically, but needs to 15337 * reference the host instance ("this") to obtain an initial value. If both the value and valueFn properties are defined, 15338 * the value returned by the valueFn has precedence over the value property, unless it returns undefined, in which 15339 * case the value property is used.</p> 15340 * 15341 * <p>valueFn can also be set to a string, representing the name of the instance method to be used to retrieve the value.</p> 15342 * </dd> 15343 * 15344 * <dt>readOnly <boolean></dt> 15345 * <dd>Whether or not the attribute is read only. Attributes having readOnly set to true 15346 * cannot be modified by invoking the set method.</dd> 15347 * 15348 * <dt>writeOnce <boolean> or <string></dt> 15349 * <dd> 15350 * Whether or not the attribute is "write once". Attributes having writeOnce set to true, 15351 * can only have their values set once, be it through the default configuration, 15352 * constructor configuration arguments, or by invoking set. 15353 * <p>The writeOnce attribute can also be set to the string "initOnly", 15354 * in which case the attribute can only be set during initialization 15355 * (when used with Base, this means it can only be set during construction)</p> 15356 * </dd> 15357 * 15358 * <dt>setter <Function | String></dt> 15359 * <dd> 15360 * <p>The setter function used to massage or normalize the value passed to the set method for the attribute. 15361 * The value returned by the setter will be the final stored value. Returning 15362 * <a href="#property_Attribute.INVALID_VALUE">Attribute.INVALID_VALUE</a>, from the setter will prevent 15363 * the value from being stored. 15364 * </p> 15365 * 15366 * <p>setter can also be set to a string, representing the name of the instance method to be used as the setter function.</p> 15367 * </dd> 15368 * 15369 * <dt>getter <Function | String></dt> 15370 * <dd> 15371 * <p> 15372 * The getter function used to massage or normalize the value returned by the get method for the attribute. 15373 * The value returned by the getter function is the value which will be returned to the user when they 15374 * invoke get. 15375 * </p> 15376 * 15377 * <p>getter can also be set to a string, representing the name of the instance method to be used as the getter function.</p> 15378 * </dd> 15379 * 15380 * <dt>validator <Function | String></dt> 15381 * <dd> 15382 * <p> 15383 * The validator function invoked prior to setting the stored value. Returning 15384 * false from the validator function will prevent the value from being stored. 15385 * </p> 15386 * 15387 * <p>validator can also be set to a string, representing the name of the instance method to be used as the validator function.</p> 15388 * </dd> 15389 * 15390 * <dt>lazyAdd <boolean></dt> 15391 * <dd>Whether or not to delay initialization of the attribute until the first call to get/set it. 15392 * This flag can be used to over-ride lazy initialization on a per attribute basis, when adding multiple attributes through 15393 * the <a href="#method_addAttrs">addAttrs</a> method.</dd> 15394 * 15395 * </dl> 15396 * 15397 * <p>The setter, getter and validator are invoked with the value and name passed in as the first and second arguments, and with 15398 * the context ("this") set to the host object.</p> 15399 * 15400 * <p>Configuration properties outside of the list mentioned above are considered private properties used internally by attribute, 15401 * and are not intended for public use.</p> 15402 * 15403 * @method addAttr 15404 * 15405 * @param {String} name The name of the attribute. 15406 * @param {Object} config An object with attribute configuration property/value pairs, specifying the configuration for the attribute. 15407 * 15408 * <p> 15409 * <strong>NOTE:</strong> The configuration object is modified when adding an attribute, so if you need 15410 * to protect the original values, you will need to merge the object. 15411 * </p> 15412 * 15413 * @param {boolean} lazy (optional) Whether or not to add this attribute lazily (on the first call to get/set). 15414 * 15415 * @return {Object} A reference to the host object. 15416 * 15417 * @chainable 15418 */ 15419 addAttr : function(name, config, lazy) { 15420 15421 15422 var host = this, // help compression 15423 state = host._state, 15424 data = state.data, 15425 value, 15426 added, 15427 hasValue; 15428 15429 config = config || {}; 15430 15431 if (LAZY_ADD in config) { 15432 lazy = config[LAZY_ADD]; 15433 } 15434 15435 added = state.get(name, ADDED); 15436 15437 if (lazy && !added) { 15438 state.data[name] = { 15439 lazy : config, 15440 added : true 15441 }; 15442 } else { 15443 15444 15445 if (!added || config.isLazyAdd) { 15446 15447 hasValue = (VALUE in config); 15448 15449 15450 if (hasValue) { 15451 15452 // We'll go through set, don't want to set value in config directly 15453 15454 // PERF TODO: VALIDATE: See if setting this to undefined is sufficient. We use to delete before. 15455 // In certain code paths/use cases, undefined may not be the same as not present. 15456 // If not, we can set it to some known fixed value (like INVALID_VALUE, say INITIALIZING_VALUE) for performance, 15457 // to avoid a delete which seems to help a lot. 15458 15459 value = config.value; 15460 config.value = undefined; 15461 } 15462 15463 config.added = true; 15464 config.initializing = true; 15465 15466 data[name] = config; 15467 15468 if (hasValue) { 15469 // Go through set, so that raw values get normalized/validated 15470 host.set(name, value); 15471 } 15472 15473 config.initializing = false;
15474 } 15475 } 15476 15477 return host; 15478 }, 15479 15480 /** 15481 * Checks if the given attribute has been added to the host 15482 * 15483 * @method attrAdded 15484 * @param {String} name The name of the attribute to check. 15485 * @return {boolean} true if an attribute with the given name has been added, false if it hasn't. 15486 * This method will return true for lazily added attributes. 15487 */ 15488 attrAdded: function(name) { 15489 return !!(this._state.get(name, ADDED)); 15490 }, 15491 15492 /** 15493 * Returns the current value of the attribute. If the attribute 15494 * has been configured with a 'getter' function, this method will delegate 15495 * to the 'getter' to obtain the value of the attribute. 15496 * 15497 * @method get 15498 * 15499 * @param {String} name The name of the attribute. If the value of the attribute is an Object, 15500 * dot notation can be used to obtain the value of a property of the object (e.g. <code>get("x.y.z")</code>) 15501 * 15502 * @return {Any} The value of the attribute 15503 */ 15504 get : function(name) { 15505 return this._getAttr(name); 15506 }, 15507 15508 /** 15509 * Checks whether or not the attribute is one which has been 15510 * added lazily and still requires initialization. 15511 * 15512 * @method _isLazyAttr 15513 * @private 15514 * @param {String} name The name of the attribute 15515 * @return {boolean} true if it's a lazily added attribute, false otherwise. 15516 */ 15517 _isLazyAttr: function(name) { 15518 return this._state.get(name, LAZY); 15519 }, 15520 15521 /** 15522 * Finishes initializing an attribute which has been lazily added. 15523 * 15524 * @method _addLazyAttr 15525 * @private 15526 * @param {Object} name The name of the attribute 15527 * @param {Object} [lazyCfg] Optional config hash for the attribute. This is added for performance 15528 * along the critical path, where the calling method has already obtained lazy config from state. 15529 */ 15530 _addLazyAttr: function(name, lazyCfg) { 15531 var state = this._state; 15532 15533 lazyCfg = lazyCfg || state.get(name, LAZY); 15534 15535 if (lazyCfg) { 15536 15537 // PERF TODO: For App's id override, otherwise wouldn't be 15538 // needed. It expects to find it in the cfg for it's 15539 // addAttr override. Would like to remove, once App override is 15540 // removed. 15541 state.data[name].lazy = undefined; 15542 15543 lazyCfg.isLazyAdd = true; 15544 15545 this.addAttr(name, lazyCfg); 15546 } 15547 }, 15548 15549 /** 15550 * Sets the value of an attribute. 15551 * 15552 * @method set 15553 * @chainable 15554 * 15555 * @param {String} name The name of the attribute. If the 15556 * current value of the attribute is an Object, dot notation can be used 15557 * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>). 15558 * @param {Any} value The value to set the attribute to. 15559 * @param {Object} [opts] Optional data providing the circumstances for the change. 15560 * @return {Object} A reference to the host object. 15561 */ 15562 set : function(name, val, opts) { 15563 return this._setAttr(name, val, opts); 15564 }, 15565 15566 /** 15567 * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details. 15568 * 15569 * @method _set 15570 * @protected 15571 * @chainable 15572 * 15573 * @param {String} name The name of the attribute. 15574 * @param {Any} val The value to set the attribute to. 15575 * @param {Object} [opts] Optional data providing the circumstances for the change. 15576 * @return {Object} A reference to the host object. 15577 */ 15578 _set : function(name, val, opts) { 15579 return this._setAttr(name, val, opts, true); 15580 }, 15581 15582 /** 15583 * Provides the common implementation for the public set and protected _set methods. 15584 * 15585 * See <a href="#method_set">set</a> for argument details. 15586 * 15587 * @method _setAttr 15588 * @protected 15589 * @chainable 15590 * 15591 * @param {String} name The name of the attribute. 15592 * @param {Any} value The value to set the attribute to. 15593 * @param {Object} [opts] Optional data providing the circumstances for the change. 15594 * @param {boolean} force If true, allows the caller to set values for 15595 * readOnly or writeOnce attributes which have already been set. 15596 * 15597 * @return {Object} A reference to the host object. 15598 */ 15599 _setAttr : function(name, val, opts, force) { 15600 var allowSet = true, 15601 state = this._state, 15602 stateProxy = this._stateProxy, 15603 tCfgs = this._tCfgs, 15604 cfg, 15605 initialSet, 15606 strPath, 15607 path, 15608 currVal, 15609 writeOnce, 15610 initializing; 15611 15612 if (name.indexOf(DOT) !== -1) { 15613 strPath = name; 15614 15615 path = name.split(DOT); 15616 name = path.shift(); 15617 } 15618 15619 // On Demand - Should be rare - handles out of order valueFn, setter, getter references 15620 if (tCfgs && tCfgs[name]) { 15621 this._addOutOfOrder(name, tCfgs[name]); 15622 } 15623 15624 cfg = state.data[name] || {}; 15625 15626 if (cfg.lazy) { 15627 cfg = cfg.lazy; 15628 this._addLazyAttr(name, cfg); 15629 } 15630 15631 initialSet = (cfg.value === undefined); 15632 15633 if (stateProxy && name in stateProxy && !cfg._bypassProxy) { 15634 // TODO: Value is always set for proxy. Can we do any better? Maybe take a snapshot as the initial value for the first call to set? 15635 initialSet = false;
15636 } 15637 15638 writeOnce = cfg.writeOnce; 15639 initializing = cfg.initializing; 15640 15641 if (!initialSet && !force) { 15642 15643 if (writeOnce) { 15644 allowSet = false; 15645 } 15646 15647 if (cfg.readOnly) { 15648 allowSet = false; 15649 } 15650 } 15651 15652 if (!initializing && !force && writeOnce === INIT_ONLY) { 15653 allowSet = false; 15654 } 15655 15656 if (allowSet) { 15657 // Don't need currVal if initialSet (might fail in custom getter if it always expects a non-undefined/non-null value) 15658 if (!initialSet) { 15659 currVal = this.get(name); 15660 } 15661 15662 if (path) { 15663 var copyVal = [currVal].reduce( 15664 function(retVal, currVal) { 15665 Object.keys(currVal).forEach( 15666 function(item) { 15667 retVal[item] = currVal[item]; 15668 } 15669 ); 15670 return retVal; 15671 }, 15672 {} 15673 ); 15674 15675 var pathNode = copyVal; 15676 var leafIdx = path.length - 1; 15677 15678 for (var i = 0; i < leafIdx && pathNode; i++) { 15679 pathNode = pathNode[path[i]]; 15680 } 15681 15682 if (pathNode) { 15683 delete pathNode[path[leafIdx]]; 15684 } 15685 15686 val = O.setValue(Y.clone(copyVal), path, val); 15687 15688 if (val === undefined) { 15689 allowSet = false; 15690 } 15691 } 15692 15693 if (allowSet) { 15694 if (!this._fireAttrChange || initializing) { 15695 this._setAttrVal(name, strPath, currVal, val, opts, cfg); 15696 } else { 15697 // HACK - no real reason core needs to know about _fireAttrChange, but 15698 // it adds fn hops if we want to break it out. Not sure it's worth it for this critical path 15699 this._fireAttrChange(name, strPath, currVal, val, opts, cfg); 15700 } 15701 } 15702 } 15703 15704 return this; 15705 }, 15706 15707 /** 15708 * Utility method used by get/set to add attributes 15709 * encountered out of order when calling addAttrs(). 15710 * 15711 * For example, if: 15712 * 15713 * this.addAttrs({ 15714 * foo: { 15715 * setter: function() { 15716 * // make sure this bar is available when foo is added 15717 * this.get("bar"); 15718 * } 15719 * }, 15720 * bar: { 15721 * value: ... 15722 * } 15723 * }); 15724 * 15725 * @method _addOutOfOrder 15726 * @private 15727 * @param name {String} attribute name 15728 * @param cfg {Object} attribute configuration 15729 */ 15730 _addOutOfOrder : function(name, cfg) { 15731 15732 var attrs = {}; 15733 attrs[name] = cfg; 15734 15735 delete this._tCfgs[name]; 15736 15737 // TODO: The original code went through addAttrs, so 15738 // sticking with it for this pass. Seems like we could 15739 // just jump straight to _addAttr() and get some perf 15740 // improvement. 15741 this._addAttrs(attrs, this._tVals); 15742 }, 15743 15744 /** 15745 * Provides the common implementation for the public get method, 15746 * allowing Attribute hosts to over-ride either method. 15747 * 15748 * See <a href="#method_get">get</a> for argument details. 15749 * 15750 * @method _getAttr 15751 * @protected 15752 * @chainable 15753 * 15754 * @param {String} name The name of the attribute. 15755 * @return {Any} The value of the attribute. 15756 */ 15757 _getAttr : function(name) { 15758 var fullName = name, 15759 tCfgs = this._tCfgs, 15760 path, 15761 getter, 15762 val, 15763 attrCfg; 15764 15765 if (name.indexOf(DOT) !== -1) { 15766 path = name.split(DOT); 15767 name = path.shift(); 15768 } 15769 15770 // On Demand - Should be rare - handles out of 15771 // order valueFn, setter, getter references 15772 if (tCfgs && tCfgs[name]) { 15773 this._addOutOfOrder(name, tCfgs[name]); 15774 } 15775 15776 attrCfg = this._state.data[name] || {}; 15777 15778 // Lazy Init 15779 if (attrCfg.lazy) { 15780 attrCfg = attrCfg.lazy; 15781 this._addLazyAttr(name, attrCfg); 15782 } 15783 15784 val = this._getStateVal(name, attrCfg); 15785 15786 getter = attrCfg.getter; 15787 15788 if (getter && !getter.call) { 15789 getter = this[getter]; 15790 } 15791 15792 val = (getter) ? getter.call(this, val, fullName) : val; 15793 val = (path) ? O.getValue(val, path) : val; 15794 15795 return val; 15796 }, 15797 15798 /** 15799 * Gets the stored value for the attribute, from either the 15800 * internal state object, or the state proxy if it exits 15801 * 15802 * @method _getStateVal 15803 * @private 15804 * @param {String} name The name of the attribute 15805 * @param {Object} [cfg] Optional config hash for the attribute. This is added for performance along the critical path, 15806 * where the calling method has already obtained the config from state. 15807 * 15808 * @return {Any} The stored value of the attribute 15809 */ 15810 _getStateVal : function(name, cfg) { 15811 var stateProxy = this._stateProxy; 15812 15813 if (!cfg) { 15814 cfg = this._state.getAll(name) || {}; 15815 } 15816 15817 return (stateProxy && (name in stateProxy) && !(cfg._bypassProxy)) ? stateProxy[name] : cfg.value; 15818 }, 15819 15820 /** 15821 * Sets the stored value for the attribute, in either the 15822 * internal state object, or the state proxy if it exits 15823 * 15824 * @method _setStateVal 15825 * @private 15826 * @param {String} name The name of the attribute 15827 * @param {Any} value The value of the attribute 15828 */ 15829 _setStateVal : function(name, value) { 15830 var stateProxy = this._stateProxy; 15831 if (stateProxy && (name in stateProxy) && !this._state.get(name, BYPASS_PROXY)) { 15832 stateProxy[name] = value; 15833 } else { 15834 this._state.add(name, VALUE, value); 15835 } 15836 }, 15837 15838 /** 15839 * Updates the stored value of the attribute in the privately held State object, 15840 * if validation and setter passes. 15841 * 15842 * @method _setAttrVal 15843 * @private 15844 * @param {String} attrName The attribute name. 15845 * @param {String} subAttrName The sub-attribute name, if setting a sub-attribute property ("x.y.z"). 15846 * @param {Any} prevVal The currently stored value of the attribute. 15847 * @param {Any} newVal The value which is going to be stored. 15848 * @param {Object} [opts] Optional data providing the circumstances for the change. 15849 * @param {Object} [attrCfg] Optional config hash for the attribute. This is added for performance along the critical path, 15850 * where the calling method has already obtained the config from state. 15851 * 15852 * @return {Boolean} true if the new attribute value was stored, false if not. 15853 */ 15854 _setAttrVal : function(attrName, subAttrName, prevVal, newVal, opts, attrCfg) { 15855 15856 var host = this, 15857 allowSet = true, 15858 cfg = attrCfg || this._state.data[attrName] || {}, 15859 validator = cfg.validator, 15860 setter = cfg.setter, 15861 initializing = cfg.initializing, 15862 prevRawVal = this._getStateVal(attrName, cfg), 15863 name = subAttrName || attrName, 15864 retVal, 15865 valid; 15866 15867 if (validator) { 15868 if (!validator.call) { 15869 // Assume string - trying to keep critical path tight, so avoiding Lang check 15870 validator = this[validator]; 15871 } 15872 if (validator) { 15873 valid = validator.call(host, newVal, name, opts); 15874 15875 if (!valid && initializing) { 15876 newVal = cfg.defaultValue; 15877 valid = true; // Assume it's valid, for perf. 15878 } 15879 } 15880 } 15881 15882 if (!validator || valid) { 15883 if (setter) { 15884 if (!setter.call) { 15885 // Assume string - trying to keep critical path tight, so avoiding Lang check 15886 setter = this[setter]; 15887 } 15888 if (setter) { 15889 retVal = setter.call(host, newVal, name, opts); 15890 15891 if (retVal === INVALID_VALUE) { 15892 if (initializing) { 15893 newVal = cfg.defaultValue; 15894 } else { 15895 allowSet = false;
15896 } 15897 } else if (retVal !== undefined){ 15898 newVal = retVal; 15899 } 15900 } 15901 } 15902 15903 if (allowSet) { 15904 if(!subAttrName && (newVal === prevRawVal) && !Lang.isObject(newVal)) { 15905 allowSet = false; 15906 } else { 15907 // Store value 15908 if (!(INIT_VALUE in cfg)) { 15909 cfg.initValue = newVal; 15910 } 15911 host._setStateVal(attrName, newVal); 15912 } 15913 } 15914 15915 } else { 15916 allowSet = false; 15917 } 15918 15919 return allowSet; 15920 }, 15921 15922 /** 15923 * Sets multiple attribute values. 15924 * 15925 * @method setAttrs 15926 * @param {Object} attrs An object with attributes name/value pairs. 15927 * @param {Object} [opts] Optional data providing the circumstances for the change. 15928 * @return {Object} A reference to the host object. 15929 * @chainable 15930 */ 15931 setAttrs : function(attrs, opts) { 15932 return this._setAttrs(attrs, opts); 15933 }, 15934 15935 /** 15936 * Implementation behind the public setAttrs method, to set multiple attribute values. 15937 * 15938 * @method _setAttrs 15939 * @protected 15940 * @param {Object} attrs An object with attributes name/value pairs. 15941 * @param {Object} [opts] Optional data providing the circumstances for the change 15942 * @return {Object} A reference to the host object. 15943 * @chainable 15944 */ 15945 _setAttrs : function(attrs, opts) { 15946 var attr; 15947 for (attr in attrs) { 15948 if ( attrs.hasOwnProperty(attr) ) { 15949 this.set(attr, attrs[attr], opts); 15950 } 15951 } 15952 return this; 15953 }, 15954 15955 /** 15956 * Gets multiple attribute values. 15957 * 15958 * @method getAttrs 15959 * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are 15960 * returned. If set to true, all attributes modified from their initial values are returned. 15961 * @return {Object} An object with attribute name/value pairs. 15962 */ 15963 getAttrs : function(attrs) { 15964 return this._getAttrs(attrs); 15965 }, 15966 15967 /** 15968 * Implementation behind the public getAttrs method, to get multiple attribute values. 15969 * 15970 * @method _getAttrs 15971 * @protected 15972 * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are 15973 * returned. If set to true, all attributes modified from their initial values are returned. 15974 * @return {Object} An object with attribute name/value pairs. 15975 */ 15976 _getAttrs : function(attrs) { 15977 var obj = {}, 15978 attr, i, len, 15979 modifiedOnly = (attrs === true); 15980 15981 // TODO - figure out how to get all "added" 15982 if (!attrs || modifiedOnly) { 15983 attrs = O.keys(this._state.data); 15984 } 15985 15986 for (i = 0, len = attrs.length; i < len; i++) { 15987 attr = attrs[i]; 15988 15989 if (!modifiedOnly || this._getStateVal(attr) != this._state.get(attr, INIT_VALUE)) { 15990 // Go through get, to honor cloning/normalization 15991 obj[attr] = this.get(attr); 15992 } 15993 } 15994 15995 return obj; 15996 }, 15997 15998 /** 15999 * Configures a group of attributes, and sets initial values. 16000 * 16001 * <p> 16002 * <strong>NOTE:</strong> This method does not isolate the configuration object by merging/cloning. 16003 * The caller is responsible for merging/cloning the configuration object if required. 16004 * </p> 16005 * 16006 * @method addAttrs 16007 * @chainable 16008 * 16009 * @param {Object} cfgs An object with attribute name/configuration pairs. 16010 * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply. 16011 * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only. 16012 * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set.
16013 * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration. 16014 * See <a href="#method_addAttr">addAttr</a>. 16015 * 16016 * @return {Object} A reference to the host object. 16017 */ 16018 addAttrs : function(cfgs, values, lazy) { 16019 if (cfgs) { 16020 this._tCfgs = cfgs; 16021 this._tVals = (values) ? this._normAttrVals(values) : null; 16022 this._addAttrs(cfgs, this._tVals, lazy); 16023 this._tCfgs = this._tVals = null; 16024 } 16025 16026 return this; 16027 }, 16028 16029 /** 16030 * Implementation behind the public addAttrs method. 16031 * 16032 * This method is invoked directly by get if it encounters a scenario 16033 * in which an attribute's valueFn attempts to obtain the 16034 * value an attribute in the same group of attributes, which has not yet 16035 * been added (on demand initialization). 16036 * 16037 * @method _addAttrs 16038 * @private 16039 * @param {Object} cfgs An object with attribute name/configuration pairs. 16040 * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply. 16041 * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only. 16042 * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set. 16043 * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration. 16044 * See <a href="#method_addAttr">addAttr</a>. 16045 */ 16046 _addAttrs : function(cfgs, values, lazy) { 16047 var tCfgs = this._tCfgs, 16048 tVals = this._tVals, 16049 attr, 16050 attrCfg, 16051 value; 16052 16053 for (attr in cfgs) { 16054 if (cfgs.hasOwnProperty(attr)) { 16055 16056 // Not Merging. Caller is responsible for isolating configs 16057 attrCfg = cfgs[attr]; 16058 attrCfg.defaultValue = attrCfg.value; 16059 16060 // Handle simple, complex and user values, accounting for read-only 16061 value = this._getAttrInitVal(attr, attrCfg, tVals); 16062 16063 if (value !== undefined) { 16064 attrCfg.value = value; 16065 } 16066 16067 if (tCfgs[attr]) { 16068 tCfgs[attr] = undefined; 16069 } 16070 16071 this.addAttr(attr, attrCfg, lazy); 16072 } 16073 } 16074 }, 16075 16076 /** 16077 * Utility method to protect an attribute configuration 16078 * hash, by merging the entire object and the individual 16079 * attr config objects. 16080 * 16081 * @method _protectAttrs 16082 * @protected 16083 * @param {Object} attrs A hash of attribute to configuration object pairs. 16084 * @return {Object} A protected version of the attrs argument. 16085 * @deprecated Use `AttributeCore.protectAttrs()` or 16086 * `Attribute.protectAttrs()` which are the same static utility method. 16087 */ 16088 _protectAttrs : AttributeCore.protectAttrs, 16089 16090 /** 16091 * Utility method to normalize attribute values. The base implementation 16092 * simply merges the hash to protect the original. 16093 * 16094 * @method _normAttrVals 16095 * @param {Object} valueHash An object with attribute name/value pairs 16096 * 16097 * @return {Object} An object literal with 2 properties - "simple" and "complex", 16098 * containing simple and complex attribute values respectively keyed 16099 * by the top level attribute name, or null, if valueHash is falsey. 16100 * 16101 * @private 16102 */ 16103 _normAttrVals : function(valueHash) { 16104 var vals, 16105 subvals, 16106 path, 16107 attr, 16108 v, k; 16109 16110 if (!valueHash) { 16111 return null; 16112 } 16113 16114 vals = {}; 16115 16116 for (k in valueHash) { 16117 if (valueHash.hasOwnProperty(k)) { 16118 if (k.indexOf(DOT) !== -1) { 16119 path = k.split(DOT); 16120 attr = path.shift(); 16121 16122 subvals = subvals || {}; 16123 16124 v = subvals[attr] = subvals[attr] || []; 16125 v[v.length] = { 16126 path : path, 16127 value: valueHash[k] 16128 }; 16129 } else { 16130 vals[k] = valueHash[k]; 16131 } 16132 } 16133 } 16134 16135 return { simple:vals, complex:subvals }; 16136 }, 16137 16138 /** 16139 * Returns the initial value of the given attribute from 16140 * either the default configuration provided, or the 16141 * over-ridden value if it exists in the set of initValues 16142 * provided and the attribute is not read-only. 16143 * 16144 * @param {String} attr The name of the attribute 16145 * @param {Object} cfg The attribute configuration object 16146 * @param {Object}
16146 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals 16147 * 16148 * @return {Any} The initial value of the attribute. 16149 * 16150 * @method _getAttrInitVal 16151 * @private 16152 */ 16153 _getAttrInitVal : function(attr, cfg, initValues) { 16154 var val = cfg.value, 16155 valFn = cfg.valueFn, 16156 tmpVal, 16157 initValSet = false, 16158 readOnly = cfg.readOnly, 16159 simple, 16160 complex, 16161 i, 16162 l, 16163 path, 16164 subval, 16165 subvals; 16166 16167 if (!readOnly && initValues) { 16168 // Simple Attributes 16169 simple = initValues.simple; 16170 if (simple && simple.hasOwnProperty(attr)) { 16171 val = simple[attr]; 16172 initValSet = true; 16173 } 16174 } 16175 16176 if (valFn && !initValSet) { 16177 if (!valFn.call) { 16178 valFn = this[valFn]; 16179 } 16180 if (valFn) { 16181 tmpVal = valFn.call(this, attr); 16182 val = tmpVal; 16183 } 16184 } 16185 16186 if (!readOnly && initValues) { 16187 16188 // Complex Attributes (complex values applied, after simple, in case both are set) 16189 complex = initValues.complex; 16190 16191 if (complex && complex.hasOwnProperty(attr) && (val !== undefined) && (val !== null)) { 16192 subvals = complex[attr]; 16193 for (i = 0, l = subvals.length; i < l; ++i) { 16194 path = subvals[i].path; 16195 subval = subvals[i].value; 16196 O.setValue(val, path, subval); 16197 } 16198 } 16199 } 16200 16201 return val; 16202 }, 16203 16204 /** 16205 * Utility method to set up initial attributes defined during construction, 16206 * either through the constructor.ATTRS property, or explicitly passed in. 16207 * 16208 * @method _initAttrs 16209 * @protected 16210 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 16211 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 16212 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 16213 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 16214 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 16215 */ 16216 _initAttrs : function(attrs, values, lazy) { 16217 // ATTRS support for Node, which is not Base based 16218 attrs = attrs || this.constructor.ATTRS; 16219 16220 var Base = Y.Base, 16221 BaseCore = Y.BaseCore, 16222 baseInst = (Base && Y.instanceOf(this, Base)), 16223 baseCoreInst = (!baseInst && BaseCore && Y.instanceOf(this, BaseCore)); 16224 16225 if (attrs && !baseInst && !baseCoreInst) { 16226 this.addAttrs(Y.AttributeCore.protectAttrs(attrs), values, lazy); 16227 } 16228 } 16229 }; 16230 16231 Y.AttributeCore = AttributeCore; 16232 16233 16234}, 'patched-v3.18.1', {"requires": ["oop"]}); 16235 16236YUI.add('attribute-observable', function (Y, NAME) { 16237 16238 /*For log lines*/ 16239 /*jshint maxlen:200*/ 16240 16241 16242 /** 16243 * The attribute module provides an augmentable Attribute implementation, which 16244 * adds configurable attributes and attribute change events to the class being 16245 * augmented. It also provides a State class, which is used internally by Attribute, 16246 * but can also be used independently to provide a name/property/value data structure to 16247 * store state. 16248 * 16249 * @module attribute 16250 */ 16251 16252 /** 16253 * The `attribute-observable` submodule provides augmentable attribute change event support 16254 * for AttributeCore based implementations. 16255 * 16256 * @module attribute 16257 * @submodule attribute-observable 16258 */ 16259 var EventTarget = Y.EventTarget, 16260 16261 CHANGE = "Change", 16262 BROADCAST = "broadcast"; 16263 16264 /** 16265 * Provides an augmentable implementation of attribute change events for 16266 * AttributeCore. 16267 * 16268 * @class AttributeObservable 16269 * @extensionfor AttributeCore 16270 * @uses EventTarget 16271 */ 16272 function AttributeObservable() { 16273 // Perf tweak - avoid creating event literals if not required. 16274 this._ATTR_E_FACADE = {}; 16275 16276 EventTarget.call(this, {emitFacade:true}); 16277 } 16278 16279 AttributeObservable._ATTR_CFG = [BROADCAST]; 16280 16281 AttributeObservable.prototype = { 16282 16283 /** 16284 * Sets the value of an attribute. 16285 * 16286 * @method set 16287 * @chainable 16288 * 16289 * @param {String} name The name of the attribute. If the 16290 * current value of the attribute is an Object, dot notation can be used 16291 * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>). 16292 * 16293 * @param {Any} value The value to set the attribute to. 16294 * 16295 * @param {Object} opts (Optional) Optional event data to be mixed into 16296 * the event facade passed to subscribers of the attribute's change event. This 16297 * can be used as a flexible way to identify the source of a call to set, allowing 16298 * the developer to distinguish between set called internally by the host, vs. 16299 * set called externally by the application developer. 16300 * 16301 * @return {Object} A reference to the host object. 16302 */ 16303 set : function(name, val, opts) { 16304 return this._setAttr(name, val, opts); 16305 }, 16306 16307 /** 16308 * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details. 16309 * 16310 * @method _set 16311 * @protected 16312 * @chainable 16313 * 16314 * @param {String} name The name of the attribute. 16315 * @param {Any} val The value to set the attribute to. 16316 * @param {Object} opts (Optional) Optional event data to be mixed into 16317 * the event facade passed to subscribers of the attribute's change event. 16318 * @return {Object} A reference to the host object. 16319 */ 16320 _set : function(name, val, opts) { 16321 return this._setAttr(name, val, opts, true); 16322 }, 16323 16324 /** 16325 * Sets multiple attribute values. 16326 * 16327 * @method setAttrs 16328 * @param {Object} attrs An object with attributes name/value pairs. 16329 * @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set 16330 * @return {Object} A reference to the host object. 16331 * @chainable 16332 */ 16333 setAttrs : function(attrs, opts) { 16334 return this._setAttrs(attrs, opts); 16335 }, 16336 16337 /** 16338 * Implementation behind the public setAttrs method, to set multiple attribute values. 16339 * 16340 * @method _setAttrs 16341 * @protected 16342 * @param {Object} attrs An object with attributes name/value pairs. 16343 * @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set 16344 * @return {Object} A reference to the host object. 16345 * @chainable 16346 */ 16347 _setAttrs : function(attrs, opts) { 16348 var attr; 16349 for (attr in attrs) { 16350 if ( attrs.hasOwnProperty(attr) ) { 16351 this.set(attr, attrs[attr], opts); 16352 } 16353 } 16354 return this; 16355 }, 16356 16357 /** 16358 * Utility method to help setup the event payload and fire the attribute change event. 16359 * 16360 * @method _fireAttrChange 16361 * @private 16362 * @param {String} attrName The name of the attribute 16363 * @param {String} subAttrName The full path of the property being changed, 16364 * if this is a sub-attribute value being change. Otherwise null. 16365 * @param {Any} currVal The current value of the attribute 16366 * @param {Any} newVal The new value of the attribute 16367 * @param {Object} opts Any additional event data to mix into the attribute change event's event facade. 16368 * @param {Object} [cfg] The attribute config stored in State, if already available. 16369 */ 16370 _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) { 16371 var host = this, 16372 eventName = this._getFullType(attrName + CHANGE), 16373 state = host._state, 16374 facade, 16375 broadcast, 16376 e; 16377 16378 if (!cfg) { 16379 cfg = state.data[attrName] || {}; 16380 } 16381 16382 if (!cfg.published) { 16383 16384 // PERF: Using lower level _publish() for 16385 // critical path performance 16386 e = host._publish(eventName); 16387 16388 e.emitFacade = true; 16389 e.defaultTargetOnly = true; 16390 e.defaultFn = host._defAttrChangeFn; 16391 16392 broadcast = cfg.broadcast; 16393 if (broadcast !== undefined) { 16394 e.broadcast = broadcast; 16395 } 16396 16397 cfg.published = true; 16398 } 16399 16400 if (opts) { 16401 facade = Y.merge(opts); 16402 facade._attrOpts = opts; 16403 } else { 16404 facade = host._ATTR_E_FACADE; 16405 } 16406 16407 // Not using the single object signature for fire({type:..., newVal:...}), since 16408 // we don't want to override type. Changed to the fire(type, {newVal:...}) signature. 16409 16410 facade.attrName = attrName; 16411 facade.subAttrName = subAttrName; 16412 facade.prevVal = currVal; 16413 facade.newVal = newVal; 16414 16415 if (host._hasPotentialSubscribers(eventName)) { 16416 host.fire(eventName, facade); 16417 } else { 16418 this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg); 16419 } 16420 }, 16421 16422 /** 16423 * Default function for attribute change events. 16424 * 16425 * @private 16426 * @method _defAttrChangeFn 16427 * @param {EventFacade} e The event object for attribute change events. 16428 * @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not 16429 */ 16430 _defAttrChangeFn : function(e, eventFastPath) { 16431 16432 var opts = e._attrOpts; 16433 if (opts) { 16434 delete e._attrOpts; 16435 } 16436 16437 if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) { 16438 16439 16440 if (!eventFastPath) { 16441 // Prevent "after" listeners from being invoked since nothing changed. 16442 e.stopImmediatePropagation(); 16443 } 16444 16445 } else { 16446 if (!eventFastPath) { 16447 e.newVal = this.get(e.attrName); 16448 } 16449 } 16450 } 16451 }; 16452 16453 // Basic prototype augment - no lazy constructor invocation. 16454 Y.mix(AttributeObservable, EventTarget, false, null, 1); 16455 16456 Y.AttributeObservable = AttributeObservable; 16457 16458 /**
16459 The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now 16460 an alias for the `AttributeObservable` class extension. Use that class 16461 extnesion instead. This alias will be removed in a future version of YUI. 16462 16463 @class AttributeEvents 16464 @uses EventTarget 16465 @deprecated Use `AttributeObservable` instead. 16466 @see AttributeObservable 16467 **/ 16468 Y.AttributeEvents = AttributeObservable; 16469 16470 16471}, 'patched-v3.18.1', {"requires": ["event-custom"]}); 16472 16473YUI.add('attribute-extras', function (Y, NAME) { 16474 16475 /** 16476 * The attribute module provides an augmentable Attribute implementation, which 16477 * adds configurable attributes and attribute change events to the class being 16478 * augmented. It also provides a State class, which is used internally by Attribute, 16479 * but can also be used independently to provide a name/property/value data structure to 16480 * store state. 16481 * 16482 * @module attribute 16483 */ 16484 16485 /** 16486 * The attribute-extras submodule provides less commonly used attribute methods, and can 16487 * be augmented/mixed into an implemention which used attribute-core. 16488 * 16489 * @module attribute 16490 * @submodule attribute-extras 16491 */ 16492 var BROADCAST = "broadcast", 16493 PUBLISHED = "published", 16494 INIT_VALUE = "initValue", 16495 16496 MODIFIABLE = { 16497 readOnly:1, 16498 writeOnce:1, 16499 getter:1, 16500 broadcast:1 16501 }; 16502 16503 /** 16504 * A augmentable implementation for AttributeCore, providing less frequently used 16505 * methods for Attribute management such as modifyAttrs(), removeAttr and reset() 16506 * 16507 * @class AttributeExtras 16508 * @extensionfor AttributeCore 16509 */ 16510 function AttributeExtras() {} 16511 16512 AttributeExtras.prototype = { 16513 16514 /** 16515 * Updates the configuration of an attribute which has already been added. 16516 * <p> 16517 * The properties which can be modified through this interface are limited 16518 * to the following subset of attributes, which can be safely modified 16519 * after a value has already been set on the attribute: 16520 * </p> 16521 * <dl> 16522 * <dt>readOnly;</dt> 16523 * <dt>writeOnce;</dt> 16524 * <dt>broadcast; and</dt> 16525 * <dt>getter.</dt> 16526 * </dl> 16527 * <p> 16528 * Note: New attributes cannot be added using this interface. New attributes must be 16529 * added using {{#crossLink "AttributeCore/addAttr:method"}}addAttr{{/crossLink}}, or an 16530 * appropriate manner for a class which utilises Attributes (e.g. the 16531 * {{#crossLink "Base/ATTRS:property"}}ATTRS{{/crossLink}} property in 16532 * {{#crossLink "Base"}}Base{{/crossLink}}). 16533 * </p> 16534 * @method modifyAttr 16535 * @param {String} name The name of the attribute whose configuration is to be updated. 16536 * @param {Object} config An object with configuration property/value pairs, specifying the configuration properties to modify. 16537 */ 16538 modifyAttr: function(name, config) { 16539 var host = this, // help compression 16540 prop, state; 16541 16542 if (host.attrAdded(name)) { 16543 16544 if (host._isLazyAttr(name)) { 16545 host._addLazyAttr(name); 16546 } 16547 16548 state = host._state; 16549 for (prop in config) { 16550 if (MODIFIABLE[prop] && config.hasOwnProperty(prop)) { 16551 state.add(name, prop, config[prop]); 16552 16553 // If we reconfigured broadcast, need to republish 16554 if (prop === BROADCAST) { 16555 state.remove(name, PUBLISHED); 16556 } 16557 } 16558 } 16559 } else { 16560 } 16561 }, 16562 16563 /** 16564 * Removes an attribute from the host object 16565 * 16566 * @method removeAttr 16567 * @param {String} name The name of the attribute to be removed. 16568 */ 16569 removeAttr: function(name) { 16570 this._state.removeAll(name); 16571 }, 16572 16573 /** 16574 * Resets the attribute (or all attributes) to its initial value, as long as 16575 * the attribute is not readOnly, or writeOnce. 16576 * 16577 * @method reset 16578 * @param {String} name Optional. The name of the attribute to reset. If omitted, all attributes are reset. 16579 * @return {Object} A reference to the host object. 16580 * @chainable 16581 */ 16582 reset : function(name) { 16583 var host = this; // help compression 16584 16585 if (name) { 16586 if (host._isLazyAttr(name)) { 16587 host._addLazyAttr(name); 16588 } 16589 host.set(name, host._state.get(name, INIT_VALUE)); 16590 } else { 16591 Y.Object.each(host._state.data, function(v, n) { 16592 host.reset(n); 16593 }); 16594 } 16595 return host; 16596 }, 16597 16598 /** 16599 * Returns an object with the configuration properties (and value) 16600 * for the given attribute. If attrName is not provided, returns the 16601 * configuration properties for all attributes. 16602 * 16603 * @method _getAttrCfg 16604 * @protected 16605 * @param {String} name Optional. The attribute name. If not provided, the method will return the configuration for all attributes. 16606 * @return {Object} The configuration properties for the given attribute, or all attributes. 16607 */ 16608 _getAttrCfg : function(name) { 16609 var o, 16610 state = this._state; 16611 16612 if (name) { 16613 o = state.getAll(name) || {}; 16614 } else { 16615 o = {}; 16616 Y.each(state.data, function(v, n) { 16617 o[n] = state.getAll(n); 16618 }); 16619 } 16620 16621 return o; 16622 } 16623 }; 16624 16625 Y.AttributeExtras = AttributeExtras; 16626 16627 16628}, 'patched-v3.18.1', {"requires": ["oop"]}); 16629 16630YUI.add('event-custom-base', function (Y, NAME) { 16631 16632/** 16633 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 16634 * events. 16635 * @module event-custom 16636 */ 16637 16638Y.Env.evt = { 16639 handles: {}, 16640 plugins: {} 16641}; 16642 16643/** 16644 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 16645 * events. 16646 * @module event-custom 16647 * @submodule event-custom-base 16648 */ 16649 16650/** 16651 * Allows for the insertion of methods that are executed before or after 16652 * a specified method 16653 * @class Do 16654 * @static 16655 */ 16656 16657var DO_BEFORE = 0, 16658 DO_AFTER = 1, 16659 16660DO = { 16661 16662 /** 16663 * Cache of objects touched by the utility 16664 * @property objs 16665 * @static 16666 * @deprecated Since 3.6.0. The `_yuiaop` property on the AOP'd object 16667 * replaces the role of this property, but is considered to be private, and 16668 * is only mentioned to provide a migration path. 16669 * 16670 * If you have a use case which warrants migration to the _yuiaop property,
16671 * please file a ticket to let us know what it's used for and we can see if 16672 * we need to expose hooks for that functionality more formally. 16673 */ 16674 objs: null, 16675 16676 /** 16677 * <p>Execute the supplied method before the specified function. Wrapping 16678 * function may optionally return an instance of the following classes to 16679 * further alter runtime behavior:</p> 16680 * <dl> 16681 * <dt></code>Y.Do.Halt(message, returnValue)</code></dt> 16682 * <dd>Immediatly stop execution and return 16683 * <code>returnValue</code>. No other wrapping functions will be 16684 * executed.</dd> 16685 * <dt></code>Y.Do.AlterArgs(message, newArgArray)</code></dt> 16686 * <dd>Replace the arguments that the original function will be 16687 * called with.</dd> 16688 * <dt></code>Y.Do.Prevent(message)</code></dt> 16689 * <dd>Don't execute the wrapped function. Other before phase 16690 * wrappers will be executed.</dd> 16691 * </dl> 16692 * 16693 * @method before 16694 * @param fn {Function} the function to execute 16695 * @param obj the object hosting the method to displace 16696 * @param sFn {string} the name of the method to displace 16697 * @param c The execution context for fn 16698 * @param arg* {mixed} 0..n additional arguments to supply to the subscriber 16699 * when the event fires. 16700 * @return {EventHandle} handle for the subscription 16701 * @static 16702 */ 16703 before: function(fn, obj, sFn, c) { 16704 var f = fn, a; 16705 if (c) { 16706 a = [fn, c].concat(Y.Array(arguments, 4, true)); 16707 f = Y.rbind.apply(Y, a); 16708 } 16709 16710 return this._inject(DO_BEFORE, f, obj, sFn); 16711 }, 16712 16713 /** 16714 * <p>Execute the supplied method after the specified function. Wrapping 16715 * function may optionally return an instance of the following classes to 16716 * further alter runtime behavior:</p> 16717 * <dl> 16718 * <dt></code>Y.Do.Halt(message, returnValue)</code></dt> 16719 * <dd>Immediatly stop execution and return 16720 * <code>returnValue</code>. No other wrapping functions will be 16721 * executed.</dd> 16722 * <dt></code>Y.Do.AlterReturn(message, returnValue)</code></dt> 16723 * <dd>Return <code>returnValue</code> instead of the wrapped 16724 * method's original return value. This can be further altered by 16725 * other after phase wrappers.</dd> 16726 * </dl> 16727 * 16728 * <p>The static properties <code>Y.Do.originalRetVal</code> and 16729 * <code>Y.Do.currentRetVal</code> will be populated for reference.</p> 16730 * 16731 * @method after 16732 * @param fn {Function} the function to execute 16733 * @param obj the object hosting the method to displace 16734 * @param sFn {string} the name of the method to displace 16735 * @param c The execution context for fn 16736 * @param arg* {mixed} 0..n additional arguments to supply to the subscriber 16737 * @return {EventHandle} handle for the subscription 16738 * @static 16739 */ 16740 after: function(fn, obj, sFn, c) { 16741 var f = fn, a; 16742 if (c) { 16743 a = [fn, c].concat(Y.Array(arguments, 4, true)); 16744 f = Y.rbind.apply(Y, a); 16745 } 16746 16747 return this._inject(DO_AFTER, f, obj, sFn); 16748 }, 16749 16750 /** 16751 * Execute the supplied method before or after the specified function. 16752 * Used by <code>before</code> and <code>after</code>. 16753 * 16754 * @method _inject 16755 * @param when {string} before or after 16756 * @param fn {Function} the function to execute 16757 * @param obj the object hosting the method to displace 16758 * @param sFn {string} the name of the method to displace 16759 * @param c The execution context for fn 16760 * @return {EventHandle} handle for the subscription 16761 * @private 16762 * @static 16763 */ 16764 _inject: function(when, fn, obj, sFn) { 16765 // object id 16766 var id = Y.stamp(obj), o, sid; 16767 16768 if (!obj._yuiaop) { 16769 // create a map entry for the obj if it doesn't exist, to hold overridden methods 16770 obj._yuiaop = {}; 16771 } 16772 16773 o = obj._yuiaop; 16774 16775 if (!o[sFn]) { 16776 // create a map entry for the method if it doesn't exist 16777 o[sFn] = new Y.Do.Method(obj, sFn); 16778 16779 // re-route the method to our wrapper 16780 obj[sFn] = function() { 16781 return o[sFn].exec.apply(o[sFn], arguments); 16782 }; 16783 } 16784 16785 // subscriber id 16786 sid = id + Y.stamp(fn) + sFn; 16787 16788 // register the callback 16789 o[sFn].register(sid, fn, when); 16790 16791 return new Y.EventHandle(o[sFn], sid); 16792 }, 16793 16794 /** 16795 * Detach a before or after subscription. 16796 * 16797 * @method detach 16798 * @param handle {EventHandle} the subscription handle 16799 * @static 16800 */ 16801 detach: function(handle) { 16802 if (handle.detach) { 16803 handle.detach(); 16804 } 16805 } 16806}; 16807 16808Y.Do = DO; 16809 16810////////////////////////////////////////////////////////////////////////// 16811 16812/** 16813 * Contains the return value from the wrapped method, accessible 16814 * by 'after' event listeners. 16815 * 16816 * @property originalRetVal 16817 * @static 16818 * @since 3.2.0 16819 */ 16820
16821/** 16822 * Contains the current state of the return value, consumable by 16823 * 'after' event listeners, and updated if an after subscriber 16824 * changes the return value generated by the wrapped function. 16825 * 16826 * @property currentRetVal 16827 * @static 16828 * @since 3.2.0 16829 */ 16830 16831////////////////////////////////////////////////////////////////////////// 16832 16833/** 16834 * Wrapper for a displaced method with aop enabled 16835 * @class Do.Method 16836 * @constructor 16837 * @param obj The object to operate on 16838 * @param sFn The name of the method to displace 16839 */ 16840DO.Method = function(obj, sFn) { 16841 this.obj = obj; 16842 this.methodName = sFn; 16843 this.method = obj[sFn]; 16844 this.before = {}; 16845 this.after = {}; 16846}; 16847 16848/** 16849 * Register a aop subscriber 16850 * @method register 16851 * @param sid {string} the subscriber id 16852 * @param fn {Function} the function to execute 16853 * @param when {string} when to execute the function 16854 */ 16855DO.Method.prototype.register = function (sid, fn, when) { 16856 if (when) { 16857 this.after[sid] = fn; 16858 } else { 16859 this.before[sid] = fn; 16860 } 16861}; 16862 16863/** 16864 * Unregister a aop subscriber 16865 * @method delete 16866 * @param sid {string} the subscriber id 16867 * @param fn {Function} the function to execute 16868 * @param when {string} when to execute the function 16869 */ 16870DO.Method.prototype._delete = function (sid) { 16871 delete this.before[sid]; 16872 delete this.after[sid]; 16873}; 16874 16875/** 16876 * <p>Execute the wrapped method. All arguments are passed into the wrapping 16877 * functions. If any of the before wrappers return an instance of 16878 * <code>Y.Do.Halt</code> or <code>Y.Do.Prevent</code>, neither the wrapped 16879 * function nor any after phase subscribers will be executed.</p> 16880 * 16881 * <p>The return value will be the return value of the wrapped function or one 16882 * provided by a wrapper function via an instance of <code>Y.Do.Halt</code> or 16883 * <code>Y.Do.AlterReturn</code>. 16884 * 16885 * @method exec 16886 * @param arg* {any} Arguments are passed to the wrapping and wrapped functions 16887 * @return {any} Return value of wrapped function unless overwritten (see above) 16888 */ 16889DO.Method.prototype.exec = function () { 16890 16891 var args = Y.Array(arguments, 0, true), 16892 i, ret, newRet, 16893 bf = this.before, 16894 af = this.after, 16895 prevented = false; 16896 16897 // execute before 16898 for (i in bf) { 16899 if (bf.hasOwnProperty(i)) { 16900 ret = bf[i].apply(this.obj, args); 16901 if (ret) { 16902 switch (ret.constructor) { 16903 case DO.Halt: 16904 return ret.retVal; 16905 case DO.AlterArgs: 16906 args = ret.newArgs; 16907 break; 16908 case DO.Prevent: 16909 prevented = true; 16910 break; 16911 default: 16912 } 16913 } 16914 } 16915 } 16916 16917 // execute method 16918 if (!prevented) { 16919 ret = this.method.apply(this.obj, args); 16920 } 16921 16922 DO.originalRetVal = ret; 16923 DO.currentRetVal = ret; 16924 16925 // execute after methods. 16926 for (i in af) { 16927 if (af.hasOwnProperty(i)) { 16928 newRet = af[i].apply(this.obj, args); 16929 // Stop processing if a Halt object is returned 16930 if (newRet && newRet.constructor === DO.Halt) { 16931 return newRet.retVal; 16932 // Check for a new return value 16933 } else if (newRet && newRet.constructor === DO.AlterReturn) { 16934 ret = newRet.newRetVal; 16935 // Update the static retval state 16936 DO.currentRetVal = ret; 16937 } 16938 } 16939 } 16940 16941 return ret; 16942}; 16943 16944////////////////////////////////////////////////////////////////////////// 16945 16946/** 16947 * Return an AlterArgs object when you want to change the arguments that 16948 * were passed into the function. Useful for Do.before subscribers. An 16949 * example would be a service that scrubs out illegal characters prior to 16950 * executing the core business logic. 16951 * @class Do.AlterArgs 16952 * @constructor 16953 * @param msg {String} (optional) Explanation of the altered return value 16954 * @param newArgs {Array} Call parameters to be used for the original method 16955 * instead of the arguments originally passed in. 16956 */ 16957DO.AlterArgs = function(msg, newArgs) { 16958 this.msg = msg; 16959 this.newArgs = newArgs; 16960}; 16961 16962/** 16963 * Return an AlterReturn object when you want to change the result returned 16964 * from the core method to the caller. Useful for Do.after subscribers. 16965 * @class Do.AlterReturn 16966 * @constructor 16967 * @param msg {String} (optional) Explanation of the altered return value 16968 * @param newRetVal {any} Return value passed to code that invoked the wrapped 16969 * function. 16970 */ 16971DO.AlterReturn = function(msg, newRetVal) { 16972 this.msg = msg; 16973 this.newRetVal = newRetVal; 16974}; 16975 16976/** 16977 * Return a Halt object when you want to terminate the execution 16978 * of all subsequent subscribers as well as the wrapped method 16979 * if it has not exectued yet. Useful for Do.before subscribers. 16980 * @class Do.Halt 16981 * @constructor 16982 * @param msg {String} (optional) Explanation of why the termination was done 16983 * @param retVal {any} Return value passed to code that invoked the wrapped 16984 * function. 16985 */ 16986DO.Halt = function(msg, retVal) { 16987 this.msg = msg; 16988 this.retVal = retVal; 16989}; 16990 16991/** 16992 * Return a Prevent object when you want to prevent the wrapped function 16993 * from executing, but want the remaining listeners to execute. Useful 16994 * for Do.before subscribers. 16995 * @class Do.Prevent 16996 * @constructor 16997 * @param msg {String} (optional) Explanation of why the termination was done 16998 */ 16999DO.Prevent = function(msg) { 17000 this.msg = msg; 17001}; 17002 17003/** 17004 * Return an Error object when you want to terminate the execution 17005 * of all subsequent method calls. 17006 * @class Do.Error 17007 * @constructor 17008 * @param msg {String} (optional) Explanation of the altered return value 17009 * @param retVal {any} Return value passed to code that invoked the wrapped 17010 * function. 17011 * @deprecated use Y.Do.Halt or Y.Do.Prevent 17012 */ 17013DO.Error = DO.Halt; 17014 17015
17016////////////////////////////////////////////////////////////////////////// 17017 17018/** 17019 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 17020 * events. 17021 * @module event-custom 17022 * @submodule event-custom-base 17023 */ 17024 17025 17026// var onsubscribeType = "_event:onsub", 17027var YArray = Y.Array, 17028 17029 AFTER = 'after', 17030 CONFIGS = [ 17031 'broadcast', 17032 'monitored', 17033 'bubbles', 17034 'context', 17035 'contextFn', 17036 'currentTarget', 17037 'defaultFn', 17038 'defaultTargetOnly', 17039 'details', 17040 'emitFacade', 17041 'fireOnce', 17042 'async', 17043 'host', 17044 'preventable', 17045 'preventedFn', 17046 'queuable', 17047 'silent', 17048 'stoppedFn', 17049 'target', 17050 'type' 17051 ], 17052 17053 CONFIGS_HASH = YArray.hash(CONFIGS), 17054 17055 nativeSlice = Array.prototype.slice, 17056 17057 YUI3_SIGNATURE = 9, 17058 YUI_LOG = 'yui:log', 17059 17060 mixConfigs = function(r, s, ov) { 17061 var p; 17062 17063 for (p in s) { 17064 if (CONFIGS_HASH[p] && (ov || !(p in r))) { 17065 r[p] = s[p]; 17066 } 17067 } 17068 17069 return r; 17070 }; 17071 17072/** 17073 * The CustomEvent class lets you define events for your application 17074 * that can be subscribed to by one or more independent component. 17075 * 17076 * @param {String} type The type of event, which is passed to the callback 17077 * when the event fires. 17078 * @param {object} defaults configuration object. 17079 * @class CustomEvent 17080 * @constructor 17081 */ 17082 17083 /** 17084 * The type of event, returned to subscribers when the event fires 17085 * @property type 17086 * @type string 17087 */ 17088 17089/** 17090 * By default all custom events are logged in the debug build, set silent 17091 * to true to disable debug outpu for this event. 17092 * @property silent 17093 * @type boolean 17094 */ 17095 17096Y.CustomEvent = function(type, defaults) { 17097 17098 this._kds = Y.CustomEvent.keepDeprecatedSubs; 17099 17100 this.id = Y.guid(); 17101 17102 this.type = type; 17103 this.silent = this.logSystem = (type === YUI_LOG); 17104 17105 if (this._kds) { 17106 /** 17107 * The subscribers to this event 17108 * @property subscribers 17109 * @type Subscriber {} 17110 * @deprecated 17111 */ 17112 17113 /** 17114 * 'After' subscribers 17115 * @property afters 17116 * @type Subscriber {} 17117 * @deprecated 17118 */ 17119 this.subscribers = {}; 17120 this.afters = {}; 17121 } 17122 17123 if (defaults) { 17124 mixConfigs(this, defaults, true); 17125 } 17126}; 17127 17128/** 17129 * Static flag to enable population of the <a href="#property_subscribers">`subscribers`</a> 17130 * and <a href="#property_subscribers">`afters`</a> properties held on a `CustomEvent` instance. 17131 * 17132 * These properties were changed to private properties (`_subscribers` and `_afters`), and 17133 * converted from objects to arrays for performance reasons. 17134 * 17135 * Setting this property to true will populate the deprecated `subscribers` and `afters` 17136 * properties for people who may be using them (which is expected to be rare). There will 17137 * be a performance hit, compared to the new array based implementation. 17138 * 17139 * If you are using these deprecated properties for a use case which the public API 17140 * does not support, please file an enhancement request, and we can provide an alternate 17141 * public implementation which doesn't have the performance cost required to maintiain the 17142 * properties as objects. 17143 * 17144 * @property keepDeprecatedSubs 17145 * @static 17146 * @for CustomEvent 17147 * @type boolean 17148 * @default false 17149 * @deprecated 17150 */ 17151Y.CustomEvent.keepDeprecatedSubs = false; 17152 17153Y.CustomEvent.mixConfigs = mixConfigs; 17154 17155Y.CustomEvent.prototype = { 17156 17157 constructor: Y.CustomEvent, 17158 17159 /** 17160 * Monitor when an event is attached or detached. 17161 * 17162 * @property monitored 17163 * @type boolean 17164 */ 17165 17166 /** 17167 * If 0, this event does not broadcast. If 1, the YUI instance is notified 17168 * every time this event fires. If 2, the YUI instance and the YUI global 17169 * (if event is enabled on the global) are notified every time this event 17170 * fires. 17171 * @property broadcast 17172 * @type int 17173 */ 17174 17175 /** 17176 * Specifies whether this event should be queued when the host is actively 17177 * processing an event. This will effect exectution order of the callbacks 17178 * for the various events. 17179 * @property queuable 17180 * @type boolean 17181 * @default false 17182 */ 17183 17184 /** 17185 * This event has fired if true 17186 * 17187 * @property fired 17188 * @type boolean 17189 * @default false; 17190 */ 17191 17192 /** 17193 * An array containing the arguments the custom event 17194 * was last fired with. 17195 * @property firedWith 17196 * @type Array 17197 */ 17198 17199 /** 17200 * This event should only fire one time if true, and if 17201 * it has fired, any new subscribers should be notified 17202 * immediately. 17203 * 17204 * @property fireOnce 17205 * @type boolean 17206 * @default false; 17207 */ 17208 17209 /** 17210 * fireOnce listeners will fire syncronously unless async 17211 * is set to true 17212 * @property async 17213 * @type boolean 17214 * @default false 17215 */ 17216 17217 /** 17218 * Flag for stopPropagation that is modified during fire() 17219 * 1 means to stop propagation to bubble targets. 2 means
17220 * to also stop additional subscribers on this target. 17221 * @property stopped 17222 * @type int 17223 */ 17224 17225 /** 17226 * Flag for preventDefault that is modified during fire(). 17227 * if it is not 0, the default behavior for this event 17228 * @property prevented 17229 * @type int 17230 */ 17231 17232 /** 17233 * Specifies the host for this custom event. This is used 17234 * to enable event bubbling 17235 * @property host 17236 * @type EventTarget 17237 */ 17238 17239 /** 17240 * The default function to execute after event listeners 17241 * have fire, but only if the default action was not 17242 * prevented. 17243 * @property defaultFn 17244 * @type Function 17245 */ 17246 17247 /** 17248 * Flag for the default function to execute only if the 17249 * firing event is the current target. This happens only 17250 * when using custom event delegation and setting the 17251 * flag to `true` mimics the behavior of event delegation 17252 * in the DOM. 17253 * 17254 * @property defaultTargetOnly 17255 * @type Boolean 17256 * @default false 17257 */ 17258 17259 /** 17260 * The function to execute if a subscriber calls 17261 * stopPropagation or stopImmediatePropagation 17262 * @property stoppedFn 17263 * @type Function 17264 */ 17265 17266 /** 17267 * The function to execute if a subscriber calls 17268 * preventDefault 17269 * @property preventedFn 17270 * @type Function 17271 */ 17272 17273 /** 17274 * The subscribers to this event 17275 * @property _subscribers 17276 * @type Subscriber [] 17277 * @private 17278 */ 17279 17280 /** 17281 * 'After' subscribers 17282 * @property _afters 17283 * @type Subscriber [] 17284 * @private 17285 */ 17286 17287 /** 17288 * If set to true, the custom event will deliver an EventFacade object 17289 * that is similar to a DOM event object. 17290 * @property emitFacade 17291 * @type boolean 17292 * @default false 17293 */ 17294 17295 /** 17296 * Supports multiple options for listener signatures in order to 17297 * port YUI 2 apps. 17298 * @property signature 17299 * @type int 17300 * @default 9 17301 */ 17302 signature : YUI3_SIGNATURE, 17303 17304 /** 17305 * The context the the event will fire from by default. Defaults to the YUI 17306 * instance. 17307 * @property context 17308 * @type object 17309 */ 17310 context : Y, 17311 17312 /** 17313 * Specifies whether or not this event's default function 17314 * can be cancelled by a subscriber by executing preventDefault() 17315 * on the event facade 17316 * @property preventable 17317 * @type boolean 17318 * @default true 17319 */ 17320 preventable : true, 17321 17322 /** 17323 * Specifies whether or not a subscriber can stop the event propagation 17324 * via stopPropagation(), stopImmediatePropagation(), or halt() 17325 * 17326 * Events can only bubble if emitFacade is true. 17327 * 17328 * @property bubbles 17329 * @type boolean 17330 * @default true 17331 */ 17332 bubbles : true, 17333 17334 /** 17335 * Returns the number of subscribers for this event as the sum of the on() 17336 * subscribers and after() subscribers. 17337 * 17338 * @method hasSubs 17339 * @return Number 17340 */ 17341 hasSubs: function(when) { 17342 var s = 0, 17343 a = 0, 17344 subs = this._subscribers, 17345 afters = this._afters, 17346 sib = this.sibling; 17347 17348 if (subs) { 17349 s = subs.length; 17350 } 17351 17352 if (afters) { 17353 a = afters.length; 17354 } 17355 17356 if (sib) { 17357 subs = sib._subscribers; 17358 afters = sib._afters; 17359 17360 if (subs) { 17361 s += subs.length; 17362 } 17363 17364 if (afters) { 17365 a += afters.length; 17366 } 17367 } 17368 17369 if (when) { 17370 return (when === 'after') ? a : s; 17371 } 17372 17373 return (s + a); 17374 }, 17375 17376 /** 17377 * Monitor the event state for the subscribed event. The first parameter 17378 * is what should be monitored, the rest are the normal parameters when 17379 * subscribing to an event. 17380 * @method monitor 17381 * @param what {string} what to monitor ('detach', 'attach', 'publish'). 17382 * @return {EventHandle} return value from the monitor event subscription. 17383 */ 17384 monitor: function(what) { 17385 this.monitored = true; 17386 var type = this.id + '|' + this.type + '_' + what, 17387 args = nativeSlice.call(arguments, 0); 17388 args[0] = type;
17389 return this.host.on.apply(this.host, args); 17390 }, 17391 17392 /** 17393 * Get all of the subscribers to this event and any sibling event 17394 * @method getSubs 17395 * @return {Array} first item is the on subscribers, second the after. 17396 */ 17397 getSubs: function() { 17398 17399 var sibling = this.sibling, 17400 subs = this._subscribers, 17401 afters = this._afters, 17402 siblingSubs, 17403 siblingAfters; 17404 17405 if (sibling) { 17406 siblingSubs = sibling._subscribers; 17407 siblingAfters = sibling._afters; 17408 } 17409 17410 if (siblingSubs) { 17411 if (subs) { 17412 subs = subs.concat(siblingSubs); 17413 } else { 17414 subs = siblingSubs.concat(); 17415 } 17416 } else { 17417 if (subs) { 17418 subs = subs.concat(); 17419 } else { 17420 subs = []; 17421 } 17422 } 17423 17424 if (siblingAfters) { 17425 if (afters) { 17426 afters = afters.concat(siblingAfters); 17427 } else { 17428 afters = siblingAfters.concat(); 17429 } 17430 } else { 17431 if (afters) { 17432 afters = afters.concat(); 17433 } else { 17434 afters = []; 17435 } 17436 } 17437 17438 return [subs, afters]; 17439 }, 17440 17441 /** 17442 * Apply configuration properties. Only applies the CONFIG whitelist 17443 * @method applyConfig 17444 * @param o hash of properties to apply. 17445 * @param force {boolean} if true, properties that exist on the event 17446 * will be overwritten. 17447 */ 17448 applyConfig: function(o, force) { 17449 mixConfigs(this, o, force); 17450 }, 17451 17452 /** 17453 * Create the Subscription for subscribing function, context, and bound 17454 * arguments. If this is a fireOnce event, the subscriber is immediately 17455 * notified. 17456 * 17457 * @method _on 17458 * @param fn {Function} Subscription callback 17459 * @param [context] {Object} Override `this` in the callback 17460 * @param [args] {Array} bound arguments that will be passed to the callback after the arguments generated by fire() 17461 * @param [when] {String} "after" to slot into after subscribers 17462 * @return {EventHandle} 17463 * @protected 17464 */ 17465 _on: function(fn, context, args, when) { 17466 17467 17468 var s = new Y.Subscriber(fn, context, args, when), 17469 firedWith; 17470 17471 if (this.fireOnce && this.fired) { 17472 17473 firedWith = this.firedWith; 17474 17475 // It's a little ugly for this to know about facades, 17476 // but given the current breakup, not much choice without 17477 // moving a whole lot of stuff around. 17478 if (this.emitFacade && this._addFacadeToArgs) { 17479 this._addFacadeToArgs(firedWith); 17480 } 17481 17482 if (this.async) { 17483 setTimeout(Y.bind(this._notify, this, s, firedWith), 0); 17484 } else { 17485 this._notify(s, firedWith); 17486 } 17487 } 17488 17489 if (when === AFTER) { 17490 if (!this._afters) { 17491 this._afters = []; 17492 } 17493 this._afters.push(s); 17494 } else { 17495 if (!this._subscribers) { 17496 this._subscribers = []; 17497 } 17498 this._subscribers.push(s); 17499 } 17500 17501 if (this._kds) { 17502 if (when === AFTER) { 17503 this.afters[s.id] = s; 17504 } else { 17505 this.subscribers[s.id] = s; 17506 } 17507 } 17508 17509 return new Y.EventHandle(this, s); 17510 }, 17511 17512 /** 17513 * Listen for this event 17514 * @method subscribe 17515 * @param {Function} fn The function to execute. 17516 * @return {EventHandle} Unsubscribe handle. 17517 * @deprecated use on. 17518 */ 17519 subscribe: function(fn, context) { 17520 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null; 17521 return this._on(fn, context, a, true); 17522 }, 17523 17524 /** 17525 * Listen for this event 17526 * @method on 17527 * @param {Function} fn The function to execute. 17528 * @param {object} context optional execution context. 17529 * @param {mixed} arg* 0..n additional arguments to supply to the subscriber 17530 * when the event fires. 17531 * @return {EventHandle} An object with a detach method to detch the handler(s). 17532 */ 17533 on: function(fn, context) { 17534 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null; 17535 17536 if (this.monitored && this.host) { 17537 this.host._monitor('attach', this, { 17538 args: arguments 17539 }); 17540 } 17541 return this._on(fn, context, a, true); 17542 }, 17543 17544 /** 17545 * Listen for this event after the normal subscribers have been notified and 17546 * the default behavior has been applied. If a normal subscriber prevents the 17547 * default behavior, it also prevents after listeners from firing. 17548 * @method after 17549 * @param {Function} fn The function to execute. 17550 * @param {object} context optional execution context. 17551 * @param {mixed} arg* 0..n additional arguments to supply to the subscriber 17552 * when the event fires. 17553 * @return {EventHandle} handle Unsubscribe handle. 17554 */ 17555 after: function(fn, context) { 17556 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null; 17557 return this._on(fn, context, a, AFTER); 17558 }, 17559 17560 /** 17561 * Detach listeners. 17562 * @method detach 17563 * @param {Function} fn The subscribed function to remove, if not supplied 17564 * all will be removed. 17565 * @param {Object} context The context object passed to subscribe. 17566 * @return {Number} returns the number of subscribers unsubscribed. 17567 */ 17568 detach: function(fn, context) { 17569 // unsubscribe handle 17570 if (fn && fn.detach) { 17571 return fn.detach(); 17572 } 17573 17574 var i, s, 17575 found = 0, 17576 subs = this._subscribers, 17577 afters = this._afters; 17578 17579 if (subs) { 17580 for (i = subs.length; i >= 0; i--) { 17581 s = subs[i]; 17582 if (s && (!fn || fn === s.fn)) { 17583 this._delete(s, subs, i); 17584 found++; 17585 } 17586 } 17587 } 17588 17589 if (afters) { 17590 for (i = afters.length; i >= 0; i--) { 17591 s = afters[i]; 17592 if (s && (!fn || fn === s.fn)) { 17593 this._delete(s, afters, i); 17594 found++; 17595 } 17596 } 17597 } 17598 17599 return found; 17600 }, 17601 17602 /** 17603 * Detach listeners. 17604 * @method unsubscribe 17605 * @param {Function} fn The subscribed function to remove, if not supplied 17606 * all will be removed. 17607 * @param {Object} context The context object passed to subscribe. 17608 * @return {int|undefined} returns the number of subscribers unsubscribed. 17609 * @deprecated use detach. 17610 */ 17611 unsubscribe: function() { 17612 return this.detach.apply(this, arguments); 17613 }, 17614 17615 /** 17616 * Notify a single subscriber 17617 * @method _notify 17618 * @param {Subscriber} s the subscriber. 17619 * @param {Array} args the arguments array to apply to the listener. 17620 * @protected 17621 */ 17622 _notify: function(s, args, ef) { 17623 17624 17625 var ret; 17626 17627 ret = s.notify(args, this); 17628 17629 if (false === ret || this.stopped > 1) { 17630 return false;
17631 } 17632 17633 return true; 17634 }, 17635 17636 /** 17637 * Logger abstraction to centralize the application of the silent flag 17638 * @method log 17639 * @param {string} msg message to log. 17640 * @param {string} cat log category. 17641 */ 17642 log: function(msg, cat) { 17643 }, 17644 17645 /** 17646 * Notifies the subscribers. The callback functions will be executed 17647 * from the context specified when the event was created, and with the 17648 * following parameters: 17649 * <ul> 17650 * <li>The type of event</li> 17651 * <li>All of the arguments fire() was executed with as an array</li> 17652 * <li>The custom object (if any) that was passed into the subscribe() 17653 * method</li> 17654 * </ul> 17655 * @method fire 17656 * @param {Object*} arguments an arbitrary set of parameters to pass to 17657 * the handler. 17658 * @return {boolean} false if one of the subscribers returned false, 17659 * true otherwise. 17660 * 17661 */ 17662 fire: function() { 17663 17664 // push is the fastest way to go from arguments to arrays 17665 // for most browsers currently 17666 // http://jsperf.com/push-vs-concat-vs-slice/2 17667 17668 var args = []; 17669 args.push.apply(args, arguments); 17670 17671 return this._fire(args); 17672 }, 17673 17674 /** 17675 * Private internal implementation for `fire`, which is can be used directly by 17676 * `EventTarget` and other event module classes which have already converted from 17677 * an `arguments` list to an array, to avoid the repeated overhead. 17678 * 17679 * @method _fire 17680 * @private 17681 * @param {Array} args The array of arguments passed to be passed to handlers. 17682 * @return {boolean} false if one of the subscribers returned false, true otherwise. 17683 */ 17684 _fire: function(args) { 17685 17686 if (this.fireOnce && this.fired) { 17687 return true; 17688 } else { 17689 17690 // this doesn't happen if the event isn't published 17691 // this.host._monitor('fire', this.type, args); 17692 17693 this.fired = true; 17694 17695 if (this.fireOnce) { 17696 this.firedWith = args; 17697 } 17698 17699 if (this.emitFacade) { 17700 return this.fireComplex(args); 17701 } else { 17702 return this.fireSimple(args); 17703 } 17704 } 17705 }, 17706 17707 /** 17708 * Set up for notifying subscribers of non-emitFacade events. 17709 * 17710 * @method fireSimple 17711 * @param args {Array} Arguments passed to fire() 17712 * @return Boolean false if a subscriber returned false 17713 * @protected 17714 */ 17715 fireSimple: function(args) { 17716 this.stopped = 0; 17717 this.prevented = 0; 17718 if (this.hasSubs()) { 17719 var subs = this.getSubs(); 17720 this._procSubs(subs[0], args); 17721 this._procSubs(subs[1], args); 17722 } 17723 if (this.broadcast) { 17724 this._broadcast(args); 17725 } 17726 return this.stopped ? false : true; 17727 }, 17728 17729 // Requires the event-custom-complex module for full funcitonality. 17730 fireComplex: function(args) { 17731 args[0] = args[0] || {}; 17732 return this.fireSimple(args); 17733 }, 17734 17735 /** 17736 * Notifies a list of subscribers. 17737 * 17738 * @method _procSubs 17739 * @param subs {Array} List of subscribers 17740 * @param args {Array} Arguments passed to fire() 17741 * @param ef {} 17742 * @return Boolean false if a subscriber returns false or stops the event 17743 * propagation via e.stopPropagation(), 17744 * e.stopImmediatePropagation(), or e.halt() 17745 * @private 17746 */ 17747 _procSubs: function(subs, args, ef) { 17748 var s, i, l; 17749 17750 for (i = 0, l = subs.length; i < l; i++) { 17751 s = subs[i]; 17752 if (s && s.fn) { 17753 if (false === this._notify(s, args, ef)) { 17754 this.stopped = 2; 17755 } 17756 if (this.stopped === 2) { 17757 return false; 17758 } 17759 } 17760 } 17761 17762 return true; 17763 }, 17764 17765 /** 17766 * Notifies the YUI instance if the event is configured with broadcast = 1, 17767 * and both the YUI instance and Y.Global if configured with broadcast = 2. 17768 * 17769 * @method _broadcast 17770 * @param args {Array} Arguments sent to fire() 17771 * @private 17772 */ 17773 _broadcast: function(args) { 17774 if (!this.stopped && this.broadcast) { 17775 17776 var a = args.concat(); 17777 a.unshift(this.type); 17778 17779 if (this.host !== Y) { 17780 Y.fire.apply(Y, a); 17781 } 17782 17783 if (this.broadcast === 2) { 17784 Y.Global.fire.apply(Y.Global, a); 17785 } 17786 } 17787 }, 17788 17789 /** 17790 * Removes all listeners 17791 * @method unsubscribeAll 17792 * @return {Number} The number of listeners unsubscribed. 17793 * @deprecated use detachAll. 17794 */ 17795 unsubscribeAll: function() { 17796 return this.detachAll.apply(this, arguments); 17797 }, 17798 17799 /** 17800 * Removes all listeners 17801 * @method detachAll 17802 * @return {Number} The number of listeners unsubscribed. 17803 */ 17804 detachAll: function() { 17805 return this.detach(); 17806 }, 17807 17808 /** 17809 * Deletes the subscriber from the internal store of on() and after() 17810 * subscribers. 17811 * 17812 * @method _delete 17813 * @param s subscriber object. 17814 * @param subs (optional) on or after subscriber array 17815 * @param index (optional) The index found. 17816 * @private 17817 */ 17818 _delete: function(s, subs, i) { 17819 var when = s._when; 17820 17821 if (!subs) { 17822 subs = (when === AFTER) ? this._afters : this._subscribers; 17823 } 17824 17825 if (subs) { 17826 i = YArray.indexOf(subs, s, 0); 17827 17828 if (s && subs[i] === s) { 17829 subs.splice(i, 1); 17830 } 17831 } 17832 17833 if (this._kds) { 17834 if (when === AFTER) { 17835 delete this.afters[s.id]; 17836 } else { 17837 delete this.subscribers[s.id]; 17838 } 17839 } 17840 17841 if (this.monitored && this.host) { 17842 this.host._monitor('detach', this, { 17843 ce: this, 17844 sub: s 17845 }); 17846 } 17847 17848 if (s) { 17849 s.deleted = true; 17850 } 17851 } 17852}; 17853/** 17854 * Stores the subscriber information to be used when the event fires. 17855 * @param {Function} fn The wrapped function to execute. 17856 * @param {Object} context The value of the keyword 'this' in the listener. 17857 * @param {Array} args* 0..n additional arguments to supply the listener. 17858 * 17859 * @class Subscriber 17860 * @constructor 17861 */ 17862Y.Subscriber = function(fn, context, args, when) { 17863 17864 /** 17865 * The callback that will be execute when the event fires 17866 * This is wrapped by Y.rbind if obj was supplied.
17867 * @property fn 17868 * @type Function 17869 */ 17870 this.fn = fn; 17871 17872 /** 17873 * Optional 'this' keyword for the listener 17874 * @property context 17875 * @type Object 17876 */ 17877 this.context = context; 17878 17879 /** 17880 * Unique subscriber id 17881 * @property id 17882 * @type String 17883 */ 17884 this.id = Y.guid(); 17885 17886 /** 17887 * Additional arguments to propagate to the subscriber 17888 * @property args 17889 * @type Array 17890 */ 17891 this.args = args; 17892 17893 this._when = when; 17894 17895 /** 17896 * Custom events for a given fire transaction. 17897 * @property events 17898 * @type {EventTarget} 17899 */ 17900 // this.events = null; 17901 17902 /** 17903 * This listener only reacts to the event once 17904 * @property once 17905 */ 17906 // this.once = false; 17907 17908}; 17909 17910Y.Subscriber.prototype = { 17911 constructor: Y.Subscriber, 17912 17913 _notify: function(c, args, ce) { 17914 if (this.deleted && !this.postponed) { 17915 if (this.postponed) { 17916 delete this.fn; 17917 delete this.context; 17918 } else { 17919 delete this.postponed; 17920 return null; 17921 } 17922 } 17923 var a = this.args, ret; 17924 switch (ce.signature) { 17925 case 0: 17926 ret = this.fn.call(c, ce.type, args, c); 17927 break; 17928 case 1: 17929 ret = this.fn.call(c, args[0] || null, c); 17930 break; 17931 default: 17932 if (a || args) { 17933 args = args || []; 17934 a = (a) ? args.concat(a) : args; 17935 ret = this.fn.apply(c, a); 17936 } else { 17937 ret = this.fn.call(c); 17938 } 17939 } 17940 17941 if (this.once) { 17942 ce._delete(this); 17943 } 17944 17945 return ret; 17946 }, 17947 17948 /** 17949 * Executes the subscriber. 17950 * @method notify 17951 * @param args {Array} Arguments array for the subscriber. 17952 * @param ce {CustomEvent} The custom event that sent the notification. 17953 */ 17954 notify: function(args, ce) { 17955 var c = this.context, 17956 ret = true; 17957 17958 if (!c) { 17959 c = (ce.contextFn) ? ce.contextFn() : ce.context; 17960 } 17961 17962 // only catch errors if we will not re-throw them. 17963 if (Y.config && Y.config.throwFail) { 17964 ret = this._notify(c, args, ce); 17965 } else { 17966 try { 17967 ret = this._notify(c, args, ce); 17968 } catch (e) { 17969 Y.error(this + ' failed: ' + e.message, e); 17970 } 17971 } 17972 17973 return ret; 17974 }, 17975 17976 /** 17977 * Returns true if the fn and obj match this objects properties. 17978 * Used by the unsubscribe method to match the right subscriber. 17979 * 17980 * @method contains 17981 * @param {Function} fn the function to execute. 17982 * @param {Object} context optional 'this' keyword for the listener. 17983 * @return {boolean} true if the supplied arguments match this 17984 * subscriber's signature. 17985 */ 17986 contains: function(fn, context) { 17987 if (context) { 17988 return ((this.fn === fn) && this.context === context); 17989 } else { 17990 return (this.fn === fn); 17991 } 17992 }, 17993 17994 valueOf : function() { 17995 return this.id; 17996 } 17997 17998}; 17999/** 18000 * Return value from all subscribe operations 18001 * @class EventHandle 18002 * @constructor 18003 * @param {CustomEvent} evt the custom event. 18004 * @param {Subscriber} sub the subscriber. 18005 */ 18006Y.EventHandle = function(evt, sub) { 18007 18008 /** 18009 * The custom event 18010 * 18011 * @property evt 18012 * @type CustomEvent 18013 */ 18014 this.evt = evt; 18015 18016 /** 18017 * The subscriber object 18018 * 18019 * @property sub 18020 * @type Subscriber 18021 */ 18022 this.sub = sub; 18023}; 18024 18025Y.EventHandle.prototype = { 18026 batch: function(f, c) { 18027 f.call(c || this, this); 18028 if (Y.Lang.isArray(this.evt)) { 18029 Y.Array.each(this.evt, function(h) { 18030 h.batch.call(c || h, f); 18031 }); 18032 } 18033 }, 18034 18035 /** 18036 * Detaches this subscriber 18037 * @method detach 18038 * @return {Number} the number of detached listeners 18039 */ 18040 detach: function() { 18041 var evt = this.evt, detached = 0, i; 18042 if (evt) { 18043 if (Y.Lang.isArray(evt)) { 18044 for (i = 0; i < evt.length; i++) { 18045 detached += evt[i].detach(); 18046 } 18047 } else { 18048 evt._delete(this.sub); 18049 detached = 1; 18050 } 18051 18052 } 18053 18054 return detached; 18055 }, 18056 18057 /** 18058 * Monitor the event state for the subscribed event. The first parameter 18059 * is what should be monitored, the rest are the normal parameters when 18060 * subscribing to an event. 18061 * @method monitor 18062 * @param what {string} what to monitor ('attach', 'detach', 'publish'). 18063 * @return {EventHandle} return value from the monitor event subscription. 18064 */ 18065 monitor: function(what) { 18066 return this.evt.monitor.apply(this.evt, arguments); 18067 } 18068}; 18069 18070/** 18071 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 18072 * events. 18073 * @module event-custom 18074 * @submodule event-custom-base 18075 */ 18076 18077/** 18078 * EventTarget provides the implementation for any object to 18079 * publish, subscribe and fire to custom events, and also 18080 * alows other EventTargets to target the object with events 18081 * sourced from the other object. 18082 * EventTarget is designed to be used with Y.augment to wrap 18083 * EventCustom in an interface that allows events to be listened to
18084 * and fired by name. This makes it possible for implementing code to 18085 * subscribe to an event that either has not been created yet, or will 18086 * not be created at all. 18087 * @class EventTarget 18088 * @param opts a configuration object 18089 * @config emitFacade {boolean} if true, all events will emit event 18090 * facade payloads by default (default false) 18091 * @config prefix {String} the prefix to apply to non-prefixed event names 18092 */ 18093 18094var L = Y.Lang, 18095 PREFIX_DELIMITER = ':', 18096 CATEGORY_DELIMITER = '|', 18097 AFTER_PREFIX = '~AFTER~', 18098 WILD_TYPE_RE = /(.*?)(:)(.*?)/, 18099 18100 _wildType = Y.cached(function(type) { 18101 return type.replace(WILD_TYPE_RE, "*$2$3"); 18102 }), 18103 18104 /** 18105 * If the instance has a prefix attribute and the 18106 * event type is not prefixed, the instance prefix is 18107 * applied to the supplied type. 18108 * @method _getType 18109 * @private 18110 */ 18111 _getType = function(type, pre) { 18112 18113 if (!pre || (typeof type !== "string") || type.indexOf(PREFIX_DELIMITER) > -1) { 18114 return type; 18115 } 18116 18117 return pre + PREFIX_DELIMITER + type; 18118 }, 18119 18120 /** 18121 * Returns an array with the detach key (if provided), 18122 * and the prefixed event name from _getType 18123 * Y.on('detachcategory| menu:click', fn) 18124 * @method _parseType 18125 * @private 18126 */ 18127 _parseType = Y.cached(function(type, pre) { 18128 18129 var t = type, detachcategory, after, i; 18130 18131 if (!L.isString(t)) { 18132 return t; 18133 } 18134 18135 i = t.indexOf(AFTER_PREFIX); 18136 18137 if (i > -1) { 18138 after = true; 18139 t = t.substr(AFTER_PREFIX.length); 18140 } 18141 18142 i = t.indexOf(CATEGORY_DELIMITER); 18143 18144 if (i > -1) { 18145 detachcategory = t.substr(0, (i)); 18146 t = t.substr(i+1); 18147 if (t === '*') { 18148 t = null; 18149 } 18150 } 18151 18152 // detach category, full type with instance prefix, is this an after listener, short type 18153 return [detachcategory, (pre) ? _getType(t, pre) : t, after, t]; 18154 }), 18155 18156 ET = function(opts) { 18157 18158 var etState = this._yuievt, 18159 etConfig; 18160 18161 if (!etState) { 18162 etState = this._yuievt = { 18163 events: {}, // PERF: Not much point instantiating lazily. We're bound to have events 18164 targets: null, // PERF: Instantiate lazily, if user actually adds target, 18165 config: { 18166 host: this, 18167 context: this 18168 }, 18169 chain: Y.config.chain 18170 }; 18171 } 18172 18173 etConfig = etState.config; 18174 18175 if (opts) { 18176 mixConfigs(etConfig, opts, true); 18177 18178 if (opts.chain !== undefined) { 18179 etState.chain = opts.chain; 18180 } 18181 18182 if (opts.prefix) { 18183 etConfig.prefix = opts.prefix; 18184 } 18185 } 18186 }; 18187 18188ET.prototype = { 18189 18190 constructor: ET, 18191 18192 /** 18193 * Listen to a custom event hosted by this object one time. 18194 * This is the equivalent to <code>on</code> except the 18195 * listener is immediatelly detached when it is executed. 18196 * @method once 18197 * @param {String} type The name of the event 18198 * @param {Function} fn The callback to execute in response to the event 18199 * @param {Object} [context] Override `this` object in callback 18200 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 18201 * @return {EventHandle} A subscription handle capable of detaching the 18202 * subscription 18203 */ 18204 once: function() { 18205 var handle = this.on.apply(this, arguments); 18206 handle.batch(function(hand) { 18207 if (hand.sub) { 18208 hand.sub.once = true; 18209 } 18210 }); 18211 return handle; 18212 }, 18213 18214 /** 18215 * Listen to a custom event hosted by this object one time. 18216 * This is the equivalent to <code>after</code> except the 18217 * listener is immediatelly detached when it is executed. 18218 * @method onceAfter 18219 * @param {String} type The name of the event 18220 * @param {Function} fn The callback to execute in response to the event 18221 * @param {Object} [context] Override `this` object in callback 18222 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 18223 * @return {EventHandle} A subscription handle capable of detaching that 18224 * subscription 18225 */ 18226 onceAfter: function() { 18227 var handle = this.after.apply(this, arguments); 18228 handle.batch(function(hand) { 18229 if (hand.sub) { 18230 hand.sub.once = true; 18231 } 18232 }); 18233 return handle; 18234 }, 18235 18236 /** 18237 * Takes the type parameter passed to 'on' and parses out the 18238 * various pieces that could be included in the type. If the 18239 * event type is passed without a prefix, it will be expanded 18240 * to include the prefix one is supplied or the event target 18241 * is configured with a default prefix. 18242 * @method parseType 18243 * @param {String} type the type 18244 * @param {String} [pre] The prefix. Defaults to this._yuievt.config.prefix 18245 * @since 3.3.0 18246 * @return {Array} an array containing: 18247 * * the detach category, if supplied, 18248 * * the prefixed event type, 18249 * * whether or not this is an after listener, 18250 * * the supplied event type 18251 */ 18252 parseType: function(type, pre) { 18253 return _parseType(type, pre || this._yuievt.config.prefix); 18254 }, 18255 18256 /** 18257 * Subscribe a callback function to a custom event fired by this object or 18258 * from an object that bubbles its events to this object. 18259 * 18260 * this.on("change", this._onChange, this); 18261 * 18262 * Callback functions for events published with `emitFacade = true` will 18263 * receive an `EventFacade` as the first argument (typically named "e"). 18264 * These callbacks can then call `e.preventDefault()` to disable the 18265 * behavior published to that event's `defaultFn`. See the `EventFacade` 18266 * API for all available properties and methods. Subscribers to 18267 * non-`emitFacade` events will receive the arguments passed to `fire()` 18268 * after the event name. 18269 * 18270 * To subscribe to multiple events at once, pass an object as the first 18271 * argument, where the key:value pairs correspond to the eventName:callback. 18272 * 18273 * this.on({ 18274 * "attrChange" : this._onAttrChange, 18275 * "change" : this._onChange 18276 * }); 18277 * 18278 * You can also pass an array of event names as the first argument to 18279 * subscribe to all listed events with the same callback. 18280 * 18281 * this.on([ "change", "attrChange" ], this._onChange); 18282 * 18283 * Returning `false` from a callback is supported as an alternative to 18284 * calling `e.preventDefault(); e.stopPropagation();`. However, it is 18285 * recommended to use the event methods whenever possible. 18286 * 18287 * @method on 18288 * @param {String} type The name of the event 18289 * @param {Function} fn The callback to execute in response to the event 18290 * @param {Object} [context] Override `this` object in callback 18291 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 18292 * @return {EventHandle} A subscription handle capable of detaching that 18293 * subscription 18294 */ 18295 on: function(type, fn, context) { 18296 18297 var yuievt = this._yuievt, 18298 parts = _parseType(type, yuievt.config.prefix), f, c, args, ret, ce, 18299 detachcategory, handle, store = Y.Env.evt.handles, after, adapt, shorttype, 18300 Node = Y.Node, n, domevent, isArr; 18301 18302 // full name, args, detachcategory, after 18303 this._monitor('attach', parts[1], { 18304 args: arguments, 18305 category: parts[0], 18306 after: parts[2] 18307 }); 18308 18309 if (L.isObject(type)) { 18310 18311 if (L.isFunction(type)) { 18312 return Y.Do.before.apply(Y.Do, arguments); 18313 } 18314 18315 f = fn; 18316 c = context; 18317 args = nativeSlice.call(arguments, 0); 18318 ret = []; 18319 18320 if (L.isArray(type)) { 18321 isArr = true; 18322 } 18323 18324 after = type._after; 18325 delete type._after; 18326 18327 Y.each(type, function(v, k) { 18328 18329 if (L.isObject(v)) { 18330 f = v.fn || ((L.isFunction(v)) ? v : f); 18331 c = v.context || c; 18332 } 18333 18334 var nv = (after) ? AFTER_PREFIX : ''; 18335 18336 args[0] = nv + ((isArr) ? v : k); 18337 args[1] = f; 18338 args[2] = c; 18339
18340 ret.push(this.on.apply(this, args)); 18341 18342 }, this); 18343 18344 return (yuievt.chain) ? this : new Y.EventHandle(ret); 18345 } 18346 18347 detachcategory = parts[0]; 18348 after = parts[2]; 18349 shorttype = parts[3]; 18350 18351 // extra redirection so we catch adaptor events too. take a look at this. 18352 if (Node && Y.instanceOf(this, Node) && (shorttype in Node.DOM_EVENTS)) { 18353 args = nativeSlice.call(arguments, 0); 18354 args.splice(2, 0, Node.getDOMNode(this)); 18355 return Y.on.apply(Y, args); 18356 } 18357 18358 type = parts[1]; 18359 18360 if (Y.instanceOf(this, YUI)) { 18361 18362 adapt = Y.Env.evt.plugins[type]; 18363 args = nativeSlice.call(arguments, 0); 18364 args[0] = shorttype; 18365 18366 if (Node) { 18367 n = args[2]; 18368 18369 if (Y.instanceOf(n, Y.NodeList)) { 18370 n = Y.NodeList.getDOMNodes(n); 18371 } else if (Y.instanceOf(n, Node)) { 18372 n = Node.getDOMNode(n); 18373 } 18374 18375 domevent = (shorttype in Node.DOM_EVENTS); 18376 18377 // Captures both DOM events and event plugins. 18378 if (domevent) { 18379 args[2] = n; 18380 } 18381 } 18382 18383 // check for the existance of an event adaptor 18384 if (adapt) { 18385 handle = adapt.on.apply(Y, args); 18386 } else if ((!type) || domevent) { 18387 handle = Y.Event._attach(args); 18388 } 18389 18390 } 18391 18392 if (!handle) { 18393 ce = yuievt.events[type] || this.publish(type); 18394 handle = ce._on(fn, context, (arguments.length > 3) ? nativeSlice.call(arguments, 3) : null, (after) ? 'after' : true); 18395 18396 // TODO: More robust regex, accounting for category 18397 if (type.indexOf("*:") !== -1) { 18398 this._hasSiblings = true; 18399 } 18400 } 18401 18402 if (detachcategory) { 18403 store[detachcategory] = store[detachcategory] || {}; 18404 store[detachcategory][type] = store[detachcategory][type] || []; 18405 store[detachcategory][type].push(handle); 18406 } 18407 18408 return (yuievt.chain) ? this : handle; 18409 18410 }, 18411 18412 /** 18413 * subscribe to an event 18414 * @method subscribe 18415 * @deprecated use on 18416 */ 18417 subscribe: function() { 18418 return this.on.apply(this, arguments); 18419 }, 18420 18421 /** 18422 * Detach one or more listeners the from the specified event 18423 * @method detach 18424 * @param type {string|Object} Either the handle to the subscriber or the 18425 * type of event. If the type 18426 * is not specified, it will attempt to remove 18427 * the listener from all hosted events. 18428 * @param fn {Function} The subscribed function to unsubscribe, if not 18429 * supplied, all subscribers will be removed. 18430 * @param context {Object} The custom object passed to subscribe. This is 18431 * optional, but if supplied will be used to 18432 * disambiguate multiple listeners that are the same 18433 * (e.g., you subscribe many object using a function 18434 * that lives on the prototype) 18435 * @return {EventTarget} the host 18436 */ 18437 detach: function(type, fn, context) { 18438 18439 var evts = this._yuievt.events, 18440 i, 18441 Node = Y.Node, 18442 isNode = Node && (Y.instanceOf(this, Node)); 18443 18444 // detachAll disabled on the Y instance. 18445 if (!type && (this !== Y)) { 18446 for (i in evts) { 18447 if (evts.hasOwnProperty(i)) { 18448 evts[i].detach(fn, context); 18449 } 18450 } 18451 if (isNode) { 18452 Y.Event.purgeElement(Node.getDOMNode(this)); 18453 } 18454 18455 return this; 18456 } 18457 18458 var parts = _parseType(type, this._yuievt.config.prefix), 18459 detachcategory = L.isArray(parts) ? parts[0] : null, 18460 shorttype = (parts) ? parts[3] : null, 18461 adapt, store = Y.Env.evt.handles, detachhost, cat, args, 18462 ce, 18463 18464 keyDetacher = function(lcat, ltype, host) { 18465 var handles = lcat[ltype], ce, i; 18466 if (handles) { 18467 for (i = handles.length - 1; i >= 0; --i) { 18468 ce = handles[i].evt; 18469 if (ce.host === host || ce.el === host) { 18470 handles[i].detach(); 18471 } 18472 } 18473 } 18474 }; 18475 18476 if (detachcategory) { 18477 18478 cat = store[detachcategory]; 18479 type = parts[1]; 18480 detachhost = (isNode) ? Y.Node.getDOMNode(this) : this; 18481 18482 if (cat) { 18483 if (type) { 18484 keyDetacher(cat, type, detachhost); 18485 } else { 18486 for (i in cat) { 18487 if (cat.hasOwnProperty(i)) { 18488 keyDetacher(cat, i, detachhost); 18489 } 18490 } 18491 } 18492 18493 return this; 18494 } 18495 18496 // If this is an event handle, use it to detach 18497 } else if (L.isObject(type) && type.detach) { 18498 type.detach(); 18499 return this; 18500 // extra redirection so we catch adaptor events too. take a look at this. 18501 } else if (isNode && ((!shorttype) || (shorttype in Node.DOM_EVENTS))) { 18502 args = nativeSlice.call(arguments, 0); 18503 args[2] = Node.getDOMNode(this); 18504 Y.detach.apply(Y, args); 18505 return this; 18506 } 18507 18508 adapt = Y.Env.evt.plugins[shorttype]; 18509 18510 // The YUI instance handles DOM events and adaptors 18511 if (Y.instanceOf(this, YUI)) { 18512 args = nativeSlice.call(arguments, 0); 18513 // use the adaptor specific detach code if 18514 if (adapt && adapt.detach) { 18515 adapt.detach.apply(Y, args); 18516 return this; 18517 // DOM event fork 18518 } else if (!type || (!adapt && Node && (type in Node.DOM_EVENTS))) { 18519 args[0] = type; 18520 Y.Event.detach.apply(Y.Event, args); 18521 return this; 18522 } 18523 } 18524 18525 // ce = evts[type]; 18526 ce = evts[parts[1]]; 18527 if (ce) { 18528 ce.detach(fn, context); 18529 } 18530 18531 return this; 18532 }, 18533 18534 /** 18535 * detach a listener 18536 * @method unsubscribe 18537 * @deprecated use detach 18538 */ 18539 unsubscribe: function() { 18540 return this.detach.apply(this, arguments); 18541 }, 18542 18543 /** 18544 * Removes all listeners from the specified event. If the event type 18545 * is not specified, all listeners from all hosted custom events will 18546 * be removed. 18547 * @method detachAll 18548 * @param type {String} The type, or name of the event 18549 */ 18550 detachAll: function(type) { 18551 return this.detach(type); 18552 }, 18553 18554 /** 18555 * Removes all listeners from the specified event. If the event type 18556 * is not specified, all listeners from all hosted custom events will 18557 * be removed. 18558 * @method unsubscribeAll 18559 * @param type {String} The type, or name of the event 18560 * @deprecated use detachAll 18561 */ 18562 unsubscribeAll: function() { 18563 return this.detachAll.apply(this, arguments); 18564 }, 18565 18566 /** 18567 * Creates a new custom event of the specified type. If a custom event 18568 * by that name already exists, it will not be re-created. In either 18569 * case the custom event is returned. 18570 * 18571 * @method publish 18572 * 18573 * @param type {String} the type, or name of the event 18574 * @param opts {object} optional config params. Valid properties are: 18575 * @param [opts.broadcast=false] {Boolean} whether or not the YUI instance and YUI global 18576 * are notified when the event is fired. 18577 * @param [opts.bubbles=true] {Boolean} Whether or not this event bubbles. Events can 18578 * only bubble if `emitFacade` is true.
18579 * @param [opts.context=this] {Object} the default execution context for the listeners. 18580 * @param [opts.defaultFn] {Function} the default function to execute when this event 18581 * fires if preventDefault was not called. 18582 * @param [opts.emitFacade=false] {Boolean} whether or not this event emits a facade. 18583 * @param [opts.prefix] {String} the prefix for this targets events, e.g., 'menu' in 'menu:click'. 18584 * @param [opts.fireOnce=false] {Boolean} if an event is configured to fire once, 18585 * new subscribers after the fire will be notified immediately. 18586 * @param [opts.async=false] {Boolean} fireOnce event listeners will fire synchronously 18587 * if the event has already fired unless `async` is `true`. 18588 * @param [opts.preventable=true] {Boolean} whether or not `preventDefault()` has an effect. 18589 * @param [opts.preventedFn] {Function} a function that is executed when `preventDefault()` is called. 18590 * @param [opts.queuable=false] {Boolean} whether or not this event can be queued during bubbling. 18591 * @param [opts.silent] {Boolean} if silent is true, debug messages are not provided for this event. 18592 * @param [opts.stoppedFn] {Function} a function that is executed when stopPropagation is called. 18593 * @param [opts.monitored] {Boolean} specifies whether or not this event should send notifications about 18594 * when the event has been attached, detached, or published. 18595 * @param [opts.type] {String} the event type (valid option if not provided as the first parameter to publish). 18596 * 18597 * @return {CustomEvent} the custom event 18598 * 18599 */ 18600 publish: function(type, opts) { 18601 18602 var ret, 18603 etState = this._yuievt, 18604 etConfig = etState.config, 18605 pre = etConfig.prefix; 18606 18607 if (typeof type === "string") { 18608 if (pre) { 18609 type = _getType(type, pre); 18610 } 18611 ret = this._publish(type, etConfig, opts); 18612 } else { 18613 ret = {}; 18614 18615 Y.each(type, function(v, k) { 18616 if (pre) { 18617 k = _getType(k, pre); 18618 } 18619 ret[k] = this._publish(k, etConfig, v || opts); 18620 }, this); 18621 18622 } 18623 18624 return ret; 18625 }, 18626 18627 /** 18628 * Returns the fully qualified type, given a short type string. 18629 * That is, returns "foo:bar" when given "bar" if "foo" is the configured prefix. 18630 * 18631 * NOTE: This method, unlike _getType, does no checking of the value passed in, and 18632 * is designed to be used with the low level _publish() method, for critical path 18633 * implementations which need to fast-track publish for performance reasons. 18634 * 18635 * @method _getFullType 18636 * @private 18637 * @param {String} type The short type to prefix 18638 * @return {String} The prefixed type, if a prefix is set, otherwise the type passed in 18639 */ 18640 _getFullType : function(type) { 18641 18642 var pre = this._yuievt.config.prefix; 18643 18644 if (pre) { 18645 return pre + PREFIX_DELIMITER + type; 18646 } else { 18647 return type; 18648 } 18649 }, 18650 18651 /** 18652 * The low level event publish implementation. It expects all the massaging to have been done 18653 * outside of this method. e.g. the `type` to `fullType` conversion. It's designed to be a fast 18654 * path publish, which can be used by critical code paths to improve performance. 18655 * 18656 * @method _publish 18657 * @private 18658 * @param {String} fullType The prefixed type of the event to publish. 18659 * @param {Object} etOpts The EventTarget specific configuration to mix into the published event. 18660 * @param {Object} ceOpts The publish specific configuration to mix into the published event. 18661 * @return {CustomEvent} The published event. If called without `etOpts` or `ceOpts`, this will 18662 * be the default `CustomEvent` instance, and can be configured independently. 18663 */ 18664 _publish : function(fullType, etOpts, ceOpts) { 18665 18666 var ce, 18667 etState = this._yuievt, 18668 etConfig = etState.config, 18669 host = etConfig.host, 18670 context = etConfig.context, 18671 events = etState.events; 18672 18673 ce = events[fullType]; 18674 18675 // PERF: Hate to pull the check out of monitor, but trying to keep critical path tight. 18676 if ((etConfig.monitored && !ce) || (ce && ce.monitored)) { 18677 this._monitor('publish', fullType, { 18678 args: arguments 18679 }); 18680 } 18681 18682 if (!ce) { 18683 // Publish event 18684 ce = events[fullType] = new Y.CustomEvent(fullType, etOpts); 18685 18686 if (!etOpts) { 18687 ce.host = host; 18688 ce.context = context; 18689 } 18690 } 18691 18692 if (ceOpts) { 18693 mixConfigs(ce, ceOpts, true); 18694 } 18695 18696 return ce; 18697 }, 18698 18699 /** 18700 * This is the entry point for the event monitoring system. 18701 * You can monitor 'attach', 'detach', 'fire', and 'publish'. 18702 * When configured, these events generate an event. click -> 18703 * click_attach, click_detach, click_publish -- these can 18704 * be subscribed to like other events to monitor the event 18705 * system. Inividual published events can have monitoring 18706 * turned on or off (publish can't be turned off before it 18707 * it published) by setting the events 'monitor' config. 18708 * 18709 * @method _monitor 18710 * @param what {String} 'attach', 'detach', 'fire', or 'publish' 18711 * @param eventType {String|CustomEvent} The prefixed name of the event being monitored, or the CustomEvent object. 18712 * @param o {Object} Information about the event interaction, such as 18713 * fire() args, subscription category, publish config 18714 * @private 18715 */ 18716 _monitor: function(what, eventType, o) {
18717 var monitorevt, ce, type; 18718 18719 if (eventType) { 18720 if (typeof eventType === "string") { 18721 type = eventType; 18722 ce = this.getEvent(eventType, true); 18723 } else { 18724 ce = eventType; 18725 type = eventType.type; 18726 } 18727 18728 if ((this._yuievt.config.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) { 18729 monitorevt = type + '_' + what; 18730 o.monitored = what; 18731 this.fire.call(this, monitorevt, o); 18732 } 18733 } 18734 }, 18735 18736 /** 18737 * Fire a custom event by name. The callback functions will be executed 18738 * from the context specified when the event was created, and with the 18739 * following parameters. 18740 * 18741 * The first argument is the event type, and any additional arguments are 18742 * passed to the listeners as parameters. If the first of these is an 18743 * object literal, and the event is configured to emit an event facade, 18744 * that object is mixed into the event facade and the facade is provided 18745 * in place of the original object. 18746 * 18747 * If the custom event object hasn't been created, then the event hasn't 18748 * been published and it has no subscribers. For performance sake, we 18749 * immediate exit in this case. This means the event won't bubble, so 18750 * if the intention is that a bubble target be notified, the event must 18751 * be published on this object first. 18752 * 18753 * @method fire 18754 * @param type {String|Object} The type of the event, or an object that contains 18755 * a 'type' property. 18756 * @param arguments {Object*} an arbitrary set of parameters to pass to 18757 * the handler. If the first of these is an object literal and the event is 18758 * configured to emit an event facade, the event facade will replace that 18759 * parameter after the properties the object literal contains are copied to 18760 * the event facade. 18761 * @return {Boolean} True if the whole lifecycle of the event went through, 18762 * false if at any point the event propagation was halted. 18763 */ 18764 fire: function(type) { 18765 18766 var typeIncluded = (typeof type === "string"), 18767 argCount = arguments.length, 18768 t = type, 18769 yuievt = this._yuievt, 18770 etConfig = yuievt.config, 18771 pre = etConfig.prefix, 18772 ret, 18773 ce, 18774 ce2, 18775 args; 18776 18777 if (typeIncluded && argCount <= 3) { 18778 18779 // PERF: Try to avoid slice/iteration for the common signatures 18780 18781 // Most common 18782 if (argCount === 2) { 18783 args = [arguments[1]]; // fire("foo", {}) 18784 } else if (argCount === 3) { 18785 args = [arguments[1], arguments[2]]; // fire("foo", {}, opts) 18786 } else { 18787 args = []; // fire("foo") 18788 } 18789 18790 } else { 18791 args = nativeSlice.call(arguments, ((typeIncluded) ? 1 : 0)); 18792 } 18793 18794 if (!typeIncluded) { 18795 t = (type && type.type); 18796 } 18797 18798 if (pre) { 18799 t = _getType(t, pre); 18800 } 18801 18802 ce = yuievt.events[t]; 18803 18804 if (this._hasSiblings) { 18805 ce2 = this.getSibling(t, ce); 18806 18807 if (ce2 && !ce) { 18808 ce = this.publish(t); 18809 } 18810 } 18811 18812 // PERF: trying to avoid function call, since this is a critical path 18813 if ((etConfig.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) { 18814 this._monitor('fire', (ce || t), { 18815 args: args 18816 }); 18817 } 18818 18819 // this event has not been published or subscribed to 18820 if (!ce) { 18821 if (yuievt.hasTargets) { 18822 return this.bubble({ type: t }, args, this); 18823 } 18824 18825 // otherwise there is nothing to be done 18826 ret = true; 18827 } else { 18828 18829 if (ce2) { 18830 ce.sibling = ce2; 18831 } 18832 18833 ret = ce._fire(args); 18834 } 18835 18836 return (yuievt.chain) ? this : ret; 18837 }, 18838 18839 getSibling: function(type, ce) { 18840 var ce2; 18841 18842 // delegate to *:type events if there are subscribers 18843 if (type.indexOf(PREFIX_DELIMITER) > -1) { 18844 type = _wildType(type); 18845 ce2 = this.getEvent(type, true); 18846 if (ce2) { 18847 ce2.applyConfig(ce); 18848 ce2.bubbles = false;
18849 ce2.broadcast = 0; 18850 } 18851 } 18852 18853 return ce2; 18854 }, 18855 18856 /** 18857 * Returns the custom event of the provided type has been created, a 18858 * falsy value otherwise 18859 * @method getEvent 18860 * @param type {String} the type, or name of the event 18861 * @param prefixed {String} if true, the type is prefixed already 18862 * @return {CustomEvent} the custom event or null 18863 */ 18864 getEvent: function(type, prefixed) { 18865 var pre, e; 18866 18867 if (!prefixed) { 18868 pre = this._yuievt.config.prefix; 18869 type = (pre) ? _getType(type, pre) : type; 18870 } 18871 e = this._yuievt.events; 18872 return e[type] || null; 18873 }, 18874 18875 /** 18876 * Subscribe to a custom event hosted by this object. The 18877 * supplied callback will execute after any listeners add 18878 * via the subscribe method, and after the default function, 18879 * if configured for the event, has executed. 18880 * 18881 * @method after 18882 * @param {String} type The name of the event 18883 * @param {Function} fn The callback to execute in response to the event 18884 * @param {Object} [context] Override `this` object in callback 18885 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 18886 * @return {EventHandle} A subscription handle capable of detaching the 18887 * subscription 18888 */ 18889 after: function(type, fn) { 18890 18891 var a = nativeSlice.call(arguments, 0); 18892 18893 switch (L.type(type)) { 18894 case 'function': 18895 return Y.Do.after.apply(Y.Do, arguments); 18896 case 'array': 18897 // YArray.each(a[0], function(v) { 18898 // v = AFTER_PREFIX + v; 18899 // }); 18900 // break; 18901 case 'object': 18902 a[0]._after = true; 18903 break; 18904 default: 18905 a[0] = AFTER_PREFIX + type; 18906 } 18907 18908 return this.on.apply(this, a); 18909 18910 }, 18911 18912 /** 18913 * Executes the callback before a DOM event, custom event 18914 * or method. If the first argument is a function, it 18915 * is assumed the target is a method. For DOM and custom 18916 * events, this is an alias for Y.on. 18917 * 18918 * For DOM and custom events: 18919 * type, callback, context, 0-n arguments 18920 * 18921 * For methods: 18922 * callback, object (method host), methodName, context, 0-n arguments 18923 * 18924 * @method before 18925 * @return detach handle 18926 */ 18927 before: function() { 18928 return this.on.apply(this, arguments); 18929 } 18930 18931}; 18932 18933Y.EventTarget = ET; 18934 18935// make Y an event target 18936Y.mix(Y, ET.prototype); 18937ET.call(Y, { bubbles: false }); 18938 18939YUI.Env.globalEvents = YUI.Env.globalEvents || new ET(); 18940 18941/** 18942 * Hosts YUI page level events. This is where events bubble to 18943 * when the broadcast config is set to 2. This property is 18944 * only available if the custom event module is loaded. 18945 * @property Global 18946 * @type EventTarget 18947 * @for YUI 18948 */ 18949Y.Global = YUI.Env.globalEvents; 18950 18951// @TODO implement a global namespace function on Y.Global? 18952 18953/** 18954`Y.on()` can do many things: 18955 18956<ul> 18957 <li>Subscribe to custom events `publish`ed and `fire`d from Y</li> 18958 <li>Subscribe to custom events `publish`ed with `broadcast` 1 or 2 and 18959 `fire`d from any object in the YUI instance sandbox</li> 18960 <li>Subscribe to DOM events</li> 18961 <li>Subscribe to the execution of a method on any object, effectively 18962 treating that method as an event</li> 18963</ul> 18964 18965For custom event subscriptions, pass the custom event name as the first argument 18966and callback as the second. The `this` object in the callback will be `Y` unless 18967an override is passed as the third argument. 18968 18969 Y.on('io:complete', function () { 18970 Y.MyApp.updateStatus('Transaction complete'); 18971 }); 18972 18973To subscribe to DOM events, pass the name of a DOM event as the first argument 18974and a CSS selector string as the third argument after the callback function. 18975Alternately, the third argument can be a `Node`, `NodeList`, `HTMLElement`, 18976array, or simply omitted (the default is the `window` object). 18977 18978 Y.on('click', function (e) { 18979 e.preventDefault(); 18980 18981 // proceed with ajax form submission 18982 var url = this.get('action'); 18983 ... 18984 }, '#my-form'); 18985 18986The `this` object in DOM event callbacks will be the `Node` targeted by the CSS 18987selector or other identifier. 18988 18989`on()` subscribers for DOM events or custom events `publish`ed with a 18990`defaultFn` can prevent the default behavior with `e.preventDefault()` from the 18991event object passed as the first parameter to the subscription callback. 18992 18993To subscribe to the execution of an object method, pass arguments corresponding to the call signature for 18994<a href="../classes/Do.html#methods_before">`Y.Do.before(...)`</a>. 18995 18996NOTE: The formal parameter list below is for events, not for function 18997injection. See `Y.Do.before` for that signature. 18998 18999@method on 19000@param {String} type DOM or custom event name 19001@param {Function} fn The callback to execute in response to the event 19002@param {Object} [context] Override `this` object in callback 19003@param {Any} [arg*] 0..n additional arguments to supply to the subscriber 19004@return {EventHandle} A subscription handle capable of detaching the 19005 subscription 19006@see Do.before 19007@for YUI
19008**/ 19009 19010/** 19011Listen for an event one time. Equivalent to `on()`, except that 19012the listener is immediately detached when executed. 19013 19014See the <a href="#methods_on">`on()` method</a> for additional subscription 19015options. 19016 19017@see on 19018@method once 19019@param {String} type DOM or custom event name 19020@param {Function} fn The callback to execute in response to the event 19021@param {Object} [context] Override `this` object in callback 19022@param {Any} [arg*] 0..n additional arguments to supply to the subscriber 19023@return {EventHandle} A subscription handle capable of detaching the 19024 subscription 19025@for YUI 19026**/ 19027 19028/** 19029Listen for an event one time. Equivalent to `once()`, except, like `after()`, 19030the subscription callback executes after all `on()` subscribers and the event's 19031`defaultFn` (if configured) have executed. Like `after()` if any `on()` phase 19032subscriber calls `e.preventDefault()`, neither the `defaultFn` nor the `after()` 19033subscribers will execute. 19034 19035The listener is immediately detached when executed. 19036 19037See the <a href="#methods_on">`on()` method</a> for additional subscription 19038options. 19039 19040@see once 19041@method onceAfter 19042@param {String} type The custom event name 19043@param {Function} fn The callback to execute in response to the event 19044@param {Object} [context] Override `this` object in callback 19045@param {Any} [arg*] 0..n additional arguments to supply to the subscriber 19046@return {EventHandle} A subscription handle capable of detaching the 19047 subscription 19048@for YUI 19049**/ 19050 19051/** 19052Like `on()`, this method creates a subscription to a custom event or to the 19053execution of a method on an object. 19054 19055For events, `after()` subscribers are executed after the event's 19056`defaultFn` unless `e.preventDefault()` was called from an `on()` subscriber. 19057 19058See the <a href="#methods_on">`on()` method</a> for additional subscription 19059options. 19060 19061NOTE: The subscription signature shown is for events, not for function 19062injection. See <a href="../classes/Do.html#methods_after">`Y.Do.after`</a> 19063for that signature. 19064 19065@see on 19066@see Do.after 19067@method after 19068@param {String} type The custom event name 19069@param {Function} fn The callback to execute in response to the event 19070@param {Object} [context] Override `this` object in callback 19071@param {Any} [args*] 0..n additional arguments to supply to the subscriber 19072@return {EventHandle} A subscription handle capable of detaching the 19073 subscription 19074@for YUI 19075**/ 19076 19077 19078}, 'patched-v3.18.1', {"requires": ["oop"]}); 19079 19080YUI.add('event-custom-complex', function (Y, NAME) { 19081 19082 19083/** 19084 * Adds event facades, preventable default behavior, and bubbling. 19085 * events. 19086 * @module event-custom 19087 * @submodule event-custom-complex 19088 */ 19089 19090var FACADE, 19091 FACADE_KEYS, 19092 YObject = Y.Object, 19093 key, 19094 EMPTY = {}, 19095 CEProto = Y.CustomEvent.prototype, 19096 ETProto = Y.EventTarget.prototype, 19097 19098 mixFacadeProps = function(facade, payload) { 19099 var p; 19100 19101 for (p in payload) { 19102 if (!(FACADE_KEYS.hasOwnProperty(p))) { 19103 facade[p] = payload[p]; 19104 } 19105 } 19106 }; 19107 19108/** 19109 * Wraps and protects a custom event for use when emitFacade is set to true. 19110 * Requires the event-custom-complex module 19111 * @class EventFacade 19112 * @param e {Event} the custom event 19113 * @param currentTarget {HTMLElement} the element the listener was attached to 19114 */ 19115 19116Y.EventFacade = function(e, currentTarget) { 19117 19118 if (!e) { 19119 e = EMPTY; 19120 } 19121 19122 this._event = e; 19123 19124 /** 19125 * The arguments passed to fire 19126 * @property details 19127 * @type Array 19128 */ 19129 this.details = e.details; 19130 19131 /** 19132 * The event type, this can be overridden by the fire() payload 19133 * @property type 19134 * @type string 19135 */ 19136 this.type = e.type; 19137 19138 /** 19139 * The real event type 19140 * @property _type 19141 * @type string 19142 * @private 19143 */ 19144 this._type = e.type; 19145 19146 ////////////////////////////////////////////////////// 19147 19148 /** 19149 * Node reference for the targeted eventtarget 19150 * @property target 19151 * @type Node 19152 */ 19153 this.target = e.target; 19154 19155 /** 19156 * Node reference for the element that the listener was attached to. 19157 * @property currentTarget 19158 * @type Node 19159 */ 19160 this.currentTarget = currentTarget; 19161 19162 /** 19163 * Node reference to the relatedTarget 19164 * @property relatedTarget 19165 * @type Node 19166 */ 19167 this.relatedTarget = e.relatedTarget; 19168 19169}; 19170 19171Y.mix(Y.EventFacade.prototype, { 19172 19173 /** 19174 * Stops the propagation to the next bubble target 19175 * @method stopPropagation 19176 */ 19177 stopPropagation: function() { 19178 this._event.stopPropagation(); 19179 this.stopped = 1; 19180 }, 19181 19182 /** 19183 * Stops the propagation to the next bubble target and 19184 * prevents any additional listeners from being exectued 19185 * on the current target. 19186 * @method stopImmediatePropagation 19187 */ 19188 stopImmediatePropagation: function() { 19189 this._event.stopImmediatePropagation(); 19190 this.stopped = 2; 19191 }, 19192 19193 /** 19194 * Prevents the event's default behavior 19195 * @method preventDefault 19196 */ 19197 preventDefault: function() { 19198 this._event.preventDefault(); 19199 this.prevented = 1; 19200 }, 19201 19202 /** 19203 * Stops the event propagation and prevents the default 19204 * event behavior. 19205 * @method halt 19206 * @param immediate {boolean} if true additional listeners 19207 * on the current target will not be executed 19208 */ 19209 halt: function(immediate) { 19210 this._event.halt(immediate); 19211 this.prevented = 1; 19212 this.stopped = (immediate) ? 2 : 1; 19213 } 19214 19215}); 19216 19217CEProto.fireComplex = function(args) { 19218 19219 var es, 19220 ef, 19221 q, 19222 queue, 19223 ce, 19224 ret = true, 19225 events, 19226 subs, 19227 ons, 19228 afters, 19229 afterQueue, 19230 postponed, 19231 prevented, 19232 preventedFn, 19233 defaultFn, 19234 self = this, 19235 host = self.host || self, 19236 next, 19237 oldbubble, 19238 stack = self.stack, 19239 yuievt = host._yuievt, 19240 hasPotentialSubscribers; 19241 19242 if (stack) { 19243 19244 // queue this event if the current item in the queue bubbles 19245 if (self.queuable && self.type !== stack.next.type) { 19246 19247 if (!stack.queue) { 19248 stack.queue = []; 19249 } 19250 stack.queue.push([self, args]); 19251 19252 return true; 19253 } 19254 } 19255 19256 hasPotentialSubscribers = self.hasSubs() || yuievt.hasTargets || self.broadcast; 19257 19258 self.target = self.target || host; 19259 self.currentTarget = host; 19260 19261 self.details = args.concat(); 19262 19263 if (hasPotentialSubscribers) { 19264 19265 es = stack || { 19266 19267 id: self.id, // id of the first event in the stack 19268 next: self, 19269 silent: self.silent, 19270 stopped: 0, 19271 prevented: 0, 19272 bubbling: null, 19273 type: self.type, 19274 // defaultFnQueue: new Y.Queue(), 19275 defaultTargetOnly: self.defaultTargetOnly 19276 19277 }; 19278 19279 subs = self.getSubs(); 19280 ons = subs[0]; 19281 afters = subs[1]; 19282 19283 self.stopped = (self.type !== es.type) ? 0 : es.stopped; 19284 self.prevented = (self.type !== es.type) ? 0 : es.prevented; 19285 19286 if (self.stoppedFn) { 19287 // PERF TODO: Can we replace with callback, like preventedFn. Look into history 19288 events = new Y.EventTarget({
19289 fireOnce: true, 19290 context: host 19291 }); 19292 self.events = events; 19293 events.on('stopped', self.stoppedFn); 19294 } 19295 19296 19297 self._facade = null; // kill facade to eliminate stale properties 19298 19299 ef = self._createFacade(args); 19300 19301 if (ons) { 19302 self._procSubs(ons, args, ef); 19303 } 19304 19305 // bubble if this is hosted in an event target and propagation has not been stopped 19306 if (self.bubbles && host.bubble && !self.stopped) { 19307 oldbubble = es.bubbling; 19308 19309 es.bubbling = self.type; 19310 19311 if (es.type !== self.type) { 19312 es.stopped = 0; 19313 es.prevented = 0; 19314 } 19315 19316 ret = host.bubble(self, args, null, es); 19317 19318 self.stopped = Math.max(self.stopped, es.stopped); 19319 self.prevented = Math.max(self.prevented, es.prevented); 19320 19321 es.bubbling = oldbubble; 19322 } 19323 19324 prevented = self.prevented; 19325 19326 if (prevented) { 19327 preventedFn = self.preventedFn; 19328 if (preventedFn) {
19329 preventedFn.apply(host, args); 19330 } 19331 } else { 19332 defaultFn = self.defaultFn; 19333 19334 if (defaultFn && ((!self.defaultTargetOnly && !es.defaultTargetOnly) || host === ef.target)) { 19335 defaultFn.apply(host, args); 19336 } 19337 } 19338 19339 // broadcast listeners are fired as discreet events on the 19340 // YUI instance and potentially the YUI global. 19341 if (self.broadcast) { 19342 self._broadcast(args); 19343 } 19344 19345 if (afters && !self.prevented && self.stopped < 2) { 19346 19347 // Queue the after 19348 afterQueue = es.afterQueue; 19349 19350 if (es.id === self.id || self.type !== yuievt.bubbling) { 19351 19352 self._procSubs(afters, args, ef); 19353 19354 if (afterQueue) { 19355 while ((next = afterQueue.last())) { 19356 next(); 19357 } 19358 } 19359 } else { 19360 postponed = afters; 19361 19362 if (es.execDefaultCnt) { 19363 postponed = Y.merge(postponed); 19364 19365 Y.each(postponed, function(s) { 19366 s.postponed = true; 19367 }); 19368 } 19369 19370 if (!afterQueue) { 19371 es.afterQueue = new Y.Queue(); 19372 } 19373 19374 es.afterQueue.add(function() { 19375 self._procSubs(postponed, args, ef); 19376 }); 19377 } 19378 19379 } 19380 19381 self.target = null; 19382 19383 if (es.id === self.id) { 19384 19385 queue = es.queue; 19386 19387 if (queue) { 19388 while (queue.length) { 19389 q = queue.pop(); 19390 ce = q[0]; 19391 // set up stack to allow the next item to be processed 19392 es.next = ce; 19393 ce._fire(q[1]); 19394 } 19395 } 19396 19397 self.stack = null; 19398 } 19399 19400 ret = !(self.stopped); 19401 19402 if (self.type !== yuievt.bubbling) { 19403 es.stopped = 0; 19404 es.prevented = 0; 19405 self.stopped = 0; 19406 self.prevented = 0; 19407 } 19408 19409 } else { 19410 defaultFn = self.defaultFn; 19411 19412 if(defaultFn) { 19413 ef = self._createFacade(args); 19414 19415 if ((!self.defaultTargetOnly) || (host === ef.target)) {
19416 defaultFn.apply(host, args); 19417 } 19418 } 19419 } 19420 19421 // Kill the cached facade to free up memory. 19422 // Otherwise we have the facade from the last fire, sitting around forever. 19423 self._facade = null; 19424 19425 return ret; 19426}; 19427 19428/** 19429 * @method _hasPotentialSubscribers 19430 * @for CustomEvent 19431 * @private 19432 * @return {boolean} Whether the event has potential subscribers or not 19433 */ 19434CEProto._hasPotentialSubscribers = function() { 19435 return this.hasSubs() || this.host._yuievt.hasTargets || this.broadcast; 19436}; 19437 19438/** 19439 * Internal utility method to create a new facade instance and 19440 * insert it into the fire argument list, accounting for any payload 19441 * merging which needs to happen. 19442 * 19443 * This used to be called `_getFacade`, but the name seemed inappropriate 19444 * when it was used without a need for the return value. 19445 * 19446 * @method _createFacade 19447 * @private 19448 * @param fireArgs {Array} The arguments passed to "fire", which need to be 19449 * shifted (and potentially merged) when the facade is added. 19450 * @return {EventFacade} The event facade created. 19451 */ 19452 19453// TODO: Remove (private) _getFacade alias, once synthetic.js is updated. 19454CEProto._createFacade = CEProto._getFacade = function(fireArgs) { 19455 19456 var userArgs = this.details, 19457 firstArg = userArgs && userArgs[0], 19458 firstArgIsObj = (firstArg && (typeof firstArg === "object")), 19459 ef = this._facade; 19460 19461 if (!ef) { 19462 ef = new Y.EventFacade(this, this.currentTarget); 19463 } 19464 19465 if (firstArgIsObj) { 19466 // protect the event facade properties 19467 mixFacadeProps(ef, firstArg); 19468 19469 // Allow the event type to be faked http://yuilibrary.com/projects/yui3/ticket/2528376 19470 if (firstArg.type) { 19471 ef.type = firstArg.type; 19472 } 19473 19474 if (fireArgs) { 19475 fireArgs[0] = ef; 19476 } 19477 } else { 19478 if (fireArgs) { 19479 fireArgs.unshift(ef); 19480 } 19481 } 19482 19483 // update the details field with the arguments 19484 ef.details = this.details; 19485 19486 // use the original target when the event bubbled to this target 19487 ef.target = this.originalTarget || this.target; 19488 19489 ef.currentTarget = this.currentTarget; 19490 ef.stopped = 0; 19491 ef.prevented = 0; 19492 19493 this._facade = ef; 19494 19495 return this._facade; 19496}; 19497 19498/** 19499 * Utility method to manipulate the args array passed in, to add the event facade, 19500 * if it's not already the first arg. 19501 * 19502 * @method _addFacadeToArgs 19503 * @private 19504 * @param {Array} The arguments to manipulate 19505 */ 19506CEProto._addFacadeToArgs = function(args) { 19507 var e = args[0]; 19508 19509 // Trying not to use instanceof, just to avoid potential cross Y edge case issues. 19510 if (!(e && e.halt && e.stopImmediatePropagation && e.stopPropagation && e._event)) { 19511 this._createFacade(args); 19512 } 19513}; 19514 19515/** 19516 * Stop propagation to bubble targets 19517 * @for CustomEvent 19518 * @method stopPropagation 19519 */ 19520CEProto.stopPropagation = function() { 19521 this.stopped = 1; 19522 if (this.stack) { 19523 this.stack.stopped = 1; 19524 } 19525 if (this.events) { 19526 this.events.fire('stopped', this); 19527 } 19528}; 19529 19530/** 19531 * Stops propagation to bubble targets, and prevents any remaining 19532 * subscribers on the current target from executing. 19533 * @method stopImmediatePropagation 19534 */ 19535CEProto.stopImmediatePropagation = function() { 19536 this.stopped = 2; 19537 if (this.stack) { 19538 this.stack.stopped = 2; 19539 } 19540 if (this.events) { 19541 this.events.fire('stopped', this); 19542 } 19543}; 19544 19545/** 19546 * Prevents the execution of this event's defaultFn 19547 * @method preventDefault 19548 */ 19549CEProto.preventDefault = function() { 19550 if (this.preventable) { 19551 this.prevented = 1; 19552 if (this.stack) { 19553 this.stack.prevented = 1; 19554 } 19555 } 19556}; 19557 19558/** 19559 * Stops the event propagation and prevents the default 19560 * event behavior. 19561 * @method halt 19562 * @param immediate {boolean} if true additional listeners 19563 * on the current target will not be executed 19564 */ 19565CEProto.halt = function(immediate) { 19566 if (immediate) { 19567 this.stopImmediatePropagation(); 19568 } else { 19569 this.stopPropagation(); 19570 } 19571 this.preventDefault(); 19572}; 19573 19574/** 19575 * Registers another EventTarget as a bubble target. Bubble order 19576 * is determined by the order registered. Multiple targets can 19577 * be specified. 19578 * 19579 * Events can only bubble if emitFacade is true. 19580 * 19581 * Included in the event-custom-complex submodule. 19582 * 19583 * @method addTarget 19584 * @chainable 19585 * @param o {EventTarget} the target to add 19586 * @for EventTarget 19587 */ 19588ETProto.addTarget = function(o) { 19589 var etState = this._yuievt; 19590 19591 if (!etState.targets) { 19592 etState.targets = {}; 19593 } 19594 19595 etState.targets[Y.stamp(o)] = o; 19596 etState.hasTargets = true; 19597 19598 return this; 19599}; 19600 19601/** 19602 * Returns an array of bubble targets for this object. 19603 * @method getTargets 19604 * @return EventTarget[] 19605 */ 19606ETProto.getTargets = function() { 19607 var targets = this._yuievt.targets; 19608 return targets ? YObject.values(targets) : []; 19609}; 19610 19611/** 19612 * Removes a bubble target 19613 * @method removeTarget 19614 * @chainable 19615 * @param o {EventTarget} the target to remove 19616 * @for EventTarget 19617 */ 19618ETProto.removeTarget = function(o) { 19619 var targets = this._yuievt.targets; 19620 19621 if (targets) { 19622 delete targets[Y.stamp(o, true)]; 19623 19624 if (YObject.size(targets) === 0) { 19625 this._yuievt.hasTargets = false;
19626 } 19627 } 19628 19629 return this; 19630}; 19631 19632/** 19633 * Propagate an event. Requires the event-custom-complex module. 19634 * @method bubble 19635 * @param evt {CustomEvent} the custom event to propagate 19636 * @return {boolean} the aggregated return value from Event.Custom.fire 19637 * @for EventTarget 19638 */ 19639ETProto.bubble = function(evt, args, target, es) { 19640 19641 var targs = this._yuievt.targets, 19642 ret = true, 19643 t, 19644 ce, 19645 i, 19646 bc, 19647 ce2, 19648 type = evt && evt.type, 19649 originalTarget = target || (evt && evt.target) || this, 19650 oldbubble; 19651 19652 if (!evt || ((!evt.stopped) && targs)) { 19653 19654 for (i in targs) { 19655 if (targs.hasOwnProperty(i)) { 19656 19657 t = targs[i]; 19658 19659 ce = t._yuievt.events[type]; 19660 19661 if (t._hasSiblings) { 19662 ce2 = t.getSibling(type, ce); 19663 } 19664 19665 if (ce2 && !ce) { 19666 ce = t.publish(type); 19667 } 19668 19669 oldbubble = t._yuievt.bubbling; 19670 t._yuievt.bubbling = type; 19671 19672 // if this event was not published on the bubble target, 19673 // continue propagating the event. 19674 if (!ce) { 19675 if (t._yuievt.hasTargets) { 19676 t.bubble(evt, args, originalTarget, es); 19677 } 19678 } else { 19679 19680 if (ce2) { 19681 ce.sibling = ce2; 19682 } 19683 19684 // set the original target to that the target payload on the facade is correct. 19685 ce.target = originalTarget; 19686 ce.originalTarget = originalTarget; 19687 ce.currentTarget = t; 19688 bc = ce.broadcast; 19689 ce.broadcast = false; 19690 19691 // default publish may not have emitFacade true -- that 19692 // shouldn't be what the implementer meant to do 19693 ce.emitFacade = true; 19694 19695 ce.stack = es; 19696 19697 // TODO: See what's getting in the way of changing this to use 19698 // the more performant ce._fire(args || evt.details || []). 19699 19700 // Something in Widget Parent/Child tests is not happy if we 19701 // change it - maybe evt.details related? 19702 ret = ret && ce.fire.apply(ce, args || evt.details || []); 19703 19704 ce.broadcast = bc; 19705 ce.originalTarget = null; 19706 19707 // stopPropagation() was called 19708 if (ce.stopped) { 19709 break; 19710 } 19711 } 19712 19713 t._yuievt.bubbling = oldbubble; 19714 } 19715 } 19716 } 19717 19718 return ret; 19719}; 19720 19721/** 19722 * @method _hasPotentialSubscribers 19723 * @for EventTarget 19724 * @private 19725 * @param {String} fullType The fully prefixed type name 19726 * @return {boolean} Whether the event has potential subscribers or not 19727 */ 19728ETProto._hasPotentialSubscribers = function(fullType) { 19729 19730 var etState = this._yuievt, 19731 e = etState.events[fullType]; 19732 19733 if (e) { 19734 return e.hasSubs() || etState.hasTargets || e.broadcast; 19735 } else { 19736 return false; 19737 } 19738}; 19739 19740FACADE = new Y.EventFacade(); 19741FACADE_KEYS = {}; 19742 19743// Flatten whitelist 19744for (key in FACADE) { 19745 FACADE_KEYS[key] = true; 19746} 19747 19748 19749}, 'patched-v3.18.1', {"requires": ["event-custom-base"]}); 19750 19751YUI.add('oop', function (Y, NAME) { 19752 19753/** 19754Adds object inheritance and manipulation utilities to the YUI instance. This 19755module is required by most YUI components. 19756 19757@module oop 19758**/ 19759 19760var L = Y.Lang, 19761 A = Y.Array, 19762 OP = Object.prototype, 19763 CLONE_MARKER = '_~yuim~_', 19764 19765 hasOwn = OP.hasOwnProperty, 19766 toString = OP.toString; 19767 19768/** 19769Calls the specified _action_ method on _o_ if it exists. Otherwise, if _o_ is an 19770array, calls the _action_ method on `Y.Array`, or if _o_ is an object, calls the 19771_action_ method on `Y.Object`. 19772 19773If _o_ is an array-like object, it will be coerced to an array. 19774 19775This is intended to be used with array/object iteration methods that share 19776signatures, such as `each()`, `some()`, etc. 19777 19778@method dispatch 19779@param {Object} o Array or object to dispatch to. 19780@param {Function} f Iteration callback. 19781 @param {Mixed} f.value Value being iterated. 19782 @param {Mixed} f.key Current object key or array index. 19783 @param {Mixed} f.object Object or array being iterated. 19784@param {Object} c `this` object to bind the iteration callback to. 19785@param {Boolean} proto If `true`, prototype properties of objects will be 19786 iterated. 19787@param {String} action Function name to be dispatched on _o_. For example: 19788 'some', 'each', etc. 19789@private 19790@return {Mixed} Returns the value returned by the chosen iteration action, which 19791 varies. 19792**/ 19793function dispatch(o, f, c, proto, action) { 19794 if (o && o[action] && o !== Y) { 19795 return o[action].call(o, f, c); 19796 } else { 19797 switch (A.test(o)) { 19798 case 1: 19799 return A[action](o, f, c); 19800 case 2: 19801 return A[action](Y.Array(o, 0, true), f, c); 19802 default: 19803 return Y.Object[action](o, f, c, proto); 19804 } 19805 } 19806} 19807 19808/** 19809Augments the _receiver_ with prototype properties from the _supplier_. The 19810receiver may be a constructor function or an object. The supplier must be a 19811constructor function. 19812 19813If the _receiver_ is an object, then the _supplier_ constructor will be called 19814immediately after _receiver_ is augmented, with _receiver_ as the `this` object. 19815 19816If the _receiver_ is a constructor function, then all prototype methods of 19817_supplier_ that are copied to _receiver_ will be sequestered, and the 19818_supplier_ constructor will not be called immediately. The first time any 19819sequestered method is called on the _receiver_'s prototype, all sequestered 19820methods will be immediately copied to the _receiver_'s prototype, the 19821_supplier_'s constructor will be executed, and finally the newly unsequestered 19822method that was called will be executed. 19823 19824This sequestering logic sounds like a bunch of complicated voodoo, but it makes 19825it cheap to perform frequent augmentation by ensuring that suppliers'
19826constructors are only called if a supplied method is actually used. If none of 19827the supplied methods is ever used, then there's no need to take the performance 19828hit of calling the _supplier_'s constructor. 19829 19830@method augment 19831@param {Function|Object} receiver Object or function to be augmented. 19832@param {Function} supplier Function that supplies the prototype properties with 19833 which to augment the _receiver_. 19834@param {Boolean} [overwrite=false] If `true`, properties already on the receiver 19835 will be overwritten if found on the supplier's prototype. 19836@param {String[]} [whitelist] An array of property names. If specified, 19837 only the whitelisted prototype properties will be applied to the receiver, and 19838 all others will be ignored. 19839@param {Array|any} [args] Argument or array of arguments to pass to the 19840 supplier's constructor when initializing. 19841@return {Function} Augmented object. 19842@for YUI 19843**/ 19844Y.augment = function (receiver, supplier, overwrite, whitelist, args) { 19845 var rProto = receiver.prototype, 19846 sequester = rProto && supplier, 19847 sProto = supplier.prototype, 19848 to = rProto || receiver, 19849 19850 copy, 19851 newPrototype, 19852 replacements, 19853 sequestered, 19854 unsequester; 19855 19856 args = args ? Y.Array(args) : []; 19857 19858 if (sequester) { 19859 newPrototype = {}; 19860 replacements = {}; 19861 sequestered = {}; 19862 19863 copy = function (value, key) { 19864 if (overwrite || !(key in rProto)) { 19865 if (toString.call(value) === '[object Function]') { 19866 sequestered[key] = value; 19867 19868 newPrototype[key] = replacements[key] = function () { 19869 return unsequester(this, value, arguments); 19870 }; 19871 } else { 19872 newPrototype[key] = value; 19873 } 19874 } 19875 }; 19876 19877 unsequester = function (instance, fn, fnArgs) { 19878 // Unsequester all sequestered functions. 19879 for (var key in sequestered) { 19880 if (hasOwn.call(sequestered, key) 19881 && instance[key] === replacements[key]) { 19882 19883 instance[key] = sequestered[key]; 19884 } 19885 } 19886 19887 // Execute the supplier constructor. 19888 supplier.apply(instance, args); 19889 19890 // Finally, execute the original sequestered function. 19891 return fn.apply(instance, fnArgs); 19892 }; 19893 19894 if (whitelist) { 19895 Y.Array.each(whitelist, function (name) { 19896 if (name in sProto) { 19897 copy(sProto[name], name); 19898 } 19899 }); 19900 } else { 19901 Y.Object.each(sProto, copy, null, true); 19902 } 19903 } 19904 19905 Y.mix(to, newPrototype || sProto, overwrite, whitelist); 19906 19907 if (!sequester) { 19908 supplier.apply(to, args); 19909 } 19910 19911 return receiver; 19912}; 19913 19914/** 19915 * Copies object properties from the supplier to the receiver. If the target has 19916 * the property, and the property is an object, the target object will be 19917 * augmented with the supplier's value. 19918 * 19919 * @method aggregate 19920 * @param {Object} receiver Object to receive the augmentation. 19921 * @param {Object} supplier Object that supplies the properties with which to 19922 * augment the receiver. 19923 * @param {Boolean} [overwrite=false] If `true`, properties already on the receiver 19924 * will be overwritten if found on the supplier. 19925 * @param {String[]} [whitelist] Whitelist. If supplied, only properties in this 19926 * list will be applied to the receiver. 19927 * @return {Object} Augmented object. 19928 */ 19929Y.aggregate = function(r, s, ov, wl) { 19930 return Y.mix(r, s, ov, wl, 0, true); 19931}; 19932 19933/** 19934 * Utility to set up the prototype, constructor and superclass properties to 19935 * support an inheritance strategy that can chain constructors and methods. 19936 * Static members will not be inherited. 19937 * 19938 * @method extend 19939 * @param {function} r the object to modify. 19940 * @param {function} s the object to inherit. 19941 * @param {object} px prototype properties to add/override. 19942 * @param {object} sx static properties to add/override. 19943 * @return {object} the extended object. 19944 */ 19945Y.extend = function(r, s, px, sx) { 19946 if (!s || !r) { 19947 Y.error('extend failed, verify dependencies'); 19948 } 19949 19950 var sp = s.prototype, rp = Y.Object(sp); 19951 r.prototype = rp; 19952 19953 rp.constructor = r; 19954 r.superclass = sp; 19955 19956 // assign constructor property 19957 if (s != Object && sp.constructor == OP.constructor) { 19958 sp.constructor = s; 19959 } 19960 19961 // add prototype overrides 19962 if (px) { 19963 Y.mix(rp, px, true); 19964 } 19965 19966 // add object overrides 19967 if (sx) { 19968 Y.mix(r, sx, true); 19969 } 19970 19971 return r; 19972}; 19973 19974/** 19975 * Executes the supplied function for each item in 19976 * a collection. Supports arrays, objects, and 19977 * NodeLists 19978 * @method each 19979 * @param {object} o the object to iterate. 19980 * @param {function} f the function to execute. This function 19981 * receives the value, key, and object as parameters. 19982 * @param {object} c the execution context for the function. 19983 * @param {boolean} proto if true, prototype properties are 19984 * iterated on objects. 19985 * @return {YUI} the YUI instance. 19986 */ 19987Y.each = function(o, f, c, proto) {
19988 return dispatch(o, f, c, proto, 'each'); 19989}; 19990 19991/** 19992 * Executes the supplied function for each item in 19993 * a collection. The operation stops if the function 19994 * returns true. Supports arrays, objects, and 19995 * NodeLists. 19996 * @method some 19997 * @param {object} o the object to iterate. 19998 * @param {function} f the function to execute. This function 19999 * receives the value, key, and object as parameters. 20000 * @param {object} c the execution context for the function. 20001 * @param {boolean} proto if true, prototype properties are 20002 * iterated on objects. 20003 * @return {boolean} true if the function ever returns true, 20004 * false otherwise. 20005 */ 20006Y.some = function(o, f, c, proto) { 20007 return dispatch(o, f, c, proto, 'some'); 20008}; 20009 20010/** 20011Deep object/array copy. Function clones are actually wrappers around the 20012original function. Array-like objects are treated as arrays. Primitives are 20013returned untouched. Optionally, a function can be provided to handle other data 20014types, filter keys, validate values, etc. 20015 20016**Note:** Cloning a non-trivial object is a reasonably heavy operation, due to 20017the need to recursively iterate down non-primitive properties. Clone should be 20018used only when a deep clone down to leaf level properties is explicitly 20019required. This method will also 20020 20021In many cases (for example, when trying to isolate objects used as hashes for 20022configuration properties), a shallow copy, using `Y.merge()` is normally 20023sufficient. If more than one level of isolation is required, `Y.merge()` can be 20024used selectively at each level which needs to be isolated from the original 20025without going all the way to leaf properties. 20026 20027@method clone 20028@param {object} o what to clone. 20029@param {boolean} safe if true, objects will not have prototype items from the 20030 source. If false, they will. In this case, the original is initially 20031 protected, but the clone is not completely immune from changes to the source 20032 object prototype. Also, cloned prototype items that are deleted from the 20033 clone will result in the value of the source prototype being exposed. If 20034 operating on a non-safe clone, items should be nulled out rather than 20035 deleted. 20036@param {function} f optional function to apply to each item in a collection; it 20037 will be executed prior to applying the value to the new object. 20038 Return false to prevent the copy. 20039@param {object} c optional execution context for f. 20040@param {object} owner Owner object passed when clone is iterating an object. 20041 Used to set up context for cloned functions. 20042@param {object} cloned hash of previously cloned objects to avoid multiple 20043 clones. 20044@return {Array|Object} the cloned object. 20045**/ 20046Y.clone = function(o, safe, f, c, owner, cloned) { 20047 var o2, marked, stamp; 20048 20049 // Does not attempt to clone: 20050 // 20051 // * Non-typeof-object values, "primitive" values don't need cloning. 20052 // 20053 // * YUI instances, cloning complex object like YUI instances is not 20054 // advised, this is like cloning the world. 20055 // 20056 // * DOM nodes (#2528250), common host objects like DOM nodes cannot be 20057 // "subclassed" in Firefox and old versions of IE. Trying to use 20058 // `Object.create()` or `Y.extend()` on a DOM node will throw an error in 20059 // these browsers. 20060 // 20061 // Instad, the passed-in `o` will be return as-is when it matches one of the 20062 // above criteria. 20063 if (!L.isObject(o) || 20064 Y.instanceOf(o, YUI) || 20065 (o.addEventListener || o.attachEvent)) { 20066 20067 return o; 20068 } 20069 20070 marked = cloned || {}; 20071 20072 switch (L.type(o)) { 20073 case 'date': 20074 return new Date(o); 20075 case 'regexp': 20076 // if we do this we need to set the flags too 20077 // return new RegExp(o.source); 20078 return o; 20079 case 'function': 20080 // o2 = Y.bind(o, owner); 20081 // break; 20082 return o; 20083 case 'array': 20084 o2 = []; 20085 break; 20086 default: 20087 20088 // #2528250 only one clone of a given object should be created. 20089 if (o[CLONE_MARKER]) { 20090 return marked[o[CLONE_MARKER]]; 20091 } 20092 20093 stamp = Y.guid(); 20094 20095 o2 = (safe) ? {} : Y.Object(o); 20096 20097 o[CLONE_MARKER] = stamp; 20098 marked[stamp] = o; 20099 } 20100 20101 Y.each(o, function(v, k) { 20102 if ((k || k === 0) && (!f || (f.call(c || this, v, k, this, o) !== false))) { 20103 if (k !== CLONE_MARKER) { 20104 if (k == 'prototype') { 20105 // skip the prototype 20106 // } else if (o[k] === o) { 20107 // this[k] = this; 20108 } else { 20109 this[k] = 20110 Y.clone(v, safe, f, c, owner || o, marked); 20111 } 20112 } 20113 } 20114 }, o2); 20115 20116 if (!cloned) { 20117 Y.Object.each(marked, function(v, k) { 20118 if (v[CLONE_MARKER]) { 20119 try { 20120 delete v[CLONE_MARKER]; 20121 } catch (e) { 20122 v[CLONE_MARKER] = null; 20123 } 20124 } 20125 }, this); 20126 marked = null; 20127 } 20128 20129 return o2; 20130}; 20131 20132/** 20133 * Returns a function that will execute the supplied function in the 20134 * supplied object's context, optionally adding any additional 20135 * supplied parameters to the beginning of the arguments collection the 20136 * supplied to the function. 20137 * 20138 * @method bind 20139 * @param {Function|String} f the function to bind, or a function name 20140 * to execute on the context object. 20141 * @param {object} c the execution context. 20142 * @param {any} args* 0..n arguments to include before the arguments the 20143 * function is executed with. 20144 * @return {function} the wrapped function. 20145 */ 20146Y.bind = function(f, c) { 20147 var xargs = arguments.length > 2 ? 20148 Y.Array(arguments, 2, true) : null; 20149 return function() { 20150 var fn = L.isString(f) ? c[f] : f, 20151 args = (xargs) ? 20152 xargs.concat(Y.Array(arguments, 0, true)) : arguments; 20153 return fn.apply(c || fn, args); 20154 }; 20155}; 20156 20157/** 20158 * Returns a function that will execute the supplied function in the 20159 * supplied object's context, optionally adding any additional 20160 * supplied parameters to the end of the arguments the function 20161 * is executed with. 20162 * 20163 * @method rbind 20164 * @param {Function|String} f the function to bind, or a function name 20165 * to execute on the context object. 20166 * @param {object} c the execution context. 20167 * @param {any} args* 0..n arguments to append to the end of 20168 * arguments collection supplied to the function. 20169 * @return {function} the wrapped function. 20170 */ 20171Y.rbind = function(f, c) { 20172 var xargs = arguments.length > 2 ? Y.Array(arguments, 2, true) : null; 20173 return function() { 20174 var fn = L.isString(f) ? c[f] : f, 20175 args = (xargs) ? 20176 Y.Array(arguments, 0, true).concat(xargs) : arguments; 20177 return fn.apply(c || fn, args); 20178 }; 20179}; 20180 20181 20182}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 20183 20184YUI.add('aui-base-lang', function (A, NAME) { 20185 20186(function() { 20187 var Lang = A.Lang, 20188 aArray = A.Array, 20189 AObject = A.Object, 20190 20191 isArray = Lang.isArray, 20192 isNumber = Lang.isNumber, 20193 isString = Lang.isString, 20194 isUndefined = Lang.isUndefined, 20195 20196 owns = AObject.owns; 20197
20198 A.fn = function(fn, context, args) { 20199 var wrappedFn, 20200 dynamicLookup; 20201 20202 // Explicitly set function arguments 20203 if (!isNumber(fn)) { 20204 var xargs = arguments; 20205 20206 if (xargs.length > 2) { 20207 xargs = aArray(xargs, 2, true); 20208 } 20209 20210 dynamicLookup = (isString(fn) && context); 20211 20212 wrappedFn = function() { 20213 var method = (!dynamicLookup) ? fn : context[fn]; 20214 20215 return method.apply(context || fn, xargs); 20216 }; 20217 } 20218 else { 20219 // Set function arity 20220 var argLength = fn; 20221 20222 fn = context; 20223 context = args; 20224 dynamicLookup = (isString(fn) && context); 20225 20226 wrappedFn = function() { 20227 var method = (!dynamicLookup) ? fn : context[fn], 20228 returnValue; 20229 20230 context = context || method; 20231 20232 if (argLength > 0) { 20233 returnValue = method.apply(context, aArray(arguments, 0, true).slice(0, argLength)); 20234 } 20235 else { 20236 returnValue = method.call(context); 20237 } 20238 20239 return returnValue; 20240 }; 20241 } 20242 20243 return wrappedFn; 20244 }; 20245 20246 A.mix(Lang, { 20247 constrain: function(num, min, max) { 20248 return Math.min(Math.max(num, min), max); 20249 }, 20250 20251 emptyFn: function() {}, 20252 20253 emptyFnFalse: function() { 20254 return false; 20255 }, 20256 20257 emptyFnTrue: function() { 20258 return true; 20259 }, 20260 20261 isGuid: function(id) { 20262 return String(id).indexOf(A.Env._guidp) === 0; 20263 }, 20264 20265 isInteger: function(val) { 20266 return typeof val === 'number' && 20267 isFinite(val) && 20268 val > -9007199254740992 && 20269 val < 9007199254740992 && 20270 Math.floor(val) === val; 20271 }, 20272 20273 isNode: function(val) { 20274 return A.instanceOf(val, A.Node); 20275 }, 20276 20277 isNodeList: function(val) { 20278 return A.instanceOf(val, A.NodeList); 20279 }, 20280 20281 toFloat: function(value, defaultValue) { 20282 return parseFloat(value) || defaultValue || 0; 20283 }, 20284 20285 toInt: function(value, radix, defaultValue) { 20286 return parseInt(value, radix || 10) || defaultValue || 0; 20287 } 20288 }); 20289 20290 A.mix(aArray, { 20291 remove: function(a, from, to) { 20292 var rest = a.slice((to || from) + 1 || a.length); 20293 a.length = (from < 0) ? (a.length + from) : from; 20294 20295 return a.push.apply(a, rest); 20296 }, 20297 20298 removeItem: function(a, item) { 20299 var index = aArray.indexOf(a, item); 20300 20301 if (index > -1) { 20302 return aArray.remove(a, index); 20303 } 20304 20305 return a; 20306 } 20307 }); 20308 20309 var LString = A.namespace('Lang.String'), 20310 20311 DOC = A.config.doc, 20312 REGEX_DASH = /-([a-z])/gi, 20313 REGEX_ESCAPE_REGEX = /([.*+?^$(){}|[\]\/\\])/g, 20314 REGEX_NL2BR = /\r?\n/g, 20315 REGEX_STRIP_SCRIPTS = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/gi, 20316 REGEX_STRIP_TAGS = /<\/?[^>]+>/gi, 20317 REGEX_UNCAMELIZE = /([a-zA-Z][a-zA-Z])([A-Z])([a-z])/g, 20318 REGEX_UNCAMELIZE_REPLACE_SEPARATOR = /([a-z])([A-Z])/g, 20319 STR_ELLIPSIS = '...', 20320 20321 htmlUnescapedValues = [], 20322 20323 MAP_HTML_CHARS_ESCAPED = { 20324 '&': '&', 20325 '<': '<', 20326 '>': '>', 20327 '"': '"', 20328 '\'': ''', 20329 '/': '/', 20330 '`': '`' 20331 }, 20332 htmlChar, 20333 MAP_HTML_CHARS_UNESCAPED = {}; 20334 20335 for (htmlChar in MAP_HTML_CHARS_ESCAPED) { 20336 if (MAP_HTML_CHARS_ESCAPED.hasOwnProperty(htmlChar)) { 20337 var escapedValue = MAP_HTML_CHARS_ESCAPED[htmlChar]; 20338 20339 MAP_HTML_CHARS_UNESCAPED[escapedValue] = htmlChar; 20340 20341 htmlUnescapedValues.push(htmlChar); 20342 } 20343 } 20344 20345 var REGEX_HTML_ESCAPE = new RegExp('[' + htmlUnescapedValues.join('') + ']', 'g'), 20346 REGEX_HTML_UNESCAPE = /&([^;]+);/g; 20347 20348 A.mix(LString, { 20349 camelize: A.cached( 20350 function(str, separator) { 20351 var regex = REGEX_DASH; 20352 20353 str = String(str); 20354 20355 if (separator) { 20356 regex = new RegExp(separator + '([a-z])', 'gi'); 20357 } 20358 20359 return str.replace(regex, LString._camelize); 20360 } 20361 ), 20362 20363 capitalize: A.cached( 20364 function(str) { 20365 if (str) { 20366 str = String(str); 20367 20368 str = str.charAt(0).toUpperCase() + str.substr(1).toLowerCase(); 20369 } 20370 20371 return str; 20372 } 20373 ), 20374 20375 contains: function(str, searchString) { 20376 return str.indexOf(searchString) !== -1; 20377 }, 20378 20379 defaultValue: function(str, defaultValue) { 20380 if (isUndefined(str) || str === '') { 20381 if (isUndefined(defaultValue)) { 20382 defaultValue = ''; 20383 } 20384 20385 str = defaultValue; 20386 } 20387 20388 return str; 20389 }, 20390
20391 endsWith: function(str, suffix) { 20392 var length = (str.length - suffix.length); 20393 20394 return ((length >= 0) && (str.indexOf(suffix, length) === length)); 20395 }, 20396 20397 escapeHTML: function(str) { 20398 return str.replace(REGEX_HTML_ESCAPE, LString._escapeHTML); 20399 }, 20400 20401 // Courtesy of: http://simonwillison.net/2006/Jan/20/escape/ 20402 escapeRegEx: function(str) { 20403 return str.replace(REGEX_ESCAPE_REGEX, '\\$1'); 20404 }, 20405 20406 nl2br: function(str) { 20407 return String(str).replace(REGEX_NL2BR, '<br />'); 20408 }, 20409 20410 padNumber: function(num, length, precision) { 20411 var str = precision ? Number(num).toFixed(precision) : String(num); 20412 var index = str.indexOf('.'); 20413 20414 if (index === -1) { 20415 index = str.length; 20416 } 20417 20418 return LString.repeat('0', Math.max(0, length - index)) + str; 20419 }, 20420 20421 pluralize: function(count, singularVersion, pluralVersion) { 20422 var suffix; 20423 20424 if (count === 1) { 20425 suffix = singularVersion; 20426 } 20427 else { 20428 suffix = pluralVersion || singularVersion + 's'; 20429 } 20430 20431 return count + ' ' + suffix; 20432 }, 20433 20434 prefix: function(prefix, str) { 20435 str = String(str); 20436 20437 if (str.indexOf(prefix) !== 0) { 20438 str = prefix + str; 20439 } 20440 20441 return str; 20442 }, 20443 20444 remove: function(str, substitute, all) { 20445 var re = new RegExp(LString.escapeRegEx(substitute), all ? 'g' : ''); 20446 20447 return str.replace(re, ''); 20448 }, 20449 20450 removeAll: function(str, substitute) { 20451 return LString.remove(str, substitute, true); 20452 }, 20453 20454 repeat: function(str, length) { 20455 return new Array(length + 1).join(str); 20456 }, 20457 20458 round: function(value, precision) { 20459 value = Number(value); 20460 20461 if (isNumber(precision)) { 20462 precision = Math.pow(10, precision); 20463 value = Math.round(value * precision) / precision; 20464 } 20465 20466 return value; 20467 }, 20468 20469 startsWith: function(str, prefix) { 20470 return (str.lastIndexOf(prefix, 0) === 0); 20471 }, 20472 20473 stripScripts: function(str) { 20474 if (str) { 20475 str = String(str).replace(REGEX_STRIP_SCRIPTS, ''); 20476 } 20477 20478 return str; 20479 }, 20480 20481 stripTags: function(str) { 20482 if (str) { 20483 str = String(str).replace(REGEX_STRIP_TAGS, ''); 20484 } 20485 20486 return str; 20487 }, 20488 20489 substr: function(str, start, length) { 20490 return String(str).substr(start, length); 20491 }, 20492 20493 uncamelize: A.cached( 20494 function(str, separator) { 20495 separator = separator || ' '; 20496 20497 str = String(str); 20498 20499 str = str.replace(REGEX_UNCAMELIZE, '$1' + separator + '$2$3'); 20500 str = str.replace(REGEX_UNCAMELIZE_REPLACE_SEPARATOR, '$1' + separator + '$2'); 20501 20502 return str; 20503 } 20504 ), 20505 20506 toLowerCase: function(str) { 20507 return String(str).toLowerCase(); 20508 }, 20509 20510 toUpperCase: function(str) { 20511 return String(str).toUpperCase(); 20512 }, 20513 20514 trim: Lang.trim, 20515 20516 truncate: function(str, length, where) { 20517 str = String(str); 20518 20519 var ellipsisLength = STR_ELLIPSIS.length, 20520 strLength = str.length; 20521 20522 if (length > 3) { 20523 if (str && (strLength > length)) { 20524 where = where || 'end'; 20525 20526 if (where === 'end') { 20527 str = str.substr(0, (length - ellipsisLength)) + STR_ELLIPSIS; 20528 } 20529 else if (where === 'middle') { 20530 var middlePointA = Math.floor((length - ellipsisLength) / 2), 20531 middlePointB = middlePointA; 20532 20533 if (length % 2 === 0) {
20534 middlePointA = Math.ceil((length - ellipsisLength) / 2); 20535 middlePointB = Math.floor((length - ellipsisLength) / 2); 20536 } 20537 20538 str = str.substr(0, middlePointA) + STR_ELLIPSIS + str.substr(strLength - middlePointB); 20539 } 20540 else if (where === 'start') { 20541 str = STR_ELLIPSIS + str.substr(strLength - length + ellipsisLength); 20542 } 20543 } 20544 } 20545 else { 20546 str = STR_ELLIPSIS; 20547 } 20548 20549 return str; 20550 }, 20551 20552 undef: function(str) { 20553 if (isUndefined(str)) { 20554 str = ''; 20555 } 20556 20557 return str; 20558 }, 20559 20560 // inspired from Google unescape entities 20561 unescapeEntities: function(str) { 20562 if (LString.contains(str, '&')) { 20563 if (DOC && !LString.contains(str, '<')) { 20564 str = LString._unescapeEntitiesUsingDom(str); 20565 } 20566 else { 20567 str = LString.unescapeHTML(str); 20568 } 20569 } 20570 20571 return str; 20572 }, 20573 20574 unescapeHTML: function(str) { 20575 return str.replace(REGEX_HTML_UNESCAPE, LString._unescapeHTML); 20576 }, 20577 20578 _camelize: function(match0, match1) { 20579 return match1.toUpperCase(); 20580 }, 20581 20582 _escapeHTML: function(match) { 20583 return MAP_HTML_CHARS_ESCAPED[match]; 20584 }, 20585 20586 _unescapeHTML: function(match, entity) { 20587 var value = MAP_HTML_CHARS_UNESCAPED[match] || match; 20588 20589 if (!value && entity.charAt(0) === '#') { 20590 var charCode = Number('0' + value.substr(1)); 20591 20592 if (!isNaN(charCode)) { 20593 value = String.fromCharCode(charCode); 20594 } 20595 } 20596 20597 return value; 20598 }, 20599 20600 _unescapeEntitiesUsingDom: function(str) { 20601 var el = DOC.createElement('a'); 20602 20603 el.innerHTML = str; 20604 20605 if (el.normalize) { 20606 el.normalize(); 20607 } 20608 20609 str = el.firstChild.nodeValue; 20610 20611 el.innerHTML = ''; 20612 20613 return str; 20614 } 20615 }); 20616 20617 /* 20618 * Maps an object to an array, using the return value of fn as the values 20619 * for the new array. 20620 */ 20621 AObject.map = function(obj, fn, context) { 20622 var map = [], 20623 i; 20624 20625 for (i in obj) { 20626 if (owns(obj, i)) { 20627 map[map.length] = fn.call(context, obj[i], i, obj); 20628 } 20629 } 20630 20631 return map; 20632 }; 20633 20634 /* 20635 * Maps an array or object to a resulting array, using the return value of 20636 * fn as the values for the new array. Like A.each, this function can accept 20637 * an object or an array. 20638 */ 20639 A.map = function(obj) { 20640 var module = AObject; 20641 20642 if (isArray(obj)) { 20643 module = aArray; 20644 } 20645 20646 return module.map.apply(this, arguments); 20647 }; 20648}()); 20649 20650 20651}, '3.1.0-deprecated.77'); 20652 20653/** 20654 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 20655 * 20656 * This library is free software; you can redistribute it and/or modify it under 20657 * the terms of the GNU Lesser General Public License as published by the Free 20658 * Software Foundation; either version 2.1 of the License, or (at your option) 20659 * any later version. 20660 * 20661 * This library is distributed in the hope that it will be useful, but WITHOUT 20662 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 20663 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 20664 * details. 20665 */ 20666(function () { 20667 var A = AUI().use('oop'); 20668 var usedModules = {}; 20669 var Dependency = { 20670 _getAOP: function _getAOP(obj, methodName) { 20671 return obj._yuiaop && obj._yuiaop[methodName]; 20672 }, 20673 _proxy: function _proxy(obj, methodName, methodFn, context, guid, modules, _A) { 20674 var args; 20675 var queue = Dependency._proxyLoaders[guid]; 20676 20677 Dependency._replaceMethod(obj, methodName, methodFn, context); 20678 20679 while (args = queue.next()) {
20680 methodFn.apply(context, args); 20681 } 20682 20683 for (var i = modules.length - 1; i >= 0; i--) { 20684 usedModules[modules[i]] = true; 20685 } 20686 }, 20687 _proxyLoaders: {}, 20688 _replaceMethod: function _replaceMethod(obj, methodName, methodFn) { 20689 var AOP = Dependency._getAOP(obj, methodName); 20690 20691 var proxy = obj[methodName]; 20692 20693 if (AOP) { 20694 proxy = AOP.method; 20695 AOP.method = methodFn; 20696 } else { 20697 obj[methodName] = methodFn; 20698 } 20699 20700 A.mix(methodFn, proxy); 20701 }, 20702 provide: function provide(obj, methodName, methodFn, modules, proto) { 20703 if (!Array.isArray(modules)) { 20704 modules = [modules]; 20705 } 20706 20707 var before; 20708 var guid = A.guid(); 20709 20710 if (A.Lang.isObject(methodFn, true)) { 20711 var config = methodFn; 20712 methodFn = config.fn; 20713 before = config.before; 20714 20715 if (!A.Lang.isFunction(before)) { 20716 before = null; 20717 } 20718 } 20719 20720 if (proto && A.Lang.isFunction(obj)) { 20721 obj = obj.prototype; 20722 } 20723 20724 var AOP = Dependency._getAOP(obj, methodName); 20725 20726 if (AOP) { 20727 delete obj._yuiaop[methodName]; 20728 } 20729 20730 var proxy = function proxy() { 20731 var args = arguments; 20732 var context = obj; 20733 20734 if (proto) { 20735 context = this; 20736 } 20737 20738 if (modules.length == 1) { 20739 if (modules[0] in usedModules) { 20740 Dependency._replaceMethod(obj, methodName, methodFn, context); 20741 20742 methodFn.apply(context, args); 20743 return; 20744 } 20745 } 20746 20747 var firstLoad = false; 20748 var queue = Dependency._proxyLoaders[guid]; 20749 20750 if (!queue) { 20751 firstLoad = true; 20752 Dependency._proxyLoaders[guid] = new A.Queue(); 20753 queue = Dependency._proxyLoaders[guid]; 20754 } 20755 20756 queue.add(args); 20757 20758 if (firstLoad) { 20759 modules.push(A.bind(Dependency._proxy, Liferay, obj, methodName, methodFn, context, guid, modules)); 20760 A.use.apply(A, modules); 20761 } 20762 }; 20763 20764 proxy.toString = function () { 20765 return methodFn.toString(); 20766 }; 20767 20768 obj[methodName] = proxy; 20769 } 20770 }; 20771 Liferay.Dependency = Dependency; 20772 Liferay.provide = Dependency.provide; 20773})(); 20774//# sourceMappingURL=dependency.js.map 20775function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 20776 20777function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } 20778 20779function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } 20780 20781function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 20782 20783/** 20784 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 20785 * 20786 * This library is free software; you can redistribute it and/or modify it under 20787 * the terms of the GNU Lesser General Public License as published by the Free 20788 * Software Foundation; either version 2.1 of the License, or (at your option) 20789 * any later version. 20790 * 20791 * This library is distributed in the hope that it will be useful, but WITHOUT 20792 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 20793 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 20794 * details. 20795 */ 20796(function (A, Liferay) { 20797 A.use('aui-base-lang'); 20798 var AArray = A.Array; 20799 var Lang = A.Lang; 20800 var EVENT_CLICK = 'click'; 20801 var MAP_TOGGLE_STATE = { 20802 "false": { 20803 cssClass: 'controls-hidden', 20804 iconCssClass: 'hidden', 20805 state: 'hidden' 20806 }, 20807 "true": { 20808 cssClass: 'controls-visible', 20809 iconCssClass: 'view', 20810 state: 'visible' 20811 } 20812 }; 20813 var REGEX_SUB = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g; 20814 var SRC_HIDE_LINK = { 20815 src: 'hideLink' 20816 }; 20817 var STR_RIGHT_SQUARE_BRACKET = ']'; 20818 var TPL_LEXICON_ICON = '<svg class="lexicon-icon lexicon-icon-{0} {1}" focusable="false" role="image">' + '<use data-href="' + themeDisplay.getPathThemeImages() + '/lexicon/icons.svg#{0}" />' + '</svg>'; 20819 var Window = { 20820 _map: {}, 20821 getById: function getById(id) { 20822 var instance = this; 20823 return instance._map[id]; 20824 } 20825 }; 20826 var Util = { 20827 _getEditableInstance: function _getEditableInstance(title) { 20828 var editable = Util._EDITABLE; 20829 20830 if (!editable) { 20831 editable = new A.Editable({ 20832 after: { 20833 contentTextChange: function contentTextChange(event) { 20834 var instance = this; 20835 20836 if (!event.initial) { 20837 var title = instance.get('node'); 20838 var portletTitleEditOptions = title.getData('portletTitleEditOptions'); 20839 Util.savePortletTitle({ 20840 doAsUserId: portletTitleEditOptions.doAsUserId, 20841 plid: portletTitleEditOptions.plid, 20842 portletId: portletTitleEditOptions.portletId, 20843 title: event.newVal 20844 }); 20845 } 20846 }, 20847 startEditing: function startEditing() { 20848 var instance = this; 20849 var Layout = Liferay.Layout; 20850 20851 if (Layout) { 20852 instance._dragListener = Layout.getLayoutHandler().on('drag:start', function () { 20853 instance.fire('save'); 20854 }); 20855 } 20856 20857 var title = instance.get('node'); 20858 instance._titleListener = title.on('mouseupoutside', function (event) { 20859 var editable = Util._getEditableInstance(title); 20860 20861 if (!editable.get('boundingBox').contains(event.target)) { 20862 editable.save(); 20863 } 20864 }); 20865 }, 20866 stopEditing: function stopEditing() { 20867 var instance = this; 20868 20869 if (instance._dragListener) { 20870 instance._dragListener.detach(); 20871 } 20872 20873 if (instance._titleListener) { 20874 instance._titleListener.detach(); 20875 } 20876 } 20877 }, 20878 cssClass: 'lfr-portlet-title-editable', 20879 node: title 20880 }); 20881 editable.get('cancelButton').icon = 'times'; 20882 editable.get('saveButton').icon = 'check'; 20883 Util._EDITABLE = editable; 20884 } 20885 20886 return editable; 20887 }, 20888 addInputCancel: function addInputCancel() { 20889 A.use('aui-button-search-cancel', function (A) { 20890 new A.ButtonSearchCancel({ 20891 trigger: 'input[type=password], input[type=search], input.clearable, input.search-query' 20892 }); 20893 }); 20894 20895 Util.addInputCancel = function () {}; 20896 }, 20897 checkAll: function checkAll(form, name, allBox, selectClassName) { 20898 if (form) { 20899 form = Util.getDOM(form); 20900 20901 if (typeof form === 'string') { 20902 form = document.querySelector(form); 20903 } 20904 20905 allBox = Util.getDOM(allBox); 20906 20907 if (typeof allBox === 'string') { 20908 allBox = document.querySelector(allBox); 20909 } 20910 20911 var selector; 20912 20913 if (Array.isArray(name)) { 20914 selector = 'input[name=' + name.join('], input[name=') + STR_RIGHT_SQUARE_BRACKET; 20915 } else { 20916 selector = 'input[name=' + name + STR_RIGHT_SQUARE_BRACKET; 20917 } 20918 20919 var allBoxChecked = allBox.checked; 20920 var uploadedItems = Array.from(form.querySelectorAll(selector));
20921 uploadedItems.forEach(function (item) { 20922 if (!item.disabled) { 20923 item.checked = allBoxChecked; 20924 } 20925 }); 20926 20927 if (selectClassName) { 20928 var selectItem = form.querySelector(selectClassName); 20929 20930 if (allBoxChecked) { 20931 selectItem.classList.add('info'); 20932 } else { 20933 selectItem.classList.remove('info'); 20934 } 20935 } 20936 } 20937 }, 20938 checkAllBox: function checkAllBox(form, name, allBox) { 20939 var totalOn = 0; 20940 20941 if (form) { 20942 form = Util.getDOM(form); 20943 20944 if (typeof form === 'string') { 20945 form = document.querySelector(form); 20946 } 20947 20948 allBox = Util.getDOM(allBox); 20949 20950 if (typeof allBox === 'string') { 20951 allBox = document.querySelector(allBox) || form.querySelector("input[name=\"".concat(allBox, "\"]")); 20952 } 20953 20954 var inputs = Array.from(form.querySelectorAll('input[type=checkbox]')); 20955 20956 if (!Array.isArray(name)) { 20957 name = [name]; 20958 } 20959 20960 var totalBoxes = 0; 20961 inputs.forEach(function (input) { 20962 if (input.id !== allBox.id || input.id !== allBox.name && name.indexOf(input.name) > -1) { 20963 totalBoxes++; 20964 20965 if (input.checked) { 20966 totalOn++; 20967 } 20968 } 20969 }); 20970 allBox.checked = totalBoxes === totalOn; 20971 } 20972 20973 return totalOn; 20974 }, 20975 checkTab: function checkTab(box) { 20976 if (document.all && window.event.keyCode == 9) { 20977 box.selection = document.selection.createRange(); 20978 setTimeout(function () { 20979 Util.processTab(box.id); 20980 }, 0); 20981 } 20982 }, 20983 disableElements: function disableElements(el) { 20984 var currentElement = Util.getElement(el); 20985 20986 if (currentElement) { 20987 var children = currentElement.getElementsByTagName('*'); 20988 20989 var emptyFnFalse = function emptyFnFalse() { 20990 return false; 20991 }; 20992 20993 for (var i = children.length - 1; i >= 0; i--) { 20994 var item = children[i]; 20995 item.style.cursor = 'default'; 20996 item.onclick = emptyFnFalse; 20997 item.onmouseover = emptyFnFalse; 20998 item.onmouseout = emptyFnFalse; 20999 item.onmouseenter = emptyFnFalse; 21000 item.onmouseleave = emptyFnFalse; 21001 item.action = ''; 21002 item.disabled = true; 21003 item.href = 'javascript:;'; 21004 item.onsubmit = emptyFnFalse; 21005 } 21006 } 21007 }, 21008 disableFormButtons: function disableFormButtons(inputs, form) { 21009 inputs.attr('disabled', true); 21010 inputs.setStyle('opacity', 0.5); 21011 21012 if (A.UA.gecko) { 21013 A.getWin().on('unload', function () { 21014 inputs.attr('disabled', false); 21015 }); 21016 } else if (A.UA.safari) { 21017 A.use('node-event-html5', function (A) { 21018 A.getWin().on('pagehide', function () { 21019 Util.enableFormButtons(inputs, form); 21020 }); 21021 }); 21022 } 21023 }, 21024 disableToggleBoxes: function disableToggleBoxes(checkBoxId, toggleBoxId, checkDisabled) { 21025 var checkBox = document.getElementById(checkBoxId); 21026 var toggleBox = document.getElementById(toggleBoxId); 21027 21028 if (checkBox && toggleBox) { 21029 toggleBox.disabled = checkDisabled && checkBox.checked; 21030 checkBox.addEventListener(EVENT_CLICK, function () { 21031 toggleBox.disabled = !toggleBox.disabled; 21032 }); 21033 } 21034 }, 21035 enableFormButtons: function enableFormButtons(inputs) { 21036 Util._submitLocked = null; 21037 Util.toggleDisabled(inputs, false); 21038 }, 21039 21040 /** 21041 * @deprecated As of Athanasius (7.3.x), with no direct replacement 21042 */ 21043 escapeCDATA: function escapeCDATA(str) { 21044 return str.replace(/<!\[CDATA\[|\]\]>/gi, function (match) { 21045 var str = ''; 21046 21047 if (match == ']]>') { 21048 str = ']]>'; 21049 } else if (match == '<![CDATA[') { 21050 str = '<![CDATA['; 21051 } 21052 21053 return str; 21054 }); 21055 }, 21056 forcePost: function forcePost(link) { 21057 var currentElement = Util.getElement(link); 21058 21059 if (currentElement) { 21060 var url = currentElement.getAttribute('href'); 21061 var newWindow = currentElement.getAttribute('target') == '_blank'; 21062 var hrefFm = document.hrefFm; 21063 21064 if (newWindow) { 21065 hrefFm.setAttribute('target', '_blank'); 21066 } 21067 21068 submitForm(hrefFm, url, !newWindow); 21069 Util._submitLocked = null; 21070 } 21071 }, 21072 getAttributes: function getAttributes(el, attributeGetter) { 21073 var result = null; 21074 21075 if (el) { 21076 el = Util.getDOM(el); 21077 21078 if (el.jquery) { 21079 el = el[0]; 21080 } 21081 21082 result = {}; 21083 var getterFn = typeof attributeGetter === 'function'; 21084 var getterString = typeof attributeGetter === 'string'; 21085 var attrs = el.attributes; 21086 var length = attrs.length; 21087 21088 while (length--) { 21089 var attr = attrs[length]; 21090 var name = attr.nodeName.toLowerCase(); 21091 var value = attr.nodeValue; 21092 21093 if (getterString) { 21094 if (name.indexOf(attributeGetter) === 0) { 21095 name = name.substr(attributeGetter.length); 21096 } else { 21097 continue; 21098 } 21099 } else if (getterFn) { 21100 value = attributeGetter(value, name, attrs); 21101 21102 if (value === false) { 21103 continue; 21104 } 21105 } 21106 21107 result[name] = value; 21108 } 21109 } 21110 21111 return result; 21112 }, 21113 getColumnId: function getColumnId(str) { 21114 var columnId = str.replace(/layout-column_/, ''); 21115 return columnId; 21116 }, 21117 getGeolocation: function getGeolocation(success, fallback, options) { 21118 if (success && navigator.geolocation) { 21119 navigator.geolocation.getCurrentPosition(function (position) { 21120 success(position.coords.latitude, position.coords.longitude, position); 21121 }, fallback, options); 21122 } else if (fallback) { 21123 fallback(); 21124 } 21125 }, 21126 getLexiconIcon: function getLexiconIcon(icon, cssClass) { 21127 var instance = this; 21128 var tempElement = document.createElement('div'); 21129 tempElement.innerHTML = instance.getLexiconIconTpl(icon, cssClass); 21130 return tempElement.firstChild; 21131 }, 21132 getLexiconIconTpl: function getLexiconIconTpl(icon, cssClass) { 21133 return Liferay.Util.sub(TPL_LEXICON_ICON, icon, cssClass || ''); 21134 }, 21135 getOpener: function getOpener() { 21136 var openingWindow = Window._opener; 21137 21138 if (!openingWindow) { 21139 var topUtil = Liferay.Util.getTop().Liferay.Util; 21140 var windowName = Liferay.Util.getWindowName(); 21141 var dialog = topUtil.Window.getById(windowName); 21142 21143 if (dialog) { 21144 openingWindow = dialog._opener; 21145 Window._opener = openingWindow; 21146 } 21147 } 21148 21149 return openingWindow || window.opener || window.parent; 21150 }, 21151 getTop: function getTop() { 21152 var topWindow = Util._topWindow; 21153 21154 if (!topWindow) { 21155 var parentWindow = window.parent; 21156 var parentThemeDisplay; 21157 21158 while (parentWindow != window) { 21159 try { 21160 if (typeof parentWindow.location.href == 'undefined') { 21161 break; 21162 } 21163 21164 parentThemeDisplay = parentWindow.themeDisplay; 21165 } catch (e) { 21166 break; 21167 } 21168 21169 if (!parentThemeDisplay || window.name === 'simulationDeviceIframe') { 21170 break; 21171 } else if (!parentThemeDisplay.isStatePopUp() || parentWindow == parentWindow.parent) { 21172 topWindow = parentWindow; 21173 break; 21174 } 21175 21176 parentWindow = parentWindow.parent; 21177 } 21178 21179 if (!topWindow) { 21180 topWindow = window; 21181 } 21182 21183 Util._topWindow = topWindow; 21184 } 21185 21186 return topWindow; 21187 }, 21188 getURLWithSessionId: function getURLWithSessionId(url) { 21189 if (!themeDisplay.isAddSessionIdToURL()) { 21190 return url; 21191 } // LEP-4787 21192 21193 21194 var x = url.indexOf(';'); 21195 21196 if (x > -1) { 21197 return url; 21198 } 21199 21200 var sessionId = ';jsessionid=' + themeDisplay.getSessionId(); 21201 x = url.indexOf('?'); 21202 21203 if (x > -1) { 21204 return url.substring(0, x) + sessionId + url.substring(x); 21205 } // In IE6, http://www.abc.com;jsessionid=XYZ does not work, but 21206 // http://www.abc.com/;jsessionid=XYZ does work. 21207 21208 21209 x = url.indexOf('//'); 21210 21211 if (x > -1) { 21212 var y = url.lastIndexOf('/'); 21213 21214 if (x + 1 == y) { 21215 return url + '/' + sessionId; 21216 } 21217 } 21218 21219 return url + sessionId; 21220 }, 21221 getWindow: function getWindow(id) { 21222 if (!id) { 21223 id = Util.getWindowName(); 21224 } 21225 21226 return Util.getTop().Liferay.Util.Window.getById(id); 21227 }, 21228 getWindowName: function getWindowName() { 21229 return window.name || Window._name || ''; 21230 }, 21231 21232 /** 21233 * @deprecated As of Athanasius (7.3.x), replaced by `window.innerWidth` 21234 */ 21235 getWindowWidth: function getWindowWidth() { 21236 return window.innerWidth; 21237 }, 21238 21239 /** 21240 * @deprecated As of Athanasius (7.3.x), replaced by `typeof val === 'function'` 21241 */ 21242 isFunction: function isFunction(val) { 21243 return typeof val === 'function'; 21244 }, 21245 listCheckboxesExcept: function listCheckboxesExcept(form, except, name, checked) { 21246 form = Util.getDOM(form); 21247 21248 if (typeof form === 'string') { 21249 form = document.querySelector(form); 21250 } 21251 21252 var selector = 'input[type=checkbox]'; 21253 21254 if (name) { 21255 selector += '[name=' + name + ']'; 21256 } 21257 21258 var checkboxes = Array.from(form.querySelectorAll(selector)); 21259 return checkboxes.reduce(function (prev, item) { 21260 var value = item.value; 21261 21262 if (value && item.name !== except && item.checked === checked && !item.disabled) { 21263 prev.push(value); 21264 } 21265 21266 return prev; 21267 }, []).join(); 21268 }, 21269 listCheckedExcept: function listCheckedExcept(form, except, name) { 21270 return Util.listCheckboxesExcept(form, except, name, true); 21271 }, 21272 listSelect: function listSelect(select, delimeter) { 21273 select = Util.getElement(select); 21274 return Array.from(select.querySelectorAll('option')).reduce(function (prev, item) { 21275 var val = item.value; 21276 21277 if (val) { 21278 prev.push(val); 21279 } 21280 21281 return prev; 21282 }, []).join(delimeter || ','); 21283 }, 21284 listUncheckedExcept: function listUncheckedExcept(form, except, name) { 21285 return Util.listCheckboxesExcept(form, except, name, false); 21286 }, 21287 openInDialog: function openInDialog(event, config) { 21288 event.preventDefault(); 21289 var currentTarget = Util.getElement(event.currentTarget); 21290 config = A.mix(A.merge({}, currentTarget.dataset), config); 21291 21292 if (!config.uri) { 21293 config.uri = currentTarget.dataset.href || currentTarget.getAttribute('href'); 21294 } 21295 21296 if (!config.title) { 21297 config.title = currentTarget.getAttribute('title'); 21298 } 21299 21300 Liferay.Util.openWindow(config); 21301 }, 21302 openWindow: function openWindow(config, callback) { 21303 config.openingWindow = window; 21304 var top = Util.getTop(); 21305 var topUtil = top.Liferay.Util; 21306 21307 topUtil._openWindowProvider(config, callback); 21308 }, 21309 processTab: function processTab(id) { 21310 document.all[id].selection.text = String.fromCharCode(9); 21311 document.all[id].focus(); 21312 }, 21313 21314 /** 21315 * @deprecated As of Athanasius (7.3.x), with no direct replacement 21316 */ 21317 randomInt: function randomInt() { 21318 return Math.ceil(Math.random() * new Date().getTime()); 21319 }, 21320 removeEntitySelection: function removeEntitySelection(entityIdString, entityNameString, removeEntityButton, namespace) { 21321 var elementByEntityId = document.getElementById("".concat(namespace).concat(entityIdString)); 21322 21323 if (elementByEntityId) { 21324 elementByEntityId.value = 0; 21325 } 21326 21327 var elementByEntityName = document.getElementById("".concat(namespace).concat(entityNameString)); 21328 21329 if (elementByEntityName) { 21330 elementByEntityName.value = ''; 21331 } 21332 21333 Liferay.Util.toggleDisabled(removeEntityButton, true); 21334 Liferay.fire('entitySelectionRemoved'); 21335 }, 21336 reorder: function reorder(box, down) { 21337 box = Util.getElement(box); 21338 21339 if (box) { 21340 if (box.getAttribute('selectedIndex') == -1) { 21341 box.setAttribute('selectedIndex', 0); 21342 } else { 21343 var selectedItems = Array.from(box.querySelectorAll('option:checked')); 21344 var items = Array.from(box.querySelectorAll('option')); 21345 21346 if (down) {
21347 selectedItems.reverse().forEach(function (item) { 21348 var itemIndex = items.indexOf(item); 21349 var lastIndex = items.length - 1; 21350 21351 if (itemIndex === lastIndex) { 21352 box.insertBefore(item, box.firstChild); 21353 } else { 21354 var nextItem = item.nextElementSibling.nextElementSibling; 21355 box.insertBefore(item, nextItem); 21356 } 21357 }); 21358 } else { 21359 selectedItems.forEach(function (item) { 21360 var itemIndex = items.indexOf(item); 21361 21362 if (itemIndex === 0) { 21363 box.appendChild(item); 21364 } else { 21365 box.insertBefore(item, item.previousElementSibling); 21366 } 21367 }); 21368 } 21369 } 21370 } 21371 }, 21372 rowCheckerCheckAllBox: function rowCheckerCheckAllBox(ancestorTable, ancestorRow, checkboxesIds, checkboxAllIds, cssClass) { 21373 Util.checkAllBox(ancestorTable, checkboxesIds, checkboxAllIds); 21374 21375 if (ancestorRow) { 21376 ancestorRow.toggleClass(cssClass); 21377 } 21378 }, 21379 savePortletTitle: function savePortletTitle(params) { 21380 params = _objectSpread({ 21381 doAsUserId: 0, 21382 plid: 0, 21383 portletId: 0, 21384 title: '', 21385 url: themeDisplay.getPathMain() + '/portal/update_portlet_title' 21386 }, params); 21387 var data = { 21388 doAsUserId: params.doAsUserId, 21389 p_auth: Liferay.authToken, 21390 p_l_id: params.plid, 21391 portletId: params.portletId, 21392 title: params.title 21393 }; 21394 Liferay.Util.fetch(params.url, { 21395 body: Liferay.Util.objectToFormData(data), 21396 method: 'POST' 21397 }); 21398 }, 21399 selectFolder: function selectFolder(folderData, namespace) { 21400 var folderDataElement = document.getElementById(namespace + folderData.idString); 21401 21402 if (folderDataElement) { 21403 folderDataElement.value = folderData.idValue; 21404 } 21405 21406 var folderNameElement = document.getElementById(namespace + folderData.nameString); 21407 21408 if (folderNameElement) { 21409 folderNameElement.value = this.unescape(folderData.nameValue); 21410 } 21411 21412 var removeFolderButton = document.getElementById("".concat(namespace, "removeFolderButton")); 21413 21414 if (removeFolderButton) { 21415 this.toggleDisabled(removeFolderButton, false); 21416 } 21417 }, 21418 setCursorPosition: function setCursorPosition(el, position) { 21419 var instance = this; 21420 instance.setSelectionRange(el, position, position); 21421 }, 21422 setSelectionRange: function setSelectionRange(el, selectionStart, selectionEnd) { 21423 el = Util.getDOM(el); 21424 21425 if (el.jquery) { 21426 el = el[0]; 21427 } 21428 21429 if (el.setSelectionRange) { 21430 el.focus(); 21431 el.setSelectionRange(selectionStart, selectionEnd); 21432 } else if (el.createTextRange) { 21433 var textRange = el.createTextRange(); 21434 textRange.collapse(true); 21435 textRange.moveEnd('character', selectionEnd); 21436 textRange.moveEnd('character', selectionStart); 21437 textRange.select(); 21438 } 21439 }, 21440 showCapsLock: function showCapsLock(event, spanId) { 21441 var span = document.getElementById(spanId); 21442 21443 if (span) { 21444 var keyCode = event.keyCode ? event.keyCode : event.which; 21445 var shiftKeyCode = keyCode === 16; 21446 var shiftKey = event.shiftKey ? event.shiftKey : shiftKeyCode; 21447 var display = 'none'; 21448 21449 if (keyCode >= 65 && keyCode <= 90 && !shiftKey || keyCode >= 97 && keyCode <= 122 && shiftKey) { 21450 display = ''; 21451 } 21452 21453 span.style.display = display; 21454 } 21455 }, 21456 21457 /** 21458 * @deprecated As of Athanasius (7.3.x), with no direct replacement 21459 */ 21460 sortByAscending: function sortByAscending(a, b) { 21461 a = a[1].toLowerCase(); 21462 b = b[1].toLowerCase(); 21463 21464 if (a > b) { 21465 return 1; 21466 } 21467 21468 if (a < b) { 21469 return -1; 21470 } 21471 21472 return 0; 21473 }, 21474 sub: function sub(string, data) { 21475 if (arguments.length > 2 || _typeof(data) !== 'object' && typeof data !== 'function') { 21476 data = Array.prototype.slice.call(arguments, 1); 21477 } 21478 21479 return string.replace ? string.replace(REGEX_SUB, function (match, key) { 21480 return data[key] === undefined ? match : data[key]; 21481 }) : string; 21482 }, 21483 submitCountdown: 0, 21484 submitForm: function submitForm(form) { 21485 form.submit(); 21486 }, 21487 21488 /** 21489 * @deprecated As of Athanasius (7.3.x), replaced by `parseInt()` 21490 */ 21491 toNumber: function toNumber(value) { 21492 return parseInt(value, 10) || 0; 21493 }, 21494 toggleBoxes: function toggleBoxes(checkBoxId, toggleBoxId, displayWhenUnchecked, toggleChildCheckboxes) { 21495 var checkBox = document.getElementById(checkBoxId); 21496 var toggleBox = document.getElementById(toggleBoxId); 21497 21498 if (checkBox && toggleBox) { 21499 var checked = checkBox.checked; 21500 21501 if (displayWhenUnchecked) { 21502 checked = !checked; 21503 } 21504 21505 if (checked) { 21506 toggleBox.classList.remove('hide'); 21507 } else { 21508 toggleBox.classList.add('hide'); 21509 } 21510 21511 checkBox.addEventListener(EVENT_CLICK, function () { 21512 toggleBox.classList.toggle('hide'); 21513 21514 if (toggleChildCheckboxes) { 21515 var childCheckboxes = toggleBox.querySelectorAll('input[type=checkbox]');
21516 childCheckboxes.forEach(function (childCheckbox) { 21517 childCheckbox.checked = checkBox.checked; 21518 }); 21519 } 21520 }); 21521 } 21522 }, 21523 toggleRadio: function toggleRadio(radioId, showBoxIds, hideBoxIds) { 21524 var radioButton = document.getElementById(radioId); 21525 21526 if (radioButton) { 21527 var showBoxes; 21528 21529 if (showBoxIds) { 21530 if (Array.isArray(showBoxIds)) { 21531 showBoxIds = showBoxIds.join(',#'); 21532 } 21533 21534 showBoxes = document.querySelectorAll('#' + showBoxIds); 21535 showBoxes.forEach(function (showBox) { 21536 if (radioButton.checked) { 21537 showBox.classList.remove('hide'); 21538 } else { 21539 showBox.classList.add('hide'); 21540 } 21541 }); 21542 } 21543 21544 radioButton.addEventListener('change', function () { 21545 if (showBoxes) { 21546 showBoxes.forEach(function (showBox) { 21547 showBox.classList.remove('hide'); 21548 }); 21549 } 21550 21551 if (hideBoxIds) { 21552 if (Array.isArray(hideBoxIds)) { 21553 hideBoxIds = hideBoxIds.join(',#'); 21554 } 21555 21556 var hideBoxes = document.querySelectorAll('#' + hideBoxIds); 21557 hideBoxes.forEach(function (hideBox) { 21558 hideBox.classList.add('hide'); 21559 }); 21560 } 21561 }); 21562 } 21563 }, 21564 21565 /* 21566 * @deprecated As of Athanasius (7.3.x), with no direct replacement 21567 */ 21568 toggleSearchContainerButton: function toggleSearchContainerButton(buttonId, searchContainerId, form, ignoreFieldName) { 21569 A.one(searchContainerId).delegate(EVENT_CLICK, function () { 21570 Util.toggleDisabled(buttonId, !Util.listCheckedExcept(form, ignoreFieldName)); 21571 }, 'input[type=checkbox]'); 21572 }, 21573 toggleSelectBox: function toggleSelectBox(selectBoxId, value, toggleBoxId) { 21574 var selectBox = document.getElementById(selectBoxId); 21575 var toggleBox = document.getElementById(toggleBoxId); 21576 21577 if (selectBox && toggleBox) { 21578 var dynamicValue = typeof value === 'function'; 21579 21580 var toggle = function toggle() { 21581 var currentValue = selectBox.value; 21582 var visible = value == currentValue; 21583 21584 if (dynamicValue) { 21585 visible = value(currentValue, value); 21586 } 21587 21588 if (visible) { 21589 toggleBox.classList.remove('hide'); 21590 } else { 21591 toggleBox.classList.add('hide'); 21592 } 21593 }; 21594 21595 toggle(); 21596 selectBox.addEventListener('change', toggle); 21597 } 21598 } 21599 }; 21600 Liferay.provide(Util, 'afterIframeLoaded', function (event) { 21601 var nodeInstances = A.Node._instances; 21602 var docEl = event.doc; 21603 var docUID = docEl._yuid; 21604 21605 if (docUID in nodeInstances) { 21606 delete nodeInstances[docUID]; 21607 } 21608 21609 var iframeDocument = A.one(docEl); 21610 var iframeBody = iframeDocument.one('body'); 21611 var dialog = event.dialog; 21612 var lfrFormContent = iframeBody.one('.lfr-form-content'); 21613 iframeBody.addClass('dialog-iframe-popup'); 21614 21615 if (lfrFormContent && iframeBody.one('.button-holder.dialog-footer')) { 21616 iframeBody.addClass('dialog-with-footer'); 21617 var stagingAlert = iframeBody.one('.portlet-body > .lfr-portlet-message-staging-alert'); 21618 21619 if (stagingAlert) { 21620 stagingAlert.remove(); 21621 lfrFormContent.prepend(stagingAlert); 21622 } 21623 } 21624 21625 iframeBody.addClass(dialog.iframeConfig.bodyCssClass); 21626 event.win.focus(); 21627 var iframeWindow = event.win; 21628 21629 if (iframeWindow.Liferay.SPA) { 21630 var beforeScreenFlipHandler = iframeWindow.Liferay.on('beforeScreenFlip', function () { 21631 iframeWindow.document.body.classList.add('dialog-iframe-popup'); 21632 }); 21633 21634 iframeWindow.onunload = function () { 21635 if (beforeScreenFlipHandler) { 21636 iframeWindow.Liferay.detach(beforeScreenFlipHandler); 21637 } 21638 }; 21639 } 21640 21641 var detachEventHandles = function detachEventHandles() { 21642 AArray.invoke(eventHandles, 'detach'); 21643 iframeDocument.purge(true); 21644 }; 21645 21646 var eventHandles = [iframeBody.delegate('submit', detachEventHandles, 'form'), iframeBody.delegate(EVENT_CLICK, function (event) { 21647 dialog.set('visible', false, event.currentTarget.hasClass('lfr-hide-dialog') ? SRC_HIDE_LINK : null); 21648 detachEventHandles(); 21649 }, '.btn-cancel,.lfr-hide-dialog')]; 21650 Liferay.fire('modalIframeLoaded', { 21651 src: event.dialog.iframe.node.getAttribute('src') 21652 }); 21653 }, ['aui-base']); 21654 Liferay.provide(Util, 'openDDMPortlet', function (config, callback) { 21655 var defaultValues = { 21656 eventName: 'selectStructure' 21657 }; 21658 config = A.merge(defaultValues, config); 21659 var params = { 21660 classNameId: config.classNameId, 21661 classPK: config.classPK, 21662 doAsGroupId: config.doAsGroupId || themeDisplay.getScopeGroupId(), 21663 eventName: config.eventName, 21664 groupId: config.groupId, 21665 mvcPath: config.mvcPath || '/view.jsp', 21666 p_p_state: 'pop_up', 21667 portletResourceNamespace: config.portletResourceNamespace, 21668 resourceClassNameId: config.resourceClassNameId, 21669 scopeTitle: config.title, 21670 structureAvailableFields: config.structureAvailableFields, 21671 templateId: config.templateId 21672 }; 21673 21674 if ('mode' in config) { 21675 params.mode = config.mode; 21676 } 21677 21678 if ('navigationStartsOn' in config) { 21679 params.navigationStartsOn = config.navigationStartsOn; 21680 } 21681 21682 if ('redirect' in config) { 21683 params.redirect = config.redirect; 21684 } 21685 21686 if ('refererPortletName' in config) { 21687 params.refererPortletName = config.refererPortletName; 21688 } 21689 21690 if ('refererWebDAVToken' in config) { 21691 params.refererWebDAVToken = config.refererWebDAVToken; 21692 } 21693 21694 if ('searchRestriction' in config) { 21695 params.searchRestriction = config.searchRestriction; 21696 params.searchRestrictionClassNameId = config.searchRestrictionClassNameId; 21697 params.searchRestrictionClassPK = config.searchRestrictionClassPK; 21698 } 21699 21700 if ('showAncestorScopes' in config) { 21701 params.showAncestorScopes = config.showAncestorScopes; 21702 } 21703 21704 if ('showBackURL' in config) { 21705 params.showBackURL = config.showBackURL; 21706 } 21707 21708 if ('showCacheableInput' in config) { 21709 params.showCacheableInput = config.showCacheableInput; 21710 } 21711 21712 if ('showHeader' in config) { 21713 params.showHeader = config.showHeader; 21714 } 21715 21716 if ('showManageTemplates' in config) { 21717 params.showManageTemplates = config.showManageTemplates; 21718 } 21719 21720 var url = Liferay.Util.PortletURL.createRenderURL(config.basePortletURL, params); 21721 config.uri = url.toString(); 21722 var dialogConfig = config.dialog; 21723 21724 if (!dialogConfig) { 21725 dialogConfig = {}; 21726 config.dialog = dialogConfig; 21727 } 21728 21729 var eventHandles = []; 21730 21731 if (callback) { 21732 eventHandles.push(Liferay.once(config.eventName, callback)); 21733 } 21734 21735 var detachSelectionOnHideFn = function detachSelectionOnHideFn(event) { 21736 Liferay.fire(config.eventName); 21737 21738 if (!event.newVal) { 21739 new A.EventHandle(eventHandles).detach(); 21740 } 21741 }; 21742 21743 Util.openWindow(config, function (dialogWindow) { 21744 eventHandles.push(dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn)); 21745 }); 21746 }, ['aui-base']); 21747 Liferay.provide(Util, 'openDocument', function (webDavUrl, onSuccess, onError) { 21748 if (A.UA.ie) {
21749 try { 21750 var executor = new A.config.win.ActiveXObject('SharePoint.OpenDocuments'); 21751 executor.EditDocument(webDavUrl); 21752 21753 if (Lang.isFunction(onSuccess)) { 21754 onSuccess(); 21755 } 21756 } catch (e) { 21757 if (Lang.isFunction(onError)) { 21758 onError(e); 21759 } 21760 } 21761 } 21762 }, ['aui-base']); 21763 Liferay.provide(Util, 'selectEntityHandler', function (containerSelector, selectEventName, disableButton) { 21764 var container = A.one(containerSelector); 21765 21766 if (!container) { 21767 return; 21768 } 21769 21770 var openingLiferay = Util.getOpener().Liferay; 21771 var selectorButtons = container.getDOM().querySelectorAll('.selector-button'); 21772 container.delegate(EVENT_CLICK, function (event) { 21773 var currentTarget = event.currentTarget.getDOM(); 21774 21775 if (currentTarget.disabled || currentTarget.dataset['preventSelection']) { 21776 return; 21777 } 21778 21779 var confirmSelection = currentTarget.dataset['confirmSelection'] === 'true'; 21780 21781 if (!confirmSelection || confirm(currentTarget.dataset['confirmSelectionMessage'])) { 21782 if (disableButton) { 21783 selectorButtons.forEach(function (selectorButton) { 21784 selectorButton.disabled = false; 21785 }); 21786 currentTarget.disabled = true; 21787 } 21788 21789 var result = Util.getAttributes(currentTarget, 'data-'); 21790 openingLiferay.fire(selectEventName, result); 21791 21792 var _window = Util.getWindow(); 21793 21794 if (_window) { 21795 _window.hide(); 21796 } 21797 } 21798 }, '.selector-button'); 21799 openingLiferay.on('entitySelectionRemoved', function () { 21800 selectorButtons.forEach(function (selectorButton) { 21801 selectorButton.disabled = false; 21802 }); 21803 }); 21804 }, ['aui-base']); 21805 Liferay.provide(Util, 'portletTitleEdit', function (options) { 21806 var obj = options.obj; 21807 A.Event.defineOutside('mouseup'); 21808 21809 if (obj) { 21810 var title = obj.one('.portlet-title-text'); 21811 21812 if (title && !title.hasClass('not-editable')) { 21813 title.addClass('portlet-title-editable'); 21814 title.on(EVENT_CLICK, function (event) { 21815 var editable = Util._getEditableInstance(title); 21816 21817 var rendered = editable.get('rendered'); 21818 21819 if (rendered) { 21820 editable.fire('stopEditing'); 21821 } 21822 21823 editable.set('node', event.currentTarget); 21824 21825 if (rendered) { 21826 editable.syncUI(); 21827 } 21828 21829 editable._startEditing(event); 21830 21831 if (!rendered) { 21832 var defaultIconsTpl = A.ToolbarRenderer.prototype.TEMPLATES.icon; 21833 A.ToolbarRenderer.prototype.TEMPLATES.icon = Liferay.Util.getLexiconIconTpl('{cssClass}'); 21834 21835 editable._comboBox.icons.destroy(); 21836 21837 editable._comboBox._renderIcons(); 21838 21839 A.ToolbarRenderer.prototype.TEMPLATES.icon = defaultIconsTpl; 21840 } 21841 }); 21842 title.setData('portletTitleEditOptions', options); 21843 } 21844 } 21845 }, ['aui-editable-deprecated', 'event-outside']); 21846 Liferay.provide(Util, 'editEntity', function (config, callback) { 21847 var dialog = Util.getWindow(config.id); 21848 var eventName = config.eventName || config.id; 21849 var eventHandles = [Liferay.on(eventName, callback)]; 21850 21851 var detachSelectionOnHideFn = function detachSelectionOnHideFn(event) { 21852 if (!event.newVal) { 21853 new A.EventHandle(eventHandles).detach(); 21854 } 21855 }; 21856 21857 if (dialog) { 21858 eventHandles.push(dialog.after(['destroy', 'visibleChange'], detachSelectionOnHideFn)); 21859 dialog.show(); 21860 } else { 21861 var destroyDialog = function destroyDialog(event) { 21862 var dialogId = config.id; 21863 var dialogWindow = Util.getWindow(dialogId); 21864 21865 if (dialogWindow && Util.getPortletId(dialogId) === event.portletId) { 21866 dialogWindow.destroy(); 21867 Liferay.detach('destroyPortlet', destroyDialog); 21868 } 21869 }; 21870 21871 var editURL = new Liferay.Util.PortletURL.createPortletURL(config.uri, A.merge({ 21872 eventName: eventName 21873 }, config.urlParams)); 21874 config.uri = editURL.toString(); 21875 config.dialogIframe = A.merge({ 21876 bodyCssClass: 'dialog-with-footer' 21877 }, config.dialogIframe || {}); 21878 Util.openWindow(config, function (dialogWindow) { 21879 eventHandles.push(dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn)); 21880 Liferay.on('destroyPortlet', destroyDialog); 21881 }); 21882 } 21883 }, ['aui-base', 'liferay-util-window']); 21884 Liferay.provide(Util, 'selectEntity', function (config, callback) { 21885 var dialog = Util.getWindow(config.id); 21886 var eventName = config.eventName || config.id; 21887 var eventHandles = [Liferay.on(eventName, callback)]; 21888 var selectedData = config.selectedData; 21889 21890 if (selectedData) { 21891 config.dialog.destroyOnHide = true; 21892 } 21893 21894 var detachSelectionOnHideFn = function detachSelectionOnHideFn(event) { 21895 if (!event.newVal) { 21896 new A.EventHandle(eventHandles).detach(); 21897 } 21898 }; 21899 21900 var syncAssets = function syncAssets(event) { 21901 var currentWindow = event.currentTarget.node.get('contentWindow.document'); 21902 var selectorButtons = currentWindow.all('.lfr-search-container-wrapper .selector-button'); 21903 A.each(selectorButtons, function (item) { 21904 var assetEntryId = item.attr('data-entityid') || item.attr('data-entityname'); 21905 var assetGroupId = item.attr('data-groupid'); 21906 21907 if (assetGroupId) { 21908 assetEntryId = assetGroupId + '-' + assetEntryId; 21909 } 21910 21911 var disabled = selectedData && selectedData.includes(assetEntryId); 21912 21913 if (disabled) { 21914 item.attr('data-prevent-selection', true); 21915 } else { 21916 item.removeAttribute('data-prevent-selection'); 21917 } 21918 21919 Util.toggleDisabled(item, disabled); 21920 }); 21921 }; 21922 21923 if (dialog) { 21924 eventHandles.push(dialog.after(['destroy', 'visibleChange'], detachSelectionOnHideFn)); 21925 dialog.show(); 21926 } else { 21927 var destroyDialog = function destroyDialog(event) { 21928 var dialogId = config.id; 21929 var dialogWindow = Util.getWindow(dialogId); 21930 21931 if (dialogWindow && Util.getPortletId(dialogId) === event.portletId) { 21932 dialogWindow.destroy(); 21933 Liferay.detach('destroyPortlet', destroyDialog); 21934 } 21935 }; 21936 21937 Util.openWindow(config, function (dialogWindow) { 21938 eventHandles.push(dialogWindow.after(['destroy', 'visibleChange'], detachSelectionOnHideFn), dialogWindow.iframe.after(['load'], syncAssets)); 21939 Liferay.on('destroyPortlet', destroyDialog); 21940 }); 21941 } 21942 }, ['aui-base', 'liferay-util-window']); 21943 Liferay.provide(Util, 'toggleControls', function (node) { 21944 var docBody = A.getBody(); 21945 node = node || docBody;
21946 var trigger = node.one('.toggle-controls'); 21947 21948 if (trigger) { 21949 var controlsVisible = Liferay._editControlsState === 'visible'; 21950 var currentState = MAP_TOGGLE_STATE[controlsVisible]; 21951 var icon = trigger.one('.lexicon-icon'); 21952 21953 if (icon) { 21954 currentState.icon = icon; 21955 } 21956 21957 docBody.addClass(currentState.cssClass); 21958 Liferay.fire('toggleControls', { 21959 enabled: controlsVisible 21960 }); 21961 trigger.on('tap', function () { 21962 controlsVisible = !controlsVisible; 21963 var prevState = currentState; 21964 currentState = MAP_TOGGLE_STATE[controlsVisible]; 21965 docBody.toggleClass(prevState.cssClass); 21966 docBody.toggleClass(currentState.cssClass); 21967 var editControlsIconClass = currentState.iconCssClass; 21968 var editControlsState = currentState.state; 21969 21970 if (icon) { 21971 var newIcon = currentState.icon; 21972 21973 if (!newIcon) { 21974 newIcon = Util.getLexiconIcon(editControlsIconClass); 21975 newIcon = A.one(newIcon); 21976 currentState.icon = newIcon; 21977 } 21978 21979 icon.replace(newIcon); 21980 icon = newIcon; 21981 } 21982 21983 Liferay._editControlsState = editControlsState; 21984 Liferay.Util.Session.set('com.liferay.frontend.js.web_toggleControls', editControlsState); 21985 Liferay.fire('toggleControls', { 21986 enabled: controlsVisible, 21987 src: 'ui' 21988 }); 21989 }); 21990 } 21991 }, ['event-tap']); 21992 Liferay.provide(Util, '_openWindowProvider', function (config, callback) { 21993 var dialog = Window.getWindow(config); 21994 21995 if (Lang.isFunction(callback)) { 21996 callback(dialog); 21997 } 21998 }, ['liferay-util-window']); 21999 Util.Window = Window; 22000 Liferay.Util = Util; 22001 Liferay.STATUS_CODE = { 22002 BAD_REQUEST: 400, 22003 INTERNAL_SERVER_ERROR: 500, 22004 OK: 200, 22005 SC_DUPLICATE_FILE_EXCEPTION: 490, 22006 SC_FILE_ANTIVIRUS_EXCEPTION: 494, 22007 SC_FILE_CUSTOM_EXCEPTION: 499, 22008 SC_FILE_EXTENSION_EXCEPTION: 491, 22009 SC_FILE_NAME_EXCEPTION: 492, 22010 SC_FILE_SIZE_EXCEPTION: 493, 22011 SC_UPLOAD_REQUEST_SIZE_EXCEPTION: 495 22012 }; // 0-200: Theme Developer 22013 // 200-400: Portlet Developer 22014 // 400+: Liferay 22015 22016 Liferay.zIndex = { 22017 ALERT: 430, 22018 DOCK: 10, 22019 DOCK_PARENT: 20, 22020 DRAG_ITEM: 460, 22021 DROP_AREA: 440, 22022 DROP_POSITION: 450, 22023 MENU: 5000, 22024 OVERLAY: 1000, 22025 POPOVER: 1600, 22026 TOOLTIP: 10000, 22027 WINDOW: 1200 22028 }; 22029})(AUI(), Liferay); 22030//# sourceMappingURL=util.js.map 22031YUI.add('aui-base-html5-shiv', function (A, NAME) { 22032 22033A.HTML5_ELEMENTS = [ 22034 'abbr', 22035 'article', 22036 'aside', 22037 'audio', 22038 'canvas', 22039 'command', 22040 'datalist', 22041 'details', 22042 'figure', 22043 'figcaption', 22044 'footer', 22045 'header', 22046 'hgroup', 22047 'keygen', 22048 'mark', 22049 'meter', 22050 'nav', 22051 'output', 22052 'progress', 22053 'section', 22054 'source', 22055 'summary', 22056 'time', 22057 'video' 22058]; 22059 22060A.html5shiv = function(frag) { 22061 var DOC = frag || A.config.doc; 22062 22063 if (A.UA.ie && DOC && DOC.createElement) { 22064 var elements = A.HTML5_ELEMENTS, 22065 length = elements.length; 22066 22067 while (length--) { 22068 DOC.createElement(elements[length]); 22069 } 22070 } 22071 22072 return frag; 22073}; 22074 22075 22076}, '3.1.0-deprecated.77'); 22077 22078YUI.add('arraylist-add', function (Y, NAME) { 22079 22080/** 22081 * Collection utilities beyond what is provided in the YUI core 22082 * @module collection 22083 * @submodule arraylist-add 22084 * @deprecated Use ModelList or a custom ArrayList subclass 22085 */ 22086 22087/* 22088 * Adds methods add and remove to Y.ArrayList 22089 */ 22090Y.mix(Y.ArrayList.prototype, { 22091 22092 /** 22093 * Add a single item to the ArrayList. Does not prevent duplicates. 22094 * 22095 * @method add 22096 * @param { mixed } item Item presumably of the same type as others in the 22097 * ArrayList. 22098 * @param {Number} index (Optional.) Number representing the position at 22099 * which the item should be inserted. 22100 * @return {ArrayList} the instance. 22101 * @for ArrayList 22102 * @deprecated Use ModelList or a custom ArrayList subclass 22103 * @chainable 22104 */ 22105 add: function(item, index) { 22106 var items = this._items; 22107 22108 if (Y.Lang.isNumber(index)) { 22109 items.splice(index, 0, item); 22110 } 22111 else { 22112 items.push(item); 22113 } 22114 22115 return this; 22116 }, 22117 22118 /**
22119 * Removes first or all occurrences of an item to the ArrayList. If a 22120 * comparator is not provided, uses itemsAreEqual method to determine 22121 * matches. 22122 * 22123 * @method remove 22124 * @param { mixed } needle Item to find and remove from the list. 22125 * @param { Boolean } all If true, remove all occurrences. 22126 * @param { Function } comparator optional a/b function to test equivalence. 22127 * @return {ArrayList} the instance. 22128 * @for ArrayList 22129 * @deprecated Use ModelList or a custom ArrayList subclass 22130 * @chainable 22131 */ 22132 remove: function(needle, all, comparator) { 22133 comparator = comparator || this.itemsAreEqual; 22134 22135 for (var i = this._items.length - 1; i >= 0; --i) { 22136 if (comparator.call(this, needle, this.item(i))) { 22137 this._items.splice(i, 1); 22138 if (!all) { 22139 break; 22140 } 22141 } 22142 } 22143 22144 return this; 22145 }, 22146 22147 /** 22148 * Default comparator for items stored in this list. Used by remove(). 22149 * 22150 * @method itemsAreEqual 22151 * @param { mixed } a item to test equivalence with. 22152 * @param { mixed } b other item to test equivalance. 22153 * @return { Boolean } true if items are deemed equivalent. 22154 * @for ArrayList 22155 * @deprecated Use ModelList or a custom ArrayList subclass 22156 */ 22157 itemsAreEqual: function(a, b) { 22158 return a === b; 22159 } 22160 22161}); 22162 22163 22164}, 'patched-v3.18.1', {"requires": ["arraylist"]}); 22165 22166YUI.add('arraylist-filter', function (Y, NAME) { 22167 22168/** 22169 * Collection utilities beyond what is provided in the YUI core 22170 * @module collection 22171 * @submodule arraylist-filter 22172 * @deprecated Use ModelList or a custom subclass implementation 22173 */ 22174 22175/* 22176 * Adds filter method to ArrayList prototype 22177 */ 22178Y.mix(Y.ArrayList.prototype, { 22179 22180 /** 22181 * <p>Create a new ArrayList (or augmenting class instance) from a subset 22182 * of items as determined by the boolean function passed as the 22183 * argument. The original ArrayList is unchanged.</p> 22184 * 22185 * <p>The validator signature is <code>validator( item )</code>.</p> 22186 * 22187 * @method filter 22188 * @param { Function } validator Boolean function to determine in or out. 22189 * @return { ArrayList } New instance based on who passed the validator. 22190 * @for ArrayList 22191 * @deprecated Use ModelList or a custom subclass implementation 22192 */ 22193 filter: function(validator) { 22194 var items = []; 22195 22196 Y.Array.each(this._items, function(item, i) { 22197 item = this.item(i); 22198 22199 if (validator(item)) { 22200 items.push(item); 22201 } 22202 }, this); 22203 22204 return new this.constructor(items); 22205 } 22206 22207}); 22208 22209 22210}, 'patched-v3.18.1', {"requires": ["arraylist"]}); 22211 22212YUI.add('arraylist', function (Y, NAME) { 22213 22214/** 22215 * Collection utilities beyond what is provided in the YUI core 22216 * @module collection 22217 * @submodule arraylist 22218 */ 22219 22220var YArray = Y.Array, 22221 YArray_each = YArray.each, 22222 ArrayListProto; 22223 22224/** 22225 * Generic ArrayList class for managing lists of items and iterating operations 22226 * over them. The targeted use for this class is for augmentation onto a 22227 * class that is responsible for managing multiple instances of another class 22228 * (e.g. NodeList for Nodes). The recommended use is to augment your class with 22229 * ArrayList, then use ArrayList.addMethod to mirror the API of the constituent 22230 * items on the list's API. 22231 * 22232 * The default implementation creates immutable lists, but mutability can be 22233 * provided via the arraylist-add submodule or by implementing mutation methods 22234 * directly on the augmented class's prototype. 22235 * 22236 * @class ArrayList 22237 * @constructor 22238 * @param items { Array } array of items this list will be responsible for 22239 */ 22240function ArrayList( items ) { 22241 if ( items !== undefined ) { 22242 this._items = Y.Lang.isArray( items ) ? items : YArray( items ); 22243 } else { 22244 // ||= to support lazy initialization from augment 22245 this._items = this._items || []; 22246 } 22247} 22248 22249ArrayListProto = { 22250 /** 22251 * Get an item by index from the list. Override this method if managing a 22252 * list of objects that have a different public representation (e.g. Node 22253 * instances vs DOM nodes). The iteration methods that accept a user 22254 * function will use this method for access list items for operation. 22255 * 22256 * @method item 22257 * @param i { Integer } index to fetch 22258 * @return { mixed } the item at the requested index 22259 */ 22260 item: function ( i ) { 22261 return this._items[i]; 22262 }, 22263 22264 /** 22265 * <p>Execute a function on each item of the list, optionally providing a 22266 * custom execution context. Default context is the item.</p> 22267 * 22268 * <p>The callback signature is <code>callback( item, index )</code>.</p> 22269 * 22270 * @method each 22271 * @param fn { Function } the function to execute 22272 * @param context { mixed } optional override 'this' in the function 22273 * @return { ArrayList } this instance 22274 * @chainable 22275 */ 22276 each: function ( fn, context ) { 22277 YArray_each( this._items, function ( item, i ) { 22278 item = this.item( i ); 22279 22280 fn.call( context || item, item, i, this ); 22281 }, this); 22282 22283 return this; 22284 }, 22285 22286 /** 22287 * <p>Execute a function on each item of the list, optionally providing a 22288 * custom execution context. Default context is the item.</p> 22289 * 22290 * <p>The callback signature is <code>callback( item, index )</code>.</p> 22291 * 22292 * <p>Unlike <code>each</code>, if the callback returns true, the 22293 * iteration will stop.</p> 22294 * 22295 * @method some 22296 * @param fn { Function } the function to execute 22297 * @param context { mixed } optional override 'this' in the function 22298 * @return { Boolean } True if the function returned true on an item 22299 */ 22300 some: function ( fn, context ) { 22301 return YArray.some( this._items, function ( item, i ) { 22302 item = this.item( i ); 22303
22304 return fn.call( context || item, item, i, this ); 22305 }, this); 22306 }, 22307 22308 /** 22309 * Finds the first index of the needle in the managed array of items. 22310 * 22311 * @method indexOf 22312 * @param needle { mixed } The item to search for 22313 * @return { Integer } Array index if found. Otherwise -1 22314 */ 22315 indexOf: function ( needle ) { 22316 return YArray.indexOf( this._items, needle ); 22317 }, 22318 22319 /** 22320 * How many items are in this list? 22321 * 22322 * @method size 22323 * @return { Integer } Number of items in the list 22324 */ 22325 size: function () { 22326 return this._items.length; 22327 }, 22328 22329 /** 22330 * Is this instance managing any items? 22331 * 22332 * @method isEmpty 22333 * @return { Boolean } true if 1 or more items are being managed 22334 */ 22335 isEmpty: function () { 22336 return !this.size(); 22337 }, 22338 22339 /** 22340 * Provides an array-like representation for JSON.stringify. 22341 * 22342 * @method toJSON 22343 * @return { Array } an array representation of the ArrayList 22344 */ 22345 toJSON: function () { 22346 return this._items; 22347 } 22348}; 22349// Default implementation does not distinguish between public and private 22350// item getter 22351/** 22352 * Protected method for optimizations that may be appropriate for API 22353 * mirroring. Similar in functionality to <code>item</code>, but is used by 22354 * methods added with <code>ArrayList.addMethod()</code>. 22355 * 22356 * @method _item 22357 * @protected 22358 * @param i { Integer } Index of item to fetch 22359 * @return { mixed } The item appropriate for pass through API methods 22360 */ 22361ArrayListProto._item = ArrayListProto.item; 22362 22363// Mixed onto existing proto to preserve constructor NOT being an own property. 22364// This has bitten me when composing classes by enumerating, copying prototypes. 22365Y.mix(ArrayList.prototype, ArrayListProto); 22366 22367Y.mix( ArrayList, { 22368 22369 /** 22370 * <p>Adds a pass through method to dest (typically the prototype of a list 22371 * class) that calls the named method on each item in the list with 22372 * whatever parameters are passed in. Allows for API indirection via list 22373 * instances.</p> 22374 * 22375 * <p>Accepts a single string name or an array of string names.</p> 22376 * 22377 * <pre><code>list.each( function ( item ) { 22378 * item.methodName( 1, 2, 3 ); 22379 * } ); 22380 * // becomes 22381 * list.methodName( 1, 2, 3 );</code></pre> 22382 * 22383 * <p>Additionally, the pass through methods use the item retrieved by the 22384 * <code>_item</code> method in case there is any special behavior that is 22385 * appropriate for API mirroring.</p> 22386 * 22387 * <p>If the iterated method returns a value, the return value from the 22388 * added method will be an array of values with each value being at the 22389 * corresponding index for that item. If the iterated method does not 22390 * return a value, the added method will be chainable. 22391 * 22392 * @method addMethod 22393 * @static 22394 * @param dest {Object} Object or prototype to receive the iterator method 22395 * @param name {String|String[]} Name of method of methods to create 22396 */ 22397 addMethod: function ( dest, names ) { 22398 22399 names = YArray( names ); 22400 22401 YArray_each( names, function ( name ) { 22402 dest[ name ] = function () { 22403 var args = YArray( arguments, 0, true ), 22404 ret = []; 22405 22406 YArray_each( this._items, function ( item, i ) { 22407 item = this._item( i ); 22408 22409 var result = item[ name ].apply( item, args ); 22410 22411 if ( result !== undefined && result !== item ) { 22412 ret[i] = result; 22413 } 22414 }, this); 22415 22416 return ret.length ? ret : this; 22417 }; 22418 } ); 22419 } 22420} ); 22421 22422Y.ArrayList = ArrayList; 22423 22424 22425}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 22426 22427YUI.add('array-extras', function (Y, NAME) { 22428 22429/** 22430Adds additional utility methods to the `Y.Array` class. 22431 22432@module collection 22433@submodule array-extras 22434**/ 22435 22436var A = Y.Array, 22437 L = Y.Lang, 22438 ArrayProto = Array.prototype; 22439 22440/** 22441Returns the index of the last item in the array that contains the specified 22442value, or `-1` if the value isn't found. 22443 22444@method lastIndexOf 22445@param {Array} a Array to search in. 22446@param {Any} val Value to search for. 22447@param {Number} [fromIndex] Index at which to start searching backwards. 22448 Defaults to the array's length - 1. If negative, it will be taken as an offset 22449 from the end of the array. If the calculated index is less than 0, the array 22450 will not be searched and `-1` will be returned. 22451@return {Number} Index of the item that contains the value, or `-1` if not 22452 found. 22453@static 22454@for Array 22455**/ 22456A.lastIndexOf = L._isNative(ArrayProto.lastIndexOf) ? 22457 function(a, val, fromIndex) {
22458 // An undefined fromIndex is still considered a value by some (all?) 22459 // native implementations, so we can't pass it unless it's actually 22460 // specified. 22461 return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) : 22462 a.lastIndexOf(val); 22463 } : 22464 function(a, val, fromIndex) { 22465 var len = a.length, 22466 i = len - 1; 22467 22468 if (fromIndex || fromIndex === 0) { 22469 i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len); 22470 } 22471 22472 if (i > -1 && len > 0) { 22473 for (; i > -1; --i) { 22474 if (i in a && a[i] === val) { 22475 return i; 22476 } 22477 } 22478 } 22479 22480 return -1; 22481 }; 22482 22483/** 22484Returns a copy of the input array with duplicate items removed. 22485 22486Note: If the input array only contains strings, the `Y.Array.dedupe()` method is 22487a much faster alternative. 22488 22489@method unique 22490@param {Array} array Array to dedupe. 22491@param {Function} [testFn] Custom function to use to test the equality of two 22492 values. A truthy return value indicates that the values are equal. A falsy 22493 return value indicates that the values are not equal. 22494 22495 @param {Any} testFn.a First value to compare. 22496 @param {Any} testFn.b Second value to compare. 22497 @param {Number} testFn.index Index of the current item in the original 22498 array. 22499 @param {Array} testFn.array The original array. 22500 @return {Boolean} _true_ if the items are equal, _false_ otherwise. 22501 22502@return {Array} Copy of the input array with duplicate items removed. 22503@static 22504**/ 22505A.unique = function (array, testFn) { 22506 var i = 0, 22507 len = array.length, 22508 results = [], 22509 j, result, resultLen, value; 22510 22511 // Note the label here. It's used to jump out of the inner loop when a value 22512 // is not unique. 22513 outerLoop: for (; i < len; i++) { 22514 value = array[i]; 22515 22516 // For each value in the input array, iterate through the result array 22517 // and check for uniqueness against each result value. 22518 for (j = 0, resultLen = results.length; j < resultLen; j++) { 22519 result = results[j]; 22520 22521 // If the test function returns true or there's no test function and 22522 // the value equals the current result item, stop iterating over the 22523 // results and continue to the next value in the input array. 22524 if (testFn) { 22525 if (testFn.call(array, value, result, i, array)) { 22526 continue outerLoop; 22527 } 22528 } else if (value === result) { 22529 continue outerLoop; 22530 } 22531 } 22532 22533 // If we get this far, that means the current value is not already in 22534 // the result array, so add it. 22535 results.push(value); 22536 } 22537 22538 return results; 22539}; 22540 22541/** 22542Executes the supplied function on each item in the array. Returns a new array 22543containing the items for which the supplied function returned a truthy value. 22544 22545@method filter 22546@param {Array} a Array to filter. 22547@param {Function} f Function to execute on each item. 22548@param {Object} [o] Optional context object. 22549@return {Array} Array of items for which the supplied function returned a 22550 truthy value (empty if it never returned a truthy value). 22551@static 22552*/ 22553A.filter = L._isNative(ArrayProto.filter) ? 22554 function(a, f, o) { 22555 return ArrayProto.filter.call(a, f, o); 22556 } : 22557 function(a, f, o) { 22558 var i = 0, 22559 len = a.length, 22560 results = [], 22561 item; 22562 22563 for (; i < len; ++i) { 22564 if (i in a) { 22565 item = a[i]; 22566 22567 if (f.call(o, item, i, a)) { 22568 results.push(item); 22569 } 22570 } 22571 } 22572 22573 return results; 22574 }; 22575 22576/** 22577The inverse of `Array.filter()`. Executes the supplied function on each item. 22578Returns a new array containing the items for which the supplied function 22579returned `false`. 22580 22581@method reject 22582@param {Array} a the array to iterate. 22583@param {Function} f the function to execute on each item. 22584@param {object} [o] Optional context object. 22585@return {Array} The items for which the supplied function returned `false`. 22586@static 22587*/ 22588A.reject = function(a, f, o) { 22589 return A.filter(a, function(item, i, a) { 22590 return !f.call(o, item, i, a); 22591 }); 22592}; 22593 22594/** 22595Executes the supplied function on each item in the array. Iteration stops if the 22596supplied function does not return a truthy value. 22597 22598@method every 22599@param {Array} a the array to iterate. 22600@param {Function} f the function to execute on each item. 22601@param {Object} [o] Optional context object. 22602@return {Boolean} `true` if every item in the array returns `true` from the 22603 supplied function, `false` otherwise. 22604@static 22605*/ 22606A.every = L._isNative(ArrayProto.every) ? 22607 function(a, f, o) { 22608 return ArrayProto.every.call(a, f, o); 22609 } : 22610 function(a, f, o) { 22611 for (var i = 0, l = a.length; i < l; ++i) { 22612 if (i in a && !f.call(o, a[i], i, a)) { 22613 return false;
22614 } 22615 } 22616 22617 return true; 22618 }; 22619 22620/** 22621Executes the supplied function on each item in the array and returns a new array 22622containing all the values returned by the supplied function. 22623 22624@example 22625 22626 // Convert an array of numbers into an array of strings. 22627 Y.Array.map([1, 2, 3, 4], function (item) { 22628 return '' + item; 22629 }); 22630 // => ['1', '2', '3', '4'] 22631 22632@method map 22633@param {Array} a the array to iterate. 22634@param {Function} f the function to execute on each item. 22635@param {object} [o] Optional context object. 22636@return {Array} A new array containing the return value of the supplied function 22637 for each item in the original array. 22638@static 22639*/ 22640A.map = L._isNative(ArrayProto.map) ? 22641 function(a, f, o) { 22642 return ArrayProto.map.call(a, f, o); 22643 } : 22644 function(a, f, o) { 22645 var i = 0, 22646 len = a.length, 22647 results = ArrayProto.concat.call(a); 22648 22649 for (; i < len; ++i) { 22650 if (i in a) { 22651 results[i] = f.call(o, a[i], i, a); 22652 } 22653 } 22654 22655 return results; 22656 }; 22657 22658 22659/** 22660Executes the supplied function on each item in the array, "folding" the array 22661into a single value. 22662 22663@method reduce 22664@param {Array} a Array to iterate. 22665@param {Any} init Initial value to start with. 22666@param {Function} f Function to execute on each item. This function should 22667 update and return the value of the computation. It will receive the following 22668 arguments: 22669 @param {Any} f.previousValue Value returned from the previous iteration, 22670 or the initial value if this is the first iteration. 22671 @param {Any} f.currentValue Value of the current item being iterated. 22672 @param {Number} f.index Index of the current item. 22673 @param {Array} f.array Array being iterated. 22674@param {Object} [o] Optional context object. 22675@return {Any} Final result from iteratively applying the given function to each 22676 element in the array. 22677@static 22678*/ 22679A.reduce = L._isNative(ArrayProto.reduce) ? 22680 function(a, init, f, o) { 22681 // ES5 Array.reduce doesn't support a thisObject, so we need to 22682 // implement it manually. 22683 return ArrayProto.reduce.call(a, function(init, item, i, a) { 22684 return f.call(o, init, item, i, a); 22685 }, init); 22686 } : 22687 function(a, init, f, o) { 22688 var i = 0, 22689 len = a.length, 22690 result = init; 22691 22692 for (; i < len; ++i) { 22693 if (i in a) { 22694 result = f.call(o, result, a[i], i, a); 22695 } 22696 } 22697 22698 return result; 22699 }; 22700 22701/** 22702Executes the supplied function on each item in the array, searching for the 22703first item that matches the supplied function. 22704 22705@method find 22706@param {Array} a the array to search. 22707@param {Function} f the function to execute on each item. Iteration is stopped 22708 as soon as this function returns `true`. 22709@param {Object} [o] Optional context object. 22710@return {Object} the first item that the supplied function returns `true` for, 22711 or `null` if it never returns `true`. 22712@static 22713*/ 22714A.find = function(a, f, o) { 22715 for (var i = 0, l = a.length; i < l; i++) { 22716 if (i in a && f.call(o, a[i], i, a)) { 22717 return a[i]; 22718 } 22719 } 22720 return null; 22721}; 22722 22723/** 22724Iterates over an array, returning a new array of all the elements that match the 22725supplied regular expression. 22726 22727@method grep 22728@param {Array} a Array to iterate over. 22729@param {RegExp} pattern Regular expression to test against each item. 22730@return {Array} All the items in the array that produce a match against the 22731 supplied regular expression. If no items match, an empty array is returned. 22732@static 22733*/ 22734A.grep = function(a, pattern) { 22735 return A.filter(a, function(item, index) { 22736 return pattern.test(item); 22737 }); 22738}; 22739 22740/** 22741Partitions an array into two new arrays, one with the items for which the 22742supplied function returns `true`, and one with the items for which the function 22743returns `false`. 22744 22745@method partition 22746@param {Array} a Array to iterate over. 22747@param {Function} f Function to execute for each item in the array. It will 22748 receive the following arguments: 22749 @param {Any} f.item Current item. 22750 @param {Number} f.index Index of the current item. 22751 @param {Array} f.array The array being iterated. 22752@param {Object} [o] Optional execution context. 22753@return {Object} An object with two properties: `matches` and `rejects`. Each is 22754 an array containing the items that were selected or rejected by the test 22755 function (or an empty array if none). 22756@static 22757*/ 22758A.partition = function(a, f, o) { 22759 var results = { 22760 matches: [], 22761 rejects: [] 22762 }; 22763 22764 A.each(a, function(item, index) { 22765 var set = f.call(o, item, index, a) ? results.matches : results.rejects; 22766 set.push(item); 22767 }); 22768 22769 return results; 22770}; 22771 22772/** 22773Creates an array of arrays by pairing the corresponding elements of two arrays
22774together into a new array. 22775 22776@method zip 22777@param {Array} a Array to iterate over. 22778@param {Array} a2 Another array whose values will be paired with values of the 22779 first array. 22780@return {Array} An array of arrays formed by pairing each element of the first 22781 array with an item in the second array having the corresponding index. 22782@static 22783*/ 22784A.zip = function(a, a2) { 22785 var results = []; 22786 A.each(a, function(item, index) { 22787 results.push([item, a2[index]]); 22788 }); 22789 return results; 22790}; 22791 22792/** 22793Flattens an array of nested arrays at any abitrary depth into a single, flat 22794array. 22795 22796@method flatten 22797@param {Array} a Array with nested arrays to flatten. 22798@return {Array} An array whose nested arrays have been flattened. 22799@static 22800@since 3.7.0 22801**/ 22802A.flatten = function(a) { 22803 var result = [], 22804 i, len, val; 22805 22806 // Always return an array. 22807 if (!a) { 22808 return result; 22809 } 22810 22811 for (i = 0, len = a.length; i < len; ++i) { 22812 val = a[i]; 22813 22814 if (L.isArray(val)) { 22815 // Recusively flattens any nested arrays. 22816 result.push.apply(result, A.flatten(val)); 22817 } else { 22818 result.push(val); 22819 } 22820 } 22821 22822 return result; 22823}; 22824 22825 22826}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 22827 22828YUI.add('array-invoke', function (Y, NAME) { 22829 22830/** 22831@module collection 22832@submodule array-invoke 22833*/ 22834 22835/** 22836Executes a named method on each item in an array of objects. Items in the array 22837that do not have a function by that name will be skipped. 22838 22839@example 22840 22841 Y.Array.invoke(arrayOfDrags, 'plug', Y.Plugin.DDProxy); 22842 22843@method invoke 22844@param {Array} items Array of objects supporting the named method. 22845@param {String} name the name of the method to execute on each item. 22846@param {Any} [args*] Any number of additional args are passed as parameters to 22847 the execution of the named method. 22848@return {Array} All return values, indexed according to the item index. 22849@static 22850@for Array 22851**/ 22852Y.Array.invoke = function(items, name) { 22853 var args = Y.Array(arguments, 2, true), 22854 isFunction = Y.Lang.isFunction, 22855 ret = []; 22856 22857 Y.Array.each(Y.Array(items), function(item, i) { 22858 if (item && isFunction(item[name])) { 22859 ret[i] = item[name].apply(item, args); 22860 } 22861 }); 22862 22863 return ret; 22864}; 22865 22866 22867}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 22868 22869YUI.add('base-base', function (Y, NAME) { 22870 22871 /** 22872 * The base module provides the Base class, which objects requiring attribute and custom event support can extend. 22873 * The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides 22874 * plugin support and also provides the BaseCore.build method which provides a way to build custom classes using extensions. 22875 * 22876 * @module base 22877 */ 22878 22879 /** 22880 * The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host, 22881 * and without the extension support provided by BaseCore.build. 22882 * 22883 * @module base 22884 * @submodule base-base 22885 */ 22886 22887 var AttributeCore = Y.AttributeCore, 22888 AttributeExtras = Y.AttributeExtras, 22889 BaseCore = Y.BaseCore, 22890 BaseObservable = Y.BaseObservable; 22891 22892 /** 22893 * <p> 22894 * A base class which objects requiring attributes and custom event support can 22895 * extend. Base also handles the chaining of initializer and destructor methods across 22896 * the hierarchy as part of object construction and destruction. Additionally, attributes configured 22897 * through the static <a href="#property_ATTRS">ATTRS</a> property for each class 22898 * in the hierarchy will be initialized by Base. 22899 * </p> 22900 * 22901 * <p> 22902 * **NOTE:** Prior to version 3.11.0, ATTRS would get added a class at a time. That is, 22903 * Base would loop through each class in the hierarchy, and add the class' ATTRS, and 22904 * then call it's initializer, and move on to the subclass' ATTRS and initializer. As of 22905 * 3.11.0, ATTRS from all classes in the hierarchy are added in one `addAttrs` call before 22906 * any initializers are called. This fixes subtle edge-case issues with subclass ATTRS overriding 22907 * superclass `setter`, `getter` or `valueFn` definitions and being unable to get/set attributes 22908 * defined by the subclass. This order of operation change may impact `setter`, `getter` or `valueFn` 22909 * code which expects a superclass' initializer to have run. This is expected to be rare, but to supp
22909ort 22910 * it, Base supports a `_preAddAttrs()`, method hook (same signature as `addAttrs`). Components can 22911 * implement this method on their prototype for edge cases which do require finer control over 22912 * the order in which attributes are added (see widget-htmlparser). 22913 * </p> 22914 * 22915 * <p> 22916 * The static <a href="#property_NAME">NAME</a> property of each class extending 22917 * from Base will be used as the identifier for the class, and is used by Base to prefix 22918 * all events fired by instances of that class. 22919 * </p> 22920 * 22921 * @class Base 22922 * @constructor 22923 * @uses BaseCore 22924 * @uses BaseObservable 22925 * @uses AttributeCore 22926 * @uses AttributeObservable 22927 * @uses AttributeExtras 22928 * @uses EventTarget 22929 * 22930 * @param {Object} config Object with configuration property name/value pairs. The object can be 22931 * used to provide default values for the objects published attributes. 22932 * 22933 * <p> 22934 * The config object can also contain the following non-attribute properties, providing a convenient 22935 * way to configure events listeners and plugins for the instance, as part of the constructor call: 22936 * </p> 22937 * 22938 * <dl> 22939 * <dt>on</dt> 22940 * <dd>An event name to listener function map, to register event listeners for the "on" moment of the event. 22941 * A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd> 22942 * <dt>after</dt> 22943 * <dd>An event name to listener function map, to register event listeners for the "after" moment of the event. 22944 * A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd> 22945 * <dt>bubbleTargets</dt> 22946 * <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance. 22947 * A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd> 22948 * <dt>plugins</dt> 22949 * <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details). 22950 * A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd> 22951 * </dl> 22952 */ 22953 function Base() { 22954 BaseCore.apply(this, arguments); 22955 BaseObservable.apply(this, arguments); 22956 AttributeExtras.apply(this, arguments); 22957 } 22958 22959 /** 22960 * The list of properties which can be configured for 22961 * each attribute (e.g. setter, getter, writeOnce, readOnly etc.) 22962 * 22963 * @property _ATTR_CFG 22964 * @type Array 22965 * @static 22966 * @private 22967 */ 22968 Base._ATTR_CFG = BaseCore._ATTR_CFG.concat(BaseObservable._ATTR_CFG); 22969 22970 /** 22971 * The array of non-attribute configuration properties supported by this class. 22972 * 22973 * `Base` supports "on", "after", "plugins" and "bubbleTargets" properties, 22974 * which are not set up as attributes. 22975 * 22976 * This property is primarily required so that when 22977 * <a href="#property__allowAdHocAttrs">`_allowAdHocAttrs`</a> is enabled by 22978 * a class, non-attribute configurations don't get added as ad-hoc attributes. 22979 * 22980 * @property _NON_ATTRS_CFG 22981 * @type Array 22982 * @static 22983 * @private 22984 */ 22985 Base._NON_ATTRS_CFG = BaseCore._NON_ATTRS_CFG.concat(BaseObservable._NON_ATTRS_CFG); 22986 22987 /** 22988 * <p> 22989 * The string to be used to identify instances of 22990 * this class, for example in prefixing events. 22991 * </p> 22992 * <p> 22993 * Classes extending Base, should define their own 22994 * static NAME property, which should be camelCase by 22995 * convention (e.g. MyClass.NAME = "myClass";). 22996 * </p> 22997 * @property NAME
22998 * @type String 22999 * @static 23000 */ 23001 Base.NAME = 'base'; 23002 23003 /** 23004 * The default set of attributes which will be available for instances of this class, and 23005 * their configuration. In addition to the configuration properties listed by 23006 * Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute 23007 * can also be configured with a "cloneDefaultValue" property, which defines how the statically 23008 * defined value field should be protected ("shallow", "deep" and false are supported values). 23009 * 23010 * By default if the value is an object literal or an array it will be "shallow" cloned, to 23011 * protect the default value. 23012 * 23013 * @property ATTRS 23014 * @type Object 23015 * @static 23016 */ 23017 Base.ATTRS = AttributeCore.protectAttrs(BaseCore.ATTRS); 23018 23019 /** 23020 Provides a way to safely modify a `Y.Base` subclass' static `ATTRS` after 23021 the class has been defined or created. 23022 23023 Base-based classes cache information about the class hierarchy in order to 23024 efficiently create instances. This cache includes includes the aggregated 23025 `ATTRS` configs. If the static `ATTRS` configs need to be modified after the 23026 class has been defined or create, then use this method which will make sure 23027 to clear any cached data before making any modifications. 23028 23029 @method modifyAttrs 23030 @param {Function} [ctor] The constructor function whose `ATTRS` should be 23031 modified. If a `ctor` function is not specified, then `this` is assumed 23032 to be the constructor which hosts the `ATTRS`. 23033 @param {Object} configs The collection of `ATTRS` configs to mix with the 23034 existing attribute configurations. 23035 @static 23036 @since 3.10.0 23037 **/ 23038 Base.modifyAttrs = BaseCore.modifyAttrs; 23039 23040 Y.mix(Base, BaseCore, false, null, 1); 23041 Y.mix(Base, AttributeExtras, false, null, 1); 23042 23043 // Needs to be `true`, to overwrite methods from `BaseCore`. 23044 Y.mix(Base, BaseObservable, true, null, 1); 23045 23046 // Fix constructor 23047 Base.prototype.constructor = Base; 23048 23049 Y.Base = Base; 23050 23051 23052}, 'patched-v3.18.1', {"requires": ["attribute-base", "base-core", "base-observable"]}); 23053 23054YUI.add('base-pluginhost', function (Y, NAME) { 23055 23056 /** 23057 * The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with 23058 * Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods. 23059 * 23060 * @module base 23061 * @submodule base-pluginhost 23062 * @for Base 23063 */ 23064 23065 var Base = Y.Base, 23066 PluginHost = Y.Plugin.Host; 23067 23068 Y.mix(Base, PluginHost, false, null, 1); 23069 23070 /** 23071 * Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased 23072 * method for argument and return value details. 23073 * 23074 * @method plug 23075 * @static 23076 */ 23077 Base.plug = PluginHost.plug; 23078 23079 /** 23080 * Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the 23081 * aliased method for argument and return value details. 23082 * 23083 * @method unplug 23084 * @static 23085 */ 23086 Base.unplug = PluginHost.unplug; 23087 23088 23089}, 'patched-v3.18.1', {"requires": ["base-base", "pluginhost"]}); 23090 23091YUI.add('classnamemanager', function (Y, NAME) { 23092 23093/** 23094* Contains a singleton (ClassNameManager) that enables easy creation and caching of 23095* prefixed class names. 23096* @module classnamemanager 23097*/ 23098 23099/** 23100 * A singleton class providing: 23101 * 23102 * <ul> 23103 * <li>Easy creation of prefixed class names</li> 23104 * <li>Caching of previously created class names for improved performance.</li> 23105 * </ul> 23106 * 23107 * @class ClassNameManager 23108 * @static 23109 */ 23110 23111// String constants 23112var CLASS_NAME_PREFIX = 'classNamePrefix', 23113 CLASS_NAME_DELIMITER = 'classNameDelimiter', 23114 CONFIG = Y.config; 23115 23116// Global config 23117 23118/** 23119 * Configuration property indicating the prefix for all CSS class names in this YUI instance. 23120 * 23121 * @property classNamePrefix 23122 * @type {String} 23123 * @default "yui" 23124 * @static 23125 */ 23126CONFIG[CLASS_NAME_PREFIX] = CONFIG[CLASS_NAME_PREFIX] || 'yui3'; 23127 23128/** 23129 * Configuration property indicating the delimiter used to compose all CSS class names in 23130 * this YUI instance. 23131 * 23132 * @property classNameDelimiter 23133 * @type {String} 23134 * @default "-" 23135 * @static 23136 */ 23137CONFIG[CLASS_NAME_DELIMITER] = CONFIG[CLASS_NAME_DELIMITER] || '-'; 23138 23139Y.ClassNameManager = function () { 23140 23141 var sPrefix = CONFIG[CLASS_NAME_PREFIX], 23142 sDelimiter = CONFIG[CLASS_NAME_DELIMITER]; 23143 23144 return { 23145 23146 /** 23147 * Returns a class name prefixed with the value of the 23148 * <code>Y.config.classNamePrefix</code> attribute + the provided strings. 23149 * Uses the <code>Y.config.classNameDelimiter</code> attribute to delimit the 23150 * provided strings. E.g. Y.ClassNameManager.getClassName('foo','bar'); // yui-foo-bar 23151 * 23152 * @method getClassName 23153 * @param {String} [classnameSection*] one or more classname sections to be joined 23154 * @param {Boolean} skipPrefix If set to true, the classname will not be prefixed with the default Y.config.classNameDelimiter value. 23155 */ 23156 getClassName: Y.cached(function () { 23157 23158 var args = Y.Array(arguments); 23159 23160 if (args[args.length-1] !== true) { 23161 args.unshift(sPrefix); 23162 } else { 23163 args.pop(); 23164 } 23165 23166 return args.join(sDelimiter); 23167 }) 23168 23169 }; 23170 23171}(); 23172 23173 23174}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 23175 23176YUI.add('datatype-xml-format', function (Y, NAME) { 23177 23178/** 23179 * The Number Utility provides type-conversion and string-formatting 23180 * convenience methods for Numbers. 23181 * 23182 * @module datatype-xml 23183 * @submodule datatype-xml-format 23184 */ 23185 23186/** 23187 * XML provides a set of utility functions to operate against XML documents. 23188 * 23189 * @class XML 23190 * @static 23191 */ 23192var LANG = Y.Lang; 23193 23194Y.mix(Y.namespace("XML"), { 23195 /** 23196 * Converts data to type XMLDocument. 23197 * 23198 * @method format 23199 * @param data {XMLDocument} Data to convert. 23200 * @return {String} String. 23201 */ 23202 format: function(data) { 23203 try { 23204 if(!LANG.isUndefined(data.getXml)) { 23205 return data.getXml(); 23206 } 23207 23208 if(!LANG.isUndefined(XMLSerializer)) { 23209 return (new XMLSerializer()).serializeToString(data); 23210 } 23211 } 23212 catch(e) { 23213 if(data && data.xml) { 23214 return data.xml; 23215 } 23216 else { 23217 return (LANG.isValue(data) && data.toString) ? data.toString() : ""; 23218 } 23219 } 23220 } 23221}); 23222 23223Y.namespace("DataType"); 23224Y.DataType.XML = Y.XML; 23225 23226 23227}, 'patched-v3.18.1'); 23228 23229YUI.add('datatype-xml-parse', function (Y, NAME) { 23230 23231/** 23232 * Parse XML submodule. 23233 * 23234 * @module datatype-xml 23235 * @submodule datatype-xml-parse 23236 * @for XML 23237 */ 23238 23239Y.mix(Y.namespace("XML"), { 23240 /** 23241 * Converts data to type XMLDocument. 23242 * 23243 * @method parse 23244 * @param data {String} Data to convert. 23245 * @return {XMLDocument} XML Document. 23246 */ 23247 parse: function(data) { 23248 var xmlDoc = null, win; 23249 if (typeof data === "string") { 23250 win = Y.config.win; 23251 if (win.ActiveXObject !== undefined) { 23252 xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 23253 xmlDoc.async = false;
23254 xmlDoc.loadXML(data); 23255 } else if (win.DOMParser !== undefined) { 23256 xmlDoc = new DOMParser().parseFromString(data, "text/xml"); 23257 } else if (win.Windows !== undefined) { 23258 xmlDoc = new Windows.Data.Xml.Dom.XmlDocument(); 23259 xmlDoc.loadXml(data); 23260 } 23261 } 23262 23263 if (xmlDoc === null || xmlDoc.documentElement === null || xmlDoc.documentElement.nodeName === "parsererror") { 23264 } 23265 23266 return xmlDoc; 23267 } 23268}); 23269 23270// Add Parsers shortcut 23271Y.namespace("Parsers").xml = Y.XML.parse; 23272 23273Y.namespace("DataType"); 23274Y.DataType.XML = Y.XML; 23275 23276 23277}, 'patched-v3.18.1'); 23278 23279YUI.add('dom-base', function (Y, NAME) { 23280 23281/** 23282* @for DOM 23283* @module dom 23284*/ 23285var documentElement = Y.config.doc.documentElement, 23286 Y_DOM = Y.DOM, 23287 TAG_NAME = 'tagName', 23288 OWNER_DOCUMENT = 'ownerDocument', 23289 EMPTY_STRING = '', 23290 addFeature = Y.Features.add, 23291 testFeature = Y.Features.test; 23292 23293Y.mix(Y_DOM, { 23294 /** 23295 * Returns the text content of the HTMLElement. 23296 * @method getText 23297 * @param {HTMLElement} element The html element. 23298 * @return {String} The text content of the element (includes text of any descending elements). 23299 */ 23300 getText: (documentElement.textContent !== undefined) ? 23301 function(element) { 23302 var ret = ''; 23303 if (element) { 23304 ret = element.textContent; 23305 } 23306 return ret || ''; 23307 } : function(element) { 23308 var ret = ''; 23309 if (element) { 23310 ret = element.innerText || element.nodeValue; // might be a textNode 23311 } 23312 return ret || ''; 23313 }, 23314 23315 /** 23316 * Sets the text content of the HTMLElement. 23317 * @method setText 23318 * @param {HTMLElement} element The html element. 23319 * @param {String} content The content to add. 23320 */ 23321 setText: (documentElement.textContent !== undefined) ? 23322 function(element, content) { 23323 if (element) { 23324 element.textContent = content; 23325 } 23326 } : function(element, content) { 23327 if ('innerText' in element) { 23328 element.innerText = content; 23329 } else if ('nodeValue' in element) { 23330 element.nodeValue = content; 23331 } 23332 }, 23333 23334 CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8 23335 'for': 'htmlFor', 23336 'class': 'className' 23337 } : { // w3c 23338 'htmlFor': 'for', 23339 'className': 'class' 23340 }, 23341 23342 /** 23343 * Provides a normalized attribute interface. 23344 * @method setAttribute 23345 * @param {HTMLElement} el The target element for the attribute. 23346 * @param {String} attr The attribute to set. 23347 * @param {String} val The value of the attribute. 23348 */ 23349 setAttribute: function(el, attr, val, ieAttr) { 23350 if (el && attr && el.setAttribute) { 23351 attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr; 23352 el.setAttribute(attr, val, ieAttr); 23353 } 23354 }, 23355 23356 23357 /** 23358 * Provides a normalized attribute interface. 23359 * @method getAttribute 23360 * @param {HTMLElement} el The target element for the attribute. 23361 * @param {String} attr The attribute to get. 23362 * @return {String} The current value of the attribute. 23363 */ 23364 getAttribute: function(el, attr, ieAttr) { 23365 ieAttr = (ieAttr !== undefined) ? ieAttr : 2; 23366 var ret = ''; 23367 if (el && attr && el.getAttribute) { 23368 attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr; 23369 // BUTTON value issue for IE < 8 23370 ret = (el.tagName === "BUTTON" && attr === 'value') ? Y_DOM.getValue(el) : el.getAttribute(attr, ieAttr); 23371 23372 if (ret === null) { 23373 ret = ''; // per DOM spec 23374 } 23375 } 23376 return ret; 23377 }, 23378 23379 VALUE_SETTERS: {}, 23380 23381 VALUE_GETTERS: {}, 23382 23383 getValue: function(node) { 23384 var ret = '', // TODO: return null? 23385 getter; 23386 23387 if (node && node[TAG_NAME]) { 23388 getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()]; 23389 23390 if (getter) { 23391 ret = getter(node); 23392 } else { 23393 ret = node.value; 23394 } 23395 } 23396 23397 // workaround for IE8 JSON stringify bug 23398 // which converts empty string values to null 23399 if (ret === EMPTY_STRING) { 23400 ret = EMPTY_STRING; // for real 23401 } 23402 23403 return (typeof ret === 'string') ? ret : ''; 23404 }, 23405 23406 setValue: function(node, val) { 23407 var setter; 23408 23409 if (node && node[TAG_NAME]) { 23410 setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()]; 23411 val = (val === null) ? '' : val; 23412 if (setter) { 23413 setter(node, val); 23414 } else { 23415 node.value = val; 23416 } 23417 } 23418 }, 23419 23420 creators: {} 23421}); 23422 23423addFeature('value-set', 'select', { 23424 test: function() { 23425 var node = Y.config.doc.createElement('select'); 23426 node.innerHTML = '<option>1</option><option>2</option>'; 23427 node.value = '2'; 23428 return (node.value && node.value === '2'); 23429 } 23430}); 23431
23432if (!testFeature('value-set', 'select')) { 23433 Y_DOM.VALUE_SETTERS.select = function(node, val) { 23434 for (var i = 0, options = node.getElementsByTagName('option'), option; 23435 option = options[i++];) { 23436 if (Y_DOM.getValue(option) === val) { 23437 option.selected = true; 23438 //Y_DOM.setAttribute(option, 'selected', 'selected'); 23439 break; 23440 } 23441 } 23442 }; 23443} 23444 23445Y.mix(Y_DOM.VALUE_GETTERS, { 23446 button: function(node) { 23447 return (node.attributes && node.attributes.value) ? node.attributes.value.value : ''; 23448 } 23449}); 23450 23451Y.mix(Y_DOM.VALUE_SETTERS, { 23452 // IE: node.value changes the button text, which should be handled via innerHTML 23453 button: function(node, val) { 23454 var attr = node.attributes.value; 23455 if (!attr) { 23456 attr = node[OWNER_DOCUMENT].createAttribute('value'); 23457 node.setAttributeNode(attr); 23458 } 23459 23460 attr.value = val; 23461 } 23462}); 23463 23464 23465Y.mix(Y_DOM.VALUE_GETTERS, { 23466 option: function(node) { 23467 var attrs = node.attributes; 23468 return (attrs.value && attrs.value.specified) ? node.value : node.text; 23469 }, 23470 23471 select: function(node) { 23472 var val = node.value, 23473 options = node.options; 23474 23475 if (options && options.length) { 23476 // TODO: implement multipe select 23477 if (node.multiple) { 23478 } else if (node.selectedIndex > -1) { 23479 val = Y_DOM.getValue(options[node.selectedIndex]); 23480 } 23481 } 23482 23483 return val; 23484 } 23485}); 23486var addClass, hasClass, removeClass; 23487 23488Y.mix(Y.DOM, { 23489 /** 23490 * Determines whether a DOM element has the given className. 23491 * @method hasClass 23492 * @for DOM 23493 * @param {HTMLElement} element The DOM element. 23494 * @param {String} className the class name to search for 23495 * @return {Boolean} Whether or not the element has the given class. 23496 */ 23497 hasClass: function(node, className) { 23498 var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)'); 23499 return re.test(node.className); 23500 }, 23501 23502 /** 23503 * Adds a class name to a given DOM element. 23504 * @method addClass 23505 * @for DOM 23506 * @param {HTMLElement} element The DOM element. 23507 * @param {String} className the class name to add to the class attribute 23508 */ 23509 addClass: function(node, className) { 23510 if (!Y.DOM.hasClass(node, className)) { // skip if already present 23511 node.className = Y.Lang.trim([node.className, className].join(' ')); 23512 } 23513 }, 23514 23515 /** 23516 * Removes a class name from a given element. 23517 * @method removeClass 23518 * @for DOM 23519 * @param {HTMLElement} element The DOM element. 23520 * @param {String} className the class name to remove from the class attribute 23521 */ 23522 removeClass: function(node, className) { 23523 if (className && hasClass(node, className)) { 23524 node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' + 23525 className + '(?:\\s+|$)'), ' ')); 23526 23527 if ( hasClass(node, className) ) { // in case of multiple adjacent 23528 removeClass(node, className); 23529 } 23530 } 23531 }, 23532 23533 /** 23534 * Replace a class with another class for a given element. 23535 * If no oldClassName is present, the newClassName is simply added. 23536 * @method replaceClass 23537 * @for DOM 23538 * @param {HTMLElement} element The DOM element 23539 * @param {String} oldClassName the class name to be replaced 23540 * @param {String} newClassName the class name that will be replacing the old class name 23541 */ 23542 replaceClass: function(node, oldC, newC) { 23543 removeClass(node, oldC); // remove first in case oldC === newC 23544 addClass(node, newC); 23545 }, 23546 23547 /** 23548 * If the className exists on the node it is removed, if it doesn't exist it is added. 23549 * @method toggleClass 23550 * @for DOM 23551 * @param {HTMLElement} element The DOM element 23552 * @param {String} className the class name to be toggled 23553 * @param {Boolean} addClass optional boolean to indicate whether class 23554 * should be added or removed regardless of current state 23555 */ 23556 toggleClass: function(node, className, force) { 23557 var add = (force !== undefined) ? force : 23558 !(hasClass(node, className)); 23559 23560 if (add) { 23561 addClass(node, className); 23562 } else { 23563 removeClass(node, className); 23564 } 23565 } 23566}); 23567 23568hasClass = Y.DOM.hasClass; 23569removeClass = Y.DOM.removeClass; 23570addClass = Y.DOM.addClass; 23571 23572var re_tag = /<([a-z]+)/i, 23573 23574 Y_DOM = Y.DOM, 23575 23576 addFeature = Y.Features.add, 23577 testFeature = Y.Features.test, 23578 23579 creators = {}, 23580 23581 createFromDIV = function(html, tag) { 23582 var div = Y.config.doc.createElement('div'), 23583 ret = true; 23584 23585 div.innerHTML = html; 23586 if (!div.firstChild || div.firstChild.tagName !== tag.toUpperCase()) { 23587 ret = false;
23588 } 23589 23590 return ret; 23591 }, 23592 23593 re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/, 23594 23595 TABLE_OPEN = '<table>', 23596 TABLE_CLOSE = '</table>', 23597 23598 selectedIndex; 23599 23600Y.mix(Y.DOM, { 23601 _fragClones: {}, 23602 23603 _create: function(html, doc, tag) { 23604 tag = tag || 'div'; 23605 23606 var frag = Y_DOM._fragClones[tag]; 23607 if (frag) { 23608 frag = frag.cloneNode(false); 23609 } else { 23610 frag = Y_DOM._fragClones[tag] = doc.createElement(tag); 23611 } 23612 frag.innerHTML = html; 23613 return frag; 23614 }, 23615 23616 _children: function(node, tag) { 23617 var i = 0, 23618 children = node.children, 23619 childNodes, 23620 hasComments, 23621 child; 23622 23623 if (children && children.tags) { // use tags filter when possible 23624 if (tag) { 23625 children = node.children.tags(tag); 23626 } else { // IE leaks comments into children 23627 hasComments = children.tags('!').length; 23628 } 23629 } 23630 23631 if (!children || (!children.tags && tag) || hasComments) { 23632 childNodes = children || node.childNodes; 23633 children = []; 23634 while ((child = childNodes[i++])) { 23635 if (child.nodeType === 1) { 23636 if (!tag || tag === child.tagName) { 23637 children.push(child); 23638 } 23639 } 23640 } 23641 } 23642 23643 return children || []; 23644 }, 23645 23646 /** 23647 * Creates a new dom node using the provided markup string. 23648 * @method create 23649 * @param {String} html The markup used to create the element 23650 * @param {HTMLDocument} doc An optional document context 23651 * @return {HTMLElement|DocumentFragment} returns a single HTMLElement 23652 * when creating one node, and a documentFragment when creating 23653 * multiple nodes. 23654 */ 23655 create: function(html, doc) { 23656 if (typeof html === 'string') { 23657 html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML 23658 23659 } 23660 23661 doc = doc || Y.config.doc; 23662 var m = re_tag.exec(html), 23663 create = Y_DOM._create, 23664 custom = creators, 23665 ret = null, 23666 creator, tag, node, nodes; 23667 23668 if (html != undefined) { // not undefined or null 23669 if (m && m[1]) { 23670 creator = custom[m[1].toLowerCase()]; 23671 if (typeof creator === 'function') { 23672 create = creator; 23673 } else { 23674 tag = creator; 23675 } 23676 } 23677 23678 node = create(html, doc, tag); 23679 nodes = node.childNodes; 23680 23681 if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment" 23682 ret = node.removeChild(nodes[0]); 23683 } else if (nodes[0] && nodes[0].className === 'yui3-big-dummy') { // using dummy node to preserve some attributes (e.g. OPTION not selected) 23684 selectedIndex = node.selectedIndex; 23685 23686 if (nodes.length === 2) { 23687 ret = nodes[0].nextSibling; 23688 } else { 23689 node.removeChild(nodes[0]); 23690 ret = Y_DOM._nl2frag(nodes, doc); 23691 } 23692 } else { // return multiple nodes as a fragment 23693 ret = Y_DOM._nl2frag(nodes, doc); 23694 } 23695 23696 } 23697 23698 return ret; 23699 }, 23700 23701 _nl2frag: function(nodes, doc) { 23702 var ret = null, 23703 i, len; 23704 23705 if (nodes && (nodes.push || nodes.item) && nodes[0]) { 23706 doc = doc || nodes[0].ownerDocument; 23707 ret = doc.createDocumentFragment(); 23708 23709 if (nodes.item) { // convert live list to static array 23710 nodes = Y.Array(nodes, 0, true); 23711 } 23712 23713 for (i = 0, len = nodes.length; i < len; i++) { 23714 ret.appendChild(nodes[i]); 23715 } 23716 } // else inline with log for minification 23717 return ret; 23718 }, 23719 23720 /** 23721 * Inserts content in a node at the given location 23722 * @method addHTML 23723 * @param {HTMLElement} node The node to insert into 23724 * @param {HTMLElement | Array | HTMLCollection} content The content to be inserted 23725 * @param {HTMLElement} where Where to insert the content 23726 * If no "where" is given, content is appended to the node 23727 * Possible values for "where" 23728 * <dl> 23729 * <dt>HTMLElement</dt> 23730 * <dd>The element to insert before</dd> 23731 * <dt>"replace"</dt> 23732 * <dd>Replaces the existing HTML</dd> 23733 * <dt>"before"</dt> 23734 * <dd>Inserts before the existing HTML</dd> 23735 * <dt>"before"</dt> 23736 * <dd>Inserts content before the node</dd> 23737 * <dt>"after"</dt> 23738 * <dd>Inserts content after the node</dd> 23739 * </dl> 23740 */ 23741 addHTML: function(node, content, where) { 23742 var nodeParent = node.parentNode, 23743 i = 0, 23744 item, 23745 ret = content, 23746 newNode; 23747 23748 23749 if (content != undefined) { // not null or undefined (maybe 0) 23750 if (content.nodeType) { // DOM node, just add it 23751 newNode = content; 23752 } else if (typeof content == 'string' || typeof content == 'number') { 23753 ret = newNode = Y_DOM.create(content); 23754 } else if (content[0] && content[0].nodeType) { // array or collection 23755 newNode = Y.config.doc.createDocumentFragment(); 23756 while ((item = content[i++])) { 23757 newNode.appendChild(item); // append to fragment for insertion 23758 } 23759 } 23760 } 23761 23762 if (where) { 23763 if (newNode && where.parentNode) { // insert regardless of relationship to node 23764 where.parentNode.insertBefore(newNode, where); 23765 } else { 23766 switch (where) { 23767 case 'replace': 23768 while (node.firstChild) { 23769 node.removeChild(node.firstChild); 23770 } 23771 if (newNode) { // allow empty content to clear node 23772 node.appendChild(newNode); 23773 } 23774 break; 23775 case 'before': 23776 if (newNode) { 23777 nodeParent.insertBefore(newNode, node); 23778 } 23779 break; 23780 case 'after': 23781 if (newNode) { 23782 if (node.nextSibling) { // IE errors if refNo
23782de is null 23783 nodeParent.insertBefore(newNode, node.nextSibling); 23784 } else { 23785 nodeParent.appendChild(newNode); 23786 } 23787 } 23788 break; 23789 default: 23790 if (newNode) { 23791 node.appendChild(newNode); 23792 } 23793 } 23794 } 23795 } else if (newNode) { 23796 node.appendChild(newNode); 23797 } 23798 23799 // `select` elements are the only elements with `selectedIndex`. 23800 // Don't grab the dummy `option` element's `selectedIndex`. 23801 if (node.nodeName == "SELECT" && selectedIndex > 0) { 23802 node.selectedIndex = selectedIndex - 1; 23803 } 23804 23805 return ret; 23806 }, 23807 23808 wrap: function(node, html) { 23809 var parent = (html && html.nodeType) ? html : Y.DOM.create(html), 23810 nodes = parent.getElementsByTagName('*'); 23811 23812 if (nodes.length) { 23813 parent = nodes[nodes.length - 1]; 23814 } 23815 23816 if (node.parentNode) { 23817 node.parentNode.replaceChild(parent, node); 23818 } 23819 parent.appendChild(node); 23820 }, 23821 23822 unwrap: function(node) { 23823 var parent = node.parentNode, 23824 lastChild = parent.lastChild, 23825 next = node, 23826 grandparent; 23827 23828 if (parent) { 23829 grandparent = parent.parentNode; 23830 if (grandparent) { 23831 node = parent.firstChild; 23832 while (node !== lastChild) { 23833 next = node.nextSibling; 23834 grandparent.insertBefore(node, parent); 23835 node = next; 23836 } 23837 grandparent.replaceChild(lastChild, parent); 23838 } else { 23839 parent.removeChild(node); 23840 } 23841 } 23842 } 23843}); 23844 23845addFeature('innerhtml', 'table', { 23846 test: function() { 23847 var node = Y.config.doc.createElement('table'); 23848 try { 23849 node.innerHTML = '<tbody></tbody>'; 23850 } catch(e) { 23851 return false; 23852 } 23853 return (node.firstChild && node.firstChild.nodeName === 'TBODY'); 23854 } 23855}); 23856 23857addFeature('innerhtml-div', 'tr', { 23858 test: function() { 23859 return createFromDIV('<tr></tr>', 'tr'); 23860 } 23861}); 23862 23863addFeature('innerhtml-div', 'script', { 23864 test: function() { 23865 return createFromDIV('<script></script>', 'script'); 23866 } 23867}); 23868 23869if (!testFeature('innerhtml', 'table')) { 23870 // TODO: thead/tfoot with nested tbody 23871 // IE adds TBODY when creating TABLE elements (which may share this impl) 23872 creators.tbody = function(html, doc) { 23873 var frag = Y_DOM.create(TABLE_OPEN + html + TABLE_CLOSE, doc), 23874 tb = Y.DOM._children(frag, 'tbody')[0]; 23875 23876 if (frag.children.length > 1 && tb && !re_tbody.test(html)) { 23877 tb.parentNode.removeChild(tb); // strip extraneous tbody 23878 } 23879 return frag; 23880 }; 23881} 23882 23883if (!testFeature('innerhtml-div', 'script')) { 23884 creators.script = function(html, doc) { 23885 var frag = doc.createElement('div'); 23886 23887 frag.innerHTML = '-' + html; 23888 frag.removeChild(frag.firstChild); 23889 return frag; 23890 }; 23891 23892 creators.link = creators.style = creators.script; 23893} 23894 23895if (!testFeature('innerhtml-div', 'tr')) { 23896 Y.mix(creators, { 23897 option: function(html, doc) { 23898 return Y_DOM.create('<select><option class="yui3-big-dummy" selected></option>' + html + '</select>', doc); 23899 }, 23900 23901 tr: function(html, doc) { 23902 return Y_DOM.create('<tbody>' + html + '</tbody>', doc); 23903 }, 23904 23905 td: function(html, doc) { 23906 return Y_DOM.create('<tr>' + html + '</tr>', doc); 23907 }, 23908 23909 col: function(html, doc) { 23910 return Y_DOM.create('<colgroup>' + html + '</colgroup>', doc); 23911 }, 23912 23913 tbody: 'table' 23914 }); 23915 23916 Y.mix(creators, { 23917 legend: 'fieldset', 23918 th: creators.td, 23919 thead: creators.tbody, 23920 tfoot: creators.tbody, 23921 caption: creators.tbody, 23922 colgroup: creators.tbody, 23923 optgroup: creators.option 23924 }); 23925} 23926 23927Y_DOM.creators = creators; 23928Y.mix(Y.DOM, { 23929 /** 23930 * Sets the width of the element to the given size, regardless 23931 * of box model, border, padding, etc. 23932 * @method setWidth 23933 * @param {HTMLElement} element The DOM element. 23934 * @param {String|Number} size The pixel height to size to 23935 */ 23936 23937 setWidth: function(node, size) { 23938 Y.DOM._setSize(node, 'width', size); 23939 }, 23940 23941 /** 23942 * Sets the height of the element to the given size, regardless 23943 * of box model, border, padding, etc. 23944 * @method setHeight 23945 * @param {HTMLElement} element The DOM element. 23946 * @param {String|Number} size The pixel height to size to 23947 */ 23948 23949 setHeight: function(node, size) { 23950 Y.DOM._setSize(node, 'height', size); 23951 }, 23952 23953 _setSize: function(node, prop, val) { 23954 val = (val > 0) ? val : 0; 23955 var size = 0; 23956 23957 node.style[prop] = val + 'px'; 23958 size = (prop === 'height') ? node.offsetHeight : node.offsetWidth; 23959 23960 if (size > val) { 23961 val = val - (size - val); 23962 23963 if (val < 0) { 23964 val = 0; 23965 } 23966 23967 node.style[prop] = val + 'px'; 23968 } 23969 } 23970}); 23971 23972 23973}, 'patched-v3.18.1', {"requires": ["dom-core"]}); 23974 23975YUI.add('dom-core', function (Y, NAME) { 23976 23977var NODE_TYPE = 'nodeType', 23978 OWNER_DOCUMENT = 'ownerDocument', 23979 DOCUMENT_ELEMENT = 'documentElement', 23980 DEFAULT_VIEW = 'defaultView', 23981 PARENT_WINDOW = 'parentWindow', 23982 TAG_NAME = 'tagName', 23983 PARENT_NODE = 'parentNode', 23984 PREVIOUS_SIBLING = 'previousSibling', 23985 NEXT_SIBLING = 'nextSibling', 23986 CONTAINS = 'contains', 23987 COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition', 23988 EMPTY_ARRAY = [], 23989 23990 // IE < 8 throws on node.contains(textNode) 23991 supportsContainsTextNode = (function() { 23992 var node = Y.config.doc.createElement('div'), 23993 textNode = node.appendChild(Y.config.doc.createTextNode('')), 23994 result = false;
23995 23996 try { 23997 result = node.contains(textNode); 23998 } catch(e) {} 23999 24000 return result; 24001 })(), 24002 24003/** 24004 * The DOM utility provides a cross-browser abtraction layer 24005 * normalizing DOM tasks, and adds extra helper functionality 24006 * for other common tasks. 24007 * @module dom 24008 * @main dom 24009 * @submodule dom-base 24010 * @for DOM 24011 * 24012 */ 24013 24014/** 24015 * Provides DOM helper methods. 24016 * @class DOM 24017 * 24018 */ 24019 24020Y_DOM = { 24021 /** 24022 * Returns the HTMLElement with the given ID (Wrapper for document.getElementById). 24023 * @method byId 24024 * @param {String} id the id attribute 24025 * @param {Object} doc optional The document to search. Defaults to current document 24026 * @return {HTMLElement | null} The HTMLElement with the id, or null if none found. 24027 */ 24028 byId: function(id, doc) { 24029 // handle dupe IDs and IE name collision 24030 return Y_DOM.allById(id, doc)[0] || null; 24031 }, 24032 24033 getId: function(node) { 24034 var id; 24035 // HTMLElement returned from FORM when INPUT name === "id" 24036 // IE < 8: HTMLCollection returned when INPUT id === "id" 24037 // via both getAttribute and form.id 24038 if (node.id && !node.id.tagName && !node.id.item) { 24039 id = node.id; 24040 } else if (node.attributes && node.attributes.id) { 24041 id = node.attributes.id.value; 24042 } 24043 24044 return id; 24045 }, 24046 24047 setId: function(node, id) { 24048 if (node.setAttribute) { 24049 node.setAttribute('id', id); 24050 } else { 24051 node.id = id; 24052 } 24053 }, 24054 24055 /* 24056 * Finds the ancestor of the element. 24057 * @method ancestor 24058 * @param {HTMLElement} element The html element. 24059 * @param {Function} fn optional An optional boolean test to apply. 24060 * The optional function is passed the current DOM node being tested as its only argument. 24061 * If no function is given, the parentNode is returned. 24062 * @param {Boolean} testSelf optional Whether or not to include the element in the scan 24063 * @return {HTMLElement | null} The matching DOM node or null if none found. 24064 */ 24065 ancestor: function(element, fn, testSelf, stopFn) { 24066 var ret = null; 24067 if (testSelf) { 24068 ret = (!fn || fn(element)) ? element : null; 24069 24070 } 24071 return ret || Y_DOM.elementByAxis(element, PARENT_NODE, fn, null, stopFn); 24072 }, 24073 24074 /* 24075 * Finds the ancestors of the element. 24076 * @method ancestors 24077 * @param {HTMLElement} element The html element. 24078 * @param {Function} fn optional An optional boolean test to apply. 24079 * The optional function is passed the current DOM node being tested as its only argument. 24080 * If no function is given, all ancestors are returned. 24081 * @param {Boolean} testSelf optional Whether or not to include the element in the scan 24082 * @return {Array} An array containing all matching DOM nodes. 24083 */ 24084 ancestors: function(element, fn, testSelf, stopFn) { 24085 var ancestor = element, 24086 ret = []; 24087 24088 while ((ancestor = Y_DOM.ancestor(ancestor, fn, testSelf, stopFn))) { 24089 testSelf = false; 24090 if (ancestor) { 24091 ret.unshift(ancestor); 24092 24093 if (stopFn && stopFn(ancestor)) { 24094 return ret; 24095 } 24096 } 24097 } 24098 24099 return ret; 24100 }, 24101 24102 /** 24103 * Searches the element by the given axis for the first matching element. 24104 * @method elementByAxis 24105 * @param {HTMLElement} element The html element. 24106 * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling). 24107 * @param {Function} [fn] An optional boolean test to apply. 24108 * @param {Boolean} [all] Whether text nodes as well as element nodes should be returned, or 24109 * just element nodes will be returned(default) 24110 * The optional function is passed the current HTMLElement being tested as its only argument. 24111 * If no function is given, the first element is returned. 24112 * @return {HTMLElement | null} The matching element or null if none found. 24113 */ 24114 elementByAxis: function(element, axis, fn, all, stopAt) { 24115 while (element && (element = element[axis])) { // NOTE: assignment 24116 if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) { 24117 return element; 24118 } 24119 24120 if (stopAt && stopAt(element)) { 24121 return null; 24122 } 24123 } 24124 return null; 24125 }, 24126 24127 /** 24128 * Determines whether or not one HTMLElement is or contains another HTMLElement. 24129 * @method contains 24130 * @param {HTMLElement} element The containing html element. 24131 * @param {HTMLElement} needle The html element that may be contained. 24132 * @return {Boolean} Whether or not the element is or contains the needle. 24133 */ 24134 contains: function(element, needle) { 24135 var ret = false;
24136 24137 if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) { 24138 ret = false; 24139 } else if (element[CONTAINS] && 24140 // IE < 8 throws on node.contains(textNode) so fall back to brute. 24141 // Falling back for other nodeTypes as well. 24142 (needle[NODE_TYPE] === 1 || supportsContainsTextNode)) { 24143 ret = element[CONTAINS](needle); 24144 } else if (element[COMPARE_DOCUMENT_POSITION]) { 24145 // Match contains behavior (node.contains(node) === true). 24146 // Needed for Firefox < 4. 24147 if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) { 24148 ret = true; 24149 } 24150 } else { 24151 ret = Y_DOM._bruteContains(element, needle); 24152 } 24153 24154 return ret; 24155 }, 24156 24157 /** 24158 * Determines whether or not the HTMLElement is part of the document. 24159 * @method inDoc 24160 * @param {HTMLElement} element The containing html element. 24161 * @param {HTMLElement} doc optional The document to check. 24162 * @return {Boolean} Whether or not the element is attached to the document. 24163 */ 24164 inDoc: function(element, doc) { 24165 var ret = false, 24166 rootNode; 24167 24168 if (element && element.nodeType) { 24169 (doc) || (doc = element[OWNER_DOCUMENT]); 24170 24171 rootNode = doc[DOCUMENT_ELEMENT]; 24172 24173 // contains only works with HTML_ELEMENT 24174 if (rootNode && rootNode.contains && element.tagName) { 24175 ret = rootNode.contains(element); 24176 } else { 24177 ret = Y_DOM.contains(rootNode, element); 24178 } 24179 } 24180 24181 return ret; 24182 24183 }, 24184 24185 allById: function(id, root) { 24186 root = root || Y.config.doc; 24187 var nodes = [], 24188 ret = [], 24189 i, 24190 node; 24191 24192 if (root.querySelectorAll) { 24193 ret = root.querySelectorAll('[id="' + id + '"]'); 24194 } else if (root.all) { 24195 nodes = root.all(id); 24196 24197 if (nodes) { 24198 // root.all may return HTMLElement or HTMLCollection. 24199 // some elements are also HTMLCollection (FORM, SELECT). 24200 if (nodes.nodeName) { 24201 if (nodes.id === id) { // avoid false positive on name 24202 ret.push(nodes); 24203 nodes = EMPTY_ARRAY; // done, no need to filter 24204 } else { // prep for filtering 24205 nodes = [nodes]; 24206 } 24207 } 24208 24209 if (nodes.length) { 24210 // filter out matches on node.name 24211 // and element.id as reference to element with id === 'id' 24212 for (i = 0; node = nodes[i++];) { 24213 if (node.id === id || 24214 (node.attributes && node.attributes.id && 24215 node.attributes.id.value === id)) { 24216 ret.push(node); 24217 } 24218 } 24219 } 24220 } 24221 } else { 24222 ret = [Y_DOM._getDoc(root).getElementById(id)]; 24223 } 24224 24225 return ret; 24226 }, 24227 24228 24229 isWindow: function(obj) { 24230 return !!(obj && obj.scrollTo && obj.document); 24231 }, 24232 24233 _removeChildNodes: function(node) { 24234 while (node.firstChild) { 24235 node.removeChild(node.firstChild); 24236 } 24237 }, 24238 24239 siblings: function(node, fn) { 24240 var nodes = [], 24241 sibling = node; 24242 24243 while ((sibling = sibling[PREVIOUS_SIBLING])) { 24244 if (sibling[TAG_NAME] && (!fn || fn(sibling))) { 24245 nodes.unshift(sibling); 24246 } 24247 } 24248 24249 sibling = node; 24250 while ((sibling = sibling[NEXT_SIBLING])) { 24251 if (sibling[TAG_NAME] && (!fn || fn(sibling))) { 24252 nodes.push(sibling); 24253 } 24254 } 24255 24256 return nodes; 24257 }, 24258 24259 /** 24260 * Brute force version of contains. 24261 * Used for browsers without contains support for non-HTMLElement Nodes (textNodes, etc). 24262 * @method _bruteContains 24263 * @private 24264 * @param {HTMLElement} element The containing html element. 24265 * @param {HTMLElement} needle The html element that may be contained. 24266 * @return {Boolean} Whether or not the element is or contains the needle. 24267 */ 24268 _bruteContains: function(element, needle) { 24269 while (needle) { 24270 if (element === needle) { 24271 return true; 24272 } 24273 needle = needle.parentNode; 24274 } 24275 return false;
24276 }, 24277 24278// TODO: move to Lang? 24279 /** 24280 * Memoizes dynamic regular expressions to boost runtime performance. 24281 * @method _getRegExp 24282 * @private 24283 * @param {String} str The string to convert to a regular expression. 24284 * @param {String} flags optional An optinal string of flags. 24285 * @return {RegExp} An instance of RegExp 24286 */ 24287 _getRegExp: function(str, flags) { 24288 flags = flags || ''; 24289 Y_DOM._regexCache = Y_DOM._regexCache || {}; 24290 if (!Y_DOM._regexCache[str + flags]) { 24291 Y_DOM._regexCache[str + flags] = new RegExp(str, flags); 24292 } 24293 return Y_DOM._regexCache[str + flags]; 24294 }, 24295 24296// TODO: make getDoc/Win true privates? 24297 /** 24298 * returns the appropriate document. 24299 * @method _getDoc 24300 * @private 24301 * @param {HTMLElement} element optional Target element. 24302 * @return {Object} The document for the given element or the default document. 24303 */ 24304 _getDoc: function(element) { 24305 var doc = Y.config.doc; 24306 if (element) { 24307 doc = (element[NODE_TYPE] === 9) ? element : // element === document 24308 element[OWNER_DOCUMENT] || // element === DOM node 24309 element.document || // element === window 24310 Y.config.doc; // default 24311 } 24312 24313 return doc; 24314 }, 24315 24316 /** 24317 * returns the appropriate window. 24318 * @method _getWin 24319 * @private 24320 * @param {HTMLElement} element optional Target element. 24321 * @return {Object} The window for the given element or the default window. 24322 */ 24323 _getWin: function(element) { 24324 var doc = Y_DOM._getDoc(element); 24325 return doc[DEFAULT_VIEW] || doc[PARENT_WINDOW] || Y.config.win; 24326 }, 24327 24328 _batch: function(nodes, fn, arg1, arg2, arg3, etc) { 24329 fn = (typeof fn === 'string') ? Y_DOM[fn] : fn; 24330 var result, 24331 i = 0, 24332 node, 24333 ret; 24334 24335 if (fn && nodes) { 24336 while ((node = nodes[i++])) { 24337 result = result = fn.call(Y_DOM, node, arg1, arg2, arg3, etc); 24338 if (typeof result !== 'undefined') { 24339 (ret) || (ret = []); 24340 ret.push(result); 24341 } 24342 } 24343 } 24344 24345 return (typeof ret !== 'undefined') ? ret : nodes; 24346 }, 24347 24348 generateID: function(el) { 24349 var id = el.id; 24350 24351 if (!id) { 24352 id = Y.stamp(el); 24353 el.id = id; 24354 } 24355 24356 return id; 24357 } 24358}; 24359 24360 24361Y.DOM = Y_DOM; 24362 24363 24364}, 'patched-v3.18.1', {"requires": ["oop", "features"]}); 24365 24366YUI.add('dom-screen', function (Y, NAME) { 24367 24368(function(Y) { 24369 24370/** 24371 * Adds position and region management functionality to DOM. 24372 * @module dom 24373 * @submodule dom-screen 24374 * @for DOM 24375 */ 24376 24377var DOCUMENT_ELEMENT = 'documentElement', 24378 COMPAT_MODE = 'compatMode', 24379 POSITION = 'position', 24380 FIXED = 'fixed', 24381 RELATIVE = 'relative', 24382 LEFT = 'left', 24383 TOP = 'top', 24384 _BACK_COMPAT = 'BackCompat', 24385 MEDIUM = 'medium', 24386 BORDER_LEFT_WIDTH = 'borderLeftWidth', 24387 BORDER_TOP_WIDTH = 'borderTopWidth', 24388 GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect', 24389 GET_COMPUTED_STYLE = 'getComputedStyle', 24390 24391 Y_DOM = Y.DOM, 24392 24393 // TODO: how about thead/tbody/tfoot/tr? 24394 // TODO: does caption matter? 24395 RE_TABLE = /^t(?:able|d|h)$/i, 24396 24397 SCROLL_NODE; 24398 24399if (Y.UA.ie) { 24400 if (Y.config.doc[COMPAT_MODE] !== 'BackCompat') { 24401 SCROLL_NODE = DOCUMENT_ELEMENT; 24402 } else { 24403 SCROLL_NODE = 'body'; 24404 } 24405} 24406 24407Y.mix(Y_DOM, { 24408 /** 24409 * Returns the inner height of the viewport (exludes scrollbar). 24410 * @method winHeight 24411 * @return {Number} The current height of the viewport. 24412 */ 24413 winHeight: function(node) { 24414 var h = Y_DOM._getWinSize(node).height; 24415 return h; 24416 }, 24417 24418 /** 24419 * Returns the inner width of the viewport (exludes scrollbar). 24420 * @method winWidth 24421 * @return {Number} The current width of the viewport. 24422 */ 24423 winWidth: function(node) { 24424 var w = Y_DOM._getWinSize(node).width; 24425 return w; 24426 }, 24427 24428 /** 24429 * Document height 24430 * @method docHeight 24431 * @return {Number} The current height of the document. 24432 */ 24433 docHeight: function(node) { 24434 var h = Y_DOM._getDocSize(node).height; 24435 return Math.max(h, Y_DOM._getWinSize(node).height); 24436 }, 24437 24438 /** 24439 * Document width 24440 * @method docWidth 24441 * @return {Number} The current width of the document. 24442 */ 24443 docWidth: function(node) { 24444 var w = Y_DOM._getDocSize(node).width; 24445 return Math.max(w, Y_DOM._getWinSize(node).width); 24446 }, 24447 24448 /** 24449 * Amount page has been scroll horizontally 24450 * @method docScrollX 24451 * @return {Number} The current amount the screen is scrolled horizontally. 24452 */ 24453 docScrollX: function(node, doc) { 24454 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization 24455 var dv = doc.defaultView, 24456 pageOffset = (dv) ? dv.pageXOffset : 0; 24457 return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft, pageOffset); 24458 }, 24459 24460 /** 24461 * Amount page has been scroll vertically 24462 * @method docScrollY 24463 * @return {Number} The current amount the screen is scrolled vertically. 24464 */ 24465 docScrollY: function(node, doc) { 24466 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization 24467 var dv = doc.defaultView, 24468 pageOffset = (dv) ? dv.pageYOffset : 0; 24469 return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop, pageOffset); 24470 }, 24471 24472 /** 24473 * Gets the current position of an element based on page coordinates. 24474 * Element must be part of the DOM tree to have page coordinates 24475 * (display:none or elements not appended return false). 24476 * @method getXY 24477 * @param element The target element 24478 * @return {Array} The XY position of the element 24479 24480 TODO: test inDocument/display? 24481 */
24482 getXY: function() { 24483 if (Y.config.doc[DOCUMENT_ELEMENT][GET_BOUNDING_CLIENT_RECT]) { 24484 return function(node) { 24485 var xy = null, 24486 scrollLeft, 24487 scrollTop, 24488 mode, 24489 box, 24490 offX, 24491 offY, 24492 doc, 24493 win, 24494 inDoc, 24495 rootNode; 24496 24497 if (node && node.tagName) { 24498 doc = node.ownerDocument; 24499 mode = doc[COMPAT_MODE]; 24500 24501 if (mode !== _BACK_COMPAT) { 24502 rootNode = doc[DOCUMENT_ELEMENT]; 24503 } else { 24504 rootNode = doc.body; 24505 } 24506 24507 // inline inDoc check for perf 24508 if (rootNode.contains) { 24509 inDoc = rootNode.contains(node); 24510 } else { 24511 inDoc = Y.DOM.contains(rootNode, node); 24512 } 24513 24514 if (inDoc) { 24515 win = doc.defaultView; 24516 24517 // inline scroll calc for perf 24518 if (win && 'pageXOffset' in win) { 24519 scrollLeft = win.pageXOffset; 24520 scrollTop = win.pageYOffset; 24521 } else { 24522 scrollLeft = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollLeft : Y_DOM.docScrollX(node, doc); 24523 scrollTop = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollTop : Y_DOM.docScrollY(node, doc); 24524 } 24525 24526 if (Y.UA.ie) { // IE < 8, quirks, or compatMode 24527 if (!doc.documentMode || doc.documentMode < 8 || mode === _BACK_COMPAT) { 24528 offX = rootNode.clientLeft; 24529 offY = rootNode.clientTop; 24530 } 24531 } 24532 box = node[GET_BOUNDING_CLIENT_RECT](); 24533 xy = [box.left, box.top]; 24534 24535 if (offX || offY) { 24536 xy[0] -= offX; 24537 xy[1] -= offY; 24538 24539 } 24540 if ((scrollTop || scrollLeft)) { 24541 if (!Y.UA.ios || (Y.UA.ios >= 4.2)) { 24542 xy[0] += scrollLeft; 24543 xy[1] += scrollTop; 24544 } 24545 24546 } 24547 } else { 24548 xy = Y_DOM._getOffset(node); 24549 } 24550 } 24551 return xy; 24552 }; 24553 } else { 24554 return function(node) { // manually calculate by crawling up offsetParents 24555 //Calculate the Top and Left border sizes (assumes pixels) 24556 var xy = null, 24557 doc, 24558 parentNode, 24559 bCheck, 24560 scrollTop, 24561 scrollLeft; 24562 24563 if (node) { 24564 if (Y_DOM.inDoc(node)) { 24565 xy = [node.offsetLeft, node.offsetTop]; 24566 doc = node.ownerDocument; 24567 parentNode = node; 24568 // TODO: refactor with !! or just falsey 24569 bCheck = ((Y.UA.gecko || Y.UA.webkit > 519) ? true : false); 24570 24571 // TODO: worth refactoring for TOP/LEFT only? 24572 while ((parentNode = parentNode.offsetParent)) { 24573 xy[0] += parentNode.offsetLeft; 24574 xy[1] += parentNode.offsetTop; 24575 if (bCheck) { 24576 xy = Y_DOM._calcBorders(parentNode, xy); 24577 } 24578 } 24579 24580 // account for any scrolled ancestors 24581 if (Y_DOM.getStyle(node, POSITION) != FIXED) { 24582 parentNode = node; 24583 24584 while ((parentNode = parentNode.parentNode)) { 24585 scrollTop = parentNode.scrollTop; 24586 scrollLeft = parentNode.scrollLeft; 24587 24588 //Firefox does something funky with borders when overflow is not visible. 24589 if (Y.UA.gecko && (Y_DOM.getStyle(parentNode, 'overflow') !== 'visible')) { 24590 xy = Y_DOM._calcBorders(parentNode, xy); 24591 } 24592 24593 24594 if (scrollTop || scrollLeft) { 24595 xy[0] -= scrollLeft; 24596 xy[1] -= scrollTop; 24597 } 24598 } 24599 xy[0] += Y_DOM.docScrollX(node, doc); 24600 xy[1] += Y_DOM.docScrollY(node, doc); 24601 24602 } else { 24603 //Fix FIXED position -- add scrollbars 24604 xy[0] += Y_DOM.docScrollX(node, doc); 24605 xy[1] += Y_DOM.docScrollY(node, doc); 24606 } 24607 } else { 24608 xy = Y_DOM._getOffset(node); 24609 } 24610 } 24611 24612 return xy; 24613 }; 24614 } 24615 }(),// NOTE: Executing for loadtime branching 24616 24617 /** 24618 Gets the width of vertical scrollbars on overflowed containers in the body 24619 content. 24620 24621 @method getScrollbarWidth 24622 @return {Number} Pixel width of a scrollbar in the current browser 24623 **/ 24624 getScrollbarWidth: Y.cached(function () { 24625 var doc = Y.config.doc, 24626 testNode = doc.createElement('div'), 24627 body = doc.getElementsByTagName('body')[0], 24628 // 0.1 because cached doesn't support falsy refetch values 24629 width = 0.1; 24630 24631 if (body) { 24632 testNode.style.cssText = "position:absolute;visibility:hidden;overflow:scroll;width:20px;"; 24633 testNode.appendChild(doc.createElement('p')).style.height = '1px'; 24634 body.insertBefore(testNode, body.firstChild); 24635 width = testNode.offsetWidth - testNode.clientWidth; 24636 24637 body.removeChild(testNode); 24638 } 24639 24640 return width; 24641 }, null, 0.1), 24642 24643 /** 24644 * Gets the current X position of an element based on page coordinates. 24645 * Element must be part of the DOM tree to have page coordinates 24646 * (display:none or elements not appended return false). 24647 * @method getX 24648 * @param element The target element 24649 * @return {Number} The X position of the element 24650 */ 24651 24652 getX: function(node) { 24653 return Y_DOM.getXY(node)[0]; 24654 }, 24655 24656 /** 24657 * Gets the current Y position of an element based on page coordinates. 24658 * Element must be part of the DOM tree to have page coordinates 24659 * (display:none or elements not appended return false). 24660 * @method getY 24661 * @param element The target element 24662 * @return {Number} The Y position of the element 24663 */ 24664 24665 getY: function(node) { 24666 return Y_DOM.getXY(node)[1]; 24667 }, 24668 24669 /** 24670 * Set the position of an html element in page coordinates. 24671 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 24672 * @method setXY 24673 * @param element The target element 24674 * @param {Array} xy Contains X & Y values for new position (coordinates are page-based) 24675 * @param {Boolean} noRetry By default we try and set the position a second time if the first fails 24676 */ 24677 setXY: function(node, xy, noRetry) { 24678 var setStyle = Y_DOM.setStyle, 24679 pos, 24680 delta, 24681 newXY, 24682 currentXY, 24683 offsetDir, 24684 dir, 24685 x; 24686 24687 if (node && xy) { 24688 pos = Y_DOM.getStyle(node, POSITION); 24689 24690 offsetDir = Y_DOM.OFFSET_XY; 24691 24692 if (!offsetDir) { 24693 dir = Y_DOM.getComputedStyle(node, 'direction'); 24694 24695 offsetDir = (dir === 'rtl' ? 'right' : LEFT); 24696 } 24697 24698 delta = Y_DOM._getOffset(node, offsetDir); 24699 if (pos == 'static') { // default to relative 24700 pos = RELATIVE; 24701 setStyle(node, POSITION, pos); 24702 } 24703 currentXY = Y_DOM._getDirXY(node, offsetDir); 24704 24705 x = xy[0]; 24706 24707 if (offsetDir === 'right') { 24708 x = Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10)); 24709 24710 if (!delta[0] && !noRetry) { 24711 noRetry = false;
24712 } 24713 } 24714 24715 if (x !== null) { 24716 setStyle(node, offsetDir, x - currentXY[0] + delta[0] + 'px'); 24717 } 24718 24719 if (xy[1] !== null) { 24720 setStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px'); 24721 } 24722 24723 if (!noRetry) { 24724 newXY = Y_DOM.getXY(node); 24725 if (newXY[0] !== xy[0] || newXY[1] !== xy[1]) { 24726 Y_DOM.setXY(node, xy, true); 24727 } 24728 } 24729 24730 } else { 24731 } 24732 }, 24733 24734 /** 24735 * Set the X position of an html element in page coordinates, regardless of how the element is positioned. 24736 * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 24737 * @method setX 24738 * @param element The target element 24739 * @param {Number} x The X values for new position (coordinates are page-based) 24740 */ 24741 setX: function(node, x) { 24742 return Y_DOM.setXY(node, [x, null]); 24743 }, 24744 24745 /** 24746 * Set the Y position of an html element in page coordinates, regardless of how the element is positioned. 24747 * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 24748 * @method setY 24749 * @param element The target element 24750 * @param {Number} y The Y values for new position (coordinates are page-based) 24751 */ 24752 setY: function(node, y) { 24753 return Y_DOM.setXY(node, [null, y]); 24754 }, 24755 24756 /** 24757 * @method swapXY 24758 * @description Swap the xy position with another node 24759 * @param {Node} node The node to swap with 24760 * @param {Node} otherNode The other node to swap with 24761 * @return {Node} 24762 */ 24763 swapXY: function(node, otherNode) { 24764 var xy = Y_DOM.getXY(node); 24765 Y_DOM.setXY(node, Y_DOM.getXY(otherNode)); 24766 Y_DOM.setXY(otherNode, xy); 24767 }, 24768 24769 _calcBorders: function(node, xy2) { 24770 var t = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0, 24771 l = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0; 24772 if (Y.UA.gecko) { 24773 if (RE_TABLE.test(node.tagName)) { 24774 t = 0; 24775 l = 0; 24776 } 24777 } 24778 xy2[0] += l; 24779 xy2[1] += t; 24780 return xy2; 24781 }, 24782 24783 _getWinSize: function(node, doc) { 24784 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; 24785 var win = doc.defaultView || doc.parentWindow, 24786 mode = doc[COMPAT_MODE], 24787 h = win.innerHeight, 24788 w = win.innerWidth, 24789 root = doc[DOCUMENT_ELEMENT]; 24790 24791 if ( mode && !Y.UA.opera ) { // IE, Gecko 24792 if (mode != 'CSS1Compat') { // Quirks 24793 root = doc.body; 24794 } 24795 h = root.clientHeight; 24796 w = root.clientWidth; 24797 } 24798 return { height: h, width: w }; 24799 }, 24800 24801 _getDocSize: function(node) { 24802 var doc = (node) ? Y_DOM._getDoc(node) : Y.config.doc, 24803 root = doc[DOCUMENT_ELEMENT]; 24804 24805 if (doc[COMPAT_MODE] != 'CSS1Compat') { 24806 root = doc.body; 24807 } 24808 24809 return { height: root.scrollHeight, width: root.scrollWidth }; 24810 }, 24811 24812 _getDirXY: function(node, dir) { 24813 var xy = Y_DOM.getXY(node); 24814 24815 if (dir === 'right') { 24816 xy[0] = (Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10))); 24817 } 24818 24819 return xy; 24820 } 24821}); 24822 24823})(Y); 24824(function(Y) { 24825var TOP = 'top', 24826 RIGHT = 'right', 24827 BOTTOM = 'bottom', 24828 LEFT = 'left', 24829 24830 getOffsets = function(r1, r2) { 24831 var t = Math.max(r1[TOP], r2[TOP]), 24832 r = Math.min(r1[RIGHT], r2[RIGHT]), 24833 b = Math.min(r1[BOTTOM], r2[BOTTOM]), 24834 l = Math.max(r1[LEFT], r2[LEFT]), 24835 ret = {}; 24836 24837 ret[TOP] = t; 24838 ret[RIGHT] = r; 24839 ret[BOTTOM] = b; 24840 ret[LEFT] = l; 24841 return ret; 24842 }, 24843 24844 DOM = Y.DOM; 24845 24846Y.mix(DOM, { 24847 /** 24848 * Returns an Object literal containing the following about this element: (top, right, bottom, left) 24849 * @for DOM 24850 * @method region 24851 * @param {HTMLElement} element The DOM element. 24852 * @return {Object} Object literal containing the following about this element: (top, right, bottom, left) 24853 */ 24854 region: function(node) { 24855 var xy = DOM.getXY(node), 24856 ret = false;
24857 24858 if (node && xy) { 24859 ret = DOM._getRegion( 24860 xy[1], // top 24861 xy[0] + node.offsetWidth, // right 24862 xy[1] + node.offsetHeight, // bottom 24863 xy[0] // left 24864 ); 24865 } 24866 24867 return ret; 24868 }, 24869 24870 /** 24871 * Find the intersect information for the passed nodes. 24872 * @method intersect 24873 * @for DOM 24874 * @param {HTMLElement} element The first element 24875 * @param {HTMLElement | Object} element2 The element or region to check the interect with 24876 * @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance e.g. DragDrop) 24877 * @return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion) 24878 */ 24879 intersect: function(node, node2, altRegion) { 24880 var r = altRegion || DOM.region(node), region = {}, 24881 n = node2, 24882 off; 24883 24884 if (n.tagName) { 24885 region = DOM.region(n); 24886 } else if (Y.Lang.isObject(node2)) { 24887 region = node2; 24888 } else { 24889 return false; 24890 } 24891 24892 off = getOffsets(region, r); 24893 return { 24894 top: off[TOP], 24895 right: off[RIGHT], 24896 bottom: off[BOTTOM], 24897 left: off[LEFT], 24898 area: ((off[BOTTOM] - off[TOP]) * (off[RIGHT] - off[LEFT])), 24899 yoff: ((off[BOTTOM] - off[TOP])), 24900 xoff: (off[RIGHT] - off[LEFT]), 24901 inRegion: DOM.inRegion(node, node2, false, altRegion) 24902 }; 24903 24904 }, 24905 /** 24906 * Check if any part of this node is in the passed region 24907 * @method inRegion 24908 * @for DOM 24909 * @param {Object} node The node to get the region from 24910 * @param {Object} node2 The second node to get the region from or an Object literal of the region 24911 * @param {Boolean} all Should all of the node be inside the region 24912 * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop) 24913 * @return {Boolean} True if in region, false if not. 24914 */ 24915 inRegion: function(node, node2, all, altRegion) { 24916 var region = {}, 24917 r = altRegion || DOM.region(node), 24918 n = node2, 24919 off; 24920 24921 if (n.tagName) { 24922 region = DOM.region(n); 24923 } else if (Y.Lang.isObject(node2)) { 24924 region = node2; 24925 } else { 24926 return false; 24927 } 24928 24929 if (all) { 24930 return ( 24931 r[LEFT] >= region[LEFT] && 24932 r[RIGHT] <= region[RIGHT] && 24933 r[TOP] >= region[TOP] && 24934 r[BOTTOM] <= region[BOTTOM] ); 24935 } else { 24936 off = getOffsets(region, r); 24937 if (off[BOTTOM] >= off[TOP] && off[RIGHT] >= off[LEFT]) { 24938 return true; 24939 } else { 24940 return false; 24941 } 24942 24943 } 24944 }, 24945 24946 /** 24947 * Check if any part of this element is in the viewport 24948 * @method inViewportRegion 24949 * @for DOM 24950 * @param {HTMLElement} element The DOM element. 24951 * @param {Boolean} all Should all of the node be inside the region 24952 * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop) 24953 * @return {Boolean} True if in region, false if not. 24954 */ 24955 inViewportRegion: function(node, all, altRegion) { 24956 return DOM.inRegion(node, DOM.viewportRegion(node), all, altRegion); 24957 24958 }, 24959 24960 _getRegion: function(t, r, b, l) { 24961 var region = {}; 24962 24963 region[TOP] = region[1] = t; 24964 region[LEFT] = region[0] = l; 24965 region[BOTTOM] = b; 24966 region[RIGHT] = r; 24967 region.width = region[RIGHT] - region[LEFT]; 24968 region.height = region[BOTTOM] - region[TOP]; 24969 24970 return region; 24971 }, 24972 24973 /** 24974 * Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left) 24975 * @method viewportRegion 24976 * @for DOM 24977 * @return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left) 24978 */ 24979 viewportRegion: function(node) { 24980 node = node || Y.config.doc.documentElement; 24981 var ret = false, 24982 scrollX, 24983 scrollY; 24984 24985 if (node) { 24986 scrollX = DOM.docScrollX(node); 24987 scrollY = DOM.docScrollY(node); 24988 24989 ret = DOM._getRegion(scrollY, // top 24990 DOM.winWidth(node) + scrollX, // right 24991 scrollY + DOM.winHeight(node), // bottom 24992 scrollX); // left 24993 } 24994 24995 return ret; 24996 } 24997}); 24998})(Y); 24999 25000 25001}, 'patched-v3.18.1', {"requires": ["dom-base", "dom-style"]}); 25002 25003YUI.add('dom-style', function (Y, NAME) { 25004 25005/** 25006 * Add style management functionality to DOM. 25007 * @module dom 25008 * @submodule dom-style 25009 * @for DOM 25010 */ 25011 25012var DOCUMENT_ELEMENT = 'documentElement', 25013 DEFAULT_VIEW = 'defaultView', 25014 OWNER_DOCUMENT = 'ownerDocument', 25015 STYLE = 'style', 25016 FLOAT = 'float', 25017 CSS_FLOAT = 'cssFloat', 25018 STYLE_FLOAT = 'styleFloat', 25019 TRANSPARENT = 'transparent', 25020 GET_COMPUTED_STYLE = 'getComputedStyle', 25021 GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect', 25022 25023 DOCUMENT = Y.config.doc, 25024 25025 Y_DOM = Y.DOM, 25026 25027 TRANSFORM, 25028 TRANSFORMORIGIN, 25029 VENDOR_TRANSFORM = [ 25030 'WebkitTransform', 25031 'MozTransform', 25032 'OTransform', 25033 'msTransform', 25034 'transform' 25035 ], 25036 25037 re_unit = /width|height|top|left|right|bottom|margin|padding/i; 25038 25039Y.Array.each(VENDOR_TRANSFORM, function(val) { 25040 if (val in DOCUMENT[DOCUMENT_ELEMENT].style) { 25041 TRANSFORM = val;
25042 TRANSFORMORIGIN = val + "Origin"; 25043 } 25044}); 25045 25046Y.mix(Y_DOM, { 25047 DEFAULT_UNIT: 'px', 25048 25049 CUSTOM_STYLES: { 25050 }, 25051 25052 25053 /** 25054 * Sets a style property for a given element. 25055 * @method setStyle 25056 * @param {HTMLElement} node The HTMLElement to apply the style to. 25057 * @param {String} att The style property to set. 25058 * @param {String|Number} val The value. 25059 * @param {Object} [style] The style node. Defaults to `node.style`. 25060 */ 25061 setStyle: function(node, att, val, style) { 25062 style = style || node.style; 25063 var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES; 25064 25065 if (style) { 25066 if (val === null || val === '') { // normalize unsetting 25067 val = ''; 25068 } else if (!isNaN(Number(val)) && re_unit.test(att)) { // number values may need a unit 25069 val += Y_DOM.DEFAULT_UNIT; 25070 } 25071 25072 if (att in CUSTOM_STYLES) { 25073 if (CUSTOM_STYLES[att].set) { 25074 CUSTOM_STYLES[att].set(node, val, style); 25075 return; // NOTE: return 25076 } else if (typeof CUSTOM_STYLES[att] === 'string') { 25077 att = CUSTOM_STYLES[att]; 25078 } 25079 } else if (att === '') { // unset inline styles 25080 att = 'cssText'; 25081 val = ''; 25082 } 25083 style[att] = val; 25084 } 25085 }, 25086 25087 /** 25088 * Returns the current style value for the given property. 25089 * @method getStyle 25090 * @param {HTMLElement} node The HTMLElement to get the style from. 25091 * @param {String} att The style property to get. 25092 * @param {Object} [style] The style node. Defaults to `node.style`. 25093 */ 25094 getStyle: function(node, att, style) { 25095 style = style || node.style; 25096 var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES, 25097 val = ''; 25098 25099 if (style) { 25100 if (att in CUSTOM_STYLES) { 25101 if (CUSTOM_STYLES[att].get) { 25102 return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return 25103 } else if (typeof CUSTOM_STYLES[att] === 'string') { 25104 att = CUSTOM_STYLES[att]; 25105 } 25106 } 25107 val = style[att]; 25108 if (val === '') { // TODO: is empty string sufficient? 25109 val = Y_DOM[GET_COMPUTED_STYLE](node, att); 25110 } 25111 } 25112 25113 return val; 25114 }, 25115 25116 /** 25117 * Sets multiple style properties. 25118 * @method setStyles 25119 * @param {HTMLElement} node The HTMLElement to apply the styles to. 25120 * @param {Object} hash An object literal of property:value pairs. 25121 */ 25122 setStyles: function(node, hash) { 25123 var style = node.style; 25124 Y.each(hash, function(v, n) { 25125 Y_DOM.setStyle(node, n, v, style); 25126 }, Y_DOM); 25127 }, 25128 25129 /** 25130 * Returns the computed style for the given node. 25131 * @method getComputedStyle 25132 * @param {HTMLElement} node The HTMLElement to get the style from. 25133 * @param {String} att The style property to get. 25134 * @return {String} The computed value of the style property. 25135 */ 25136 getComputedStyle: function(node, att) { 25137 var val = '', 25138 doc = node[OWNER_DOCUMENT], 25139 computed; 25140 25141 if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) { 25142 computed = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null); 25143 if (computed) { // FF may be null in some cases (ticket #2530548) 25144 val = computed[att]; 25145 } 25146 } 25147 return val; 25148 } 25149}); 25150 25151// normalize reserved word float alternatives ("cssFloat" or "styleFloat") 25152if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== undefined) { 25153 Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT; 25154} else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== undefined) { 25155 Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT; 25156} 25157 25158// safari converts transparent to rgba(), others use "transparent" 25159if (Y.UA.webkit) { 25160 Y_DOM[GET_COMPUTED_STYLE] = function(node, att) { 25161 var view = node[OWNER_DOCUMENT][DEFAULT_VIEW], 25162 val = view[GET_COMPUTED_STYLE](node, '')[att]; 25163 25164 if (val === 'rgba(0, 0, 0, 0)') { 25165 val = TRANSPARENT; 25166 } 25167 25168 return val; 25169 }; 25170 25171} 25172 25173Y.DOM._getAttrOffset = function(node, attr) { 25174 var val = Y.DOM[GET_COMPUTED_STYLE](node, attr), 25175 offsetParent = node.offsetParent, 25176 position, 25177 parentOffset, 25178 offset; 25179 25180 if (val === 'auto') { 25181 position = Y.DOM.getStyle(node, 'position'); 25182 if (position === 'static' || position === 'relative') { 25183 val = 0; 25184 } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) { 25185 parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr]; 25186 offset = node[GET_BOUNDING_CLIENT_RECT]()[attr]; 25187 if (attr === 'left' || attr === 'top') { 25188 val = offset - parentOffset; 25189 } else { 25190 val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr]; 25191 } 25192 } 25193 } 25194 25195 return val; 25196}; 25197 25198Y.DOM._getOffset = function(node, dir) { 25199 var pos,
25200 xy = null, 25201 offset = { 25202 left: 'offsetLeft', 25203 right: 'offsetRight' 25204 }, 25205 margins = { 25206 left: 'marginLeft', 25207 right: 'marginRight' 25208 }, 25209 margin; 25210 25211 dir = dir || 'left'; 25212 25213 if (node) { 25214 pos = Y_DOM.getStyle(node, 'position'); 25215 margin = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, margins[dir]), 10); 25216 xy = [ 25217 parseInt(Y_DOM[GET_COMPUTED_STYLE](node, dir), 10), 25218 parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10) 25219 ]; 25220 25221 if ( isNaN(xy[0]) ) { // in case of 'auto' 25222 xy[0] = parseInt(Y_DOM.getStyle(node, dir), 10); // try inline 25223 if ( isNaN(xy[0]) ) { // default to offset value 25224 xy[0] = (pos === 'relative') ? 0 : (node[offset[dir]] - margin) || 0; 25225 } 25226 } 25227 25228 if ( isNaN(xy[1]) ) { // in case of 'auto' 25229 xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline 25230 if ( isNaN(xy[1]) ) { // default to offset value 25231 xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0; 25232 } 25233 } 25234 } 25235 25236 return xy; 25237 25238}; 25239 25240if (TRANSFORM) { 25241 Y_DOM.CUSTOM_STYLES.transform = { 25242 set: function(node, val, style) { 25243 style[TRANSFORM] = val; 25244 }, 25245 25246 get: function(node) { 25247 return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM); 25248 } 25249 }; 25250 25251 Y_DOM.CUSTOM_STYLES.transformOrigin = { 25252 set: function(node, val, style) { 25253 style[TRANSFORMORIGIN] = val; 25254 }, 25255 25256 get: function(node) { 25257 return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORMORIGIN); 25258 } 25259 }; 25260} 25261 25262 25263}, 'patched-v3.18.1', {"requires": ["dom-base"]}); 25264 25265YUI.add('event-base', function (Y, NAME) { 25266 25267/* 25268 * DOM event listener abstraction layer 25269 * @module event 25270 * @submodule event-base 25271 */ 25272 25273/** 25274 * The domready event fires at the moment the browser's DOM is 25275 * usable. In most cases, this is before images are fully 25276 * downloaded, allowing you to provide a more responsive user 25277 * interface. 25278 * 25279 * In YUI 3, domready subscribers will be notified immediately if 25280 * that moment has already passed when the subscription is created. 25281 * 25282 * One exception is if the yui.js file is dynamically injected into 25283 * the page. If this is done, you must tell the YUI instance that 25284 * you did this in order for DOMReady (and window load events) to 25285 * fire normally. That configuration option is 'injected' -- set 25286 * it to true if the yui.js script is not included inline. 25287 * 25288 * This method is part of the 'event-ready' module, which is a 25289 * submodule of 'event'. 25290 * 25291 * @event domready 25292 * @for YUI 25293 */ 25294Y.publish('domready', { 25295 fireOnce: true, 25296 async: true 25297}); 25298 25299if (YUI.Env.DOMReady) { 25300 Y.fire('domready'); 25301} else { 25302 Y.Do.before(function() { Y.fire('domready'); }, YUI.Env, '_ready'); 25303} 25304 25305/** 25306 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 25307 * events. 25308 * @module event 25309 * @submodule event-base 25310 */ 25311 25312/** 25313 * Wraps a DOM event, properties requiring browser abstraction are 25314 * fixed here. Provids a security layer when required. 25315 * @class DOMEventFacade 25316 * @param ev {Event} the DOM event 25317 * @param currentTarget {HTMLElement} the element the listener was attached to 25318 * @param wrapper {CustomEvent} the custom event wrapper for this DOM event 25319 */ 25320 25321 var ua = Y.UA, 25322 25323 EMPTY = {}, 25324 25325 /** 25326 * webkit key remapping required for Safari < 3.1 25327 * @property webkitKeymap 25328 * @private 25329 */ 25330 webkitKeymap = { 25331 63232: 38, // up 25332 63233: 40, // down 25333 63234: 37, // left 25334 63235: 39, // right 25335 63276: 33, // page up 25336 63277: 34, // page down 25337 25: 9, // SHIFT-TAB (Safari provides a different key code in 25338 // this case, even though the shiftKey modifier is set) 25339 63272: 46, // delete 25340 63273: 36, // home 25341 63275: 35 // end 25342 }, 25343 25344 /** 25345 * Returns a wrapped node. Intended to be used on event targets, 25346 * so it will return the node's parent if the target is a text 25347 * node. 25348 * 25349 * If accessing a property of the node throws an error, this is 25350 * probably the anonymous div wrapper Gecko adds inside text 25351 * nodes. This likely will only occur when attempting to access 25352 * the relatedTarget. In this case, we now return null because 25353 * the anonymous div is completely useless and we do not know 25354 * what the related target was because we can't even get to 25355 * the element's parent node. 25356 * 25357 * @method resolve 25358 * @private 25359 */ 25360 resolve = function(n) { 25361 if (!n) { 25362 return n; 25363 } 25364 try { 25365 if (n && 3 == n.nodeType) { 25366 n = n.parentNode; 25367 } 25368 } catch(e) { 25369 return null; 25370 } 25371 25372 return Y.one(n); 25373 }, 25374 25375 DOMEventFacade = function(ev, currentTarget, wrapper) { 25376 this._event = ev; 25377 this._currentTarget = currentTarget; 25378 this._wrapper = wrapper || EMPTY; 25379 25380 // if not lazy init 25381 this.init(); 25382 }; 25383 25384Y.extend(DOMEventFacade, Object, { 25385 25386 init: function() { 25387 25388 var e = this._event, 25389 overrides = this._wrapper.overrides, 25390 x = e.pageX, 25391 y = e.pageY, 25392 c, 25393 currentTarget = this._currentTarget; 25394 25395 this.altKey = e.altKey; 25396 this.ctrlKey = e.ctrlKey; 25397 this.metaKey = e.metaKey; 25398 this.shiftKey = e.shiftKey; 25399 this.type = (overrides && overrides.type) || e.type; 25400 this.clientX = e.clientX; 25401 this.clientY = e.clientY; 25402 25403 this.pageX = x; 25404 this.pageY = y; 25405
25406 // charCode is unknown in keyup, keydown. keyCode is unknown in keypress. 25407 // FF 3.6 - 8+? pass 0 for keyCode in keypress events. 25408 // Webkit, FF 3.6-8+?, and IE9+? pass 0 for charCode in keydown, keyup. 25409 // Webkit and IE9+? duplicate charCode in keyCode. 25410 // Opera never sets charCode, always keyCode (though with the charCode). 25411 // IE6-8 don't set charCode or which. 25412 // All browsers other than IE6-8 set which=keyCode in keydown, keyup, and 25413 // which=charCode in keypress. 25414 // 25415 // Moral of the story: (e.which || e.keyCode) will always return the 25416 // known code for that key event phase. e.keyCode is often different in 25417 // keypress from keydown and keyup. 25418 c = e.keyCode || e.charCode; 25419 25420 if (ua.webkit && (c in webkitKeymap)) { 25421 c = webkitKeymap[c]; 25422 } 25423 25424 this.keyCode = c; 25425 this.charCode = c; 25426 // Fill in e.which for IE - implementers should always use this over 25427 // e.keyCode or e.charCode. 25428 this.which = e.which || e.charCode || c; 25429 // this.button = e.button; 25430 this.button = this.which; 25431 25432 this.target = resolve(e.target); 25433 this.currentTarget = resolve(currentTarget); 25434 this.relatedTarget = resolve(e.relatedTarget); 25435 25436 if (e.type == "mousewheel" || e.type == "DOMMouseScroll") { 25437 this.wheelDelta = (e.detail) ? (e.detail * -1) : Math.round(e.wheelDelta / 80) || ((e.wheelDelta < 0) ? -1 : 1); 25438 } 25439 25440 if (this._touch) { 25441 this._touch(e, currentTarget, this._wrapper); 25442 } 25443 }, 25444 25445 stopPropagation: function() { 25446 this._event.stopPropagation(); 25447 this._wrapper.stopped = 1; 25448 this.stopped = 1; 25449 }, 25450 25451 stopImmediatePropagation: function() { 25452 var e = this._event; 25453 if (e.stopImmediatePropagation) { 25454 e.stopImmediatePropagation(); 25455 } else { 25456 this.stopPropagation(); 25457 } 25458 this._wrapper.stopped = 2; 25459 this.stopped = 2; 25460 }, 25461 25462 preventDefault: function(returnValue) { 25463 var e = this._event; 25464 e.preventDefault(); 25465 if (returnValue) { 25466 e.returnValue = returnValue; 25467 } 25468 this._wrapper.prevented = 1; 25469 this.prevented = 1; 25470 }, 25471 25472 halt: function(immediate) { 25473 if (immediate) { 25474 this.stopImmediatePropagation(); 25475 } else { 25476 this.stopPropagation(); 25477 } 25478 25479 this.preventDefault(); 25480 } 25481 25482}); 25483 25484DOMEventFacade.resolve = resolve; 25485Y.DOM2EventFacade = DOMEventFacade; 25486Y.DOMEventFacade = DOMEventFacade; 25487 25488 /** 25489 * The native event 25490 * @property _event 25491 * @type {DOMEvent} 25492 * @private 25493 */ 25494 25495 /** 25496 The name of the event (e.g. "click") 25497 25498 @property type 25499 @type {String} 25500 **/ 25501 25502 /** 25503 `true` if the "alt" or "option" key is pressed. 25504 25505 @property altKey 25506 @type {Boolean} 25507 **/ 25508 25509 /** 25510 `true` if the shift key is pressed. 25511 25512 @property shiftKey 25513 @type {Boolean} 25514 **/ 25515 25516 /** 25517 `true` if the "Windows" key on a Windows keyboard, "command" key on an 25518 Apple keyboard, or "meta" key on other keyboards is pressed. 25519 25520 @property metaKey 25521 @type {Boolean} 25522 **/ 25523 25524 /** 25525 `true` if the "Ctrl" or "control" key is pressed. 25526 25527 @property ctrlKey 25528 @type {Boolean} 25529 **/ 25530 25531 /** 25532 * The X location of the event on the page (including scroll) 25533 * @property pageX 25534 * @type {Number} 25535 */ 25536 25537 /** 25538 * The Y location of the event on the page (including scroll) 25539 * @property pageY 25540 * @type {Number} 25541 */ 25542 25543 /** 25544 * The X location of the event in the viewport 25545 * @property clientX 25546 * @type {Number} 25547 */ 25548 25549 /** 25550 * The Y location of the event in the viewport 25551 * @property clientY 25552 * @type {Number} 25553 */ 25554 25555 /** 25556 * The keyCode for key events. Uses charCode if keyCode is not available 25557 * @property keyCode 25558 * @type {Number} 25559 */ 25560 25561 /** 25562 * The charCode for key events. Same as keyCode 25563 * @property charCode 25564 * @type {Number} 25565 */ 25566 25567 /** 25568 * The button that was pushed. 1 for left click, 2 for middle click, 3 for 25569 * right click. This is only reliably populated on `mouseup` events. 25570 * @property button 25571 * @type {Number} 25572 */ 25573 25574 /** 25575 * The button that was pushed. Same as button. 25576 * @property which 25577 * @type {Number} 25578 */ 25579 25580 /** 25581 * Node reference for the targeted element 25582 * @property target 25583 * @type {Node} 25584 */ 25585 25586 /** 25587 * Node reference for the element that the listener was attached to. 25588 * @property currentTarget 25589 * @type {Node} 25590 */ 25591 25592 /** 25593 * Node reference to the relatedTarget 25594 * @property relatedTarget 25595 * @type {Node} 25596 */ 25597 25598 /** 25599 * Number representing the direction and velocity of the movement of the mousewheel. 25600 * Negative is down, the higher the number, the faster. Applies to the mousewheel event. 25601 * @property wheelDelta 25602 * @type {Number} 25603 */ 25604 25605 /** 25606 * Stops the propagation to the next bubble target 25607 * @method stopPropagation 25608 */ 25609 25610 /** 25611 * Stops the propagation to the next bubble target and 25612 * prevents any additional listeners from being exectued 25613 * on the current target. 25614 * @method stopImmediatePropagation 25615 */ 25616 25617 /** 25618 * Prevents the event's default behavior 25619 * @method preventDefault 25620 * @param returnValue {string} sets the returnValue of the event to this value 25621 * (rather than the default false value). This can be used to add a customized 25622 * confirmation query to the beforeunload event). 25623 */ 25624 25625 /** 25626 * Stops the event propagation and prevents the default 25627 * event behavior. 25628 * @method halt 25629 * @param immediate {boolean} if true additional listeners 25630 * on the current target will not be executed 25631 */ 25632(function() { 25633 25634/** 25635 * The event utility provides functions to add and remove event listeners, 25636 * event cleansing. It also tries to automatically remove listeners it 25637 * registers during the unload event. 25638 * @module event 25639 * @main event 25640 * @submodule event-base 25641 */ 25642 25643/** 25644 * The event utility provides functions to add and remove event listeners, 25645 * event cleansing. It also tries to automatically remove listeners it 25646 * registers during the unload event. 25647 * 25648 * @class Event 25649 * @static 25650 */ 25651 25652Y.Env.evt.dom_wrappers = {}; 25653Y.Env.evt.dom_map = {}; 25654 25655var _eventenv = Y.Env.evt, 25656 config = Y.config, 25657 win = config.win, 25658 add = YUI.Env.add, 25659 remove = YUI.Env.remove, 25660 25661 onLoad = function() { 25662 YUI.Env.windowLoaded = true; 25663 Y.Event._load(); 25664 remove(win, "load", onLoad); 25665 }, 25666 25667 onUnload = function() { 25668 Y.Event._unload(); 25669 }, 25670 25671 EVENT_READY = 'domready', 25672 25673 COMPAT_ARG = '~yui|2|compat~', 25674 25675 shouldIterate = function(o) { 25676 try { 25677 // TODO: See if there's a more performant way to return true early on this, for the common case 25678 return (o && typeof o !== "string" && Y.Lang.isNumber(o.length) && !o.tagName && !Y.DOM.isWindow(o)); 25679 } catch(ex) { 25680 return false;
25681 } 25682 }, 25683 25684 // aliases to support DOM event subscription clean up when the last 25685 // subscriber is detached. deleteAndClean overrides the DOM event's wrapper 25686 // CustomEvent _delete method. 25687 _ceProtoDelete = Y.CustomEvent.prototype._delete, 25688 _deleteAndClean = function(s) { 25689 var ret = _ceProtoDelete.apply(this, arguments); 25690 25691 if (!this.hasSubs()) { 25692 Y.Event._clean(this); 25693 } 25694 25695 return ret; 25696 }, 25697 25698Event = function() { 25699 25700 /** 25701 * True after the onload event has fired 25702 * @property _loadComplete 25703 * @type boolean 25704 * @static 25705 * @private 25706 */ 25707 var _loadComplete = false, 25708 25709 /** 25710 * The number of times to poll after window.onload. This number is 25711 * increased if additional late-bound handlers are requested after 25712 * the page load. 25713 * @property _retryCount 25714 * @static 25715 * @private 25716 */ 25717 _retryCount = 0, 25718 25719 /** 25720 * onAvailable listeners 25721 * @property _avail 25722 * @static 25723 * @private 25724 */ 25725 _avail = [], 25726 25727 /** 25728 * Custom event wrappers for DOM events. Key is 25729 * 'event:' + Element uid stamp + event type 25730 * @property _wrappers 25731 * @type CustomEvent 25732 * @static 25733 * @private 25734 */ 25735 _wrappers = _eventenv.dom_wrappers, 25736 25737 _windowLoadKey = null, 25738 25739 /** 25740 * Custom event wrapper map DOM events. Key is 25741 * Element uid stamp. Each item is a hash of custom event 25742 * wrappers as provided in the _wrappers collection. This 25743 * provides the infrastructure for getListeners. 25744 * @property _el_events 25745 * @static 25746 * @private 25747 */ 25748 _el_events = _eventenv.dom_map; 25749 25750 return { 25751 25752 /** 25753 * The number of times we should look for elements that are not 25754 * in the DOM at the time the event is requested after the document 25755 * has been loaded. The default is 1000@amp;40 ms, so it will poll 25756 * for 40 seconds or until all outstanding handlers are bound 25757 * (whichever comes first). 25758 * @property POLL_RETRYS 25759 * @type int 25760 * @static 25761 * @final 25762 */ 25763 POLL_RETRYS: 1000, 25764 25765 /** 25766 * The poll interval in milliseconds 25767 * @property POLL_INTERVAL 25768 * @type int 25769 * @static 25770 * @final 25771 */ 25772 POLL_INTERVAL: 40, 25773 25774 /** 25775 * addListener/removeListener can throw errors in unexpected scenarios. 25776 * These errors are suppressed, the method returns false, and this property 25777 * is set 25778 * @property lastError 25779 * @static 25780 * @type Error 25781 */ 25782 lastError: null, 25783 25784 25785 /** 25786 * poll handle 25787 * @property _interval 25788 * @static 25789 * @private 25790 */ 25791 _interval: null, 25792 25793 /** 25794 * document readystate poll handle 25795 * @property _dri 25796 * @static 25797 * @private 25798 */ 25799 _dri: null, 25800 25801 /** 25802 * True when the document is initially usable 25803 * @property DOMReady 25804 * @type boolean 25805 * @static 25806 */ 25807 DOMReady: false, 25808 25809 /** 25810 * @method startInterval 25811 * @static 25812 * @private 25813 */ 25814 startInterval: function() { 25815 if (!Event._interval) { 25816Event._interval = setInterval(Event._poll, Event.POLL_INTERVAL); 25817 } 25818 }, 25819 25820 /** 25821 * Executes the supplied callback when the item with the supplied 25822 * id is found. This is meant to be used to execute behavior as 25823 * soon as possible as the page loads. If you use this after the 25824 * initial page load it will poll for a fixed time for the element. 25825 * The number of times it will poll and the frequency are 25826 * configurable. By default it will poll for 10 seconds. 25827 * 25828 * <p>The callback is executed with a single parameter: 25829 * the custom object parameter, if provided.</p> 25830 * 25831 * @method onAvailable 25832 * 25833 * @param {string||string[]} id the id of the element, or an array 25834 * of ids to look for. 25835 * @param {function} fn what to execute when the element is found. 25836 * @param {object} p_obj an optional object to be passed back as 25837 * a parameter to fn. 25838 * @param {boolean|object} p_override If set to true, fn will execute 25839 * in the context of p_obj, if set to an object it 25840 * will execute in the context of that object 25841 * @param checkContent {boolean} check child node readiness (onContentReady) 25842 * @static 25843 * @deprecated Use Y.on("available") 25844 */ 25845 // @TODO fix arguments 25846 onAvailable: function(id, fn, p_obj, p_override, checkContent, compat) { 25847 25848 var a = Y.Array(id), i, availHandle; 25849 25850 for (i=0; i<a.length; i=i+1) { 25851 _avail.push({ 25852 id: a[i], 25853 fn: fn, 25854 obj: p_obj, 25855 override: p_override, 25856 checkReady: checkContent, 25857 compat: compat 25858 }); 25859 } 25860 _retryCount = this.POLL_RETRYS; 25861 25862 // We want the first test to be immediate, but async 25863 setTimeout(Event._poll, 0); 25864 25865 availHandle = new Y.EventHandle({ 25866 25867 _delete: function() { 25868 // set by the event system for lazy DOM listeners 25869 if (availHandle.handle) { 25870 availHandle.handle.detach(); 25871 return; 25872 } 25873 25874 var i, j; 25875 25876 // otherwise try to remove the onAvailable listener(s) 25877 for (i = 0; i < a.length; i++) { 25878 for (j = 0; j < _avail.length; j++) { 25879 if (a[i] === _avail[j].id) { 25880 _avail.splice(j, 1); 25881 } 25882 } 25883 } 25884 } 25885 25886 }); 25887 25888 return availHandle; 25889 }, 25890 25891 /** 25892 * Works the same way as onAvailable, but additionally checks the 25893 * state of sibling elements to determine if the content of the 25894 * available element is safe to modify. 25895 * 25896 * <p>The callback is executed with a single parameter:
25897 * the custom object parameter, if provided.</p> 25898 * 25899 * @method onContentReady 25900 * 25901 * @param {string} id the id of the element to look for. 25902 * @param {function} fn what to execute when the element is ready. 25903 * @param {object} obj an optional object to be passed back as 25904 * a parameter to fn. 25905 * @param {boolean|object} override If set to true, fn will execute 25906 * in the context of p_obj. If an object, fn will 25907 * exectute in the context of that object 25908 * 25909 * @static 25910 * @deprecated Use Y.on("contentready") 25911 */ 25912 // @TODO fix arguments 25913 onContentReady: function(id, fn, obj, override, compat) { 25914 return Event.onAvailable(id, fn, obj, override, true, compat); 25915 }, 25916 25917 /** 25918 * Adds an event listener 25919 * 25920 * @method attach 25921 * 25922 * @param {String} type The type of event to append 25923 * @param {Function} fn The method the event invokes 25924 * @param {String|HTMLElement|Array|NodeList} el An id, an element 25925 * reference, or a collection of ids and/or elements to assign the 25926 * listener to. 25927 * @param {Object} context optional context object 25928 * @param {Boolean|object} args 0..n arguments to pass to the callback 25929 * @return {EventHandle} an object to that can be used to detach the listener 25930 * 25931 * @static 25932 */ 25933 25934 attach: function(type, fn, el, context) { 25935 return Event._attach(Y.Array(arguments, 0, true)); 25936 }, 25937 25938 _createWrapper: function (el, type, capture, compat, facade) { 25939 25940 var cewrapper, 25941 ek = Y.stamp(el), 25942 key = 'event:' + ek + type; 25943 25944 if (false === facade) { 25945 key += 'native'; 25946 } 25947 if (capture) { 25948 key += 'capture'; 25949 } 25950 25951 25952 cewrapper = _wrappers[key]; 25953 25954 25955 if (!cewrapper) { 25956 // create CE wrapper 25957 cewrapper = Y.publish(key, { 25958 silent: true, 25959 bubbles: false, 25960 emitFacade:false, 25961 contextFn: function() { 25962 if (compat) { 25963 return cewrapper.el; 25964 } else { 25965 cewrapper.nodeRef = cewrapper.nodeRef || Y.one(cewrapper.el); 25966 return cewrapper.nodeRef; 25967 } 25968 } 25969 }); 25970 25971 cewrapper.overrides = {}; 25972 25973 // for later removeListener calls 25974 cewrapper.el = el; 25975 cewrapper.key = key; 25976 cewrapper.domkey = ek; 25977 cewrapper.type = type; 25978 cewrapper.fn = function(e) { 25979 cewrapper.fire(Event.getEvent(e, el, (compat || (false === facade)))); 25980 }; 25981 cewrapper.capture = capture; 25982 25983 if (el == win && type == "load") { 25984 // window load happens once 25985 cewrapper.fireOnce = true; 25986 _windowLoadKey = key; 25987 } 25988 cewrapper._delete = _deleteAndClean; 25989 25990 _wrappers[key] = cewrapper; 25991 _el_events[ek] = _el_events[ek] || {}; 25992 _el_events[ek][key] = cewrapper; 25993 25994 add(el, type, cewrapper.fn, capture); 25995 } 25996 25997 return cewrapper; 25998 25999 }, 26000 26001 _attach: function(args, conf) { 26002 26003 var compat, 26004 handles, oEl, cewrapper, context, 26005 fireNow = false, ret, 26006 type = args[0], 26007 fn = args[1], 26008 el = args[2] || win, 26009 facade = conf && conf.facade, 26010 capture = conf && conf.capture, 26011 overrides = conf && conf.overrides; 26012 26013 if (args[args.length-1] === COMPAT_ARG) { 26014 compat = true; 26015 } 26016 26017 if (!fn || !fn.call) { 26018 return false;
26019 } 26020 26021 // The el argument can be an array of elements or element ids. 26022 if (shouldIterate(el)) { 26023 26024 handles=[]; 26025 26026 Y.each(el, function(v, k) { 26027 args[2] = v; 26028 handles.push(Event._attach(args.slice(), conf)); 26029 }); 26030 26031 // return (handles.length === 1) ? handles[0] : handles; 26032 return new Y.EventHandle(handles); 26033 26034 // If the el argument is a string, we assume it is 26035 // actually the id of the element. If the page is loaded 26036 // we convert el to the actual element, otherwise we 26037 // defer attaching the event until the element is 26038 // ready 26039 } else if (Y.Lang.isString(el)) { 26040 26041 // oEl = (compat) ? Y.DOM.byId(el) : Y.Selector.query(el); 26042 26043 if (compat) { 26044 oEl = Y.DOM.byId(el); 26045 } else { 26046 26047 oEl = Y.Selector.query(el); 26048 26049 switch (oEl.length) { 26050 case 0: 26051 oEl = null; 26052 break; 26053 case 1: 26054 oEl = oEl[0]; 26055 break; 26056 default: 26057 args[2] = oEl; 26058 return Event._attach(args, conf); 26059 } 26060 } 26061 26062 if (oEl) { 26063 26064 el = oEl; 26065 26066 // Not found = defer adding the event until the element is available 26067 } else { 26068 26069 ret = Event.onAvailable(el, function() { 26070 26071 ret.handle = Event._attach(args, conf); 26072 26073 }, Event, true, false, compat); 26074 26075 return ret; 26076 26077 } 26078 } 26079 26080 // Element should be an html element or node 26081 if (!el) { 26082 return false; 26083 } 26084 26085 if (Y.Node && Y.instanceOf(el, Y.Node)) { 26086 el = Y.Node.getDOMNode(el); 26087 } 26088 26089 cewrapper = Event._createWrapper(el, type, capture, compat, facade); 26090 if (overrides) { 26091 Y.mix(cewrapper.overrides, overrides); 26092 } 26093 26094 if (el == win && type == "load") { 26095 26096 // if the load is complete, fire immediately. 26097 // all subscribers, including the current one 26098 // will be notified. 26099 if (YUI.Env.windowLoaded) { 26100 fireNow = true; 26101 } 26102 } 26103 26104 if (compat) { 26105 args.pop(); 26106 } 26107 26108 context = args[3]; 26109 26110 // set context to the Node if not specified 26111 // ret = cewrapper.on.apply(cewrapper, trimmedArgs); 26112 ret = cewrapper._on(fn, context, (args.length > 4) ? args.slice(4) : null); 26113 26114 if (fireNow) { 26115 cewrapper.fire(); 26116 } 26117 26118 return ret; 26119 26120 }, 26121 26122 /** 26123 * Removes an event listener. Supports the signature the event was bound 26124 * with, but the preferred way to remove listeners is using the handle 26125 * that is returned when using Y.on 26126 * 26127 * @method detach 26128 * 26129 * @param {String} type the type of event to remove. 26130 * @param {Function} fn the method the event invokes. If fn is 26131 * undefined, then all event handlers for the type of event are 26132 * removed. 26133 * @param {String|HTMLElement|Array|NodeList|EventHandle} el An 26134 * event handle, an id, an element reference, or a collection 26135 * of ids and/or elements to remove the listener from. 26136 * @return {boolean} true if the unbind was successful, false otherwise. 26137 * @static 26138 */ 26139 detach: function(type, fn, el, obj) { 26140 26141 var args=Y.Array(arguments, 0, true), compat, l, ok, i, 26142 id, ce; 26143 26144 if (args[args.length-1] === COMPAT_ARG) { 26145 compat = true; 26146 // args.pop(); 26147 } 26148 26149 if (type && type.detach) { 26150 return type.detach(); 26151 } 26152 26153 // The el argument can be a string 26154 if (typeof el == "string") { 26155 26156 // el = (compat) ? Y.DOM.byId(el) : Y.all(el); 26157 if (compat) { 26158 el = Y.DOM.byId(el); 26159 } else { 26160 el = Y.Selector.query(el); 26161 l = el.length; 26162 if (l < 1) { 26163 el = null; 26164 } else if (l == 1) { 26165 el = el[0]; 26166 } 26167 } 26168 // return Event.detach.apply(Event, args); 26169 } 26170 26171 if (!el) { 26172 return false;
26173 } 26174 26175 if (el.detach) { 26176 args.splice(2, 1); 26177 return el.detach.apply(el, args); 26178 // The el argument can be an array of elements or element ids. 26179 } else if (shouldIterate(el)) { 26180 ok = true; 26181 for (i=0, l=el.length; i<l; ++i) { 26182 args[2] = el[i]; 26183 ok = ( Y.Event.detach.apply(Y.Event, args) && ok ); 26184 } 26185 26186 return ok; 26187 } 26188 26189 if (!type || !fn || !fn.call) { 26190 return Event.purgeElement(el, false, type); 26191 } 26192 26193 id = 'event:' + Y.stamp(el) + type; 26194 ce = _wrappers[id]; 26195 26196 if (ce) { 26197 return ce.detach(fn); 26198 } else { 26199 return false; 26200 } 26201 26202 }, 26203 26204 /** 26205 * Finds the event in the window object, the caller's arguments, or 26206 * in the arguments of another method in the callstack. This is 26207 * executed automatically for events registered through the event 26208 * manager, so the implementer should not normally need to execute 26209 * this function at all. 26210 * @method getEvent 26211 * @param {Event} e the event parameter from the handler 26212 * @param {HTMLElement} el the element the listener was attached to 26213 * @return {Event} the event 26214 * @static 26215 */ 26216 getEvent: function(e, el, noFacade) { 26217 var ev = e || win.event; 26218 26219 return (noFacade) ? ev : 26220 new Y.DOMEventFacade(ev, el, _wrappers['event:' + Y.stamp(el) + e.type]); 26221 }, 26222 26223 /** 26224 * Generates an unique ID for the element if it does not already 26225 * have one. 26226 * @method generateId 26227 * @param el the element to create the id for 26228 * @return {string} the resulting id of the element 26229 * @static 26230 */ 26231 generateId: function(el) { 26232 return Y.DOM.generateID(el); 26233 }, 26234 26235 /** 26236 * We want to be able to use getElementsByTagName as a collection 26237 * to attach a group of events to. Unfortunately, different 26238 * browsers return different types of collections. This function 26239 * tests to determine if the object is array-like. It will also 26240 * fail if the object is an array, but is empty. 26241 * @method _isValidCollection 26242 * @param o the object to test 26243 * @return {boolean} true if the object is array-like and populated 26244 * @deprecated was not meant to be used directly 26245 * @static 26246 * @private 26247 */ 26248 _isValidCollection: shouldIterate, 26249 26250 /** 26251 * hook up any deferred listeners 26252 * @method _load 26253 * @static 26254 * @private 26255 */ 26256 _load: function(e) { 26257 if (!_loadComplete) { 26258 _loadComplete = true; 26259 26260 // Just in case DOMReady did not go off for some reason 26261 // E._ready(); 26262 if (Y.fire) { 26263 Y.fire(EVENT_READY); 26264 } 26265 26266 // Available elements may not have been detected before the 26267 // window load event fires. Try to find them now so that the 26268 // the user is more likely to get the onAvailable notifications 26269 // before the window load notification 26270 Event._poll(); 26271 } 26272 }, 26273 26274 /** 26275 * Polling function that runs before the onload event fires, 26276 * attempting to attach to DOM Nodes as soon as they are 26277 * available 26278 * @method _poll 26279 * @static 26280 * @private 26281 */ 26282 _poll: function() { 26283 if (Event.locked) { 26284 return; 26285 } 26286 26287 if (Y.UA.ie && !YUI.Env.DOMReady) { 26288 // Hold off if DOMReady has not fired and check current 26289 // readyState to protect against the IE operation aborted 26290 // issue. 26291 Event.startInterval(); 26292 return; 26293 } 26294 26295 Event.locked = true; 26296 26297 // keep trying until after the page is loaded. We need to 26298 // check the page load state prior to trying to bind the 26299 // elements so that we can be certain all elements have been 26300 // tested appropriately 26301 var i, len, item, el, notAvail, executeItem, 26302 tryAgain = !_loadComplete; 26303 26304 if (!tryAgain) { 26305 tryAgain = (_retryCount > 0); 26306 } 26307 26308 // onAvailable 26309 notAvail = []; 26310 26311 executeItem = function (el, item) { 26312 var context, ov = item.override; 26313 try { 26314 if (item.compat) { 26315 if (item.override) { 26316 if (ov === true) { 26317 context = item.obj; 26318 } else { 26319 context = ov; 26320 } 26321 } else { 26322 context = el; 26323 } 26324 item.fn.call(context, item.obj); 26325 } else { 26326 context = item.obj || Y.one(el); 26327 item.fn.apply(context, (Y.Lang.isArray(ov)) ? ov : []); 26328 } 26329 } catch (e) { 26330 } 26331 }; 26332 26333 // onAvailable 26334 for (i=0,len=_avail.length; i<len; ++i) { 26335 item = _avail[i]; 26336 if (item && !item.checkReady) { 26337 26338 // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id); 26339 el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true); 26340 26341 if (el) { 26342 executeItem(el, item); 26343 _avail[i] = null; 26344 } else { 26345 notAvail.push(item); 26346 } 26347 } 26348 } 26349 26350 // onContentReady 26351 for (i=0,len=_avail.length; i<len; ++i) { 26352 item = _avail[i]; 26353 if (item && item.checkReady) { 26354 26355 // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id); 26356 el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true); 26357 26358 if (el) { 26359 // The element is available, but not necessarily ready 26360 // @todo should we test parentNode.nextSibling? 26361 if (_loadComplete || (el.get && el.get('nextSibling')) || el.nextSibling) { 26362 executeItem(el, item); 26363 _avail[i] = null; 26364 } 26365 } else { 26366 notAvail.push(item); 26367 } 26368 } 26369 } 26370 26371 _retryCount = (notAvail.length === 0) ? 0 : _retryCount - 1; 26372 26373 if (tryAgain) { 26374 // we may need to strip the nulled out items here 26375 Event.startInterval(); 26376 } else { 26377 clearInterval(Event._interval); 26378 Event._interval = null; 26379 } 26380 26381 Event.locked = false;
26382 26383 return; 26384 26385 }, 26386 26387 /** 26388 * Removes all listeners attached to the given element via addListener. 26389 * Optionally, the node's children can also be purged. 26390 * Optionally, you can specify a specific type of event to remove. 26391 * @method purgeElement 26392 * @param {HTMLElement} el the element to purge 26393 * @param {boolean} recurse recursively purge this element's children 26394 * as well. Use with caution. 26395 * @param {string} type optional type of listener to purge. If 26396 * left out, all listeners will be removed 26397 * @static 26398 */ 26399 purgeElement: function(el, recurse, type) { 26400 // var oEl = (Y.Lang.isString(el)) ? Y.one(el) : el, 26401 var oEl = (Y.Lang.isString(el)) ? Y.Selector.query(el, null, true) : el, 26402 lis = Event.getListeners(oEl, type), i, len, children, child; 26403 26404 if (recurse && oEl) { 26405 lis = lis || []; 26406 children = Y.Selector.query('*', oEl); 26407 len = children.length; 26408 for (i = 0; i < len; ++i) { 26409 child = Event.getListeners(children[i], type); 26410 if (child) { 26411 lis = lis.concat(child); 26412 } 26413 } 26414 } 26415 26416 if (lis) { 26417 for (i = 0, len = lis.length; i < len; ++i) { 26418 lis[i].detachAll(); 26419 } 26420 } 26421 26422 }, 26423 26424 /** 26425 * Removes all object references and the DOM proxy subscription for 26426 * a given event for a DOM node. 26427 * 26428 * @method _clean 26429 * @param wrapper {CustomEvent} Custom event proxy for the DOM 26430 * subscription 26431 * @private 26432 * @static 26433 * @since 3.4.0 26434 */ 26435 _clean: function (wrapper) { 26436 var key = wrapper.key, 26437 domkey = wrapper.domkey; 26438 26439 remove(wrapper.el, wrapper.type, wrapper.fn, wrapper.capture); 26440 delete _wrappers[key]; 26441 delete Y._yuievt.events[key]; 26442 if (_el_events[domkey]) { 26443 delete _el_events[domkey][key]; 26444 if (!Y.Object.size(_el_events[domkey])) { 26445 delete _el_events[domkey]; 26446 } 26447 } 26448 }, 26449 26450 /** 26451 * Returns all listeners attached to the given element via addListener. 26452 * Optionally, you can specify a specific type of event to return. 26453 * @method getListeners 26454 * @param el {HTMLElement|string} the element or element id to inspect 26455 * @param type {string} optional type of listener to return. If 26456 * left out, all listeners will be returned 26457 * @return {CustomEvent} the custom event wrapper for the DOM event(s) 26458 * @static 26459 */ 26460 getListeners: function(el, type) { 26461 var ek = Y.stamp(el, true), evts = _el_events[ek], 26462 results=[] , key = (type) ? 'event:' + ek + type : null, 26463 adapters = _eventenv.plugins; 26464 26465 if (!evts) { 26466 return null; 26467 } 26468 26469 if (key) { 26470 // look for synthetic events 26471 if (adapters[type] && adapters[type].eventDef) { 26472 key += '_synth'; 26473 } 26474 26475 if (evts[key]) { 26476 results.push(evts[key]); 26477 } 26478 26479 // get native events as well 26480 key += 'native'; 26481 if (evts[key]) { 26482 results.push(evts[key]); 26483 } 26484 26485 } else { 26486 Y.each(evts, function(v, k) { 26487 results.push(v); 26488 }); 26489 } 26490 26491 return (results.length) ? results : null; 26492 }, 26493 26494 /** 26495 * Removes all listeners registered by pe.event. Called 26496 * automatically during the unload event. 26497 * @method _unload 26498 * @static 26499 * @private 26500 */ 26501 _unload: function(e) { 26502 Y.each(_wrappers, function(v, k) { 26503 if (v.type == 'unload') { 26504 v.fire(e); 26505 } 26506 v.detachAll(); 26507 }); 26508 remove(win, "unload", onUnload); 26509 }, 26510 26511 /** 26512 * Adds a DOM event directly without the caching, cleanup, context adj, etc 26513 *
26514 * @method nativeAdd 26515 * @param {HTMLElement} el the element to bind the handler to 26516 * @param {string} type the type of event handler 26517 * @param {function} fn the callback to invoke 26518 * @param {Boolean} capture capture or bubble phase 26519 * @static 26520 * @private 26521 */ 26522 nativeAdd: add, 26523 26524 /** 26525 * Basic remove listener 26526 * 26527 * @method nativeRemove 26528 * @param {HTMLElement} el the element to bind the handler to 26529 * @param {string} type the type of event handler 26530 * @param {function} fn the callback to invoke 26531 * @param {Boolean} capture capture or bubble phase 26532 * @static 26533 * @private 26534 */ 26535 nativeRemove: remove 26536 }; 26537 26538}(); 26539 26540Y.Event = Event; 26541 26542if (config.injected || YUI.Env.windowLoaded) { 26543 onLoad(); 26544} else { 26545 add(win, "load", onLoad); 26546} 26547 26548// Process onAvailable/onContentReady items when when the DOM is ready in IE 26549if (Y.UA.ie) { 26550 Y.on(EVENT_READY, Event._poll); 26551 26552 // In IE6 and below, detach event handlers when the page is unloaded in 26553 // order to try and prevent cross-page memory leaks. This isn't done in 26554 // other browsers because a) it's not necessary, and b) it breaks the 26555 // back/forward cache. 26556 if (Y.UA.ie < 7) { 26557 try { 26558 add(win, "unload", onUnload); 26559 } catch(e) { 26560 } 26561 } 26562} 26563 26564Event.Custom = Y.CustomEvent; 26565Event.Subscriber = Y.Subscriber; 26566Event.Target = Y.EventTarget; 26567Event.Handle = Y.EventHandle; 26568Event.Facade = Y.EventFacade; 26569 26570Event._poll(); 26571 26572}()); 26573 26574/** 26575 * DOM event listener abstraction layer 26576 * @module event 26577 * @submodule event-base 26578 */ 26579 26580/** 26581 * Executes the callback as soon as the specified element 26582 * is detected in the DOM. This function expects a selector 26583 * string for the element(s) to detect. If you already have 26584 * an element reference, you don't need this event. 26585 * @event available 26586 * @param type {string} 'available' 26587 * @param fn {function} the callback function to execute. 26588 * @param el {string} an selector for the element(s) to attach 26589 * @param context optional argument that specifies what 'this' refers to. 26590 * @param args* 0..n additional arguments to pass on to the callback function. 26591 * These arguments will be added after the event object. 26592 * @return {EventHandle} the detach handle 26593 * @for YUI 26594 */ 26595Y.Env.evt.plugins.available = { 26596 on: function(type, fn, id, o) { 26597 var a = arguments.length > 4 ? Y.Array(arguments, 4, true) : null; 26598 return Y.Event.onAvailable.call(Y.Event, id, fn, o, a); 26599 } 26600}; 26601 26602/** 26603 * Executes the callback as soon as the specified element 26604 * is detected in the DOM with a nextSibling property 26605 * (indicating that the element's children are available). 26606 * This function expects a selector 26607 * string for the element(s) to detect. If you already have 26608 * an element reference, you don't need this event. 26609 * @event contentready 26610 * @param type {string} 'contentready' 26611 * @param fn {function} the callback function to execute. 26612 * @param el {string} an selector for the element(s) to attach. 26613 * @param context optional argument that specifies what 'this' refers to. 26614 * @param args* 0..n additional arguments to pass on to the callback function. 26615 * These arguments will be added after the event object. 26616 * @return {EventHandle} the detach handle 26617 * @for YUI 26618 */ 26619Y.Env.evt.plugins.contentready = { 26620 on: function(type, fn, id, o) { 26621 var a = arguments.length > 4 ? Y.Array(arguments, 4, true) : null; 26622 return Y.Event.onContentReady.call(Y.Event, id, fn, o, a); 26623 } 26624}; 26625 26626 26627}, 'patched-v3.18.1', {"requires": ["event-custom-base"]}); 26628 26629YUI.add('event-delegate', function (Y, NAME) { 26630 26631/** 26632 * Adds event delegation support to the library. 26633 * 26634 * @module event 26635 * @submodule event-delegate 26636 */ 26637 26638var toArray = Y.Array, 26639 YLang = Y.Lang, 26640 isString = YLang.isString, 26641 isObject = YLang.isObject, 26642 isArray = YLang.isArray, 26643 selectorTest = Y.Selector.test, 26644 detachCategories = Y.Env.evt.handles; 26645 26646/** 26647 * <p>Sets up event delegation on a container element. The delegated event 26648 * will use a supplied selector or filtering function to test if the event 26649 * references at least one node that should trigger the subscription 26650 * callback.</p> 26651 * 26652 * <p>Selector string filters will trigger the callback if the event originated 26653 * from a node that matches it or is contained in a node that matches it. 26654 * Function filters are called for each Node up the parent axis to the 26655 * subscribing container node, and receive at each level the Node and the event 26656 * object. The function should return true (or a truthy value) if that Node 26657 * should trigger the subscription callback. Note, it is possible for filters 26658 * to match multiple Nodes for a single event. In this case, the delegate 26659 * callback will be executed for each matching Node.</p> 26660 * 26661 * <p>For each matching Node, the callback will be executed with its 'this' 26662 * object set to the Node matched by the filter (unless a specific context was 26663 * provided during subscription), and the provided event's 26664 * <code>currentTarget</code> will also be set to the matching Node. The 26665 * containing Node from which the subscription was originally made can be 26666 * referenced as <code>e.container</code>. 26667 * 26668 * @method delegate 26669 * @param type {String} the event type to delegate 26670 * @param fn {Function} the callback function to execute. This function 26671 * will be provided the event object for the delegated event. 26672 * @param el {String|node} the element that is the delegation container 26673 * @param filter {string|Function} a selector that must match the target of the 26674 * event or a function to test target and its parents for a match 26675 * @param context optional argument that specifies what 'this' refers to. 26676 * @param args* 0..n additional arguments to pass on to the callback function. 26677 * These arguments will be added after the event object. 26678 * @return {EventHandle} the detach handle 26679 * @static 26680 * @for Event 26681 */ 26682function delegate(type, fn, el, filter) { 26683 var args = toArray(arguments, 0, true), 26684 query = isString(el) ? el : null,
26685 typeBits, synth, container, categories, cat, i, len, handles, handle; 26686 26687 // Support Y.delegate({ click: fnA, key: fnB }, el, filter, ...); 26688 // and Y.delegate(['click', 'key'], fn, el, filter, ...); 26689 if (isObject(type)) { 26690 handles = []; 26691 26692 if (isArray(type)) { 26693 for (i = 0, len = type.length; i < len; ++i) { 26694 args[0] = type[i]; 26695 handles.push(Y.delegate.apply(Y, args)); 26696 } 26697 } else { 26698 // Y.delegate({'click', fn}, el, filter) => 26699 // Y.delegate('click', fn, el, filter) 26700 args.unshift(null); // one arg becomes two; need to make space 26701 26702 for (i in type) { 26703 if (type.hasOwnProperty(i)) { 26704 args[0] = i; 26705 args[1] = type[i]; 26706 handles.push(Y.delegate.apply(Y, args)); 26707 } 26708 } 26709 } 26710 26711 return new Y.EventHandle(handles); 26712 } 26713 26714 typeBits = type.split(/\|/); 26715 26716 if (typeBits.length > 1) { 26717 cat = typeBits.shift(); 26718 args[0] = type = typeBits.shift(); 26719 } 26720 26721 synth = Y.Node.DOM_EVENTS[type]; 26722 26723 if (isObject(synth) && synth.delegate) { 26724 handle = synth.delegate.apply(synth, arguments); 26725 } 26726 26727 if (!handle) { 26728 if (!type || !fn || !el || !filter) { 26729 return; 26730 } 26731 26732 container = (query) ? Y.Selector.query(query, null, true) : el; 26733 26734 if (!container && isString(el)) { 26735 handle = Y.on('available', function () { 26736 Y.mix(handle, Y.delegate.apply(Y, args), true); 26737 }, el); 26738 } 26739 26740 if (!handle && container) { 26741 args.splice(2, 2, container); // remove the filter 26742 26743 handle = Y.Event._attach(args, { facade: false }); 26744 handle.sub.filter = filter; 26745 handle.sub._notify = delegate.notifySub; 26746 } 26747 } 26748 26749 if (handle && cat) { 26750 categories = detachCategories[cat] || (detachCategories[cat] = {}); 26751 categories = categories[type] || (categories[type] = []); 26752 categories.push(handle); 26753 } 26754 26755 return handle; 26756} 26757
26758/** 26759Overrides the <code>_notify</code> method on the normal DOM subscription to 26760inject the filtering logic and only proceed in the case of a match. 26761 26762This method is hosted as a private property of the `delegate` method 26763(e.g. `Y.delegate.notifySub`) 26764 26765@method notifySub 26766@param thisObj {Object} default 'this' object for the callback 26767@param args {Array} arguments passed to the event's <code>fire()</code> 26768@param ce {CustomEvent} the custom event managing the DOM subscriptions for 26769 the subscribed event on the subscribing node. 26770@return {Boolean} false if the event was stopped 26771@private 26772@static 26773@since 3.2.0 26774**/ 26775delegate.notifySub = function (thisObj, args, ce) { 26776 // Preserve args for other subscribers 26777 args = args.slice(); 26778 if (this.args) { 26779 args.push.apply(args, this.args); 26780 } 26781 26782 // Only notify subs if the event occurred on a targeted element 26783 var currentTarget = delegate._applyFilter(this.filter, args, ce), 26784 //container = e.currentTarget, 26785 e, i, len, ret; 26786 26787 if (currentTarget) { 26788 // Support multiple matches up the the container subtree 26789 currentTarget = toArray(currentTarget); 26790 26791 // The second arg is the currentTarget, but we'll be reusing this 26792 // facade, replacing the currentTarget for each use, so it doesn't 26793 // matter what element we seed it with. 26794 e = args[0] = new Y.DOMEventFacade(args[0], ce.el, ce); 26795 26796 e.container = Y.one(ce.el); 26797 26798 for (i = 0, len = currentTarget.length; i < len && !e.stopped; ++i) { 26799 e.currentTarget = Y.one(currentTarget[i]); 26800 26801 ret = this.fn.apply(this.context || e.currentTarget, args); 26802 26803 if (ret === false) { // stop further notifications 26804 break; 26805 } 26806 } 26807 26808 return ret; 26809 } 26810}; 26811 26812/** 26813Compiles a selector string into a filter function to identify whether 26814Nodes along the parent axis of an event's target should trigger event 26815notification. 26816 26817This function is memoized, so previously compiled filter functions are 26818returned if the same selector string is provided. 26819 26820This function may be useful when defining synthetic events for delegate 26821handling. 26822 26823Hosted as a property of the `delegate` method (e.g. `Y.delegate.compileFilter`). 26824 26825@method compileFilter 26826@param selector {String} the selector string to base the filtration on 26827@return {Function} 26828@since 3.2.0 26829@static 26830**/ 26831delegate.compileFilter = Y.cached(function (selector) { 26832 return function (target, e) { 26833 return selectorTest(target._node, selector, 26834 (e.currentTarget === e.target) ? null : e.currentTarget._node); 26835 }; 26836}); 26837 26838/** 26839Regex to test for disabled elements during filtering. This is only relevant to 26840IE to normalize behavior with other browsers, which swallow events that occur 26841to disabled elements. IE fires the event from the parent element instead of the 26842original target, though it does preserve `event.srcElement` as the disabled 26843element. IE also supports disabled on `<a>`, but the event still bubbles, so it 26844acts more like `e.preventDefault()` plus styling. That issue is not handled here 26845because other browsers fire the event on the `<a>`, so delegate is supported in 26846both cases. 26847 26848@property _disabledRE 26849@type {RegExp} 26850@protected 26851@since 3.8.1 26852**/ 26853delegate._disabledRE = /^(?:button|input|select|textarea)$/i; 26854 26855/** 26856Walks up the parent axis of an event's target, and tests each element 26857against a supplied filter function. If any Nodes, including the container, 26858satisfy the filter, the delegated callback will be triggered for each. 26859 26860Hosted as a protected property of the `delegate` method (e.g. 26861`Y.delegate._applyFilter`). 26862 26863@method _applyFilter 26864@param filter {Function} boolean function to test for inclusion in event 26865 notification 26866@param args {Array} the arguments that would be passed to subscribers 26867@param ce {CustomEvent} the DOM event wrapper 26868@return {Node|Node[]|undefined} The Node or Nodes that satisfy the filter 26869@protected 26870**/ 26871delegate._applyFilter = function (filter, args, ce) { 26872 var e = args[0], 26873 container = ce.el, // facadeless events in IE, have no e.currentTarget 26874 target = e.target || e.srcElement, 26875 match = [], 26876 isContainer = false;
26877 26878 // Resolve text nodes to their containing element 26879 if (target.nodeType === 3) { 26880 target = target.parentNode; 26881 } 26882 26883 // For IE. IE propagates events from the parent element of disabled 26884 // elements, where other browsers swallow the event entirely. To normalize 26885 // this in IE, filtering for matching elements should abort if the target 26886 // is a disabled form control. 26887 if (target.disabled && delegate._disabledRE.test(target.nodeName)) { 26888 return match; 26889 } 26890 26891 // passing target as the first arg rather than leaving well enough alone 26892 // making 'this' in the filter function refer to the target. This is to 26893 // support bound filter functions. 26894 args.unshift(target); 26895 26896 if (isString(filter)) { 26897 while (target) { 26898 isContainer = (target === container); 26899 if (selectorTest(target, filter, (isContainer ? null: container))) { 26900 match.push(target); 26901 } 26902 26903 if (isContainer) { 26904 break; 26905 } 26906 26907 target = target.parentNode; 26908 } 26909 } else { 26910 // filter functions are implementer code and should receive wrappers 26911 args[0] = Y.one(target); 26912 args[1] = new Y.DOMEventFacade(e, container, ce); 26913 26914 while (target) { 26915 // filter(target, e, extra args...) - this === target 26916 if (filter.apply(args[0], args)) { 26917 match.push(target); 26918 } 26919 26920 if (target === container) { 26921 break; 26922 } 26923 26924 target = target.parentNode; 26925 args[0] = Y.one(target); 26926 } 26927 args[1] = e; // restore the raw DOM event 26928 } 26929 26930 if (match.length <= 1) { 26931 match = match[0]; // single match or undefined 26932 } 26933 26934 // remove the target 26935 args.shift(); 26936 26937 return match; 26938}; 26939 26940/** 26941 * Sets up event delegation on a container element. The delegated event 26942 * will use a supplied filter to test if the callback should be executed. 26943 * This filter can be either a selector string or a function that returns 26944 * a Node to use as the currentTarget for the event. 26945 * 26946 * The event object for the delegated event is supplied to the callback 26947 * function. It is modified slightly in order to support all properties 26948 * that may be needed for event delegation. 'currentTarget' is set to 26949 * the element that matched the selector string filter or the Node returned 26950 * from the filter function. 'container' is set to the element that the 26951 * listener is delegated from (this normally would be the 'currentTarget'). 26952 * 26953 * Filter functions will be called with the arguments that would be passed to 26954 * the callback function, including the event object as the first parameter. 26955 * The function should return false (or a falsey value) if the success criteria 26956 * aren't met, and the Node to use as the event's currentTarget and 'this' 26957 * object if they are. 26958 * 26959 * @method delegate 26960 * @param type {string} the event type to delegate 26961 * @param fn {function} the callback function to execute. This function 26962 * will be provided the event object for the delegated event. 26963 * @param el {string|node} the element that is the delegation container 26964 * @param filter {string|function} a selector that must match the target of the 26965 * event or a function that returns a Node or false. 26966 * @param context optional argument that specifies what 'this' refers to. 26967 * @param args* 0..n additional arguments to pass on to the callback function. 26968 * These arguments will be added after the event object. 26969 * @return {EventHandle} the detach handle 26970 * @for YUI 26971 */ 26972Y.delegate = Y.Event.delegate = delegate; 26973 26974 26975}, 'patched-v3.18.1', {"requires": ["node-base"]}); 26976 26977YUI.add('event-focus', function (Y, NAME) { 26978 26979/** 26980 * Adds bubbling and delegation support to DOM events focus and blur. 26981 * 26982 * @module event 26983 * @submodule event-focus 26984 */ 26985var Event = Y.Event, 26986 26987 YLang = Y.Lang, 26988 26989 isString = YLang.isString, 26990 26991 arrayIndex = Y.Array.indexOf, 26992 26993 useActivate = (function() { 26994 26995 // Changing the structure of this test, so that it doesn't use inline JS in HTML, 26996 // which throws an exception in Win8 packaged apps, due to additional security restrictions:
26997 // http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences 26998 26999 var supported = false, 27000 doc = Y.config.doc, 27001 p; 27002 27003 if (doc) { 27004 27005 p = doc.createElement("p"); 27006 p.setAttribute("onbeforeactivate", ";"); 27007 27008 // onbeforeactivate is a function in IE8+. 27009 // onbeforeactivate is a string in IE6,7 (unfortunate, otherwise we could have just checked for function below). 27010 // onbeforeactivate is a function in IE10, in a Win8 App environment (no exception running the test). 27011 27012 // onbeforeactivate is undefined in Webkit/Gecko. 27013 // onbeforeactivate is a function in Webkit/Gecko if it's a supported event (e.g. onclick). 27014 27015 supported = (p.onbeforeactivate !== undefined); 27016 } 27017 27018 return supported; 27019 }()); 27020 27021function define(type, proxy, directEvent) { 27022 var nodeDataKey = '_' + type + 'Notifiers'; 27023 27024 Y.Event.define(type, { 27025 27026 _useActivate : useActivate, 27027 27028 _attach: function (el, notifier, delegate) { 27029 if (Y.DOM.isWindow(el)) { 27030 return Event._attach([type, function (e) { 27031 notifier.fire(e); 27032 }, el]); 27033 } else { 27034 return Event._attach( 27035 [proxy, this._proxy, el, this, notifier, delegate], 27036 { capture: true }); 27037 } 27038 }, 27039 27040 _proxy: function (e, notifier, delegate) { 27041 var target = e.target, 27042 currentTarget = e.currentTarget, 27043 notifiers = target.getData(nodeDataKey), 27044 yuid = Y.stamp(currentTarget._node), 27045 defer = (useActivate || target !== currentTarget), 27046 directSub; 27047 27048 notifier.currentTarget = (delegate) ? target : currentTarget; 27049 notifier.container = (delegate) ? currentTarget : null; 27050 27051 // Maintain a list to handle subscriptions from nested 27052 // containers div#a>div#b>input #a.on(focus..) #b.on(focus..), 27053 // use one focus or blur subscription that fires notifiers from 27054 // #b then #a to emulate bubble sequence. 27055 if (!notifiers) { 27056 notifiers = {}; 27057 target.setData(nodeDataKey, notifiers); 27058 27059 // only subscribe to the element's focus if the target is 27060 // not the current target ( 27061 if (defer) { 27062 directSub = Event._attach( 27063 [directEvent, this._notify, target._node]).sub; 27064 directSub.once = true; 27065 } 27066 } else { 27067 // In old IE, defer is always true. In capture-phase browsers, 27068 // The delegate subscriptions will be encountered first, which 27069 // will establish the notifiers data and direct subscription 27070 // on the node. If there is also a direct subscription to the 27071 // node's focus/blur, it should not call _notify because the 27072 // direct subscription from the delegate sub(s) exists, which 27073 // will call _notify. So this avoids _notify being called 27074 // twice, unnecessarily. 27075 defer = true; 27076 } 27077 27078 if (!notifiers[yuid]) { 27079 notifiers[yuid] = []; 27080 } 27081 27082 notifiers[yuid].push(notifier); 27083 27084 if (!defer) { 27085 this._notify(e); 27086 } 27087 }, 27088 27089 _notify: function (e, container) { 27090 var currentTarget = e.currentTarget, 27091 notifierData = currentTarget.getData(nodeDataKey), 27092 axisNodes = currentTarget.ancestors(), 27093 doc = currentTarget.get('ownerDocument'), 27094 delegates = [], 27095 // Used to escape loops when there are no more 27096 // notifiers to consider 27097 count = notifierData ? 27098 Y.Object.keys(notifierData).length : 27099 0, 27100 target, notifiers, notifier, yuid, match, tmp, i, len, sub, ret; 27101 27102 // clear the notifications list (mainly for delegation) 27103 currentTarget.clearData(nodeDataKey); 27104 27105 // Order the delegate subs by their placement in the parent axis 27106 axisNodes.push(currentTarget); 27107 // document.get('ownerDocument') returns null 27108 // which we'll use to prevent having duplicate Nodes in the list 27109 if (doc) { 27110 axisNodes.unshift(doc); 27111 } 27112 27113 // ancestors() returns the Nodes from top to bottom 27114 axisNodes._nodes.reverse(); 27115 27116 if (count) { 27117 // Store the count for step 2 27118 tmp = count; 27119 axisNodes.some(function (node) { 27120 var yuid = Y.stamp(node), 27121 notifiers = notifierData[yuid], 27122 i, len; 27123 27124 if (notifiers) { 27125 count--; 27126 for (i = 0, len = notifiers.length; i < len; ++i) { 27127 if (notifiers[i].handle.sub.filter) { 27128 delegates.push(notifiers[i]); 27129 } 27130 } 27131 } 27132 27133 return !count; 27134 }); 27135 count = tmp; 27136 } 27137 27138 // Walk up the parent axis, notifying direct subscriptions and 27139 // testing delegate filters. 27140 while (count && (target = axisNodes.shift())) { 27141 yuid = Y.stamp(target); 27142 27143 notifiers = notifierData[yuid]; 27144 27145 if (notifiers) { 27146 for (i = 0, len = notifiers.length; i < len; ++i) { 27147 notifier = notifiers[i]; 27148 sub = notifier.handle.sub; 27149 match = true; 27150 27151 e.currentTarget = target; 27152 27153 if (sub.filter) { 27154 match = sub.filter.apply(target, 27155 [target, e].concat(sub.args || [])); 27156 27157 // No longer necessary to test against this 27158 // delegate subscription for the nodes along 27159 // the parent axis. 27160 delegates.splice( 27161 arrayIndex(delegates, notifier), 1); 27162 } 27163 27164 if (match) { 27165 // undefined for direct subs 27166 e.container = notifier.container; 27167 ret = notifier.fire(e); 27168 } 27169 27170 if (ret === false || e.stopped === 2) { 27171 break; 27172 } 27173 } 27174 27175 delete notifiers[yuid]; 27176 count--; 27177 } 27178 27179 if (e.stopped !== 2) { 27180 // delegates come after subs targeting this specific node 27181 // because they would not normally report until they'd 27182 // bubbled to the container node. 27183 for (i = 0, len = delegates.length; i < len; ++i) { 27184 notifier = delegates[i]; 27185 sub = notifier.handle.sub; 27186 27187 if (sub.filter.apply(target, 27188 [target, e].concat(sub.args || []))) { 27189 27190 e.container = notifier.container; 27191 e.currentTarget = target; 27192 ret = notifier.fire(e); 27193 } 27194 27195 if (ret === false || e.stopped === 2 || 27196 // If e.stopPropagation() is called, notify any 27197 // delegate subs from the same container, but break 27198 // once the container changes. This emulates 27199 // delegate() behavior for events like 'click' which 27200 // won't notify delegates higher up the parent axis. 27201 (e.stopped && delegates[i+1] && 27202 delegates[i+1].container !== notifier.container)) { 27203 break; 27204 } 27205 } 27206 } 27207 27208 if (e.stopped) { 27209 break; 27210 } 27211 } 27212 }, 27213 27214 on: function (node, sub, notifier) { 27215 sub.handle = this._attach(node._node, notifier); 27216 }, 27217 27218 detach: function (node, sub) { 27219 sub.handle.detach(); 27220 }, 27221 27222 delegate: function (node, sub, notifier, filter) { 27223 if (isString(filter)) { 27224 sub.filter = function (target) { 27225 return Y.Selector.test(target._node, filter, 27226 node === target ? null : node._node); 27227 }; 27228 } 27229 27230 sub.handle = this._attach(node._node, notifier, true); 27231 }, 27232 27233 detachDelegate: function (node, sub) { 27234 sub.handle.detach(); 27235 } 27236 }, true); 27237} 27238 27239// For IE, we need to defer to focusin rather than focus because 27240// `el.focus(); doSomething();` executes el.onbeforeactivate, el.onactivate, 27241// el.onfocusin, doSomething, then el.onfocus. All others support capture 27242// phase focus, which executes before doSomething. To guarantee consistent 27243// behavior for this use case, IE's direct subscriptions are made against 27244// focusin so subscribers will be notified before js following el.focus() is 27245// executed. 27246if (useActivate) { 27247 // name capture phase direct subscription 27248 define("focus", "beforeactivate", "focusin");
27249 define("blur", "beforedeactivate", "focusout"); 27250} else { 27251 define("focus", "focus", "focus"); 27252 define("blur", "blur", "blur"); 27253} 27254 27255 27256}, 'patched-v3.18.1', {"requires": ["event-synthetic"]}); 27257 27258YUI.add('event-hover', function (Y, NAME) { 27259 27260/** 27261 * Adds support for a "hover" event. The event provides a convenience wrapper 27262 * for subscribing separately to mouseenter and mouseleave. The signature for 27263 * subscribing to the event is</p> 27264 * 27265 * <pre><code>node.on("hover", overFn, outFn); 27266 * node.delegate("hover", overFn, outFn, ".filterSelector"); 27267 * Y.on("hover", overFn, outFn, ".targetSelector"); 27268 * Y.delegate("hover", overFn, outFn, "#container", ".filterSelector"); 27269 * </code></pre> 27270 * 27271 * <p>Additionally, for compatibility with a more typical subscription 27272 * signature, the following are also supported:</p> 27273 * 27274 * <pre><code>Y.on("hover", overFn, ".targetSelector", outFn); 27275 * Y.delegate("hover", overFn, "#container", outFn, ".filterSelector"); 27276 * </code></pre> 27277 * 27278 * @module event 27279 * @submodule event-hover 27280 */ 27281var isFunction = Y.Lang.isFunction, 27282 noop = function () {}, 27283 conf = { 27284 processArgs: function (args) { 27285 // Y.delegate('hover', over, out, '#container', '.filter') 27286 // comes in as ['hover', over, out, '#container', '.filter'], but 27287 // node.delegate('hover', over, out, '.filter') 27288 // comes in as ['hover', over, containerEl, out, '.filter'] 27289 var i = isFunction(args[2]) ? 2 : 3; 27290 27291 return (isFunction(args[i])) ? args.splice(i,1)[0] : noop; 27292 }, 27293 27294 on: function (node, sub, notifier, filter) { 27295 var args = (sub.args) ? sub.args.slice() : []; 27296 27297 args.unshift(null); 27298 27299 sub._detach = node[(filter) ? "delegate" : "on"]({ 27300 mouseenter: function (e) { 27301 e.phase = 'over'; 27302 notifier.fire(e); 27303 }, 27304 mouseleave: function (e) { 27305 var thisObj = sub.context || this; 27306 27307 args[0] = e; 27308 27309 e.type = 'hover'; 27310 e.phase = 'out'; 27311 sub._extra.apply(thisObj, args); 27312 } 27313 }, filter); 27314 }, 27315 27316 detach: function (node, sub, notifier) { 27317 sub._detach.detach(); 27318 } 27319 }; 27320 27321conf.delegate = conf.on; 27322conf.detachDelegate = conf.detach; 27323 27324Y.Event.define("hover", conf); 27325 27326 27327}, 'patched-v3.18.1', {"requires": ["event-mouseenter"]}); 27328 27329YUI.add('event-key', function (Y, NAME) { 27330 27331/** 27332 * Functionality to listen for one or more specific key combinations. 27333 * @module event 27334 * @submodule event-key 27335 */ 27336 27337var ALT = "+alt", 27338 CTRL = "+ctrl", 27339 META = "+meta", 27340 SHIFT = "+shift", 27341 27342 trim = Y.Lang.trim, 27343 27344 eventDef = { 27345 KEY_MAP: { 27346 enter : 13, 27347 space : 32, 27348 esc : 27, 27349 backspace: 8, 27350 tab : 9, 27351 pageup : 33, 27352 pagedown : 34 27353 }, 27354 27355 _typeRE: /^(up|down|press):/, 27356 _keysRE: /^(?:up|down|press):|\+(alt|ctrl|meta|shift)/g, 27357 27358 processArgs: function (args) { 27359 var spec = args.splice(3,1)[0], 27360 mods = Y.Array.hash(spec.match(/\+(?:alt|ctrl|meta|shift)\b/g) || []), 27361 config = { 27362 type: this._typeRE.test(spec) ? RegExp.$1 : null, 27363 mods: mods, 27364 keys: null 27365 }, 27366 // strip type and modifiers from spec, leaving only keyCodes 27367 bits = spec.replace(this._keysRE, ''), 27368 chr, uc, lc, i; 27369 27370 if (bits) { 27371 bits = bits.split(','); 27372 27373 config.keys = {}; 27374 27375 // FIXME: need to support '65,esc' => keypress, keydown 27376 for (i = bits.length - 1; i >= 0; --i) { 27377 chr = trim(bits[i]); 27378 27379 // catch sloppy filters, trailing commas, etc 'a,,' 27380 if (!chr) { 27381 continue; 27382 } 27383 27384 // non-numerics are single characters or key names 27385 if (+chr == chr) { 27386 config.keys[chr] = mods; 27387 } else { 27388 lc = chr.toLowerCase(); 27389 27390 if (this.KEY_MAP[lc]) { 27391 config.keys[this.KEY_MAP[lc]] = mods; 27392 // FIXME: '65,enter' defaults keydown for both 27393 if (!config.type) { 27394 config.type = "down"; // safest 27395 } 27396 } else { 27397 // FIXME: Character mapping only works for keypress 27398 // events. Otherwise, it uses String.fromCharCode() 27399 // from the keyCode, which is wrong. 27400 chr = chr.charAt(0); 27401 uc = chr.toUpperCase(); 27402 27403 if (mods["+shift"]) { 27404 chr = uc; 27405 } 27406 27407 // FIXME: stupid assumption that 27408 // the keycode of the lower case == the 27409 // charCode of the upper case 27410 // a (key:65,char:97), A (key:65,char:65) 27411 config.keys[chr.charCodeAt(0)] = 27412 (chr === uc) ? 27413 // upper case chars get +shift free 27414 Y.merge(mods, { "+shift": true }) : 27415 mods; 27416 } 27417 } 27418 } 27419 } 27420 27421 if (!config.type) { 27422 config.type = "press"; 27423 } 27424 27425 return config; 27426 }, 27427 27428 on: function (node, sub, notifier, filter) { 27429 var spec = sub._extra, 27430 type = "key" + spec.type, 27431 keys = spec.keys, 27432 method = (filter) ? "delegate" : "on"; 27433 27434 // Note: without specifying any keyCodes, this becomes a 27435 // horribly inefficient alias for 'keydown' (et al), but I 27436 // can't abort this subscription for a simple 27437 // Y.on('keypress', ...); 27438 // Please use keyCodes or just subscribe directly to keydown, 27439 // keyup, or keypress 27440 sub._detach = node[method](type, function (e) { 27441 var key = keys ? keys[e.which] : spec.mods; 27442 27443 if (key && 27444 (!key[ALT] || (key[ALT] && e.altKey)) && 27445 (!key[CTRL] || (key[CTRL] && e.ctrlKey)) && 27446 (!key[META] || (key[META] && e.metaKey)) && 27447 (!key[SHIFT] || (key[SHIFT] && e.shiftKey))) 27448 { 27449 notifier.fire(e); 27450 } 27451 }, filter); 27452 }, 27453 27454 detach: function (node, sub, notifier) { 27455 sub._detach.detach(); 27456 } 27457 }; 27458 27459eventDef.delegate = eventDef.on; 27460eventDef.detachDelegate = eventDef.detach; 27461 27462/** 27463 * <p>Add a key listener. The listener will only be notified if the 27464 * keystroke detected meets the supplied specification. The 27465 * specification is a string that is defined as:</p> 27466 * 27467 * <dl> 27468 * <dt>spec</dt> 27469 * <dd><code>[{type}:]{code}[,{code}]*</code></dd> 27470 * <dt>type</dt> 27471 * <dd><code>"down", "up", or "press"</code></dd> 27472 * <dt>code</dt> 27473 * <dd><code>{keyCode|character|keyName}[+{modifier}]*</code></dd> 27474 * <dt>modifier</dt> 27475 * <dd><code>"shift", "ctrl", "alt", or "meta"</code></dd> 27476 * <dt>keyName</dt> 27477 * <dd><code>"enter", "space", "backspace", "esc", "tab", "pageup", or "pagedown"</code></dd> 27478 * </dl> 27479 * 27480 * <p>Examples:</p> 27481 * <ul> 27482 * <li><code>Y.on("key", callback, "press:12,65+shift+ctrl", "#my-input");</code></li> 27483 * <li><code>Y.delegate("key", preventSubmit, "#forms", "enter", "input[type=text]");</code></li> 27484 * <li><code>Y.one("doc").on("key", viNav, "j,k,l,;");</code></li> 27485 * </ul> 27486 * 27487 * @event key 27488 * @for YUI 27489 * @param type {string} 'key' 27490 * @param fn {function} the function to execute 27491 * @param id {string|HTMLElement|collection}
27491 the element(s) to bind 27492 * @param spec {string} the keyCode and modifier specification 27493 * @param o optional context object 27494 * @param args 0..n additional arguments to provide to the listener. 27495 * @return {Event.Handle} the detach handle 27496 */ 27497Y.Event.define('key', eventDef, true); 27498 27499 27500}, 'patched-v3.18.1', {"requires": ["event-synthetic"]}); 27501
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.