1/** 2 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or modify it under 5 * the terms of the GNU Lesser General Public License as published by the Free 6 * Software Foundation; either version 2.1 of the License, or (at your option) 7 * any later version. 8 * 9 * This library is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 * details. 13 */ 14(function () { 15 var LiferayAUI = Liferay.AUI; 16 var combine = LiferayAUI.getCombine(); 17 window.__CONFIG__ = { 18 basePath: '', 19 combine: combine, 20 reportMismatchedAnonymousModules: 'warn', 21 url: combine ? LiferayAUI.getComboPath() : Liferay.ThemeDisplay.getCDNBaseURL() 22 }; 23 24 if (!combine) { 25 __CONFIG__.defaultURLParams = { 26 languageId: themeDisplay.getLanguageId() 27 }; 28 } 29 30 __CONFIG__.maps = Liferay.MAPS; 31 __CONFIG__.modules = Liferay.MODULES; 32 __CONFIG__.paths = Liferay.PATHS;
33 __CONFIG__.resolvePath = Liferay.RESOLVE_PATH; 34 __CONFIG__.namespace = 'Liferay'; 35 __CONFIG__.explainResolutions = Liferay.EXPLAIN_RESOLUTIONS; 36 __CONFIG__.exposeGlobal = Liferay.EXPOSE_GLOBAL; 37 __CONFIG__.logLevel = Liferay.LOG_LEVEL; 38 __CONFIG__.waitTimeout = Liferay.WAIT_TIMEOUT; 39})(); 40//# sourceMappingURL=config.js.map 41!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();var o=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=t}return r(e,[{key:"build",value:function(e){var t=this,n=this._config,r=[],o=[],i=[],a=n.basePath;return a.length&&"/"!==a.charAt(a.length-1)&&(a+="/"),e.forEach(function(e){var l=n.getModule(e),u=t._getModulePath(l);n.combine?(r.push(u),o.push(l.name)):i.push({modules:[l.name],url:t._getURLWithParams(n.url+a+u)})}),r.length&&(i=i.concat(this._generateBufferURLs(o,r,{basePath:a,url:n.url,urlMaxLength:n.urlMaxLength})),r.length=0),i}},{key:"_generateBufferURLs",value:function(e,t,n){for(var r=n.basePath,o=[],i=n.urlMaxLength,a={modules:[e[0]],url:n.url+r+t[0]},l=1;l<t.length;l++){var u=e[l],s=t[l];a.url.length+r.length+s.length+1<i?(a.modules.push(u),a.url+="&"+r+s):(o.push(a),a={modules:[u],url:n.url+r+s})}return a.url=this._getURLWithParams(a.url),o.push(a),o}},{key:"_getModulePath",value:function(e){var t=this._config.paths,n=e.name;return Object.keys(t).forEach(function(e){n!==e&&0!==n.indexOf(e+"/")||(n=t[e]+n.substring(e.length))}),n.lastIndexOf(".js")!==n.length-3&&(n+=".js"),n}},{key:"_getURLWithParams",value:function(e){var t=this._config.defaultURLParams||{},n=Object.keys(t);if(!n.length)return e;var r=n.map(function(e){return e+"="+t[e]}).join("&");return e+(e.indexOf("?")>-1?"&":"?")+r}}]),e}();t.default=o},function(e,t,n){"use strict";var r,o=n(2),i=(r=o)&&r.__esModule?r:{default:r};var a=window.__CONFIG__||{},l="string"==typeof a.namespace?a.namespace:void 0,u=void 0===a.exposeGlobal||a.exposeGlobal,s=new i.default(a);if(l){var c=window[l]?window[l]:{};c.Loader=s,window[l]=c}else window.Loader=s;u&&(window.Loader=s,window.require=i.default.prototype.require.bind(s),window.define=i.default.prototype.define.bind(s),window.define.amd={})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=c(n(3)),i=c(n(6)),a=c(n(7)),l=c(n(0)),u=c(n(8)),s=c(n(9));function c(e){return e&&e.__esModule?e:{default:e}}function f(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var d=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=new o.default(t||window.__CONFIG__),this._log=new u.default(this._config),this._dependencyResolver=new i.default(this._config),this._urlBuilder=new l.default(this._config),this._scriptLoader=new a.default(n||window.document,this._config,this._log),this._requireCallId=0}return r(e,[{key:"version",value:function(){return s.default.version}},{key:"define",value:function(){for(var e=this._config,t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];var o=n[0],i=e.getModule(o);if(i&&i.defined)this._log.warn("Module '"+o+"' is being redefined. Only the first","definition will be used");else{var a=n[1],l=n[2];if(2==n.length&&(l=a,a=["require","exports","module"]),"function"!=typeof l){var u=l;l=function(){return u}}if(!(i=e.getModule(o)))throw new Error("Trying to define a module that was not registered: "+o+"\nThis usually means that someone is calling define() for a module that has not been previously required.");
41if(i.defined)throw new Error("Trying to define a module more than once: "+o+"\nThis usually means that someone is calling define() more than once for the same module, which can lead to unexpected results.");this._log.resolution("Defining",i.name),i.factory=l,i.dependencies=a,i.define.resolve(n)}}},{key:"require",value:function(){for(var e=this,t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];var o=this._scriptLoader,i=this._config,a=this._requireCallId++,l=void 0,u=void 0,s=void 0;if(1==n.length)l=n[0],u=void 0,s=void 0;else if(2==n.length){var c=n[n.length-1];"function"==typeof c?(l=n[0],u=c,s=void 0):null==c?(l=n[0],u=void 0,s=void 0):(l=n,u=void 0,s=void 0)}else{var d=n[n.length-1],h=!1;if("function"!=typeof d&&null!=d||(h=!0),h){var p=n[n.length-2],m=!1;"function"!=typeof p&&null!=p||(m=!0),m?(l=n.slice(0,n.length-2),u=p,s=d):(l=n.slice(0,n.length-1),u=d,s=void 0)}else l=n,u=void 0,s=void 0}if("string"==typeof l)l=[l];else if(1==l.length&&Array.isArray(l[0])){var v;l=(v=[]).concat.apply(v,f(l))}if(void 0===u&&(u=function(){}),void 0===s){var g=new Error("");s=function(t){var n="(n/a)";g.stack&&(n="\n"+(n=g.stack.split("\n").map(function(e){return" "+e}).join("\n"))),e._log.error("\n","A require() call has failed but no failure handler was","provided.\n","Note that even if the call stack of this error trace","looks like coming from the Liferay AMD Loader, it is not","an error in the Loader what has caused it, but an error","caused by the require() call.\n","The reason why the Loader is in the stack trace is","because it is printing the error so that it doesn't get","lost.\n","However, we recommend providing a failure handler in all","require() calls to be able to recover from errors better","and to avoid the appearance of this message.\n","\n","Some information about the require() call follows:\n"," · Require call id:",a,"\n"," · Required modules:",l,"\n"," · Missing modules:",t.missingModules?t.missingModules:"(n/a)","\n"," · Stack trace of the require() call:",""+n,"\n",t)}}u=this._interceptHandler(u,"success",a),s=this._interceptHandler(s,"failure",a);var y=void 0,_=void 0,b=void 0,w=!1;this._dependencyResolver.resolve(l).then(function(t){return e._log.resolution("Require call",a,"resolved modules",l,"to",t),e._throwOnResolutionErrors(t),i.addMappings(t.configMap),i.addPaths(t.pathMap),y=t.resolvedModules,(_=e._getUnregisteredModuleNames(y)).forEach(function(e){var n={map:t.moduleMap[e]},r=t.moduleFlags?t.moduleFlags[e]:{};(r=r||{}).esModule&&(n.esModule=!0),i.addModule(e,n)}),b=e._setRejectTimeout(l,t,function(){w=!0,s.apply(void 0,arguments)}),e._log.resolution("Fetching",_,"from require call",a),o.loadModules(_)}).then(function(){if(!w)return e._waitForModuleDefinitions(y)}).then(function(){if(!w){clearTimeout(b),e._setModuleImplementations(a,y);var t=e._getModuleImplementations(l);u.apply(void 0,f(t))}}).catch(function(e){w||(b&&clearTimeout(b),s(e))})}},{key:"_interceptHandler",value:function(e,t,n){var r=this;return function(){r._log.resolution("Invoking",t,"handler for","require call",n);try{e.apply(void 0,arguments)}catch(e){r._log.error("\n","A require() call",t,"handler has thrown an error.\n","Note that even if the call stack of this error trace","looks like coming from the Liferay AMD Loader, it is not","an error in the Loader what has caused it, but an error","in the handler's code.\n","The reason why the Loader is in the stack trace is","because it is printing the error on behalf of the handler","so that it doesn't get lost.\n","However, we recommend wrapping all handler code inside a","try/catch to be able to recover from errors better and to","avoid the appearance of this message.\n","\n",e)}}}},{key:"_throwOnResolutionErrors",value:function(e){var t=e.resolvedModules.filter(function(e){return 0===e.indexOf(":ERROR:")}).map(function(e){return e.substr(7)});if(t.length>0)throw Object.assign(new Error("The following problems where detected while resolving modules:\n"+t.map(function(e){return" · "+e}).join("\n")),{resolutionErrors:t})}},{key:"_getUnregisteredModuleNames",value:function(e){var t=this._config;return e.filter(function(e){return!t.getModule(e)})}},{key:"_setRejectTimeout",value:function(e,t,n){var r=this._config;if(0!==r.waitTimeout)return setTimeout(function(){var o=t.resolvedModules.filter(function(e){var t=r.getModule(e);return!t||!t.implemented}),i=Object.assign(new Error("Load timeout for modules: "+e),{modules:e,resolution:t,missingModules:o});n(i)},r.waitTimeout)}},{key:"_waitForModuleDefinitions",value:function(e){var t=this._config;return Promise.all(t.getModules(e).map(function(e){return e.define}))}},{key:"_waitForModuleImplementations",value:function(e){var t=this._config;return Promise.all(t.getModules(e).map(function(e){return e.implement}))}},{key:"_setModuleImplementations",value:function(e,t){var n=this,r=this._config;r.getModules(t).forEach(function(t){if(!t.implemented){if(t.implement.rejected)throw t.implement.rejection;n._log.resolution("Implementing",t.name,"from require call",e);try{var o={get exports(){return t.implementation},set exports(e){t.implementation=e}},i=t.dependencies.map(function(e){if("exports"===e)return o.exports;if("module"===e)return o;if("require"===e)return n._createLocalRequire(t);var i=r.getDependency(t.name,e);if(!i)throw new Error("Unsatisfied dependency: "+e+" found in module "+t.name);if(!i.implementation&&!i.implemented)throw new Error('Module "'+i.name+'" has not been loaded yet for context: '+t.name);return i.implementation}),a=t.factory.apply(t,f(i));void 0!==a&&(t.implementation=a),t.implement.resolve(t.implementation)}catch(e){throw t.implement.fulfilled||t.implement.reject(e),e}}})}},{key:"_createLocalRequire",value:function(e){var t=this,n=this._config,r=function(r){for(var o=arguments.length,i=Array(o>1?o-1:0),a=1;a<o;a++)i[a-1]=arguments[a];if(i.length>0)return t.require.apply(t,[r].concat(i));var l=n.getDependency(e.name,r);
41if(!(l&&"implementation"in l))throw new Error('Module "'+r+'" has not been loaded yet for context: '+e.name);return l.implementation};return r.toUrl=function(e){return t._urlBuilder.build([e])[0].url},r}},{key:"_getModuleImplementations",value:function(e){return this._config.getModules(e).map(function(e){return e.implementation})}}]),e}();t.default=d,d.prototype.define.amd={}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,o=!1,i=void 0;try{for(var a,l=e[Symbol.iterator]();!(r=(a=l.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{!r&&l.return&&l.return()}finally{if(o)throw i}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),l=n(4),u=(r=l)&&r.__esModule?r:{default:r};var s=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._modules={},this._maps={},this._paths={},this._config={maps:{},paths:{}},this._parse(t,"defaultURLParams",{}),this._parse(t,"explainResolutions",!1),this._parse(t,"showWarnings",!1),this._parse(t,"waitTimeout",7e3),this._parse(t,"basePath","/"),this._parse(t,"resolvePath","/o/js_resolve_modules"),this._parse(t,"combine",!1),this._parse(t,"url",""),this._parse(t,"urlMaxLength",2e3),this._parse(t,"logLevel","error")}return a(e,[{key:"addModule",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this._modules[e])throw new Error("Module is already registered: "+e);var n=new u.default(e);return Object.entries(t).forEach(function(e){var t=i(e,2),r=t[0],o=t[1];n[r]=o}),this._modules[e]=n,n}},{key:"addMappings",value:function(e){Object.assign(this._maps,e)}},{key:"addPaths",value:function(e){Object.assign(this._paths,e)}},{key:"getModules",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0;return void 0===t?Object.values(this._modules):t.map(function(t){return e.getModule(t)})}},{key:"getModule",value:function(e){var t=this._modules[e];if(!t){var n=this._mapModule(e);t=this._modules[n]}return t}},{key:"getDependency",value:function(e,t){var n=this.getModule(e),r=this._modules[t];if(!r){var o=this._mapModule(t,n.map);r=this._modules[o]}return r}},{key:"_parse",value:function(e,t,n){this._config[t]=e.hasOwnProperty(t)?e[t]:n}},{key:"_mapModule",value:function(e,t){return t&&(e=this._mapMatches(e,t)),Object.keys(this._maps).length>0&&(e=this._mapMatches(e,this._maps)),e}},{key:"_mapMatches",value:function(e,t){var n=t[e];return n?"object"===(void 0===n?"undefined":o(n))?n.value:n:((n=this._mapExactMatch(e,t))||(n=this._mapPartialMatch(e,t)),n||(n=this._mapWildcardMatch(e,t)),n||e)}},{key:"_mapExactMatch",value:function(e,t){for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){var r=t[n];if(r.value&&r.exactMatch&&e===n)return r.value}}},{key:"_mapPartialMatch",value:function(e,t){for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n)){var r=t[n];if(!r.exactMatch&&(r.value&&(r=r.value),e===n||0===e.indexOf(n+"/")))return r+e.substring(n.length)}}},{key:"_mapWildcardMatch",value:function(e,t){if("function"==typeof t["*"])return t["*"](e)}},{key:"explainResolutions",get:function(){return this._config.explainResolutions}},{key:"showWarnings",get:function(){return this._config.showWarnings}},{key:"waitTimeout",get:function(){return this._config.waitTimeout}},{key:"basePath",get:function(){return this._config.basePath}},{key:"resolvePath",get:function(){return this._config.resolvePath}},{key:"combine",get:function(){return this._config.combine}},{key:"url",get:function(){return this._config.url}},{key:"urlMaxLength",get:function(){return this._config.urlMaxLength}},{key:"logLevel",get:function(){return this._config.logLevel}},{key:"defaultURLParams",get:function(){return this._config.defaultURLParams}},{key:"paths",get:function(){return this._paths}}]),e}();t.default=s},function(e,t,n){"use strict";
41Object.defineProperty(t,"__esModule",{value:!0});var r,o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(5),a=(r=i)&&r.__esModule?r:{default:r};var l=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._name=t,this._dependencies=void 0,this._factory=void 0,this._implementation={},this._map=void 0,this._state={_fetch:a.default.new(),_define:a.default.new(),_implement:a.default.new()}}return o(e,[{key:"name",get:function(){return this._name},set:function(e){throw new Error("Name of module "+this.name+" is read-only")}},{key:"dependencies",get:function(){return this._dependencies},set:function(e){if(this._dependencies)throw new Error("Dependencies of module "+this.name+" already set");this._dependencies=e}},{key:"factory",get:function(){return this._factory},set:function(e){if(this._factory)throw new Error("Factory of module "+this.name+" already set");this._factory=e}},{key:"implementation",get:function(){return this._implementation},set:function(e){this._implementation=e}},{key:"map",get:function(){return this._map},set:function(e){if(this._map)throw new Error("Local module map of module "+this.name+" already set");this._map=e}},{key:"esModule",get:function(){return this._implementation.__esModule},set:function(e){Object.defineProperty(this._implementation,"__esModule",{configurable:!0,value:e,writable:!0})}},{key:"fetch",get:function(){return this._state._fetch}},{key:"fetched",get:function(){return this.fetch.resolved}},{key:"define",get:function(){return this._state._define}},{key:"defined",get:function(){return this.define.resolved}},{key:"implement",get:function(){return this._state._implement}},{key:"implemented",get:function(){return this.implement.resolved}}]),e}();t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function e(){throw function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),new Error("Don't construct ResolvablePromise objects directly: rely on ResolvablePromise.new() instead")};function o(e){if(e.fulfilled)throw new Error("Promise already fulfilled")}t.default=r,r.new=function(){var e={},t=new Promise(function(t,n){e._resolve=t,e._reject=n});return Object.assign(t,e,{fulfilled:!1,resolved:!1,rejected:!1,resolution:void 0,rejection:void 0}),t.resolve=function(e){return function(e,t){o(e),e.fulfilled=!0,e.resolved=!0,e.resolution=t,e._resolve(t)}(t,e)},t.reject=function(e){return function(e,t){o(e),e.fulfilled=!0,e.rejected=!0,e.rejection=t,e._reject(t)}(t,e)},"undefined"!=typeof jest&&t.catch(function(){}),t}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();var o=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=t,this._cachedResolutions={}}return r(e,[{key:"resolve",value:function(e){var t=this;if(void 0===e||0==e.length)throw new Error("Argument 'modules' cannot be undefined or empty");var n=this._config;return new Promise(function(r,o){var i=t._cachedResolutions[e];if(i)r(i);else{var a="modules="+encodeURIComponent(e),l=n.resolvePath+"?"+a,u={};l.length>n.urlMaxLength&&(l=n.resolvePath,u={method:"POST",body:a}),fetch(l,u).then(function(e){return e.text()}).then(function(n){var o=JSON.parse(n);t._cachedResolutions[e]=o,r(o)}).catch(o)}})}}]),e}();t.default=o},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,o=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(0),a=(r=i)&&r.__esModule?r:{default:r};var l=function(){function e(t,n,r){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._document=t,this._config=n,this._log=r,this._urlBuilder=new a.default(n),this._injectedScripts={}}return o(e,[{key:"loadModules",value:function(e){var t=this,n=this._urlBuilder;if(0==e.length)return Promise.resolve();var r=n.build(e).map(function(e){return t._loadScript(e)});return Promise.all(r)}},{key:"_loadScript",value:function(e){var t=this,n=this._config.getModules(e.modules),r=this._injectedScripts[e.url];return r||((r=this._document.createElement("script")).src=e.url,r.async=!1,r.onload=r.onreadystatechange=function(){t.readyState&&"complete"!==t.readyState&&"load"!==t.readyState||(r.onload=r.onreadystatechange=null,r.onerror=null,n.forEac
41h(function(e){e.fetch.fulfilled?t._log.warn("Module '"+e.name+"' is being fetched from\n",r.src,"but was already fetched from\n",e.fetch.resolved?e.fetch.resolution.src:e.fetch.rejection.script.src):e.fetch.resolve(r)}))},r.onerror=function(){r.onload=r.onreadystatechange=null,r.onerror=null;var t=Object.assign(new Error("Unable to load script from URL "+e.url),{url:e.url,modules:e.modules,script:r});n.forEach(function(e){return e.fetch.reject(t)})},this._injectedScripts[e.url]=r,this._document.head.appendChild(r)),Promise.all(n.map(function(e){return e.fetch}))}}]),e}();t.default=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();var o={off:0,error:1,warn:2,info:3,debug:4},i="liferay-amd-loader |",a=function(){function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._config=t}return r(e,[{key:"error",value:function(){var e;if(this._applies("error")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).error.apply(e,[i].concat(n))}}},{key:"warn",value:function(){var e;if(this._applies("warn")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).warn.apply(e,[i].concat(n))}}},{key:"info",value:function(){var e;if(this._applies("info")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).info.apply(e,[i].concat(n))}}},{key:"debug",value:function(){var e;if(this._applies("debug")){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).debug.apply(e,[i].concat(n))}}},{key:"resolution",value:function(){var e;if(this._config.explainResolutions){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];(e=console).log.apply(e,[i].concat(n))}}},{key:"_applies",value:function(e){var t=o[this._config.logLevel];return o[e]<=t}}]),e}();t.default=a},function(e){e.exports={name:"liferay-amd-loader",version:"4.2.0",description:"AMD Loader with support for combo URL and conditional loading",scripts:{clean:"rm -rf build",build:"node bin/build-loader.js",ci:"npm run format:check && npm run lint && npm run build && npm run build-demo && npm test","build-demo":"node bin/build-demo.js",demo:"node bin/run-demo.js",test:"jest --runInBand",format:"prettier --write '{*,.*}.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'","format:check":"prettier --list-different '{*,.*}.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'",lint:"eslint '*.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'","lint:fix":"eslint --fix '*.js' 'bin/**/{*,.*}.js' 'src/**/{*,.*}.js'",prepublish:"publish-please guard","publish-please":"publish-please",prepublishOnly:"npm run build && npm run build-demo && npm test",proxyPortal:"webpack-dev-server --config webpack.proxyPortal.js"},repository:{type:"git",url:"git+https://github.com/liferay/liferay-amd-loader.git"},jest:{collectCoverage:!0,coverageDirectory:"build/coverage",modulePathIgnorePatterns:["liferay-amd-loader/build/.*",".*/__tests__/__fixtures__/.*"],testPathIgnorePatterns:[".eslintrc.js"],testURL:"http://localhost/"},author:{name:"Iliyan Peychev"},license:"LGPL-3.0",keywords:["Liferay","AMD","ES6","Loader"],bugs:{url:"https://github.com/liferay/liferay-amd-loader/issues"},homepage:"https://github.com/liferay/liferay-amd-loader",files:[".babelrc",".eslintrc.js",".publishrc","LICENSE.md","package.json","README.md","webpack.config.js","src","bin","build","src"],devDependencies:{"babel-loader":"^7.1.2","babel-preset-es2015":"^6.24.1",combohandler:"^0.4.0",eslint:"^5.15.1","eslint-config-liferay":"^3.0.0","fs-extra":"^5.0.0",globby:"^7.1.1","http-server":"^0.11.1",jest:"^22.2.1",prettier:"^1.16.4","publish-please":"^2.3.1","uglifyjs-webpack-plugin":"^1.2.0",webpack:"^4.29.6","webpack-cli":"^3.3.0","webpack-dev-server":"^3.2.1"}}}]); 42//# sourceMappingURL=loader.js.map 43/** 44The YUI module contains the components required for building the YUI seed file. 45This includes the script loading mechanism, a simple queue, and the core 46utilities for the library. 47 48@module yui 49@main yui 50@submodule yui-base 51**/ 52 53/*jshint eqeqeq: false*/ 54if (typeof YUI != 'undefined') { 55 YUI._YUI = YUI; 56} 57 58/** 59The YUI global namespace object. This is the constructor for all YUI instances. 60 61This is a self-instantiable factory function, meaning you don't need to precede 62it with the `new` operator. You can invoke it directly like this: 63 64 YUI().use('*', function (Y) { 65 // Y is a new YUI instance. 66 }); 67 68But it also works like this: 69 70 var Y = YUI(); 71 72The `YUI` constructor accepts an optional config object, like this: 73 74 YUI({ 75 debug: true, 76 combine: false 77 }).use('node', function (Y) { 78 // Y.Node is ready to use. 79 }); 80 81See the API docs for the <a href="config.html">Config</a> class for the complete 82list of supported configuration properties accepted by the YUI constuctor. 83 84If a global `YUI` object is already defined, the existing YUI object will not be 85overwritten, to ensure that defined namespaces are preserved. 86 87Each YUI instance has full custom event support, but only if the event system is 88available. 89 90@class YUI 91@uses EventTarget 92@constructor 93@global 94@param {Object} [config]* Zero or more optional configuration objects. Config 95 values are stored in the `Y.config` property. See the 96 <a href="config.html">Config</a> docs for the list of supported properties. 97**/ 98 99 /*global YUI*/ 100 /*global YUI_config*/ 101 var YUI = function() { 102 var i = 0, 103 Y = this, 104 args = arguments, 105 l = args.length, 106 instanceOf = function(o, type) { 107 return (o && o.hasOwnProperty && (o instanceof type)); 108 }, 109 gconf = (typeof YUI_config !== 'undefined') && YUI_config; 110 111 if (!(instanceOf(Y, YUI))) { 112 Y = new YUI(); 113 } else { 114 // set up the core environment 115 Y._init(); 116 117 /** 118 Master configuration that might span multiple contexts in a non- 119 browser environment. It is applied first to all instances in all 120 contexts. 121 122 @example 123 124 YUI.GlobalConfig = { 125 filter: 'debug' 126 }; 127 128 YUI().use('node', function (Y) { 129 // debug files used here 130 }); 131 132 YUI({ 133 filter: 'min' 134 }).use('node', function (Y) { 135 // min files used here 136 }); 137 138 @property {Object} GlobalConfig 139 @global 140 @static 141 **/ 142 if (YUI.GlobalConfig) { 143 Y.applyConfig(YUI.GlobalConfig); 144 } 145 146 /** 147 Page-level config applied to all YUI instances created on the 148 current page. This is applied after `YUI.GlobalConfig` and before 149 any instance-level configuration. 150 151 @example 152 153 // Single global var to include before YUI seed file 154 YUI_config = { 155 filter: 'debug' 156 }; 157 158 YUI().use('node', function (Y) { 159 // debug files used here 160 }); 161 162 YUI({ 163 filter: 'min' 164 }).use('node', function (Y) { 165 // min files used here 166 }); 167 168 @property {Object} YUI_config 169 @global 170 **/ 171 if (gconf) { 172 Y.applyConfig(gconf); 173 } 174 175 // bind the specified additional modules for this instance 176 if (!l) { 177 Y._afterConfig(); 178 Y._setup(); 179 } 180 } 181 182 if (l) { 183 // Each instance can accept one or more configuration objects. 184 // These are applied after YUI.GlobalConfig and YUI_Config, 185 // overriding values set in those config files if there is a 186 // matching property. 187 for (; i < l; i++) { 188 Y.applyConfig(args[i]); 189 } 190 191 Y._afterConfig(); 192 Y._setup(); 193 } 194 195 Y.instanceOf = instanceOf; 196 197 return Y; 198 }; 199 200(function() { 201 202 var proto, prop, 203 VERSION = 'patched-v3.18.1', 204 PERIOD = '.', 205 BASE = 'http://yui.yahooapis.com/', 206 /* 207 These CSS class names can't be generated by 208 getClassName since it is not available at the 209 time they are being used. 210 */ 211 DOC_LABEL = 'yui3-js-enabled', 212 CSS_STAMP_EL = 'yui3-css-stamp', 213 NOOP = function() {}, 214 SLICE = Array.prototype.slice, 215 APPLY_TO_AUTH = { 'io.xdrReady': 1, // the functions applyTo 216 'io.xdrResponse': 1, // can call. this should 217 'SWF.eventHandler': 1 }, // be done at build time 218 hasWin = (typeof window != 'undefined'), 219 win = (hasWin) ? window : null, 220 doc = (hasWin) ? win.document : null, 221 docEl = doc && doc.documentElement, 222 docClass = docEl && docEl.className, 223 instances = {}, 224 time = new Date().getTime(), 225 add = function(el, type, fn, capture) { 226 if (el && el.addEventListener) { 227 el.addEventListener(type, fn, capture); 228 } else if (el && el.attachEvent) { 229 el.attachEvent('on' + type, fn); 230 } 231 }, 232 remove = function(el, type, fn, capture) { 233 if (el && el.removeEventListener) { 234 // this can throw an uncaught exception in FF 235 try { 236 el.removeEventListener(type, fn, capture); 237 } catch (ex) {} 238 } else if (el && el.detachEvent) { 239 el.detachEvent('on' + type, fn); 240 } 241 }, 242 handleReady = function() { 243 YUI.Env.DOMReady = true; 244 if (hasWin) { 245 remove(doc, 'DOMContentLoaded', handleReady); 246 } 247 }, 248 handleLoad = function() { 249 YUI.Env.windowLoaded = true; 250 YUI.Env.DOMReady = true; 251 if (hasWin) { 252 remove(window, 'load', handleLoad); 253 } 254 }, 255 getLoader = function(Y, o) { 256 var loader = Y.Env._loader, 257 lCore = [ 'loader-base' ], 258 G_ENV = YUI.Env, 259 mods = G_ENV.mods; 260 261 if (loader) { 262 //loader._config(Y.config); 263 loader.ignoreRegistered = false;
264 loader.onEnd = null; 265 loader.data = null; 266 loader.required = []; 267 loader.loadType = null; 268 } else { 269 loader = new Y.Loader(Y.config); 270 Y.Env._loader = loader; 271 } 272 if (mods && mods.loader) { 273 lCore = [].concat(lCore, YUI.Env.loaderExtras); 274 } 275 YUI.Env.core = Y.Array.dedupe([].concat(YUI.Env.core, lCore)); 276 277 return loader; 278 }, 279 280 clobber = function(r, s) { 281 for (var i in s) { 282 if (s.hasOwnProperty(i)) { 283 r[i] = s[i]; 284 } 285 } 286 }, 287 288 ALREADY_DONE = { success: true }; 289 290// Stamp the documentElement (HTML) with a class of "yui-loaded" to 291// enable styles that need to key off of JS being enabled. 292if (docEl && docClass.indexOf(DOC_LABEL) == -1) { 293 if (docClass) { 294 docClass += ' '; 295 } 296 docClass += DOC_LABEL; 297 docEl.className = docClass; 298} 299 300if (VERSION.indexOf('@') > -1) { 301 VERSION = '3.5.0'; // dev time hack for cdn test 302} 303 304proto = { 305 /** 306 Applies a new configuration object to the config of this YUI instance. This 307 will merge new group/module definitions, and will also update the loader 308 cache if necessary. Updating `Y.config` directly will not update the cache. 309 310 @method applyConfig 311 @param {Object} o the configuration object. 312 @since 3.2.0 313 **/ 314 applyConfig: function(o) { 315 316 o = o || NOOP; 317 318 var attr, 319 name, 320 // detail, 321 config = this.config, 322 mods = config.modules, 323 groups = config.groups, 324 aliases = config.aliases, 325 loader = this.Env._loader; 326 327 for (name in o) { 328 if (o.hasOwnProperty(name)) { 329 attr = o[name]; 330 if (mods && name == 'modules') { 331 clobber(mods, attr); 332 } else if (aliases && name == 'aliases') { 333 clobber(aliases, attr); 334 } else if (groups && name == 'groups') { 335 clobber(groups, attr); 336 } else if (name == 'win') { 337 config[name] = (attr && attr.contentWindow) || attr; 338 config.doc = config[name] ? config[name].document : null; 339 } else if (name == '_yuid') { 340 // preserve the guid 341 } else { 342 config[name] = attr; 343 } 344 } 345 } 346 347 if (loader) { 348 loader._config(o); 349 } 350 351 }, 352 353 /** 354 Old way to apply a config to this instance (calls `applyConfig` under the 355 hood). 356 357 @private 358 @method _config 359 @param {Object} o The config to apply 360 **/ 361 _config: function(o) { 362 this.applyConfig(o); 363 }, 364 365 /** 366 Initializes this YUI instance. 367 368 @private 369 @method _init 370 **/ 371 _init: function() { 372 var filter, el, 373 Y = this, 374 G_ENV = YUI.Env, 375 Env = Y.Env, 376 prop; 377 378 /** 379 The version number of this YUI instance. 380 381 This value is typically updated by a script when a YUI release is built, 382 so it may not reflect the correct version number when YUI is run from 383 the development source tree. 384 385 @property {String} version 386 **/ 387 Y.version = VERSION; 388 389 if (!Env) { 390 Y.Env = { 391 core: ['get', 'features', 'intl-base', 'yui-log', 'yui-later', 'loader-base', 'loader-rollup', 'loader-yui3'], 392 loaderExtras: ['loader-rollup', 'loader-yui3'], 393 mods: {}, // flat module map 394 versions: {}, // version module map 395 base: BASE, 396 cdn: BASE + VERSION + '/', 397 // bootstrapped: false, 398 _idx: 0, 399 _used: {}, 400 _attached: {}, 401 _exported: {}, 402 _missed: [], 403 _yidx: 0, 404 _uidx: 0, 405 _guidp: 'y', 406 _loaded: {}, 407 // serviced: {},
408 // Regex in English: 409 // I'll start at the \b(yui). 410 // 1. Look in the test string for "yui" or 411 // "yui-base" or "yui-davglass" or "yui-foobar" that comes after a word break. That is, it 412 // can't match "foyui" or "i_heart_yui". This can be anywhere in the string. 413 // 2. After #1 must come a forward slash followed by the string matched in #1, so 414 // "yui-base/yui-base" or "yui-pants/yui-pants". 415 // 3. The second occurence of the #1 token can optionally be followed by "-debug" or "-min", 416 // so "yui/yui-min", "yui/yui-debug", "yui-base/yui-base-debug". NOT "yui/yui-tshirt". 417 // 4. This is followed by ".js", so "yui/yui.js". 418 // 0. Going back to the beginning, now. If all that stuff in 1-4 comes after a "?" in the string, 419 // then capture the junk between the LAST "&" and the string in 1-4. So 420 // "blah?foo/yui/yui.js" will capture "foo/" and "blah?some/thing.js&3.3.0/build/yui-davglass/yui-davglass.js" 421 // will capture "3.3.0/build/" 422 // 423 // Regex Exploded: 424 // (?:\? Find a ? 425 // (?:[^&]*&) followed by 0..n characters followed by an & 426 // * in fact, find as many sets of characters followed by a & as you can 427 // ([^&]*) capture the stuff after the last & in \1 428 // )? but it's ok if all this ?junk&more_junk stuff isn't even there 429 // \b( after a word break find either the string 430 // yui(?:-\w+)? "yui" optionally followed by a -, then more characters 431 // ) and store the yui-* string in \2 432 // \/\2 then comes a / followed by the yui-* string in \2 433 // (?:-(min|debug))? optionally followed by "-min" or "-debug" 434 // .js and ending in ".js" 435 _BASE_RE: /(?:\?(?:[^&]*&)*([^&]*))?\b(aui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/, 436 parseBasePath: function(src, pattern) { 437 var match = src.match(pattern), 438 path, filter; 439 440 if (match) { 441 path = RegExp.leftContext || src.slice(0, src.indexOf(match[0])); 442 443 // this is to set up the path to the loader. The file 444 // filter for loader should match the yui include. 445 filter = match[3]; 446 447 // extract correct path for mixed combo urls 448 // http://yuilibrary.com/projects/yui3/ticket/2528423 449 if (match[1]) { 450 path += '?' + match[1]; 451 } 452 path = { 453 filter: filter, 454 path: path 455 }; 456 } 457 return path; 458 }, 459 getBase: G_ENV && G_ENV.getBase || 460 function(pattern) { 461 var nodes = (doc && doc.getElementsByTagName('script')) || [], 462 path = Env.cdn, parsed, 463 i, len, src; 464 465 for (i = 0, len = nodes.length; i < len; ++i) { 466 src = nodes[i].src; 467 if (src) { 468 parsed = Y.Env.parseBasePath(src, pattern); 469 if (parsed) { 470 filter = parsed.filter; 471 path = parsed.path; 472 break; 473 } 474 } 475 } 476 477 // use CDN default 478 return path; 479 } 480 481 }; 482 483 Env = Y.Env; 484 485 Env._loaded[VERSION] = {}; 486 487 if (G_ENV && Y !== YUI) { 488 Env._yidx = ++G_ENV._yidx; 489 Env._guidp = ('yui_' + VERSION + '_' + 490 Env._yidx + '_' + time).replace(/[^a-z0-9_]+/g, '_'); 491 } else if (YUI._YUI) { 492 493 G_ENV = YUI._YUI.Env; 494 Env._yidx += G_ENV._yidx; 495 Env._uidx += G_ENV._uidx; 496 497 for (prop in G_ENV) {
498 if (!(prop in Env)) { 499 Env[prop] = G_ENV[prop]; 500 } 501 } 502 503 delete YUI._YUI; 504 } 505 506 Y.id = Y.stamp(Y); 507 instances[Y.id] = Y; 508 509 } 510 511 Y.constructor = YUI; 512 513 // configuration defaults 514 Y.config = Y.config || { 515 bootstrap: true, 516 cacheUse: true, 517 debug: true, 518 doc: doc, 519 fetchCSS: true, 520 throwFail: true, 521 useBrowserConsole: true, 522 useNativeES5: true, 523 win: win 524 }; 525 526 //Register the CSS stamp element 527 if (doc && !doc.getElementById(CSS_STAMP_EL)) { 528 el = doc.createElement('div'); 529 el.innerHTML = '<div id="' + CSS_STAMP_EL + '" style="position: absolute !important; visibility: hidden !important"></div>'; 530 YUI.Env.cssStampEl = el.firstChild; 531 if (doc.body) { 532 doc.body.appendChild(YUI.Env.cssStampEl); 533 } else { 534 docEl.insertBefore(YUI.Env.cssStampEl, docEl.firstChild); 535 } 536 } else if (doc && doc.getElementById(CSS_STAMP_EL) && !YUI.Env.cssStampEl) { 537 YUI.Env.cssStampEl = doc.getElementById(CSS_STAMP_EL); 538 } 539 540 Y.config.lang = Y.config.lang || 'en-US'; 541 542 Y.config.base = YUI.config.base || 543 (YUI.config.defaultBase && YUI.config.root && YUI.config.defaultBase + YUI.config.root) || 544 Y.Env.getBase(Y.Env._BASE_RE); 545 546 if (!filter || (!('mindebug').indexOf(filter))) { 547 filter = 'min'; 548 } 549 filter = (filter) ? '-' + filter : filter; 550 Y.config.loaderPath = YUI.config.loaderPath || 'loader/loader' + filter + '.js'; 551 552 }, 553 554 /** 555 This method is called after all other configuration has been applied to 556 the YUI instance. 557 558 @method _afterConfig 559 @private 560 **/ 561 _afterConfig: function () { 562 var Y = this; 563 564 // We need to set up Y.config.global after the rest of the configuration 565 // so that setting it in user configuration prevents the library from 566 // using eval(). This is critical for Content Security Policy enabled 567 // sites and other environments like Chrome extensions 568 if (!Y.config.hasOwnProperty('global')) { 569 Y.config.global = Function('return this')(); 570 } 571 }, 572 573 /** 574 Finishes the instance setup. Attaches whatever YUI modules were defined 575 at the time that this instance was created. 576 577 @method _setup 578 @private 579 **/ 580 _setup: function() { 581 var i, Y = this, 582 core = [], 583 mods = YUI.Env.mods, 584 extendedCore = Y.config.extendedCore || [], 585 extras = Y.config.core || [].concat(YUI.Env.core).concat(extendedCore); //Clone it.. 586 587 for (i = 0; i < extras.length; i++) { 588 if (mods[extras[i]]) { 589 core.push(extras[i]); 590 } 591 } 592 593 Y._attach(['yui-base']); 594 Y._attach(core); 595 596 if (Y.Loader) { 597 getLoader(Y); 598 } 599 600 }, 601 602 /** 603 Executes the named method on the specified YUI instance if that method is 604 whitelisted. 605 606 @method applyTo 607 @param {String} id YUI instance id. 608 @param {String} method Name of the method to execute. For example: 609 'Object.keys'. 610 @param {Array} args Arguments to apply to the method. 611 @return {Mixed} Return value from the applied method, or `null` if the 612 specified instance was not found or the method was not whitelisted. 613 **/ 614 applyTo: function(id, method, args) { 615 if (!(method in APPLY_TO_AUTH)) { 616 this.log(method + ': applyTo not allowed', 'warn', 'yui'); 617 return null; 618 } 619 620 var instance = instances[id], nest, m, i; 621 if (instance) { 622 nest = method.split('.'); 623 m = instance; 624 for (i = 0; i < nest.length; i = i + 1) { 625 m = m[nest[i]]; 626 if (!m) { 627 this.log('applyTo not found: ' + method, 'warn', 'yui'); 628 } 629 } 630 return m && m.apply(instance, args); 631 } 632 633 return null; 634 }, 635 636/** 637Registers a YUI module and makes it available for use in a `YUI().use()` call or 638as a dependency for other modules. 639 640The easiest way to create a first-class YUI module is to use 641<a href="http://yui.github.com/shifter/">Shifter</a>, the YUI component build 642tool. 643 644Shifter will automatically wrap your module code in a `YUI.add()` call along 645with any configuration info required for the module. 646 647@example 648 649 YUI.add('davglass', function (Y) { 650 Y.davglass = function () { 651 }; 652 }, '3.4.0', { 653 requires: ['harley-davidson', 'mt-dew'] 654 }); 655 656@method add 657@param {String} name Module name. 658@param {Function} fn Function containing module code. This function will be 659 executed whenever the module is attached to a specific YUI instance. 660 661 @param {YUI} fn.Y The YUI instance to which this module is attached.
662 @param {String} fn.name Name of the module 663 664@param {String} version Module version number. This is currently used only for 665 informational purposes, and is not used internally by YUI. 666 667@param {Object} [details] Module config. 668 @param {Array} [details.requires] Array of other module names that must be 669 attached before this module can be attached. 670 @param {Array} [details.optional] Array of optional module names that should 671 be attached before this module is attached if they've already been 672 loaded. If the `loadOptional` YUI option is `true`, optional modules 673 that have not yet been loaded will be loaded just as if they were hard 674 requirements. 675 @param {Array} [details.use] Array of module names that are included within 676 or otherwise provided by this module, and which should be attached 677 automatically when this module is attached. This makes it possible to 678 create "virtual rollup" modules that simply attach a collection of other 679 modules or submodules. 680 681@return {YUI} This YUI instance. 682**/ 683 add: function(name, fn, version, details) { 684 details = details || {}; 685 var env = YUI.Env, 686 mod = { 687 name: name, 688 fn: fn, 689 version: version, 690 details: details 691 }, 692 //Instance hash so we don't apply it to the same instance twice 693 applied = {}, 694 loader, inst, modInfo, 695 i, versions = env.versions; 696 697 env.mods[name] = mod; 698 versions[version] = versions[version] || {}; 699 versions[version][name] = mod; 700 701 for (i in instances) { 702 if (instances.hasOwnProperty(i)) { 703 inst = instances[i]; 704 if (!applied[inst.id]) { 705 applied[inst.id] = true; 706 loader = inst.Env._loader; 707 if (loader) { 708 modInfo = loader.getModuleInfo(name); 709 if (!modInfo || modInfo.temp) { 710 loader.addModule(details, name); 711 } 712 } 713 } 714 } 715 } 716 717 return this; 718 }, 719 720 /** 721 Executes the callback function associated with each required module, 722 attaching the module to this YUI instance. 723 724 @method _attach 725 @param {Array} r The array of modules to attach 726 @param {Boolean} [moot=false] If `true`, don't throw a warning if the module 727 is not attached. 728 @private 729 **/ 730 _attach: function(r, moot) { 731 var i, name, mod, details, req, use, after, 732 mods = YUI.Env.mods, 733 aliases = YUI.Env.aliases, 734 Y = this, j, 735 cache = YUI.Env._renderedMods, 736 loader = Y.Env._loader, 737 done = Y.Env._attached, 738 exported = Y.Env._exported, 739 len = r.length, loader, def, go, 740 c = [], 741 modArgs, esCompat, reqlen, modInfo, 742 condition, 743 __exports__, __imports__; 744 745 //Check for conditional modules (in a second+ instance) and add their requirements 746 //TODO I hate this entire method, it needs to be fixed ASAP (3.5.0) ^davglass 747 for (i = 0; i < len; i++) { 748 name = r[i]; 749 mod = mods[name]; 750 c.push(name); 751 if (loader && loader.conditions[name]) { 752 for (j in loader.conditions[name]) { 753 if (loader.conditions[name].hasOwnProperty(j)) { 754 def = loader.conditions[name][j]; 755 go = def && ((def.ua && Y.UA[def.ua]) || (def.test && def.test(Y))); 756 if (go) { 757 c.push(def.name); 758 } 759 } 760 } 761 } 762 } 763 r = c; 764 len = r.length; 765 766 for (i = 0; i < len; i++) { 767 if (!done[r[i]]) { 768 name = r[i]; 769 mod = mods[name]; 770 771 if (aliases && aliases[name] && !mod) { 772 Y._attach(aliases[name]); 773 continue; 774 } 775 if (!mod) { 776 modInfo = loader && loader.getModuleInfo(name); 777 if (modInfo) { 778 mod = modInfo; 779 moot = true; 780 } 781 782 783 //if (!loader || !loader.moduleInfo[name]) { 784 //if ((!loader || !loader.moduleInfo[name]) && !moot) { 785 if (!moot && name) { 786 if ((name.indexOf('skin-') === -1) && (name.indexOf('css') === -1)) { 787 Y.Env._missed.push(name); 788 Y.Env._missed = Y.Array.dedupe(Y.Env._missed); 789 Y.message('NOT loaded: ' + name, 'warn', 'yui'); 790 } 791 } 792 } else { 793 done[name] = true; 794 //Don't like this, but in case a mod was asked for once, then we fetch it 795 //We need to remove it from the missed list ^davglass 796 for (j = 0; j < Y.Env._missed.length; j++) { 797 if (Y.Env._missed[j] === name) {
798 Y.message('Found: ' + name + ' (was reported as missing earlier)', 'warn', 'yui'); 799 Y.Env._missed.splice(j, 1); 800 } 801 } 802 803 // Optional dependencies normally work by modifying the 804 // dependency list of a module. If the dependency's test 805 // passes it is added to the list. If not, it's not loaded. 806 // This following check ensures that optional dependencies 807 // are not attached when they were already loaded into the 808 // page (when bundling for example) 809 if (loader && !loader._canBeAttached(name)) { 810 return true; 811 } 812 813 /* 814 If it's a temp module, we need to redo it's requirements if it's already loaded 815 since it may have been loaded by another instance and it's dependencies might 816 have been redefined inside the fetched file. 817 */ 818 if (loader && cache && cache[name] && cache[name].temp) { 819 loader.getRequires(cache[name]); 820 req = []; 821 modInfo = loader.getModuleInfo(name); 822 for (j in modInfo.expanded_map) { 823 if (modInfo.expanded_map.hasOwnProperty(j)) { 824 req.push(j); 825 } 826 } 827 Y._attach(req); 828 } 829 830 details = mod.details; 831 req = details.requires; 832 esCompat = details.es; 833 use = details.use; 834 after = details.after; 835 //Force Intl load if there is a language (Loader logic) @todo fix this shit 836 if (details.lang) { 837 req = req || []; 838 req.unshift('intl'); 839 } 840 841 if (req) { 842 reqlen = req.length; 843 for (j = 0; j < reqlen; j++) { 844 if (!done[req[j]]) { 845 if (!Y._attach(req)) { 846 return false; 847 } 848 break; 849 } 850 } 851 } 852 853 if (after) { 854 for (j = 0; j < after.length; j++) { 855 if (!done[after[j]]) { 856 if (!Y._attach(after, true)) { 857 return false; 858 } 859 break; 860 } 861 } 862 } 863 864 if (mod.fn) { 865 modArgs = [Y, name]; 866 if (esCompat) { 867 __imports__ = {}; 868 __exports__ = {}; 869 // passing `exports` and `imports` onto the module function 870 modArgs.push(__imports__, __exports__); 871 if (req) { 872 reqlen = req.length; 873 for (j = 0; j < reqlen; j++) { 874 __imports__[req[j]] = exported.hasOwnProperty(req[j]) ? exported[req[j]] : Y; 875 } 876 } 877 } 878 if (Y.config.throwFail) { 879 __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs); 880 } else { 881 try { 882 __exports__ = mod.fn.apply(esCompat ? undefined : mod, modArgs); 883 } catch (e) { 884 Y.error('Attach error: ' + name, e, name); 885 return false;
886 } 887 } 888 if (esCompat) { 889 // store the `exports` in case others `es` modules requires it 890 exported[name] = __exports__; 891 892 // If an ES module is conditionally loaded and set 893 // to be used "instead" another module, replace the 894 // trigger module's content with the conditionally 895 // loaded one so the values returned by require() 896 // still makes sense 897 condition = mod.details.condition; 898 if (condition && condition.when === 'instead') { 899 exported[condition.trigger] = __exports__; 900 } 901 } 902 } 903 904 if (use) { 905 for (j = 0; j < use.length; j++) { 906 if (!done[use[j]]) { 907 if (!Y._attach(use)) { 908 return false; 909 } 910 break; 911 } 912 } 913 } 914 915 916 917 } 918 } 919 } 920 921 return true; 922 }, 923 924 /** 925 Delays the `use` callback until another event has taken place such as 926 `window.onload`, `domready`, `contentready`, or `available`. 927 928 @private 929 @method _delayCallback 930 @param {Function} cb The original `use` callback. 931 @param {String|Object} until Either an event name ('load', 'domready', etc.) 932 or an object containing event/args keys for contentready/available. 933 @return {Function} 934 **/ 935 _delayCallback: function(cb, until) { 936 937 var Y = this, 938 mod = ['event-base']; 939 940 until = (Y.Lang.isObject(until) ? until : { event: until }); 941 942 if (until.event === 'load') { 943 mod.push('event-synthetic'); 944 } 945 946 return function() { 947 var args = arguments; 948 Y._use(mod, function() { 949 Y.on(until.event, function() { 950 args[1].delayUntil = until.event; 951 cb.apply(Y, args); 952 }, until.args); 953 }); 954 }; 955 }, 956 957 /** 958 Attaches one or more modules to this YUI instance. When this is executed, 959 the requirements of the desired modules are analyzed, and one of several 960 things can happen: 961 962 963 * All required modules have already been loaded, and just need to be 964 attached to this YUI instance. In this case, the `use()` callback will 965 be executed synchronously after the modules are attached. 966 967 * One or more modules have not yet been loaded, or the Get utility is not 968 available, or the `bootstrap` config option is `false`. In this case, 969 a warning is issued indicating that modules are missing, but all 970 available modules will still be attached and the `use()` callback will 971 be executed synchronously. 972 973 * One or more modules are missing and the Loader is not available but the 974 Get utility is, and `bootstrap` is not `false`. In this case, the Get 975 utility will be used to load the Loader, and we will then proceed to 976 the following state: 977 978 * One or more modules are missing and the Loader is available. In this 979 case, the Loader will be used to resolve the dependency tree for the 980 missing modules and load them and their dependencies. When the Loader is 981 finished loading modules, the `use()` callback will be executed 982 asynchronously. 983 984 @example 985 986 // Loads and attaches dd and its dependencies. 987 YUI().use('dd', function (Y) { 988 // ... 989 }); 990 991 // Loads and attaches dd and node as well as all of their dependencies. 992 YUI().use(['dd', 'node'], function (Y) { 993 // ... 994 }); 995 996 // Attaches all modules that have already been loaded. 997 YUI().use('*', function (Y) { 998 // ... 999 }); 1000 1001 // Attaches a gallery module. 1002 YUI().use('gallery-yql', function (Y) { 1003 // ... 1004 }); 1005 1006 // Attaches a YUI 2in3 module. 1007 YUI().use('yui2-datatable', function (Y) { 1008 // ... 1009 }); 1010 1011 @method use 1012 @param {String|Array} modules* One or more module names to attach. 1013 @param {Function} [callback] Callback function to be executed once all 1014 specified modules and their dependencies have been attached.
1015 @param {YUI} callback.Y The YUI instance created for this sandbox. 1016 @param {Object} callback.status Object containing `success`, `msg` and 1017 `data` properties. 1018 @chainable 1019 **/ 1020 use: function() { 1021 var args = SLICE.call(arguments, 0), 1022 callback = args[args.length - 1], 1023 Y = this, 1024 i = 0, 1025 name, 1026 Env = Y.Env, 1027 provisioned = true; 1028 1029 // The last argument supplied to use can be a load complete callback 1030 if (Y.Lang.isFunction(callback)) { 1031 args.pop(); 1032 if (Y.config.delayUntil) { 1033 callback = Y._delayCallback(callback, Y.config.delayUntil); 1034 } 1035 } else { 1036 callback = null; 1037 } 1038 if (Y.Lang.isArray(args[0])) { 1039 args = args[0]; 1040 } 1041 1042 if (Y.config.cacheUse) { 1043 while ((name = args[i++])) { 1044 if (!Env._attached[name]) { 1045 provisioned = false; 1046 break; 1047 } 1048 } 1049 1050 if (provisioned) { 1051 if (args.length) { 1052 } 1053 Y._notify(callback, ALREADY_DONE, args); 1054 return Y; 1055 } 1056 } 1057 1058 if (Y._loading) { 1059 Y._useQueue = Y._useQueue || new Y.Queue(); 1060 Y._useQueue.add([args, callback]); 1061 } else { 1062 Y._use(args, function(Y, response) { 1063 Y._notify(callback, response, args); 1064 }); 1065 } 1066 1067 return Y; 1068 }, 1069 1070 /** 1071 Sugar for loading both legacy and ES6-based YUI modules. 1072 1073 @method require 1074 @param {String} [modules*] List of module names to import or a single 1075 module name. 1076 @param {Function} callback Callback that gets called once all the modules 1077 were loaded. Each parameter of the callback is the export value of the 1078 corresponding module in the list. If the module is a legacy YUI module, 1079 the YUI instance is used instead of the module exports. 1080 @example 1081 ``` 1082 YUI().require(['es6-set'], function (Y, imports) { 1083 var Set = imports.Set, 1084 set = new Set(); 1085 }); 1086 ``` 1087 **/ 1088 require: function () { 1089 var args = SLICE.call(arguments), 1090 callback; 1091 1092 if (typeof args[args.length - 1] === 'function') { 1093 callback = args.pop(); 1094 1095 // only add the callback if one was provided 1096 // YUI().require('foo'); is valid 1097 args.push(function (Y) { 1098 var i, length = args.length, 1099 exported = Y.Env._exported, 1100 __imports__ = {}; 1101 1102 // Get only the imports requested as arguments 1103 for (i = 0; i < length; i++) { 1104 if (exported.hasOwnProperty(args[i])) { 1105 __imports__[args[i]] = exported[args[i]]; 1106 } 1107 } 1108 1109 // Using `undefined` because: 1110 // - Using `Y.config.global` would force the value of `this` to be 1111 // the global object even in strict mode 1112 // - Using `Y` goes against the goal of moving away from a shared 1113 // object and start thinking in terms of imported and exported 1114 // objects 1115 callback.call(undefined, Y, __imports__); 1116 }); 1117 } 1118 // Do not return the Y object. This makes it hard to follow this 1119 // traditional pattern: 1120 // var Y = YUI().use(...); 1121 // This is a good idea in the light of ES6 modules, to avoid working 1122 // in the global scope. 1123 // This also leaves the door open for returning a promise, once the 1124 // YUI loader is based on the ES6 loader which uses 1125 // loader.import(...).then(...) 1126 this.use.apply(this, args); 1127 }, 1128 1129 /** 1130 Handles Loader notifications about attachment/load errors. 1131 1132 @method _notify 1133 @param {Function} callback Callback to pass to `Y.config.loadErrorFn`. 1134 @param {Object} response Response returned from Loader. 1135 @param {Array} args Arguments passed from Loader. 1136 @private 1137 **/ 1138 _notify: function(callback, response, args) { 1139 if (!response.success && this.config.loadErrorFn) { 1140 this.config.loadErrorFn.call(this, this, callback, response, args); 1141 } else if (callback) { 1142 if (this.Env._missed && this.Env._missed.length) { 1143 response.msg = 'Missing modules: ' + this.Env._missed.join(); 1144 response.success = false;
1145 } 1146 if (this.config.throwFail) { 1147 callback(this, response); 1148 } else { 1149 try { 1150 callback(this, response); 1151 } catch (e) { 1152 this.error('use callback error', e, args); 1153 } 1154 } 1155 } 1156 }, 1157 1158 /** 1159 Called from the `use` method queue to ensure that only one set of loading 1160 logic is performed at a time. 1161 1162 @method _use 1163 @param {String} args* One or more modules to attach. 1164 @param {Function} [callback] Function to call once all required modules have 1165 been attached. 1166 @private 1167 **/ 1168 _use: function(args, callback) { 1169 1170 if (!this.Array) { 1171 this._attach(['yui-base']); 1172 } 1173 1174 var len, loader, handleBoot, 1175 Y = this, 1176 G_ENV = YUI.Env, 1177 mods = G_ENV.mods, 1178 Env = Y.Env, 1179 used = Env._used, 1180 aliases = G_ENV.aliases, 1181 queue = G_ENV._loaderQueue, 1182 firstArg = args[0], 1183 YArray = Y.Array, 1184 config = Y.config, 1185 boot = config.bootstrap, 1186 missing = [], 1187 i, 1188 r = [], 1189 ret = true, 1190 fetchCSS = config.fetchCSS, 1191 process = function(names, skip) { 1192 1193 var i = 0, a = [], name, len, m, req, use; 1194 1195 if (!names.length) { 1196 return; 1197 } 1198 1199 if (aliases) { 1200 len = names.length; 1201 for (i = 0; i < len; i++) { 1202 if (aliases[names[i]] && !mods[names[i]]) { 1203 a = [].concat(a, aliases[names[i]]); 1204 } else { 1205 a.push(names[i]); 1206 } 1207 } 1208 names = a; 1209 } 1210 1211 len = names.length; 1212 1213 for (i = 0; i < len; i++) { 1214 name = names[i]; 1215 if (!skip) { 1216 r.push(name); 1217 } 1218 1219 // only attach a module once 1220 if (used[name]) { 1221 continue; 1222 } 1223 1224 m = mods[name]; 1225 req = null; 1226 use = null; 1227 1228 if (m) { 1229 used[name] = true; 1230 req = m.details.requires; 1231 use = m.details.use; 1232 } else { 1233 // CSS files don't register themselves, see if it has 1234 // been loaded 1235 if (!G_ENV._loaded[VERSION][name]) { 1236 missing.push(name); 1237 } else { 1238 used[name] = true; // probably css 1239 } 1240 } 1241 1242 // make sure requirements are attached 1243 if (req && req.length) { 1244 process(req); 1245 } 1246 1247 // make sure we grab the submodule dependencies too 1248 if (use && use.length) { 1249 process(use, 1); 1250 } 1251 } 1252 1253 }, 1254 1255 handleLoader = function(fromLoader) { 1256 var response = fromLoader || { 1257 success: true, 1258 msg: 'not dynamic' 1259 }, 1260 redo, origMissing, 1261 ret = true, 1262 data = response.data; 1263 1264 Y._loading = false; 1265 1266 if (data) { 1267 origMissing = missing; 1268 missing = []; 1269 r = []; 1270 process(data); 1271 redo = missing.length; 1272 if (redo) { 1273 if ([].concat(missing).sort().join() == 1274 origMissing.sort().join()) { 1275 redo = false; 1276 } 1277 } 1278 } 1279 1280 if (redo && data) { 1281 Y._loading = true; 1282 Y._use(missing, function() { 1283 if (Y._attach(data)) { 1284 Y._notify(callback, response, data); 1285 } 1286 }); 1287 } else { 1288 if (data) { 1289 ret = Y._attach(data); 1290 } 1291 if (ret) { 1292 Y._notify(callback, response, args); 1293 } 1294 } 1295 1296 if (Y._useQueue && Y._useQueue.size() && !Y._loading) { 1297 Y._use.apply(Y, Y._useQueue.next()); 1298 } 1299 1300 }; 1301 1302 1303 // YUI().use('*'); // bind everything available 1304 if (firstArg === '*') { 1305 args = []; 1306 for (i in mods) { 1307 if (mods.hasOwnProperty(i)) { 1308 args.push(i); 1309 } 1310 } 1311 ret = Y._attach(args); 1312 if (ret) { 1313 handleLoader(); 1314 } 1315 return Y; 1316 } 1317 1318 if ((mods.loader || mods['loader-base']) && !Y.Loader) { 1319 Y._attach(['loader' + ((!mods.loader) ? '-base' : '')]); 1320 } 1321 1322 1323 // use loader to expand dependencies and sort the 1324 // requirements if it is available.
1325 if (boot && Y.Loader && args.length) { 1326 loader = getLoader(Y); 1327 loader.require(args); 1328 loader.ignoreRegistered = true; 1329 loader._boot = true; 1330 loader.calculate(null, (fetchCSS) ? null : 'js'); 1331 args = loader.sorted; 1332 loader._boot = false; 1333 } 1334 1335 process(args); 1336 1337 len = missing.length; 1338 1339 1340 if (len) { 1341 missing = YArray.dedupe(missing); 1342 len = missing.length; 1343 } 1344 1345 1346 // dynamic load 1347 if (boot && len && Y.Loader) { 1348 Y._loading = true; 1349 loader = getLoader(Y); 1350 loader.onEnd = handleLoader; 1351 loader.context = Y; 1352 loader.data = args; 1353 loader.ignoreRegistered = false; 1354 loader.require(missing); 1355 loader.insert(null, (fetchCSS) ? null : 'js'); 1356 1357 } else if (boot && len && Y.Get && !Env.bootstrapped) { 1358 1359 Y._loading = true; 1360 1361 handleBoot = function() { 1362 Y._loading = false; 1363 queue.running = false; 1364 Env.bootstrapped = true; 1365 G_ENV._bootstrapping = false; 1366 if (Y._attach(['loader'])) { 1367 Y._use(args, callback); 1368 } 1369 }; 1370 1371 if (G_ENV._bootstrapping) { 1372 queue.add(handleBoot); 1373 } else { 1374 G_ENV._bootstrapping = true; 1375 Y.Get.script(config.base + config.loaderPath, { 1376 onEnd: handleBoot 1377 }); 1378 } 1379 1380 } else { 1381 ret = Y._attach(args); 1382 if (ret) { 1383 handleLoader(); 1384 } 1385 } 1386 1387 return Y; 1388 }, 1389 1390 1391 /** 1392 Utility method for safely creating namespaces if they don't already exist. 1393 May be called statically on the YUI global object or as a method on a YUI 1394 instance. 1395 1396 When called statically, a namespace will be created on the YUI global 1397 object: 1398 1399 // Create `YUI.your.namespace.here` as nested objects, preserving any 1400 // objects that already exist instead of overwriting them. 1401 YUI.namespace('your.namespace.here'); 1402 1403 When called as a method on a YUI instance, a namespace will be created on 1404 that instance: 1405 1406 // Creates `Y.property.package`. 1407 Y.namespace('property.package'); 1408 1409 Dots in the input string cause `namespace` to create nested objects for each 1410 token. If any part of the requested namespace already exists, the current 1411 object will be left in place and will not be overwritten. This allows 1412 multiple calls to `namespace` to preserve existing namespaced properties. 1413 1414 If the first token in the namespace string is "YAHOO", that token is 1415 discarded. This is legacy behavior for backwards compatibility with YUI 2. 1416 1417 Be careful with namespace tokens. Reserved words may work in some browsers 1418 and not others. For instance, the following will fail in some browsers 1419 because the supported version of JavaScript reserves the word "long": 1420 1421 Y.namespace('really.long.nested.namespace'); 1422 1423 Note: If you pass multiple arguments to create multiple namespaces, only the 1424 last one created is returned from this function. 1425
1426 @method namespace 1427 @param {String} namespace* One or more namespaces to create. 1428 @return {Object} Reference to the last namespace object created. 1429 **/ 1430 namespace: function() { 1431 var a = arguments, o, i = 0, j, d, arg; 1432 1433 for (; i < a.length; i++) { 1434 o = this; //Reset base object per argument or it will get reused from the last 1435 arg = a[i]; 1436 if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present 1437 d = arg.split(PERIOD); 1438 for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) { 1439 o[d[j]] = o[d[j]] || {}; 1440 o = o[d[j]]; 1441 } 1442 } else { 1443 o[arg] = o[arg] || {}; 1444 o = o[arg]; //Reset base object to the new object so it's returned 1445 } 1446 } 1447 return o; 1448 }, 1449 1450 // this is replaced if the log module is included 1451 log: NOOP, 1452 message: NOOP, 1453 // this is replaced if the dump module is included 1454 dump: function (o) { return ''+o; }, 1455 1456 /** 1457 Reports an error. 1458 1459 The reporting mechanism is controlled by the `throwFail` configuration 1460 attribute. If `throwFail` is falsy, the message is logged. If `throwFail` is 1461 truthy, a JS exception is thrown. 1462 1463 If an `errorFn` is specified in the config it must return `true` to indicate 1464 that the exception was handled and keep it from being thrown. 1465 1466 @method error 1467 @param {String} msg Error message. 1468 @param {Error|String} [e] JavaScript error object or an error string. 1469 @param {String} [src] Source of the error (such as the name of the module in 1470 which the error occurred). 1471 @chainable 1472 **/ 1473 error: function(msg, e, src) { 1474 //TODO Add check for window.onerror here 1475 1476 var Y = this, ret; 1477 1478 if (Y.config.errorFn) { 1479 ret = Y.config.errorFn.apply(Y, arguments); 1480 } 1481 1482 if (!ret) { 1483 throw (e || new Error(msg)); 1484 } else { 1485 Y.message(msg, 'error', ''+src); // don't scrub this one 1486 } 1487 1488 return Y; 1489 }, 1490 1491 /** 1492 Generates an id string that is unique among all YUI instances in this 1493 execution context. 1494 1495 @method guid 1496 @param {String} [pre] Prefix. 1497 @return {String} Unique id. 1498 **/ 1499 guid: function(pre) { 1500 var id = this.Env._guidp + '_' + (++this.Env._uidx); 1501 return (pre) ? (pre + id) : id; 1502 }, 1503 1504 /** 1505 Returns a unique id associated with the given object and (if *readOnly* is 1506 falsy) stamps the object with that id so it can be identified in the future. 1507 1508 Stamping an object involves adding a `_yuid` property to it that contains 1509 the object's id. One exception to this is that in Internet Explorer, DOM 1510 nodes have a `uniqueID` property that contains a browser-generated unique 1511 id, which will be used instead of a YUI-generated id when available. 1512 1513 @method stamp 1514 @param {Object} o Object to stamp. 1515 @param {Boolean} readOnly If truthy and the given object has not already 1516 been stamped, the object will not be modified and `null` will be 1517 returned. 1518 @return {String} Object's unique id, or `null` if *readOnly* was truthy and 1519 the given object was not already stamped. 1520 **/ 1521 stamp: function(o, readOnly) { 1522 var uid; 1523 if (!o) { 1524 return o; 1525 } 1526 1527 // IE generates its own unique ID for dom nodes 1528 // The uniqueID property of a document node returns a new ID 1529 if (o.uniqueID && o.nodeType && o.nodeType !== 9) { 1530 uid = o.uniqueID; 1531 } else { 1532 uid = (typeof o === 'string') ? o : o._yuid; 1533 } 1534 1535 if (!uid) { 1536 uid = this.guid(); 1537 if (!readOnly) { 1538 try { 1539 o._yuid = uid; 1540 } catch (e) { 1541 uid = null; 1542 } 1543 } 1544 } 1545 return uid; 1546 }, 1547 1548 /** 1549 Destroys this YUI instance. 1550 1551 @method destroy 1552 @since 3.3.0 1553 **/ 1554 destroy: function() { 1555 var Y = this; 1556 if (Y.Event) { 1557 Y.Event._unload(); 1558 } 1559 delete instances[Y.id]; 1560 delete Y.Env; 1561 delete Y.config; 1562 } 1563 1564 /** 1565 Safe `instanceof` wrapper that works around a memory leak in IE when the 1566 object being tested is `window` or `document`. 1567 1568 Unless you are testing objects that may be `window` or `document`, you 1569 should use the native `instanceof` operator instead of this method. 1570 1571 @method instanceOf 1572 @param {Object} o Object to check. 1573 @param {Object} type Class to check against. 1574 @since 3.3.0 1575 **/ 1576}; 1577 1578 YUI.prototype = proto; 1579 1580 // inheritance utilities are not available yet 1581 for (prop in proto) { 1582 if (proto.hasOwnProperty(prop)) { 1583 YUI[prop] = proto[prop]; 1584 } 1585 } 1586 1587 /** 1588 Applies a configuration to all YUI instances in this execution context. 1589 1590 The main use case for this method is in "mashups" where several third-party 1591 scripts need to write to a global YUI config, but cannot share a single 1592 centrally-managed config object. This way they can all call 1593 `YUI.applyConfig({})` instead of overwriting the single global config. 1594 1595 @example 1596 1597 YUI.applyConfig({ 1598 modules: { 1599 davglass: { 1600 fullpath: './davglass.js' 1601 } 1602 } 1603 }); 1604 1605 YUI.applyConfig({ 1606 modules: { 1607 foo: { 1608 fullpath: './foo.js' 1609 } 1610 } 1611 }); 1612 1613 YUI().use('davglass', function (Y) { 1614 // Module davglass will be available here. 1615 }); 1616 1617 @method applyConfig 1618 @param {Object} o Configuration object to apply. 1619 @static 1620 @since 3.5.0 1621 **/ 1622 YUI.applyConfig = function(o) { 1623 if (!o) { 1624 return; 1625 } 1626 //If there is a GlobalConfig, apply it first to set the defaults 1627 if (YUI.GlobalConfig) { 1628 this.prototype.applyConfig.call(this, YUI.GlobalConfig); 1629 } 1630 //Apply this config to it 1631 this.prototype.applyConfig.call(this, o); 1632 //Reset GlobalConfig to the combined config 1633 YUI.GlobalConfig = this.config; 1634 }; 1635 1636 // set up the environment 1637 YUI._init(); 1638 1639 if (hasWin) { 1640 add(doc, 'DOMContentLoaded', handleReady); 1641 1642 // add a window load event at load time so we can capture 1643 // the case where it fires before dynamic loading is 1644 // complete. 1645 add(window, 'load', handleLoad); 1646 } else { 1647 handleReady(); 1648 handleLoad(); 1649 } 1650 1651 YUI.Env.add = add; 1652 YUI.Env.remove = remove; 1653 1654 /*global exports*/
1655 // Support the CommonJS method for exporting our single global 1656 if (typeof exports == 'object') { 1657 exports.YUI = YUI; 1658 /** 1659 * Set a method to be called when `Get.script` is called in Node.js 1660 * `Get` will open the file, then pass it's content and it's path 1661 * to this method before attaching it. Commonly used for code coverage 1662 * instrumentation. <strong>Calling this multiple times will only 1663 * attach the last hook method</strong>. This method is only 1664 * available in Node.js. 1665 * @method setLoadHook 1666 * @static 1667 * @param {Function} fn The function to set 1668 * @param {String} fn.data The content of the file 1669 * @param {String} fn.path The file path of the file 1670 */ 1671 YUI.setLoadHook = function(fn) { 1672 YUI._getLoadHook = fn; 1673 }; 1674 /** 1675 * Load hook for `Y.Get.script` in Node.js, see `YUI.setLoadHook` 1676 * @method _getLoadHook 1677 * @private 1678 * @param {String} data The content of the file 1679 * @param {String} path The file path of the file 1680 */ 1681 YUI._getLoadHook = null; 1682 } 1683 1684 YUI.Env[VERSION] = {}; 1685}()); 1686 1687 1688/** 1689Config object that contains all of the configuration options for 1690this `YUI` instance. 1691 1692This object is supplied by the implementer when instantiating YUI. Some 1693properties have default values if they are not supplied by the implementer. 1694 1695This object should not be updated directly because some values are cached. Use 1696`applyConfig()` to update the config object on a YUI instance that has already 1697been configured. 1698 1699@class config 1700@static 1701**/ 1702 1703/** 1704If `true` (the default), YUI will "bootstrap" the YUI Loader and module metadata 1705if they're needed to load additional dependencies and aren't already available. 1706 1707Setting this to `false` will prevent YUI from automatically loading the Loader 1708and module metadata, so you will need to manually ensure that they're available 1709or handle dependency resolution yourself. 1710 1711@property {Boolean} bootstrap 1712@default true 1713**/ 1714 1715/** 1716 1717@property {Object} filters 1718**/ 1719 1720/** 1721If `true`, YUI will use a combo handler to load multiple modules in as few 1722requests as possible. 1723 1724The YUI CDN (which YUI uses by default) supports combo handling, but other 1725servers may not. If the server from which you're loading YUI does not support 1726combo handling, set this to `false`. 1727 1728Providing a value for the `base` config property will cause `combine` to default 1729to `false` instead of `true`. 1730 1731@property {Boolean} combine 1732@default true 1733*/ 1734 1735/** 1736Array of module names that should never be dynamically loaded. 1737 1738@property {String[]} ignore 1739**/ 1740 1741/** 1742Array of module names that should always be loaded when required, even if 1743already present on the page. 1744 1745@property {String[]} force
1746**/ 1747 1748/** 1749DOM element or id that should be used as the insertion point for dynamically 1750added `<script>` and `<link>` nodes. 1751 1752@property {HTMLElement|String} insertBefore 1753**/ 1754 1755/** 1756Object hash containing attributes to add to dynamically added `<script>` nodes. 1757 1758@property {Object} jsAttributes 1759**/ 1760 1761/** 1762Object hash containing attributes to add to dynamically added `<link>` nodes. 1763 1764@property {Object} cssAttributes 1765**/ 1766 1767/** 1768Timeout in milliseconds before a dynamic JS or CSS request will be considered a 1769failure. If not set, no timeout will be enforced. 1770 1771@property {Number} timeout 1772**/ 1773 1774/** 1775A hash of module definitions to add to the list of available YUI modules. These 1776modules can then be dynamically loaded via the `use()` method. 1777 1778This is a hash in which keys are module names and values are objects containing 1779module metadata. 1780 1781See `Loader.addModule()` for the supported module metadata fields. Also see 1782`groups`, which provides a way to configure the base and combo spec for a set of 1783modules. 1784 1785@example 1786 1787 modules: { 1788 mymod1: { 1789 requires: ['node'], 1790 fullpath: '/mymod1/mymod1.js' 1791 }, 1792 1793 mymod2: { 1794 requires: ['mymod1'], 1795 fullpath: '/mymod2/mymod2.js' 1796 }, 1797 1798 mymod3: '/js/mymod3.js', 1799 mycssmod: '/css/mycssmod.css' 1800 } 1801 1802@property {Object} modules 1803**/ 1804 1805/** 1806Aliases are dynamic groups of modules that can be used as shortcuts. 1807 1808@example 1809 1810 YUI({ 1811 aliases: { 1812 davglass: [ 'node', 'yql', 'dd' ], 1813 mine: [ 'davglass', 'autocomplete'] 1814 } 1815 }).use('mine', function (Y) { 1816 // Node, YQL, DD & AutoComplete available here. 1817 }); 1818 1819@property {Object} aliases 1820**/ 1821 1822/** 1823A hash of module group definitions. 1824 1825For each group you can specify a list of modules and the base path and 1826combo spec to use when dynamically loading the modules. 1827 1828@example 1829 1830 groups: { 1831 yui2: { 1832 // specify whether or not this group has a combo service 1833 combine: true, 1834 1835 // The comboSeperator to use with this group's combo handler 1836 comboSep: ';', 1837 1838 // The maxURLLength for this server 1839 maxURLLength: 500, 1840 1841 // the base path for non-combo paths 1842 base: 'http://yui.yahooapis.com/2.8.0r4/build/', 1843 1844 // the path to the combo service 1845 comboBase: 'http://yui.yahooapis.com/combo?', 1846 1847 // a fragment to prepend to the path attribute when 1848 // when building combo urls 1849 root: '2.8.0r4/build/', 1850 1851 // the module definitions 1852 modules: { 1853 yui2_yde: { 1854 path: "yahoo-dom-event/yahoo-dom-event.js" 1855 }, 1856 yui2_anim: { 1857 path: "animation/animation.js", 1858 requires: ['yui2_yde'] 1859 } 1860 } 1861 } 1862 } 1863 1864@property {Object} groups 1865**/ 1866 1867/** 1868Path to the Loader JS file, relative to the `base` path. 1869 1870This is used to dynamically bootstrap the Loader when it's needed and isn't yet 1871available. 1872 1873@property {String} loaderPath 1874@default "loader/loader-min.js" 1875**/ 1876 1877/** 1878If `true`, YUI will attempt to load CSS dependencies and skins. Set this to 1879`false` to prevent YUI from loading any CSS, or set it to the string `"force"` 1880to force CSS dependencies to be loaded even if their associated JS modules are 1881already loaded. 1882 1883@property {Boolean|String} fetchCSS 1884@default true 1885**/ 1886 1887/** 1888Default gallery version used to build gallery module urls. 1889 1890@property {String} gallery 1891@since 3.1.0 1892**/ 1893 1894/** 1895Default YUI 2 version used to build YUI 2 module urls. 1896 1897This is used for intrinsic YUI 2 support via the 2in3 project. Also see the 1898`2in3` config for pulling different revisions of the wrapped YUI 2 modules. 1899 1900@property {String} yui2 1901@default "2.9.0" 1902@since 3.1.0 1903**/ 1904 1905/** 1906Revision number of YUI 2in3 modules that should be used when loading YUI 2in3. 1907 1908@property {String} 2in3 1909@default "4" 1910@since 3.1.0 1911**/ 1912 1913/** 1914Alternate console log function that should be used in environments without a 1915supported native console. This function is executed with the YUI instance as its 1916`this` object. 1917 1918@property {Function} logFn 1919@since 3.1.0
1920**/ 1921 1922/** 1923The minimum log level to log messages for. Log levels are defined 1924incrementally. Messages greater than or equal to the level specified will 1925be shown. All others will be discarded. The order of log levels in 1926increasing priority is: 1927 1928 debug 1929 info 1930 warn 1931 error 1932 1933@property {String} logLevel 1934@default 'debug' 1935@since 3.10.0 1936**/ 1937 1938/** 1939Callback to execute when `Y.error()` is called. It receives the error message 1940and a JavaScript error object if one was provided. 1941 1942This function is executed with the YUI instance as its `this` object. 1943 1944Returning `true` from this function will prevent an exception from being thrown. 1945 1946@property {Function} errorFn 1947@param {String} errorFn.msg Error message 1948@param {Object} [errorFn.err] Error object (if one was provided). 1949@since 3.2.0 1950**/ 1951 1952/** 1953A callback to execute when Loader fails to load one or more resources. 1954 1955This could be because of a script load failure. It could also be because a 1956module fails to register itself when the `requireRegistration` config is `true`. 1957 1958If this function is defined, the `use()` callback will only be called when the 1959loader succeeds. Otherwise, `use()` will always executes unless there was a 1960JavaScript error when attaching a module. 1961 1962@property {Function} loadErrorFn 1963@since 3.3.0 1964**/ 1965 1966/** 1967If `true`, Loader will expect all loaded scripts to be first-class YUI modules 1968that register themselves with the YUI global, and will trigger a failure if a 1969loaded script does not register a YUI module. 1970 1971@property {Boolean} requireRegistration 1972@default false 1973@since 3.3.0 1974**/ 1975 1976/** 1977Cache serviced use() requests. 1978 1979@property {Boolean} cacheUse 1980@default true 1981@since 3.3.0 1982@deprecated No longer used. 1983**/ 1984 1985/** 1986Whether or not YUI should use native ES5 functionality when available for 1987features like `Y.Array.each()`, `Y.Object()`, etc. 1988 1989When `false`, YUI will always use its own fallback implementations instead of 1990relying on ES5 functionality, even when ES5 functionality is available. 1991 1992@property {Boolean} useNativeES5 1993@default true 1994@since 3.5.0 1995**/ 1996 1997/** 1998 * Leverage native JSON stringify if the browser has a native 1999 * implementation. In general, this is a good idea. See the Known Issues 2000 * section in the JSON user guide for caveats. The default value is true 2001 * for browsers with native JSON support. 2002 * 2003 * @property useNativeJSONStringify 2004 * @type Boolean 2005 * @default true 2006 * @since 3.8.0 2007 */ 2008 2009 /** 2010 * Leverage native JSON parse if the browser has a native implementation. 2011 * In general, this is a good idea. See the Known Issues section in the 2012 * JSON user guide for caveats. The default value is true for browsers with 2013 * native JSON support. 2014 * 2015 * @property useNativeJSONParse 2016 * @type Boolean 2017 * @default true 2018 * @since 3.8.0 2019 */ 2020 2021/** 2022Delay the `use` callback until a specific event has passed (`load`, `domready`, `contentready` or `available`) 2023 2024@property {Object|String} delayUntil 2025@since 3.6.0 2026@example 2027 2028You can use `load` or `domready` strings by default: 2029 2030 YUI({ 2031 delayUntil: 'domready' 2032 }, function (Y) { 2033 // This will not execute until 'domeready' occurs. 2034 }); 2035 2036Or you can delay until a node is available (with `available` or `contentready`): 2037 2038 YUI({ 2039 delayUntil: { 2040 event: 'available', 2041 args : '#foo' 2042 } 2043 }, function (Y) { 2044 // This will not execute until a node matching the selector "#foo" is 2045 // available in the DOM. 2046 }); 2047 2048**/ 2049YUI.add('yui-base', function (Y, NAME) { 2050 2051/* 2052 * YUI stub 2053 * @module yui 2054 * @submodule yui-base 2055 */ 2056/** 2057 * The YUI module contains the components required for building the YUI 2058 * seed file. This includes the script loading mechanism, a simple queue, 2059 * and the core utilities for the library. 2060 * @module yui 2061 * @submodule yui-base 2062 */ 2063 2064/** 2065 * Provides core language utilites and extensions used throughout YUI. 2066 * 2067 * @class Lang 2068 * @static 2069 */ 2070 2071var L = Y.Lang || (Y.Lang = {}), 2072 2073STRING_PROTO = String.prototype, 2074TOSTRING = Object.prototype.toString, 2075 2076TYPES = { 2077 'undefined' : 'undefined', 2078 'number' : 'number', 2079 'boolean' : 'boolean', 2080 'string' : 'string', 2081 '[object Function]': 'function', 2082 '[object RegExp]' : 'regexp', 2083 '[object Array]' : 'array', 2084 '[object Date]' : 'date', 2085 '[object Error]' : 'error' 2086}, 2087 2088SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g, 2089 2090WHITESPACE = "\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", 2091WHITESPACE_CLASS = "[\x09-\x0D\x20\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+", 2092TRIM_LEFT_REGEX = new RegExp("^" + WHITESPACE_CLASS), 2093TRIM_RIGHT_REGEX = new RegExp(WHITESPACE_CLASS + "$"), 2094TRIMREGEX = new RegExp(TRIM_LEFT_REGEX.source + "|" + TRIM_RIGHT_REGEX.source, "g"), 2095 2096NATIVE_FN_REGEX = /\{\s*\[(?:native code|function)\]\s*\}/i; 2097 2098// -- Protected Methods -------------------------------------------------------- 2099 2100/** 2101Returns `true` if the given function appears to be implemented in native code, 2102`false` otherwise. Will always return `false` -- even in ES5-capable browsers -- 2103if the `useNativeES5` YUI config option is set to `false`. 2104 2105This isn't guaranteed to be 100% accurate and won't work for anything other than 2106functions, but it can be useful for determining whether a function like 2107`Array.prototype.forEach` is native or a JS shim provided by another library. 2108 2109There's a great article by @kangax discussing certain flaws with this technique: 2110<http://perfectionkills.com/detecting-built-in-host-methods/> 2111 2112While his points are valid, it's still possible to benefit from this function 2113as long as it's used carefully and sparingly, and in such a way that false 2114negatives have minimal consequences. It's used internally to avoid using 2115potentially broken non-native ES5 shims that have been added to the page b
2115y 2116other libraries. 2117 2118@method _isNative 2119@param {Function} fn Function to test. 2120@return {Boolean} `true` if _fn_ appears to be native, `false` otherwise. 2121@static 2122@protected 2123@since 3.5.0 2124**/ 2125L._isNative = function (fn) { 2126 return !!(Y.config.useNativeES5 && fn && NATIVE_FN_REGEX.test(fn)); 2127}; 2128 2129// -- Public Methods ----------------------------------------------------------- 2130 2131/** 2132 * Determines whether or not the provided item is an array. 2133 * 2134 * Returns `false` for array-like collections such as the function `arguments` 2135 * collection or `HTMLElement` collections. Use `Y.Array.test()` if you want to 2136 * test for an array-like collection. 2137 * 2138 * @method isArray 2139 * @param o The object to test. 2140 * @return {boolean} true if o is an array. 2141 * @static 2142 */ 2143L.isArray = L._isNative(Array.isArray) ? Array.isArray : function (o) { 2144 return L.type(o) === 'array'; 2145}; 2146 2147/** 2148 * Determines whether or not the provided item is a boolean. 2149 * @method isBoolean 2150 * @static 2151 * @param o The object to test. 2152 * @return {boolean} true if o is a boolean. 2153 */ 2154L.isBoolean = function(o) { 2155 return typeof o === 'boolean'; 2156}; 2157 2158/** 2159 * Determines whether or not the supplied item is a date instance. 2160 * @method isDate 2161 * @static 2162 * @param o The object to test. 2163 * @return {boolean} true if o is a date. 2164 */ 2165L.isDate = function(o) { 2166 return L.type(o) === 'date' && o.toString() !== 'Invalid Date' && !isNaN(o); 2167}; 2168 2169/** 2170 * <p> 2171 * Determines whether or not the provided item is a function. 2172 * Note: Internet Explorer thinks certain functions are objects: 2173 * </p> 2174 * 2175 * <pre> 2176 * var obj = document.createElement("object"); 2177 * Y.Lang.isFunction(obj.getAttribute) // reports false in IE 2178 * 2179 * var input = document.createElement("input"); // append to body 2180 * Y.Lang.isFunction(input.focus) // reports false in IE 2181 * </pre> 2182 * 2183 * <p> 2184 * You will have to implement additional tests if these functions 2185 * matter to you. 2186 * </p> 2187 * 2188 * @method isFunction 2189 * @static 2190 * @param o The object to test. 2191 * @return {boolean} true if o is a function. 2192 */ 2193L.isFunction = function(o) { 2194 return L.type(o) === 'function'; 2195}; 2196 2197/** 2198 * Determines whether or not the provided item is null. 2199 * @method isNull 2200 * @static 2201 * @param o The object to test. 2202 * @return {boolean} true if o is null. 2203 */ 2204L.isNull = function(o) { 2205 return o === null; 2206}; 2207 2208/** 2209 * Determines whether or not the provided item is a legal number. 2210 * @method isNumber 2211 * @static 2212 * @param o The object to test. 2213 * @return {boolean} true if o is a number. 2214 */ 2215L.isNumber = function(o) { 2216 return typeof o === 'number' && isFinite(o); 2217}; 2218 2219/** 2220 * Determines whether or not the provided item is of type object 2221 * or function. Note that arrays are also objects, so 2222 * <code>Y.Lang.isObject([]) === true</code>. 2223 * @method isObject 2224 * @static 2225 * @param o The object to test. 2226 * @param failfn {boolean} fail if the input is a function. 2227 * @return {boolean} true if o is an object. 2228 * @see isPlainObject 2229 */ 2230L.isObject = function(o, failfn) { 2231 var t = typeof o; 2232 return (o && (t === 'object' || 2233 (!failfn && (t === 'function' || L.isFunction(o))))) || false; 2234}; 2235 2236/** 2237 * Determines whether or not the provided value is a regexp. 2238 * @method isRegExp 2239 * @static 2240 * @param value The value or object to test. 2241 * @return {boolean} true if value is a regexp. 2242 */ 2243L.isRegExp = function(value) { 2244 return L.type(value) === 'regexp'; 2245}; 2246 2247/** 2248 * Determines whether or not the provided item is a string. 2249 * @method isString 2250 * @static 2251 * @param o The object to test. 2252 * @return {boolean} true if o is a string. 2253 */ 2254L.isString = function(o) { 2255 return typeof o === 'string'; 2256}; 2257 2258/** 2259 * Determines whether or not the provided item is undefined. 2260 * @method isUndefined 2261 * @static 2262 * @param o The object to test. 2263 * @return {boolean} true if o is undefined. 2264 */ 2265L.isUndefined = function(o) { 2266 return typeof o === 'undefined'; 2267}; 2268 2269/** 2270 * A convenience method for detecting a legitimate non-null value. 2271 * Returns false for null/undefined/NaN, true for other values, 2272 * including 0/false/'' 2273 * @method isValue 2274 * @static 2275 * @param o The item to test. 2276 * @return {boolean} true if it is not null/undefined/NaN || false. 2277 */ 2278L.isValue = function(o) { 2279 var t = L.type(o); 2280 2281 switch (t) { 2282 case 'number': 2283 return isFinite(o); 2284 2285 case 'null': // fallthru 2286 case 'undefined': 2287 return false;
2288 2289 default: 2290 return !!t; 2291 } 2292}; 2293 2294/** 2295 * Returns the current time in milliseconds. 2296 * 2297 * @method now 2298 * @return {Number} Current time in milliseconds. 2299 * @static 2300 * @since 3.3.0 2301 */ 2302L.now = Date.now || function () { 2303 return new Date().getTime(); 2304}; 2305 2306/** 2307 * Performs `{placeholder}` substitution on a string. The object passed as the 2308 * second parameter provides values to replace the `{placeholder}`s. 2309 * `{placeholder}` token names must match property names of the object. For example, 2310 * 2311 *`var greeting = Y.Lang.sub("Hello, {who}!", { who: "World" });` 2312 * 2313 * `{placeholder}` tokens that are undefined on the object map will be left 2314 * in tact (leaving unsightly `{placeholder}`'s in the output string). 2315 * 2316 * @method sub 2317 * @param {string} s String to be modified. 2318 * @param {object} o Object containing replacement values. 2319 * @return {string} the substitute result. 2320 * @static 2321 * @since 3.2.0 2322 */ 2323L.sub = function(s, o) { 2324 2325 /** 2326 Finds the value of `key` in given object. 2327 If the key has a 'dot' notation e.g. 'foo.bar.baz', the function will 2328 try to resolve this path if it doesn't exist as a property 2329 @example 2330 value({ 'a.b': 1, a: { b: 2 } }, 'a.b'); // 1 2331 value({ a: { b: 2 } } , 'a.b'); // 2 2332 @param {Object} obj A key/value pairs object 2333 @param {String} key 2334 @return {Any} 2335 @private 2336 **/ 2337 function value(obj, key) { 2338 2339 var subkey; 2340 2341 if ( typeof obj[key] !== 'undefined' ) { 2342 return obj[key]; 2343 } 2344 2345 key = key.split('.'); // given 'a.b.c' 2346 subkey = key.slice(1).join('.'); // 'b.c' 2347 key = key[0]; // 'a' 2348 2349 // special case for null as typeof returns object and we don't want that. 2350 if ( subkey && typeof obj[key] === 'object' && obj[key] !== null ) { 2351 return value(obj[key], subkey); 2352 } 2353 } 2354 2355 return s.replace ? s.replace(SUBREGEX, function (match, key) { 2356 var val = key.indexOf('.')>-1 ? value(o, key) : o[key]; 2357 return typeof val === 'undefined' ? match : val; 2358 }) : s; 2359}; 2360 2361/** 2362 * Returns a string without any leading or trailing whitespace. If 2363 * the input is not a string, the input will be returned untouched. 2364 * @method trim 2365 * @static 2366 * @param s {string} the string to trim. 2367 * @return {string} the trimmed string. 2368 */ 2369L.trim = L._isNative(STRING_PROTO.trim) && !WHITESPACE.trim() ? function(s) { 2370 return s && s.trim ? s.trim() : s; 2371} : function (s) { 2372 try { 2373 return s.replace(TRIMREGEX, ''); 2374 } catch (e) { 2375 return s; 2376 } 2377}; 2378 2379/** 2380 * Returns a string without any leading whitespace. 2381 * @method trimLeft 2382 * @static 2383 * @param s {string} the string to trim. 2384 * @return {string} the trimmed string. 2385 */ 2386L.trimLeft = L._isNative(STRING_PROTO.trimLeft) && !WHITESPACE.trimLeft() ? function (s) { 2387 return s.trimLeft(); 2388} : function (s) { 2389 return s.replace(TRIM_LEFT_REGEX, ''); 2390}; 2391 2392/** 2393 * Returns a string without any trailing whitespace. 2394 * @method trimRight 2395 * @static 2396 * @param s {string} the string to trim. 2397 * @return {string} the trimmed string. 2398 */ 2399L.trimRight = L._isNative(STRING_PROTO.trimRight) && !WHITESPACE.trimRight() ? function (s) { 2400 return s.trimRight(); 2401} : function (s) { 2402 return s.replace(TRIM_RIGHT_REGEX, ''); 2403}; 2404 2405/** 2406Returns one of the following strings, representing the type of the item passed 2407in: 2408 2409 * "array" 2410 * "boolean" 2411 * "date" 2412 * "error" 2413 * "function" 2414 * "null" 2415 * "number" 2416 * "object" 2417 * "regexp" 2418 * "string" 2419 * "undefined" 2420 2421Known issues: 2422 2423 * `typeof HTMLElementCollection` returns function in Safari, but 2424 `Y.Lang.type()` reports "object", which could be a good thing -- 2425 but it actually caused the logic in <code>Y.Lang.isObject</code> to fail. 2426 2427@method type 2428@param o the item to test. 2429@return {string} the detected type. 2430@static 2431**/ 2432L.type = function(o) { 2433 return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null'); 2434}; 2435/** 2436@module yui 2437@submodule yui-base 2438*/ 2439 2440var Lang = Y.Lang, 2441 Native = Array.prototype, 2442 2443 hasOwn = Object.prototype.hasOwnProperty; 2444 2445/** 2446Provides utility methods for working with arrays. Additional array helpers can 2447be found in the `collection` and `array-extras` modules. 2448 2449`Y.Array(thing)` returns a native array created from _thing_. Depending on 2450_thing_'s type, one of the following will happen: 2451 2452 * Arrays are returned unmodified unless a non-zero _startIndex_ is 2453 specified. 2454 * Array-like collections (see `Array.test()`) are converted to arrays. 2455 * For everything else, a new array is created with _thing_ as the sole 2456 item. 2457 2458Note: elements that are also collections, such as `<form>` and `<select>` 2459elements, are not automatically converted to arrays. To force a conversion, 2460pass `true` as the value of the _force_ parameter. 2461 2462@class Array 2463@constructor 2464@param {Any} thing The thing to arrayify. 2465@param {Number} [startIndex=0] If non-zero and _thing_ is an array or array-like 2466 collection, a subset of items starting at the specified index will be 2467 returned. 2468@param {Boolean} [force=false] If `true`, _thing_ will be treated as an 2469 array-like collection no matter what. 2470@return {Array} A native array created from _thing_, according to the rules 2471 described above. 2472**/ 2473function YArray(thing, startIndex, force) { 2474 var len, result; 2475 2476 /*jshint expr: true*/ 2477 startIndex || (startIndex = 0); 2478 2479 if (force || YArray.test(thing)) { 2480 // IE throws when trying to slice HTMLElement collections. 2481 try { 2482 return Native.slice.call(thing, startIndex); 2483 } catch (ex) { 2484 result = []; 2485 2486 for (len = thing.length; startIndex < len; ++startIndex) { 2487 result.push(thing[startIndex]); 2488 } 2489 2490 return result; 2491 } 2492 } 2493 2494 return [thing]; 2495} 2496 2497Y.Array = YArray; 2498 2499/**
2500Dedupes an array of strings, returning an array that's guaranteed to contain 2501only one copy of a given string. 2502 2503This method differs from `Array.unique()` in that it's optimized for use only 2504with arrays consisting entirely of strings or entirely of numbers, whereas 2505`unique` may be used with other value types (but is slower). 2506 2507Using `dedupe()` with values other than strings or numbers, or with arrays 2508containing a mix of strings and numbers, may result in unexpected behavior. 2509 2510@method dedupe 2511@param {String[]|Number[]} array Array of strings or numbers to dedupe. 2512@return {Array} Copy of _array_ containing no duplicate values. 2513@static 2514@since 3.4.0 2515**/ 2516YArray.dedupe = Lang._isNative(Object.create) ? function (array) { 2517 var hash = Object.create(null), 2518 results = [], 2519 i, item, len; 2520 2521 for (i = 0, len = array.length; i < len; ++i) { 2522 item = array[i]; 2523 2524 if (!hash[item]) { 2525 hash[item] = 1; 2526 results.push(item); 2527 } 2528 } 2529 2530 return results; 2531} : function (array) { 2532 var hash = {}, 2533 results = [], 2534 i, item, len; 2535 2536 for (i = 0, len = array.length; i < len; ++i) { 2537 item = array[i]; 2538 2539 if (!hasOwn.call(hash, item)) { 2540 hash[item] = 1; 2541 results.push(item); 2542 } 2543 } 2544 2545 return results; 2546}; 2547 2548/** 2549Executes the supplied function on each item in the array. This method wraps 2550the native ES5 `Array.forEach()` method if available. 2551 2552@method each 2553@param {Array} array Array to iterate. 2554@param {Function} fn Function to execute on each item in the array. The function 2555 will receive the following arguments: 2556 @param {Any} fn.item Current array item. 2557 @param {Number} fn.index Current array index. 2558 @param {Array} fn.array Array being iterated. 2559@param {Object} [thisObj] `this` object to use when calling _fn_. 2560@return {YUI} The YUI instance. 2561@static 2562**/ 2563YArray.each = YArray.forEach = Lang._isNative(Native.forEach) ? function (array, fn, thisObj) { 2564 Native.forEach.call(array || [], fn, thisObj || Y); 2565 return Y; 2566} : function (array, fn, thisObj) { 2567 for (var i = 0, len = (array && array.length) || 0; i < len; ++i) { 2568 if (i in array) { 2569 fn.call(thisObj || Y, array[i], i, array); 2570 } 2571 } 2572 2573 return Y; 2574}; 2575 2576/** 2577Alias for `each()`. 2578 2579@method forEach 2580@static 2581**/ 2582 2583/** 2584Returns an object using the first array as keys and the second as values. If 2585the second array is not provided, or if it doesn't contain the same number of 2586values as the first array, then `true` will be used in place of the missing 2587values. 2588 2589@example 2590 2591 Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']); 2592 // => {a: 'foo', b: 'bar', c: true} 2593 2594@method hash 2595@param {String[]} keys Array of strings to use as keys. 2596@param {Array} [values] Array to use as values. 2597@return {Object} Hash using the first array as keys and the second as values. 2598@static 2599**/ 2600YArray.hash = function (keys, values) { 2601 var hash = {}, 2602 vlen = (values && values.length) || 0, 2603 i, len; 2604 2605 for (i = 0, len = keys.length; i < len; ++i) { 2606 if (i in keys) { 2607 hash[keys[i]] = vlen > i && i in values ? values[i] : true; 2608 } 2609 } 2610 2611 return hash; 2612}; 2613 2614/** 2615Returns the index of the first item in the array that's equal (using a strict 2616equality check) to the specified _value_, or `-1` if the value isn't found. 2617 2618This method wraps the native ES5 `Array.indexOf()` method if available. 2619 2620@method indexOf 2621@param {Array} array Array to search. 2622@param {Any} value Value to search for. 2623@param {Number} [from=0] The index at which to begin the search. 2624@return {Number} Index of the item strictly equal to _value_, or `-1` if not 2625 found. 2626@static 2627**/ 2628YArray.indexOf = Lang._isNative(Native.indexOf) ? function (array, value, from) { 2629 return Native.indexOf.call(array, value, from); 2630} : function (array, value, from) { 2631 // http://es5.github.com/#x15.4.4.14 2632 var len = array.length; 2633 2634 from = +from || 0; 2635 from = (from > 0 || -1) * Math.floor(Math.abs(from)); 2636 2637 if (from < 0) { 2638 from += len; 2639 2640 if (from < 0) { 2641 from = 0; 2642 } 2643 } 2644 2645 for (; from < len; ++from) { 2646 if (from in array && array[from] === value) { 2647 return from; 2648 } 2649 } 2650 2651 return -1; 2652}; 2653 2654/** 2655Numeric sort convenience function. 2656 2657The native `Array.prototype.sort()` function converts values to strings and 2658sorts them in lexicographic order, which is unsuitable for sorting numeric 2659values. Provide `Array.numericSort` as a custom sort function when you want 2660to sort values in numeric order. 2661 2662@example 2663 2664 [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort); 2665 // => [4, 8, 15, 16, 23, 42] 2666 2667@method numericSort 2668@param {Number} a First value to compare. 2669@param {Number} b Second value to compare. 2670@return {Number} Difference between _a_ and _b_. 2671@static 2672**/ 2673YArray.numericSort = function (a, b) { 2674 return a - b; 2675}; 2676 2677/** 2678Executes the supplied function on each item in the array. Returning a truthy 2679value from the function will stop the processing of remaining items. 2680 2681@method some 2682@param {Array} array Array to iterate over. 2683@param {Function} fn Function to execute on each item. The function will receive 2684 the following arguments: 2685 @param {Any} fn.value Current array item. 2686 @param {Number} fn.index Current array index. 2687 @param {Array} fn.array Array being iterated over. 2688@param {Object} [thisObj] `this` object to use when calling _fn_. 2689@return {Boolean} `true` if the function returns a truthy value on any of the 2690 items in the array; `false` otherwise. 2691@static 2692**/ 2693YArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) { 2694 return Native.some.call(array, fn, thisObj); 2695} : function (array, fn, thisObj) { 2696 for (var i = 0, len = array.length; i < len; ++i) { 2697 if (i in array && fn.call(thisObj, array[i], i, array)) { 2698 return true; 2699 } 2700 } 2701 2702 return false;
2703}; 2704 2705/** 2706Evaluates _obj_ to determine if it's an array, an array-like collection, or 2707something else. This is useful when working with the function `arguments` 2708collection and `HTMLElement` collections. 2709 2710Note: This implementation doesn't consider elements that are also 2711collections, such as `<form>` and `<select>`, to be array-like. 2712 2713@method test 2714@param {Object} obj Object to test. 2715@return {Number} A number indicating the results of the test: 2716 2717 * 0: Neither an array nor an array-like collection. 2718 * 1: Real array. 2719 * 2: Array-like collection. 2720 2721@static 2722**/ 2723YArray.test = function (obj) { 2724 var result = 0; 2725 2726 if (Lang.isArray(obj)) { 2727 result = 1; 2728 } else if (Lang.isObject(obj)) { 2729 try { 2730 // indexed, but no tagName (element) or scrollTo/document (window. From DOM.isWindow test which we can't use here), 2731 // or functions without apply/call (Safari 2732 // HTMLElementCollection bug). 2733 if ('length' in obj && !obj.tagName && !(obj.scrollTo && obj.document) && !obj.apply) { 2734 result = 2; 2735 } 2736 } catch (ex) {} 2737 } 2738 2739 return result; 2740}; 2741/** 2742 * The YUI module contains the components required for building the YUI 2743 * seed file. This includes the script loading mechanism, a simple queue, 2744 * and the core utilities for the library. 2745 * @module yui 2746 * @submodule yui-base 2747 */ 2748 2749/** 2750 * A simple FIFO queue. Items are added to the Queue with add(1..n items) and 2751 * removed using next(). 2752 * 2753 * @class Queue 2754 * @constructor 2755 * @param {MIXED} item* 0..n items to seed the queue. 2756 */ 2757function Queue() { 2758 this._init(); 2759 this.add.apply(this, arguments); 2760} 2761 2762Queue.prototype = { 2763 /** 2764 * Initialize the queue 2765 * 2766 * @method _init 2767 * @protected 2768 */ 2769 _init: function() { 2770 /** 2771 * The collection of enqueued items 2772 * 2773 * @property _q 2774 * @type Array 2775 * @protected 2776 */ 2777 this._q = []; 2778 }, 2779 2780 /** 2781 * Get the next item in the queue. FIFO support 2782 * 2783 * @method next 2784 * @return {MIXED} the next item in the queue. 2785 */ 2786 next: function() { 2787 return this._q.shift(); 2788 }, 2789 2790 /** 2791 * Get the last in the queue. LIFO support. 2792 * 2793 * @method last 2794 * @return {MIXED} the last item in the queue. 2795 */ 2796 last: function() { 2797 return this._q.pop(); 2798 }, 2799 2800 /** 2801 * Add 0..n items to the end of the queue. 2802 * 2803 * @method add 2804 * @param {MIXED} item* 0..n items. 2805 * @return {object} this queue. 2806 */ 2807 add: function() { 2808 this._q.push.apply(this._q, arguments); 2809 2810 return this; 2811 }, 2812 2813 /** 2814 * Returns the current number of queued items. 2815 * 2816 * @method size 2817 * @return {Number} The size. 2818 */ 2819 size: function() { 2820 return this._q.length; 2821 } 2822}; 2823 2824Y.Queue = Queue; 2825 2826YUI.Env._loaderQueue = YUI.Env._loaderQueue || new Queue(); 2827 2828/** 2829The YUI module contains the components required for building the YUI seed file. 2830This includes the script loading mechanism, a simple queue, and the core 2831utilities for the library. 2832 2833@module yui 2834@submodule yui-base 2835**/ 2836 2837var CACHED_DELIMITER = '__', 2838 2839 hasOwn = Object.prototype.hasOwnProperty, 2840 isObject = Y.Lang.isObject; 2841 2842/** 2843Returns a wrapper for a function which caches the return value of that function, 2844keyed off of the combined string representation of the argument values provided 2845when the wrapper is called. 2846 2847Calling this function again with the same arguments will return the cached value 2848rather than executing the wrapped function. 2849 2850Note that since the cache is keyed off of the string representation of arguments 2851passed to the wrapper function, arguments that aren't strings and don't provide 2852a meaningful `toString()` method may result in unexpected caching behavior. For 2853example, the objects `{}` and `{foo: 'bar'}` would both be converted to the 2854string `[object Object]` when used as a cache key. 2855 2856@method cached 2857@param {Function} source The function to memoize. 2858@param {Object} [cache={}] Object in which to store cached values. You may seed 2859 this object with pre-existing cached values if desired. 2860@param {any} [refetch] If supplied, this value is compared with the cached value 2861 using a `==` comparison. If the values are equal, the wrapped function is 2862 executed again even though a cached value exists. 2863@return {Function} Wrapped function. 2864@for YUI
2865**/ 2866Y.cached = function (source, cache, refetch) { 2867 /*jshint expr: true*/ 2868 cache || (cache = {}); 2869 2870 return function (arg) { 2871 var key = arguments.length > 1 ? 2872 Array.prototype.join.call(arguments, CACHED_DELIMITER) : 2873 String(arg); 2874 2875 /*jshint eqeqeq: false*/ 2876 if (!(key in cache) || (refetch && cache[key] == refetch)) { 2877 cache[key] = source.apply(source, arguments); 2878 } 2879 2880 return cache[key]; 2881 }; 2882}; 2883 2884/** 2885Returns the `location` object from the window/frame in which this YUI instance 2886operates, or `undefined` when executing in a non-browser environment 2887(e.g. Node.js). 2888 2889It is _not_ recommended to hold references to the `window.location` object 2890outside of the scope of a function in which its properties are being accessed or 2891its methods are being called. This is because of a nasty bug/issue that exists 2892in both Safari and MobileSafari browsers: 2893[WebKit Bug 34679](https://bugs.webkit.org/show_bug.cgi?id=34679). 2894 2895@method getLocation 2896@return {location} The `location` object from the window/frame in which this YUI 2897 instance operates. 2898@since 3.5.0 2899**/ 2900Y.getLocation = function () { 2901 // It is safer to look this up every time because yui-base is attached to a 2902 // YUI instance before a user's config is applied; i.e. `Y.config.win` does 2903 // not point the correct window object when this file is loaded. 2904 var win = Y.config.win; 2905 2906 // It is not safe to hold a reference to the `location` object outside the 2907 // scope in which it is being used. The WebKit engine used in Safari and 2908 // MobileSafari will "disconnect" the `location` object from the `window` 2909 // when a page is restored from back/forward history cache. 2910 return win && win.location; 2911}; 2912 2913/** 2914Returns a new object containing all of the properties of all the supplied 2915objects. The properties from later objects will overwrite those in earlier 2916objects. 2917 2918Passing in a single object will create a shallow copy of it. For a deep copy, 2919use `clone()`. 2920 2921@method merge 2922@param {Object} objects* One or more objects to merge. 2923@return {Object} A new merged object. 2924**/ 2925Y.merge = function () { 2926 var i = 0, 2927 len = arguments.length, 2928 result = {}, 2929 key, 2930 obj; 2931 2932 for (; i < len; ++i) { 2933 obj = arguments[i]; 2934 2935 for (key in obj) { 2936 if (hasOwn.call(obj, key)) { 2937 result[key] = obj[key]; 2938 } 2939 } 2940 } 2941 2942 return result; 2943}; 2944 2945/** 2946Mixes _supplier_'s properties into _receiver_. 2947 2948Properties on _receiver_ or _receiver_'s prototype will not be overwritten or 2949shadowed unless the _overwrite_ parameter is `true`, and will not be merged 2950unless the _merge_ parameter is `true`. 2951 2952In the default mode (0), only properties the supplier owns are copied (prototype 2953properties are not copied). The following copying modes are available: 2954 2955 * `0`: _Default_. Object to object. 2956 * `1`: Prototype to prototype. 2957 * `2`: Prototype to prototype and object to object. 2958 * `3`: Prototype to object. 2959 * `4`: Object to prototype. 2960 2961@method mix 2962@param {Function|Object} receiver The object or function to receive the mixed 2963 properties. 2964@param {Function|Object} supplier The object or function supplying the 2965 properties to be mixed. 2966@param {Boolean} [overwrite=false] If `true`, properties that already exist 2967 on the receiver will be overwritten with properties from the supplier. 2968@param {String[]} [whitelist] An array of property names to copy. If 2969 specified, only the whitelisted properties will be copied, and all others 2970 will be ignored. 2971@param {Number} [mode=0] Mix mode to use. See above for available modes. 2972@param {Boolean} [merge=false] If `true`, objects and arrays that already 2973 exist on the receiver will have the corresponding object/array from the 2974 supplier merged into them, rather than being skipped or overwritten. When 2975 both _overwrite_ and _merge_ are `true`, _merge_ takes precedence. 2976@return {Function|Object|YUI} The receiver, or the YUI instance if the 2977 specified receiver is falsy. 2978**/ 2979Y.mix = function(receiver, supplier, overwrite, whitelist, mode, merge) { 2980 var alwaysOverwrite, exists, from, i, key, len, to; 2981 2982 // If no supplier is given, we return the receiver. If no receiver is given, 2983 // we return Y. Returning Y doesn't make much sense to me, but it's 2984 // grandfathered in for backcompat reasons. 2985 if (!receiver || !supplier) { 2986 return receiver || Y; 2987 } 2988 2989 if (mode) { 2990 // In mode 2 (prototype to prototype and object to object), we recurse 2991 // once to do the proto to proto mix. The object to object mix will be 2992 // handled later on. 2993 if (mode === 2) { 2994 Y.mix(receiver.prototype, supplier.prototype, overwrite, 2995 whitelist, 0, merge); 2996 } 2997 2998 // Depending on which mode is specified, we may be copying from or to 2999 // the prototypes of the supplier and receiver. 3000 from = mode === 1 || mode === 3 ? supplier.prototype : supplier; 3001 to = mode === 1 || mode === 4 ? receiver.prototype : receiver; 3002 3003 // If either the supplier or receiver doesn't actually have a 3004 // prototype property, then we could end up with an undefined `from` 3005 // or `to`. If that happens, we abort and return the receiver. 3006 if (!from || !to) { 3007 return receiver; 3008 } 3009 } else { 3010 from = supplier; 3011 to = receiver; 3012 } 3013 3014 // If `overwrite` is truthy and `merge` is falsy, then we can skip a 3015 // property existence check on each iteration and save some time. 3016 alwaysOverwrite = overwrite && !merge; 3017 3018 if (whitelist) { 3019 for (i = 0, len = whitelist.length; i < len; ++i) { 3020 key = whitelist[i]; 3021 3022 // We call `Object.prototype.hasOwnProperty` instead of calling 3023 // `hasOwnProperty` on the object itself, since the object's 3024 // `hasOwnProperty` method may have been overridden or removed. 3025 // Also, some native objects don't implement a `hasOwnProperty` 3026 // method. 3027 if (!hasOwn.call(from, key)) { 3028 continue; 3029 } 3030 3031 // The `key in to` check here is (sadly) intentional for backwards 3032 // compatibility reasons. It prevents undesired shadowing of 3033 // prototype members on `to`. 3034 exists = alwaysOverwrite ? false : key in to; 3035 3036 if (merge && exists && isObject(to[key], true) 3037 && isObject(from[key], true)) { 3038 // If we're in merge mode, and the key is present on both 3039 // objects, and the value on both objects is either an object or 3040 // an array (but not a function), then we recurse to merge the 3041 // `from` value into the `to` value instead of overwriting it. 3042 // 3043 // Note: It's intentional that the whitelist isn't passed to the 3044 // recursive call here. This is legacy behavior that lots of 3045 // code still depends on. 3046 Y.mix(to[key], from[key], overwrite, null, 0, merge); 3047 } else if (overwrite || !exists) { 3048 // We're not in merge mode, so we'll only copy the `from` value 3049 // to the `to` value if we're in overwrite mode or if the 3050 // current key doesn't exist on the `to` object. 3051 to[key] = from[key]; 3052 } 3053 } 3054 } else { 3055 for (key in from) { 3056 // The code duplication here is for runtime performance reasons. 3057 // Combining whitelist and non-whitelist operations into a single 3058 // loop or breaking the shared logic out into a function both result 3059 // in worse performance, and Y.mix is critical enough that the byte 3060 // tradeoff is worth it. 3061 if (!hasOwn.call(from, key)) { 3062 continue; 3063 } 3064 3065 // The `key in to` check here is (sadly) intentional for backwards 3066 // compatibility reasons. It prevents undesired shadowing of 3067 // prototype members on `to`. 3068 exists = alwaysOverwrite ? false : key in to; 3069 3070 if (merge && exists && isObject(to[key], true) 3071 && isObject(from[key], true)) { 3072 Y.mix(to[key], from[key], overwrite, null, 0, merge); 3073 } else if (overwrite || !exists) { 3074 to[key] = from[key]; 3075 } 3076 } 3077 3078 // If this is an IE browser with the JScript enumeration bug, force 3079 // enumeration of the buggy properties by making a recursive call with 3080 // the buggy properties as the whitelist. 3081 if (Y.Object._hasEnumBug) { 3082 Y.mix(to, from, overwrite, Y.Object._forceEnum, mode, merge); 3083 } 3084 } 3085 3086 return receiver; 3087}; 3088/** 3089 * The YUI module contains the components required for building the YUI 3090 * seed file. This includes the script loading mechanism, a simple queue, 3091 * and the core utilities for the library. 3092 * @module yui 3093 * @submodule yui-base 3094 */ 3095 3096/** 3097 * Adds utilities to the YUI instance for working with objects. 3098 * 3099 * @class Object 3100 */ 3101 3102var Lang = Y.Lang, 3103 hasOwn = Object.prototype.hasOwnProperty, 3104 3105 UNDEFINED, // <-- Note the comma. We're still declaring vars. 3106 3107/** 3108 * Returns a new object that uses _obj_ as its prototype. This method wraps the 3109 * native ES5 `Object.create()` method if available, but doesn't currently 3110 * pass through `Object.create()`'s second argument (properties) in order to 3111 * ensure compatibility with older browsers. 3112 * 3113 * @method () 3114 * @param {Object} obj Prototype object. 3115 * @return {Object} New object using _obj_ as its prototype. 3116 * @static 3117 */ 3118O = Y.Object = Lang._isNative(Object.create) ? function (obj) { 3119 // We currently wrap the native Object.create instead of simply aliasing it 3120 // to ensure consistency with our fallback shim, which currently doesn't 3121 // support Object.create()'s second argument (properties). Once we have a 3122 // safe fallback for the properties arg, we can stop wrapping 3123 // Object.create(). 3124 return Object.create(obj); 3125} : (function () { 3126 // Reusable constructor function for the Object.create() shim. 3127 function F() {} 3128 3129 // The actual shim. 3130 return function (obj) { 3131 F.prototype = obj; 3132 return new F(); 3133 }; 3134}()), 3135 3136/** 3137 * Property names that IE doesn't enumerate in for..in loops, even when they 3138 * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to 3139 * manually enumerate these properties. 3140 * 3141 * @property _forceEnum
3142 * @type String[] 3143 * @protected 3144 * @static 3145 */ 3146forceEnum = O._forceEnum = [ 3147 'hasOwnProperty', 3148 'isPrototypeOf', 3149 'propertyIsEnumerable', 3150 'toString', 3151 'toLocaleString', 3152 'valueOf' 3153], 3154 3155/** 3156 * `true` if this browser has the JScript enumeration bug that prevents 3157 * enumeration of the properties named in the `_forceEnum` array, `false` 3158 * otherwise. 3159 * 3160 * See: 3161 * - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug> 3162 * - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation> 3163 * 3164 * @property _hasEnumBug 3165 * @type Boolean 3166 * @protected 3167 * @static 3168 */ 3169hasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'), 3170 3171/** 3172 * `true` if this browser incorrectly considers the `prototype` property of 3173 * functions to be enumerable. Currently known to affect Opera 11.50 and Android 2.3.x. 3174 * 3175 * @property _hasProtoEnumBug 3176 * @type Boolean 3177 * @protected 3178 * @static 3179 */ 3180hasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), 3181 3182/** 3183 * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or 3184 * exists only on _obj_'s prototype. This is essentially a safer version of 3185 * `obj.hasOwnProperty()`. 3186 * 3187 * @method owns 3188 * @param {Object} obj Object to test. 3189 * @param {String} key Property name to look for. 3190 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise. 3191 * @static 3192 */ 3193owns = O.owns = function (obj, key) { 3194 return !!obj && hasOwn.call(obj, key); 3195}; // <-- End of var declarations. 3196 3197/** 3198 * Alias for `owns()`. 3199 * 3200 * @method hasKey 3201 * @param {Object} obj Object to test. 3202 * @param {String} key Property name to look for. 3203 * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise. 3204 * @static 3205 */ 3206O.hasKey = owns; 3207 3208/** 3209 * Returns an array containing the object's enumerable keys. Does not include 3210 * prototype keys or non-enumerable keys. 3211 * 3212 * Note that keys are returned in enumeration order (that is, in the same order 3213 * that they would be enumerated by a `for-in` loop), which may not be the same 3214 * as the order in which they were defined. 3215 * 3216 * This method is an alias for the native ES5 `Object.keys()` method if 3217 * available and non-buggy. The Opera 11.50 and Android 2.3.x versions of 3218 * `Object.keys()` have an inconsistency as they consider `prototype` to be 3219 * enumerable, so a non-native shim is used to rectify the difference. 3220 * 3221 * @example 3222 * 3223 * Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'}); 3224 * // => ['a', 'b', 'c'] 3225 * 3226 * @method keys 3227 * @param {Object} obj An object. 3228 * @return {String[]} Array of keys. 3229 * @static 3230 */ 3231O.keys = Lang._isNative(Object.keys) && !hasProtoEnumBug ? Object.keys : function (obj) { 3232 if (!Lang.isObject(obj)) { 3233 throw new TypeError('Object.keys called on a non-object'); 3234 } 3235 3236 var keys = [], 3237 i, key, len; 3238 3239 if (hasProtoEnumBug && typeof obj === 'function') { 3240 for (key in obj) { 3241 if (owns(obj, key) && key !== 'prototype') { 3242 keys.push(key); 3243 } 3244 } 3245 } else { 3246 for (key in obj) { 3247 if (owns(obj, key)) { 3248 keys.push(key); 3249 } 3250 } 3251 } 3252 3253 if (hasEnumBug) { 3254 for (i = 0, len = forceEnum.length; i < len; ++i) { 3255 key = forceEnum[i]; 3256 3257 if (owns(obj, key)) { 3258 keys.push(key); 3259 } 3260 } 3261 } 3262 3263 return keys; 3264}; 3265 3266/** 3267 * Returns an array containing the values of the object's enumerable keys. 3268 * 3269 * Note that values are returned in enumeration order (that is, in the same 3270 * order that they would be enumerated by a `for-in` loop), which may not be the 3271 * same as the order in which they were defined. 3272 * 3273 * @example 3274 * 3275 * Y.Object.values({a: 'foo', b: 'bar', c: 'baz'}); 3276 * // => ['foo', 'bar', 'baz'] 3277 * 3278 * @method values 3279 * @param {Object} obj An object. 3280 * @return {Array} Array of values. 3281 * @static 3282 */ 3283O.values = function (obj) { 3284 var keys = O.keys(obj), 3285 i = 0, 3286 len = keys.length, 3287 values = []; 3288 3289 for (; i < len; ++i) { 3290 values.push(obj[keys[i]]); 3291 } 3292 3293 return values; 3294}; 3295 3296/** 3297 * Returns the number of enumerable keys owned by an object. 3298 * 3299 * @method size 3300 * @param {Object} obj An object. 3301 * @return {Number} The object's size. 3302 * @static 3303 */ 3304O.size = function (obj) { 3305 try { 3306 return O.keys(obj).length; 3307 } catch (ex) { 3308 return 0; // Legacy behavior for non-objects. 3309 } 3310}; 3311 3312/** 3313 * Returns `true` if the object owns an enumerable property with the specified 3314 * value. 3315 * 3316 * @method hasValue 3317 * @param {Object} obj An object. 3318 * @param {any} value The value to search for. 3319 * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise. 3320 * @static 3321 */ 3322O.hasValue = function (obj, value) { 3323 return Y.Array.indexOf(O.values(obj), value) > -1; 3324}; 3325 3326/** 3327 * Executes a function on each enumerable property in _obj_. The function 3328 * receives the value, the key, and the object itself as parameters (in that 3329 * order). 3330 * 3331 * By default, only properties owned by _obj_ are enumerated. To include 3332 * prototype properties, set the _proto_ parameter to `true`. 3333 * 3334 * @method each 3335 * @param {Object} obj Object to enumerate. 3336 * @param {Function} fn Function to execute on each enumerable property. 3337 * @param {mixed} fn.value Value of the current property. 3338 * @param {String} fn.key Key of the current property. 3339 * @param {Object} fn.obj Object being enumerated. 3340 * @param {Object} [thisObj] `this` object to use when calling _fn_. 3341 * @param {Boolean} [proto=false] Include prototype properties. 3342 * @return {YUI} the YUI instance. 3343 * @chainable
3344 * @static 3345 */ 3346O.each = function (obj, fn, thisObj, proto) { 3347 var key; 3348 3349 for (key in obj) { 3350 if (proto || owns(obj, key)) { 3351 fn.call(thisObj || Y, obj[key], key, obj); 3352 } 3353 } 3354 3355 return Y; 3356}; 3357 3358/** 3359 * Executes a function on each enumerable property in _obj_, but halts if the 3360 * function returns a truthy value. The function receives the value, the key, 3361 * and the object itself as paramters (in that order). 3362 * 3363 * By default, only properties owned by _obj_ are enumerated. To include 3364 * prototype properties, set the _proto_ parameter to `true`. 3365 * 3366 * @method some 3367 * @param {Object} obj Object to enumerate. 3368 * @param {Function} fn Function to execute on each enumerable property. 3369 * @param {mixed} fn.value Value of the current property. 3370 * @param {String} fn.key Key of the current property. 3371 * @param {Object} fn.obj Object being enumerated. 3372 * @param {Object} [thisObj] `this` object to use when calling _fn_. 3373 * @param {Boolean} [proto=false] Include prototype properties. 3374 * @return {Boolean} `true` if any execution of _fn_ returns a truthy value, 3375 * `false` otherwise. 3376 * @static 3377 */ 3378O.some = function (obj, fn, thisObj, proto) { 3379 var key; 3380 3381 for (key in obj) { 3382 if (proto || owns(obj, key)) { 3383 if (fn.call(thisObj || Y, obj[key], key, obj)) { 3384 return true; 3385 } 3386 } 3387 } 3388 3389 return false; 3390}; 3391 3392/** 3393 * Retrieves the sub value at the provided path, 3394 * from the value object provided. 3395 * 3396 * @method getValue 3397 * @static 3398 * @param o The object from which to extract the property value. 3399 * @param path {Array} A path array, specifying the object traversal path 3400 * from which to obtain the sub value. 3401 * @return {Any} The value stored in the path, undefined if not found, 3402 * undefined if the source is not an object. Returns the source object 3403 * if an empty path is provided. 3404 */ 3405O.getValue = function(o, path) { 3406 if (!Lang.isObject(o)) { 3407 return UNDEFINED; 3408 } 3409 3410 var i, 3411 p = Y.Array(path), 3412 l = p.length; 3413 3414 for (i = 0; o !== UNDEFINED && i < l; i++) { 3415 o = o[p[i]]; 3416 } 3417 3418 return o; 3419}; 3420 3421/** 3422 * Sets the sub-attribute value at the provided path on the 3423 * value object. Returns the modified value object, or 3424 * undefined if the path is invalid. 3425 * 3426 * @method setValue 3427 * @static 3428 * @param o The object on which to set the sub value. 3429 * @param path {Array} A path array, specifying the object traversal path 3430 * at which to set the sub value. 3431 * @param val {Any} The new value for the sub-attribute. 3432 * @return {Object} The modified object, with the new sub value set, or 3433 * undefined, if the path was invalid. 3434 */ 3435O.setValue = function(o, path, val) { 3436 var i, 3437 p = Y.Array(path), 3438 leafIdx = p.length - 1, 3439 ref = o; 3440 3441 if (leafIdx >= 0) { 3442 for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) { 3443 ref = ref[p[i]]; 3444 } 3445 3446 if (ref !== UNDEFINED) { 3447 ref[p[i]] = val; 3448 } else { 3449 return UNDEFINED; 3450 } 3451 } 3452 3453 return o; 3454}; 3455 3456/** 3457 * Returns `true` if the object has no enumerable properties of its own. 3458 * 3459 * @method isEmpty 3460 * @param {Object} obj An object. 3461 * @return {Boolean} `true` if the object is empty. 3462 * @static 3463 * @since 3.2.0 3464 */ 3465O.isEmpty = function (obj) { 3466 return !O.keys(Object(obj)).length; 3467}; 3468/** 3469 * The YUI module contains the components required for building the YUI seed 3470 * file. This includes the script loading mechanism, a simple queue, and the 3471 * core utilities for the library. 3472 * @module yui 3473 * @submodule yui-base 3474 */ 3475 3476/** 3477 * YUI user agent detection. 3478 * Do not fork for a browser if it can be avoided. Use feature detection when 3479 * you can. Use the user agent as a last resort. For all fields listed 3480 * as @type float, UA stores a version number for the browser engine, 3481 * 0 otherwise. This value may or may not map to the version number of 3482 * the browser using the engine. The value is presented as a float so 3483 * that it can easily be used for boolean evaluation as well as for 3484 * looking for a particular range of versions. Because of this, 3485 * some of the granularity of the version info may be lost. The fields that 3486 * are @type string default to null. The API docs list the values that 3487 * these fields can have. 3488 * @class UA 3489 * @static 3490 */ 3491 3492/** 3493* Static method on `YUI.Env` for parsing a UA string. Called at instantiation 3494* to populate `Y.UA`. 3495* 3496* @static 3497* @method parseUA 3498* @param {String} [subUA=navigator.userAgent] UA string to parse 3499* @return {Object} The Y.UA object 3500*/ 3501YUI.Env.parseUA = function(subUA) { 3502 3503 var numberify = function(s) { 3504 var c = 0; 3505 return parseFloat(s.replace(/\./g, function() { 3506 return (c++ === 1) ? '' : '.'; 3507 })); 3508 }, 3509 3510 win = Y.config.win, 3511 3512 nav = win && win.navigator, 3513 3514 o = { 3515 3516 /** 3517 * Internet Explorer version number or 0. Example: 6 3518 * @property ie 3519 * @type float 3520 * @static 3521 */ 3522 ie: 0, 3523 3524 /** 3525 * Opera version number or 0. Example: 9.2 3526 * @property opera 3527 * @type float 3528 * @static 3529 */ 3530 opera: 0, 3531 3532 /** 3533 * Gecko engine revision number. Will evaluate to 1 if Gecko 3534 * is detected but the revision could not be found. Other browsers 3535 * will be 0. Example: 1.8 3536 * <pre> 3537 * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7 3538 * Firefox 1.5.0.9: 1.8.0.9 <-- 1.8 3539 * Firefox 2.0.0.3: 1.8.1.3 <-- 1.81 3540 * Firefox 3.0 <-- 1.9 3541 * Firefox 3.5 <-- 1.91 3542 * </pre> 3543 * @property gecko 3544 * @type float 3545 * @static 3546 */ 3547 gecko: 0, 3548 3549 /** 3550 * AppleWebKit version. KHTML browsers that are not WebKit browsers 3551 * will evaluate to 1, other browsers 0. Example: 418.9 3552 * <pre> 3553 * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the 3554 * latest available for Mac OSX 10.3. 3555 * Safari 2.0.2: 416 <-- hasOwnProperty introduced 3556 * Safari 2.0.4: 418 <-- preventDefault fixed 3557 * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run 3558 * different versions of webkit 3559 * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been 3560 * updated, but not updated 3561 * to the latest patch. 3562 * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native 3563 * SVG and many major issues fixed). 3564 * Safari 3.0.4 (523.12) 523.12 <-- First Tiger release - automatic 3565 * update from 2.x via the 10.4.11 OS patch. 3566 * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event. 3567 * yahoo.com user agent hack removed. 3568 * </pre> 3569 * http://en.wikipedia.org/wiki/Safari_version_history 3570 * @property webkit 3571 * @type float 3572 * @static 3573 */ 3574 webkit: 0, 3575 3576 /** 3577 * Safari will be detected as webkit, but this property will also 3578 * be populated with the Safari version number 3579 * @property safari 3580 * @type float 3581 * @static 3582 */ 3583 safari: 0, 3584 3585 /** 3586 * Chrome will be detected as webkit, but this property will also 3587 * be populated with the Chrome version number 3588 * @property chrome 3589 * @type float 3590 * @static 3591 */ 3592 chrome: 0, 3593 3594 /** 3595 * The mobile property will be set to a string containing any relevant 3596 * user agent information when a modern mobile browser is detected. 3597 * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series 3598 * devices with the WebKit-based browser, and Opera Mini. 3599 * @property mobile 3600 * @type string 3601 * @default null 3602 * @static 3603 */ 3604 mobile: null, 3605 3606 /** 3607 * Adobe AIR version number or 0. Only populated if webkit is detected. 3608 * Example: 1.0 3609 * @property air 3610 * @type float 3611 */ 3612 air: 0, 3613 /** 3614 * PhantomJS version number or 0. Only populated if webkit is detected. 3615 * Example: 1.0 3616 * @property phantomjs 3617 * @type float 3618 */ 3619 phantomjs: 0, 3620 /** 3621 * Detects Apple iPad's OS version 3622 * @property ipad 3623 * @type float 3624 * @static 3625 */ 3626 ipad: 0, 3627 /** 3628 * Detects Apple iPhone's OS version 3629 * @property iphone 3630 * @type float 3631 * @static 3632 */ 3633 iphone: 0, 3634 /** 3635 * Detects Apples iPod's OS version 3636 * @property ipod 3637 * @type float 3638 * @static 3639 */ 3640 ipod: 0, 3641 /** 3642 * General truthy check for iPad, iPhone or iPod 3643 * @property ios 3644 * @type Boolean 3645 * @default null 3646 * @static 3647 */ 3648 ios: null, 3649 /** 3650 * Detects Googles Android OS version 3651 * @property android 3652 * @type float 3653 * @static 3654 */ 3655 android: 0, 3656 /** 3657 * Detects Kindle Silk 3658 * @property silk 3659 * @type float 3660 * @static 3661 */ 3662 silk: 0, 3663 /** 3664 * Detects Ubuntu version 3665 * @property ubuntu 3666 * @type float 3667 * @static 3668 */ 3669 ubuntu: 0, 3670 /** 3671 * Detects Kindle Silk Acceleration 3672 * @property accel 3673 * @type Boolean 3674 * @static 3675 */ 3676 accel: false, 3677 /** 3678 * Detects Palms WebOS version 3679 * @property webos 3680 * @type float 3681 * @static 3682 */ 3683 webos: 0, 3684 3685 /** 3686 * Google Caja version number or 0. 3687 * @property caja 3688 * @type float 3689 */ 3690 caja: nav && nav.cajaVersion, 3691 3692 /** 3693 * Set to true if the page appears to be in SSL 3694 * @property secure 3695 * @type boolean 3696 * @static 3697 */ 3698 secure: false, 3699 3700 /** 3701 * The operating system. 3702 * 3703 * Possible values are `windows`, `macintosh`, `android`, `symbos`, `linux`, `rhino` and `ios`. 3704 * 3705 * @property os 3706 * @type string 3707 * @default null 3708 * @static 3709 */ 3710 os: null, 3711 3712 /** 3713 * The Nodejs Version 3714 * @property nodejs 3715 * @type float 3716 * @default 0 3717 * @static 3718 */ 3719 nodejs: 0, 3720 /** 3721 * Window8/IE10 Application host environment 3722 * @property winjs 3723 * @type Boolean 3724 * @static 3725 */ 3726 winjs: !!((typeof Windows !== "undefined") && Windows.System), 3727 /** 3728 * Are touch/msPointer events available on this device 3729 * @property touchEnabled 3730 * @type Boolean 3731 * @static 3732 */ 3733 touchEnabled: false 3734 }, 3735 3736 ua = subUA || nav && nav.userAgent, 3737 3738 loc = win && win.location, 3739 3740 href = loc && loc.href, 3741 3742 m; 3743 3744 /** 3745 * The User Agent string that was parsed 3746 * @property userAgent
3747 * @type String 3748 * @static 3749 */ 3750 o.userAgent = ua; 3751 3752 3753 o.secure = href && (href.toLowerCase().indexOf('https') === 0); 3754 3755 if (ua) { 3756 3757 if ((/windows|win32/i).test(ua)) { 3758 o.os = 'windows'; 3759 } else if ((/macintosh|mac_powerpc/i).test(ua)) { 3760 o.os = 'macintosh'; 3761 } else if ((/android/i).test(ua)) { 3762 o.os = 'android'; 3763 } else if ((/symbos/i).test(ua)) { 3764 o.os = 'symbos'; 3765 } else if ((/linux/i).test(ua)) { 3766 o.os = 'linux'; 3767 } else if ((/rhino/i).test(ua)) { 3768 o.os = 'rhino'; 3769 } 3770 3771 // Modern KHTML browsers should qualify as Safari X-Grade 3772 if ((/KHTML/).test(ua)) { 3773 o.webkit = 1; 3774 } 3775 if ((/IEMobile|XBLWP7/).test(ua)) { 3776 o.mobile = 'windows'; 3777 } 3778 if ((/Fennec/).test(ua)) { 3779 o.mobile = 'gecko'; 3780 } 3781 // Modern WebKit browsers are at least X-Grade 3782 m = ua.match(/AppleWebKit\/([^\s]*)/); 3783 if (m && m[1]) { 3784 o.webkit = numberify(m[1]); 3785 o.safari = o.webkit; 3786 3787 if (/PhantomJS/.test(ua)) { 3788 m = ua.match(/PhantomJS\/([^\s]*)/); 3789 if (m && m[1]) { 3790 o.phantomjs = numberify(m[1]); 3791 } 3792 } 3793 3794 // Mobile browser check 3795 if (/ Mobile\//.test(ua) || (/iPad|iPod|iPhone/).test(ua)) { 3796 o.mobile = 'Apple'; // iPhone or iPod Touch 3797 3798 m = ua.match(/OS ([^\s]*)/); 3799 if (m && m[1]) { 3800 m = numberify(m[1].replace('_', '.')); 3801 } 3802 o.ios = m; 3803 o.os = 'ios'; 3804 o.ipad = o.ipod = o.iphone = 0; 3805 3806 m = ua.match(/iPad|iPod|iPhone/); 3807 if (m && m[0]) { 3808 o[m[0].toLowerCase()] = o.ios; 3809 } 3810 } else { 3811 m = ua.match(/NokiaN[^\/]*|webOS\/\d\.\d/); 3812 if (m) { 3813 // Nokia N-series, webOS, ex: NokiaN95 3814 o.mobile = m[0]; 3815 } 3816 if (/webOS/.test(ua)) { 3817 o.mobile = 'WebOS'; 3818 m = ua.match(/webOS\/([^\s]*);/); 3819 if (m && m[1]) { 3820 o.webos = numberify(m[1]); 3821 } 3822 } 3823 if (/ Android/.test(ua)) { 3824 o.mobile = 'Android'; 3825 m = ua.match(/Android ([^\s]*);/); 3826 if (m && m[1]) { 3827 o.android = numberify(m[1]); 3828 } 3829 3830 } 3831 if (/Silk/.test(ua)) { 3832 m = ua.match(/Silk\/([^\s]*)/); 3833 if (m && m[1]) { 3834 o.silk = numberify(m[1]); 3835 } 3836 if (!o.android) { 3837 o.android = 2.34; //Hack for desktop mode in Kindle 3838 o.os = 'Android'; 3839 } 3840 if (/Accelerated=true/.test(ua)) { 3841 o.accel = true; 3842 } 3843 } 3844 } 3845 3846 m = ua.match(/OPR\/(\d+\.\d+)/); 3847 3848 if (m && m[1]) { 3849 // Opera 15+ with Blink (pretends to be both Chrome and Safari) 3850 o.opera = numberify(m[1]); 3851 } else { 3852 m = ua.match(/(Chrome|CrMo|CriOS)\/([^\s]*)/); 3853 3854 if (m && m[1] && m[2]) { 3855 o.chrome = numberify(m[2]); // Chrome 3856 o.safari = 0; //Reset safari back to 0 3857 if (m[1] === 'CrMo') { 3858 o.mobile = 'chrome'; 3859 } 3860 } else { 3861 m = ua.match(/AdobeAIR\/([^\s]*)/); 3862 if (m) { 3863 o.air = m[0]; // Adobe AIR 1.0 or better 3864 } 3865 } 3866 } 3867 } 3868 3869 m = ua.match(/Ubuntu\ (\d+\.\d+)/); 3870 if (m && m[1]) { 3871 3872 o.os = 'linux'; 3873 o.ubuntu = numberify(m[1]); 3874 3875 m = ua.match(/\ WebKit\/([^\s]*)/); 3876 if (m && m[1]) { 3877 o.webkit = numberify(m[1]); 3878 } 3879 m = ua.match(/\ Chromium\/([^\s]*)/); 3880 if (m && m[1]) { 3881 o.chrome = numberify(m[1]); 3882 } 3883 if (/ Mobile$/.test(ua)) { 3884 o.mobile = 'Ubuntu'; 3885 } 3886 } 3887 3888 if (!o.webkit) { // not webkit 3889// @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr) 3890 if (/Opera/.test(ua)) { 3891 m = ua.match(/Opera[\s\/]([^\s]*)/); 3892 if (m && m[1]) { 3893 o.opera = numberify(m[1]); 3894 } 3895 m = ua.match(/Version\/([^\s]*)/); 3896 if (m && m[1]) { 3897 o.opera = numberify(m[1]); // opera 10+ 3898 } 3899 3900 if (/Opera Mobi/.test(ua)) { 3901 o.mobile = 'opera'; 3902 m = ua.replace('Opera Mobi', '').match(/Opera ([^\s]*)/); 3903 if (m && m[1]) { 3904 o.opera = numberify(m[1]); 3905 } 3906 } 3907 m = ua.match(/Opera Mini[^;]*/); 3908 3909 if (m) { 3910 o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316 3911 } 3912 } else { // not opera or webkit 3913 m = ua.match(/MSIE ([^;]*)|Trident.*; rv:([0-9.]+)/); 3914 3915 if (m && (m[1] || m[2])) { 3916 o.ie = numberify(m[1] || m[2]); 3917 } else { // not opera, webkit, or ie 3918 m = ua.match(/Gecko\/([^\s]*)/); 3919 3920 if (m) { 3921 o.gecko = 1; // Gecko detected, look for revision 3922 m = ua.match(/rv:([^\s\)]*)/); 3923 if (m && m[1]) { 3924 o.gecko = numberify(m[1]); 3925 if (/Mobile|Tablet/.test(ua)) { 3926 o.mobile = "ffos"; 3927 } 3928 } 3929 } 3930 } 3931 } 3932 } 3933 } 3934 3935 //Check for known properties to tell if touch events are enabled on this device or if 3936 //the number of MSPointer touchpoints on this device is greater than 0. 3937 if (win && nav && !(o.chrome && o.chrome < 6)) { 3938 o.touchEnabled = (("ontouchstart" in win) || (("msMaxTouchPoints" in nav) && (nav.msMaxTouchPoints > 0))); 3939 } 3940 3941 //It was a parsed UA, do not assign the global value. 3942 if (!subUA) { 3943 3944 if (typeof process === 'object') { 3945 3946 if (process.versions && process.versions.node) { 3947 //NodeJS 3948 o.os = process.platform; 3949 o.nodejs = numberify(process.versions.node); 3950 } 3951 } 3952 3953 YUI.Env.UA = o; 3954 3955 } 3956 3957 return o; 3958}; 3959 3960 3961Y.UA = YUI.Env.UA || YUI.Env.parseUA(); 3962 3963/**
3964Performs a simple comparison between two version numbers, accounting for 3965standard versioning logic such as the fact that "535.8" is a lower version than 3966"535.24", even though a simple numerical comparison would indicate that it's 3967greater. Also accounts for cases such as "1.1" vs. "1.1.0", which are 3968considered equivalent. 3969 3970Returns -1 if version _a_ is lower than version _b_, 0 if they're equivalent, 39711 if _a_ is higher than _b_. 3972 3973Versions may be numbers or strings containing numbers and dots. For example, 3974both `535` and `"535.8.10"` are acceptable. A version string containing 3975non-numeric characters, like `"535.8.beta"`, may produce unexpected results. 3976 3977@method compareVersions 3978@param {Number|String} a First version number to compare. 3979@param {Number|String} b Second version number to compare. 3980@return -1 if _a_ is lower than _b_, 0 if they're equivalent, 1 if _a_ is 3981 higher than _b_. 3982**/ 3983Y.UA.compareVersions = function (a, b) { 3984 var aPart, aParts, bPart, bParts, i, len; 3985 3986 if (a === b) { 3987 return 0; 3988 } 3989 3990 aParts = (a + '').split('.'); 3991 bParts = (b + '').split('.'); 3992 3993 for (i = 0, len = Math.max(aParts.length, bParts.length); i < len; ++i) { 3994 aPart = parseInt(aParts[i], 10); 3995 bPart = parseInt(bParts[i], 10); 3996 3997 /*jshint expr: true*/ 3998 isNaN(aPart) && (aPart = 0); 3999 isNaN(bPart) && (bPart = 0); 4000 4001 if (aPart < bPart) { 4002 return -1; 4003 } 4004 4005 if (aPart > bPart) { 4006 return 1; 4007 } 4008 } 4009 4010 return 0; 4011}; 4012YUI.Env.aliases = { 4013 "anim": ["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"], 4014 "anim-shape-transform": ["anim-shape"], 4015 "app": ["app-base","app-content","app-transitions","lazy-model-list","model","model-list","model-sync-rest","model-sync-local","router","view","view-node-map"], 4016 "attribute": ["attribute-base","attribute-complex"], 4017 "attribute-events": ["attribute-observable"], 4018 "autocomplete": ["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"], 4019 "axes": ["axis-numeric","axis-category","axis-time","axis-stacked"], 4020 "axes-base": ["axis-numeric-base","axis-category-base","axis-time-base","axis-stacked-base"], 4021 "base": ["base-base","base-pluginhost","base-build"], 4022 "cache": ["cache-base","cache-offline","cache-plugin"], 4023 "charts": ["charts-base"], 4024 "collection": ["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"], 4025 "color": ["color-base","color-hsl","color-harmony"], 4026 "controller": ["router"], 4027 "dataschema": ["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"], 4028 "datasource": ["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"], 4029 "datatable": ["datatable-core","datatable-table","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-message","datatable-mutable","datatable-sort","datatable-datasource"], 4030 "datatype": ["datatype-date","datatype-number","datatype-xml"], 4031 "datatype-date": ["datatype-date-parse","datatype-date-format","datatype-date-math"], 4032 "datatype-number": ["datatype-number-parse","datatype-number-format"], 4033 "datatype-xml": ["datatype-xml-parse","datatype-xml-format"], 4034 "dd": ["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"], 4035 "dom": ["dom-base","dom-screen","dom-style","selector-native","selector"], 4036 "editor": ["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"], 4037 "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"], 4038 "event-custom": ["event-custom-base","event-custom-complex"], 4039 "event-gestures": ["event-flick","event-move"], 4040 "handlebars": ["handlebars-compiler"], 4041 "highlight": ["highlight-base","highlight-accentfold"], 4042 "history": ["history-base","history-hash","history-html5"], 4043 "io": ["io-base","io-xdr","io-form","io-upload-iframe","io-queue"], 4044 "json": ["json-parse","json-stringify"], 4045 "loader": ["loader-base","loader-rollup","loader-yui3"], 4046 "loader-pathogen-encoder": ["loader-base","loader-rollup","loader-yui3","loader-pathogen-combo
4046handler"], 4047 "node": ["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"], 4048 "pluginhost": ["pluginhost-base","pluginhost-config"], 4049 "querystring": ["querystring-parse","querystring-stringify"], 4050 "recordset": ["recordset-base","recordset-sort","recordset-filter","recordset-indexer"], 4051 "resize": ["resize-base","resize-proxy","resize-constrain"], 4052 "slider": ["slider-base","slider-value-range","clickable-rail","range-slider"], 4053 "template": ["template-base","template-micro"], 4054 "text": ["text-accentfold","text-wordbreak"], 4055 "widget": ["widget-base","widget-htmlparser","widget-skin","widget-uievents"] 4056}; 4057 4058 4059}, 'patched-v3.18.1', { 4060 "use": [ 4061 "yui-base", 4062 "get", 4063 "features", 4064 "intl-base", 4065 "yui-log", 4066 "yui-later", 4067 "loader-base", 4068 "loader-rollup", 4069 "loader-yui3" 4070 ] 4071}); 4072YUI.add('get', function (Y, NAME) { 4073 4074/*jslint boss:true, expr:true, laxbreak: true */ 4075 4076/** 4077Provides dynamic loading of remote JavaScript and CSS resources. 4078 4079@module get 4080@class Get 4081@static 4082**/ 4083 4084var Lang = Y.Lang, 4085 4086 CUSTOM_ATTRS, // defined lazily in Y.Get.Transaction._createNode() 4087 4088 Get, Transaction; 4089 4090Y.Get = Get = { 4091 // -- Public Properties ---------------------------------------------------- 4092 4093 /** 4094 Default options for CSS requests. Options specified here will override 4095 global defaults for CSS requests. 4096 4097 See the `options` property for all available options. 4098 4099 @property cssOptions 4100 @type Object 4101 @static 4102 @since 3.5.0 4103 **/ 4104 cssOptions: { 4105 attributes: { 4106 rel: 'stylesheet' 4107 }, 4108 4109 doc : Y.config.linkDoc || Y.config.doc, 4110 pollInterval: 50 4111 }, 4112 4113 /** 4114 Default options for JS requests. Options specified here will override global 4115 defaults for JS requests. 4116 4117 See the `options` property for all available options. 4118 4119 @property jsOptions 4120 @type Object 4121 @static 4122 @since 3.5.0 4123 **/ 4124 jsOptions: { 4125 autopurge: true, 4126 doc : Y.config.scriptDoc || Y.config.doc 4127 }, 4128 4129 /** 4130 Default options to use for all requests. 4131 4132 Note that while all available options are documented here for ease of 4133 discovery, some options (like callback functions) only make sense at the 4134 transaction level. 4135 4136 Callback functions specified via the options object or the `options` 4137 parameter of the `css()`, `js()`, or `load()` methods will receive the 4138 transaction object as a parameter. See `Y.Get.Transaction` for details on 4139 the properties and methods available on transactions. 4140 4141 @static 4142 @since 3.5.0 4143 @property {Object} options 4144 4145 @property {Boolean} [options.async=false] Whether or not to load scripts 4146 asynchronously, meaning they're requested in parallel and execution 4147 order is not guaranteed. Has no effect on CSS, since CSS is always 4148 loaded asynchronously. 4149 4150 @property {Object} [options.attributes] HTML attribute name/value pairs that 4151 should be added to inserted nodes. By default, the `charset` attribute 4152 will be set to "utf-8" and nodes will be given an auto-generated `id` 4153 attribute, but you can override these with your own values if desired. 4154 4155 @property {Boolean} [options.autopurge] Whether or not to automatically 4156 purge inserted nodes after the purge threshold is reached. This is 4157 `true` by default for JavaScript, but `false` for CSS since purging a
4158 CSS node will also remove any styling applied by the referenced file. 4159 4160 @property {Object} [options.context] `this` object to use when calling 4161 callback functions. Defaults to the transaction object. 4162 4163 @property {Mixed} [options.data] Arbitrary data object to pass to "on*" 4164 callbacks. 4165 4166 @property {Document} [options.doc] Document into which nodes should be 4167 inserted. By default, the current document is used. 4168 4169 @property {HTMLElement|String} [options.insertBefore] HTML element or id 4170 string of an element before which all generated nodes should be 4171 inserted. If not specified, Get will automatically determine the best 4172 place to insert nodes for maximum compatibility. 4173 4174 @property {Function} [options.onEnd] Callback to execute after a transaction 4175 is complete, regardless of whether it succeeded or failed. 4176 4177 @property {Function} [options.onFailure] Callback to execute after a 4178 transaction fails, times out, or is aborted. 4179 4180 @property {Function} [options.onProgress] Callback to execute after each 4181 individual request in a transaction either succeeds or fails. 4182 4183 @property {Function} [options.onSuccess] Callback to execute after a 4184 transaction completes successfully with no errors. Note that in browsers 4185 that don't support the `error` event on CSS `<link>` nodes, a failed CSS 4186 request may still be reported as a success because in these browsers 4187 it can be difficult or impossible to distinguish between success and 4188 failure for CSS resources. 4189 4190 @property {Function} [options.onTimeout] Callback to execute after a 4191 transaction times out. 4192 4193 @property {Number} [options.pollInterval=50] Polling interval (in 4194 milliseconds) for detecting CSS load completion in browsers that don't 4195 support the `load` event on `<link>` nodes. This isn't used for 4196 JavaScript. 4197 4198 @property {Number} [options.purgethreshold=20] Number of nodes to insert 4199 before triggering an automatic purge when `autopurge` is `true`. 4200 4201 @property {Number} [options.timeout] Number of milliseconds to wait before 4202 aborting a transaction. When a timeout occurs, the `onTimeout` callback 4203 is called, followed by `onFailure` and finally `onEnd`. By default, 4204 there is no timeout. 4205 4206 @property {String} [options.type] Resource type ("css" or "js"). This option 4207 is set automatically by the `css()` and `js()` functions and will be 4208 ignored there, but may be useful when using the `load()` function. If 4209 not specified, the type will be inferred from the URL, defaulting to 4210 "js" if the URL doesn't contain a recognizable file extension. 4211 **/ 4212 options: { 4213 attributes: { 4214 charset: 'utf-8' 4215 }, 4216 4217 purgethreshold: 20 4218 }, 4219 4220 // -- Protected Properties ------------------------------------------------- 4221 4222 /** 4223 Regex that matches a CSS URL. Used to guess the file type when it's not 4224 specified. 4225 4226 @property REGEX_CSS 4227 @type RegExp 4228 @final 4229 @protected 4230 @static 4231 @since 3.5.0 4232 **/ 4233 REGEX_CSS: /\.css(?:[?;].*)?$/i, 4234 4235 /** 4236 Regex that matches a JS URL. Used to guess the file type when it's not 4237 specified. 4238 4239 @property REGEX_JS 4240 @type RegExp 4241 @final 4242 @protected 4243 @static 4244 @since 3.5.0 4245 **/ 4246 REGEX_JS : /\.js(?:[?;].*)?$/i, 4247 4248 /** 4249 Contains information about the current environment, such as what script and 4250 link injection features it supports. 4251 4252 This object is created and populated the first time the `_getEnv()` method 4253 is called. 4254 4255 @property _env 4256 @type Object 4257 @protected 4258 @static 4259 @since 3.5.0 4260 **/ 4261 4262 /** 4263 Mapping of document _yuid strings to <head> or <base> node references so we 4264 don't have to look the node up each time we want to insert a request node. 4265 4266 @property _insertCache 4267 @type Object 4268 @protected 4269 @static 4270 @since 3.5.0 4271 **/ 4272 _insertCache: {}, 4273 4274 /** 4275 Information about the currently pending transaction, if any. 4276 4277 This is actually an object with two properties: `callback`, containing the 4278 optional callback passed to `css()`, `load()`, or `js()`; and `transaction`, 4279 containing the actual transaction instance. 4280 4281 @property _pending 4282 @type Object 4283 @protected 4284 @static 4285 @since 3.5.0 4286 **/ 4287 _pending: null, 4288 4289 /** 4290 HTML nodes eligible to be purged next time autopurge is triggered. 4291 4292 @property _purgeNodes 4293 @type HTMLElement[] 4294 @protected 4295 @static 4296 @since 3.5.0 4297 **/ 4298 _purgeNodes: [], 4299 4300 /** 4301 Queued transactions and associated callbacks. 4302 4303 @property _queue 4304 @type Object[] 4305 @protected 4306 @static 4307 @since 3.5.0 4308 **/ 4309 _queue: [], 4310 4311 // -- Public Methods ------------------------------------------------------- 4312 4313 /** 4314 Aborts the specified transaction. 4315 4316 This will cause the transaction's `onFailure` callback to be called and 4317 will prevent any new script and link nodes from being added to the document, 4318 but any resources that have already been requested will continue loading 4319 (there's no safe way to prevent this, unfortunately). 4320 4321 *Note:* This method is deprecated as of 3.5.0, and will be removed in a 4322 future version of YUI. Use the transaction-level `abort()` method instead. 4323 4324 @method abort 4325 @param {Get.Transaction} transaction Transaction to abort. 4326 @deprecated Use the `abort()` method on the transaction instead. 4327 @static 4328 **/ 4329 abort: function (transaction) { 4330 var i, id, item, len, pending; 4331 4332 4333 if (!transaction.abort) { 4334 id = transaction; 4335 pending = this._pending; 4336 transaction = null; 4337 4338 if (pending && pending.transaction.id === id) { 4339 transaction = pending.transaction; 4340 this._pending = null; 4341 } else { 4342 for (i = 0, len = this._queue.length; i < len; ++i) { 4343 item = this._queue[i].transaction; 4344 4345 if (item.id === id) { 4346 transaction = item; 4347 this._queue.splice(i, 1); 4348 break; 4349 } 4350 } 4351 } 4352 } 4353 4354 transaction && transaction.abort(); 4355 }, 4356 4357 /** 4358 Loads one or more CSS files. 4359 4360 The _urls_ parameter may be provided as a URL string, a request object, 4361 or an array of URL strings and/or request objects. 4362 4363 A request object is just an object that contains a `url` property and zero 4364 or more options that should apply specifically to that request. 4365 Request-specific options take priority over transaction-level options and 4366 default options. 4367 4368 URLs may be relative or absolute, and do not have to have the same origin 4369 as the current page. 4370 4371 The `options` parameter may be omitted completely and a callback passed in 4372 its place, if desired. 4373 4374 @example 4375 4376 // Load a single CSS file and log a message on completion. 4377 Y.Get.css('foo.css', function (err) { 4378 if (err) { 4379 } else { 4380 } 4381 }); 4382 4383 // Load multiple CSS files and log a message when all have finished 4384 // loading. 4385 var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css']; 4386 4387 Y.Get.css(urls, function (err) { 4388 if (err) { 4389 } else { 4390 } 4391 }); 4392 4393 // Specify transaction-level options, which will apply to all requests 4394 // within the transaction. 4395 Y.Get.css(urls, { 4396 attributes: {'class': 'my-css'}, 4397 timeout : 5000 4398 }); 4399 4400 // Specify per-request options, which override transaction-level and 4401 // default options. 4402 Y.Get.css([ 4403 {url: 'foo.css', attributes: {id: 'foo'}}, 4404 {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}} 4405 ]); 4406 4407 @method css 4408 @param {String|Object|Array}
4408 urls URL string, request object, or array 4409 of URLs and/or request objects to load. 4410 @param {Object} [options] Options for this transaction. See the 4411 `Y.Get.options` property for a complete list of available options. 4412 @param {Function} [callback] Callback function to be called on completion. 4413 This is a general callback and will be called before any more granular 4414 callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options` 4415 object. 4416 4417 @param {Array|null} callback.err Array of errors that occurred during 4418 the transaction, or `null` on success. 4419 @param {Get.Transaction} callback.transaction Transaction object. 4420 4421 @return {Get.Transaction} Transaction object. 4422 @static 4423 **/ 4424 css: function (urls, options, callback) { 4425 return this._load('css', urls, options, callback); 4426 }, 4427 4428 /** 4429 Loads one or more JavaScript resources. 4430 4431 The _urls_ parameter may be provided as a URL string, a request object, 4432 or an array of URL strings and/or request objects. 4433 4434 A request object is just an object that contains a `url` property and zero 4435 or more options that should apply specifically to that request. 4436 Request-specific options take priority over transaction-level options and 4437 default options. 4438 4439 URLs may be relative or absolute, and do not have to have the same origin 4440 as the current page. 4441 4442 The `options` parameter may be omitted completely and a callback passed in 4443 its place, if desired. 4444 4445 Scripts will be executed in the order they're specified unless the `async` 4446 option is `true`, in which case they'll be loaded in parallel and executed 4447 in whatever order they finish loading. 4448 4449 @example 4450 4451 // Load a single JS file and log a message on completion. 4452 Y.Get.js('foo.js', function (err) { 4453 if (err) { 4454 } else { 4455 } 4456 }); 4457 4458 // Load multiple JS files, execute them in order, and log a message when 4459 // all have finished loading. 4460 var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js']; 4461 4462 Y.Get.js(urls, function (err) { 4463 if (err) { 4464 } else { 4465 } 4466 }); 4467 4468 // Specify transaction-level options, which will apply to all requests 4469 // within the transaction. 4470 Y.Get.js(urls, { 4471 attributes: {'class': 'my-js'}, 4472 timeout : 5000 4473 }); 4474 4475 // Specify per-request options, which override transaction-level and 4476 // default options. 4477 Y.Get.js([ 4478 {url: 'foo.js', attributes: {id: 'foo'}}, 4479 {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}} 4480 ]); 4481 4482 @method js 4483 @param {String|Object|Array} urls URL string, request object, or array 4484 of URLs and/or request objects to load. 4485 @param {Object} [options] Options for this transaction. See the 4486 `Y.Get.options` property for a complete list of available options. 4487 @param {Function} [callback] Callback function to be called on completion. 4488 This is a general callback and will be called before any more granular 4489 callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options` 4490 object. 4491 4492 @param {Array|null} callback.err Array of errors that occurred during 4493 the transaction, or `null` on success. 4494 @param {Get.Transaction} callback.transaction Transaction object. 4495 4496 @return {Get.Transaction} Transaction object. 4497 @since 3.5.0 4498 @static 4499 **/ 4500 js: function (urls, options, callback) { 4501 return this._load('js', urls, options, callback); 4502 }, 4503 4504 /** 4505 Loads one or more CSS and/or JavaScript resources in the same transaction. 4506 4507 Use this method when you want to load both CSS and JavaScript in a single 4508 transaction and be notified when all requested URLs have finished loading, 4509 regardless of type. 4510 4511 Behavior and options are the same as for the `css()` and `js()` methods. If 4512 a resource type isn't specified in per-request options or transaction-level 4513 options, Get will guess the file type based on the URL's extension (`.css` 4514 or `.js`, with or without a following query string). If the file type can't 4515 be guessed from the URL, a warning will be logged and Get will assume the 4516 URL is a JavaScript resource. 4517 4518 @example 4519 4520 // Load both CSS and JS files in a single transaction, and log a message 4521 // when all files have finished loading. 4522 Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) { 4523 if (err) { 4524 } else { 4525 } 4526 }); 4527 4528 @method load 4529 @param {String|Object|Array}
4529 urls URL string, request object, or array 4530 of URLs and/or request objects to load. 4531 @param {Object} [options] Options for this transaction. See the 4532 `Y.Get.options` property for a complete list of available options. 4533 @param {Function} [callback] Callback function to be called on completion. 4534 This is a general callback and will be called before any more granular 4535 callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options` 4536 object. 4537 4538 @param {Array|null} err Array of errors that occurred during the 4539 transaction, or `null` on success. 4540 @param {Get.Transaction} Transaction object. 4541 4542 @return {Get.Transaction} Transaction object. 4543 @since 3.5.0 4544 @static 4545 **/ 4546 load: function (urls, options, callback) { 4547 return this._load(null, urls, options, callback); 4548 }, 4549 4550 // -- Protected Methods ---------------------------------------------------- 4551 4552 /** 4553 Triggers an automatic purge if the purge threshold has been reached. 4554 4555 @method _autoPurge 4556 @param {Number} threshold Purge threshold to use, in milliseconds. 4557 @protected 4558 @since 3.5.0 4559 @static 4560 **/ 4561 _autoPurge: function (threshold) { 4562 if (threshold && this._purgeNodes.length >= threshold) { 4563 this._purge(this._purgeNodes); 4564 } 4565 }, 4566 4567 /** 4568 Populates the `_env` property with information about the current 4569 environment. 4570 4571 @method _getEnv 4572 @return {Object} Environment information. 4573 @protected 4574 @since 3.5.0 4575 @static 4576 **/ 4577 _getEnv: function () { 4578 var doc = Y.config.doc, 4579 ua = Y.UA; 4580 4581 // Note: some of these checks require browser sniffs since it's not 4582 // feasible to load test files on every pageview just to perform a 4583 // feature test. I'm sorry if this makes you sad. 4584 return (this._env = { 4585 4586 // True if this is a browser that supports disabling async mode on 4587 // dynamically created script nodes. See 4588 // https://developer.mozilla.org/En/HTML/Element/Script#Attributes 4589 4590 // IE10 doesn't return true for the MDN feature test, so setting it explicitly, 4591 // because it is async by default, and allows you to disable async by setting it to false 4592 async: (doc && doc.createElement('script').async === true) || (ua.ie >= 10), 4593 4594 // True if this browser fires an event when a dynamically injected 4595 // link node fails to load. This is currently true for Firefox 9+ 4596 // and WebKit 535.24+ 4597 cssFail: ua.gecko >= 9 || ua.compareVersions(ua.webkit, 535.24) >= 0, 4598 4599 // True if this browser fires an event when a dynamically injected 4600 // link node finishes loading. This is currently true for IE, Opera, 4601 // Firefox 9+, and WebKit 535.24+. Note that IE versions <9 fire the 4602 // DOM 0 "onload" event, but not "load". All versions of IE fire 4603 // "onload". 4604 // davglass: Seems that Chrome on Android needs this to be false. 4605 cssLoad: ( 4606 (!ua.gecko && !ua.webkit) || ua.gecko >= 9 || 4607 ua.compareVersions(ua.webkit, 535.24) >= 0 4608 ) && !(ua.chrome && ua.chrome <= 18), 4609 4610 // True if this browser preserves script execution order while 4611 // loading scripts in parallel as long as the script node's `async` 4612 // attribute is set to false to explicitly disable async execution. 4613 preservesScriptOrder: !!(ua.gecko || ua.opera || (ua.ie && ua.ie >= 10)) 4614 }); 4615 }, 4616 4617 _getTransaction: function (urls, options) { 4618 var requests = [], 4619 i, len, req, url; 4620 4621 if (!Lang.isArray(urls)) { 4622 urls = [urls]; 4623 } 4624 4625 options = Y.merge(this.options, options); 4626 4627 // Clone the attributes object so we don't end up modifying it by ref. 4628 options.attributes = Y.merge(this.options.attributes, 4629 options.attributes); 4630 4631 for (i = 0, len = urls.length; i < len; ++i) { 4632 url = urls[i]; 4633 req = {attributes: {}}; 4634 4635 // If `url` is a string, we create a URL object for it, then mix in 4636 // global options and request-specific options. If it's an object 4637 // with a "url" property, we assume it's a request object c
4637ontaining 4638 // URL-specific options. 4639 if (typeof url === 'string') { 4640 req.url = url; 4641 } else if (url.url) { 4642 // URL-specific options override both global defaults and 4643 // request-specific options. 4644 Y.mix(req, url, false, null, 0, true); 4645 url = url.url; // Make url a string so we can use it later. 4646 } else { 4647 continue; 4648 } 4649 4650 Y.mix(req, options, false, null, 0, true); 4651 4652 // If we didn't get an explicit type for this URL either in the 4653 // request options or the URL-specific options, try to determine 4654 // one from the file extension. 4655 if (!req.type) { 4656 if (this.REGEX_CSS.test(url)) { 4657 req.type = 'css'; 4658 } else { 4659 if (!this.REGEX_JS.test(url)) { 4660 } 4661 4662 req.type = 'js'; 4663 } 4664 } 4665 4666 // Mix in type-specific default options, but don't overwrite any 4667 // options that have already been set. 4668 Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions, 4669 false, null, 0, true); 4670 4671 // Give the node an id attribute if it doesn't already have one. 4672 req.attributes.id || (req.attributes.id = Y.guid()); 4673 4674 // Backcompat for <3.5.0 behavior. 4675 if (req.win) { 4676 req.doc = req.win.document; 4677 } else { 4678 req.win = req.doc.defaultView || req.doc.parentWindow; 4679 } 4680 4681 if (req.charset) { 4682 req.attributes.charset = req.charset; 4683 } 4684 4685 requests.push(req); 4686 } 4687 4688 return new Transaction(requests, options); 4689 }, 4690 4691 _load: function (type, urls, options, callback) { 4692 var transaction; 4693 4694 // Allow callback as third param. 4695 if (typeof options === 'function') { 4696 callback = options; 4697 options = {}; 4698 } 4699 4700 options || (options = {}); 4701 options.type = type; 4702 4703 options._onFinish = Get._onTransactionFinish; 4704 4705 if (!this._env) { 4706 this._getEnv(); 4707 } 4708 4709 transaction = this._getTransaction(urls, options); 4710 4711 this._queue.push({ 4712 callback : callback, 4713 transaction: transaction 4714 }); 4715 4716 this._next(); 4717 4718 return transaction; 4719 }, 4720 4721 _onTransactionFinish : function() { 4722 Get._pending = null; 4723 Get._next(); 4724 }, 4725 4726 _next: function () { 4727 var item; 4728 4729 if (this._pending) { 4730 return; 4731 } 4732 4733 item = this._queue.shift(); 4734 4735 if (item) { 4736 this._pending = item; 4737 item.transaction.execute(item.callback); 4738 } 4739 }, 4740 4741 _purge: function (nodes) { 4742 var purgeNodes = this._purgeNodes, 4743 isTransaction = nodes !== purgeNodes, 4744 index, node; 4745 4746 while (node = nodes.pop()) { // assignment 4747 // Don't purge nodes that haven't finished loading (or errored out), 4748 // since this can hang the transaction. 4749 if (!node._yuiget_finished) { 4750 continue; 4751 } 4752 4753 node.parentNode && node.parentNode.removeChild(node); 4754 4755 // If this is a transaction-level purge and this node also exists in 4756 // the Get-level _purgeNodes array, we need to remove it from 4757 // _purgeNodes to avoid creating a memory leak. The indexOf lookup 4758 // sucks, but until we get WeakMaps, this is the least troublesome 4759 // way to do this (we can't just hold onto node ids because they may 4760 // not be in the same document). 4761 if (isTransaction) { 4762 index = Y.Array.indexOf(purgeNodes, node); 4763 4764 if (index > -1) { 4765 purgeNodes.splice(index, 1); 4766 } 4767 } 4768 } 4769 } 4770}; 4771 4772/** 4773Alias for `js()`. 4774 4775@method script 4776@static 4777**/ 4778Get.script = Get.js; 4779 4780/** 4781Represents a Get transaction, which may contain requests for one or more JS or 4782CSS files. 4783 4784This class should not be instantiated manually. Instances will be created and
4785returned as needed by Y.Get's `css()`, `js()`, and `load()` methods. 4786 4787@class Get.Transaction 4788@constructor 4789@since 3.5.0 4790**/ 4791Get.Transaction = Transaction = function (requests, options) { 4792 var self = this; 4793 4794 self.id = Transaction._lastId += 1; 4795 self.data = options.data; 4796 self.errors = []; 4797 self.nodes = []; 4798 self.options = options; 4799 self.requests = requests; 4800 4801 self._callbacks = []; // callbacks to call after execution finishes 4802 self._queue = []; 4803 self._reqsWaiting = 0; 4804 4805 // Deprecated pre-3.5.0 properties. 4806 self.tId = self.id; // Use `id` instead. 4807 self.win = options.win || Y.config.win; 4808}; 4809 4810/** 4811Arbitrary data object associated with this transaction. 4812 4813This object comes from the options passed to `Get.css()`, `Get.js()`, or 4814`Get.load()`, and will be `undefined` if no data object was specified. 4815 4816@property {Object} data 4817**/ 4818 4819/** 4820Array of errors that have occurred during this transaction, if any. Each error 4821object has the following properties: 4822`errors.error`: Error message. 4823`errors.request`: Request object related to the error. 4824 4825@since 3.5.0 4826@property {Object[]} errors 4827**/ 4828 4829/** 4830Numeric id for this transaction, unique among all transactions within the same 4831YUI sandbox in the current pageview. 4832 4833@property {Number} id 4834@since 3.5.0 4835**/ 4836 4837/**
4838HTMLElement nodes (native ones, not YUI Node instances) that have been inserted 4839during the current transaction. 4840 4841@property {HTMLElement[]} nodes 4842**/ 4843 4844/** 4845Options associated with this transaction. 4846 4847See `Get.options` for the full list of available options. 4848 4849@property {Object} options 4850@since 3.5.0 4851**/ 4852 4853/** 4854Request objects contained in this transaction. Each request object represents 4855one CSS or JS URL that will be (or has been) requested and loaded into the page. 4856 4857@property {Object} requests 4858@since 3.5.0 4859**/ 4860 4861/** 4862Id of the most recent transaction. 4863 4864@property _lastId 4865@type Number 4866@protected 4867@static 4868**/ 4869Transaction._lastId = 0; 4870 4871Transaction.prototype = { 4872 // -- Public Properties ---------------------------------------------------- 4873 4874 /** 4875 Current state of this transaction. One of "new", "executing", or "done". 4876 4877 @property _state 4878 @type String 4879 @protected 4880 **/ 4881 _state: 'new', // "new", "executing", or "done" 4882 4883 // -- Public Methods ------------------------------------------------------- 4884 4885 /** 4886 Aborts this transaction. 4887 4888 This will cause the transaction's `onFailure` callback to be called and 4889 will prevent any new script and link nodes from being added to the document, 4890 but any resources that have already been requested will continue loading 4891 (there's no safe way to prevent this, unfortunately). 4892 4893 @method abort 4894 @param {String} [msg="Aborted."] Optional message to use in the `errors` 4895 array describing why the transaction was aborted. 4896 **/ 4897 abort: function (msg) { 4898 this._pending = null; 4899 this._pendingCSS = null; 4900 this._pollTimer = clearTimeout(this._pollTimer); 4901 this._queue = []; 4902 this._reqsWaiting = 0; 4903 4904 this.errors.push({error: msg || 'Aborted'}); 4905 this._finish(); 4906 }, 4907 4908 /** 4909 Begins execting the transaction. 4910 4911 There's usually no reason to call this manually, since Get will call it 4912 automatically when other pending transactions have finished. If you really 4913 want to execute your transaction before Get does, you can, but be aware that 4914 this transaction's scripts may end up executing before the scripts in other 4915 pending transactions. 4916 4917 If the transaction is already executing, the specified callback (if any) 4918 will be queued and called after execution finishes. If the transaction has 4919 already finished, the callback will be called immediately (the transaction 4920 will not be executed again). 4921 4922 @method execute 4923 @param {Function} callback Callback function to execute after all requests 4924 in the transaction are complete, or after the transaction is aborted. 4925 **/ 4926 execute: function (callback) { 4927 var self = this, 4928 requests = self.requests, 4929 state = self._state, 4930 i, len, queue, req; 4931 4932 if (state === 'done') { 4933 callback && callback(self.errors.length ? self.errors : null, self); 4934 return; 4935 } else { 4936 callback && self._callbacks.push(callback); 4937 4938 if (state === 'executing') { 4939 return; 4940 } 4941 } 4942 4943 self._state = 'executing'; 4944 self._queue = queue = []; 4945 4946 if (self.options.timeout) { 4947 self._timeout = setTimeout(function () { 4948 self.abort('Timeout'); 4949 }, self.options.timeout); 4950 } 4951 4952 self._reqsWaiting = requests.length; 4953 4954 for (i = 0, len = requests.length; i < len; ++i) { 4955 req = requests[i]; 4956 4957 if (req.async || req.type === 'css') { 4958 // No need to queue CSS or fully async JS. 4959 self._insert(req); 4960 } else { 4961 queue.push(req); 4962 } 4963 } 4964 4965 self._next(); 4966 }, 4967 4968 /** 4969 Manually purges any `<script>` or `<link>` nodes this transaction has 4970 created. 4971 4972 Be careful when purging a transaction that contains CSS requests, since 4973 removing `<link>` nodes will also remove any styles they applied. 4974 4975 @method purge 4976 **/ 4977 purge: function () { 4978 Get._purge(this.nodes); 4979 }, 4980 4981 // -- Protected Methods ---------------------------------------------------- 4982 _createNode: function (name, attrs, doc) { 4983 var node = doc.createElement(name), 4984 attr, testEl; 4985 4986 if (!CUSTOM_ATTRS) { 4987 // IE6 and IE7 expect property names rather than attribute names for 4988 // certain attributes. Rather than sniffing, we do a quick feature 4989 // test the first time _createNode() runs to determine whether we 4990 // need to provide a workaround. 4991 testEl = doc.createElement('div'); 4992 testEl.setAttribute('class', 'a'); 4993 4994 CUSTOM_ATTRS = testEl.className === 'a' ? {} : { 4995 'for' : 'htmlFor', 4996 'class': 'className' 4997 }; 4998 } 4999 5000 for (attr in attrs) { 5001 if (attrs.hasOwnProperty(attr)) { 5002 node.setAttribute(CUSTOM_ATTRS[attr] || attr, attrs[attr]); 5003 } 5004 } 5005 5006 return node; 5007 }, 5008 5009 _finish: function () { 5010 var errors = this.errors.length ? this.errors : null, 5011 options = this.options, 5012 thisObj = options.context || this, 5013 data, i, len; 5014 5015 if (this._state === 'done') { 5016 return; 5017 } 5018 5019 this._state = 'done'; 5020 5021 for (i = 0, len = this._callbacks.length; i < len; ++i) { 5022 this._callbacks[i].call(thisObj, errors, this); 5023 } 5024 5025 data = this._getEventData(); 5026 5027 if (errors) {
5028 if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') { 5029 options.onTimeout.call(thisObj, data); 5030 } 5031 5032 if (options.onFailure) { 5033 options.onFailure.call(thisObj, data); 5034 } 5035 } else if (options.onSuccess) { 5036 options.onSuccess.call(thisObj, data); 5037 } 5038 5039 if (options.onEnd) { 5040 options.onEnd.call(thisObj, data); 5041 } 5042 5043 if (options._onFinish) { 5044 options._onFinish(); 5045 } 5046 }, 5047 5048 _getEventData: function (req) { 5049 if (req) { 5050 // This merge is necessary for backcompat. I hate it. 5051 return Y.merge(this, { 5052 abort : this.abort, // have to copy these because the prototype isn't preserved 5053 purge : this.purge, 5054 request: req, 5055 url : req.url, 5056 win : req.win 5057 }); 5058 } else { 5059 return this; 5060 } 5061 }, 5062 5063 _getInsertBefore: function (req) { 5064 var doc = req.doc, 5065 el = req.insertBefore, 5066 cache, docStamp; 5067 5068 if (el) { 5069 return typeof el === 'string' ? doc.getElementById(el) : el; 5070 } 5071 5072 cache = Get._insertCache; 5073 docStamp = Y.stamp(doc); 5074 5075 if ((el = cache[docStamp])) { // assignment 5076 return el; 5077 } 5078 5079 // Inserting before a <base> tag apparently works around an IE bug 5080 // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what 5081 // bug that is, exactly. Better safe than sorry? 5082 if ((el = doc.getElementsByTagName('base')[0])) { // assignment 5083 return (cache[docStamp] = el); 5084 } 5085 5086 // Look for a <head> element. 5087 el = doc.head || doc.getElementsByTagName('head')[0]; 5088 5089 if (el) { 5090 // Create a marker node at the end of <head> to use as an insertion 5091 // point. Inserting before this node will ensure that all our CSS 5092 // gets inserted in the correct order, to maintain style precedence. 5093 el.appendChild(doc.createTextNode('')); 5094 return (cache[docStamp] = el.lastChild); 5095 } 5096 5097 // If all else fails, just insert before the first script node on the 5098 // page, which is virtually guaranteed to exist. 5099 return (cache[docStamp] = doc.getElementsByTagName('script')[0]); 5100 }, 5101 5102 _insert: function (req) { 5103 var env = Get._env, 5104 insertBefore = this._getInsertBefore(req), 5105 isScript = req.type === 'js', 5106 node = req.node, 5107 self = this, 5108 ua = Y.UA, 5109 cssTimeout, nodeType; 5110 5111 if (!node) { 5112 if (isScript) { 5113 nodeType = 'script'; 5114 } else if (!env.cssLoad && ua.gecko) { 5115 nodeType = 'style'; 5116 } else { 5117 nodeType = 'link'; 5118 } 5119 5120 node = req.node = this._createNode(nodeType, req.attributes, 5121 req.doc); 5122 } 5123 5124 function onError() { 5125 self._progress('Failed to load ' + req.url, req); 5126 } 5127 5128 function onLoad() { 5129 if (cssTimeout) { 5130 clearTimeout(cssTimeout); 5131 } 5132 5133 self._progress(null, req); 5134 } 5135 5136 // Deal with script asynchronicity. 5137 if (isScript) { 5138 node.setAttribute('src', req.url); 5139 5140 if (req.async) { 5141 // Explicitly indicate that we want the browser to execute this 5142 // script asynchronously. This is necessary for older browsers 5143 // like Firefox <4. 5144 node.async = true; 5145 } else { 5146 if (env.async) { 5147 // This browser treats injected scripts as async by default 5148 // (standard HTML5 behavior) but asynchronous loading isn't 5149 // desired, so tell the browser not to mark this script as 5150 // async. 5151 node.async = false; 5152 } 5153 5154 // If this browser doesn't preserve script execution order based 5155 // on insertion order, we'll need to avoid inserting other 5156 // scripts until this one finishes loading. 5157 if (!env.preservesScriptOrder) { 5158 this._pending = req; 5159 } 5160 } 5161 } else { 5162 if (!env.cssLoad && ua.gecko) { 5163 // In Firefox <9, we can import the requested URL into a <style> 5164 // node and poll for the existence of node.sheet.cssRules. This 5165 // gives us a reliable way to determine CSS load completion that 5166 // also works for cross-domain stylesheets. 5167 // 5168 // Props to Zach Leatherman for calling my attention to this 5169 // technique. 5170 node.innerHTML = (req.attributes.charset ? 5171 '@charset "' + req.attributes.charset + '";' : '') + 5172 '@import "' + req.url + '";'; 5173 } else { 5174 node.setAttribute('href', req.url); 5175 } 5176 } 5177 5178 // Inject the node. 5179 if (isScript && ua.ie && (ua.ie < 9 || (document.documentMode && document.documentMode < 9))) { 5180 // Script on IE < 9, and IE 9+ when in IE 8 or older modes, including quirks mode. 5181 node.onreadystatechange = function () { 5182 if (/loaded|complete/.test(node.readyState)) { 5183 node.onreadystatechange = null; 5184 onLoad(); 5185 } 5186 }; 5187 } else if (!isScript && !env.cssLoad) { 5188 // CSS on Firefox <9 or WebKit. 5189 this._poll(req); 5190 } else { 5191 // Script or CSS on everything else. Using DOM 0 events because that 5192 // evens the playing field with older IEs. 5193 5194 if (ua.ie >= 10) { 5195 5196 // We currently need to introduce a timeout for IE10, since it 5197 // calls onerror/onload synchronously for 304s - messing up existing 5198 // program flow. 5199 5200 // Remove this block if the following bug gets fixed by GA 5201 /*jshint maxlen: 1500 */ 5202 // https://connect.microsoft.com/IE/feedback/details/763871/dynamically-loaded-scripts-with-304s-responses-interrupt-the-currently-executing-js-thread-onload 5203 node.onerror = function() { setTimeout(onError, 0); }; 5204 node.onload = function() { setTimeout(onLoad, 0); }; 5205 } else { 5206 node.onerror = onError; 5207 node.onload = onLoad; 5208 } 5209 5210 // If this browser doesn't fire an event when CSS fails to load, 5211 // fail after a timeout to avoid blocking the transaction queue. 5212 if (!env.cssFail && !isScript) { 5213 cssTimeout = setTimeout(onError, req.timeout || 3000); 5214 } 5215 } 5216 5217 this.nodes.push(node); 5218 insertBefore.parentNode.insertBefore(node, insertBefore); 5219 }, 5220 5221 _next: function () {
5222 if (this._pending) { 5223 return; 5224 } 5225 5226 // If there are requests in the queue, insert the next queued request. 5227 // Otherwise, if we're waiting on already-inserted requests to finish, 5228 // wait longer. If there are no queued requests and we're not waiting 5229 // for anything to load, then we're done! 5230 if (this._queue.length) { 5231 this._insert(this._queue.shift()); 5232 } else if (!this._reqsWaiting) { 5233 this._finish(); 5234 } 5235 }, 5236 5237 _poll: function (newReq) { 5238 var self = this, 5239 pendingCSS = self._pendingCSS, 5240 isWebKit = Y.UA.webkit, 5241 i, hasRules, j, nodeHref, req, sheets; 5242 5243 if (newReq) { 5244 pendingCSS || (pendingCSS = self._pendingCSS = []); 5245 pendingCSS.push(newReq); 5246 5247 if (self._pollTimer) { 5248 // A poll timeout is already pending, so no need to create a 5249 // new one. 5250 return; 5251 } 5252 } 5253 5254 self._pollTimer = null; 5255 5256 // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s 5257 // will still be treated as a success. There's no good workaround for 5258 // this. 5259 5260 for (i = 0; i < pendingCSS.length; ++i) { 5261 req = pendingCSS[i]; 5262 5263 if (isWebKit) { 5264 // Look for a stylesheet matching the pending URL. 5265 sheets = req.doc.styleSheets; 5266 j = sheets.length; 5267 nodeHref = req.node.href; 5268 5269 while (--j >= 0) { 5270 if (sheets[j].href === nodeHref) { 5271 pendingCSS.splice(i, 1); 5272 i -= 1; 5273 self._progress(null, req); 5274 break; 5275 } 5276 } 5277 } else { 5278 // Many thanks to Zach Leatherman for calling my attention to 5279 // the @import-based cross-domain technique used here, and to 5280 // Oleg Slobodskoi for an earlier same-domain implementation. 5281 // 5282 // See Zach's blog for more details: 5283 // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/ 5284 try { 5285 // We don't really need to store this value since we never 5286 // use it again, but if we don't store it, Closure Compiler 5287 // assumes the code is useless and removes it. 5288 hasRules = !!req.node.sheet.cssRules; 5289 5290 // If we get here, the stylesheet has loaded. 5291 pendingCSS.splice(i, 1); 5292 i -= 1; 5293 self._progress(null, req); 5294 } catch (ex) { 5295 // An exception means the stylesheet is still loading. 5296 } 5297 } 5298 } 5299 5300 if (pendingCSS.length) { 5301 self._pollTimer = setTimeout(function () { 5302 self._poll.call(self); 5303 }, self.options.pollInterval); 5304 } 5305 }, 5306 5307 _progress: function (err, req) { 5308 var options = this.options; 5309 5310 if (err) { 5311 req.error = err; 5312 5313 this.errors.push({ 5314 error : err, 5315 request: req 5316 }); 5317 5318 } 5319 5320 req.node._yuiget_finished = req.finished = true; 5321 5322 if (options.onProgress) { 5323 options.onProgress.call(options.context || this, 5324 this._getEventData(req)); 5325 } 5326 5327 if (req.autopurge) { 5328 // Pre-3.5.0 Get always excludes the most recent node from an 5329 // autopurge. I find this odd, but I'm keeping that behavior for 5330 // the sake of backcompat. 5331 Get._autoPurge(this.options.purgethreshold); 5332 Get._purgeNodes.push(req.node); 5333 } 5334 5335 if (this._pending === req) { 5336 this._pending = null; 5337 } 5338 5339 this._reqsWaiting -= 1; 5340 5341 this._next(); 5342 } 5343}; 5344 5345 5346}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5347YUI.add('features', function (Y, NAME) { 5348 5349var feature_tests = {}; 5350 5351/** 5352Contains the core of YUI's feature test architecture. 5353@module features 5354*/ 5355 5356/** 5357* Feature detection 5358* @class Features 5359* @static 5360*/ 5361 5362Y.mix(Y.namespace('Features'), { 5363 5364 /** 5365 * Object hash of all registered feature tests 5366 * @property tests 5367 * @type Object 5368 */ 5369 tests: feature_tests, 5370 5371 /** 5372 * Add a test to the system 5373 * 5374 * ``` 5375 * Y.Features.add("load", "1", {}); 5376 * ``` 5377 * 5378 * @method add 5379 * @param {String} cat The category, right now only 'load' is supported 5380 * @param {String}
5380 name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3 5381 * @param {Object} o Object containing test properties 5382 * @param {String} o.name The name of the test 5383 * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance 5384 * @param {String} o.trigger The module that triggers this test. 5385 */ 5386 add: function(cat, name, o) { 5387 feature_tests[cat] = feature_tests[cat] || {}; 5388 feature_tests[cat][name] = o; 5389 }, 5390 /** 5391 * Execute all tests of a given category and return the serialized results 5392 * 5393 * ``` 5394 * caps=1:1;2:1;3:0 5395 * ``` 5396 * @method all 5397 * @param {String} cat The category to execute 5398 * @param {Array} args The arguments to pass to the test function 5399 * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0 5400 */ 5401 all: function(cat, args) { 5402 var cat_o = feature_tests[cat], 5403 // results = {}; 5404 result = []; 5405 if (cat_o) { 5406 Y.Object.each(cat_o, function(v, k) { 5407 result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0)); 5408 }); 5409 } 5410 5411 return (result.length) ? result.join(';') : ''; 5412 }, 5413 /** 5414 * Run a specific test and return a Boolean response. 5415 * 5416 * ``` 5417 * Y.Features.test("load", "1"); 5418 * ``` 5419 * 5420 * @method test 5421 * @param {String} cat The category of the test to run 5422 * @param {String} name The name of the test to run 5423 * @param {Array} args The arguments to pass to the test function 5424 * @return {Boolean} True or false if the test passed/failed. 5425 */ 5426 test: function(cat, name, args) { 5427 args = args || []; 5428 var result, ua, test, 5429 cat_o = feature_tests[cat], 5430 feature = cat_o && cat_o[name]; 5431 5432 if (!feature) { 5433 } else { 5434 5435 result = feature.result; 5436 5437 if (Y.Lang.isUndefined(result)) { 5438 5439 ua = feature.ua; 5440 if (ua) { 5441 result = (Y.UA[ua]); 5442 } 5443 5444 test = feature.test; 5445 if (test && ((!ua) || result)) { 5446 result = test.apply(Y, args); 5447 } 5448 5449 feature.result = result; 5450 } 5451 } 5452 5453 return result; 5454 } 5455}); 5456 5457// Y.Features.add("load", "1", {}); 5458// Y.Features.test("load", "1"); 5459// caps=1:1;2:0;3:1; 5460 5461/* This file is auto-generated by (yogi loader --yes --mix --start ../) */ 5462/*jshint maxlen:900, eqeqeq: false */ 5463var add = Y.Features.add; 5464// app-transitions-native 5465add('load', '0', { 5466 "name": "app-transitions-native", 5467 "test": function (Y) { 5468 var doc = Y.config.doc, 5469 node = doc ? doc.documentElement : null; 5470 5471 if (node && node.style) { 5472 return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 5473 } 5474 5475 return false; 5476}, 5477 "trigger": "app-transitions" 5478}); 5479// autocomplete-list-keys 5480add('load', '1', { 5481 "name": "autocomplete-list-keys", 5482 "test": function (Y) { 5483 // Only add keyboard support to autocomplete-list if this doesn't appear to 5484 // be an iOS or Android-based mobile device. 5485 // 5486 // There's currently no feasible way to actually detect whether a device has 5487 // a hardware keyboard, so this sniff will have to do. It can easily be 5488 // overridden by manually loading the autocomplete-list-keys module. 5489 // 5490 // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari 5491 // doesn't fire the keyboard events used by AutoCompleteList, so there's 5492 // no point loading the -keys module even when a bluetooth keyboard may be 5493 // available. 5494 return !(Y.UA.ios || Y.UA.android); 5495}, 5496 "trigger": "autocomplete-list" 5497}); 5498// dd-gestures 5499add('load', '2', { 5500 "name": "dd-gestures", 5501 "trigger": "dd-drag", 5502 "ua": "touchEnabled" 5503}); 5504// dom-style-ie 5505add('load', '3', { 5506 "name": "dom-style-ie", 5507 "test": function (Y) { 5508 5509 var testFeature = Y.Features.test, 5510 addFeature = Y.Features.add, 5511 WINDOW = Y.config.win, 5512 DOCUMENT = Y.config.doc, 5513 DOCUMENT_ELEMENT = 'documentElement', 5514 ret = false;
5515 5516 addFeature('style', 'computedStyle', { 5517 test: function() { 5518 return WINDOW && 'getComputedStyle' in WINDOW; 5519 } 5520 }); 5521 5522 addFeature('style', 'opacity', { 5523 test: function() { 5524 return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style; 5525 } 5526 }); 5527 5528 ret = (!testFeature('style', 'opacity') && 5529 !testFeature('style', 'computedStyle')); 5530 5531 return ret; 5532}, 5533 "trigger": "dom-style" 5534}); 5535// editor-para-ie 5536add('load', '4', { 5537 "name": "editor-para-ie", 5538 "trigger": "editor-para", 5539 "ua": "ie", 5540 "when": "instead" 5541}); 5542// event-base-ie 5543add('load', '5', { 5544 "name": "event-base-ie", 5545 "test": function(Y) { 5546 var imp = Y.config.doc && Y.config.doc.implementation; 5547 return (imp && (!imp.hasFeature('Events', '2.0'))); 5548}, 5549 "trigger": "node-base" 5550}); 5551// graphics-canvas 5552add('load', '6', { 5553 "name": "graphics-canvas", 5554 "test": function(Y) { 5555 var DOCUMENT = Y.config.doc, 5556 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", 5557 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5558 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5559 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 5560}, 5561 "trigger": "graphics" 5562}); 5563// graphics-canvas-default 5564add('load', '7', { 5565 "name": "graphics-canvas-default", 5566 "test": function(Y) { 5567 var DOCUMENT = Y.config.doc, 5568 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", 5569 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5570 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5571 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 5572}, 5573 "trigger": "graphics" 5574}); 5575// graphics-svg 5576add('load', '8', { 5577 "name": "graphics-svg", 5578 "test": function(Y) { 5579 var DOCUMENT = Y.config.doc, 5580 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 5581 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5582 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5583 5584 return svg && (useSVG || !canvas); 5585}, 5586 "trigger": "graphics" 5587}); 5588// graphics-svg-default 5589add('load', '9', { 5590 "name": "graphics-svg-default", 5591 "test": function(Y) { 5592 var DOCUMENT = Y.config.doc, 5593 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 5594 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 5595 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 5596 5597 return svg && (useSVG || !canvas); 5598}, 5599 "trigger": "graphics" 5600}); 5601// graphics-vml 5602add('load', '10', { 5603 "name": "graphics-vml", 5604 "test": function(Y) { 5605 var DOCUMENT = Y.config.doc, 5606 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 5607 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 5608}, 5609 "trigger": "graphics" 5610}); 5611// graphics-vml-default 5612add('load', '11', { 5613 "name": "graphics-vml-default", 5614 "test": function(Y) { 5615 var DOCUMENT = Y.config.doc, 5616 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 5617 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 5618}, 5619 "trigger": "graphics" 5620}); 5621// history-hash-ie 5622add('load', '12', { 5623 "name": "history-hash-ie", 5624 "test": function (Y) { 5625 var docMode = Y.config.doc && Y.config.doc.documentMode; 5626 5627 return Y.UA.ie && (!('onhashchange' in Y.config.win) || 5628 !docMode || docMode < 8); 5629}, 5630 "trigger": "history-hash" 5631}); 5632// io-nodejs 5633add('load', '13', { 5634 "name": "io-nodejs", 5635 "trigger": "io-base", 5636 "ua": "nodejs" 5637}); 5638// json-parse-shim 5639add('load', '14', { 5640 "name": "json-parse-shim", 5641 "test": function (Y) { 5642 var _JSON = Y.config.global.JSON, 5643 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 5644 nativeSupport = Y.config.useNativeJSONParse !== false && !!Native; 5645 5646 function workingNative( k, v ) { 5647 return k === "ok" ? true : v; 5648 } 5649 5650 // Double check basic functionality. This is mainly to catch early broken 5651 // implementations of the JSON API in Firefox 3.1 beta1 and beta2
5652 if ( nativeSupport ) { 5653 try { 5654 nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok; 5655 } 5656 catch ( e ) { 5657 nativeSupport = false; 5658 } 5659 } 5660 5661 return !nativeSupport; 5662}, 5663 "trigger": "json-parse" 5664}); 5665// json-stringify-shim 5666add('load', '15', { 5667 "name": "json-stringify-shim", 5668 "test": function (Y) { 5669 var _JSON = Y.config.global.JSON, 5670 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 5671 nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native; 5672 5673 // Double check basic native functionality. This is primarily to catch broken 5674 // early JSON API implementations in Firefox 3.1 beta1 and beta2. 5675 if ( nativeSupport ) { 5676 try { 5677 nativeSupport = ( '0' === Native.stringify(0) ); 5678 } catch ( e ) { 5679 nativeSupport = false; 5680 } 5681 } 5682 5683 5684 return !nativeSupport; 5685}, 5686 "trigger": "json-stringify" 5687}); 5688// scrollview-base-ie 5689add('load', '16', { 5690 "name": "scrollview-base-ie", 5691 "trigger": "scrollview-base", 5692 "ua": "ie" 5693}); 5694// selector-css2 5695add('load', '17', { 5696 "name": "selector-css2", 5697 "test": function (Y) { 5698 var DOCUMENT = Y.config.doc, 5699 ret = DOCUMENT && !('querySelectorAll' in DOCUMENT); 5700 5701 return ret; 5702}, 5703 "trigger": "selector" 5704}); 5705// transition-timer 5706add('load', '18', { 5707 "name": "transition-timer", 5708 "test": function (Y) { 5709 var DOCUMENT = Y.config.doc, 5710 node = (DOCUMENT) ? DOCUMENT.documentElement: null, 5711 ret = true; 5712 5713 if (node && node.style) { 5714 ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 5715 } 5716 5717 return ret; 5718}, 5719 "trigger": "transition" 5720}); 5721// widget-base-ie 5722add('load', '19', { 5723 "name": "widget-base-ie", 5724 "trigger": "widget-base", 5725 "ua": "ie" 5726}); 5727// yql-jsonp 5728add('load', '20', { 5729 "name": "yql-jsonp", 5730 "test": function (Y) { 5731 /* Only load the JSONP module when not in nodejs or winjs 5732 TODO Make the winjs module a CORS module 5733 */ 5734 return (!Y.UA.nodejs && !Y.UA.winjs); 5735}, 5736 "trigger": "yql" 5737}); 5738// yql-nodejs 5739add('load', '21', { 5740 "name": "yql-nodejs", 5741 "trigger": "yql", 5742 "ua": "nodejs" 5743}); 5744// yql-winjs 5745add('load', '22', { 5746 "name": "yql-winjs", 5747 "trigger": "yql", 5748 "ua": "winjs" 5749}); 5750 5751}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5752YUI.add('intl-base', function (Y, NAME) { 5753 5754/** 5755 * The Intl utility provides a central location for managing sets of 5756 * localized resources (strings and formatting patterns). 5757 * 5758 * @class Intl 5759 * @uses EventTarget 5760 * @static 5761 */ 5762 5763var SPLIT_REGEX = /[, ]/; 5764 5765Y.mix(Y.namespace('Intl'), { 5766 5767 /** 5768 * Returns the language among those available that 5769 * best matches the preferred language list, using the Lookup 5770 * algorithm of BCP 47. 5771 * If none of the available languages meets the user's preferences, 5772 * then "" is returned. 5773 * Extended language ranges are not supported. 5774 * 5775 * @method lookupBestLang 5776 * @param {String[] | String} preferredLanguages The list of preferred 5777 * languages in descending preference order, represented as BCP 47 5778 * language tags. A string array or a comma-separated list. 5779 * @param {String[]} availableLanguages The list of languages 5780 * that the application supports, represented as BCP 47 language 5781 * tags. 5782 * 5783 * @return {String} The available language that best matches the 5784 * preferred language list, or "". 5785 * @since 3.1.0 5786 */ 5787 lookupBestLang: function(preferredLanguages, availableLanguages) { 5788 5789 var i, language, result, index; 5790 5791 // check whether the list of available languages contains language; 5792 // if so return it 5793 function scan(language) { 5794 var i; 5795 for (i = 0; i < availableLanguages.length; i += 1) { 5796 if (language.toLowerCase() === 5797 availableLanguages[i].toLowerCase()) { 5798 return availableLanguages[i]; 5799 } 5800 } 5801 } 5802
5803 if (Y.Lang.isString(preferredLanguages)) { 5804 preferredLanguages = preferredLanguages.split(SPLIT_REGEX); 5805 } 5806 5807 for (i = 0; i < preferredLanguages.length; i += 1) { 5808 language = preferredLanguages[i]; 5809 if (!language || language === '*') { 5810 continue; 5811 } 5812 // check the fallback sequence for one language 5813 while (language.length > 0) { 5814 result = scan(language); 5815 if (result) { 5816 return result; 5817 } else { 5818 index = language.lastIndexOf('-'); 5819 if (index >= 0) { 5820 language = language.substring(0, index); 5821 // one-character subtags get cut along with the 5822 // following subtag 5823 if (index >= 2 && language.charAt(index - 2) === '-') { 5824 language = language.substring(0, index - 2); 5825 } 5826 } else { 5827 // nothing available for this language 5828 break; 5829 } 5830 } 5831 } 5832 } 5833 5834 return ''; 5835 } 5836}); 5837 5838 5839}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5840YUI.add('yui-log', function (Y, NAME) { 5841 5842/** 5843 * Provides console log capability and exposes a custom event for 5844 * console implementations. This module is a `core` YUI module, 5845 * <a href="../classes/YUI.html#method_log">it's documentation is located under the YUI class</a>. 5846 * 5847 * @module yui 5848 * @submodule yui-log 5849 */ 5850 5851var INSTANCE = Y, 5852 LOGEVENT = 'yui:log', 5853 UNDEFINED = 'undefined', 5854 LEVELS = { debug: 1, 5855 info: 2, 5856 warn: 4, 5857 error: 8 }; 5858 5859/** 5860 * If the 'debug' config is true, a 'yui:log' event will be 5861 * dispatched, which the Console widget and anything else 5862 * can consume. If the 'useBrowserConsole' config is true, it will 5863 * write to the browser console if available. YUI-specific log 5864 * messages will only be present in the -debug versions of the 5865 * JS files. The build system is supposed to remove log statements 5866 * from the raw and minified versions of the files. 5867 * 5868 * @method log 5869 * @for YUI 5870 * @param {String} msg The message to log. 5871 * @param {String} cat The log category for the message. Default 5872 * categories are "info", "warn", "error", "debug". 5873 * Custom categories can be used as well. (opt). 5874 * @param {String} src The source of the the message (opt). 5875 * @param {boolean} silent If true, the log event won't fire. 5876 * @return {YUI} YUI instance. 5877 */ 5878INSTANCE.log = function(msg, cat, src, silent) { 5879 var bail, excl, incl, m, f, minlevel, 5880 Y = INSTANCE, 5881 c = Y.config, 5882 publisher = (Y.fire) ? Y : YUI.Env.globalEvents; 5883 // suppress log message if the config is off or the event stack 5884 // or the event call stack contains a consumer of the yui:log event 5885 if (c.debug) { 5886 // apply source filters 5887 src = src || ""; 5888 if (typeof src !== "undefined") { 5889 excl = c.logExclude; 5890 incl = c.logInclude; 5891 if (incl && !(src in incl)) { 5892 bail = 1; 5893 } else if (incl && (src in incl)) { 5894 bail = !incl[src]; 5895 } else if (excl && (src in excl)) { 5896 bail = excl[src]; 5897 } 5898 5899 // Set a default category of info if the category was not defined. 5900 if ((typeof cat === 'undefined')) { 5901 cat = 'info'; 5902 } 5903 5904 // Determine the current minlevel as defined in configuration 5905 Y.config.logLevel = Y.config.logLevel || 'debug'; 5906 minlevel = LEVELS[Y.config.logLevel.toLowerCase()]; 5907 5908 if (cat in LEVELS && LEVELS[cat] < minlevel) { 5909 // Skip this message if the we don't meet the defined minlevel 5910 bail = 1; 5911 } 5912 } 5913 if (!bail) { 5914 if (c.useBrowserConsole) { 5915 m = (src) ? src + ': ' + msg : msg; 5916 if (Y.Lang.isFunction(c.logFn)) { 5917 c.logFn.call(Y, msg, cat, src); 5918 } else if (typeof console !== UNDEFINED && console.log) { 5919 f = (cat && console[cat] && (cat in LEVELS)) ? cat : 'log'; 5920 console[f](m); 5921 } else if (typeof opera !== UNDEFINED) { 5922 opera.postError(m); 5923 } 5924 } 5925 5926 if (publisher && !silent) { 5927 5928 if (publisher === Y && (!publisher.getEvent(LOGEVENT))) { 5929 publisher.publish(LOGEVENT, { 5930 broadcast: 2 5931 }); 5932 } 5933 5934 publisher.fire(LOGEVENT, { 5935 msg: msg, 5936 cat: cat, 5937 src: src 5938 }); 5939 } 5940 } 5941 } 5942 5943 return Y; 5944}; 5945 5946/** 5947 * Write a system message. This message will be preserved in the 5948 * minified and raw versions of the YUI files, unlike log statements. 5949 * @method message 5950 * @for YUI 5951 * @param {String} msg The message to log. 5952 * @param {String} cat The log category for the message. Default 5953 * categories are "info", "warn", "error", "debug". 5954 * Custom categories can be used as well. (opt). 5955 * @param {String} src The source of the the message (opt). 5956 * @param {boolean} silent If true, the log event won't fire. 5957 * @return {YUI} YUI instance. 5958 */ 5959INSTANCE.message = function() { 5960 return INSTANCE.log.apply(INSTANCE, arguments); 5961}; 5962 5963 5964}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 5965YUI.add('yui-later', function (Y, NAME) { 5966 5967/** 5968 * Provides a setTimeout/setInterval wrapper. This module is a `core` YUI module, 5969 * <a href="../classes/YUI.html#method_later">
5969it's documentation is located under the YUI class</a>. 5970 * 5971 * @module yui 5972 * @submodule yui-later 5973 */ 5974 5975var NO_ARGS = []; 5976 5977/** 5978 * Executes the supplied function in the context of the supplied 5979 * object 'when' milliseconds later. Executes the function a 5980 * single time unless periodic is set to true. 5981 * @for YUI 5982 * @method later 5983 * @param when {Number} the number of milliseconds to wait until the fn 5984 * is executed. 5985 * @param o the context object. 5986 * @param fn {Function|String} the function to execute or the name of 5987 * the method in the 'o' object to execute. 5988 * @param data [Array] data that is provided to the function. This 5989 * accepts either a single item or an array. If an array is provided, 5990 * the function is executed with one parameter for each array item. 5991 * If you need to pass a single array parameter, it needs to be wrapped 5992 * in an array [myarray]. 5993 * 5994 * Note: native methods in IE may not have the call and apply methods. 5995 * In this case, it will work, but you are limited to four arguments. 5996 * 5997 * @param periodic {boolean} if true, executes continuously at supplied 5998 * interval until canceled. 5999 * @return {object} a timer object. Call the cancel() method on this 6000 * object to stop the timer. 6001 */ 6002Y.later = function(when, o, fn, data, periodic) { 6003 when = when || 0; 6004 data = (!Y.Lang.isUndefined(data)) ? Y.Array(data) : NO_ARGS; 6005 o = o || Y.config.win || Y; 6006 6007 var cancelled = false, 6008 method = (o && Y.Lang.isString(fn)) ? o[fn] : fn, 6009 wrapper = function() { 6010 // IE 8- may execute a setInterval callback one last time 6011 // after clearInterval was called, so in order to preserve 6012 // the cancel() === no more runny-run, we have to jump through 6013 // an extra hoop. 6014 if (!cancelled) { 6015 if (!method.apply) { 6016 method(data[0], data[1], data[2], data[3]); 6017 } else { 6018 method.apply(o, data || NO_ARGS); 6019 } 6020 } 6021 }, 6022 id = (periodic) ? setInterval(wrapper, when) : setTimeout(wrapper, when); 6023 6024 return { 6025 id: id, 6026 interval: periodic, 6027 cancel: function() { 6028 cancelled = true; 6029 if (this.interval) { 6030 clearInterval(id); 6031 } else { 6032 clearTimeout(id); 6033 } 6034 } 6035 }; 6036}; 6037 6038Y.Lang.later = Y.later; 6039 6040 6041 6042}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 6043YUI.add('loader-base', function (Y, NAME) { 6044 6045/** 6046 * The YUI loader core 6047 * @module loader 6048 * @submodule loader-base 6049 */ 6050 6051(function() { 6052 var VERSION = Y.version, 6053 BUILD = '/build/', 6054 ROOT = VERSION + '/', 6055 CDN_BASE = Y.Env.base, 6056 GALLERY_VERSION = 'gallery-2014.06.04-21-38', 6057 TNT = '2in3', 6058 TNT_VERSION = '4', 6059 YUI2_VERSION = '2.9.0', 6060 COMBO_BASE = CDN_BASE + 'combo?', 6061 META = { 6062 version: VERSION, 6063 root: ROOT, 6064 base: Y.Env.base, 6065 comboBase: COMBO_BASE, 6066 skin: { 6067 defaultSkin: 'sam', 6068 base: 'assets/skins/', 6069 path: 'skin.css', 6070 after: [ 6071 'cssreset', 6072 'cssfonts', 6073 'cssgrids', 6074 'cssbase', 6075 'cssreset-context', 6076 'cssfonts-context' 6077 ] 6078 }, 6079 groups: {}, 6080 patterns: {} 6081 }, 6082 groups = META.groups, 6083 yui2Update = function(tnt, yui2, config) { 6084 var root = TNT + '.' + 6085 (tnt || TNT_VERSION) + '/' + 6086 (yui2 || YUI2_VERSION) + BUILD, 6087 base = (config && config.base) ? config.base : CDN_BASE, 6088 combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE; 6089 6090 groups.yui2.base = base + root; 6091 groups.yui2.root = root; 6092 groups.yui2.comboBase = combo; 6093 }, 6094 galleryUpdate = function(tag, config) { 6095 var root = (tag || GALLERY_VERSION) + BUILD, 6096 base = (config && config.base) ? config.base : CDN_BASE, 6097 combo = (config && config.comboBase) ? config.comboBase : COMBO_BASE; 6098 6099 groups.gallery.base = base + root; 6100 groups.gallery.root = root; 6101 groups.gallery.comboBase = combo; 6102 }; 6103 6104 6105 groups[VERSION] = {}; 6106 6107 groups.gallery = { 6108 ext: false, 6109 combine: true, 6110 comboBase: COMBO_BASE, 6111 update: galleryUpdate, 6112 patterns: { 6113 'gallery-': {}, 6114 'lang/gallery-': {}, 6115 'gallerycss-': { 6116 type: 'css' 6117 } 6118 } 6119 }; 6120 6121 groups.yui2 = { 6122 combine: true, 6123 ext: false, 6124 comboBase: COMBO_BASE, 6125 update: yui2Update, 6126 patterns: { 6127 'yui2-': { 6128 configFn: function(me) { 6129 if (/-skin|reset|fonts|grids|base/.test(me.name)) { 6130 me.type = 'css'; 6131 me.path = me.path.replace(/\.js/, '.css'); 6132 // this makes skins in builds earlier than 6133 // 2.6.0 work as long as combine is false 6134 me.path = me.path.replace(/\/yui2-skin/, 6135 '/assets/skins/sam/yui2-skin'); 6136 } 6137 } 6138 } 6139 } 6140 }; 6141 6142 galleryUpdate(); 6143 yui2Update(); 6144 6145 if (YUI.Env[VERSION]) { 6146 Y.mix(META, YUI.Env[VERSION], false, [ 6147 'modules', 6148 'groups', 6149 'skin' 6150 ], 0, true); 6151 } 6152 6153 YUI.Env[VERSION] = META; 6154}()); 6155/*jslint forin: true, maxlen: 350 */ 6156 6157/** 6158 * Loader dynamically loads script and css files. It includes the dependency 6159 * information for the version of the library in use, and will automatically pull in 6160 * dependencies for the modules requested. It can also load the 6161 * files from the Yahoo! CDN, and it can utilize the combo service provided on 6162 * this network to reduce the number of http connections required to download 6163 * YUI files. 6164 * 6165 * @module loader 6166 * @main loader 6167 * @submodule loader-base 6168 */ 6169 6170var NOT_FOUND = {}, 6171 NO_REQUIREMENTS = [], 6172 MAX_URL_LENGTH = 1024, 6173 GLOBAL_ENV = YUI.Env, 6174 GLOBAL_LOADED = GLOBAL_ENV._loaded, 6175 CSS = 'css', 6176 JS = 'js', 6177 INTL = 'intl', 6178 DEFAULT_SKIN = 'sam',
6179 VERSION = Y.version, 6180 ROOT_LANG = '', 6181 YObject = Y.Object, 6182 oeach = YObject.each, 6183 yArray = Y.Array, 6184 _queue = GLOBAL_ENV._loaderQueue, 6185 META = GLOBAL_ENV[VERSION], 6186 SKIN_PREFIX = 'skin-', 6187 L = Y.Lang, 6188 ON_PAGE = GLOBAL_ENV.mods, 6189 modulekey, 6190 _path = function(dir, file, type, nomin) { 6191 var path = dir + '/' + file; 6192 if (!nomin) { 6193 path += '-min'; 6194 } 6195 path += '.' + (type || CSS); 6196 6197 return path; 6198 }; 6199 6200 6201 if (!YUI.Env._cssLoaded) { 6202 YUI.Env._cssLoaded = {}; 6203 } 6204 6205 6206/** 6207 * The component metadata is stored in Y.Env.meta. 6208 * Part of the loader module. 6209 * @property meta 6210 * @for YUI 6211 */ 6212Y.Env.meta = META; 6213 6214/** 6215 * Loader dynamically loads script and css files. It includes the dependency 6216 * info for the version of the library in use, and will automatically pull in 6217 * dependencies for the modules requested. It can load the 6218 * files from the Yahoo! CDN, and it can utilize the combo service provided on 6219 * this network to reduce the number of http connections required to download 6220 * YUI files. You can also specify an external, custom combo service to host 6221 * your modules as well. 6222 6223 var Y = YUI(); 6224 var loader = new Y.Loader({ 6225 filter: 'debug', 6226 base: '../../', 6227 root: 'build/', 6228 combine: true, 6229 require: ['node', 'dd', 'console'] 6230 }); 6231 var out = loader.resolve(true); 6232 6233 * If the Loader needs to be patched before it is used for the first time, it 6234 * should be done through the `doBeforeLoader` hook. Simply make the patch 6235 * available via configuration before YUI is loaded: 6236 6237 YUI_config = YUI_config || {}; 6238 YUI_config.doBeforeLoader = function (config) { 6239 var resolve = this.context.Loader.prototype.resolve; 6240 this.context.Loader.prototype.resolve = function () { 6241 // do something here 6242 return resolve.apply(this, arguments); 6243 }; 6244 }; 6245 6246 * @constructor 6247 * @class Loader 6248 * @param {Object} config an optional set of configuration options. 6249 * @param {String} config.base The base dir which to fetch this module from 6250 * @param {String} config.comboBase The Combo service base path. Ex: `http://yui.yahooapis.com/combo?` 6251 * @param {String} config.root The root path to prepend to module names for the combo service. Ex: `2.5.2/build/` 6252 * @param {String|Object} config.filter A filter to apply to result urls. <a href="#property_filter">See filter property</a> 6253 * @param {Object} config.filters Per-component filter specification. If specified for a given component, this overrides the filter config. 6254 * @param {Boolean} config.combine Use a combo service to reduce the number of http connections required to load your dependencies 6255 * @param {Boolean} [config.async=true] Fetch files in async 6256 * @param {Array} config.ignore: A list of modules that should never be dynamically loaded 6257 * @param {Array} config.force A list of modules that should always be loaded when required, even if already present on the page 6258 * @param {HTMLElement|String} config.insertBefore Node or id for a node that should be used as the insertion point for new nodes 6259 * @param {Object} config.jsAttributes Object literal containing attributes to add to script nodes 6260 * @param {Object} config.cssAttributes Object literal containing attributes to add to link nodes 6261 * @param {Number} config.timeout The number of milliseconds before a timeout occurs when dynamically loading nodes. If not set, there is no timeout 6262 * @param {Object} config.context Execution context for all callbacks 6263 * @param {Function} config.onSuccess Callback for the 'success' event 6264 * @param {Function} config.onFailure Callback for the 'failure' event 6265 * @param {Function} config.onTimeout Callback for the 'timeout' event 6266 * @param {Function} config.onProgress Callback executed each time a script or css file is loaded 6267 * @param {Object} config.modules A list of module definitions. See <a href="#method_addModule">Loader.addModule</a> for the supported module metadata 6268 * @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`. 6269 * @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. 6270 * @param {String} config.yui2 When using the 2in3 project, you can select the version of YUI 2 to use. V
6270alid 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. 6271 * @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. 6272 */ 6273Y.Loader = function(o) { 6274 6275 var self = this; 6276 6277 //Catch no config passed. 6278 o = o || {}; 6279 6280 modulekey = META.md5; 6281 6282 /** 6283 * Internal callback to handle multiple internal insert() calls 6284 * so that css is inserted prior to js 6285 * @property _internalCallback 6286 * @private 6287 */ 6288 // self._internalCallback = null; 6289 6290 /** 6291 * Callback that will be executed when the loader is finished 6292 * with an insert 6293 * @method onSuccess 6294 * @type function 6295 */ 6296 // self.onSuccess = null; 6297 6298 /** 6299 * Callback that will be executed if there is a failure 6300 * @method onFailure 6301 * @type function 6302 */ 6303 // self.onFailure = null; 6304 6305 /** 6306 * Callback executed each time a script or css file is loaded 6307 * @method onProgress 6308 * @type function 6309 */ 6310 // self.onProgress = null; 6311 6312 /** 6313 * Callback that will be executed if a timeout occurs 6314 * @method onTimeout 6315 * @type function 6316 */ 6317 // self.onTimeout = null; 6318 6319 /** 6320 * The execution context for all callbacks 6321 * @property context 6322 * @default {YUI} the YUI instance 6323 */ 6324 self.context = Y; 6325 6326 // Hook that allows the patching of loader 6327 if (o.doBeforeLoader) { 6328 o.doBeforeLoader.apply(self, arguments); 6329 } 6330 6331 /** 6332 * Data that is passed to all callbacks 6333 * @property data 6334 */ 6335 // self.data = null; 6336 6337 /** 6338 * Node reference or id where new nodes should be inserted before 6339 * @property insertBefore 6340 * @type string|HTMLElement 6341 */ 6342 // self.insertBefore = null; 6343 6344 /** 6345 * The charset attribute for inserted nodes 6346 * @property charset 6347 * @type string 6348 * @deprecated , use cssAttributes or jsAttributes. 6349 */ 6350 // self.charset = null; 6351 6352 /** 6353 * An object literal containing attributes to add to link nodes 6354 * @property cssAttributes 6355 * @type object 6356 */ 6357 // self.cssAttributes = null; 6358 6359 /** 6360 * An object literal containing attributes to add to script nodes 6361 * @property jsAttributes 6362 * @type object 6363 */ 6364 // self.jsAttributes = null; 6365 6366 /** 6367 * The base directory. 6368 * @property base 6369 * @type string 6370 * @default http://yui.yahooapis.com/[YUI VERSION]/build/ 6371 */ 6372 self.base = Y.Env.meta.base + Y.Env.meta.root; 6373 6374 /** 6375 * Base path for the combo service 6376 * @property comboBase 6377 * @type string 6378 * @default http://yui.yahooapis.com/combo? 6379 */ 6380 self.comboBase = Y.Env.meta.comboBase; 6381 6382 /* 6383 * Base path for language packs. 6384 */ 6385 // self.langBase = Y.Env.meta.langBase; 6386 // self.lang = ""; 6387 6388 /** 6389 * If configured, the loader will attempt to use the combo 6390 * service for YUI resources and configured external resources. 6391 * @property combine 6392 * @type boolean 6393 * @default true if a base dir isn't in the config 6394 */ 6395 self.combine = o.base && 6396 (o.base.indexOf(self.comboBase.substr(0, 20)) > -1); 6397 6398 /** 6399 * The default seperator to use between files in a combo URL 6400 * @property comboSep 6401 * @type {String} 6402 * @default Ampersand 6403 */ 6404 self.comboSep = '&'; 6405 /** 6406 * Max url length for combo urls. The default is 1024. This is the URL 6407 * limit for the Yahoo! hosted combo servers. If consuming 6408 * a different combo service that has a different URL limit 6409 * it is possible to override this default by supplying 6410 * the maxURLLength config option. The config option will 6411 * only take effect if lower than the default. 6412 * 6413 * @property maxURLLength 6414 * @type int 6415 */ 6416 self.maxURLLength = MAX_URL_LENGTH; 6417 6418 /** 6419 * Ignore modules registered on the YUI global 6420 * @property ignoreRegistered 6421 * @default false 6422 */ 6423 self.ignoreRegistered = o.ignoreRegistered; 6424 6425 /**
6426 * Root path to prepend to module path for the combo 6427 * service 6428 * @property root 6429 * @type string 6430 * @default [YUI VERSION]/build/ 6431 */ 6432 self.root = Y.Env.meta.root; 6433 6434 /** 6435 * Timeout value in milliseconds. If set, self value will be used by 6436 * the get utility. the timeout event will fire if 6437 * a timeout occurs. 6438 * @property timeout 6439 * @type int 6440 */ 6441 self.timeout = 0; 6442 6443 /** 6444 * A list of modules that should not be loaded, even if 6445 * they turn up in the dependency tree 6446 * @property ignore 6447 * @type string[] 6448 */ 6449 // self.ignore = null; 6450 6451 /** 6452 * A list of modules that should always be loaded, even 6453 * if they have already been inserted into the page. 6454 * @property force 6455 * @type string[] 6456 */ 6457 // self.force = null; 6458 6459 self.forceMap = {}; 6460 6461 /** 6462 * Should we allow rollups 6463 * @property allowRollup 6464 * @type boolean 6465 * @default false 6466 */ 6467 self.allowRollup = false; 6468 6469 /** 6470 * A filter to apply to result urls. This filter will modify the default 6471 * path for all modules. The default path for the YUI library is the 6472 * minified version of the files (e.g., event-min.js). The filter property 6473 * can be a predefined filter or a custom filter. The valid predefined 6474 * filters are: 6475 * <dl> 6476 * <dt>DEBUG</dt> 6477 * <dd>Selects the debug versions of the library (e.g., event-debug.js). 6478 * This option will automatically include the Logger widget</dd> 6479 * <dt>RAW</dt> 6480 * <dd>Selects the non-minified version of the library (e.g., event.js). 6481 * </dd> 6482 * </dl> 6483 * You can also define a custom filter, which must be an object literal 6484 * containing a search expression and a replace string: 6485 * 6486 * myFilter: { 6487 * 'searchExp': "-min\\.js", 6488 * 'replaceStr': "-debug.js" 6489 * } 6490 * 6491 * @property filter 6492 * @type string| {searchExp: string, replaceStr: string} 6493 */ 6494 // self.filter = null; 6495 6496 /** 6497 * per-component filter specification. If specified for a given 6498 * component, this overrides the filter config. 6499 * @property filters 6500 * @type object 6501 */ 6502 self.filters = {}; 6503 6504 /** 6505 * The list of requested modules 6506 * @property required 6507 * @type {string: boolean} 6508 */ 6509 self.required = {}; 6510 6511 /** 6512 * If a module name is predefined when requested, it is checked againsts 6513 * the patterns provided in this property. If there is a match, the 6514 * module is added with the default configuration. 6515 * 6516 * At the moment only supporting module prefixes, but anticipate 6517 * supporting at least regular expressions. 6518 * @property patterns 6519 * @type Object 6520 */ 6521 // self.patterns = Y.merge(Y.Env.meta.patterns); 6522 self.patterns = {}; 6523 6524 /** 6525 * Internal loader instance metadata. Use accessor `getModuleInfo()` instead. 6526 */ 6527 self.moduleInfo = {}; 6528 6529 self.groups = Y.merge(Y.Env.meta.groups); 6530 6531 /** 6532 * Provides the information used to skin the skinnable components. 6533 * The following skin definition would result in 'skin1' and 'skin2' 6534 * being loaded for calendar (if calendar was requested), and 6535 * 'sam' for all other skinnable components: 6536 * 6537 * skin: { 6538 * // The default skin, which is automatically applied if not 6539 * // overriden by a component-specific skin definition. 6540 * // Change this in to apply a different skin globally 6541 * defaultSkin: 'sam', 6542 * 6543 * // This is combined with the loader base property to get 6544 * // the default root directory for a skin. ex: 6545 * // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/ 6546 * base: 'assets/skins/', 6547 * 6548 * // Any component-specific overrides can be specified here, 6549 * // making it possible to load different skins for different 6550 * // components. It is possible to load more than one skin 6551 * // for a given component as well. 6552 * overrides: { 6553 * calendar: ['skin1', 'skin2'] 6554 * } 6555 * } 6556 * @property skin 6557 * @type {Object} 6558 */ 6559 self.skin = Y.merge(Y.Env.meta.skin); 6560 6561 /* 6562 * Map of conditional modules 6563 * @since 3.2.0 6564 */ 6565 self.conditions = {}; 6566 6567 // map of modules with a hash of modules that meet the requirement 6568 // self.provides = {}; 6569 6570 self.config = o; 6571 self._internal = true; 6572 6573 self._populateConditionsCache(); 6574 6575 /** 6576 * Set when beginning to compute the dependency tree. 6577 * Composed of what YUI reports to be loaded combined 6578 * with what has been loaded by any instance on the page 6579 * with the version number specified in the metadata. 6580 * @property loaded 6581 * @type {string: boolean} 6582 */ 6583 self.loaded = GLOBAL_LOADED[VERSION]; 6584 6585 6586 /** 6587 * Should Loader fetch scripts in `async`, defaults to `true` 6588 * @property async 6589 */ 6590 6591 self.async = true; 6592 6593 self._inspectPage(); 6594 6595 self._internal = false;
6596 6597 self._config(o); 6598 6599 self.forceMap = (self.force) ? Y.Array.hash(self.force) : {}; 6600 6601 self.testresults = null; 6602 6603 if (Y.config.tests) { 6604 self.testresults = Y.config.tests; 6605 } 6606 6607 /** 6608 * List of rollup files found in the library metadata 6609 * @property rollups 6610 */ 6611 // self.rollups = null; 6612 6613 /** 6614 * Whether or not to load optional dependencies for 6615 * the requested modules 6616 * @property loadOptional 6617 * @type boolean 6618 * @default false 6619 */ 6620 // self.loadOptional = false; 6621 6622 /** 6623 * All of the derived dependencies in sorted order, which 6624 * will be populated when either calculate() or insert() 6625 * is called 6626 * @property sorted 6627 * @type string[] 6628 */ 6629 self.sorted = []; 6630 6631 /* 6632 * A list of modules to attach to the YUI instance when complete. 6633 * If not supplied, the sorted list of dependencies are applied. 6634 * @property attaching 6635 */ 6636 // self.attaching = null; 6637 6638 /** 6639 * Flag to indicate the dependency tree needs to be recomputed 6640 * if insert is called again. 6641 * @property dirty 6642 * @type boolean 6643 * @default true 6644 */ 6645 self.dirty = true; 6646 6647 /** 6648 * List of modules inserted by the utility 6649 * @property inserted 6650 * @type {string: boolean} 6651 */ 6652 self.inserted = {}; 6653 6654 /** 6655 * List of skipped modules during insert() because the module 6656 * was not defined 6657 * @property skipped 6658 */ 6659 self.skipped = {}; 6660 6661 // Y.on('yui:load', self.loadNext, self); 6662 6663 self.tested = {}; 6664 6665 /* 6666 * Cached sorted calculate results 6667 * @property results 6668 * @since 3.2.0 6669 */ 6670 //self.results = {}; 6671 6672 if (self.ignoreRegistered) { 6673 //Clear inpage already processed modules. 6674 self._resetModules(); 6675 } 6676 6677}; 6678 6679Y.Loader.prototype = { 6680 /** 6681 * Gets the module info from the local moduleInfo hash, or from the 6682 * default metadata and populate the local moduleInfo hash. 6683 * @method getModuleInfo 6684 * @param {string} name of the module 6685 * @public 6686 */ 6687 getModuleInfo: function(name) { 6688 6689 var m = this.moduleInfo[name], 6690 rawMetaModules, globalRenderedMods, internal, v; 6691 6692 if (m) { 6693 return m; 6694 } 6695 6696 rawMetaModules = META.modules; 6697 globalRenderedMods = GLOBAL_ENV._renderedMods; 6698 internal = this._internal; 6699 6700 /* 6701 The logic here is: 6702 6703 - if the `moduleInfo[name]` is avilable, 6704 then short circuit 6705 - otherwise, if the module is in the globalCache (cross Y instance), 6706 then port it from the global registry into `moduleInfo[name]` 6707 - otherwise, if the module has raw metadata (from meta modules) 6708 then add it to the global registry and to `moduleInfo[name]` 6709 6710 */ 6711 if (globalRenderedMods && globalRenderedMods.hasOwnProperty(name) && !this.ignoreRegistered) { 6712 this.moduleInfo[name] = Y.merge(globalRenderedMods[name]); 6713 } else { 6714 if (rawMetaModules.hasOwnProperty(name)) { 6715 this._internal = true; // making sure that modules from raw data are marked as internal 6716 v = this.addModule(rawMetaModules[name], name); 6717 // Inspect the page for the CSS module and mark it as loaded. 6718 if (v && v.type === CSS) { 6719 if (this.isCSSLoaded(v.name, true)) { 6720 this.loaded[v.name] = true; 6721 } 6722 } 6723 this._internal = internal; 6724 } 6725 } 6726 return this.moduleInfo[name]; 6727 }, 6728 /** 6729 * Expand the names that are aliases to other modules. 6730 * @method _expandAliases 6731 * @param {string[]} list a module name or a list of names to be expanded 6732 * @private 6733 * @return {array} 6734 */ 6735 _expandAliases: function(list) { 6736 var expanded = [], 6737 aliases = YUI.Env.aliases, 6738 i, name; 6739 list = Y.Array(list); 6740 for (i = 0; i < list.length; i += 1) { 6741 name = list[i]; 6742 expanded.push.apply(expanded, aliases[name] ? aliases[name] : [name]); 6743 } 6744 return expanded; 6745 }, 6746 /** 6747 * Populate the conditions cache from raw modules, this is necessary 6748 * because no other module will require a conditional module, instead 6749 * the condition has to be executed and then the module is analyzed 6750 * to be included in the final requirement list. Without this cache 6751 * conditional modules will be simply ignored. 6752 * @method _populateConditionsCache 6753 * @private 6754 */ 6755 _populateConditionsCache: function() { 6756 var rawMetaModules = META.modules,
6757 cache = GLOBAL_ENV._conditions, 6758 i, j, t, trigger; 6759 6760 // if we have conditions in cache and cache is enabled 6761 // we should port them to this loader instance 6762 if (cache && !this.ignoreRegistered) { 6763 for (i in cache) { 6764 if (cache.hasOwnProperty(i)) { 6765 this.conditions[i] = Y.merge(cache[i]); 6766 } 6767 } 6768 } else { 6769 for (i in rawMetaModules) { 6770 if (rawMetaModules.hasOwnProperty(i) && rawMetaModules[i].condition) { 6771 t = this._expandAliases(rawMetaModules[i].condition.trigger); 6772 for (j = 0; j < t.length; j += 1) { 6773 trigger = t[j]; 6774 this.conditions[trigger] = this.conditions[trigger] || {}; 6775 this.conditions[trigger][rawMetaModules[i].name || i] = rawMetaModules[i].condition; 6776 } 6777 } 6778 } 6779 GLOBAL_ENV._conditions = this.conditions; 6780 } 6781 }, 6782 /** 6783 * Reset modules in the module cache to a pre-processed state so additional 6784 * computations with a different skin or language will work as expected. 6785 * @method _resetModules 6786 * @private 6787 */ 6788 _resetModules: function() { 6789 var self = this, i, o, 6790 mod, name, details; 6791 for (i in self.moduleInfo) { 6792 if (self.moduleInfo.hasOwnProperty(i) && self.moduleInfo[i]) { 6793 mod = self.moduleInfo[i]; 6794 name = mod.name; 6795 details = (YUI.Env.mods[name] ? YUI.Env.mods[name].details : null); 6796 6797 if (details) { 6798 self.moduleInfo[name]._reset = true; 6799 self.moduleInfo[name].requires = details.requires || []; 6800 self.moduleInfo[name].optional = details.optional || []; 6801 self.moduleInfo[name].supersedes = details.supercedes || []; 6802 } 6803 6804 if (mod.defaults) { 6805 for (o in mod.defaults) { 6806 if (mod.defaults.hasOwnProperty(o)) { 6807 if (mod[o]) { 6808 mod[o] = mod.defaults[o]; 6809 } 6810 } 6811 } 6812 } 6813 mod.langCache = undefined; 6814 mod.skinCache = undefined; 6815 if (mod.skinnable) { 6816 self._addSkin(self.skin.defaultSkin, mod.name); 6817 } 6818 } 6819 } 6820 }, 6821 /** 6822 Regex that matches a CSS URL. Used to guess the file type when it's not 6823 specified. 6824 6825 @property REGEX_CSS 6826 @type RegExp 6827 @final 6828 @protected 6829 @since 3.5.0 6830 **/ 6831 REGEX_CSS: /\.css(?:[?;].*)?$/i, 6832 6833 /** 6834 * Default filters for raw and debug 6835 * @property FILTER_DEFS 6836 * @type Object 6837 * @final 6838 * @protected 6839 */ 6840 FILTER_DEFS: { 6841 RAW: { 6842 'searchExp': '-min\\.js', 6843 'replaceStr': '.js' 6844 }, 6845 DEBUG: { 6846 'searchExp': '-min\\.js', 6847 'replaceStr': '-debug.js' 6848 }, 6849 COVERAGE: { 6850 'searchExp': '-min\\.js', 6851 'replaceStr': '-coverage.js' 6852 } 6853 }, 6854 /* 6855 * Check the pages meta-data and cache the result. 6856 * @method _inspectPage 6857 * @private 6858 */ 6859 _inspectPage: function() { 6860 var self = this, v, m, req, mr, i; 6861 6862 for (i in ON_PAGE) { 6863 if (ON_PAGE.hasOwnProperty(i)) { 6864 v = ON_PAGE[i]; 6865 if (v.details) { 6866 m = self.getModuleInfo(v.name); 6867 req = v.details.requires; 6868 mr = m && m.requires; 6869 6870 if (m) { 6871 if (!m._inspected && req && mr.length !== req.length) { 6872 // console.log('deleting ' + m.name); 6873 delete m.expanded; 6874 } 6875 } else { 6876 m = self.addModule(v.details, i); 6877 } 6878 m._inspected = true; 6879 } 6880 } 6881 } 6882 }, 6883 /* 6884 * returns true if b is not loaded, and is required directly or by means of modules it supersedes. 6885 * @private 6886 * @method _requires 6887 * @param {String} mod1 The first module to compare 6888 * @param {String} mod2 The second module to compare 6889 */ 6890 _requires: function(mod1, mod2) { 6891 6892 var i, rm, after_map, s, 6893 m = this.getModuleInfo(mod1), 6894 other = this.getModuleInfo(mod2); 6895
6896 if (!m || !other) { 6897 return false; 6898 } 6899 6900 rm = m.expanded_map; 6901 after_map = m.after_map; 6902 6903 // check if this module should be sorted after the other 6904 // do this first to short circut circular deps 6905 if (after_map && (mod2 in after_map)) { 6906 return true; 6907 } 6908 6909 after_map = other.after_map; 6910 6911 // and vis-versa 6912 if (after_map && (mod1 in after_map)) { 6913 return false; 6914 } 6915 6916 // check if this module requires one the other supersedes 6917 s = other.supersedes; 6918 if (s) { 6919 for (i = 0; i < s.length; i++) { 6920 if (this._requires(mod1, s[i])) { 6921 return true; 6922 } 6923 } 6924 } 6925 6926 s = m.supersedes; 6927 if (s) { 6928 for (i = 0; i < s.length; i++) { 6929 if (this._requires(mod2, s[i])) { 6930 return false; 6931 } 6932 } 6933 } 6934 6935 // check if this module requires the other directly 6936 // if (r && yArray.indexOf(r, mod2) > -1) { 6937 if (rm && (mod2 in rm)) { 6938 return true; 6939 } 6940 6941 // external css files should be sorted below yui css 6942 if (m.ext && m.type === CSS && !other.ext && other.type === CSS) { 6943 return true; 6944 } 6945 6946 return false; 6947 }, 6948 /** 6949 * Apply a new config to the Loader instance 6950 * @method _config 6951 * @private 6952 * @param {Object} o The new configuration 6953 */ 6954 _config: function(o) { 6955 var i, j, val, a, f, group, groupName, self = this, 6956 mods = [], mod, modInfo; 6957 // apply config values 6958 if (o) { 6959 for (i in o) { 6960 if (o.hasOwnProperty(i)) { 6961 val = o[i]; 6962 //TODO This should be a case 6963 if (i === 'require') { 6964 self.require(val); 6965 } else if (i === 'skin') { 6966 //If the config.skin is a string, format to the expected object 6967 if (typeof val === 'string') { 6968 self.skin.defaultSkin = o.skin; 6969 val = { 6970 defaultSkin: val 6971 }; 6972 } 6973 6974 Y.mix(self.skin, val, true); 6975 } else if (i === 'groups') { 6976 for (j in val) { 6977 if (val.hasOwnProperty(j)) { 6978 groupName = j; 6979 group = val[j]; 6980 self.addGroup(group, groupName); 6981 if (group.aliases) { 6982 for (a in group.aliases) { 6983 if (group.aliases.hasOwnProperty(a)) { 6984 self.addAlias(group.aliases[a], a); 6985 } 6986 } 6987 } 6988 } 6989 } 6990 6991 } else if (i === 'modules') { 6992 // add a hash of module definitions 6993 for (j in val) { 6994 if (val.hasOwnProperty(j)) { 6995 self.addModule(val[j], j); 6996 } 6997 } 6998 } else if (i === 'aliases') { 6999 for (j in val) { 7000 if (val.hasOwnProperty(j)) { 7001 self.addAlias(val[j], j); 7002 } 7003 } 7004 } else if (i === 'gallery') { 7005 if (this.groups.gallery.update) { 7006 this.groups.gallery.update(val, o); 7007 } 7008 } else if (i === 'yui2' || i === '2in3') { 7009 if (this.groups.yui2.update) { 7010 this.groups.yui2.update(o['2in3'], o.yui2, o); 7011 } 7012 } else { 7013 self[i] = val; 7014 } 7015 } 7016 } 7017 } 7018 7019 // fix filter 7020 f = self.filter; 7021 7022 if (L.isString(f)) { 7023 f = f.toUpperCase(); 7024 self.filterName = f; 7025 self.filter = self.FILTER_DEFS[f]; 7026 if (f === 'DEBUG') { 7027 self.require('yui-log', 'dump'); 7028 } 7029 } 7030 7031 if (self.filterName && self.coverage) { 7032 if (self.filterName === 'COVERAGE' && L.isArray(self.coverage) && self.coverage.length) { 7033 for (i = 0; i < self.coverage.length; i++) { 7034 mod = self.coverage[i]; 7035 modInfo = self.getModuleInfo(mod); 7036 if (modInfo && modInfo.use) {
7037 mods = mods.concat(modInfo.use); 7038 } else { 7039 mods.push(mod); 7040 } 7041 } 7042 self.filters = self.filters || {}; 7043 Y.Array.each(mods, function(mod) { 7044 self.filters[mod] = self.FILTER_DEFS.COVERAGE; 7045 }); 7046 self.filterName = 'RAW'; 7047 self.filter = self.FILTER_DEFS[self.filterName]; 7048 } 7049 } 7050 7051 }, 7052 7053 /** 7054 * Returns the skin module name for the specified skin name. If a 7055 * module name is supplied, the returned skin module name is 7056 * specific to the module passed in. 7057 * @method formatSkin 7058 * @param {string} skin the name of the skin. 7059 * @param {string} mod optional: the name of a module to skin. 7060 * @return {string} the full skin module name. 7061 */ 7062 formatSkin: function(skin, mod) { 7063 var s = SKIN_PREFIX + skin; 7064 if (mod) { 7065 s = s + '-' + mod; 7066 } 7067 7068 return s; 7069 }, 7070 7071 /** 7072 * Adds the skin def to the module info 7073 * @method _addSkin 7074 * @param {string} skin the name of the skin. 7075 * @param {string} mod the name of the module. 7076 * @param {string} parent parent module if this is a skin of a 7077 * submodule or plugin. 7078 * @return {string} the module name for the skin. 7079 * @private 7080 */ 7081 _addSkin: function(skin, mod, parent) { 7082 var pkg, name, nmod, 7083 sinf = this.skin, 7084 mdef = mod && this.getModuleInfo(mod), 7085 ext = mdef && mdef.ext; 7086 7087 // Add a module definition for the module-specific skin css 7088 if (mod) { 7089 name = this.formatSkin(skin, mod); 7090 if (!this.getModuleInfo(name)) { 7091 pkg = mdef.pkg || mod; 7092 nmod = { 7093 skin: true, 7094 name: name, 7095 group: mdef.group, 7096 type: 'css', 7097 after: sinf.after, 7098 path: (parent || pkg) + '/' + sinf.base + skin + 7099 '/' + mod + '.css', 7100 ext: ext 7101 }; 7102 if (mdef.base) { 7103 nmod.base = mdef.base; 7104 } 7105 if (mdef.configFn) { 7106 nmod.configFn = mdef.configFn; 7107 } 7108 this.addModule(nmod, name); 7109 7110 } 7111 } 7112 7113 return name; 7114 }, 7115 /** 7116 * Adds an alias module to the system 7117 * @method addAlias 7118 * @param {Array} use An array of modules that makes up this alias 7119 * @param {String} name The name of the alias 7120 * @example 7121 * var loader = new Y.Loader({}); 7122 * loader.addAlias([ 'node', 'yql' ], 'davglass'); 7123 * loader.require(['davglass']); 7124 * var out = loader.resolve(true); 7125 * 7126 * //out.js will contain Node and YQL modules 7127 */ 7128 addAlias: function(use, name) { 7129 YUI.Env.aliases[name] = use; 7130 this.addModule({ 7131 name: name, 7132 use: use 7133 }); 7134 }, 7135 /** 7136 * Add a new module group 7137 * @method addGroup 7138 * @param {Object} config An object containing the group configuration data 7139 * @param {String} config.name required, the group name 7140 * @param {String} config.base The base directory for this module group 7141 * @param {String} config.root The root path to add to each combo resource path 7142 * @param {Boolean} config.combine Should the request be combined 7143 * @param {String} config.comboBase Combo service base path 7144 * @param {Object} config.modules The group of modules 7145 * @param {String} name the group name. 7146 * @example 7147 * var loader = new Y.Loader({}); 7148 * loader.addGroup({ 7149 * name: 'davglass', 7150 * combine: true, 7151 * comboBase: '/combo?', 7152 * root: '', 7153 * modules: { 7154 * //Module List here 7155 * } 7156 * }, 'davglass'); 7157 */ 7158 addGroup: function(o, name) { 7159 var mods = o.modules, 7160 self = this, 7161 defaultBase = o.defaultBase || Y.config.defaultBase, 7162 i, v; 7163 7164 name = name || o.name; 7165 o.name = name; 7166 self.groups[name] = o; 7167 7168 if (!o.base && defaultBase && o.root) { 7169 o.base = defaultBase + o.root; 7170 } 7171 7172 if (o.patterns) { 7173 for (i in o.patterns) { 7174 if (o.patterns.hasOwnProperty(i)) { 7175 o.patterns[i].group = name; 7176 self.patterns[i] = o.patterns[i]; 7177 } 7178 } 7179 } 7180 7181 if (mods) { 7182 for (i in mods) { 7183 if (mods.hasOwnProperty(i)) { 7184 v = mods[i]; 7185 if (typeof v === 'string') { 7186 v = { name: i, fullpath: v }; 7187 } 7188 v.group = name; 7189 self.addModule(v, i); 7190 } 7191 } 7192 } 7193 }, 7194 7195 /** 7196 * Add a new module to the component metadata. 7197 * @method addModule 7198 * @param {Object}
7198 config An object containing the module data. 7199 * @param {String} config.name Required, the component name 7200 * @param {String} config.type Required, the component type (js or css) 7201 * @param {String} config.path Required, the path to the script from `base` 7202 * @param {Array} config.requires Array of modules required by this component 7203 * @param {Array} [config.optional] Array of optional modules for this component 7204 * @param {Array} [config.supersedes] Array of the modules this component replaces 7205 * @param {Array} [config.after] Array of modules the components which, if present, should be sorted above this one 7206 * @param {Object} [config.after_map] Faster alternative to 'after' -- supply a hash instead of an array 7207 * @param {Number} [config.rollup] The number of superseded modules required for automatic rollup 7208 * @param {String} [config.fullpath] If `fullpath` is specified, this is used instead of the configured `base + path` 7209 * @param {Boolean} [config.skinnable] Flag to determine if skin assets should automatically be pulled in 7210 * @param {Object} [config.submodules] Hash of submodules 7211 * @param {String} [config.group] The group the module belongs to -- this is set automatically when it is added as part of a group configuration. 7212 * @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"]` 7213 * @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: 7214 * @param {String} [config.condition.trigger] The name of a module that can trigger the auto-load 7215 * @param {Function} [config.condition.test] A function that returns true when the module is to be loaded. 7216 * @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"`. 7217 * @param {String} [config.condition.when] Specifies the load order of the conditional module 7218 * with regard to the position of the trigger module. 7219 * This should be one of three values: `before`, `after`, or `instead`. The default is `after`. 7220 * @param {Object} [config.testresults] A hash of test results from `Y.Features.all()` 7221 * @param {Function} [config.configFn] A function to exectute when configuring this module 7222 * @param {Object} config.configFn.mod The module config, modifying this object will modify it's config. Returning false will delete the module's config. 7223 * @param {String[]} [config.optionalRequires] List of dependencies that 7224 may optionally be loaded by this loader. This is targeted mostly at 7225 polyfills, since they should not be in the list of requires because 7226 polyfills are assumed to be available in the global scope. 7227 * @param {Function} [config.test] Test to be called when this module is 7228 added as an optional dependency of another module. If the test function 7229 returns `false`, the module will be ignored and will not be attached to 7230 this YUI instance. 7231 * @param {String} [name] The module name, required if not in the module data. 7232 * @return {Object} the module definition or null if the object passed in did not provide all required attributes. 7233 */ 7234 addModule: function(o, name) { 7235 name = name || o.name; 7236 7237 if (typeof o === 'string') { 7238 o = { name: name, fullpath: o }; 7239 } 7240 7241 7242 var subs, i, l, t, sup, s, smod, plugins, plug, 7243 j, langs, packName, supName, flatSup, flatLang, lang, ret, 7244 overrides, skinname, when, g, p, 7245 modInfo = this.moduleInfo[name], 7246 conditions = this.conditions, trigger; 7247 7248 //Only merge this data if the temp flag is set 7249 //from an earlier pass from a pattern or else 7250 //an override module (YUI_config) can not be used to 7251 //replace a default module. 7252 if (modInfo && modInfo.temp) { 7253 //This catches temp modules loaded via a pattern 7254 // The module will be added twice, once from the pattern and 7255 // Once from the actual add call, this ensures that properties 7256 // that were added to the module the first time around (group: gallery) 7257 // are also added the second time around too. 7258 o = Y.merge(modInfo, o); 7259 } 7260 7261 o.name = name; 7262 7263 if (!o || !o.name) { 7264 return null; 7265 } 7266 7267 if (!o.type) { 7268 //Always assume it's javascript unless the CSS pattern is matched. 7269 o.type = JS; 7270 p = o.path || o.fullpath; 7271 if (p && this.REGEX_CSS.test(p)) { 7272 o.type = CSS; 7273 } 7274 } 7275 7276 if (!o.path && !o.fullpath) { 7277 o.path = _path(name, name, o.type); 7278 } 7279 o.supersedes = o.supersedes || o.use; 7280 7281 o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true; 7282 7283 // Handle submodule logic 7284 subs = o.submodules; 7285 7286 this.moduleInfo[name] = o; 7287 7288 o.requires = o.requires || []; 7289 7290 /* 7291 Only allowing the cascade of requires information, since 7292 optional and supersedes are far more fine grained than 7293 a blanket requires is. 7294 */ 7295 if (this.requires) { 7296 for (i = 0; i < this.requires.length; i++) { 7297 o.requires.push(this.requires[i]); 7298 } 7299 } 7300 if (o.group && this.groups && this.groups[o.group]) { 7301 g = this.groups[o.group]; 7302 if (g.requires) { 7303 for (i = 0; i < g.requires.length; i++) { 7304 o.requires.push(g.requires[i]); 7305 } 7306 } 7307 } 7308 7309 7310 if (!o.defaults) { 7311 o.defaults = { 7312 requires: o.requires ? [].concat(o.requires) : null, 7313 supersedes: o.supersedes ? [].concat(o.supersedes) : null, 7314 optional: o.optional ? [].concat(o.optional) : null 7315 }; 7316 } 7317 7318 if (o.skinnable && o.ext && o.temp) { 7319 skinname = this._addSkin(this.skin.defaultSkin, name); 7320 o.requires.unshift(skinname); 7321 } 7322 7323 if (o.requires.length) { 7324 o.requires = this.filterRequires(o.requires) || []; 7325 } 7326 7327 if (!o.langPack && o.lang) { 7328 // Setup root package by default as a fallback 7329 // for languages that are not defined 7330 packName = this.getLangPackName(ROOT_LANG, name); 7331 smod = this.getModuleInfo(packName); 7332 7333 if (!smod) { 7334 this._addLangPack(null, o, packName); 7335 } 7336 7337 langs = yArray(o.lang); 7338 7339 for (j = 0; j < langs.length; j++) { 7340 lang = langs[j]; 7341 packName = this.getLangPackName(lang, name); 7342 smod = this.getModuleInfo(packName); 7343 if (!smod) { 7344 smod = this._addLangPack(lang, o, packName); 7345 } 7346 } 7347 } 7348 7349 7350 if (subs) { 7351 sup = o.supersedes || []; 7352 l = 0; 7353 7354 for (i in subs) { 7355 if (subs.hasOwnProperty(i)) { 7356 s = subs[i]; 7357 7358 s.path = s.path || _path(name, i, o.type); 7359 s.pkg = name; 7360 s.group = o.group; 7361 7362 if (s.supersedes) { 7363 sup = sup.concat(s.supersedes); 7364 } 7365 7366 smod = this.addModule(s, i); 7367 sup.push(i); 7368 7369 if (smod.skinnable) { 7370 o.skinnable = true; 7371 overrides = this.skin.overrides; 7372 if (overrides && overrides[i]) { 7373 for (j = 0; j < overrides[i].length; j++) { 7374 skinname = this._addSkin(overrides[i][j], 7375 i, name); 7376 sup.push(skinname); 7377 } 7378 } 7379 skinname = this._addSkin(this.skin.defaultSkin, 7380 i, name); 7381 sup.push(skinname); 7382 } 7383 7384 // looks like we are expected to work out the metadata 7385 // for the parent module language packs from what is 7386 // specified in the child modules. 7387 if (s.lang && s.lang.length) { 7388 // Setup root package by default as a fallback 7389 // for languages that are not defined 7390 packName = this.getLangPackName(ROOT_LANG, name); 7391 smod = this.getModuleInfo(packName); 7392 7393 if (!smod) { 7394 this._addLangPack(null, o, packName); 7395 } 7396 7397 langs = yArray(s.lang); 7398 7399 for (j = 0; j < langs.length; j++) { 7400 lang = langs[j]; 7401 packName = this.getLangPackName(lang, name); 7402 supName = this.getLangPackName(lang, i); 7403 smod = this.getModuleInfo(packName); 7404 7405 if (!smod) { 7406 smod = this._addLangPack(lang, o, packName); 7407 } 7408 7409 flatSup = flatSup || yArray.hash(smod.supersedes); 7410 7411 if (!(supName in flatSup)) { 7412 smod.supersedes.push(supName); 7413 } 7414 7415 o.lang = o.lang || []; 7416 7417 flatLang = flatLang || yArray.hash(o.lang); 7418 7419 if (!(lang in flatLang)) { 7420 o.lang.push(lang); 7421 } 7422 7423// Add rollup file, need to add to supersedes list too 7424 7425 // default packages 7426 packName = this.getLangPackName(ROOT_LANG, name); 7427 supName = this.getLangPackName(ROOT_LANG, i); 7428 7429 smod = this.getModuleInfo(packName); 7430 7431 if (!smod) { 7432 smod = this._addLangPack(lang, o, packName); 7433 } 7434 7435 if (!(supName in flatSup)) { 7436 smod.supersedes.push(supName); 7437 } 7438 7439// Add rollup file, need to add to supersedes list too 7440 7441 } 7442 } 7443 7444 l++; 7445 } 7446 } 7447 //o.supersedes = YObject.keys(yArray.hash(sup)); 7448 o.supersedes = yArray.dedupe(sup); 7449 if (this.allowRollup) { 7450 o.rollup = (l < 4) ? l : Math.min(l - 1, 4); 7451 } 7452 } 7453 7454 plugins = o.plugins; 7455 if (plugins) { 7456 for (i in plugins) { 7457 if (plugins.hasOwnProperty(i)) { 7458 plug = plugins[i]; 7459 plug.pkg = name; 7460 plug.path = plug.path || _path(name, i, o.type); 7461 plug.requires = plug.requires || []; 7462 plug.group = o.group; 7463 this.addModule(plug, i); 7464 if (o.skinnable) { 7465 this._addSkin(this.skin.defaultSkin, i, name); 7466 } 7467 7468 } 7469 } 7470 } 7471 7472 if (o.condition) { 7473 t = this._expandAliases(o.condition.trigger); 7474 for (i = 0; i < t.length; i++) { 7475 trigger = t[i]; 7476 when = o.condition.when; 7477 conditions[trigger] = conditions[trigger] || {}; 7478 conditions[trigger][name] = o.condition; 7479 // the 'when' attribute can be 'before', 'after', or 'instead' 7480 // the default is after. 7481 if (when && when !== 'after') { 7482 if (when === 'instead') { // replace the trigger 7483 o.supersedes = o.supersedes || []; 7484 o.supersedes.push(trigger); 7485 } 7486 // before the trigger 7487 // the trigger requires the conditional mod, 7488 // so it should appear before the conditional 7489 // mod if we do not intersede. 7490 } else { // after the trigger 7491 o.after = o.after || []; 7492 o.after.push(trigger); 7493 } 7494 } 7495 } 7496 7497 if (o.supersedes) { 7498 o.supersedes = this.filterRequires(o.supersedes); 7499 } 7500 7501 if (o.after) { 7502 o.after = this.filterRequires(o.after); 7503 o.after_map = yArray.hash(o.after); 7504 } 7505 7506 // this.dirty = true; 7507 7508 if (o.configFn) { 7509 ret = o.configFn(o); 7510 if (ret === false) { 7511 delete this.moduleInfo[name]; 7512 delete GLOBAL_ENV._renderedMods[name]; 7513 o = null; 7514 } 7515 } 7516 //Add to global cache 7517 if (o) { 7518 if (!GLOBAL_ENV._renderedMods) { 7519 GLOBAL_ENV._renderedMods = {}; 7520 } 7521 GLOBAL_ENV._renderedMods[name] = Y.mix(GLOBAL_ENV._renderedMods[name] || {}, o);
7522 GLOBAL_ENV._conditions = conditions; 7523 } 7524 7525 return o; 7526 }, 7527 7528 /** 7529 * Add a requirement for one or more module 7530 * @method require 7531 * @param {string[] | string*} what the modules to load. 7532 */ 7533 require: function(what) { 7534 var a = (typeof what === 'string') ? yArray(arguments) : what; 7535 this.dirty = true; 7536 this.required = Y.merge(this.required, yArray.hash(this.filterRequires(a))); 7537 7538 this._explodeRollups(); 7539 }, 7540 /** 7541 * Grab all the items that were asked for, check to see if the Loader 7542 * meta-data contains a "use" array. If it doesm remove the asked item and replace it with 7543 * the content of the "use". 7544 * This will make asking for: "dd" 7545 * Actually ask for: "dd-ddm-base,dd-ddm,dd-ddm-drop,dd-drag,dd-proxy,dd-constrain,dd-drop,dd-scroll,dd-drop-plugin" 7546 * @private 7547 * @method _explodeRollups 7548 */ 7549 _explodeRollups: function() { 7550 var self = this, m, m2, i, a, v, len, len2, 7551 r = self.required; 7552 7553 if (!self.allowRollup) { 7554 for (i in r) { 7555 if (r.hasOwnProperty(i)) { 7556 m = self.getModule(i); 7557 if (m && m.use) { 7558 len = m.use.length; 7559 for (a = 0; a < len; a++) { 7560 m2 = self.getModule(m.use[a]); 7561 if (m2 && m2.use) { 7562 len2 = m2.use.length; 7563 for (v = 0; v < len2; v++) { 7564 r[m2.use[v]] = true; 7565 } 7566 } else { 7567 r[m.use[a]] = true; 7568 } 7569 } 7570 } 7571 } 7572 } 7573 self.required = r; 7574 } 7575 7576 }, 7577 /** 7578 * Explodes the required array to remove aliases and replace them with real modules 7579 * @method filterRequires 7580 * @param {Array} r The original requires array 7581 * @return {Array} The new array of exploded requirements 7582 */ 7583 filterRequires: function(r) { 7584 if (r) { 7585 if (!Y.Lang.isArray(r)) { 7586 r = [r]; 7587 } 7588 r = Y.Array(r); 7589 var c = [], i, mod, o, m; 7590 7591 for (i = 0; i < r.length; i++) { 7592 mod = this.getModule(r[i]); 7593 if (mod && mod.use) { 7594 for (o = 0; o < mod.use.length; o++) { 7595 //Must walk the other modules in case a module is a rollup of rollups (datatype) 7596 m = this.getModule(mod.use[o]); 7597 if (m && m.use && (m.name !== mod.name)) { 7598 c = Y.Array.dedupe([].concat(c, this.filterRequires(m.use))); 7599 } else { 7600 c.push(mod.use[o]); 7601 } 7602 } 7603 } else { 7604 c.push(r[i]); 7605 } 7606 } 7607 r = c; 7608 } 7609 return r; 7610 }, 7611 7612 /** 7613 Returns `true` if the module can be attached to the YUI instance. Runs 7614 the module's test if there is one and caches its result. 7615 7616 @method _canBeAttached 7617 @param {String} module Name of the module to check. 7618 @return {Boolean} Result of the module's test if it has one, or `true`. 7619 **/ 7620 _canBeAttached: function (m) { 7621 m = this.getModule(m); 7622 if (m && m.test) { 7623 if (!m.hasOwnProperty('_testResult')) { 7624 m._testResult = m.test(Y); 7625 } 7626 return m._testResult; 7627 } 7628 // return `true` for modules not registered as Loader will know what 7629 // to do with them later on 7630 return true; 7631 }, 7632 7633 /**
7634 * Returns an object containing properties for all modules required 7635 * in order to load the requested module 7636 * @method getRequires 7637 * @param {object} mod The module definition from moduleInfo. 7638 * @return {array} the expanded requirement list. 7639 */ 7640 getRequires: function(mod) { 7641 7642 if (!mod) { 7643 //console.log('returning no reqs for ' + mod.name); 7644 return NO_REQUIREMENTS; 7645 } 7646 7647 if (mod._parsed) { 7648 //console.log('returning requires for ' + mod.name, mod.requires); 7649 return mod.expanded || NO_REQUIREMENTS; 7650 } 7651 7652 //TODO add modue cache here out of scope.. 7653 7654 var i, m, j, length, add, packName, lang, testresults = this.testresults, 7655 name = mod.name, cond, 7656 adddef = ON_PAGE[name] && ON_PAGE[name].details, 7657 optReqs = mod.optionalRequires, 7658 d, go, def, 7659 r, old_mod, 7660 o, skinmod, skindef, skinpar, skinname, 7661 intl = mod.lang || mod.intl, 7662 ftests = Y.Features && Y.Features.tests.load, 7663 hash, reparse; 7664 7665 // console.log(name); 7666 7667 // pattern match leaves module stub that needs to be filled out 7668 if (mod.temp && adddef) { 7669 old_mod = mod; 7670 mod = this.addModule(adddef, name); 7671 mod.group = old_mod.group; 7672 mod.pkg = old_mod.pkg; 7673 delete mod.expanded; 7674 } 7675 7676 // console.log('cache: ' + mod.langCache + ' == ' + this.lang); 7677 7678 //If a skin or a lang is different, reparse.. 7679 reparse = !((!this.lang || mod.langCache === this.lang) && (mod.skinCache === this.skin.defaultSkin)); 7680 7681 if (mod.expanded && !reparse) { 7682 return mod.expanded; 7683 } 7684 7685 // Optional dependencies are dependencies that may or may not be 7686 // available. 7687 // This feature was designed specifically to be used when transpiling 7688 // ES6 modules, in order to use polyfills and regular scripts that define 7689 // global variables without having to import them since they should be 7690 // available in the global scope. 7691 if (optReqs) { 7692 for (i = 0, length = optReqs.length; i < length; i++) { 7693 if (this._canBeAttached(optReqs[i])) { 7694 mod.requires.push(optReqs[i]); 7695 } 7696 } 7697 } 7698 7699 d = []; 7700 hash = {}; 7701 r = this.filterRequires(mod.requires); 7702 if (mod.lang) { 7703 //If a module has a lang attribute, auto add the intl requirement. 7704 d.unshift('intl'); 7705 r.unshift('intl'); 7706 intl = true; 7707 } 7708 o = this.filterRequires(mod.optional); 7709 7710 7711 mod._parsed = true; 7712 mod.langCache = this.lang; 7713 mod.skinCache = this.skin.defaultSkin; 7714 7715 for (i = 0; i < r.length; i++) { 7716 if (!hash[r[i]]) { 7717 d.push(r[i]); 7718 hash[r[i]] = true; 7719 m = this.getModule(r[i]); 7720 if (m) { 7721 add = this.getRequires(m); 7722 intl = intl || (m.expanded_map && 7723 (INTL in m.expanded_map)); 7724 for (j = 0; j < add.length; j++) { 7725 d.push(add[j]); 7726 } 7727 } 7728 } 7729 } 7730 7731 // get the requirements from superseded modules, if any 7732 r = this.filterRequires(mod.supersedes); 7733 if (r) { 7734 for (i = 0; i < r.length; i++) { 7735 if (!hash[r[i]]) { 7736 // if this module has submodules, the requirements list is 7737 // expanded to include the submodules. This is so we can 7738 // prevent dups when a submodule is already loaded and the 7739 // parent is requested. 7740 if (mod.submodules) { 7741 d.push(r[i]); 7742 } 7743 7744 hash[r[i]] = true; 7745 m = this.getModule(r[i]); 7746 7747 if (m) { 7748 add = this.getRequires(m); 7749 intl = intl || (m.expanded_map && 7750 (INTL in m.expanded_map)); 7751 for (j = 0; j < add.length; j++) { 7752 d.push(add[j]); 7753 } 7754 } 7755 } 7756 } 7757 } 7758 7759 if (o && this.loadOptional) { 7760 for (i = 0; i < o.length; i++) { 7761 if (!hash[o[i]]) { 7762 d.push(o[i]); 7763 hash[o[i]] = true; 7764 m = this.getModuleInfo(o[i]); 7765 if (m) { 7766 add = this.getRequires(m); 7767 intl = intl || (m.expanded_map && 7768 (INTL in m.expanded_map)); 7769 for (j = 0; j < add.length; j++) { 7770 d.push(add[j]); 7771 } 7772 } 7773 } 7774 } 7775 } 7776 7777 cond = this.conditions[name]; 7778 7779 if (cond) { 7780 //Set the module to not parsed since we have conditionals and this could change the dependency tree. 7781 mod._parsed = false;
7782 if (testresults && ftests) { 7783 oeach(testresults, function(result, id) { 7784 var condmod = ftests[id].name; 7785 if (!hash[condmod] && ftests[id].trigger === name) { 7786 if (result && ftests[id]) { 7787 hash[condmod] = true; 7788 d.push(condmod); 7789 } 7790 } 7791 }); 7792 } else { 7793 for (i in cond) { 7794 if (cond.hasOwnProperty(i)) { 7795 if (!hash[i]) { 7796 def = cond[i]; 7797 //first see if they've specfied a ua check 7798 //then see if they've got a test fn & if it returns true 7799 //otherwise just having a condition block is enough 7800 go = def && ((!def.ua && !def.test) || (def.ua && Y.UA[def.ua]) || 7801 (def.test && def.test(Y, r))); 7802 7803 if (go) { 7804 hash[i] = true; 7805 d.push(i); 7806 m = this.getModule(i); 7807 if (m) { 7808 add = this.getRequires(m); 7809 for (j = 0; j < add.length; j++) { 7810 d.push(add[j]); 7811 } 7812 7813 } 7814 } 7815 } 7816 } 7817 } 7818 } 7819 } 7820 7821 // Create skin modules 7822 if (mod.skinnable) { 7823 skindef = this.skin.overrides; 7824 for (i in YUI.Env.aliases) { 7825 if (YUI.Env.aliases.hasOwnProperty(i)) { 7826 if (Y.Array.indexOf(YUI.Env.aliases[i], name) > -1) { 7827 skinpar = i; 7828 } 7829 } 7830 } 7831 if (skindef && (skindef[name] || (skinpar && skindef[skinpar]))) { 7832 skinname = name; 7833 if (skindef[skinpar]) { 7834 skinname = skinpar; 7835 } 7836 for (i = 0; i < skindef[skinname].length; i++) { 7837 skinmod = this._addSkin(skindef[skinname][i], name); 7838 if (!this.isCSSLoaded(skinmod, this._boot)) { 7839 d.push(skinmod); 7840 } 7841 } 7842 } else { 7843 skinmod = this._addSkin(this.skin.defaultSkin, name); 7844 if (!this.isCSSLoaded(skinmod, this._boot)) { 7845 d.push(skinmod); 7846 } 7847 } 7848 } 7849 7850 mod._parsed = false; 7851 7852 if (intl) { 7853 7854 if (mod.lang && !mod.langPack && Y.Intl) { 7855 lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang); 7856 packName = this.getLangPackName(lang, name); 7857 if (packName) { 7858 d.unshift(packName); 7859 } 7860 } 7861 d.unshift(INTL); 7862 } 7863 7864 mod.expanded_map = yArray.hash(d); 7865 7866 mod.expanded = YObject.keys(mod.expanded_map); 7867 7868 return mod.expanded; 7869 }, 7870 /** 7871 * Check to see if named css module is already loaded on the page 7872 * @method isCSSLoaded 7873 * @param {String} name The name of the css file 7874 * @param {Boolean} skip To skip the short-circuit for ignoreRegister 7875 * @return Boolean 7876 */ 7877 isCSSLoaded: function(name, skip) { 7878 //TODO - Make this call a batching call with name being an array 7879 if (!name || !YUI.Env.cssStampEl || (!skip && this.ignoreRegistered)) { 7880 return false; 7881 } 7882 var el = YUI.Env.cssStampEl, 7883 ret = false, 7884 mod = YUI.Env._cssLoaded[name], 7885 style = el.currentStyle; //IE 7886 7887 7888 if (mod !== undefined) { 7889 return mod; 7890 } 7891 7892 //Add the classname to the element 7893 el.className = name; 7894 7895 if (!style) { 7896 style = Y.config.doc.defaultView.getComputedStyle(el, null); 7897 } 7898 7899 if (style && style.display === 'none') { 7900 ret = true; 7901 } 7902 7903 7904 el.className = ''; //Reset the classname to '' 7905 7906 YUI.Env._cssLoaded[name] = ret; 7907 7908 return ret; 7909 }, 7910 7911 /** 7912 * Returns a hash of module names the supplied module satisfies. 7913 * @method getProvides 7914 * @param {string} name The name of the module. 7915 * @return {object} what this module provides. 7916 */ 7917 getProvides: function(name) { 7918 var m = this.getModule(name), o, s; 7919 // supmap = this.provides; 7920 7921 if (!m) { 7922 return NOT_FOUND; 7923 } 7924 7925 if (m && !m.provides) { 7926 o = {}; 7927 s = m.supersedes; 7928 7929 if (s) { 7930 yArray.each(s, function(v) { 7931 Y.mix(o, this.getProvides(v)); 7932 }, this); 7933 } 7934 7935 o[name] = true; 7936 m.provides = o; 7937 7938 } 7939 7940 return m.provides; 7941 }, 7942 7943 /** 7944 * Calculates the dependency tree, the result is stored in the sorted 7945 * property. 7946 * @method calculate 7947 * @param {object} o optional options object. 7948 * @param {string} type optional argument to prune modules. 7949 */ 7950 calculate: function(o, type) { 7951 if (o || type || this.dirty) { 7952 7953 if (o) { 7954 this._config(o); 7955 } 7956 7957 if (!this._init) { 7958 this._setup(); 7959 } 7960 7961 this._explode(); 7962 7963 if (this.allowRollup) { 7964 this._rollup(); 7965 } else { 7966 this._explodeRollups(); 7967 } 7968 this._reduce(); 7969 this._sort(); 7970 } 7971 }, 7972 /** 7973 * Creates a "psuedo" package for languages provided in the lang array 7974 * @method _addLangPack 7975 * @private 7976 * @param {String} lang The language to create 7977 * @param {Object} m The module definition to create the language pack around 7978 * @param {String} packName The name of the package (e.g: lang/datatype-date-en-US) 7979 * @return {Object} The module definition 7980 */ 7981 _addLangPack: function(lang, m, packName) { 7982 var name = m.name, 7983 packPath, conf, 7984 existing = this.getModuleInfo(packName); 7985 7986 if (!existing) { 7987 7988 packPath = _path((m.pkg || name), packName, JS, true); 7989 7990 conf = { 7991 path: packPath, 7992 intl: true, 7993 langPack: true, 7994 ext: m.ext, 7995 group: m.group, 7996 supersedes: [] 7997 }; 7998 if (m.root) { 7999 conf.root = m.root; 8000 } 8001 if (m.base) { 8002 conf.base = m.base; 8003 } 8004 8005 if (m.configFn) { 8006 conf.configFn = m.configFn; 8007 } 8008 8009 this.addModule(conf, packName); 8010 8011 if (lang) { 8012 Y.Env.lang = Y.Env.lang || {};
8013 Y.Env.lang[lang] = Y.Env.lang[lang] || {}; 8014 Y.Env.lang[lang][name] = true; 8015 } 8016 } 8017 8018 return this.getModuleInfo(packName); 8019 }, 8020 8021 /** 8022 * Investigates the current YUI configuration on the page. By default, 8023 * modules already detected will not be loaded again unless a force 8024 * option is encountered. Called by calculate() 8025 * @method _setup 8026 * @private 8027 */ 8028 _setup: function() { 8029 var info = this.moduleInfo, name, i, j, m, l, 8030 packName; 8031 8032 for (name in info) { 8033 if (info.hasOwnProperty(name)) { 8034 m = info[name]; 8035 if (m) { 8036 8037 // remove dups 8038 //m.requires = YObject.keys(yArray.hash(m.requires)); 8039 m.requires = yArray.dedupe(m.requires); 8040 8041 // Create lang pack modules 8042 //if (m.lang && m.lang.length) { 8043 if (m.lang) { 8044 // Setup root package if the module has lang defined, 8045 // it needs to provide a root language pack 8046 packName = this.getLangPackName(ROOT_LANG, name); 8047 this._addLangPack(null, m, packName); 8048 } 8049 8050 } 8051 } 8052 } 8053 8054 8055 //l = Y.merge(this.inserted); 8056 l = {}; 8057 8058 // available modules 8059 if (!this.ignoreRegistered) { 8060 Y.mix(l, GLOBAL_ENV.mods); 8061 } 8062 8063 // add the ignore list to the list of loaded packages 8064 if (this.ignore) { 8065 Y.mix(l, yArray.hash(this.ignore)); 8066 } 8067 8068 // expand the list to include superseded modules 8069 for (j in l) { 8070 if (l.hasOwnProperty(j)) { 8071 Y.mix(l, this.getProvides(j)); 8072 } 8073 } 8074 8075 // remove modules on the force list from the loaded list 8076 if (this.force) { 8077 for (i = 0; i < this.force.length; i++) { 8078 if (this.force[i] in l) { 8079 delete l[this.force[i]]; 8080 } 8081 } 8082 } 8083 8084 Y.mix(this.loaded, l); 8085 8086 this._init = true; 8087 }, 8088 8089 /** 8090 * Builds a module name for a language pack 8091 * @method getLangPackName 8092 * @param {string} lang the language code. 8093 * @param {string} mname the module to build it for. 8094 * @return {string} the language pack module name. 8095 */ 8096 getLangPackName: function(lang, mname) { 8097 return ('lang/' + mname + ((lang) ? '_' + lang : '')); 8098 }, 8099 /** 8100 * Inspects the required modules list looking for additional 8101 * dependencies. Expands the required list to include all 8102 * required modules. Called by calculate() 8103 * @method _explode 8104 * @private 8105 */ 8106 _explode: function() { 8107 //TODO Move done out of scope 8108 var r = this.required, m, reqs, done = {}, 8109 self = this, name, expound; 8110 8111 // the setup phase is over, all modules have been created 8112 self.dirty = false; 8113 8114 self._explodeRollups(); 8115 r = self.required; 8116 8117 for (name in r) { 8118 if (r.hasOwnProperty(name)) { 8119 if (!done[name]) { 8120 done[name] = true; 8121 m = self.getModule(name); 8122 if (m) { 8123 expound = m.expound; 8124 8125 if (expound) { 8126 r[expound] = self.getModule(expound); 8127 reqs = self.getRequires(r[expound]); 8128 Y.mix(r, yArray.hash(reqs)); 8129 } 8130 8131 reqs = self.getRequires(m); 8132 Y.mix(r, yArray.hash(reqs)); 8133 } 8134 } 8135 } 8136 } 8137 8138 }, 8139 /** 8140 * The default method used to test a module against a pattern 8141 * @method _patternTest 8142 * @private 8143 * @param {String} mname The module being tested 8144 * @param {String} pname The pattern to match 8145 */ 8146 _patternTest: function(mname, pname) { 8147 return (mname.indexOf(pname) > -1); 8148 }, 8149 /** 8150 * Get's the loader meta data for the requested module 8151 * @method getModule 8152 * @param {String} mname The module name to get 8153 * @return {Object} The module metadata 8154 */
8155 getModule: function(mname) { 8156 //TODO: Remove name check - it's a quick hack to fix pattern WIP 8157 if (!mname) { 8158 return null; 8159 } 8160 8161 var p, found, pname, 8162 m = this.getModuleInfo(mname), 8163 patterns = this.patterns; 8164 8165 // check the patterns library to see if we should automatically add 8166 // the module with defaults 8167 if (!m || (m && m.ext)) { 8168 for (pname in patterns) { 8169 if (patterns.hasOwnProperty(pname)) { 8170 p = patterns[pname]; 8171 8172 //There is no test method, create a default one that tests 8173 // the pattern against the mod name 8174 if (!p.test) { 8175 p.test = this._patternTest; 8176 } 8177 8178 if (p.test(mname, pname)) { 8179 // use the metadata supplied for the pattern 8180 // as the module definition. 8181 found = p; 8182 break; 8183 } 8184 } 8185 } 8186 } 8187 8188 if (!m) { 8189 if (found) { 8190 if (p.action) { 8191 p.action.call(this, mname, pname); 8192 } else { 8193 // ext true or false? 8194 m = this.addModule(Y.merge(found, { 8195 test: void 0, 8196 temp: true 8197 }), mname); 8198 if (m && found.configFn) { 8199 m.configFn = found.configFn; 8200 } 8201 } 8202 } 8203 } else { 8204 if (found && m && found.configFn && !m.configFn) { 8205 m.configFn = found.configFn; 8206 m.configFn(m); 8207 } 8208 } 8209 8210 return m; 8211 }, 8212 8213 // impl in rollup submodule 8214 _rollup: function() { }, 8215 8216 /** 8217 * Remove superceded modules and loaded modules. Called by 8218 * calculate() after we have the mega list of all dependencies 8219 * @method _reduce 8220 * @return {object} the reduced dependency hash. 8221 * @private 8222 */ 8223 _reduce: function(r) { 8224 8225 r = r || this.required; 8226 8227 var i, j, s, m, type = this.loadType, 8228 ignore = this.ignore ? yArray.hash(this.ignore) : false; 8229 8230 for (i in r) { 8231 if (r.hasOwnProperty(i)) { 8232 m = this.getModule(i); 8233 // remove if already loaded 8234 if (((this.loaded[i] || ON_PAGE[i]) && 8235 !this.forceMap[i] && !this.ignoreRegistered) || 8236 (type && m && m.type !== type)) { 8237 delete r[i]; 8238 } 8239 if (ignore && ignore[i]) { 8240 delete r[i]; 8241 } 8242 // remove anything this module supersedes 8243 s = m && m.supersedes; 8244 if (s) { 8245 for (j = 0; j < s.length; j++) { 8246 if (s[j] in r) { 8247 delete r[s[j]]; 8248 } 8249 } 8250 } 8251 } 8252 } 8253 8254 return r; 8255 }, 8256 /** 8257 * Handles the queue when a module has been loaded for all cases 8258 * @method _finish 8259 * @private 8260 * @param {String} msg The message from Loader 8261 * @param {Boolean} success A boolean denoting success or failure 8262 */ 8263 _finish: function(msg, success) { 8264 8265 _queue.running = false; 8266 8267 var onEnd = this.onEnd; 8268 if (onEnd) { 8269 onEnd.call(this.context, { 8270 msg: msg, 8271 data: this.data, 8272 success: success 8273 }); 8274 } 8275 this._continue(); 8276 }, 8277 /** 8278 * The default Loader onSuccess handler, calls this.onSuccess with a payload 8279 * @method _onSuccess 8280 * @private 8281 */ 8282 _onSuccess: function() { 8283 var self = this, skipped = Y.merge(self.skipped), fn, 8284 failed = [], rreg = self.requireRegistration, 8285 success, msg, i, mod; 8286 8287 for (i in skipped) { 8288 if (skipped.hasOwnProperty(i)) { 8289 delete self.inserted[i]; 8290 } 8291 } 8292 8293 self.skipped = {}; 8294 8295 for (i in self.inserted) { 8296 if (self.inserted.hasOwnProperty(i)) { 8297 mod = self.getModule(i); 8298 if (mod && rreg && mod.type === JS && !(i in YUI.Env.mods)) { 8299 failed.push(i); 8300 } else { 8301 Y.mix(self.loaded, self.getProvides(i)); 8302 } 8303 } 8304 } 8305 8306 fn = self.onSuccess; 8307 msg = (failed.length) ? 'notregistered' : 'success'; 8308 success = !(failed.length); 8309 if (fn) { 8310 fn.call(self.context, { 8311 msg: msg, 8312 data: self.data, 8313 success: success, 8314 failed: failed, 8315 skipped: skipped 8316 }); 8317 } 8318 self._finish(msg, success); 8319 }, 8320 /** 8321 * The default Loader onProgress handler, calls this.onProgress with a payload 8322 * @method _onProgress 8323 * @private 8324 */ 8325 _onProgress: function(e) { 8326 var self = this, i;
8327 //set the internal cache to what just came in. 8328 if (e.data && e.data.length) { 8329 for (i = 0; i < e.data.length; i++) { 8330 e.data[i] = self.getModule(e.data[i].name); 8331 } 8332 } 8333 if (self.onProgress) { 8334 self.onProgress.call(self.context, { 8335 name: e.url, 8336 data: e.data 8337 }); 8338 } 8339 }, 8340 /** 8341 * The default Loader onFailure handler, calls this.onFailure with a payload 8342 * @method _onFailure 8343 * @private 8344 */ 8345 _onFailure: function(o) { 8346 var f = this.onFailure, msg = [], i = 0, len = o.errors.length; 8347 8348 for (i; i < len; i++) { 8349 msg.push(o.errors[i].error); 8350 } 8351 8352 msg = msg.join(','); 8353 8354 8355 if (f) { 8356 f.call(this.context, { 8357 msg: msg, 8358 data: this.data, 8359 success: false 8360 }); 8361 } 8362 8363 this._finish(msg, false); 8364 8365 }, 8366 8367 /** 8368 * The default Loader onTimeout handler, calls this.onTimeout with a payload 8369 * @method _onTimeout 8370 * @param {Get.Transaction} transaction The Transaction object from `Y.Get` 8371 * @private 8372 */ 8373 _onTimeout: function(transaction) { 8374 var f = this.onTimeout; 8375 if (f) { 8376 f.call(this.context, { 8377 msg: 'timeout', 8378 data: this.data, 8379 success: false, 8380 transaction: transaction 8381 }); 8382 } 8383 }, 8384 8385 /** 8386 * Sorts the dependency tree. The last step of calculate() 8387 * @method _sort 8388 * @private 8389 */ 8390 _sort: function() { 8391 var name, 8392 8393 // Object containing module names. 8394 required = this.required, 8395 8396 // Keep track of whether we've visited a module. 8397 visited = {}; 8398 8399 // Will contain modules names, in the correct order, 8400 // according to dependencies. 8401 this.sorted = []; 8402 8403 for (name in required) { 8404 if (!visited[name] && required.hasOwnProperty(name)) { 8405 this._visit(name, visited); 8406 } 8407 } 8408 }, 8409 8410 /** 8411 * Recursively visits the dependencies of the module name 8412 * passed in, and appends each module name to the `sorted` property. 8413 * @param {String} name The name of a module. 8414 * @param {Object} visited Keeps track of whether a module was visited. 8415 * @method _visit 8416 * @private 8417 */ 8418 _visit: function (name, visited) { 8419 var required, condition, moduleInfo, dependency, dependencies, 8420 trigger, isAfter, i, l; 8421 8422 visited[name] = true; 8423 required = this.required; 8424 moduleInfo = this.moduleInfo[name]; 8425 condition = this.conditions[name] || {}; 8426 8427 if (moduleInfo) { 8428 // Recurse on each dependency of this module, 8429 // figuring out its dependencies, and so on. 8430 dependencies = moduleInfo.expanded || moduleInfo.requires; 8431 8432 for (i = 0, l = dependencies.length; i < l; ++i) { 8433 dependency = dependencies[i]; 8434 trigger = condition[dependency]; 8435 8436 // We cannot process this dependency yet if it must 8437 // appear after our current module. 8438 isAfter = trigger && (!trigger.when || trigger.when === "after"); 8439 8440 // Is this module name in the required list of modules, 8441 // and have we not already visited it? 8442 if (required[dependency] && !visited[dependency] && !isAfter) { 8443 this._visit(dependency, visited); 8444 } 8445 } 8446 } 8447 8448 this.sorted.push(name); 8449 }, 8450 8451 /** 8452 * Handles the actual insertion of script/link tags 8453 * @method _insert 8454 * @private 8455 * @param {Object} source The YUI instance the request came from 8456 * @param {Object} o The metadata to include 8457 * @param {String} type JS or CSS 8458 * @param {Boolean} [skipcalc=false] Do a Loader.calculate on the meta 8459 */ 8460 _insert: function(source, o, type, skipcalc) { 8461 8462 8463 // restore the state at the time of the request 8464 if (source) { 8465 this._config(source); 8466 } 8467 8468 // build the dependency list 8469 // don't include type so we can process CSS and script in 8470 // one pass when the type is not specified. 8471 8472 var modules = this.resolve(!skipcalc),
8473 self = this, comp = 0, actions = 0, 8474 mods = {}, deps, complete; 8475 8476 self._refetch = []; 8477 8478 if (type) { 8479 //Filter out the opposite type and reset the array so the checks later work 8480 modules[((type === JS) ? CSS : JS)] = []; 8481 } 8482 if (!self.fetchCSS) { 8483 modules.css = []; 8484 } 8485 if (modules.js.length) { 8486 comp++; 8487 } 8488 if (modules.css.length) { 8489 comp++; 8490 } 8491 8492 //console.log('Resolved Modules: ', modules); 8493 8494 complete = function(d) { 8495 actions++; 8496 var errs = {}, i = 0, o = 0, u = '', fn, 8497 modName, resMods; 8498 8499 if (d && d.errors) { 8500 for (i = 0; i < d.errors.length; i++) { 8501 if (d.errors[i].request) { 8502 u = d.errors[i].request.url; 8503 } else { 8504 u = d.errors[i]; 8505 } 8506 errs[u] = u; 8507 } 8508 } 8509 8510 if (d && d.data && d.data.length && (d.type === 'success')) { 8511 for (i = 0; i < d.data.length; i++) { 8512 self.inserted[d.data[i].name] = true; 8513 //If the external module has a skin or a lang, reprocess it 8514 if (d.data[i].lang || d.data[i].skinnable) { 8515 delete self.inserted[d.data[i].name]; 8516 self._refetch.push(d.data[i].name); 8517 } 8518 } 8519 } 8520 8521 if (actions === comp) { 8522 self._loading = null; 8523 if (self._refetch.length) { 8524 //Get the deps for the new meta-data and reprocess 8525 for (i = 0; i < self._refetch.length; i++) { 8526 deps = self.getRequires(self.getModule(self._refetch[i])); 8527 for (o = 0; o < deps.length; o++) { 8528 if (!self.inserted[deps[o]]) { 8529 //We wouldn't be to this point without the module being here 8530 mods[deps[o]] = deps[o]; 8531 } 8532 } 8533 } 8534 mods = Y.Object.keys(mods); 8535 if (mods.length) { 8536 self.require(mods); 8537 resMods = self.resolve(true);
8538 if (resMods.cssMods.length) { 8539 for (i=0; i < resMods.cssMods.length; i++) { 8540 modName = resMods.cssMods[i].name; 8541 delete YUI.Env._cssLoaded[modName]; 8542 if (self.isCSSLoaded(modName)) { 8543 self.inserted[modName] = true; 8544 delete self.required[modName]; 8545 } 8546 } 8547 self.sorted = []; 8548 self._sort(); 8549 } 8550 d = null; //bail 8551 self._insert(); //insert the new deps 8552 } 8553 } 8554 if (d && d.fn) { 8555 fn = d.fn; 8556 delete d.fn; 8557 fn.call(self, d); 8558 } 8559 } 8560 }; 8561 8562 this._loading = true; 8563 8564 if (!modules.js.length && !modules.css.length) { 8565 actions = -1; 8566 complete({ 8567 fn: self._onSuccess 8568 }); 8569 return; 8570 } 8571 8572 8573 if (modules.css.length) { //Load CSS first 8574 Y.Get.css(modules.css, { 8575 data: modules.cssMods, 8576 attributes: self.cssAttributes, 8577 insertBefore: self.insertBefore, 8578 charset: self.charset, 8579 timeout: self.timeout, 8580 context: self, 8581 onProgress: function(e) { 8582 self._onProgress.call(self, e); 8583 }, 8584 onTimeout: function(d) { 8585 self._onTimeout.call(self, d); 8586 }, 8587 onSuccess: function(d) { 8588 d.type = 'success'; 8589 d.fn = self._onSuccess; 8590 complete.call(self, d); 8591 }, 8592 onFailure: function(d) { 8593 d.type = 'failure'; 8594 d.fn = self._onFailure; 8595 complete.call(self, d); 8596 } 8597 }); 8598 } 8599 8600 if (modules.js.length) { 8601 Y.Get.js(modules.js, { 8602 data: modules.jsMods, 8603 insertBefore: self.insertBefore, 8604 attributes: self.jsAttributes, 8605 charset: self.charset, 8606 timeout: self.timeout, 8607 autopurge: false, 8608 context: self, 8609 async: self.async, 8610 onProgress: function(e) { 8611 self._onProgress.call(self, e); 8612 }, 8613 onTimeout: function(d) { 8614 self._onTimeout.call(self, d); 8615 }, 8616 onSuccess: function(d) { 8617 d.type = 'success'; 8618 d.fn = self._onSuccess; 8619 complete.call(self, d); 8620 }, 8621 onFailure: function(d) { 8622 d.type = 'failure'; 8623 d.fn = self._onFailure; 8624 complete.call(self, d); 8625 } 8626 }); 8627 } 8628 }, 8629 /** 8630 * Once a loader operation is completely finished, process any additional queued items. 8631 * @method _continue 8632 * @private 8633 */ 8634 _continue: function() { 8635 if (!(_queue.running) && _queue.size() > 0) { 8636 _queue.running = true; 8637 _queue.next()(); 8638 } 8639 }, 8640 8641 /** 8642 * inserts the requested modules and their dependencies. 8643 * <code>type</code> can be "js" or "css". Both script and 8644 * css are inserted if type is not provided. 8645 * @method insert 8646 * @param {object} o optional options object. 8647 * @param {string} type the type of dependency to insert. 8648 */ 8649 insert: function(o, type, skipsort) { 8650 var self = this, copy = Y.merge(this); 8651 delete copy.require; 8652 delete copy.dirty; 8653 _queue.add(function() { 8654 self._insert(copy, o, type, skipsort); 8655 }); 8656 this._continue(); 8657 }, 8658 8659 /** 8660 * Executed every time a module is loaded, and if we are in a load 8661 * cycle, we attempt to load the next script. Public so that it 8662 * is possible to call this if using a method other than 8663 * Y.register to determine when scripts are fully loaded 8664 * @method loadNext 8665 * @deprecated 8666 * @param {string} mname optional the name of the module that has 8667 * been loaded (which is usually why it is time to load the next 8668 * one). 8669 */ 8670 loadNext: function() { 8671 return; 8672 }, 8673 8674 /** 8675 * Apply filter defined for this instance to a url/path 8676 * @method _filter 8677 * @param {string} u the string to filter. 8678 * @param {string} name the name of the module, if we are processing 8679 * a single module as opposed to a combined url. 8680 * @return {string} the filtered string. 8681 * @private 8682 */ 8683 _filter: function(u, name, group) { 8684 var f = this.filter, 8685 hasFilter = name && (name in this.filters), 8686 modFilter = hasFilter && this.filters[name], 8687 groupName = group || (this.getModuleInfo(name) || {}).group || null; 8688 8689 if (groupName && this.groups[groupName] && this.groups[groupName].filter) { 8690 modFilter = this.groups[groupName].filter; 8691 hasFilter = true; 8692 } 8693 8694 if (u) { 8695 if (hasFilter) { 8696 f = (L.isString(modFilter)) ? this.FILTER_DEFS[modFilter.toUpperCase()] || null : modFilter; 8697 } 8698 if (f) { 8699 u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr); 8700 } 8701 } 8702 return u; 8703 }, 8704 8705 /** 8706 * Generates the full url for a module 8707 * @method _url 8708 * @param {string} path the path fragment. 8709 * @param {String} name The name of the module 8710 * @param {String} [base] The base url to use. Defaults to self.base 8711 * @return {string} the full url. 8712 * @private 8713 */ 8714 _url: function(path, name, base) { 8715 return this._filter((base || this.base || '') + path, name); 8716 }, 8717 /** 8718 * Returns an Object hash of file arrays built from `loader.sorted` or from an arbitrary list of sorted modules. 8719 * @method resolve 8720 * @param {Boolean} [calc=false] Perform a loader.calculate() before anything else 8721 * @param {Array} [sorted=loader.sorted] An override for the loader.sorted array 8722 * @return {Object} Object hash (js and css) of two arrays of file lists 8723 * @example This method can be used as an off-line dep calculator 8724 * 8725 * var Y = YUI(); 8726 * var loader = new Y.Loader({ 8727 * filter: 'debug', 8728 * base: '../../', 8729 * root: 'build/', 8730 * combine: true, 8731 * require: ['node', 'dd', 'console'] 8732 * }); 8733 * var out = loader.resolve(true); 8734 * 8735 */ 8736 resolve: function(calc, sorted) { 8737 var self = this, 8738 resolved = { js: [], jsMods: [], css: [], cssMods: [] }, 8739 addSingle, 8740 usePathogen = Y.config.comboLoader && Y.config.customComboBase; 8741 8742 if (self.skin.overrides || self.skin.defaultSkin !== DEFAULT_SKIN || self.ignoreRegistered) { 8743 self._resetModules(); 8744 } 8745 8746 if (calc) { 8747 self.calculate(); 8748 } 8749 sorted = sorted || self.sorted; 8750 8751 addSingle = function(mod) { 8752 if (mod) { 8753 var group = (mod.group && self.groups[mod.group]) || NOT_FOUND, 8754 url; 8755 8756 //Always assume it's async 8757 if (group.async === false) { 8758 mod.async = group.async; 8759 } 8760 8761 url = (mod.fullpath) ? self._filter(mod.fullpath, mod.name) : 8762 self._url(mod.path, mod.name, group.base || mod.base); 8763 8764 if (mod.attributes || mod.async === false) { 8765 url = { 8766 url: url, 8767 async: mod.async 8768 }; 8769 if (mod.attributes) { 8770 url.attributes = mod.attributes; 8771 } 8772 } 8773 resolved[mod.type].push(url); 8774 resolved[mod.type + 'Mods'].push(mod); 8775 } else { 8776 } 8777 8778 }; 8779 8780 /*jslint vars: true */ 8781 var inserted = (self.ignoreRegistered) ? {}
8781 : self.inserted, 8782 comboSources, 8783 maxURLLength, 8784 comboMeta, 8785 comboBase, 8786 comboSep, 8787 group, 8788 mod, 8789 len, 8790 i, 8791 hasComboModule = false; 8792 8793 /*jslint vars: false */ 8794 8795 for (i = 0, len = sorted.length; i < len; i++) { 8796 mod = self.getModule(sorted[i]); 8797 if (!mod || inserted[mod.name]) { 8798 continue; 8799 } 8800 8801 group = self.groups[mod.group]; 8802 8803 comboBase = self.comboBase; 8804 8805 if (group) { 8806 if (!group.combine || mod.fullpath) { 8807 //This is not a combo module, skip it and load it singly later. 8808 addSingle(mod); 8809 continue; 8810 } 8811 mod.combine = true; 8812 8813 if (typeof group.root === 'string') { 8814 mod.root = group.root; 8815 } 8816 8817 comboBase = group.comboBase || comboBase; 8818 comboSep = group.comboSep; 8819 maxURLLength = group.maxURLLength; 8820 } else { 8821 if (!self.combine) { 8822 //This is not a combo module, skip it and load it singly later. 8823 addSingle(mod); 8824 continue; 8825 } 8826 } 8827 8828 if (!mod.combine && mod.ext) { 8829 addSingle(mod); 8830 continue; 8831 } 8832 hasComboModule = true; 8833 comboSources = comboSources || {}; 8834 comboSources[comboBase] = comboSources[comboBase] || 8835 { js: [], jsMods: [], css: [], cssMods: [] }; 8836 8837 comboMeta = comboSources[comboBase]; 8838 comboMeta.group = mod.group; 8839 comboMeta.comboSep = comboSep || self.comboSep; 8840 comboMeta.maxURLLength = maxURLLength || self.maxURLLength; 8841 8842 comboMeta[mod.type + 'Mods'].push(mod); 8843 if (mod.type === JS || mod.type === CSS) { 8844 resolved[mod.type + 'Mods'].push(mod); 8845 } 8846 } 8847 //only encode if we have something to encode 8848 if (hasComboModule) { 8849 if (usePathogen) { 8850 resolved = this._pathogenEncodeComboSources(resolved); 8851 } else { 8852 resolved = this._encodeComboSources(resolved, comboSources); 8853 } 8854 } 8855 return resolved; 8856 }, 8857 8858 /** 8859 * Encodes combo sources and appends them to an object hash of arrays from `loader.resolve`. 8860 * 8861 * @method _encodeComboSources 8862 * @param {Object} resolved The object hash of arrays in which to attach the encoded combo sources. 8863 * @param {Object} comboSources An object containing relevant data about modules. 8864 * @return Object 8865 * @private 8866 */ 8867 _encodeComboSources: function(resolved, comboSources) { 8868 var fragSubset, 8869 modules, 8870 tmpBase, 8871 baseLen, 8872 frags, 8873 frag, 8874 type, 8875 mod, 8876 maxURLLength, 8877 comboBase, 8878 comboMeta, 8879 comboSep, 8880 i, 8881 len, 8882 self = this; 8883 8884 for (comboBase in comboSources) { 8885 if (comboSources.hasOwnProperty(comboBase)) { 8886 comboMeta = comboSources[comboBase]; 8887 comboSep = comboMeta.comboSep; 8888 maxURLLength = comboMeta.maxURLLength; 8889 for (type in comboMeta) { 8890 if (type === JS || type === CSS) { 8891 modules = comboMeta[type + 'Mods']; 8892 frags = []; 8893 for (i = 0, len = modules.length; i < len; i += 1) { 8894 mod = modules[i]; 8895 frag = ((typeof mod.root === 'string') ? mod.root : self.root) + (mod.path || mod.fullpath); 8896 frags.push( 8897 self._filter(frag, mod.name) 8898 ); 8899 } 8900 tmpBase = comboBase + frags.join(comboSep); 8901 baseLen = tmpBase.length; 8902 if (maxURLLength <= comboBase.length) { 8903 maxURLLength = MAX_URL_LENGTH; 8904 } 8905 8906 if (frags.length) { 8907 if (baseLen > maxURLLength) { 8908 fragSubset = []; 8909 for (i = 0, len = frags.length; i < len; i++) { 8910 fragSubset.push(frags[i]); 8911 tmpBase = comboBase + fragSubset.join(comboSep); 8912 8913 if (tmpBase.length > maxURLLength) { 8914 frag = fragSubset.pop(); 8915 tmpBase = comboBase + fragSubset.join(comboSep); 8916 resolved[type].push(self._filter(tmpBase, null, comboMeta.group)); 8917 fragSubset = []; 8918 if (frag) { 8919 fragSubset.push(frag); 8920 } 8921 } 8922 } 8923 if (fragSubset.length) { 8924 tmpBase = comboBase + fragSubset.join(comboSep); 8925 resolved[type].push(self._filter(tmpBase, null, comboMeta.group)); 8926 } 8927 } else { 8928 resolved[type].push(self._filter(tmpBase, null, comboMeta.group)); 8929 } 8930 } 8931 } 8932 } 8933 } 8934 } 8935 return resolved; 8936 }, 8937 8938 /** 8939 Shortcut to calculate, resolve and load all modules. 8940 8941 var loader = new Y.Loader({ 8942 ignoreRegistered: true, 8943 modules: { 8944 mod: { 8945 path: 'mod.js' 8946 } 8947 }, 8948 requires: [ 'mod' ] 8949 }); 8950 loader.load(function() { 8951 console.log('All modules have loaded..'); 8952 }); 8953 8954 8955 @method load 8956 @param {Function} cb Executed after all load operations are complete 8957 */ 8958 load: function(cb) { 8959 if (!cb) { 8960 return; 8961 } 8962 var self = this, 8963 out = self.resolve(true); 8964 8965 self.data = out; 8966 8967 self.onEnd = function() { 8968 cb.apply(self.context || self, arguments); 8969 }; 8970 8971 self.insert(); 8972 } 8973}; 8974 8975 8976}, 'patched-v3.18.1', {"requires": ["get", "features"]}); 8977YUI.add('loader-rollup', function (Y, NAME) { 8978 8979/** 8980 * Optional automatic rollup logic for reducing http connections 8981 * when not using a combo service. 8982 * @module loader 8983 * @submodule rollup 8984 */ 8985 8986/** 8987 * Look for rollup packages to determine if all of the modules a 8988 * rollup supersedes are required. If so, include the rollup to 8989 * help reduce the total number of connections required. Called 8990 * by calculate(). This is an optional feature, and requires the 8991 * appropriate submodule to function. 8992 * @method _rollup 8993 * @for Loader 8994 * @private 8995 */ 8996Y.Loader.prototype._rollup = function() { 8997 var i, j, m, s, r = this.required, roll, 8998 info = this.moduleInfo, rolled, c, smod; 8999 9000 // find and cache rollup modules 9001 if (this.dirty || !this.rollups) { 9002 this.rollups = {}; 9003 for (i in info) { 9004 if (info.hasOwnProperty(i)) { 9005 m = this.getModule(i); 9006 // if (m && m.rollup && m.supersedes) { 9007 if (m && m.rollup) { 9008 this.rollups[i] = m; 9009 } 9010 } 9011 } 9012 } 9013 9014 // make as many passes as needed to pick up rollup rollups 9015 for (;;) { 9016 rolled = false;
9017 9018 // go through the rollup candidates 9019 for (i in this.rollups) { 9020 if (this.rollups.hasOwnProperty(i)) { 9021 // there can be only one, unless forced 9022 if (!r[i] && ((!this.loaded[i]) || this.forceMap[i])) { 9023 m = this.getModule(i); 9024 s = m.supersedes || []; 9025 roll = false; 9026 9027 // @TODO remove continue 9028 if (!m.rollup) { 9029 continue; 9030 } 9031 9032 c = 0; 9033 9034 // check the threshold 9035 for (j = 0; j < s.length; j++) { 9036 smod = info[s[j]]; 9037 9038 // if the superseded module is loaded, we can't 9039 // load the rollup unless it has been forced. 9040 if (this.loaded[s[j]] && !this.forceMap[s[j]]) { 9041 roll = false; 9042 break; 9043 // increment the counter if this module is required. 9044 // if we are beyond the rollup threshold, we will 9045 // use the rollup module 9046 } else if (r[s[j]] && m.type === smod.type) { 9047 c++; 9048 roll = (c >= m.rollup); 9049 if (roll) { 9050 break; 9051 } 9052 } 9053 } 9054 9055 if (roll) { 9056 // add the rollup 9057 r[i] = true; 9058 rolled = true; 9059 9060 // expand the rollup's dependencies 9061 this.getRequires(m); 9062 } 9063 } 9064 } 9065 } 9066 9067 // if we made it here w/o rolling up something, we are done 9068 if (!rolled) { 9069 break; 9070 } 9071 } 9072}; 9073 9074 9075}, 'patched-v3.18.1', {"requires": ["loader-base"]}); 9076YUI.add('loader-yui3', function (Y, NAME) { 9077 9078/* This file is auto-generated by (yogi loader --yes --mix --start ../) */ 9079 9080/*jshint maxlen:900, eqeqeq: false */ 9081 9082/** 9083 * YUI 3 module metadata 9084 * @module loader 9085 * @submodule loader-yui3 9086 */ 9087YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {}; 9088Y.mix(YUI.Env[Y.version].modules, { 9089 "align-plugin": { 9090 "requires": [ 9091 "node-screen", 9092 "node-pluginhost" 9093 ] 9094 }, 9095 "anim": { 9096 "use": [ 9097 "anim-base", 9098 "anim-color", 9099 "anim-curve", 9100 "anim-easing", 9101 "anim-node-plugin", 9102 "anim-scroll", 9103 "anim-xy" 9104 ] 9105 }, 9106 "anim-base": { 9107 "requires": [ 9108 "base-base", 9109 "node-style", 9110 "color-base" 9111 ] 9112 }, 9113 "anim-color": { 9114 "requires": [ 9115 "anim-base" 9116 ] 9117 }, 9118 "anim-curve": { 9119 "requires": [ 9120 "anim-xy" 9121 ] 9122 }, 9123 "anim-easing": { 9124 "requires": [ 9125 "anim-base" 9126 ] 9127 }, 9128 "anim-node-plugin": { 9129 "requires": [ 9130 "node-pluginhost", 9131 "anim-base" 9132 ] 9133 }, 9134 "anim-scroll": { 9135 "requires": [ 9136 "anim-base" 9137 ] 9138 }, 9139 "anim-shape": { 9140 "requires": [ 9141 "anim-base", 9142 "anim-easing", 9143 "anim-color", 9144 "matrix" 9145 ] 9146 }, 9147 "anim-shape-transform": { 9148 "use": [ 9149 "anim-shape" 9150 ] 9151 }, 9152 "anim-xy": { 9153 "requires": [ 9154 "anim-base", 9155 "node-screen" 9156 ] 9157 }, 9158 "app": { 9159 "use": [ 9160 "app-base", 9161 "app-content", 9162 "app-transitions", 9163 "lazy-model-list", 9164 "model", 9165 "model-list", 9166 "model-sync-rest", 9167 "model-sync-local", 9168 "router", 9169 "view", 9170 "view-node-map" 9171 ] 9172 }, 9173 "app-base": { 9174 "requires": [ 9175 "classnamemanager", 9176 "pjax-base", 9177 "router", 9178 "view" 9179 ] 9180 }, 9181 "app-content": { 9182 "requires": [ 9183 "app-base", 9184 "pjax-content" 9185 ] 9186 }, 9187 "app-transitions": { 9188 "requires": [ 9189 "app-base" 9190 ] 9191 }, 9192 "app-transitions-css": { 9193 "type": "css" 9194 }, 9195 "app-transitions-native": { 9196 "condition": { 9197 "name": "app-transitions-native", 9198 "test": function (Y) { 9199 var doc = Y.config.doc, 9200 node = doc ? doc.documentElement : null; 9201 9202 if (node && node.style) { 9203 return ('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 9204 } 9205 9206 return false;
9207}, 9208 "trigger": "app-transitions" 9209 }, 9210 "requires": [ 9211 "app-transitions", 9212 "app-transitions-css", 9213 "parallel", 9214 "transition" 9215 ] 9216 }, 9217 "array-extras": { 9218 "requires": [ 9219 "yui-base" 9220 ] 9221 }, 9222 "array-invoke": { 9223 "requires": [ 9224 "yui-base" 9225 ] 9226 }, 9227 "arraylist": { 9228 "requires": [ 9229 "yui-base" 9230 ] 9231 }, 9232 "arraylist-add": { 9233 "requires": [ 9234 "arraylist" 9235 ] 9236 }, 9237 "arraylist-filter": { 9238 "requires": [ 9239 "arraylist" 9240 ] 9241 }, 9242 "arraysort": { 9243 "requires": [ 9244 "yui-base" 9245 ] 9246 }, 9247 "async-queue": { 9248 "requires": [ 9249 "event-custom" 9250 ] 9251 }, 9252 "attribute": { 9253 "use": [ 9254 "attribute-base", 9255 "attribute-complex" 9256 ] 9257 }, 9258 "attribute-base": { 9259 "requires": [ 9260 "attribute-core", 9261 "attribute-observable", 9262 "attribute-extras" 9263 ] 9264 }, 9265 "attribute-complex": { 9266 "requires": [ 9267 "attribute-base" 9268 ] 9269 }, 9270 "attribute-core": { 9271 "requires": [ 9272 "oop" 9273 ] 9274 }, 9275 "attribute-events": { 9276 "use": [ 9277 "attribute-observable" 9278 ] 9279 }, 9280 "attribute-extras": { 9281 "requires": [ 9282 "oop" 9283 ] 9284 }, 9285 "attribute-observable": { 9286 "requires": [ 9287 "event-custom" 9288 ] 9289 }, 9290 "autocomplete": { 9291 "use": [ 9292 "autocomplete-base", 9293 "autocomplete-sources", 9294 "autocomplete-list", 9295 "autocomplete-plugin" 9296 ] 9297 }, 9298 "autocomplete-base": { 9299 "optional": [ 9300 "autocomplete-sources" 9301 ], 9302 "requires": [ 9303 "array-extras", 9304 "base-build", 9305 "escape", 9306 "event-valuechange", 9307 "node-base" 9308 ] 9309 }, 9310 "autocomplete-filters": { 9311 "requires": [ 9312 "array-extras", 9313 "text-wordbreak" 9314 ] 9315 }, 9316 "autocomplete-filters-accentfold": { 9317 "requires": [ 9318 "array-extras", 9319 "text-accentfold", 9320 "text-wordbreak" 9321 ] 9322 }, 9323 "autocomplete-highlighters": { 9324 "requires": [ 9325 "array-extras", 9326 "highlight-base" 9327 ] 9328 }, 9329 "autocomplete-highlighters-accentfold": { 9330 "requires": [ 9331 "array-extras", 9332 "highlight-accentfold" 9333 ] 9334 }, 9335 "autocomplete-list": { 9336 "after": [ 9337 "autocomplete-sources" 9338 ], 9339 "lang": [ 9340 "en", 9341 "es", 9342 "hu", 9343 "it" 9344 ], 9345 "requires": [ 9346 "autocomplete-base", 9347 "event-resize", 9348 "node-screen", 9349 "selector-css3", 9350 "shim-plugin", 9351 "widget", 9352 "widget-position", 9353 "widget-position-align" 9354 ], 9355 "skinnable": true 9356 }, 9357 "autocomplete-list-keys": { 9358 "condition": { 9359 "name": "autocomplete-list-keys", 9360 "test": function (Y) { 9361 // Only add keyboard support to autocomplete-list if this doesn't appear to 9362 // be an iOS or Android-based mobile device. 9363 // 9364 // There's currently no feasible way to actually detect whether a device has 9365 // a hardware keyboard, so this sniff will have to do. It can easily be 9366 // overridden by manually loading the autocomplete-list-keys module. 9367 // 9368 // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari 9369 // doesn't fire the keyboard events used by AutoCompleteList, so there's 9370 // no point loading the -keys module even when a bluetooth keyboard may be 9371 // available. 9372 return !(Y.UA.ios || Y.UA.android); 9373}, 9374 "trigger": "autocomplete-list" 9375 }, 9376 "requires": [ 9377 "autocomplete-list", 9378 "base-build" 9379 ] 9380 }, 9381 "autocomplete-plugin": { 9382 "requires": [ 9383 "autocomplete-list", 9384 "node-pluginhost" 9385 ] 9386 }, 9387 "autocomplete-sources": { 9388 "optional": [ 9389 "io-base", 9390 "json-parse", 9391 "jsonp", 9392 "yql" 9393 ], 9394 "requires": [ 9395 "autocomplete-base" 9396 ] 9397 }, 9398 "axes": { 9399 "use": [ 9400 "axis-numeric", 9401 "axis-category", 9402 "axis-time", 9403 "axis-stacked" 9404 ] 9405 }, 9406 "axes-base": { 9407 "use": [ 9408 "axis-numeric-base", 9409 "axis-category-base", 9410 "axis-time-base", 9411 "axis-stacked-base" 9412 ] 9413 }, 9414 "axis": { 9415 "requires": [ 9416 "dom", 9417 "widget", 9418 "widget-position", 9419 "widget-stack", 9420 "graphics", 9421 "axis-base" 9422 ] 9423 }, 9424 "axis-base": { 9425 "requires": [ 9426 "classnamemanager", 9427 "datatype-number", 9428 "datatype-date", 9429 "base", 9430 "event-custom" 9431 ] 9432 }, 9433 "axis-category": { 9434 "requires": [ 9435 "axis", 9436 "axis-category-base" 9437 ] 9438 }, 9439 "axis-category-base": { 9440 "requires": [ 9441 "axis-base" 9442 ] 9443 }, 9444 "axis-numeric": { 9445 "requires": [ 9446 "axis", 9447 "axis-numeric-base" 9448 ] 9449 }, 9450 "axis-numeric-base": { 9451 "requires": [ 9452 "axis-base" 9453 ] 9454 }, 9455 "axis-stacked": { 9456 "requires": [ 9457 "axis-numeric", 9458 "axis-stacked-base" 9459 ] 9460 }, 9461 "axis-stacked-base": { 9462 "requires": [ 9463 "axis-numeric-base" 9464 ] 9465 }, 9466 "axis-time": { 9467 "requires": [ 9468 "axis", 9469 "axis-time-base" 9470 ] 9471 }, 9472 "axis-time-base": { 9473 "requires": [ 9474 "axis-base" 9475 ] 9476 }, 9477 "base": { 9478 "use": [ 9479 "base-base", 9480 "base-pluginhost", 9481 "base-build" 9482 ] 9483 }, 9484 "base-base": { 9485 "requires": [ 9486 "attribute-base", 9487 "base-core", 9488 "base-observable" 9489 ] 9490 }, 9491 "base-build": { 9492 "requires": [ 9493 "base-base" 9494 ] 9495 }, 9496 "base-core": { 9497 "requires": [ 9498 "attribute-core" 9499 ] 9500 }, 9501 "base-observable": { 9502 "requires": [ 9503 "attribute-observable", 9504 "base-core" 9505 ] 9506 }, 9507 "base-pluginhost": { 9508 "requires": [ 9509 "base-base", 9510 "pluginhost" 9511 ] 9512 }, 9513 "button": { 9514 "requires": [ 9515 "button-core", 9516 "cssbutton", 9517 "widget" 9518 ] 9519 }, 9520 "button-core": { 9521 "requires": [ 9522 "attribute-core", 9523 "classnamemanager", 9524 "node-base", 9525 "escape" 9526 ] 9527 }, 9528 "button-group": { 9529 "requires": [ 9530 "button-plugin", 9531 "cssbutton", 9532 "widget" 9533 ] 9534 }, 9535 "button-plugin": { 9536 "requires": [ 9537 "button-core", 9538 "cssbutton", 9539 "node-pluginhost" 9540 ] 9541 }, 9542 "cache": { 9543 "use": [ 9544 "cache-base", 9545 "cache-offline", 9546 "cache-plugin" 9547 ] 9548 }, 9549 "cache-base": { 9550 "requires": [ 9551 "base" 9552 ] 9553 }, 9554 "cache-offline": { 9555 "requires": [ 9556 "cache-base", 9557 "json" 9558 ] 9559 }, 9560 "cache-plugin": { 9561 "requires": [ 9562 "plugin", 9563 "cache-base" 9564 ] 9565 }, 9566 "calendar": { 9567 "requires": [ 9568 "calendar-base", 9569 "calendarnavigator" 9570 ], 9571 "skinnable": true 9572 }, 9573 "calendar-base": { 9574 "lang": [ 9575 "ca", 9576 "ca-ES", 9577 "de", 9578 "en", 9579 "es", 9580 "es-AR", 9581 "eu-ES", 9582 "fr", 9583 "hu", 9584 "it", 9585 "ja", 9586 "nb-NO", 9587 "nl", 9588 "pt-BR", 9589 "ru", 9590 "zh-Hans", 9591 "zh-Hans-CN", 9592 "zh-Hant", 9593 "zh-Hant-HK", 9594 "zh-HANT-TW" 9595 ], 9596 "requires": [ 9597 "widget", 9598 "datatype-date", 9599 "datatype-date-math", 9600 "cssgrids" 9601 ], 9602 "skinnable": true 9603 }, 9604 "calendarnavigator": { 9605 "requires": [ 9606 "plugin", 9607 "classnamemanager", 9608 "datatype-date", 9609 "node" 9610 ], 9611 "skinnable": true 9612 }, 9613 "charts": { 9614 "use": [ 9615 "charts-base" 9616 ] 9617 }, 9618 "charts-base": { 9619 "requires": [ 9620 "dom", 9621 "event-mouseenter", 9622 "event-touch", 9623 "graphics-group", 9624 "axes", 9625 "series-pie", 9626 "series-line", 9627 "series-marker", 9628 "series-area", 9629 "series-spline", 9630 "series-column", 9631 "series-bar", 9632 "series-areaspline", 9633 "series-combo", 9634 "series-combospline", 9635 "series-line-stacked", 9636 "series-marker-stacked", 9637 "series-area-stacked", 9638 "series-spline-stacked", 9639 "series-column-stacked", 9640 "series-bar-stacked", 9641 "series-areaspline-stacked", 9642 "series-combo-stacked", 9643 "series-combospline-stacked" 9644 ] 9645 }, 9646 "charts-legend": { 9647 "requires": [ 9648 "charts-base" 9649 ] 9650 }, 9651 "classnamemanager": { 9652 "requires": [ 9653 "yui-base" 9654 ] 9655 }, 9656 "clickable-rail": { 9657 "requires": [ 9658 "slider-base" 9659 ] 9660 }, 9661 "collection": { 9662 "use": [ 9663 "array-extras", 9664 "arraylist", 9665 "arraylist-add", 9666 "arraylist-filter", 9667 "array-invoke" 9668 ] 9669 }, 9670 "color": { 9671 "use": [ 9672 "color-base", 9673 "color-hsl", 9674 "color-harmony" 9675 ] 9676 }, 9677 "color-base": { 9678 "requires": [ 9679 "yui-base" 9680 ] 9681 }, 9682 "color-harmony": { 9683 "requires": [ 9684 "color-hsl" 9685 ] 9686 }, 9687 "color-hsl": { 9688 "requires": [ 9689 "color-base" 9690 ] 9691 }, 9692 "color-hsv": { 9693 "requires": [ 9694 "color-base" 9695 ] 9696 }, 9697 "console": { 9698 "lang": [ 9699 "en", 9700 "es", 9701 "hu", 9702 "it", 9703 "ja" 9704 ], 9705 "requires": [ 9706 "yui-log", 9707 "widget" 9708 ], 9709 "skinnable": true 9710 }, 9711 "console-filters": { 9712 "requires": [ 9713 "plugin", 9714 "console" 9715 ], 9716 "skinnable": true 9717 }, 9718 "content-editable": { 9719 "requires": [ 9720 "node-base", 9721 "editor-selection", 9722 "stylesheet", 9723 "plugin" 9724 ] 9725 }, 9726 "controller": { 9727 "use": [ 9728 "router" 9729 ] 9730 }, 9731 "cookie": { 9732 "requires": [ 9733 "yui-base" 9734 ] 9735 }, 9736 "createlink-base": { 9737 "requires": [ 9738 "editor-base" 9739 ] 9740 }, 9741 "cssbase": { 9742 "after": [ 9743 "cssreset", 9744 "cssfonts", 9745 "cssgrids", 9746 "cssreset-context", 9747 "cssfonts-context", 9748 "cssgrids-context" 9749 ], 9750 "type": "css" 9751 }, 9752 "cssbase-context": { 9753 "after": [ 9754 "cssreset", 9755 "cssfonts", 9756 "cssgrids", 9757 "cssreset-context", 9758 "cssfonts-context", 9759 "cssgrids-context" 9760 ], 9761 "type": "css" 9762 }, 9763 "cssbutton": { 9764 "type": "css" 9765 }, 9766 "cssfonts": { 9767 "type": "css" 9768 }, 9769 "cssfonts-context": { 9770 "type": "css" 9771 }, 9772 "cssgrids": { 9773 "optional": [ 9774 "cssnormalize" 9775 ], 9776 "type": "css" 9777 }, 9778 "cssgrids-base": { 9779 "optional": [ 9780 "cssnormalize" 9781 ], 9782 "type": "css" 9783 }, 9784 "cssgrids-responsive": { 9785 "optional": [ 9786 "cssnormalize" 9787 ], 9788 "requires": [ 9789 "cssgrids", 9790 "cssgrids-responsive-base" 9791 ], 9792 "type": "css" 9793 }, 9794 "cssgrids-units": { 9795 "optional": [ 9796 "cssnormalize" 9797 ], 9798 "requires": [ 9799 "cssgrids-base" 9800 ], 9801 "type": "css" 9802 }, 9803 "cssnormalize": { 9804 "type": "css" 9805 }, 9806 "cssnormalize-context": { 9807 "type": "css" 9808 }, 9809 "cssreset": { 9810 "type": "css" 9811 }, 9812 "cssreset-context": { 9813 "type": "css" 9814 }, 9815 "dataschema": { 9816 "use": [ 9817 "dataschema-base", 9818 "dataschema-json", 9819 "dataschema-xml", 9820 "dataschema-array", 9821 "dataschema-text" 9822 ] 9823 }, 9824 "dataschema-array": { 9825 "requires": [ 9826 "dataschema-base" 9827 ] 9828 }, 9829 "dataschema-base": { 9830 "requires": [ 9831 "base" 9832 ] 9833 }, 9834 "dataschema-json": { 9835 "requires": [ 9836 "dataschema-base", 9837 "json" 9838 ] 9839 }, 9840 "dataschema-text": { 9841 "requires": [ 9842 "dataschema-base" 9843 ] 9844 }, 9845 "dataschema-xml": { 9846 "requires": [ 9847 "dataschema-base" 9848 ] 9849 }, 9850 "datasource": { 9851 "use": [ 9852 "datasource-local", 9853 "datasource-io", 9854 "datasource-get", 9855 "datasource-function", 9856 "datasource-cache", 9857 "datasource-jsonschema", 9858 "datasource-xmlschema", 9859 "datasource-arrayschema", 9860 "datasource-textschema", 9861 "datasource-polling" 9862 ] 9863 }, 9864 "datasource-arrayschema": { 9865 "requires": [ 9866 "datasource-local", 9867 "plugin", 9868 "dataschema-array" 9869 ] 9870 }, 9871 "datasource-cache": { 9872 "requires": [ 9873 "datasource-local", 9874 "plugin", 9875 "cache-base" 9876 ] 9877 }, 9878 "datasource-function": { 9879 "requires": [ 9880 "datasource-local" 9881 ] 9882 }, 9883 "datasource-get": { 9884 "requires": [ 9885 "datasource-local", 9886 "get" 9887 ] 9888 }, 9889 "datasource-io": { 9890 "requires": [ 9891 "datasource-local", 9892 "io-base" 9893 ] 9894 }, 9895 "datasource-jsonschema": { 9896 "requires": [ 9897 "datasource-local", 9898 "plugin", 9899 "dataschema-json" 9900 ] 9901 }, 9902 "datasource-local": { 9903 "requires": [ 9904 "base" 9905 ] 9906 }, 9907 "datasource-polling": { 9908 "requires": [ 9909 "datasource-local" 9910 ] 9911 }, 9912 "datasource-textschema": { 9913 "requires": [ 9914 "datasource-local", 9915 "plugin", 9916 "dataschema-text" 9917 ] 9918 }, 9919 "datasource-xmlschema": { 9920 "requires": [ 9921 "datasource-local", 9922 "plugin", 9923 "datatype-xml", 9924 "dataschema-xml" 9925 ] 9926 }, 9927 "datatable": { 9928 "use": [ 9929 "datatable-core", 9930 "datatable-table", 9931 "datatable-head", 9932 "datatable-body", 9933 "datatable-base", 9934 "datatable-column-widths", 9935 "datatable-message", 9936 "datatable-mutable", 9937 "datatable-sort", 9938 "datatable-datasource" 9939 ] 9940 }, 9941 "datatable-base": { 9942 "requires": [ 9943 "datatable-core", 9944 "datatable-table", 9945 "datatable-head", 9946 "datatable-body", 9947 "base-build", 9948 "widget" 9949 ], 9950 "skinnable": true 9951 }, 9952 "datatable-body": { 9953 "requires": [ 9954 "datatable-core", 9955 "view", 9956 "classnamemanager" 9957 ] 9958 }, 9959 "datatable-column-widths": { 9960 "requires": [ 9961 "datatable-base" 9962 ] 9963 }, 9964 "datatable-core": { 9965 "requires": [ 9966 "escape", 9967 "model-list", 9968 "node-event-delegate" 9969 ] 9970 }, 9971 "datatable-datasource": { 9972 "requires": [ 9973 "datatable-base", 9974 "plugin", 9975 "datasource-local" 9976 ] 9977 }, 9978 "datatable-foot": { 9979 "requires": [ 9980 "datatable-core", 9981 "view" 9982 ] 9983 }, 9984 "datatable-formatters": { 9985 "requires": [ 9986 "datatable-body", 9987
9987 "datatype-number-format", 9988 "datatype-date-format", 9989 "escape" 9990 ] 9991 }, 9992 "datatable-head": { 9993 "requires": [ 9994 "datatable-core", 9995 "view", 9996 "classnamemanager" 9997 ] 9998 }, 9999 "datatable-highlight": { 10000 "requires": [ 10001 "datatable-base", 10002 "event-hover" 10003 ], 10004 "skinnable": true 10005 }, 10006 "datatable-keynav": { 10007 "requires": [ 10008 "datatable-base" 10009 ] 10010 }, 10011 "datatable-message": { 10012 "lang": [ 10013 "en", 10014 "fr", 10015 "es", 10016 "hu", 10017 "it" 10018 ], 10019 "requires": [ 10020 "datatable-base" 10021 ], 10022 "skinnable": true 10023 }, 10024 "datatable-mutable": { 10025 "requires": [ 10026 "datatable-base" 10027 ] 10028 }, 10029 "datatable-paginator": { 10030 "lang": [ 10031 "en", 10032 "fr" 10033 ], 10034 "requires": [ 10035 "model", 10036 "view", 10037 "paginator-core", 10038 "datatable-foot", 10039 "datatable-paginator-templates" 10040 ], 10041 "skinnable": true 10042 }, 10043 "datatable-paginator-templates": { 10044 "requires": [ 10045 "template" 10046 ] 10047 }, 10048 "datatable-scroll": { 10049 "requires": [ 10050 "datatable-base", 10051 "datatable-column-widths", 10052 "dom-screen" 10053 ], 10054 "skinnable": true 10055 }, 10056 "datatable-sort": { 10057 "lang": [ 10058 "en", 10059 "fr", 10060 "es", 10061 "hu" 10062 ], 10063 "requires": [ 10064 "datatable-base" 10065 ], 10066 "skinnable": true 10067 }, 10068 "datatable-table": { 10069 "requires": [ 10070 "datatable-core", 10071 "datatable-head", 10072 "datatable-body", 10073 "view", 10074 "classnamemanager" 10075 ] 10076 }, 10077 "datatype": { 10078 "use": [ 10079 "datatype-date", 10080 "datatype-number", 10081 "datatype-xml" 10082 ] 10083 }, 10084 "datatype-date": { 10085 "use": [ 10086 "datatype-date-parse", 10087 "datatype-date-format", 10088 "datatype-date-math" 10089 ] 10090 }, 10091 "datatype-date-format": { 10092 "lang": [ 10093 "ar", 10094 "ar-JO", 10095 "ca", 10096 "ca-ES", 10097 "da", 10098 "da-DK", 10099 "de", 10100 "de-AT", 10101 "de-DE", 10102 "el", 10103 "el-GR", 10104 "en", 10105 "en-AU", 10106 "en-CA", 10107 "en-GB", 10108 "en-IE", 10109 "en-IN", 10110 "en-JO", 10111 "en-MY", 10112 "en-NZ", 10113 "en-PH", 10114 "en-SG", 10115 "en-US", 10116 "es", 10117 "es-AR", 10118 "es-BO", 10119 "es-CL", 10120 "es-CO", 10121 "es-EC", 10122 "es-ES", 10123 "es-MX", 10124 "es-PE", 10125 "es-PY", 10126 "es-US", 10127 "es-UY", 10128 "es-VE", 10129 "fi", 10130 "fi-FI", 10131 "fr", 10132 "fr-BE", 10133 "fr-CA", 10134 "fr-FR", 10135 "hi", 10136 "hi-IN", 10137 "hu", 10138 "id", 10139 "id-ID", 10140 "it", 10141 "it-IT", 10142 "ja", 10143 "ja-JP", 10144 "ko", 10145 "ko-KR", 10146 "ms", 10147 "ms-MY", 10148 "nb", 10149 "nb-NO", 10150 "nl", 10151 "nl-BE", 10152 "nl-NL", 10153 "pl", 10154 "pl-PL", 10155 "pt", 10156 "pt-BR", 10157 "ro", 10158 "ro-RO", 10159 "ru", 10160 "ru-RU", 10161 "sv", 10162 "sv-SE", 10163 "th", 10164 "th-TH", 10165 "tr", 10166 "tr-TR", 10167 "vi", 10168 "vi-VN", 10169 "zh-Hans", 10170 "zh-Hans-CN", 10171 "zh-Hant", 10172 "zh-Hant-HK", 10173 "zh-Hant-TW" 10174 ] 10175 }, 10176 "datatype-date-math": { 10177 "requires": [ 10178 "yui-base" 10179 ] 10180 }, 10181 "datatype-date-parse": {}, 10182 "datatype-number": { 10183 "use": [ 10184 "datatype-number-parse", 10185 "datatype-number-format" 10186 ] 10187 }, 10188 "datatype-number-format": {}, 10189 "datatype-number-parse": { 10190 "requires": [ 10191 "escape" 10192 ] 10193 }, 10194 "datatype-xml": { 10195 "use": [ 10196 "datatype-xml-parse", 10197 "datatype-xml-format" 10198 ] 10199 }, 10200 "datatype-xml-format": {}, 10201 "datatype-xml-parse": {}, 10202 "dd": { 10203 "use": [ 10204 "dd-ddm-base", 10205 "dd-ddm", 10206 "dd-ddm-drop", 10207 "dd-drag", 10208 "dd-proxy", 10209 "dd-constrain", 10210 "dd-drop", 10211 "dd-scroll", 10212 "dd-delegate" 10213 ] 10214 }, 10215 "dd-constrain": { 10216 "requires": [ 10217 "dd-drag" 10218 ] 10219 }, 10220 "dd-ddm": { 10221 "requires": [ 10222 "dd-ddm-base", 10223 "event-resize" 10224 ] 10225 }, 10226 "dd-ddm-base": { 10227 "requires": [ 10228 "node", 10229 "base", 10230 "yui-throttle", 10231 "classnamemanager" 10232 ] 10233 }, 10234 "dd-ddm-drop": { 10235 "requires": [ 10236 "dd-ddm" 10237 ] 10238 }, 10239 "dd-delegate": { 10240 "requires": [ 10241 "dd-drag", 10242 "dd-drop-plugin", 10243 "event-mouseenter" 10244 ] 10245 }, 10246 "dd-drag": { 10247 "requires": [ 10248 "dd-ddm-base", 10249 "selector-css2" 10250 ] 10251 }, 10252 "dd-drop": { 10253 "requires": [ 10254 "dd-drag", 10255 "dd-ddm-drop" 10256 ] 10257 }, 10258 "dd-drop-plugin": { 10259 "requires": [ 10260 "dd-drop" 10261 ] 10262 }, 10263 "dd-gestures": { 10264 "condition": { 10265 "name": "dd-gestures", 10266 "trigger": "dd-drag", 10267 "ua": "touchEnabled" 10268 }, 10269 "requires": [ 10270 "dd-drag", 10271 "event-synthetic", 10272 "event-gestures" 10273 ] 10274 }, 10275 "dd-plugin": { 10276 "optional": [ 10277 "dd-constrain", 10278 "dd-proxy" 10279 ], 10280 "requires": [ 10281 "dd-drag" 10282 ] 10283 }, 10284 "dd-proxy": { 10285 "requires": [ 10286 "dd-drag" 10287 ] 10288 }, 10289 "dd-scroll": { 10290 "requires": [ 10291 "dd-drag" 10292 ] 10293 }, 10294 "dial": { 10295 "lang": [ 10296 "en", 10297 "es", 10298 "hu" 10299 ], 10300 "requires": [ 10301 "widget", 10302 "dd-drag", 10303 "event-mouseenter", 10304 "event-move", 10305 "event-key", 10306 "transition", 10307 "intl" 10308 ], 10309 "skinnable": true 10310 }, 10311 "dom": { 10312 "use": [ 10313 "dom-base", 10314 "dom-screen", 10315 "dom-style", 10316 "selector-native", 10317 "selector" 10318 ] 10319 },
10320 "dom-base": { 10321 "requires": [ 10322 "dom-core" 10323 ] 10324 }, 10325 "dom-core": { 10326 "requires": [ 10327 "oop", 10328 "features" 10329 ] 10330 }, 10331 "dom-screen": { 10332 "requires": [ 10333 "dom-base", 10334 "dom-style" 10335 ] 10336 }, 10337 "dom-style": { 10338 "requires": [ 10339 "dom-base" 10340 ] 10341 }, 10342 "dom-style-ie": { 10343 "condition": { 10344 "name": "dom-style-ie", 10345 "test": function (Y) { 10346 10347 var testFeature = Y.Features.test, 10348 addFeature = Y.Features.add, 10349 WINDOW = Y.config.win, 10350 DOCUMENT = Y.config.doc, 10351 DOCUMENT_ELEMENT = 'documentElement', 10352 ret = false; 10353 10354 addFeature('style', 'computedStyle', { 10355 test: function() { 10356 return WINDOW && 'getComputedStyle' in WINDOW; 10357 } 10358 }); 10359 10360 addFeature('style', 'opacity', { 10361 test: function() { 10362 return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style; 10363 } 10364 }); 10365 10366 ret = (!testFeature('style', 'opacity') && 10367 !testFeature('style', 'computedStyle')); 10368 10369 return ret; 10370}, 10371 "trigger": "dom-style" 10372 }, 10373 "requires": [ 10374 "dom-style", 10375 "color-base" 10376 ] 10377 }, 10378 "dump": { 10379 "requires": [ 10380 "yui-base" 10381 ] 10382 }, 10383 "editor": { 10384 "use": [ 10385 "frame", 10386 "editor-selection", 10387 "exec-command", 10388 "editor-base", 10389 "editor-para", 10390 "editor-br", 10391 "editor-bidi", 10392 "editor-tab", 10393 "createlink-base" 10394 ] 10395 }, 10396 "editor-base": { 10397 "requires": [ 10398 "base", 10399 "frame", 10400 "node", 10401 "exec-command", 10402 "editor-selection" 10403 ] 10404 }, 10405 "editor-bidi": { 10406 "requires": [ 10407 "editor-base" 10408 ] 10409 }, 10410 "editor-br": { 10411 "requires": [ 10412 "editor-base" 10413 ] 10414 }, 10415 "editor-inline": { 10416 "requires": [ 10417 "editor-base", 10418 "content-editable" 10419 ] 10420 }, 10421 "editor-lists": { 10422 "requires": [ 10423 "editor-base" 10424 ] 10425 }, 10426 "editor-para": { 10427 "requires": [ 10428 "editor-para-base" 10429 ] 10430 }, 10431 "editor-para-base": { 10432 "requires": [ 10433 "editor-base" 10434 ] 10435 }, 10436 "editor-para-ie": { 10437 "condition": { 10438 "name": "editor-para-ie", 10439 "trigger": "editor-para", 10440 "ua": "ie", 10441 "when": "instead" 10442 }, 10443 "requires": [ 10444 "editor-para-base" 10445 ] 10446 }, 10447 "editor-selection": { 10448 "requires": [ 10449 "node" 10450 ] 10451 }, 10452 "editor-tab": { 10453 "requires": [ 10454 "editor-base" 10455 ] 10456 }, 10457 "escape": { 10458 "requires": [ 10459 "yui-base" 10460 ] 10461 }, 10462 "event": { 10463 "after": [ 10464 "node-base" 10465 ], 10466 "use": [ 10467 "event-base", 10468 "event-delegate", 10469 "event-synthetic", 10470 "event-mousewheel", 10471 "event-mouseenter", 10472 "event-key", 10473 "event-focus", 10474 "event-resize", 10475 "event-hover", 10476 "event-outside", 10477 "event-touch", 10478 "event-move", 10479 "event-flick", 10480 "event-valuechange", 10481 "event-tap" 10482 ] 10483 }, 10484 "event-base": { 10485 "after": [ 10486 "node-base" 10487 ], 10488 "requires": [ 10489 "event-custom-base" 10490 ] 10491 }, 10492 "event-base-ie": { 10493 "after": [ 10494 "event-base" 10495 ], 10496 "condition": { 10497 "name": "event-base-ie", 10498 "test": function(Y) { 10499 var imp = Y.config.doc && Y.config.doc.implementation; 10500 return (imp && (!imp.hasFeature('Events', '2.0'))); 10501}, 10502 "trigger": "node-base" 10503 }, 10504 "requires": [ 10505 "node-base" 10506 ] 10507 }, 10508 "event-contextmenu": { 10509 "requires": [ 10510 "event-synthetic", 10511 "dom-screen" 10512 ] 10513 }, 10514 "event-custom": { 10515 "use": [ 10516 "event-custom-base", 10517 "event-custom-complex" 10518 ] 10519 }, 10520 "event-custom-base": { 10521 "requires": [ 10522 "oop" 10523 ] 10524 }, 10525 "event-custom-complex": { 10526 "requires": [ 10527 "event-custom-base" 10528 ] 10529 }, 10530 "event-delegate": { 10531 "requires": [ 10532 "node-base" 10533 ] 10534 }, 10535 "event-flick": { 10536 "requires": [ 10537 "node-base", 10538 "event-touch", 10539 "event-synthetic" 10540 ] 10541 }, 10542 "event-focus": { 10543 "requires": [ 10544 "event-synthetic" 10545 ] 10546 }, 10547 "event-gestures": { 10548 "use": [ 10549 "event-flick", 10550 "event-move" 10551 ] 10552 }, 10553 "event-hover": { 10554 "requires": [ 10555 "event-mouseenter" 10556 ] 10557 }, 10558 "event-key": { 10559 "requires": [ 10560 "event-synthetic" 10561 ] 10562 }, 10563 "event-mouseenter": { 10564 "requires": [ 10565 "event-synthetic" 10566 ] 10567 }, 10568 "event-mousewheel": { 10569 "requires": [ 10570 "node-base" 10571 ] 10572 }, 10573 "event-move": { 10574 "requires": [ 10575 "node-base", 10576 "event-touch", 10577 "event-synthetic" 10578 ] 10579 }, 10580 "event-outside": { 10581 "requires": [ 10582 "event-synthetic" 10583 ] 10584 }, 10585 "event-resize": { 10586 "requires": [ 10587 "node-base", 10588 "event-synthetic" 10589 ] 10590 }, 10591 "event-simulate": { 10592 "requires": [ 10593 "event-base" 10594 ] 10595 }, 10596 "event-synthetic": { 10597 "requires": [ 10598 "node-base", 10599 "event-custom-complex" 10600 ] 10601 }, 10602 "event-tap": { 10603 "requires": [ 10604 "node-base", 10605 "event-base", 10606 "event-touch", 10607 "event-synthetic" 10608 ] 10609 }, 10610 "event-touch": { 10611 "requires": [ 10612 "node-base" 10613 ] 10614 }, 10615 "event-valuechange": { 10616 "requires": [ 10617 "event-focus", 10618 "event-synthetic" 10619 ] 10620 }, 10621 "exec-command": { 10622 "requires": [ 10623 "frame" 10624 ] 10625 }, 10626 "features": { 10627 "requires": [ 10628 "yui-base" 10629 ] 10630 }, 10631 "file": { 10632 "requires": [ 10633 "file-flash", 10634 "file-html5" 10635 ] 10636 }, 10637 "file-flash": { 10638 "requires": [ 10639 "base" 10640 ] 10641 }, 10642 "file-html5": { 10643 "requires": [ 10644 "base" 10645 ] 10646 }, 10647 "frame": { 10648 "requires": [ 10649 "base", 10650 "node", 10651 "plugin", 10652 "selector-css3", 10653 "yui-throttle" 10654 ] 10655 }, 10656 "gesture-simulate": { 10657 "requires": [ 10658 "async-queue", 10659 "event-simulate", 10660 "node-screen" 10661 ] 10662 }, 10663 "get": { 10664 "requires": [ 10665 "yui-base" 10666 ] 10667 }, 10668 "graphics": { 10669 "requires": [ 10670 "node", 10671 "event-custom", 10672 "pluginhost", 10673 "matrix", 10674 "classnamemanager" 10675 ] 10676 }, 10677 "graphics-canvas": { 10678 "condition": { 10679 "name": "graphics-canvas", 10680 "test": function(Y) { 10681 var DOCUMENT = Y.config.doc, 10682 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
10683 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10684 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10685 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 10686}, 10687 "trigger": "graphics" 10688 }, 10689 "requires": [ 10690 "graphics", 10691 "color-base" 10692 ] 10693 }, 10694 "graphics-canvas-default": { 10695 "condition": { 10696 "name": "graphics-canvas-default", 10697 "test": function(Y) { 10698 var DOCUMENT = Y.config.doc, 10699 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas", 10700 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10701 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10702 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d")); 10703}, 10704 "trigger": "graphics" 10705 } 10706 }, 10707 "graphics-group": { 10708 "requires": [ 10709 "graphics" 10710 ] 10711 }, 10712 "graphics-svg": { 10713 "condition": { 10714 "name": "graphics-svg", 10715 "test": function(Y) { 10716 var DOCUMENT = Y.config.doc, 10717 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 10718 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10719 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10720 10721 return svg && (useSVG || !canvas); 10722}, 10723 "trigger": "graphics" 10724 }, 10725 "requires": [ 10726 "graphics" 10727 ] 10728 }, 10729 "graphics-svg-default": { 10730 "condition": { 10731 "name": "graphics-svg-default", 10732 "test": function(Y) { 10733 var DOCUMENT = Y.config.doc, 10734 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas", 10735 canvas = DOCUMENT && DOCUMENT.createElement("canvas"), 10736 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")); 10737 10738 return svg && (useSVG || !canvas); 10739}, 10740 "trigger": "graphics" 10741 } 10742 }, 10743 "graphics-vml": { 10744 "condition": { 10745 "name": "graphics-vml", 10746 "test": function(Y) { 10747 var DOCUMENT = Y.config.doc, 10748 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 10749 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 10750}, 10751 "trigger": "graphics" 10752 }, 10753 "requires": [ 10754 "graphics", 10755 "color-base" 10756 ] 10757 }, 10758 "graphics-vml-default": { 10759 "condition": { 10760 "name": "graphics-vml-default", 10761 "test": function(Y) { 10762 var DOCUMENT = Y.config.doc, 10763 canvas = DOCUMENT && DOCUMENT.createElement("canvas"); 10764 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d"))); 10765}, 10766 "trigger": "graphics" 10767 } 10768 }, 10769 "handlebars": { 10770 "use": [ 10771 "handlebars-compiler" 10772 ] 10773 }, 10774 "handlebars-base": { 10775 "requires": [] 10776 }, 10777 "handlebars-compiler": { 10778 "requires": [ 10779 "handlebars-base" 10780 ] 10781 }, 10782 "highlight": { 10783 "use": [ 10784 "highlight-base", 10785 "highlight-accentfold" 10786 ] 10787 }, 10788 "highlight-accentfold": { 10789 "requires": [ 10790 "highlight-base", 10791 "text-accentfold" 10792 ] 10793 }, 10794 "highlight-base": { 10795 "requires": [ 10796 "array-extras", 10797 "classnamemanager", 10798 "escape", 10799 "text-wordbreak" 10800 ] 10801 }, 10802 "history": { 10803 "use": [ 10804 "history-base", 10805 "history-hash", 10806 "history-html5" 10807 ] 10808 }, 10809 "history-base": { 10810 "requires": [ 10811 "event-custom-complex" 10812 ] 10813 }, 10814 "history-hash": { 10815 "after": [ 10816 "history-html5" 10817 ], 10818 "requires": [ 10819 "event-synthetic", 10820 "history-base", 10821 "yui-later" 10822 ] 10823 }, 10824 "history-hash-ie": { 10825 "condition": { 10826 "name": "history-hash-ie", 10827 "test": function (Y) { 10828 var docMode = Y.config.doc && Y.config.doc.documentMode; 10829 10830 return Y.UA.ie && (!('onhashchange' in Y.config.win) || 10831 !docMode || docMode < 8); 10832}, 10833 "trigger": "history-hash" 10834 }, 10835 "requires": [ 10836 "history-hash", 10837 "node-base" 10838 ] 10839 }, 10840 "history-html5": { 10841 "optional": [ 10842 "json" 10843 ], 10844 "requires": [ 10845 "event-base", 10846 "history-base", 10847 "node-base" 10848 ] 10849 }, 10850 "imageloader": { 10851 "requires": [ 10852 "base-base", 10853 "node-style", 10854 "node-screen" 10855 ] 10856 }, 10857 "intl": { 10858 "requires": [ 10859 "intl-base", 10860 "event-custom" 10861 ] 10862 }, 10863 "intl-base": { 10864 "requires": [ 10865 "yui-base" 10866 ] 10867 }, 10868 "io": { 10869 "use": [ 10870 "io-base", 10871 "io-xdr", 10872 "io-form", 10873 "io-upload-iframe", 10874 "io-queue" 10875 ] 10876 }, 10877 "io-base": { 10878 "requires": [ 10879 "event-custom-base", 10880 "querystring-stringify-simple" 10881 ] 10882 }, 10883 "io-form": { 10884 "requires": [ 10885 "io-base", 10886 "node-base" 10887 ] 10888 }, 10889 "io-nodejs": { 10890 "condition": { 10891 "name": "io-nodejs", 10892 "trigger": "io-base", 10893 "ua": "nodejs" 10894 }, 10895 "requires": [ 10896 "io-base" 10897 ] 10898 }, 10899 "io-queue": { 10900 "requires": [ 10901 "io-base", 10902 "queue-promote" 10903 ] 10904 }, 10905 "io-upload-iframe": { 10906 "requires": [ 10907 "io-base", 10908 "node-base" 10909 ] 10910 }, 10911 "io-xdr": { 10912 "requires": [ 10913 "io-base", 10914 "datatype-xml-parse" 10915 ] 10916 }, 10917 "json": { 10918 "use": [ 10919 "json-parse", 10920 "json-stringify" 10921 ] 10922 }, 10923 "json-parse": { 10924 "requires": [ 10925 "yui-base" 10926 ] 10927 }, 10928 "json-parse-shim": { 10929 "condition": { 10930 "name": "json-parse-shim", 10931 "test": function (Y) { 10932 var _JSON = Y.config.global.JSON, 10933 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 10934 nativeSupport = Y.config.useNativeJSONParse !== false && !!Native; 10935 10936 function workingNative( k, v ) { 10937 return k === "ok" ? true : v; 10938 } 10939 10940 // Double check basic functionality. This is mainly to catch early broken 10941 // implementations of the JSON API in Firefox 3.1 beta1 and beta2
10942 if ( nativeSupport ) { 10943 try { 10944 nativeSupport = ( Native.parse( '{"ok":false}', workingNative ) ).ok; 10945 } 10946 catch ( e ) { 10947 nativeSupport = false; 10948 } 10949 } 10950 10951 return !nativeSupport; 10952}, 10953 "trigger": "json-parse" 10954 }, 10955 "requires": [ 10956 "json-parse" 10957 ] 10958 }, 10959 "json-stringify": { 10960 "requires": [ 10961 "yui-base" 10962 ] 10963 }, 10964 "json-stringify-shim": { 10965 "condition": { 10966 "name": "json-stringify-shim", 10967 "test": function (Y) { 10968 var _JSON = Y.config.global.JSON, 10969 Native = Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON, 10970 nativeSupport = Y.config.useNativeJSONStringify !== false && !!Native; 10971 10972 // Double check basic native functionality. This is primarily to catch broken 10973 // early JSON API implementations in Firefox 3.1 beta1 and beta2. 10974 if ( nativeSupport ) { 10975 try { 10976 nativeSupport = ( '0' === Native.stringify(0) ); 10977 } catch ( e ) { 10978 nativeSupport = false; 10979 } 10980 } 10981 10982 10983 return !nativeSupport; 10984}, 10985 "trigger": "json-stringify" 10986 }, 10987 "requires": [ 10988 "json-stringify" 10989 ] 10990 }, 10991 "jsonp": { 10992 "requires": [ 10993 "get", 10994 "oop" 10995 ] 10996 }, 10997 "jsonp-url": { 10998 "requires": [ 10999 "jsonp" 11000 ] 11001 }, 11002 "lazy-model-list": { 11003 "requires": [ 11004 "model-list" 11005 ] 11006 }, 11007 "loader": { 11008 "use": [ 11009 "loader-base", 11010 "loader-rollup", 11011 "loader-yui3" 11012 ] 11013 }, 11014 "loader-base": { 11015 "requires": [ 11016 "get", 11017 "features" 11018 ] 11019 }, 11020 "loader-pathogen-combohandler": {}, 11021 "loader-pathogen-encoder": { 11022 "use": [ 11023 "loader-base", 11024 "loader-rollup", 11025 "loader-yui3", 11026 "loader-pathogen-combohandler" 11027 ] 11028 }, 11029 "loader-rollup": { 11030 "requires": [ 11031 "loader-base" 11032 ] 11033 }, 11034 "loader-yui3": { 11035 "requires": [ 11036 "loader-base" 11037 ] 11038 }, 11039 "matrix": { 11040 "requires": [ 11041 "yui-base" 11042 ] 11043 }, 11044 "model": { 11045 "requires": [ 11046 "base-build", 11047 "escape", 11048 "json-parse" 11049 ] 11050 }, 11051 "model-list": { 11052 "requires": [ 11053 "array-extras", 11054 "array-invoke", 11055 "arraylist", 11056 "base-build", 11057 "escape", 11058 "json-parse", 11059 "model" 11060 ] 11061 }, 11062 "model-sync-local": { 11063 "requires": [ 11064 "model", 11065 "json-stringify" 11066 ] 11067 }, 11068 "model-sync-rest": { 11069 "requires": [ 11070 "model", 11071 "io-base", 11072 "json-stringify" 11073 ] 11074 }, 11075 "node": { 11076 "use": [ 11077 "node-base", 11078 "node-event-delegate", 11079 "node-pluginhost", 11080 "node-screen", 11081 "node-style" 11082 ] 11083 }, 11084 "node-base": { 11085 "requires": [ 11086 "event-base", 11087 "node-core", 11088 "dom-base", 11089 "dom-style" 11090 ] 11091 }, 11092 "node-core": { 11093 "requires": [ 11094 "dom-core", 11095 "selector" 11096 ] 11097 }, 11098 "node-event-delegate": { 11099 "requires": [ 11100 "node-base", 11101 "event-delegate" 11102 ] 11103 }, 11104 "node-event-html5": { 11105 "requires": [ 11106 "node-base" 11107 ] 11108 }, 11109 "node-event-simulate": { 11110 "requires": [ 11111 "node-base", 11112 "event-simulate", 11113 "gesture-simulate" 11114 ] 11115 }, 11116 "node-flick": { 11117 "requires": [ 11118 "classnamemanager", 11119 "transition", 11120 "event-flick", 11121 "plugin" 11122 ], 11123 "skinnable": true 11124 }, 11125 "node-focusmanager": { 11126 "requires": [ 11127 "attribute", 11128 "node", 11129 "plugin", 11130 "node-event-simulate", 11131 "event-key", 11132 "event-focus" 11133 ] 11134 }, 11135 "node-load": { 11136 "requires": [ 11137 "node-base", 11138 "io-base" 11139 ] 11140 }, 11141 "node-menunav": { 11142 "requires": [ 11143 "node", 11144 "classnamemanager", 11145 "plugin", 11146 "node-focusmanager" 11147 ], 11148 "skinnable": true 11149 }, 11150 "node-pluginhost": { 11151 "requires": [ 11152 "node-base", 11153 "pluginhost" 11154 ] 11155 }, 11156 "node-screen": { 11157 "requires": [ 11158 "dom-screen", 11159 "node-base" 11160 ] 11161 }, 11162 "node-scroll-info": { 11163 "requires": [ 11164 "array-extras", 11165 "base-build", 11166 "event-resize", 11167 "node-pluginhost", 11168 "plugin", 11169 "selector" 11170 ] 11171 }, 11172 "node-style": { 11173 "requires": [ 11174 "dom-style", 11175 "node-base" 11176 ] 11177 }, 11178 "oop": { 11179 "requires": [ 11180 "yui-base" 11181 ] 11182 }, 11183 "overlay": { 11184 "requires": [ 11185 "widget", 11186 "widget-stdmod", 11187 "widget-position", 11188 "widget-position-align", 11189 "widget-stack", 11190 "widget-position-constrain" 11191 ], 11192 "skinnable": true 11193 }, 11194 "paginator": { 11195 "requires": [ 11196 "paginator-core" 11197 ] 11198 }, 11199 "paginator-core": { 11200 "requires": [ 11201 "base" 11202 ] 11203 }, 11204 "paginator-url": { 11205 "requires": [ 11206 "paginator" 11207 ] 11208 }, 11209 "panel": { 11210 "requires": [ 11211 "widget", 11212 "widget-autohide", 11213 "widget-buttons", 11214 "widget-modality", 11215 "widget-position", 11216 "widget-position-align", 11217 "widget-position-constrain", 11218 "widget-stack", 11219 "widget-stdmod" 11220 ], 11221 "skinnable": true 11222 }, 11223 "parallel": { 11224 "requires": [ 11225 "yui-base" 11226 ] 11227 }, 11228 "pjax": { 11229 "requires": [ 11230 "pjax-base", 11231 "pjax-content" 11232 ] 11233 }, 11234 "pjax-base": { 11235 "requires": [ 11236 "classnamemanager", 11237 "node-event-delegate", 11238 "router" 11239 ] 11240 }, 11241 "pjax-content": { 11242 "requires": [ 11243 "io-base", 11244 "node-base", 11245 "router" 11246 ] 11247 }, 11248 "pjax-plugin": { 11249 "requires": [ 11250 "node-pluginhost", 11251 "pjax", 11252 "plugin" 11253 ] 11254 }, 11255 "plugin": { 11256 "requires": [ 11257 "base-base" 11258 ] 11259 }, 11260 "pluginhost": { 11261 "use": [ 11262 "pluginhost-base", 11263 "pluginhost-config" 11264 ] 11265 }, 11266 "pluginhost-base": { 11267 "requires": [ 11268 "yui-base" 11269 ] 11270 }, 11271 "pluginhost-config": { 11272 "requires": [ 11273 "pluginhost-base" 11274 ] 11275 }, 11276 "promise": { 11277 "requires": [ 11278 "timers" 11279 ] 11280 }, 11281 "querystring": { 11282 "use": [ 11283 "querystring-parse", 11284 "querystring-stringify" 11285 ] 11286 }, 11287 "querystring-parse": { 11288 "requires": [ 11289 "yui-base", 11290 "array-extras" 11291 ] 11292 }, 11293 "querystring-parse-simple": { 11294 "requires": [ 11295 "yui-base" 11296 ] 11297 }, 11298 "querystring-stringify": { 11299 "requires": [ 11300 "yui-base" 11301 ] 11302 }, 11303 "querystring-stringify-simple": { 11304 "requires": [ 11305 "yui-base" 11306 ] 11307 }, 11308 "queue-promote": { 11309 "requires": [ 11310 "yui-base" 11311 ] 11312 }, 11313 "range-slider": { 11314 "requires": [ 11315 "slider-base", 11316 "slider-value-range", 11317 "clickable-rail" 11318 ] 11319 }, 11320 "recordset": { 11321 "use": [ 11322 "recordset-base", 11323 "recordset-sort", 11324 "recordset-filter", 11325 "recordset-indexer" 11326 ] 11327 }, 11328 "recordset-base": { 11329 "requires": [ 11330 "base", 11331 "arraylist" 11332 ] 11333 }, 11334 "recordset-filter": { 11335 "requires": [ 11336 "recordset-base", 11337 "array-extras", 11338 "plugin" 11339 ] 11340 }, 11341 "recordset-indexer": { 11342 "requires": [ 11343 "recordset-base", 11344 "plugin" 11345 ] 11346 }, 11347 "recordset-sort": { 11348 "requires": [ 11349 "arraysort", 11350 "recordset-base", 11351 "plugin" 11352 ] 11353 }, 11354 "resize": { 11355 "use": [ 11356 "resize-base", 11357 "resize-proxy", 11358 "resize-constrain" 11359 ] 11360 }, 11361 "resize-base": { 11362 "requires": [ 11363 "base", 11364 "widget", 11365 "event", 11366 "oop", 11367 "dd-drag", 11368 "dd-delegate", 11369 "dd-drop" 11370 ], 11371 "skinnable": true 11372 }, 11373 "resize-constrain": { 11374 "requires": [ 11375 "plugin", 11376 "resize-base" 11377 ] 11378 }, 11379 "resize-plugin": { 11380 "optional": [ 11381 "resize-constrain" 11382 ], 11383 "requires": [ 11384 "resize-base", 11385 "plugin" 11386 ] 11387 }, 11388 "resize-proxy": { 11389 "requires": [ 11390 "plugin", 11391 "resize-base" 11392 ] 11393 }, 11394 "router": { 11395 "optional": [ 11396 "querystring-parse" 11397 ], 11398 "requires": [ 11399 "array-extras", 11400 "base-build", 11401 "history" 11402 ] 11403 }, 11404 "scrollview": { 11405 "requires": [ 11406 "scrollview-base", 11407 "scrollview-scrollbars" 11408 ] 11409 }, 11410 "scrollview-base": { 11411 "requires": [ 11412 "widget", 11413 "event-gestures", 11414 "event-mousewheel", 11415 "transition" 11416 ], 11417 "skinnable": true 11418 }, 11419 "scrollview-base-ie": { 11420 "condition": { 11421 "name": "scrollview-base-ie", 11422 "trigger": "scrollview-base", 11423 "ua": "ie" 11424 }, 11425 "requires": [ 11426 "scrollview-base" 11427 ] 11428 }, 11429 "scrollview-list": { 11430 "requires": [ 11431 "plugin", 11432 "classnamemanager" 11433 ], 11434 "skinnable": true 11435 }, 11436 "scrollview-paginator": { 11437 "requires": [ 11438 "plugin", 11439 "classnamemanager" 11440 ] 11441 }, 11442 "scrollview-scrollbars": { 11443 "requires": [ 11444 "classnamemanager", 11445 "transition", 11446 "plugin" 11447 ], 11448 "skinnable": true 11449 }, 11450 "selector": { 11451 "requires": [ 11452 "selector-native" 11453 ] 11454 }, 11455 "selector-css2": { 11456 "condition": { 11457 "name": "selector-css2", 11458 "test": function (Y) { 11459 var DOCUMENT = Y.config.doc, 11460 ret = DOCUMENT && !('querySelectorAll' in DOCUMENT); 11461 11462 return ret; 11463}, 11464 "trigger": "selector" 11465 }, 11466 "requires": [ 11467 "selector-native" 11468 ] 11469 }, 11470 "selector-css3": { 11471 "requires": [ 11472 "selector-native", 11473 "selector-css2" 11474 ] 11475 }, 11476 "selector-native": { 11477 "requires": [ 11478 "dom-base" 11479 ] 11480 }, 11481 "series-area": { 11482 "requires": [ 11483 "series-cartesian", 11484 "series-fill-util" 11485 ] 11486 }, 11487 "series-area-stacked": { 11488 "requires": [ 11489 "series-stacked", 11490 "series-area" 11491 ] 11492 }, 11493 "series-areaspline": { 11494 "requires": [ 11495 "series-area", 11496 "series-curve-util" 11497 ] 11498 }, 11499 "series-areaspline-stacked": { 11500 "requires": [ 11501 "series-stacked", 11502 "series-areaspline" 11503 ] 11504 }, 11505 "series-bar": { 11506 "requires": [ 11507 "series-marker", 11508 "series-histogram-base" 11509 ] 11510 }, 11511 "series-bar-stacked": { 11512 "requires": [ 11513 "series-stacked", 11514 "series-bar" 11515 ] 11516 }, 11517 "series-base": { 11518 "requires": [ 11519 "graphics", 11520 "axis-base" 11521 ] 11522 }, 11523 "series-candlestick": { 11524 "requires": [ 11525 "series-range" 11526 ] 11527 }, 11528 "series-cartesian": { 11529 "requires": [ 11530 "series-base" 11531 ] 11532 }, 11533 "series-column": { 11534 "requires": [ 11535 "series-marker", 11536 "series-histogram-base" 11537 ] 11538 }, 11539 "series-column-stacked": { 11540 "requires": [ 11541 "series-stacked", 11542 "series-column" 11543 ] 11544 }, 11545 "series-combo": { 11546 "requires": [ 11547 "series-cartesian", 11548 "series-line-util", 11549 "series-plot-util", 11550 "series-fill-util" 11551 ] 11552 }, 11553 "series-combo-stacked": { 11554 "requires": [ 11555 "series-stacked", 11556 "series-combo" 11557 ] 11558 }, 11559 "series-combospline": { 11560 "requires": [ 11561 "series-combo", 11562 "series-curve-util" 11563 ] 11564 }, 11565 "series-combospline-stacked": { 11566 "requires": [ 11567 "series-combo-stacked", 11568 "series-curve-util" 11569 ] 11570 }, 11571 "series-curve-util": {}, 11572 "series-fill-util": {}, 11573 "series-histogram-base": { 11574 "requires": [ 11575 "series-cartesian", 11576 "series-plot-util" 11577 ] 11578 }, 11579 "series-line": { 11580 "requires": [ 11581 "series-cartesian", 11582 "series-line-util" 11583 ] 11584 }, 11585 "series-line-stacked": { 11586 "requires": [ 11587 "series-stacked", 11588 "series-line" 11589 ] 11590 }, 11591 "series-line-util": {}, 11592 "series-marker": { 11593 "requires": [ 11594 "series-cartesian", 11595 "series-plot-util" 11596 ] 11597 }, 11598 "series-marker-stacked": { 11599 "requires": [ 11600 "series-stacked", 11601 "series-marker" 11602 ] 11603 }, 11604 "series-ohlc": { 11605 "requires": [ 11606 "series-range" 11607 ] 11608 }, 11609 "series-pie": { 11610 "requires": [ 11611 "series-base", 11612 "series-plot-util" 11613 ] 11614 }, 11615 "series-plot-util": {}, 11616 "series-range": { 11617 "requires": [ 11618 "series-cartesian" 11619 ] 11620 }, 11621 "series-spline": { 11622 "requires": [ 11623 "series-line", 11624 "series-curve-util" 11625 ] 11626 }, 11627 "series-spline-stacked": { 11628 "requires": [ 11629 "series-stacked", 11630 "series-spline" 11631 ] 11632 }, 11633 "series-stacked": { 11634 "requires": [ 11635 "axis-stacked" 11636 ] 11637 }, 11638 "shim-plugin": { 11639 "requires": [ 11640 "node-style", 11641 "node-pluginhost" 11642 ] 11643 }, 11644 "slider": { 11645 "use": [ 11646 "slider-base", 11647 "slider-value-range", 11648 "clickable-rail", 11649 "range-slider" 11650 ] 11651 }, 11652 "slider-base": { 11653 "requires": [ 11654 "widget", 11655 "dd-constrain", 11656 "event-key" 11657 ], 11658 "skinnable": true 11659 }, 11660 "slider-value-range": { 11661 "requires": [ 11662 "slider-base" 11663 ] 11664 }, 11665 "sortable": { 11666 "requires": [ 11667 "dd-delegate", 11668 "dd-drop-plugin", 11669 "dd-proxy" 11670 ] 11671 }, 11672 "sortable-scroll": { 11673 "requires": [ 11674 "dd-scroll", 11675 "sortable" 11676 ] 11677 }, 11678 "stylesheet": { 11679 "requires": [ 11680 "yui-base" 11681 ] 11682 }, 11683 "substitute": { 11684 "optional": [ 11685 "dump" 11686 ], 11687 "requires": [ 11688 "yui-base" 11689 ] 11690 }, 11691 "swf": { 11692 "requires": [ 11693 "event-custom", 11694 "node", 11695 "swfdetect", 11696 "escape" 11697 ] 11698 }, 11699 "swfdetect": { 11700 "requires": [ 11701 "yui-base" 11702 ] 11703 }, 11704 "tabview": { 11705 "requires": [ 11706 "widget", 11707 "widget-parent", 11708 "widget-child", 11709 "tabview-base", 11710 "node-pluginhost", 11711 "node-focusmanager" 11712 ], 11713 "skinnable": true 11714 }, 11715 "tabview-base": { 11716 "requires": [ 11717 "node-event-delegate", 11718 "classnamemanager" 11719 ] 11720 }, 11721 "tabview-plugin": { 11722 "requires": [ 11723 "tabview-base" 11724 ] 11725 }, 11726 "template": { 11727 "use": [ 11728 "template-base", 11729 "template-micro" 11730 ] 11731 }, 11732 "template-base": { 11733 "requires": [ 11734 "yui-base" 11735 ] 11736 }, 11737 "template-micro": { 11738 "requires": [ 11739 "escape" 11740 ] 11741 }, 11742 "test": { 11743 "requires": [ 11744 "event-simulate", 11745 "event-custom", 11746 "json-stringify" 11747 ] 11748 }, 11749
11749 "test-console": { 11750 "requires": [ 11751 "console-filters", 11752 "test", 11753 "array-extras" 11754 ], 11755 "skinnable": true 11756 }, 11757 "text": { 11758 "use": [ 11759 "text-accentfold", 11760 "text-wordbreak" 11761 ] 11762 }, 11763 "text-accentfold": { 11764 "requires": [ 11765 "array-extras", 11766 "text-data-accentfold" 11767 ] 11768 }, 11769 "text-data-accentfold": { 11770 "requires": [ 11771 "yui-base" 11772 ] 11773 }, 11774 "text-data-wordbreak": { 11775 "requires": [ 11776 "yui-base" 11777 ] 11778 }, 11779 "text-wordbreak": { 11780 "requires": [ 11781 "array-extras", 11782 "text-data-wordbreak" 11783 ] 11784 }, 11785 "timers": { 11786 "requires": [ 11787 "yui-base" 11788 ] 11789 }, 11790 "transition": { 11791 "requires": [ 11792 "node-style" 11793 ] 11794 }, 11795 "transition-timer": { 11796 "condition": { 11797 "name": "transition-timer", 11798 "test": function (Y) { 11799 var DOCUMENT = Y.config.doc, 11800 node = (DOCUMENT) ? DOCUMENT.documentElement: null, 11801 ret = true; 11802 11803 if (node && node.style) { 11804 ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style || 'transition' in node.style); 11805 } 11806 11807 return ret; 11808}, 11809 "trigger": "transition" 11810 }, 11811 "requires": [ 11812 "transition" 11813 ] 11814 }, 11815 "tree": { 11816 "requires": [ 11817 "base-build", 11818 "tree-node" 11819 ] 11820 }, 11821 "tree-labelable": { 11822 "requires": [ 11823 "tree" 11824 ] 11825 }, 11826 "tree-lazy": { 11827 "requires": [ 11828 "base-pluginhost", 11829 "plugin", 11830 "tree" 11831 ] 11832 }, 11833 "tree-node": {}, 11834 "tree-openable": { 11835 "requires": [ 11836 "tree" 11837 ] 11838 }, 11839 "tree-selectable": { 11840 "requires": [ 11841 "tree" 11842 ] 11843 }, 11844 "tree-sortable": { 11845 "requires": [ 11846 "tree" 11847 ] 11848 }, 11849 "uploader": { 11850 "requires": [ 11851 "uploader-html5", 11852 "uploader-flash" 11853 ] 11854 }, 11855 "uploader-flash": { 11856 "requires": [ 11857 "swfdetect", 11858 "escape", 11859 "widget", 11860 "base", 11861 "cssbutton", 11862 "node", 11863 "event-custom", 11864 "uploader-queue" 11865 ] 11866 }, 11867 "uploader-html5": { 11868 "requires": [ 11869 "widget", 11870 "node-event-simulate", 11871 "file-html5", 11872 "uploader-queue" 11873 ] 11874 }, 11875 "uploader-queue": { 11876 "requires": [ 11877 "base" 11878 ] 11879 }, 11880 "view": { 11881 "requires": [ 11882 "base-build", 11883 "node-event-delegate" 11884 ] 11885 }, 11886 "view-node-map": { 11887 "requires": [ 11888 "view" 11889 ] 11890 }, 11891 "widget": { 11892 "use": [ 11893 "widget-base", 11894 "widget-htmlparser", 11895 "widget-skin", 11896 "widget-uievents" 11897 ] 11898 }, 11899 "widget-anim": { 11900 "requires": [ 11901 "anim-base", 11902 "plugin", 11903 "widget" 11904 ] 11905 }, 11906 "widget-autohide": { 11907 "requires": [ 11908 "base-build", 11909 "event-key", 11910 "event-outside", 11911 "widget" 11912 ] 11913 }, 11914 "widget-base": { 11915 "requires": [ 11916 "attribute", 11917 "base-base", 11918 "base-pluginhost", 11919 "classnamemanager", 11920 "event-focus", 11921 "node-base", 11922 "node-style" 11923 ], 11924 "skinnable": true 11925 }, 11926 "widget-base-ie": { 11927 "condition": { 11928 "name": "widget-base-ie", 11929 "trigger": "widget-base", 11930 "ua": "ie" 11931 }, 11932 "requires": [ 11933 "widget-base" 11934 ] 11935 }, 11936 "widget-buttons": { 11937 "requires": [ 11938 "button-plugin", 11939 "cssbutton", 11940 "widget-stdmod" 11941 ] 11942 }, 11943 "widget-child": { 11944 "requires": [ 11945 "base-build", 11946 "widget" 11947 ] 11948 }, 11949 "widget-htmlparser": { 11950 "requires": [ 11951 "widget-base" 11952 ] 11953 }, 11954 "widget-modality": { 11955 "requires": [ 11956 "base-build", 11957 "event-outside", 11958 "widget" 11959 ], 11960 "skinnable": true 11961 }, 11962 "widget-parent": { 11963 "requires": [ 11964 "arraylist", 11965 "base-build", 11966 "widget" 11967 ] 11968 }, 11969 "widget-position": { 11970 "requires": [ 11971 "base-build", 11972 "node-screen", 11973 "widget" 11974 ] 11975 }, 11976 "widget-position-align": { 11977 "requires": [ 11978 "widget-position" 11979 ] 11980 }, 11981 "widget-position-constrain": { 11982 "requires": [ 11983 "widget-position" 11984 ] 11985 }, 11986 "widget-skin": { 11987 "requires": [ 11988 "widget-base" 11989 ] 11990 }, 11991 "widget-stack": { 11992 "requires": [ 11993 "base-build", 11994 "widget" 11995 ], 11996 "skinnable": true 11997 }, 11998 "widget-stdmod": { 11999 "requires": [ 12000 "base-build", 12001 "widget" 12002 ] 12003 }, 12004 "widget-uievents": { 12005 "requires": [ 12006 "node-event-delegate", 12007 "widget-base" 12008 ] 12009 }, 12010 "yql": { 12011 "requires": [ 12012 "oop" 12013 ] 12014 }, 12015 "yql-jsonp": { 12016 "condition": { 12017 "name": "yql-jsonp", 12018 "test": function (Y) { 12019 /* Only load the JSONP module when not in nodejs or winjs 12020 TODO Make the winjs module a CORS module 12021 */ 12022 return (!Y.UA.nodejs && !Y.UA.winjs); 12023}, 12024 "trigger": "yql" 12025 }, 12026 "requires": [ 12027 "yql", 12028 "jsonp", 12029 "jsonp-url" 12030 ] 12031 }, 12032 "yql-nodejs": { 12033 "condition": { 12034 "name": "yql-nodejs", 12035 "trigger": "yql", 12036 "ua": "nodejs" 12037 }, 12038 "requires": [ 12039 "yql" 12040 ] 12041 }, 12042 "yql-winjs": { 12043 "condition": { 12044 "name": "yql-winjs", 12045 "trigger": "yql", 12046 "ua": "winjs" 12047 }, 12048 "requires": [ 12049 "yql" 12050 ] 12051 }, 12052 "yui": {}, 12053 "yui-base": {}, 12054 "yui-later": { 12055 "requires": [ 12056 "yui-base" 12057 ] 12058 }, 12059 "yui-log": { 12060 "requires": [ 12061 "yui-base" 12062 ] 12063 }, 12064 "yui-throttle": { 12065 "requires": [ 12066 "yui-base" 12067 ] 12068 } 12069}); 12070YUI.Env[Y.version].md5 = 'f20377d5ab6d37137f73ea79d6eb476d'; 12071 12072 12073}, 'patched-v3.18.1', {"requires": ["loader-base"]}); 12074YUI.add('yui', function (Y, NAME) {}, 'patched-v3.18.1', { 12075 "use": [ 12076 "yui-base", 12077 "get", 12078 "features", 12079 "intl-base", 12080 "yui-log", 12081 "yui-later", 12082 "loader-base", 12083 "loader-rollup", 12084 "loader-yui3" 12085 ] 12086}); 12087YUI.add('aui-base-core', function (A, NAME) { 12088 12089var Y = A; 12090YUI.Env.aliases = YUI.Env.aliases || {}; 12091Y.mix(YUI.Env.aliases, { 12092 "aui-autosize": ["aui-autosize-iframe"], 12093 "aui-base": ["oop","yui-throttle","aui-classnamemanager","aui-debounce","aui-base-core","aui-base-lang","aui-node-base"], 12094 "aui-base-deprecated": ["aui-base","aui-node","aui-component","aui-delayed-task-deprecated","aui-selector","aui-event-base"], 12095 "aui-button": ["aui-button-core"], 12096 "aui-collection": ["aui-map","aui-set","aui-linkedset"], 12097 "aui-color-picker-deprecated": ["aui-color-picker-base-deprecated","aui-color-picker-grid-plugin-deprecated"], 12098 "aui-datasource-control-deprecated": ["aui-datasource-control-base-deprecated","aui-input-text-control-deprecated"], 12099 "aui-datatable": ["aui-datatable-edit","aui-datatable-highlight","aui-datatable-selection","aui-datatable-property-list"], 12100 "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"], 12101 "aui-datepicker-deprecated": ["aui-datepicker-base-deprecated","aui-datepicker-select-deprecated"], 12102 "aui-event": ["aui-event-base"], 12103 "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"], 12104 "aui-io": ["aui-io-request"], 12105 "aui-io-deprecated": ["aui-io-request","aui-io-plugin-deprecated"], 12106 "aui-node": ["aui-node-base"], 12107 "aui-overlay-deprecated": ["aui-overlay-base-deprecated","aui-overlay-context-deprecated","aui-overlay-context-panel-deprecated","aui-overlay-manager-deprecated","aui-overlay-mask-deprecated"], 12108 "aui-rating": ["aui-rating-base","aui-rating-thumb"], 12109 "aui-resize-deprecated": ["aui-resize-base-deprecated","aui-resize-constrain-deprecated"], 12110 "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"], 12111 "aui-search": ["aui-search-tst"], 12112 "aui-sortable": ["aui-sortable-layout","aui-sortable-list"], 12113 "aui-surface": ["aui-surface-app","aui-surface-screen"], 12114 "aui-toggler": ["aui-toggler-base","aui-toggler-delegate"], 12115 "aui-tooltip": ["aui-tooltip-base","aui-tooltip-delegate"], 12116 "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"], 12117 "aui-tree": ["aui-tree-data","aui-tree-io","aui-tree-node","aui-tree-paginator","aui-tree-view"], 12118 "aui-widget": ["aui-widget-cssclass","aui-widget-toolbars"], 12119 "aui-widget-core": ["aui-widget-cssclass"] 12120}); 12121/* This file is auto-generated by (yogi loader --yes --mix --js js/aui-loader.js --json js/aui-loader.json --start ../) */ 12122 12123/*jshint maxlen:900, eqeqeq: false */ 12124 12125/** 12126 * YUI 3 module metadata 12127 * @module loader 12128 * @submodule loader-yui3 12129 */ 12130YUI.Env[Y.version].modules = YUI.Env[Y.version].modules || {}; 12131Y.mix(YUI.Env[Y.version].modules, { 12132 "aui-ace-autocomplete-base": { 12133 "requires": [ 12134 "aui-ace-editor" 12135 ] 12136 }, 12137 "aui-ace-autocomplete-freemarker": { 12138 "requires": [ 12139 "aui-ace-autocomplete-templateprocessor" 12140 ] 12141 }, 12142 "aui-ace-autocomplete-list": { 12143 "requires": [ 12144 "aui-ace-autocomplete-base", 12145 "overlay", 12146 "widget-autohide" 12147 ], 12148 "skinnable": true 12149 }, 12150 "aui-ace-autocomplete-plugin": { 12151 "requires": [ 12152 "aui-ace-autocomplete-list", 12153 "plugin" 12154 ] 12155 }, 12156 "aui-ace-autocomplete-templateprocessor": { 12157 "requires": [ 12158 "aui-ace-autocomplete-base" 12159 ] 12160 }, 12161 "aui-ace-autocomplete-velocity": { 12162 "requires": [ 12163 "aui-ace-autocomplete-templateprocessor" 12164 ] 12165 }, 12166 "aui-ace-editor": { 12167 "requires": [ 12168 "aui-node", 12169 "aui-component" 12170 ] 12171 }, 12172 "aui-affix": { 12173 "requires": [ 12174 "base", 12175 "node-screen", 12176 "aui-node" 12177 ] 12178 }, 12179 "aui-alert": { 12180 "requires": [ 12181 "aui-aria", 12182 "aui-classnamemanager", 12183 "aui-widget-cssclass", 12184 "aui-widget-transition", 12185 "timers", 12186 "widget", 12187 "widget-stdmod" 12188 ], 12189 "skinnable": true 12190 }, 12191 "aui-aria": { 12192 "requires": [ 12193 "plugin", 12194 "aui-component" 12195 ] 12196 }, 12197 "aui-aria-table-sortable": { 12198 "requires": [ 12199 "aui-aria" 12200 ] 12201 }, 12202 "aui-arraysort": { 12203 "requires": [ 12204 "arraysort" 12205 ] 12206 }, 12207 "aui-audio": { 12208 "requires": [ 12209 "aui-aria", 12210 "aui-node", 12211 "aui-component", 12212 "node-event-html5", 12213 "querystring-stringify-simple" 12214 ], 12215 "skinnable": true 12216 }, 12217 "aui-autocomplete-deprecated": { 12218 "requires": [ 12219 "aui-base-deprecated", 12220 "aui-overlay-base-deprecated", 12221 "datasource", 12222 "dataschema", 12223 "aui-form-combobox-deprecated" 12224 ], 12225 "skinnable": true 12226 }, 12227 "aui-autosize": { 12228 "use": [ 12229 "aui-autosize-iframe" 12230 ] 12231 }, 12232 "aui-autosize-deprecated": { 12233 "requires": [ 12234 "event-valuechange", 12235 "plugin", 12236 "aui-base-deprecated" 12237 ], 12238 "skinnable": true 12239 }, 12240 "aui-autosize-iframe": { 12241 "requires": [ 12242 "plugin", 12243 "aui-component", 12244 "aui-timer", 12245 "aui-node-base" 12246 ] 12247 }, 12248 "aui-base": { 12249 "use": [ 12250 "oop", 12251 "yui-throttle", 12252 "aui-classnamemanager", 12253 "aui-debounce", 12254 "aui-base-core", 12255 "aui-base-lang", 12256 "aui-node-base" 12257 ] 12258 }, 12259 "aui-base-core": {}, 12260 "aui-base-deprecated": { 12261 "use": [ 12262 "aui-base", 12263 "aui-node", 12264 "aui-component", 12265 "aui-delayed-task-deprecated", 12266 "aui-selector", 12267 "aui-event-base" 12268 ] 12269 }, 12270 "aui-base-html5-shiv": { 12271 "condition": { 12272 "name": "aui-base-html5-shiv", 12273 "trigger": "node-base", 12274 "ua": "ie" 12275 } 12276 }, 12277 "aui-base-lang": {}, 12278 "aui-boolean-data-editor": { 12279 "requires": [ 12280 "aui-button-switch", 12281 "aui-data-editor" 12282 ] 12283 }, 12284 "aui-button": { 12285 "use": [ 12286 "aui-button-core" 12287 ] 12288 }, 12289 "aui-button-core": { 12290 "requires": [ 12291 "button", 12292 "button-group", 12293 "button-plugin", 12294 "aui-component", 12295 "aui-widget-cssclass", 12296 "aui-widget-toggle" 12297 ], 12298 "skinnable": true 12299 }, 12300 "aui-button-item-deprecated": { 12301 "requires": [ 12302 "aui-base-deprecated", 12303 "aui-state-interaction-deprecated", 12304 "widget-child" 12305 ], 12306 "skinnable": true 12307 }, 12308 "aui-button-search-cancel": { 12309 "requires": [ 12310 "array-invoke", 12311 "base", 12312 "base-build", 12313 "event-focus", 12314 "event-move", 12315 "event-resize", 12316 "node-screen", 12317 "node-event-delegate", 12318 "aui-node-base", 12319 "aui-classnamemanager", 12320 "aui-event-input" 12321 ] 12322 }, 12323 "aui-button-switch": { 12324 "requires": [ 12325 "aui-node-base", 12326 "base-build", 12327 "event-key", 12328 "transition", 12329 "widget" 12330 ], 12331 "skinnable": true 12332 }, 12333 "aui-carousel": { 12334 "requires": [ 12335 "anim", 12336 "aui-event", 12337 "aui-image-viewer-base", 12338 "aui-image-viewer-slideshow", 12339 "node-event-delegate", 12340 "node-focusmanager" 12341 ], 12342 "skinnable": true 12343 }, 12344 "aui-carousel-mobile-touch": { 12345 "condition": { 12346 "name": "aui-carousel-mobile-touch", 12347 "test": function(A) { 12348 return A.UA.mobile && A.UA.touchEnabled; 12349}, 12350 "trigger": "aui-carousel" 12351 }, 12352 "requires": [ 12353 "base-build", 12354 "aui-carousel" 12355 ] 12356 }, 12357 "aui-carousel-swipe": { 12358 "condition": { 12359 "name": "aui-carousel-swipe", 12360 "trigger": "aui-carousel", 12361 "ua": "touchEnabled" 12362 }, 12363 "requires": [ 12364 "aui-carousel", 12365 "aui-widget-swipe", 12366 "base-build" 12367 ], 12368 "skinnable": true 12369 },
12370 "aui-char-counter": { 12371 "requires": [ 12372 "aui-aria", 12373 "aui-node", 12374 "aui-event-input", 12375 "aui-component" 12376 ] 12377 }, 12378 "aui-chart-deprecated": { 12379 "requires": [ 12380 "datasource", 12381 "json", 12382 "aui-swf-deprecated" 12383 ] 12384 }, 12385 "aui-classnamemanager": { 12386 "requires": [ 12387 "classnamemanager" 12388 ] 12389 }, 12390 "aui-collection": { 12391 "use": [ 12392 "aui-map", 12393 "aui-set", 12394 "aui-linkedset" 12395 ] 12396 }, 12397 "aui-color-palette": { 12398 "requires": [ 12399 "array-extras", 12400 "aui-palette", 12401 "color-base", 12402 "node-core", 12403 "aui-widget-cssclass", 12404 "aui-widget-toggle" 12405 ], 12406 "skinnable": true 12407 }, 12408 "aui-color-picker-base": { 12409 "requires": [ 12410 "aui-color-palette", 12411 "aui-hsva-palette-modal", 12412 "event-outside" 12413 ], 12414 "skinnable": true 12415 }, 12416 "aui-color-picker-base-deprecated": { 12417 "requires": [ 12418 "dd-drag", 12419 "panel", 12420 "slider", 12421 "aui-button-item-deprecated", 12422 "aui-color-util-deprecated", 12423 "aui-form-base-deprecated", 12424 "aui-overlay-context-deprecated" 12425 ], 12426 "skinnable": true 12427 }, 12428 "aui-color-picker-deprecated": { 12429 "use": [ 12430 "aui-color-picker-base-deprecated", 12431 "aui-color-picker-grid-plugin-deprecated" 12432 ] 12433 }, 12434 "aui-color-picker-grid-plugin-deprecated": { 12435 "requires": [ 12436 "plugin", 12437 "aui-color-picker-base-deprecated" 12438 ], 12439 "skinnable": true 12440 }, 12441 "aui-color-picker-popover": { 12442 "requires": [ 12443 "aui-color-picker-base", 12444 "aui-popover", 12445 "aui-widget-cssclass", 12446 "aui-widget-toggle" 12447 ], 12448 "skinnable": true 12449 }, 12450 "aui-color-util-deprecated": { 12451 "requires": [] 12452 }, 12453 "aui-component": { 12454 "requires": [ 12455 "aui-classnamemanager", 12456 "aui-widget-cssclass", 12457 "aui-widget-toggle", 12458 "base-build", 12459 "widget-base" 12460 ] 12461 }, 12462 "aui-css": { 12463 "type": "css" 12464 }, 12465 "aui-data-editor": { 12466 "requires": [ 12467 "aui-classnamemanager", 12468 "base-build", 12469 "node-base" 12470 ], 12471 "skinnable": true 12472 }, 12473 "aui-data-set-deprecated": { 12474 "requires": [ 12475 "oop", 12476 "collection", 12477 "base" 12478 ] 12479 }, 12480 "aui-datasource-control-base-deprecated": { 12481 "requires": [ 12482 "datasource", 12483 "dataschema", 12484 "aui-base-deprecated" 12485 ] 12486 }, 12487 "aui-datasource-control-deprecated": { 12488 "use": [ 12489 "aui-datasource-control-base-deprecated", 12490 "aui-input-text-control-deprecated" 12491 ] 12492 }, 12493 "aui-datatable": { 12494 "use": [ 12495 "aui-datatable-edit", 12496 "aui-datatable-highlight", 12497 "aui-datatable-selection", 12498 "aui-datatable-property-list" 12499 ] 12500 }, 12501 "aui-datatable-base-cell-editor": { 12502 "requires": [ 12503 "datatable-base", 12504 "overlay" 12505 ], 12506 "skinnable": true 12507 }, 12508 "aui-datatable-base-options-cell-editor": { 12509 "requires": [ 12510 "aui-datatable-base-cell-editor", 12511 "escape" 12512 ], 12513 "skinnable": true 12514 }, 12515 "aui-datatable-body": { 12516 "requires": [ 12517 "aui-classnamemanager", 12518 "datatable-base", 12519 "event-key", 12520 "aui-event-base" 12521 ] 12522 }, 12523 "aui-datatable-cell-editor-support": { 12524 "requires": [ 12525 "datatable-base" 12526 ] 12527 }, 12528 "aui-datatable-checkbox-cell-editor": { 12529 "requires": [ 12530 "aui-datatable-base-options-cell-editor" 12531 ] 12532 }, 12533 "aui-datatable-core": { 12534 "requires": [ 12535 "aui-datatable-body", 12536 "datatable-base", 12537 "event-key", 12538 "aui-event-base" 12539 ], 12540 "skinnable": true 12541 }, 12542 "aui-datatable-date-cell-editor": { 12543 "requires": [ 12544 "aui-datatable-base-options-cell-editor" 12545 ] 12546 }, 12547 "aui-datatable-dropdown-cell-editor": { 12548 "requires": [ 12549 "aui-datatable-base-options-cell-editor" 12550 ] 12551 }, 12552 "aui-datatable-edit": { 12553 "use": [ 12554 "datatable-base", 12555 "calendar", 12556 "overlay", 12557 "sortable", 12558 "aui-datatype", 12559 "aui-toolbar", 12560 "aui-form-validator", 12561 "aui-datatable-base-cell-editor", 12562 "aui-datatable-base-options-cell-editor", 12563 "aui-datatable-cell-editor-support", 12564 "aui-datatable-core", 12565 "aui-datatable-checkbox-cell-editor", 12566 "aui-datatable-date-cell-editor", 12567 "aui-datatable-dropdown-cell-editor", 12568 "aui-datatable-radio-cell-editor", 12569 "aui-datatable-text-cell-editor", 12570 "aui-datatable-text-area-cell-editor" 12571 ] 12572 }, 12573 "aui-datatable-highlight": { 12574 "requires": [ 12575 "aui-datatable-selection" 12576 ], 12577 "skinnable": true 12578 }, 12579 "aui-datatable-property-list": { 12580 "requires": [ 12581 "datatable-scroll", 12582 "datatable-sort", 12583 "aui-datatable-core", 12584 "aui-datatable-edit", 12585 "aui-datatable-highlight", 12586 "aui-datatable-selection", 12587 "aui-widget-cssclass", 12588 "aui-widget-toggle" 12589 ], 12590 "skinnable": true 12591 }, 12592 "aui-datatable-radio-cell-editor": { 12593 "requires": [ 12594 "aui-datatable-base-options-cell-editor" 12595 ] 12596 }, 12597 "aui-datatable-selection": { 12598 "requires": [ 12599 "aui-datatable-core" 12600 ], 12601 "skinnable": true 12602 }, 12603 "aui-datatable-text-area-cell-editor": { 12604 "requires": [ 12605 "aui-datatable-base-options-cell-editor" 12606 ] 12607 }, 12608 "aui-datatable-text-cell-editor": { 12609 "requires": [ 12610 "aui-datatable-base-options-cell-editor" 12611 ] 12612 }, 12613 "aui-datatype": { 12614 "requires": [ 12615 "datatype", 12616 "aui-datatype-date-parse" 12617 ] 12618 }, 12619 "aui-datatype-date-parse": { 12620 "requires": [ 12621 "aui-base-lang", 12622 "datatype-date-format", 12623 "datatype-date-parse", 12624 "intl" 12625 ] 12626 }, 12627 "aui-datepicker": { 12628 "requires": [ 12629 "aui-aria", 12630 "aui-datepicker-delegate", 12631 "aui-datepicker-popover", 12632 "base", 12633 "base-build", 12634 "calendar" 12635 ], 12636 "skinnable": true 12637 }, 12638 "aui-datepicker-base-deprecated": { 12639 "requires": [ 12640 "calendar", 12641 "aui-datatype", 12642 "aui-overlay-context-deprecated" 12643 ], 12644 "skinnable": true 12645 }, 12646 "aui-datepicker-delegate": { 12647 "requires": [ 12648 "aui-datatype-date-parse", 12649 "aui-event-input", 12650 "event-focus", 12651 "node-event-delegate" 12652 ] 12653 }, 12654 "aui-datepicker-deprecated": { 12655 "skinnable": true, 12656 "use": [ 12657 "aui-datepicker-base-deprecated", 12658 "aui-datepicker-select-deprecated" 12659 ] 12660 }, 12661 "aui-datepicker-native": { 12662 "requires": [ 12663 "aui-datepicker-delegate", 12664 "aui-node-base", 12665 "base", 12666 "base-build" 12667 ] 12668 }, 12669 "aui-datepicker-popover": { 12670 "requires": [ 12671 "aui-classnamemanager", 12672 "aui-popover" 12673 ] 12674 }, 12675 "aui-datepicker-select-deprecated": { 12676 "requires": [ 12677 "aui-datepicker-base-deprecated", 12678 "aui-button-item-deprecated" 12679 ], 12680 "skinnable": true 12681 }, 12682 "aui-debounce": {}, 12683 "aui-delayed-task-deprecated": { 12684 "requires": [ 12685 "yui-base" 12686 ] 12687 }, 12688 "aui-diagram-builder": { 12689 "requires": [ 12690 "aui-aria", 12691 "aui-map", 12692 "aui-property-builder",
12693 "aui-diagram-builder-connector", 12694 "aui-property-builder-settings", 12695 "aui-diagram-node-condition", 12696 "aui-diagram-node-end", 12697 "aui-diagram-node-fork", 12698 "aui-diagram-node-join", 12699 "aui-diagram-node-start", 12700 "aui-diagram-node-state", 12701 "aui-diagram-node-task", 12702 "overlay" 12703 ], 12704 "skinnable": true 12705 }, 12706 "aui-diagram-builder-connector": { 12707 "requires": [ 12708 "arraylist-add", 12709 "arraylist-filter", 12710 "escape", 12711 "json", 12712 "graphics", 12713 "dd" 12714 ], 12715 "skinnable": true 12716 }, 12717 "aui-diagram-node": { 12718 "requires": [ 12719 "aui-aria", 12720 "aui-diagram-node-manager-base", 12721 "escape", 12722 "overlay" 12723 ] 12724 }, 12725 "aui-diagram-node-condition": { 12726 "requires": [ 12727 "aui-diagram-node-state" 12728 ] 12729 }, 12730 "aui-diagram-node-end": { 12731 "requires": [ 12732 "aui-diagram-node-state" 12733 ] 12734 }, 12735 "aui-diagram-node-fork": { 12736 "requires": [ 12737 "aui-diagram-node-state" 12738 ] 12739 }, 12740 "aui-diagram-node-join": { 12741 "requires": [ 12742 "aui-diagram-node-state" 12743 ] 12744 }, 12745 "aui-diagram-node-manager-base": { 12746 "requires": [ 12747 "base" 12748 ] 12749 }, 12750 "aui-diagram-node-start": { 12751 "requires": [ 12752 "aui-diagram-node-state" 12753 ] 12754 }, 12755 "aui-diagram-node-state": { 12756 "requires": [ 12757 "aui-diagram-node" 12758 ] 12759 }, 12760 "aui-diagram-node-task": { 12761 "requires": [ 12762 "aui-diagram-node-state" 12763 ] 12764 }, 12765 "aui-dialog-iframe-deprecated": { 12766 "requires": [ 12767 "plugin", 12768 "array-invoke", 12769 "aui-base-deprecated", 12770 "aui-loading-mask-deprecated" 12771 ], 12772 "skinnable": true 12773 }, 12774 "aui-dropdown": { 12775 "requires": [ 12776 "event-delegate", 12777 "event-key", 12778 "event-outside", 12779 "node-focusmanager", 12780 "widget", 12781 "widget-stack", 12782 "aui-classnamemanager", 12783 "aui-node", 12784 "aui-widget-cssclass", 12785 "aui-widget-toggle", 12786 "aui-widget-trigger" 12787 ], 12788 "skinnable": true 12789 }, 12790 "aui-editable-deprecated": { 12791 "requires": [ 12792 "aui-base-deprecated", 12793 "aui-form-combobox-deprecated", 12794 "escape", 12795 "event-resize" 12796 ], 12797 "skinnable": true 12798 }, 12799 "aui-event": { 12800 "use": [ 12801 "aui-event-base" 12802 ] 12803 }, 12804 "aui-event-base": { 12805 "requires": [ 12806 "event-base" 12807 ] 12808 }, 12809 "aui-event-delegate-change": { 12810 "condition": { 12811 "name": "aui-event-delegate-change", 12812 "trigger": "event-base-ie", 12813 "ua": "ie" 12814 }, 12815 "requires": [ 12816 "aui-event-base", 12817 "event-delegate", 12818 "event-synthetic" 12819 ] 12820 }, 12821 "aui-event-delegate-submit": { 12822 "condition": { 12823 "name": "aui-event-delegate-submit", 12824 "trigger": "event-base-ie", 12825 "ua": "ie" 12826 }, 12827 "requires": [ 12828 "aui-event-base", 12829 "event-delegate", 12830 "event-synthetic" 12831 ] 12832 }, 12833 "aui-event-input": { 12834 "condition": { 12835 "name": "aui-event-input", 12836 "test": function(A) { 12837 var supportsDOMEvent = A.supportsDOMEvent, 12838 testFeature = A.Features.test, 12839 addFeature = A.Features.add; 12840 12841 if (testFeature('event', 'input') === undefined) { 12842 addFeature('event', 'input', { 12843 test: function() { 12844 return supportsDOMEvent(document.createElement('textarea'), 'input') && (!A.UA.ie || A.UA.ie > 9); 12845 } 12846 }); 12847 } 12848 12849 return !testFeature('event', 'input'); 12850}, 12851 "trigger": "aui-event-base" 12852 }, 12853 "requires": [ 12854 "aui-event-base", 12855 "event-delegate", 12856 "event-synthetic", 12857 "timers" 12858 ] 12859 }, 12860 "aui-form-base-deprecated": { 12861 "requires": [ 12862 "io-form", 12863 "querystring-parse", 12864 "aui-base-deprecated", 12865 "aui-data-set-deprecated", 12866 "aui-form-field-deprecated" 12867 ] 12868 }, 12869 "aui-form-builder": { 12870 "requires": [ 12871 "aui-modal", 12872 "aui-layout",
12873 "aui-form-builder-field-list", 12874 "aui-form-builder-field-toolbar", 12875 "aui-form-builder-field-type", 12876 "aui-form-builder-field-types", 12877 "aui-form-builder-layout-builder", 12878 "aui-form-builder-page-manager", 12879 "aui-form-builder-settings-modal", 12880 "event-focus", 12881 "event-tap" 12882 ], 12883 "skinnable": true 12884 }, 12885 "aui-form-builder-available-field-deprecated": { 12886 "requires": [ 12887 "aui-property-builder-available-field" 12888 ] 12889 }, 12890 "aui-form-builder-deprecated": { 12891 "requires": [ 12892 "aui-button", 12893 "aui-collection", 12894 "aui-form-builder-available-field-deprecated", 12895 "aui-form-builder-field-deprecated", 12896 "aui-form-builder-field-button-deprecated", 12897 "aui-form-builder-field-checkbox-deprecated", 12898 "aui-form-builder-field-fieldset-deprecated", 12899 "aui-form-builder-field-file-upload-deprecated", 12900 "aui-form-builder-field-multiple-choice-deprecated", 12901 "aui-form-builder-field-radio-deprecated", 12902 "aui-form-builder-field-select-deprecated", 12903 "aui-form-builder-field-text-deprecated", 12904 "aui-form-builder-field-textarea-deprecated", 12905 "aui-property-builder", 12906 "aui-property-builder-settings", 12907 "aui-sortable-list", 12908 "aui-tabview", 12909 "aui-tooltip-base", 12910 "escape", 12911 "transition" 12912 ], 12913 "skinnable": true 12914 }, 12915 "aui-form-builder-field-base": { 12916 "requires": [ 12917 "aui-classnamemanager", 12918 "aui-node-base", 12919 "aui-text-data-editor", 12920 "aui-toggler", 12921 "base", 12922 "node-base" 12923 ], 12924 "skinnable": true 12925 }, 12926 "aui-form-builder-field-button-deprecated": { 12927 "requires": [ 12928 "aui-form-builder-field-deprecated" 12929 ] 12930 }, 12931 "aui-form-builder-field-checkbox-deprecated": { 12932 "requires": [ 12933 "aui-form-builder-field-deprecated" 12934 ] 12935 }, 12936 "aui-form-builder-field-choice": { 12937 "requires": [ 12938 "aui-boolean-data-editor", 12939 "aui-options-data-editor", 12940 "aui-tabs-data-editor", 12941 "aui-form-builder-field-base", 12942 "aui-form-field-choice" 12943 ] 12944 }, 12945 "aui-form-builder-field-deprecated": { 12946 "requires": [ 12947 "panel", 12948 "aui-datatype", 12949 "aui-datatable-edit", 12950 "aui-property-builder-field-support" 12951 ], 12952 "skinnable": true 12953 }, 12954 "aui-form-builder-field-fieldset-deprecated": { 12955 "requires": [ 12956 "aui-form-builder-field-deprecated" 12957 ] 12958 }, 12959 "aui-form-builder-field-file-upload-deprecated": { 12960 "requires": [ 12961 "aui-form-builder-field-deprecated" 12962 ] 12963 }, 12964 "aui-form-builder-field-list": { 12965 "requires": [ 12966 "aui-form-builder-field-type", 12967 "aui-form-builder-field-types", 12968 "aui-form-builder-layout-builder" 12969 ], 12970 "skinnable": true 12971 }, 12972 "aui-form-builder-field-multiple-choice-deprecated": { 12973 "requires": [ 12974 "aui-form-builder-field-deprecated" 12975 ] 12976 }, 12977 "aui-form-builder-field-radio-deprecated": { 12978 "requires": [ 12979 "aui-form-builder-field-deprecated" 12980 ] 12981 }, 12982 "aui-form-builder-field-select-deprecated": { 12983 "requires": [ 12984 "aui-form-builder-field-deprecated" 12985 ] 12986 }, 12987 "aui-form-builder-field-sentence": { 12988 "requires": [ 12989 "aui-form-builder-field-base", 12990 "aui-form-field" 12991 ] 12992 }, 12993 "aui-form-builder-field-text": { 12994 "requires": [ 12995 "aui-boolean-data-editor", 12996 "aui-radio-group-data-editor", 12997 "aui-form-builder-field-base", 12998 "aui-form-field-text" 12999 ] 13000 }, 13001 "aui-form-builder-field-text-deprecated": { 13002 "requires": [ 13003 "aui-form-builder-field-deprecated" 13004 ] 13005 },
13006 "aui-form-builder-field-textarea-deprecated": { 13007 "requires": [ 13008 "aui-form-builder-field-deprecated" 13009 ] 13010 }, 13011 "aui-form-builder-field-toolbar": { 13012 "requires": [ 13013 "aui-classnamemanager", 13014 "base", 13015 "node-base" 13016 ], 13017 "skinnable": true 13018 }, 13019 "aui-form-builder-field-type": { 13020 "requires": [ 13021 "base", 13022 "node-base" 13023 ], 13024 "skinnable": true 13025 }, 13026 "aui-form-builder-field-types": { 13027 "requires": [ 13028 "aui-classnamemanager", 13029 "aui-form-builder-field-types-modal", 13030 "base", 13031 "node-base" 13032 ], 13033 "skinnable": true 13034 }, 13035 "aui-form-builder-field-types-modal": { 13036 "requires": [ 13037 "aui-modal" 13038 ], 13039 "skinnable": true 13040 }, 13041 "aui-form-builder-layout-builder": { 13042 "requires": [ 13043 "aui-classnamemanager", 13044 "aui-layout-builder", 13045 "aui-modal", 13046 "base", 13047 "node-base" 13048 ], 13049 "skinnable": true 13050 }, 13051 "aui-form-builder-page-manager": { 13052 "requires": [ 13053 "aui-pagination", 13054 "aui-popover", 13055 "aui-tabview", 13056 "base", 13057 "event-valuechange", 13058 "node-base" 13059 ], 13060 "skinnable": true 13061 }, 13062 "aui-form-builder-settings-modal": { 13063 "requires": [ 13064 "aui-classnamemanager", 13065 "aui-modal", 13066 "base", 13067 "node-base" 13068 ], 13069 "skinnable": true 13070 }, 13071 "aui-form-combobox-deprecated": { 13072 "requires": [ 13073 "aui-form-textarea-deprecated", 13074 "aui-toolbar" 13075 ], 13076 "skinnable": true 13077 }, 13078 "aui-form-deprecated": { 13079 "use": [ 13080 "aui-form-base-deprecated", 13081 "aui-form-combobox-deprecated", 13082 "aui-form-field-deprecated", 13083 "aui-form-select-deprecated", 13084 "aui-form-textarea-deprecated", 13085 "aui-form-textfield-deprecated" 13086 ] 13087 }, 13088 "aui-form-field": { 13089 "requires": [ 13090 "aui-classnamemanager", 13091 "aui-node-base", 13092 "base-build" 13093 ], 13094 "skinnable": true 13095 }, 13096 "aui-form-field-choice": { 13097 "requires": [ 13098 "aui-form-field-required" 13099 ], 13100 "skinnable": true 13101 }, 13102 "aui-form-field-deprecated": { 13103 "requires": [ 13104 "aui-base-deprecated", 13105 "aui-component" 13106 ] 13107 }, 13108 "aui-form-field-required": { 13109 "requires": [ 13110 "aui-form-field" 13111 ] 13112 }, 13113 "aui-form-field-text": { 13114 "requires": [ 13115 "aui-form-field-required" 13116 ], 13117 "skinnable": true 13118 }, 13119 "aui-form-select-deprecated": { 13120 "requires": [ 13121 "aui-form-field-deprecated" 13122 ] 13123 }, 13124 "aui-form-textarea-deprecated": { 13125 "requires": [ 13126 "node-pluginhost", 13127 "aui-autosize-deprecated", 13128 "aui-form-textfield-deprecated" 13129 ] 13130 }, 13131 "aui-form-textfield-deprecated": { 13132 "requires": [ 13133 "aui-form-field-deprecated" 13134 ] 13135 }, 13136 "aui-form-validator": { 13137 "requires": [ 13138 "escape", 13139 "selector-css3", 13140 "node-event-delegate", 13141 "aui-node", 13142 "aui-component", 13143 "aui-event-input" 13144 ] 13145 }, 13146 "aui-hsv-palette": { 13147 "requires": [ 13148 "aui-classnamemanager", 13149 "aui-widget-cssclass", 13150 "aui-widget-toggle", 13151 "aui-event-input", 13152 "base-build", 13153 "clickable-rail", 13154 "color-hsv", 13155 "dd-constrain", 13156 "slider", 13157 "widget" 13158 ], 13159 "skinnable": true 13160 }, 13161 "aui-hsva-palette": { 13162 "requires": [ 13163 "aui-hsv-palette" 13164 ], 13165 "skinnable": true 13166 }, 13167 "aui-hsva-palette-modal": { 13168 "requires": [ 13169 "aui-hsva-palette", 13170 "aui-modal" 13171 ], 13172 "skinnable": true 13173 }, 13174 "aui-image-cropper": { 13175 "requires": [ 13176 "resize-base", 13177 "resize-constrain", 13178 "dd-constrain", 13179 "aui-node-base", 13180 "aui-component" 13181 ], 13182 "skinnable": true 13183 }, 13184 "aui-image-viewer": { 13185 "requires": [ 13186 "widget", 13187 "widget-modality", 13188 "widget-position", 13189 "widget-position-align", 13190 "widget-position-constrain", 13191 "widget-stack", 13192 "widget-stdmod", 13193 "aui-event", 13194 "aui-image-viewer-base", 13195 "aui-image-viewer-multiple", 13196 "aui-image-viewer-slideshow", 13197 "aui-node-base", 13198 "aui-widget-cssclass", 13199 "aui-widget-toggle" 13200 ], 13201 "skinnable": true 13202 }, 13203 "aui-image-viewer-base": { 13204 "requires": [ 13205 "anim", 13206 "aui-aria", 13207 "aui-classnamemanager", 13208 "aui-node", 13209 "aui-widget-responsive", 13210 "base-build", 13211 "imageloader", 13212 "node-base", 13213 "widget", 13214 "widget-stack" 13215 ], 13216 "skinnable": true 13217 }, 13218 "aui-image-viewer-media": { 13219 "requires": [ 13220 "plugin", 13221 "aui-component", 13222 "aui-image-viewer" 13223 ] 13224 }, 13225 "aui-image-viewer-multiple": { 13226 "requires": [ 13227 "base-build", 13228 "node-base", 13229 "aui-classnamemanager", 13230 "aui-image-viewer-base" 13231 ], 13232 "skinnable": true 13233 }, 13234 "aui-image-viewer-multiple-swipe": { 13235 "condition": { 13236 "name": "aui-image-viewer-multiple-swipe", 13237 "trigger": "aui-image-viewer-multiple", 13238 "ua": "touchEnabled" 13239 }, 13240 "requires": [ 13241 "aui-image-viewer-multiple",
13242 "aui-image-viewer-swipe" 13243 ] 13244 }, 13245 "aui-image-viewer-slideshow": { 13246 "requires": [ 13247 "node", 13248 "aui-classnamemanager" 13249 ] 13250 }, 13251 "aui-image-viewer-swipe": { 13252 "condition": { 13253 "name": "aui-image-viewer-swipe", 13254 "trigger": "aui-image-viewer-base", 13255 "ua": "touchEnabled" 13256 }, 13257 "requires": [ 13258 "event-resize", 13259 "aui-image-viewer-base", 13260 "aui-widget-swipe" 13261 ] 13262 }, 13263 "aui-input-text-control-deprecated": { 13264 "requires": [ 13265 "aui-base-deprecated", 13266 "aui-datasource-control-base-deprecated", 13267 "aui-form-combobox-deprecated" 13268 ] 13269 }, 13270 "aui-io": { 13271 "use": [ 13272 "aui-io-request" 13273 ] 13274 }, 13275 "aui-io-deprecated": { 13276 "use": [ 13277 "aui-io-request", 13278 "aui-io-plugin-deprecated" 13279 ] 13280 }, 13281 "aui-io-plugin-deprecated": { 13282 "requires": [ 13283 "aui-overlay-base-deprecated", 13284 "aui-parse-content", 13285 "aui-io-request", 13286 "aui-loading-mask-deprecated" 13287 ] 13288 }, 13289 "aui-io-request": { 13290 "requires": [ 13291 "io-base", 13292 "json", 13293 "plugin", 13294 "querystring-stringify", 13295 "aui-component" 13296 ] 13297 }, 13298 "aui-io-request-deprecated": { 13299 "requires": [ 13300 "io-base", 13301 "json", 13302 "plugin", 13303 "querystring-stringify", 13304 "aui-base-deprecated" 13305 ] 13306 }, 13307 "aui-layout": { 13308 "requires": [ 13309 "aui-layout-col", 13310 "aui-layout-row", 13311 "aui-node-base", 13312 "base-build", 13313 "datatype-number-parse", 13314 "event-resize" 13315 ] 13316 }, 13317 "aui-layout-builder": { 13318 "requires": [ 13319 "aui-classnamemanager", 13320 "aui-layout", 13321 "aui-layout-builder-add-col", 13322 "aui-layout-builder-add-row", 13323 "aui-layout-builder-move", 13324 "aui-layout-builder-remove-row", 13325 "aui-layout-builder-resize-col", 13326 "aui-node-base", 13327 "base-build", 13328 "node-event-delegate", 13329 "node-screen", 13330 "node-style" 13331 ] 13332 }, 13333 "aui-layout-builder-add-col": { 13334 "requires": [ 13335 "event-key", 13336 "node-base" 13337 ], 13338 "skinnable": true 13339 }, 13340 "aui-layout-builder-add-row": { 13341 "requires": [ 13342 "aui-node-base", 13343 "base-build", 13344 "node-scroll-info" 13345 ], 13346 "skinnable": true 13347 }, 13348 "aui-layout-builder-move": { 13349 "requires": [ 13350 "aui-node-base", 13351 "base-build" 13352 ], 13353 "skinnable": true 13354 }, 13355 "aui-layout-builder-remove-row": { 13356 "requires": [ 13357 "aui-node-base", 13358 "base-build" 13359 ], 13360 "skinnable": true 13361 }, 13362 "aui-layout-builder-resize-col": { 13363 "requires": [ 13364 "dd-constrain", 13365 "dd-delegate", 13366 "dd-drop-plugin", 13367 "dd-proxy", 13368 "event-mouseenter", 13369 "node-base" 13370 ], 13371 "skinnable": true 13372 }, 13373 "aui-layout-col": { 13374 "requires": [ 13375 "aui-classnamemanager", 13376 "aui-node-base", 13377 "base-build" 13378 ], 13379 "skinnable": true 13380 }, 13381 "aui-layout-row": { 13382 "requires": [ 13383 "array-invoke", 13384 "aui-node-base", 13385 "base-build" 13386 ], 13387 "skinnable": true 13388 }, 13389 "aui-linkedset": { 13390 "requires": [ 13391 "aui-set" 13392 ] 13393 }, 13394 "aui-live-search-deprecated": { 13395 "requires": [ 13396 "aui-base-deprecated" 13397 ] 13398 }, 13399 "aui-loading-mask-deprecated": { 13400 "requires": [ 13401 "plugin", 13402 "aui-overlay-mask-deprecated" 13403 ], 13404 "skinnable": true 13405 }, 13406 "aui-map": { 13407 "requires": [ 13408 "base-build" 13409 ] 13410 }, 13411 "aui-menu": { 13412 "requires": [ 13413 "base-build", 13414 "event-mouseenter", 13415 "event-resize", 13416 "widget", 13417 "widget-position", 13418 "widget-position-align", 13419 "widget-position-constrain", 13420 "widget-stack", 13421 "aui-classnamemanager", 13422 "aui-debounce", 13423 "aui-dropdown", 13424 "aui-menu-item" 13425 ], 13426 "skinnable": true 13427 }, 13428 "aui-menu-item": { 13429 "requires": [ 13430 "base-build", 13431 "node-base", 13432 "aui-classnamemanager", 13433 "aui-node", 13434 "aui-widget-shortcut" 13435 ] 13436 }, 13437 "aui-messaging": { 13438 "requires": [ 13439 "querystring", 13440 "aui-timer" 13441 ] 13442 }, 13443 "aui-modal": { 13444 "requires": [ 13445 "widget", 13446 "widget-autohide", 13447 "widget-buttons", 13448 "widget-modality", 13449 "widget-position", 13450 "widget-position-align", 13451 "widget-position-constrain", 13452 "widget-stack", 13453 "widget-stdmod", 13454 "dd-plugin", 13455 "dd-constrain", 13456 "timers", 13457 "aui-classnamemanager", 13458 "aui-widget-cssclass", 13459 "aui-widget-toggle", 13460 "aui-widget-toolbars" 13461 ], 13462 "skinnable": true 13463 }, 13464 "aui-modal-resize": { 13465 "condition": { 13466 "name": "aui-modal-resize", 13467 "test": function(A) { 13468 return !A.UA.mobile; 13469}, 13470 "trigger": "aui-modal" 13471 }, 13472 "requires": [ 13473 "aui-modal", 13474 "resize-plugin" 13475 ] 13476 }, 13477 "aui-node": { 13478 "use": [ 13479 "aui-node-base" 13480 ] 13481 }, 13482 "aui-node-accessible": { 13483 "requires": [ 13484 "aui-node-base", 13485 "event-custom-base" 13486 ] 13487 }, 13488 "aui-node-base": { 13489 "requires": [ 13490 "array-extras", 13491 "aui-base-lang", 13492 "aui-classnamemanager", 13493 "aui-debounce", 13494 "node" 13495 ] 13496 }, 13497 "aui-node-html5": { 13498 "condition": { 13499 "name": "aui-node-html5", 13500 "trigger": "aui-node", 13501 "ua": "ie" 13502 }, 13503 "requires": [ 13504 "collection", 13505 "aui-node-base" 13506 ] 13507 }, 13508 "aui-options-data-editor": { 13509 "requires": [ 13510 "aui-data-editor", 13511 "dd-constrain", 13512 "dd-delegate", 13513 "dd-drop-plugin", 13514 "dd-proxy", 13515 "event-valuechange", 13516 "node-event-delegate" 13517 ], 13518 "skinnable": true 13519 }, 13520 "aui-overlay-base-deprecated": { 13521 "requires": [ 13522 "widget-position", 13523 "widget-stack", 13524 "widget-position-align", 13525 "widget-position-constrain", 13526 "widget-stdmod", 13527 "aui-component" 13528 ] 13529 }, 13530 "aui-overlay-context-deprecated": { 13531 "requires": [ 13532 "aui-overlay-manager-deprecated", 13533 "aui-delayed-task-deprecated", 13534 "aui-aria" 13535 ] 13536 }, 13537 "aui-overlay-context-panel-deprecated": { 13538 "requires": [ 13539 "anim", 13540 "aui-overlay-context-deprecated" 13541 ], 13542 "skinnable": true 13543 }, 13544 "aui-overlay-deprecated": { 13545 "use": [ 13546 "aui-overlay-base-deprecated", 13547 "aui-overlay-context-deprecated", 13548 "aui-overlay-context-panel-deprecated", 13549 "aui-overlay-manager-deprecated", 13550 "aui-overlay-mask-deprecated" 13551 ] 13552 }, 13553 "aui-overlay-manager-deprecated": { 13554 "requires": [ 13555 "overlay", 13556 "plugin", 13557 "aui-base-deprecated", 13558 "aui-overlay-base-deprecated" 13559 ] 13560 }, 13561 "aui-overlay-mask-deprecated": { 13562 "requires": [ 13563 "event-resize", 13564 "aui-base-deprecated", 13565 "aui-overlay-base-deprecated" 13566 ], 13567 "skinnable": true 13568 }, 13569 "aui-pagination": { 13570 "requires": [ 13571 "node-event-delegate", 13572 "aui-node", 13573 "aui-component", 13574 "widget-htmlparser" 13575 ], 13576 "skinnable": true 13577 }, 13578 "aui-palette": { 13579 "requires": [ 13580 "base-build", 13581 "event-hover", 13582 "widget", 13583 "aui-classnamemanager", 13584 "aui-base", 13585 "aui-widget-cssclass", 13586 "aui-widget-toggle" 13587 ], 13588 "skinnable": true 13589 }, 13590 "aui-parse-content": { 13591 "requires": [ 13592 "async-queue", 13593 "plugin", 13594 "io-base", 13595 "aui-component", 13596 "aui-node-base" 13597 ] 13598 }, 13599 "aui-popover": { 13600 "requires": [ 13601 "event-resize", 13602 "widget", 13603 "widget-autohide", 13604 "widget-buttons", 13605 "widget-modality", 13606 "widget-position", 13607 "widget-position-align", 13608 "widget-position-constrain", 13609 "widget-stack", 13610 "widget-stdmod", 13611 "aui-classnamemanager", 13612 "aui-widget-cssclass", 13613 "aui-widget-toggle", 13614 "aui-widget-toolbars", 13615 "aui-widget-transition", 13616 "aui-widget-trigger", 13617 "aui-widget-position-align-suggestion", 13618 "aui-component", 13619 "aui-node-base" 13620 ], 13621 "skinnable": true 13622 }, 13623 "aui-progressbar": { 13624 "requires": [ 13625 "aui-node", 13626 "aui-component", 13627 "aui-aria" 13628 ], 13629 "skinnable": true 13630 }, 13631 "aui-promise": { 13632 "requires": [ 13633 "array-invoke", 13634 "promise", 13635 "oop" 13636 ] 13637 }, 13638 "aui-property-builder": { 13639 "requires": [ 13640 "dd", 13641 "collection", 13642 "aui-property-builder-available-field", 13643 "aui-property-builder-field-support", 13644 "aui-property-builder-settings", 13645 "aui-tabview" 13646 ], 13647 "skinnable": true 13648 }, 13649 "aui-property-builder-available-field": { 13650 "requires": [ 13651 "base", 13652 "aui-component", 13653 "aui-node" 13654 ] 13655 }, 13656 "aui-property-builder-field-support": {}, 13657 "aui-property-builder-settings": { 13658 "requires": [ 13659 "aui-tabview", 13660 "aui-datatable-property-list" 13661 ] 13662 }, 13663 "aui-radio-group-data-editor": { 13664 "requires": [ 13665 "aui-data-editor", 13666 "node-event-delegate" 13667 ], 13668 "skinnable": true 13669 }, 13670 "aui-rating": { 13671 "use": [ 13672 "aui-rating-base", 13673 "aui-rating-thumb" 13674 ] 13675 }, 13676 "aui-rating-base": { 13677 "requires": [ 13678 "aui-component", 13679 "aui-node-base", 13680 "widget-htmlparser", 13681 "widget-uievents" 13682 ], 13683 "skinnable": true 13684 }, 13685 "aui-rating-thumb": { 13686 "requires": [ 13687 "aui-rating-base" 13688 ] 13689 }, 13690 "aui-resize-base-deprecated": { 13691 "requires": [ 13692 "dd-drag", 13693 "dd-delegate", 13694 "dd-drop", 13695 "aui-base-deprecated" 13696 ], 13697 "skinnable": true 13698 }, 13699 "aui-resize-constrain-deprecated": { 13700 "requires": [ 13701 "dd-constrain", 13702 "plugin", 13703 "aui-resize-base-deprecated" 13704 ] 13705 }, 13706 "aui-resize-deprecated": { 13707 "skinnable": true, 13708 "use": [ 13709 "aui-resize-base-deprecated", 13710 "aui-resize-constrain-deprecated" 13711 ] 13712 }, 13713 "aui-scale-data-editor": { 13714 "requires": [ 13715 "aui-classnamemanager", 13716 "aui-data-editor", 13717 "event-valuechange" 13718 ] 13719 }, 13720 "aui-scheduler": { 13721 "use": [ 13722 "event-gestures", 13723 "aui-scheduler-base", 13724 "aui-scheduler-event-recorder", 13725 "aui-scheduler-view-agenda", 13726 "aui-scheduler-view-day", 13727 "aui-scheduler-view-month", 13728 "aui-scheduler-view-table-dd", 13729 "aui-scheduler-view-table", 13730 "aui-scheduler-view-week", 13731 "aui-viewport" 13732 ] 13733 }, 13734 "aui-scheduler-base": { 13735 "requires": [ 13736 "model", 13737 "model-list", 13738 "widget-stdmod", 13739 "color-hsl", 13740 "aui-event-base", 13741 "aui-node-base", 13742 "aui-component", 13743 "aui-datatype", 13744 "aui-button", 13745 "node-focusmanager" 13746 ], 13747 "skinnable": true 13748 }, 13749 "aui-scheduler-event-recorder": { 13750 "requires": [ 13751 "querystring", 13752 "io-form", 13753 "overlay", 13754 "aui-scheduler-base", 13755 "aui-popover" 13756 ], 13757 "skinnable": true 13758 }, 13759 "aui-scheduler-touch": { 13760 "condition": { 13761 "name": "aui-scheduler-touch", 13762 "trigger": "aui-scheduler", 13763 "ua": "touchEnabled" 13764 }, 13765 "requires": [ 13766 "base-build", 13767 "aui-scheduler" 13768 ], 13769 "skinnable": true 13770 }, 13771 "aui-scheduler-view-agenda": { 13772 "requires": [ 13773 "aui-scheduler-base" 13774 ], 13775 "skinnable": true 13776 }, 13777 "aui-scheduler-view-day": { 13778 "requires": [ 13779 "dd-drag", 13780 "dd-delegate", 13781 "dd-drop", 13782 "dd-constrain", 13783 "aui-scheduler-view-table" 13784 ], 13785 "skinnable": true 13786 }, 13787 "aui-scheduler-view-month": { 13788 "requires": [ 13789 "aui-scheduler-view-table" 13790 ], 13791 "skinnable": true 13792 }, 13793 "aui-scheduler-view-table": { 13794 "requires": [ 13795 "overlay", 13796 "aui-scheduler-base" 13797 ], 13798 "skinnable": true 13799 }, 13800 "aui-scheduler-view-table-dd": { 13801 "requires": [ 13802 "dd-drag", 13803 "dd-delegate", 13804 "dd-drop", 13805 "aui-scheduler-view-table" 13806 ] 13807 }, 13808 "aui-scheduler-view-week": { 13809 "requires": [ 13810 "aui-scheduler-view-day" 13811 ], 13812 "skinnable": true 13813 }, 13814 "aui-scroller-deprecated": { 13815 "requires": [ 13816 "event-mouseenter", 13817 "aui-base-deprecated", 13818 "aui-simple-anim-deprecated" 13819 ], 13820 "skinnable": true 13821 }, 13822 "aui-scrollspy": { 13823 "requires": [ 13824 "base-build", 13825 "node-screen", 13826 "aui-classnamemanager" 13827 ] 13828 }, 13829 "aui-search": { 13830 "use": [ 13831 "aui-search-tst" 13832 ] 13833 }, 13834 "aui-search-tst": { 13835 "requires": [ 13836 "aui-component" 13837 ] 13838 }, 13839 "aui-selector": { 13840 "requires": [ 13841 "selector-css3", 13842 "aui-classnamemanager" 13843 ] 13844 }, 13845 "aui-set": { 13846 "requires": [ 13847 "aui-map" 13848 ] 13849 }, 13850 "aui-simple-anim-deprecated": { 13851 "requires": [ 13852 "aui-base-deprecated" 13853 ] 13854 }, 13855 "aui-skin-deprecated": { 13856 "type": "css" 13857 }, 13858 "aui-sortable": { 13859 "use": [ 13860 "aui-sortable-layout", 13861 "aui-sortable-list" 13862 ] 13863 }, 13864 "aui-sortable-layout": { 13865 "requires": [ 13866 "dd-delegate", 13867 "dd-drag", 13868 "dd-drop", 13869 "dd-proxy", 13870 "aui-node", 13871 "aui-component" 13872 ], 13873 "skinnable": true 13874 }, 13875 "aui-sortable-list": { 13876 "requires": [ 13877 "dd-drag", 13878 "dd-drop", 13879 "dd-proxy", 13880 "dd-scroll", 13881 "aui-node", 13882 "aui-component" 13883 ] 13884 }, 13885 "aui-state-interaction-deprecated": { 13886 "requires": [ 13887 "aui-base-deprecated", 13888 "plugin" 13889 ] 13890 }, 13891 "aui-surface": { 13892 "use": [ 13893 "aui-surface-app", 13894 "aui-surface-screen" 13895 ] 13896 }, 13897 "aui-surface-app": { 13898 "requires": [ 13899 "event-delegate", 13900 "node-event-html5", 13901 "aui-surface-base", 13902 "aui-surface-screen", 13903 "aui-surface-screen-route" 13904 ] 13905 }, 13906 "aui-surface-base": { 13907 "requires": [ 13908 "base-build", 13909 "node-style", 13910 "timers", 13911 "aui-debounce", 13912 "aui-promise", 13913 "aui-parse-content" 13914 ] 13915 }, 13916 "aui-surface-screen": { 13917 "requires": [ 13918 "base-build" 13919 ] 13920 }, 13921 "aui-surface-screen-html": { 13922 "requires": [ 13923 "aui-base", 13924 "aui-io-request", 13925 "aui-promise", 13926
13926 "aui-surface-screen", 13927 "aui-url" 13928 ] 13929 }, 13930 "aui-surface-screen-route": { 13931 "requires": [ 13932 "base-build" 13933 ] 13934 }, 13935 "aui-swf-deprecated": { 13936 "requires": [ 13937 "querystring-parse-simple", 13938 "querystring-stringify-simple", 13939 "aui-base-deprecated" 13940 ] 13941 }, 13942 "aui-tabs-data-editor": { 13943 "requires": [ 13944 "aui-data-editor", 13945 "aui-tabview" 13946 ] 13947 }, 13948 "aui-tabview": { 13949 "requires": [ 13950 "selector-css3", 13951 "tabview", 13952 "aui-component", 13953 "aui-widget-css" 13954 ], 13955 "skinnable": true 13956 }, 13957 "aui-template-deprecated": { 13958 "requires": [ 13959 "aui-base-deprecated" 13960 ] 13961 }, 13962 "aui-text-data-editor": { 13963 "requires": [ 13964 "aui-data-editor", 13965 "event-valuechange" 13966 ], 13967 "skinnable": true 13968 }, 13969 "aui-text-data-unicode": { 13970 "requires": [ 13971 "text" 13972 ] 13973 }, 13974 "aui-text-unicode": { 13975 "requires": [ 13976 "aui-text-data-unicode" 13977 ] 13978 }, 13979 "aui-textboxlist-deprecated": { 13980 "requires": [ 13981 "anim-node-plugin", 13982 "aui-autocomplete-deprecated", 13983 "aui-button-item-deprecated", 13984 "aui-data-set-deprecated", 13985 "escape", 13986 "node-focusmanager" 13987 ], 13988 "skinnable": true 13989 }, 13990 "aui-timepicker": { 13991 "requires": [ 13992 "autocomplete", 13993 "aui-datepicker-delegate", 13994 "aui-datepicker-popover" 13995 ], 13996 "skinnable": true 13997 }, 13998 "aui-timepicker-native": { 13999 "requires": [ 14000 "base", 14001 "base-build", 14002 "aui-node-base", 14003 "aui-datepicker-delegate", 14004 "aui-datepicker-native" 14005 ] 14006 }, 14007 "aui-timer": { 14008 "requires": [ 14009 "oop" 14010 ] 14011 }, 14012 "aui-toggler": { 14013 "use": [ 14014 "aui-toggler-base", 14015 "aui-toggler-delegate" 14016 ] 14017 }, 14018 "aui-toggler-accessibility": { 14019 "requires": [ 14020 "aui-toggler-base" 14021 ] 14022 }, 14023 "aui-toggler-base": { 14024 "requires": [ 14025 "transition", 14026 "aui-selector", 14027 "aui-event-base", 14028 "aui-node", 14029 "aui-component", 14030 "event-tap" 14031 ], 14032 "skinnable": true 14033 }, 14034 "aui-toggler-delegate": { 14035 "requires": [ 14036 "array-invoke", 14037 "node-event-delegate", 14038 "aui-toggler-base" 14039 ] 14040 }, 14041 "aui-toolbar": { 14042 "requires": [ 14043 "arraylist", 14044 "arraylist-add", 14045 "aui-component", 14046 "aui-button-core" 14047 ] 14048 }, 14049 "aui-tooltip": { 14050 "use": [ 14051 "aui-tooltip-base", 14052 "aui-tooltip-delegate" 14053 ] 14054 }, 14055 "aui-tooltip-base": { 14056 "requires": [ 14057 "aui-aria", 14058 "aui-classnamemanager", 14059 "aui-component", 14060 "aui-debounce", 14061 "aui-node-base", 14062 "aui-widget-cssclass", 14063 "aui-widget-toggle", 14064 "aui-widget-transition", 14065 "aui-widget-trigger", 14066 "aui-widget-position-align-suggestion", 14067 "event-hover", 14068 "event-resize", 14069 "escape", 14070 "widget", 14071 "widget-autohide", 14072 "widget-position", 14073 "widget-position-align", 14074 "widget-position-constrain", 14075 "widget-stack", 14076 "widget-stdmod" 14077 ], 14078 "skinnable": true 14079 }, 14080 "aui-tooltip-delegate": { 14081 "requires": [ 14082 "aui-tooltip-base", 14083 "node-event-delegate" 14084 ] 14085 }, 14086 "aui-tooltip-deprecated": { 14087 "requires": [ 14088 "aui-overlay-context-panel-deprecated" 14089 ], 14090 "skinnable": true 14091 }, 14092 "aui-tpl-snippets-base-deprecated": { 14093 "requires": [ 14094 "aui-template-deprecated" 14095 ] 14096 }, 14097 "aui-tpl-snippets-checkbox-deprecated": { 14098 "requires": [ 14099 "aui-tpl-snippets-base-deprecated" 14100 ] 14101 }, 14102 "aui-tpl-snippets-deprecated": { 14103 "use": [ 14104 "aui-tpl-snippets-base-deprecated", 14105 "aui-tpl-snippets-checkbox-deprecated", 14106 "aui-tpl-snippets-input-deprecated", 14107 "aui-tpl-snippets-select-deprecated", 14108 "aui-tpl-snippets-textarea-deprecated" 14109 ] 14110 }, 14111 "aui-tpl-snippets-input-deprecated": { 14112 "requires": [ 14113 "aui-tpl-snippets-base-deprecated" 14114 ] 14115 }, 14116 "aui-tpl-snippets-select-deprecated": { 14117 "requires": [ 14118 "aui-tpl-snippets-base-deprecated" 14119 ] 14120 }, 14121 "aui-tpl-snippets-textarea-deprecated": { 14122 "requires": [ 14123 "aui-tpl-snippets-base-deprecated" 14124 ] 14125 }, 14126 "aui-tree": { 14127 "use": [ 14128 "aui-tree-data", 14129 "aui-tree-io", 14130 "aui-tree-node", 14131 "aui-tree-paginator", 14132 "aui-tree-view" 14133 ] 14134 }, 14135 "aui-tree-data": { 14136 "requires": [ 14137 "aui-base-core", 14138 "aui-base-lang", 14139 "aui-node-base", 14140 "aui-timer", 14141 "aui-component" 14142 ] 14143 }, 14144 "aui-tree-io": { 14145 "requires": [ 14146 "aui-component", 14147 "aui-io" 14148 ] 14149 }, 14150 "aui-tree-node": { 14151 "requires": [ 14152 "json", 14153 "querystring-stringify", 14154 "aui-tree-data", 14155 "aui-tree-io", 14156 "aui-tree-paginator", 14157 "event-key" 14158 ] 14159 }, 14160 "aui-tree-paginator": { 14161 "requires": [ 14162 "yui-base" 14163 ] 14164 }, 14165 "aui-tree-view": { 14166 "requires": [ 14167 "dd-delegate", 14168 "dd-proxy", 14169 "widget", 14170 "aui-tree-node", 14171 "aui-tree-paginator", 14172 "aui-tree-io" 14173 ], 14174 "skinnable": true 14175 }, 14176 "aui-undo-redo": { 14177 "requires": [ 14178 "aui-base", 14179 "base", 14180 "base-build", 14181 "event-key", 14182 "promise" 14183 ] 14184 }, 14185 "aui-url": { 14186 "requires": [ 14187 "oop", 14188 "querystring-parse", 14189 "querystring-stringify" 14190 ] 14191 }, 14192 "aui-video": { 14193 "requires": [ 14194 "event-resize", 14195 "node-event-html5", 14196 "querystring-stringify-simple", 14197 "aui-aria", 14198 "aui-node", 14199 "aui-component", 14200 "aui-debounce" 14201 ], 14202 "skinnable": true 14203 }, 14204 "aui-viewport": { 14205 "requires": [ 14206 "aui-node", 14207 "aui-component" 14208 ] 14209 }, 14210 "aui-widget": { 14211 "use": [ 14212 "aui-widget-cssclass", 14213 "aui-widget-toolbars" 14214 ] 14215 }, 14216 "aui-widget-core": { 14217 "use": [ 14218 "aui-widget-cssclass" 14219 ] 14220 }, 14221 "aui-widget-cssclass": { 14222 "requires": [ 14223 "widget-base" 14224 ] 14225 }, 14226 "aui-widget-position-align-suggestion": { 14227 "requires": [ 14228 "widget-position-align", 14229 "widget-stdmod" 14230 ] 14231 }, 14232 "aui-widget-responsive": { 14233 "requires": [ 14234 "event-resize", 14235 "widget-base" 14236 ] 14237 }, 14238 "aui-widget-shortcut": { 14239 "requires": [ 14240 "base" 14241 ] 14242 }, 14243 "aui-widget-swipe": { 14244 "requires": [ 14245 "classnamemanager", 14246 "scrollview-base", 14247 "scrollview-paginator", 14248 "timers" 14249 ] 14250 }, 14251 "aui-widget-toggle": {}, 14252 "aui-widget-toolbars": { 14253 "requires": [ 14254 "widget-stdmod", 14255 "aui-toolbar" 14256 ] 14257 }, 14258 "aui-widget-transition": { 14259 "requires": [ 14260 "transition" 14261 ] 14262 }, 14263 "aui-widget-trigger": { 14264 "requires": [ 14265 "node" 14266 ] 14267 } 14268}); 14269YUI.Env[Y.version].md5 = 'd7c627eb00edd6b6f054d8f6e7147480'; 14270/* 14271 * Alloy JavaScript Library 14272 * http://alloy.liferay.com/ 14273 * 14274 * Copyright (c) 2010 Liferay Inc. 14275 * http://alloy.liferay.com/LICENSE.txt 14276 * 14277 * Nate Cavanaugh ([email protected]) 14278 * Eduardo Lundgren ([email protected]) 14279 * 14280 * Attribution/Third-party licenses 14281 * http://alloy.liferay.com/ATTRIBUTION.txt 14282 */ 14283 14284// Simple version of 14285// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ 14286 14287A.UA.edge = (function() { 14288 var edgeVersion = A.UA.userAgent.match(/Edge\/(.[0-9.]+)/); 14289 14290 if (edgeVersion) { 14291 return edgeVersion[1]; 14292 } 14293 14294 return 0; 14295})(); 14296 14297A.supportsDOMEvent = function(domNode, eventName) { 14298 eventName = 'on' + eventName; 14299 14300 if (!(eventName in domNode)) { 14301 if (!domNode.setAttribute) { 14302 domNode = A.config.doc.createElement('div'); 14303 } 14304 14305 if (domNode.setAttribute) { 14306 domNode.setAttribute(eventName, ''); 14307 return (typeof domNode[eventName] === 'function'); 14308 } 14309 } 14310 14311 domNode = null; 14312 14313 return true; 14314}; 14315(function() { 14316 var slice = Array.prototype.slice; 14317 14318 YUI.prototype.ready = function() { 14319 var instance = this, 14320 xargs = arguments, 14321 index = xargs.length - 1, 14322 modules = slice.call(arguments, 0, index); 14323 14324 modules.unshift('event-base'); 14325 modules.push(function(instance) { 14326 var args = arguments; 14327 14328 instance.on('domready', function() { 14329 xargs[index].apply(this, args); 14330 }); 14331 }); 14332 instance.use.apply(instance, modules); 14333 }; 14334}()); 14335 14336 14337}, '3.1.0-deprecated.70'); 14338YUI.add('aui', function (A, NAME) {}, '3.1.0-deprecated.70'); 14339YUI.Env.core.push.apply(YUI.Env.core, ["aui-base-core"]); 14340YUI.add('aui-base-html5-shiv', function (A, NAME) { 14341 14342A.HTML5_ELEMENTS = [ 14343 'abbr', 14344 'article', 14345 'aside', 14346 'audio', 14347 'canvas', 14348 'command', 14349 'datalist', 14350 'details', 14351 'figure', 14352 'figcaption', 14353 'footer', 14354 'header', 14355 'hgroup', 14356 'keygen', 14357 'mark', 14358 'meter',
14359 'nav', 14360 'output', 14361 'progress', 14362 'section', 14363 'source', 14364 'summary', 14365 'time', 14366 'video' 14367]; 14368 14369A.html5shiv = function(frag) { 14370 var DOC = frag || A.config.doc; 14371 14372 if (A.UA.ie && DOC && DOC.createElement) { 14373 var elements = A.HTML5_ELEMENTS, 14374 length = elements.length; 14375 14376 while (length--) { 14377 DOC.createElement(elements[length]); 14378 } 14379 } 14380 14381 return frag; 14382}; 14383 14384 14385}, '3.1.0-deprecated.70'); 14386 14387function _typeof(obj) { 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); } 14388 14389/** 14390 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 14391 * 14392 * This library is free software; you can redistribute it and/or modify it under 14393 * the terms of the GNU Lesser General Public License as published by the Free 14394 * Software Foundation; either version 2.1 of the License, or (at your option) 14395 * any later version. 14396 * 14397 * This library is distributed in the hope that it will be useful, but WITHOUT 14398 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14399 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14400 * details. 14401 */ 14402YUI.add('liferay-browser-selectors', function (A) { 14403 var REGEX_VERSION_DOT = /\./g; 14404 var YUI3_JS_ENABLED = 'yui3-js-enabled'; 14405 14406 var parseVersionNumber = function parseVersionNumber(str) { 14407 var count = 0; 14408 return parseFloat(str.replace(REGEX_VERSION_DOT, function () { 14409 return count++ == 1 ? '' : '.'; 14410 })); 14411 }; 14412 14413 var DEFAULTS_VERSION = ['0', '0']; 14414 14415 var getVersion = function getVersion(regex, userAgent) { 14416 var version = (userAgent.match(regex) || DEFAULTS_VERSION)[1]; 14417 return parseVersionNumber(version); 14418 }; 14419 14420 var BROWSERS = ['ie', 'opera', 'chrome', 'edge', 'aol', 'camino', 'firefox', 'flock', 'mozilla', 'netscape', 'icab', 'konqueror', 'safari']; 14421 var MAP_OS_SELECTORS = { 14422 macintosh: 'mac', 14423 windows: 'win' 14424 }; 14425 var nav = navigator; 14426 var CONFIG = A.config; 14427 var DOC = CONFIG.doc; 14428 var userAgent = nav.userAgent; 14429 var UA = A.UA; 14430 var OS = UA.os; 14431 var UAX = { 14432 agent: userAgent, 14433 aol: 0, 14434 browser: 0, 14435 camino: 0, 14436 firefox: 0, 14437 flock: 0, 14438 icab: 0, 14439 konqueror: 0, 14440 mozilla: 0, 14441 netscape: 0, 14442 safari: 0 14443 }; 14444 UAX.mac = OS == 'macintosh'; 14445 UAX.rhino = OS == 'rhino'; 14446 UAX.win = OS == 'windows'; 14447 var BrowserSelectors = { 14448 getSelectors: function getSelectors() { 14449 // The methods in this if block only run once across all instances 14450 if (!UA.selectors) { 14451 if (userAgent.indexOf('Edge') !== -1) { 14452 UAX.edge = getVersion(/Edge\/([^\s]*)/, userAgent); 14453 } 14454 14455 if (UA.ie) { 14456 UAX.aol = getVersion(/America Online Browser ([^\s]*);/, userAgent); 14457 var docMode = DOC.documentMode; 14458 14459 if (docMode) { 14460 UA.browser = UA.ie; 14461 UA.ie = docMode; 14462 } 14463 } else if (UA.gecko) { 14464 UAX.netscape = getVersion(/(Netscape|Navigator)\/([^\s]*)/, userAgent); 14465 UAX.flock = getVersion(/Flock\/([^\s]*)/, userAgent); 14466 UAX.camino = getVersion(/Camino\/([^\s]*)/, userAgent); 14467 UAX.firefox = getVersion(/Firefox\/([^\s]*)/, userAgent); 14468 } else if (UA.webkit) { 14469 UAX.safari = getVersion(/Version\/([^\s]*) Safari/, userAgent); 14470 } else { 14471 UAX.icab = getVersion(/iCab(?:\/|\s)?([^\s]*)/, userAgent); 14472 UAX.konqueror = getVersion(/Konqueror\/([^\s]*)/, userAgent); 14473 } 14474 14475 if (!UAX.win && !UAX.mac) { 14476 var linux = /Linux/.test(userAgent); 14477 var sun = /Solaris|SunOS/.test(userAgent); 14478 14479 if (linux) { 14480 UA.os = 'linux'; 14481 UAX.linux = linux; 14482 } else if (sun) { 14483 UA.os = 'sun'; 14484 UAX.sun = sun; 14485 } 14486 } 14487 14488 var touch = UA.touchEnabled; 14489 UAX.touch = touch; 14490 UAX.touchMobile = touch && !!UA.mobile; 14491 A.mix(UA, UAX); 14492 var browserList = []; 14493 var versionMajor = 0; 14494 var browser; 14495 var uaVersionMajor; 14496 var uaVersionMinor; 14497 var version; 14498 var versionObj = { 14499 major: versionMajor,
14500 string: '' 14501 }; 14502 var i = BROWSERS.length; 14503 14504 while (i--) { 14505 browser = BROWSERS[i]; 14506 version = UA[browser]; 14507 14508 if (version > 0) { 14509 versionMajor = parseInt(version, 10); 14510 uaVersionMajor = browser + versionMajor; 14511 uaVersionMinor = browser + version; 14512 14513 if (String(version).indexOf('.') > -1) { 14514 uaVersionMinor = uaVersionMinor.replace(/\.(\d).*/, '-$1'); 14515 } else { 14516 uaVersionMinor += '-0'; 14517 } 14518 14519 browserList.push(browser, uaVersionMajor, uaVersionMinor); 14520 versionObj.string = browser + ''; 14521 versionObj.major = versionMajor; 14522 } 14523 } 14524 14525 UA.version = versionObj; 14526 UA.renderer = ''; 14527 14528 if (UA.ie) { 14529 UA.renderer = 'trident'; 14530 } else if (UA.edge) { 14531 UA.renderer = 'edgeHTML'; 14532 } else if (UA.gecko) { 14533 UA.renderer = 'gecko'; 14534 } else if (UA.webkit) { 14535 UA.renderer = 'webkit'; 14536 } else if (UA.opera) { 14537 UA.renderer = 'presto'; 14538 } 14539 14540 A.UA = UA; 14541 /* 14542 * Browser selectors 14543 */ 14544 14545 var selectors = [UA.renderer, 'js'].concat(browserList); 14546 var osSelector = MAP_OS_SELECTORS[UA.os] || UA.os; 14547 selectors.push(osSelector); 14548 14549 if (UA.mobile) { 14550 selectors.push('mobile'); 14551 } 14552 14553 if (UA.secure) { 14554 selectors.push('secure'); 14555 } 14556 14557 if (UA.touch) { 14558 selectors.push('touch'); 14559 } 14560 14561 UA.selectors = selectors.join(' '); 14562 var svg; 14563 var vml; 14564 vml = !(svg = !!(CONFIG.win.SVGAngle || DOC.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1'))); 14565 14566 if (vml) { 14567 var behaviorObj; 14568 var div = DOC.createElement('div'); 14569 div.innerHTML = '<v:shape adj="1"/>'; 14570 behaviorObj = div.firstChild; 14571 behaviorObj.style.behavior = 'url(#default#VML)'; 14572 14573 if (!(behaviorObj && _typeof(behaviorObj.adj) == 'object')) { 14574 vml = false; 14575 } 14576 14577 div = null; 14578 } 14579 14580 YUI._VML = vml; 14581 YUI._SVG = svg; 14582 UA.vml = YUI._VML; 14583 UA.svg = YUI._SVG; 14584 } 14585 14586 return UA.selectors; 14587 }, 14588 run: function run() { 14589 var documentElement = DOC.documentElement; 14590 var selectors = this.getSelectors(); 14591 UA.dir = documentElement.getAttribute('dir') || 'ltr'; 14592 14593 if (documentElement.className.indexOf(UA.dir) === -1) { 14594 selectors += ' ' + UA.dir; 14595 } 14596 14597 if (documentElement.className.indexOf(YUI3_JS_ENABLED) === -1 && selectors.indexOf(YUI3_JS_ENABLED) === -1) { 14598 selectors += ' ' + YUI3_JS_ENABLED; 14599 } 14600 14601 documentElement.className += ' ' + selectors; 14602 } 14603 }; 14604 Liferay.BrowserSelectors = BrowserSelectors; 14605}, '', { 14606 requires: ['yui-base'] 14607}); 14608//# sourceMappingURL=browser_selectors.js.map 14609/** 14610 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 14611 * 14612 * This library is free software; you can redistribute it and/or modify it under 14613 * the terms of the GNU Lesser General Public License as published by the Free 14614 * Software Foundation; either version 2.1 of the License, or (at your option) 14615 * any later version. 14616 * 14617 * This library is distributed in the hope that it will be useful, but WITHOUT 14618 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14619 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14620 * details. 14621 */ 14622(function () { 14623 var LiferayAUI = Liferay.AUI; 14624 var COMBINE = LiferayAUI.getCombine(); 14625 var CORE_MODULES = YUI.Env.core; 14626 var INPUT_EL = document.createElement('input'); 14627 var PATH_EDITOR_CKEDITOR = LiferayAUI.getEditorCKEditorPath(); 14628 var PATH_JAVASCRIPT = LiferayAUI.getJavaScriptRootPath(); 14629 var SUPPORTS_INPUT_SELECTION = typeof INPUT_EL.selectionStart === 'number' && typeof INPUT_EL.selectionEnd === 'number'; 14630 14631 var testHistory = function testHistory(A) { 14632 var WIN = A.config.win; 14633 var HISTORY = WIN.history; 14634 return HISTORY && HISTORY.pushState && HISTORY.replaceState && ('onpopstate' in WIN || A.UA.gecko >= 2); 14635 }; 14636 14637 window.YUI_config = { 14638 base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/aui/', 14639 combine: COMBINE, 14640 comboBase: LiferayAUI.getComboPath(), 14641 filter: Liferay.AUI.getFilter(), 14642 groups: { 14643 editor: { 14644 base: PATH_EDITOR_CKEDITOR, 14645 combine: COMBINE, 14646 modules: { 14647 'inline-editor-ckeditor': { 14648 path: 'ckeditor/main.js' 14649 } 14650 }, 14651 root: PATH_EDITOR_CKEDITOR 14652 }, 14653 liferay: { 14654 base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/liferay/', 14655 combine: COMBINE, 14656 filter: Liferay.AUI.getFilterConfig(), 14657 modules: { 14658 'liferay-address': { 14659 path: 'address.js', 14660 requires: [] 14661 }, 14662 'liferay-alert': { 14663 path: 'alert.js', 14664 requires: ['aui-alert', 'aui-component', 'event-mouseenter', 'liferay-portlet-base', 'timers'] 14665 }, 14666 'liferay-asset-addon-entry-selector': { 14667 path: 'asset_addon_entry_selector.js', 14668 requires: ['aui-component', 'liferay-portlet-base', 'liferay-util-window'] 14669 }, 14670 'liferay-asset-categories-selector': { 14671 path: 'asset_categories_selector.js', 14672 requires: ['aui-tree', 'liferay-asset-tags-selector'] 14673 }, 14674 'liferay-asset-tags-selector': { 14675 path: 'asset_tags_selector.js',
14676 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'] 14677 }, 14678 'liferay-auto-fields': { 14679 path: 'auto_fields.js', 14680 requires: ['aui-base', 'aui-data-set-deprecated', 'aui-parse-content', 'base', 'liferay-undo-manager', 'sortable'] 14681 }, 14682 'liferay-autocomplete-input': { 14683 path: 'autocomplete_input.js', 14684 requires: ['aui-base', 'autocomplete', 'autocomplete-filters', 'autocomplete-highlighters'] 14685 }, 14686 'liferay-autocomplete-input-caretindex': { 14687 condition: { 14688 name: 'liferay-autocomplete-input-caretindex', 14689 test: function test() { 14690 return SUPPORTS_INPUT_SELECTION; 14691 }, 14692 trigger: 'liferay-autocomplete-textarea' 14693 }, 14694 path: 'autocomplete_input_caretindex.js', 14695 requires: ['liferay-autocomplete-textarea'] 14696 }, 14697 'liferay-autocomplete-input-caretindex-sel': { 14698 condition: { 14699 name: 'liferay-autocomplete-input-caretindex-sel', 14700 test: function test() { 14701 return !SUPPORTS_INPUT_SELECTION; 14702 }, 14703 trigger: 'liferay-autocomplete-textarea' 14704 }, 14705 path: 'autocomplete_input_caretindex_sel.js', 14706 requires: ['liferay-autocomplete-textarea'] 14707 }, 14708 'liferay-autocomplete-input-caretoffset': { 14709 condition: { 14710 name: 'liferay-autocomplete-input-caretoffset', 14711 test: function test(A) { 14712 return !(A.UA.ie && A.UA.ie < 9); 14713 }, 14714 trigger: 'liferay-autocomplete-textarea' 14715 }, 14716 path: 'autocomplete_input_caretoffset.js', 14717 requires: ['liferay-autocomplete-textarea'] 14718 }, 14719 'liferay-autocomplete-input-caretoffset-sel': { 14720 condition: { 14721 name: 'liferay-autocomplete-input-caretoffset-sel', 14722 test: function test(A) { 14723 return A.UA.ie && A.UA.ie < 9; 14724 }, 14725 trigger: 'liferay-autocomplete-textarea' 14726 }, 14727 path: 'autocomplete_input_caretoffset_sel.js', 14728 requires: ['liferay-autocomplete-textarea'] 14729 }, 14730 'liferay-autocomplete-textarea': { 14731 path: 'autocomplete_textarea.js', 14732 requires: ['liferay-autocomplete-input'] 14733 }, 14734 'liferay-browser-selectors': { 14735 path: 'browser_selectors.js', 14736 requires: ['yui-base'] 14737 }, 14738 'liferay-cover-cropper': { 14739 path: 'cover_cropper.js', 14740 requires: ['aui-base', 'dd-constrain', 'dd-drag', 'plugin'] 14741 }, 14742 'liferay-crop-region': { 14743 path: 'crop_region.js', 14744 requires: ['aui-base'] 14745 }, 14746 'liferay-dd-proxy': { 14747 path: 'dd_proxy.js', 14748 requires: ['dd-proxy'] 14749 }, 14750 'liferay-dynamic-select': {
14751 path: 'dynamic_select.js', 14752 requires: ['aui-base'] 14753 }, 14754 'liferay-form': { 14755 path: 'form.js', 14756 requires: ['aui-base', 'aui-form-validator'] 14757 }, 14758 'liferay-form-placeholders': { 14759 condition: { 14760 name: 'liferay-form-placeholders', 14761 test: function test() { 14762 return !('placeholder' in INPUT_EL); 14763 }, 14764 trigger: 'liferay-form' 14765 }, 14766 path: 'form_placeholders.js', 14767 requires: ['liferay-form', 'plugin'] 14768 }, 14769 'liferay-fullscreen-source-editor': { 14770 path: 'fullscreen_source_editor.js', 14771 requires: ['liferay-source-editor'] 14772 }, 14773 'liferay-history': { 14774 path: 'history.js', 14775 requires: ['history-hash', 'querystring-parse-simple'] 14776 }, 14777 'liferay-history-html5': { 14778 condition: { 14779 name: 'liferay-history-html5', 14780 test: testHistory, 14781 trigger: 'liferay-history' 14782 }, 14783 path: 'history_html5.js', 14784 requires: ['history-html5', 'liferay-history', 'querystring-stringify-simple'] 14785 }, 14786 'liferay-history-manager': { 14787 path: 'history_manager.js', 14788 requires: ['liferay-history'] 14789 }, 14790 'liferay-hudcrumbs': { 14791 path: 'hudcrumbs.js', 14792 requires: ['aui-base', 'aui-debounce', 'event-resize'] 14793 }, 14794 'liferay-icon': { 14795 path: 'icon.js', 14796 requires: ['aui-base'] 14797 }, 14798 'liferay-inline-editor-base': { 14799 path: 'inline_editor_base.js', 14800 requires: ['aui-base', 'aui-overlay-base-deprecated'] 14801 }, 14802 'liferay-input-localized': { 14803 path: 'input_localized.js', 14804 requires: ['aui-base', 'aui-component', 'aui-event-input', 'aui-palette', 'aui-set', 'portal-available-languages'] 14805 }, 14806 'liferay-input-move-boxes': { 14807 path: 'input_move_boxes.js', 14808 plugins: { 14809 'liferay-input-move-boxes-touch': { 14810 condition: { 14811 name: 'liferay-input-move-boxes-touch', 14812 trigger: 'liferay-input-move-boxes', 14813 ua: 'touchMobile' 14814 } 14815 } 14816 }, 14817 requires: ['aui-base', 'aui-toolbar'] 14818 }, 14819 'liferay-input-move-boxes-touch': { 14820 path: 'input_move_boxes_touch.js', 14821 requires: ['aui-base', 'aui-template-deprecated', 'liferay-input-move-boxes', 'sortable'] 14822 }, 14823 'liferay-item-selector-dialog': { 14824 path: 'item_selector_dialog.js', 14825 requires: ['aui-component'] 14826 }, 14827 'liferay-item-selector-repository-entry-browser': { 14828 path: 'item_selector_repository_entry_browser.js', 14829 requires: ['liferay-item-selector-uploader', 'liferay-item-viewer', 'liferay-notice', 'liferay-portlet-base'] 14830 }, 14831 'liferay-item-selector-uploader': { 14832 path: 'item_selector_uploader.js', 14833 requires: ['aui-base', 'aui-progressbar', 'liferay-portlet-base', 'uploader'] 14834 }, 14835 'liferay-item-selector-url': { 14836 path: 'item_selector_url.js', 14837 requires: ['aui-event-input', 'liferay-item-viewer', 'liferay-portlet-base'] 14838 }, 14839 'liferay-item-viewer': { 14840 path: 'item_viewer.js', 14841 requires: ['aui-component', 'aui-image-viewer', 'liferay-portlet-url'] 14842 }, 14843 'liferay-language': { 14844 path: 'language.js' 14845 }, 14846 'liferay-layout': { 14847 path: 'layout.js' 14848 }, 14849 'liferay-layout-column': { 14850 path: 'layout_column.js', 14851 requires: ['aui-sortable-layout', 'dd'] 14852 }, 14853 'liferay-list-view': { 14854 path: 'list_view.js', 14855 requires: ['aui-base', 'transition'] 14856 }, 14857 'liferay-logo-editor': { 14858 path: 'logo_editor.js', 14859 requires: ['aui-image-cropper', 'liferay-alert', 'liferay-portlet-base'] 14860 }, 14861 'liferay-logo-selector': { 14862 path: 'logo_selector.js', 14863 requires: ['aui-base'] 14864 }, 14865 'liferay-menu': { 14866 path: 'menu.js', 14867 requires: ['aui-debounce', 'aui-node'] 14868 }, 14869 'liferay-menu-filter': { 14870 path: 'menu_filter.js', 14871 requires: ['autocomplete-base', 'autocomplete-filters', 'autocomplete-highlighters'] 14872 }, 14873 'liferay-menu-toggle': { 14874 path: 'menu_toggle.js', 14875 requires: ['aui-node', 'event-outside', 'event-tap', 'liferay-menu-filter'] 14876 }, 14877 'liferay-message': { 14878 path: 'message.js', 14879 requires: ['aui-base'] 14880 }, 14881 'liferay-navigation': { 14882 path: 'navigation.js', 14883 requires: ['aui-component', 'event-mouseenter'] 14884 }, 14885 'liferay-navigation-interaction': { 14886 path: 'navigation_interaction.js', 14887 plugins: { 14888 'liferay-navigation-interaction-touch': { 14889 condition: { 14890 name: 'liferay-navigation-interaction-touch', 14891 trigger: 'liferay-navigation-interaction', 14892 ua: 'touch' 14893 } 14894 } 14895 }, 14896 requires: ['aui-base', 'aui-component', 'event-mouseenter', 'node-focusmanager', 'plugin'] 14897 }, 14898 'liferay-navigation-interaction-touch': { 14899 path: 'navigation_interaction_touch.js', 14900 requires: ['event-tap', 'event-touch', 'liferay-navigation-interaction'] 14901 },
14902 'liferay-node': { 14903 path: 'node.js', 14904 requires: ['dom-base'] 14905 }, 14906 'liferay-notice': { 14907 path: 'notice.js', 14908 requires: ['aui-base', 'transition'] 14909 }, 14910 'liferay-notification': { 14911 path: 'notification.js', 14912 requires: ['liferay-alert'] 14913 }, 14914 'liferay-pagination': { 14915 path: 'pagination.js', 14916 requires: ['aui-pagination'] 14917 }, 14918 'liferay-panel-search': { 14919 path: 'panel_search.js', 14920 requires: ['aui-base', 'liferay-search-filter'] 14921 }, 14922 'liferay-poller': { 14923 path: 'poller.js', 14924 requires: ['aui-base', 'json'] 14925 }, 14926 'liferay-portlet-base': { 14927 path: 'portlet_base.js', 14928 requires: ['aui-base'] 14929 }, 14930 'liferay-portlet-url': { 14931 path: 'portlet_url.js', 14932 requires: ['aui-base'] 14933 }, 14934 'liferay-preview': { 14935 path: 'preview.js', 14936 requires: ['aui-base', 'aui-overlay-mask-deprecated', 'aui-toolbar', 'liferay-widget-zindex'] 14937 }, 14938 'liferay-progress': { 14939 path: 'progress.js', 14940 requires: ['aui-progressbar'] 14941 }, 14942 'liferay-ratings': { 14943 path: 'ratings.js', 14944 requires: ['aui-rating'] 14945 }, 14946 'liferay-resize-rtl': { 14947 condition: { 14948 test: function test() { 14949 return document.documentElement.dir === 'rtl'; 14950 }, 14951 trigger: 'resize-base' 14952 }, 14953 path: 'resize_rtl.js' 14954 }, 14955 'liferay-restore-entry': { 14956 path: 'restore_entry.js', 14957 requires: ['aui-io-plugin-deprecated', 'aui-modal', 'liferay-portlet-base'] 14958 }, 14959 'liferay-search-container': { 14960 path: 'search_container.js', 14961 requires: ['aui-base', 'aui-datatable-core'] 14962 }, 14963 'liferay-search-container-move': { 14964 path: 'search_container_move.js', 14965 requires: ['aui-component', 'dd-constrain', 'dd-delegate', 'dd-drag', 'dd-drop', 'dd-proxy', 'plugin'] 14966 }, 14967 'liferay-search-container-select': { 14968 path: 'search_container_select.js', 14969 requires: ['aui-component', 'aui-url', 'plugin'] 14970 }, 14971 'liferay-search-filter': { 14972 path: 'search_filter.js', 14973 requires: ['aui-base', 'autocomplete-base', 'autocomplete-filters'] 14974 }, 14975 'liferay-service-datasource': { 14976 path: 'service_datasource.js', 14977 requires: ['aui-base', 'datasource-local'] 14978 }, 14979 'liferay-session': { 14980 path: 'session.js', 14981 requires: ['aui-timer', 'cookie', 'liferay-notification'] 14982 }, 14983 'liferay-sign-in-modal': { 14984 path: 'sign_in_modal.js', 14985 requires: ['aui-base', 'aui-component', 'aui-parse-content', 'liferay-form', 'liferay-portlet-url', 'liferay-util-window', 'plugin'] 14986 }, 14987 'liferay-social-bookmarks': { 14988 path: 'social_bookmarks.js', 14989 requires: ['aui-component', 'aui-node'] 14990 }, 14991 'liferay-sortable': { 14992 path: 'sortable.js', 14993 requires: ['liferay-dd-proxy', 'sortable'] 14994 }, 14995 'liferay-source-editor': { 14996 path: 'source_editor.js', 14997 requires: ['aui-ace-editor'] 14998 }, 14999 'liferay-storage-formatter': { 15000 path: 'storage_formatter.js', 15001 requires: ['aui-base', 'datatype-number-format'] 15002 }, 15003 'liferay-store': { 15004 path: 'store.js' 15005 }, 15006 'liferay-toggler-interaction': { 15007 path: 'toggler_interaction.js', 15008 requires: ['liferay-toggler-key-filter'] 15009 }, 15010 'liferay-toggler-key-filter': { 15011 path: 'toggler_key_filter.js', 15012 requires: ['aui-event-base'] 15013 }, 15014 'liferay-token-list': { 15015 path: 'token_list.js', 15016 requires: ['aui-base', 'aui-template-deprecated'] 15017 }, 15018 'liferay-translation-manager': { 15019 path: 'translation_manager.js', 15020 requires: ['aui-base'] 15021 }, 15022 'liferay-undo-manager': { 15023 path: 'undo_manager.js', 15024 requires: ['aui-data-set-deprecated', 'base'] 15025 }, 15026 'liferay-upload': { 15027 path: 'upload.js', 15028 requires: ['aui-template-deprecated', 'collection', 'liferay-portlet-base', 'uploader'] 15029 }, 15030 'liferay-util-window': { 15031 path: 'util_window.js', 15032 requires: ['aui-dialog-iframe-deprecated', 'aui-modal', 'aui-url', 'event-resize', 'liferay-widget-zindex'] 15033 }, 15034 'liferay-widget-size-animation-plugin': { 15035 path: 'widget_size_animation_plugin.js', 15036 requires: ['anim-easing', 'plugin', 'widget'] 15037 }, 15038 'liferay-widget-zindex': { 15039 path: 'widget_zindex.js', 15040 requires: ['aui-modal', 'plugin'] 15041 }, 15042 'liferay-xml-formatter': { 15043 path: 'xml_formatter.js', 15044 requires: ['aui-base'] 15045 } 15046 }, 15047 root: PATH_JAVASCRIPT + '/liferay/' 15048 }, 15049 misc: { 15050 base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/misc/', 15051 combine: COMBINE, 15052 modules: { 15053 swfobject: { 15054 path: 'swfobject.js' 15055 }, 15056 swfupload: { 15057 path: 'swfupload/swfupload.js' 15058 } 15059 }, 15060 root: PATH_JAVASCRIPT + '/misc/' 15061 }, 15062 portal: { 15063 base: Liferay.ThemeDisplay.getCDNBaseURL() + PATH_JAVASCRIPT + '/liferay/', 15064 combine: false, 15065 modules: { 15066 'portal-available-languages': { 15067 path: LiferayAUI.getAvailableLangPath(), 15068 requires: ['liferay-language'] 15069 } 15070 }, 15071 root: PATH_JAVASCRIPT + '/liferay/' 15072 } 15073 }, 15074 insertBefore: 'liferayPortalCSS', 15075 lang: themeDisplay.getBCP47LanguageId(), 15076 root: PATH_JAVASCRIPT + '/aui/', 15077 useBrowserConsole: false 15078 }; 15079 CORE_MODULES.push('liferay-browser-selectors'); 15080})(); 15081//# sourceMappingURL=modules.js.map 15082/** 15083 * Copyright (c) 2000-present Liferay, Inc. All rights reserved. 15084 * 15085 * This library is free software; you can redistribute it and/or modify it under 15086 * the terms of the GNU Lesser General Public License as published by the Free 15087 * Software Foundation; either version 2.1 of the License, or (at your option) 15088 * any later version. 15089 * 15090 * This library is distributed in the hope that it will be useful, but WITHOUT 15091 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15092 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15093 * details. 15094 */ 15095(function () { 15096 var ALLOY = YUI(); 15097 15098 if (ALLOY.html5shiv) { 15099 ALLOY.html5shiv(); 15100 } 15101 15102 var originalUse = ALLOY.use; 15103 15104 ALLOY.use = function () { 15105 var args = Array.prototype.slice.call(arguments, 0); 15106 var currentURL = Liferay.currentURL; 15107 var originalCallback = args[args.length - 1]; 15108 15109 if (typeof originalCallback === 'function') { 15110 args[args.length - 1] = function () { 15111 if (Liferay.currentURL === currentURL) { 15112 originalCallback.apply(this, arguments); 15113 } 15114 }; 15115 } 15116 15117 return originalUse.apply(this, args); 15118 }; 15119 15120 window.AUI = function () { 15121 return ALLOY; 15122 }; 15123 15124 ALLOY.mix(AUI, YUI); 15125 AUI.$ = window.jQuery; 15126 AUI._ = window._; 15127})(); 15128//# sourceMappingURL=aui_sandbox.js.map 15129!function(root, factory) { 15130 false && "function" == typeof define && define.amd ? // AMD. Register as an anonymous module unless amdModuleId is set 15131 define([], function() { 15132 return root.svg4everybody = factory(); 15133 }) : "object" == typeof module && module.exports ? // Node. Does not work with strict CommonJS, but 15134 // only CommonJS-like environments that support module.exports, 15135 // like Node. 15136 module.exports = factory() : root.svg4everybody = factory(); 15137}(this, function() { 15138 /*! svg4everybody v2.1.9 | github.com/jonathantneal/svg4everybody */ 15139 function embed(parent, svg, target) { 15140 // if the target exists 15141 if (target) { 15142 // create a document fragment to hold the contents of the target 15143 var fragment = document.createDocumentFragment(), viewB
vendor: 6,434 bytes, lines 15143-15275
15143ox = !svg.hasAttribute("viewBox") && target.getAttribute("viewBox"); 15144 // conditionally set the viewBox on the svg 15145 viewBox && svg.setAttribute("viewBox", viewBox); 15146 // copy the contents of the clone into the fragment 15147 for (// clone the target 15148 var clone = target.cloneNode(!0); clone.childNodes.length; ) { 15149 fragment.appendChild(clone.firstChild); 15150 } 15151 // append the fragment into the svg 15152 parent.appendChild(fragment); 15153 } 15154 } 15155 function loadreadystatechange(xhr) { 15156 // listen to changes in the request 15157 xhr.onreadystatechange = function() { 15158 // if the request is ready 15159 if (4 === xhr.readyState) { 15160 // get the cached html document 15161 var cachedDocument = xhr._cachedDocument; 15162 // ensure the cached html document based on the xhr response 15163 cachedDocument || (cachedDocument = xhr._cachedDocument = document.implementation.createHTMLDocument(""), 15164 cachedDocument.body.innerHTML = xhr.responseText, xhr._cachedTarget = {}), // clear the xhr embeds list and embed each item 15165 xhr._embeds.splice(0).map(function(item) { 15166 // get the cached target 15167 var target = xhr._cachedTarget[item.id]; 15168 // ensure the cached target 15169 target || (target = xhr._cachedTarget[item.id] = cachedDocument.getElementById(item.id)), 15170 // embed the target into the svg 15171 embed(item.parent, item.svg, target); 15172 }); 15173 } 15174 }, // test the ready state change immediately 15175 xhr.onreadystatechange(); 15176 } 15177 function svg4everybody(rawopts) { 15178 function oninterval() { 15179 // while the index exists in the live <use> collection 15180 for (// get the cached <use> index 15181 var index = 0; index < uses.length; ) { 15182 // get the current <use> 15183 var use = uses[index], parent = use.parentNode, svg = getSVGAncestor(parent), src = use.getAttribute("xlink:href") || use.getAttribute("href"); 15184 if (!src && opts.attributeName && (src = use.getAttribute(opts.attributeName)), 15185 svg && src) { 15186 if (polyfill) { 15187 if (!opts.validate || opts.validate(src, svg, use)) { 15188 // remove the <use> element 15189 parent.removeChild(use); 15190 // parse the src and get the url and id 15191 var srcSplit = src.split("#"), url = srcSplit.shift(), id = srcSplit.join("#"); 15192 // if the link is external 15193 if (url.length) { 15194 // get the cached xhr request 15195 var xhr = requests[url]; 15196 // ensure the xhr request exists 15197 xhr || (xhr = requests[url] = new XMLHttpRequest(), xhr.open("GET", url), xhr.send(), 15198 xhr._embeds = []), // add the svg and id as an item to the xhr embeds list 15199 xhr._embeds.push({ 15200 parent: parent, 15201 svg: svg, 15202 id: id 15203 }), // prepare the xhr ready state change event 15204 loadreadystatechange(xhr); 15205 } else { 15206 // embed the local id into the svg 15207 embed(parent, svg, document.getElementById(id)); 15208 } 15209 } else { 15210 // increase the index when the previous value was not "valid" 15211 ++index, ++numberOfSvgUseElementsToBypass; 15212 } 15213 } 15214 } else { 15215 // increase the index when the previous value was not "valid" 15216 ++index; 15217 } 15218 } 15219 // continue the interval 15220 (!uses.length || uses.length - numberOfSvgUseElementsToBypass > 0) && requestAnimationFrame(oninterval, 67); 15221 } 15222 var polyfill, opts = Object(rawopts), newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/, webkitUA = /\bAppleWebKit\/(\d+)\b/, olderEdgeUA = /\bEdge\/12\.(\d+)\b/, edgeUA = /\bEdge\/.(\d+)\b/, inIframe = window.top !== window.self; 15223 polyfill = "polyfill" in opts ? opts.polyfill : newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe; 15224 // create xhr requests object 15225 var requests = {}, requestAnimationFrame = window.requestAnimationFrame || setTimeout, uses = document.getElementsByTagName("use"), numberOfSvgUseElementsToBypass = 0; 15226 // conditionally start the interval if the polyfill is active 15227 polyfill && oninterval(); 15228 } 15229 function getSVGAncestor(node) { 15230 for (var svg = node; "svg" !== svg.nodeName.toLowerCase() && (svg = svg.parentNode); ) {} 15231 return svg; 15232 } 15233 return svg4everybody; 15234}); 15235YUI.add('arraylist-add', function (Y, NAME) { 15236 15237/** 15238 * Collection utilities beyond what is provided in the YUI core 15239 * @module collection 15240 * @submodule arraylist-add 15241 * @deprecated Use ModelList or a custom ArrayList subclass 15242 */ 15243 15244/* 15245 * Adds methods add and remove to Y.ArrayList 15246 */ 15247Y.mix(Y.ArrayList.prototype, { 15248 15249 /** 15250 * Add a single item to the ArrayList. Does not prevent duplicates. 15251 * 15252 * @method add 15253 * @param { mixed } item Item presumably of the same type as others in the 15254 * ArrayList. 15255 * @param {Number} index (Optional.) Number representing the position at 15256 * which the item should be inserted. 15257 * @return {ArrayList} the instance. 15258 * @for ArrayList 15259 * @deprecated Use ModelList or a custom ArrayList subclass 15260 * @chainable 15261 */ 15262 add: function(item, index) { 15263 var items = this._items; 15264 15265 if (Y.Lang.isNumber(index)) { 15266 items.splice(index, 0, item); 15267 } 15268 else { 15269 items.push(item); 15270 } 15271 15272 return this; 15273 }, 15274 15275 /**
15276 * Removes first or all occurrences of an item to the ArrayList. If a 15277 * comparator is not provided, uses itemsAreEqual method to determine 15278 * matches. 15279 * 15280 * @method remove 15281 * @param { mixed } needle Item to find and remove from the list. 15282 * @param { Boolean } all If true, remove all occurrences. 15283 * @param { Function } comparator optional a/b function to test equivalence. 15284 * @return {ArrayList} the instance. 15285 * @for ArrayList 15286 * @deprecated Use ModelList or a custom ArrayList subclass 15287 * @chainable 15288 */ 15289 remove: function(needle, all, comparator) { 15290 comparator = comparator || this.itemsAreEqual; 15291 15292 for (var i = this._items.length - 1; i >= 0; --i) { 15293 if (comparator.call(this, needle, this.item(i))) { 15294 this._items.splice(i, 1); 15295 if (!all) { 15296 break; 15297 } 15298 } 15299 } 15300 15301 return this; 15302 }, 15303 15304 /** 15305 * Default comparator for items stored in this list. Used by remove(). 15306 * 15307 * @method itemsAreEqual 15308 * @param { mixed } a item to test equivalence with. 15309 * @param { mixed } b other item to test equivalance. 15310 * @return { Boolean } true if items are deemed equivalent. 15311 * @for ArrayList 15312 * @deprecated Use ModelList or a custom ArrayList subclass 15313 */ 15314 itemsAreEqual: function(a, b) { 15315 return a === b; 15316 } 15317 15318}); 15319 15320 15321}, 'patched-v3.18.1', {"requires": ["arraylist"]}); 15322 15323YUI.add('arraylist-filter', function (Y, NAME) { 15324 15325/** 15326 * Collection utilities beyond what is provided in the YUI core 15327 * @module collection 15328 * @submodule arraylist-filter 15329 * @deprecated Use ModelList or a custom subclass implementation 15330 */ 15331 15332/* 15333 * Adds filter method to ArrayList prototype 15334 */ 15335Y.mix(Y.ArrayList.prototype, { 15336 15337 /** 15338 * <p>Create a new ArrayList (or augmenting class instance) from a subset 15339 * of items as determined by the boolean function passed as the 15340 * argument. The original ArrayList is unchanged.</p> 15341 * 15342 * <p>The validator signature is <code>validator( item )</code>.</p> 15343 * 15344 * @method filter 15345 * @param { Function } validator Boolean function to determine in or out. 15346 * @return { ArrayList } New instance based on who passed the validator. 15347 * @for ArrayList 15348 * @deprecated Use ModelList or a custom subclass implementation 15349 */ 15350 filter: function(validator) { 15351 var items = []; 15352 15353 Y.Array.each(this._items, function(item, i) { 15354 item = this.item(i); 15355 15356 if (validator(item)) { 15357 items.push(item); 15358 } 15359 }, this); 15360 15361 return new this.constructor(items); 15362 } 15363 15364}); 15365 15366 15367}, 'patched-v3.18.1', {"requires": ["arraylist"]}); 15368 15369YUI.add('arraylist', function (Y, NAME) { 15370 15371/** 15372 * Collection utilities beyond what is provided in the YUI core 15373 * @module collection 15374 * @submodule arraylist 15375 */ 15376 15377var YArray = Y.Array, 15378 YArray_each = YArray.each, 15379 ArrayListProto; 15380 15381/** 15382 * Generic ArrayList class for managing lists of items and iterating operations 15383 * over them. The targeted use for this class is for augmentation onto a 15384 * class that is responsible for managing multiple instances of another class 15385 * (e.g. NodeList for Nodes). The recommended use is to augment your class with 15386 * ArrayList, then use ArrayList.addMethod to mirror the API of the constituent 15387 * items on the list's API. 15388 * 15389 * The default implementation creates immutable lists, but mutability can be 15390 * provided via the arraylist-add submodule or by implementing mutation methods 15391 * directly on the augmented class's prototype. 15392 * 15393 * @class ArrayList 15394 * @constructor 15395 * @param items { Array } array of items this list will be responsible for 15396 */ 15397function ArrayList( items ) { 15398 if ( items !== undefined ) { 15399 this._items = Y.Lang.isArray( items ) ? items : YArray( items ); 15400 } else { 15401 // ||= to support lazy initialization from augment 15402 this._items = this._items || []; 15403 } 15404} 15405 15406ArrayListProto = { 15407 /** 15408 * Get an item by index from the list. Override this method if managing a 15409 * list of objects that have a different public representation (e.g. Node 15410 * instances vs DOM nodes). The iteration methods that accept a user 15411 * function will use this method for access list items for operation. 15412 * 15413 * @method item 15414 * @param i { Integer } index to fetch 15415 * @return { mixed } the item at the requested index 15416 */ 15417 item: function ( i ) { 15418 return this._items[i]; 15419 }, 15420 15421 /** 15422 * <p>Execute a function on each item of the list, optionally providing a 15423 * custom execution context. Default context is the item.</p> 15424 * 15425 * <p>The callback signature is <code>callback( item, index )</code>.</p> 15426 * 15427 * @method each 15428 * @param fn { Function } the function to execute 15429 * @param context { mixed } optional override 'this' in the function 15430 * @return { ArrayList } this instance 15431 * @chainable 15432 */ 15433 each: function ( fn, context ) { 15434 YArray_each( this._items, function ( item, i ) { 15435 item = this.item( i ); 15436 15437 fn.call( context || item, item, i, this ); 15438 }, this); 15439 15440 return this; 15441 }, 15442 15443 /** 15444 * <p>Execute a function on each item of the list, optionally providing a 15445 * custom execution context. Default context is the item.</p> 15446 * 15447 * <p>The callback signature is <code>callback( item, index )</code>.</p> 15448 * 15449 * <p>Unlike <code>each</code>, if the callback returns true, the 15450 * iteration will stop.</p> 15451 * 15452 * @method some 15453 * @param fn { Function } the function to execute 15454 * @param context { mixed } optional override 'this' in the function 15455 * @return { Boolean } True if the function returned true on an item 15456 */ 15457 some: function ( fn, context ) { 15458 return YArray.some( this._items, function ( item, i ) { 15459 item = this.item( i ); 15460
15461 return fn.call( context || item, item, i, this ); 15462 }, this); 15463 }, 15464 15465 /** 15466 * Finds the first index of the needle in the managed array of items. 15467 * 15468 * @method indexOf 15469 * @param needle { mixed } The item to search for 15470 * @return { Integer } Array index if found. Otherwise -1 15471 */ 15472 indexOf: function ( needle ) { 15473 return YArray.indexOf( this._items, needle ); 15474 }, 15475 15476 /** 15477 * How many items are in this list? 15478 * 15479 * @method size 15480 * @return { Integer } Number of items in the list 15481 */ 15482 size: function () { 15483 return this._items.length; 15484 }, 15485 15486 /** 15487 * Is this instance managing any items? 15488 * 15489 * @method isEmpty 15490 * @return { Boolean } true if 1 or more items are being managed 15491 */ 15492 isEmpty: function () { 15493 return !this.size(); 15494 }, 15495 15496 /** 15497 * Provides an array-like representation for JSON.stringify. 15498 * 15499 * @method toJSON 15500 * @return { Array } an array representation of the ArrayList 15501 */ 15502 toJSON: function () { 15503 return this._items; 15504 } 15505}; 15506// Default implementation does not distinguish between public and private 15507// item getter 15508/** 15509 * Protected method for optimizations that may be appropriate for API 15510 * mirroring. Similar in functionality to <code>item</code>, but is used by 15511 * methods added with <code>ArrayList.addMethod()</code>. 15512 * 15513 * @method _item 15514 * @protected 15515 * @param i { Integer } Index of item to fetch 15516 * @return { mixed } The item appropriate for pass through API methods 15517 */ 15518ArrayListProto._item = ArrayListProto.item; 15519 15520// Mixed onto existing proto to preserve constructor NOT being an own property. 15521// This has bitten me when composing classes by enumerating, copying prototypes. 15522Y.mix(ArrayList.prototype, ArrayListProto); 15523 15524Y.mix( ArrayList, { 15525 15526 /** 15527 * <p>Adds a pass through method to dest (typically the prototype of a list 15528 * class) that calls the named method on each item in the list with 15529 * whatever parameters are passed in. Allows for API indirection via list 15530 * instances.</p> 15531 * 15532 * <p>Accepts a single string name or an array of string names.</p> 15533 * 15534 * <pre><code>list.each( function ( item ) { 15535 * item.methodName( 1, 2, 3 ); 15536 * } ); 15537 * // becomes 15538 * list.methodName( 1, 2, 3 );</code></pre> 15539 * 15540 * <p>Additionally, the pass through methods use the item retrieved by the 15541 * <code>_item</code> method in case there is any special behavior that is 15542 * appropriate for API mirroring.</p> 15543 * 15544 * <p>If the iterated method returns a value, the return value from the 15545 * added method will be an array of values with each value being at the 15546 * corresponding index for that item. If the iterated method does not 15547 * return a value, the added method will be chainable. 15548 * 15549 * @method addMethod 15550 * @static 15551 * @param dest {Object} Object or prototype to receive the iterator method 15552 * @param name {String|String[]} Name of method of methods to create 15553 */ 15554 addMethod: function ( dest, names ) { 15555 15556 names = YArray( names ); 15557 15558 YArray_each( names, function ( name ) { 15559 dest[ name ] = function () { 15560 var args = YArray( arguments, 0, true ), 15561 ret = []; 15562 15563 YArray_each( this._items, function ( item, i ) { 15564 item = this._item( i ); 15565 15566 var result = item[ name ].apply( item, args ); 15567 15568 if ( result !== undefined && result !== item ) { 15569 ret[i] = result; 15570 } 15571 }, this); 15572 15573 return ret.length ? ret : this; 15574 }; 15575 } ); 15576 } 15577} ); 15578 15579Y.ArrayList = ArrayList; 15580 15581 15582}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 15583 15584YUI.add('array-extras', function (Y, NAME) { 15585 15586/** 15587Adds additional utility methods to the `Y.Array` class. 15588 15589@module collection 15590@submodule array-extras 15591**/ 15592 15593var A = Y.Array, 15594 L = Y.Lang, 15595 ArrayProto = Array.prototype; 15596 15597/** 15598Returns the index of the last item in the array that contains the specified 15599value, or `-1` if the value isn't found. 15600 15601@method lastIndexOf 15602@param {Array} a Array to search in. 15603@param {Any} val Value to search for. 15604@param {Number} [fromIndex] Index at which to start searching backwards. 15605 Defaults to the array's length - 1. If negative, it will be taken as an offset 15606 from the end of the array. If the calculated index is less than 0, the array 15607 will not be searched and `-1` will be returned. 15608@return {Number} Index of the item that contains the value, or `-1` if not 15609 found. 15610@static 15611@for Array 15612**/ 15613A.lastIndexOf = L._isNative(ArrayProto.lastIndexOf) ? 15614 function(a, val, fromIndex) {
15615 // An undefined fromIndex is still considered a value by some (all?) 15616 // native implementations, so we can't pass it unless it's actually 15617 // specified. 15618 return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) : 15619 a.lastIndexOf(val); 15620 } : 15621 function(a, val, fromIndex) { 15622 var len = a.length, 15623 i = len - 1; 15624 15625 if (fromIndex || fromIndex === 0) { 15626 i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len); 15627 } 15628 15629 if (i > -1 && len > 0) { 15630 for (; i > -1; --i) { 15631 if (i in a && a[i] === val) { 15632 return i; 15633 } 15634 } 15635 } 15636 15637 return -1; 15638 }; 15639 15640/** 15641Returns a copy of the input array with duplicate items removed. 15642 15643Note: If the input array only contains strings, the `Y.Array.dedupe()` method is 15644a much faster alternative. 15645 15646@method unique 15647@param {Array} array Array to dedupe. 15648@param {Function} [testFn] Custom function to use to test the equality of two 15649 values. A truthy return value indicates that the values are equal. A falsy 15650 return value indicates that the values are not equal. 15651 15652 @param {Any} testFn.a First value to compare. 15653 @param {Any} testFn.b Second value to compare. 15654 @param {Number} testFn.index Index of the current item in the original 15655 array. 15656 @param {Array} testFn.array The original array. 15657 @return {Boolean} _true_ if the items are equal, _false_ otherwise. 15658 15659@return {Array} Copy of the input array with duplicate items removed. 15660@static 15661**/ 15662A.unique = function (array, testFn) { 15663 var i = 0, 15664 len = array.length, 15665 results = [], 15666 j, result, resultLen, value; 15667 15668 // Note the label here. It's used to jump out of the inner loop when a value 15669 // is not unique. 15670 outerLoop: for (; i < len; i++) { 15671 value = array[i]; 15672 15673 // For each value in the input array, iterate through the result array 15674 // and check for uniqueness against each result value. 15675 for (j = 0, resultLen = results.length; j < resultLen; j++) { 15676 result = results[j]; 15677 15678 // If the test function returns true or there's no test function and 15679 // the value equals the current result item, stop iterating over the 15680 // results and continue to the next value in the input array. 15681 if (testFn) { 15682 if (testFn.call(array, value, result, i, array)) { 15683 continue outerLoop; 15684 } 15685 } else if (value === result) { 15686 continue outerLoop; 15687 } 15688 } 15689 15690 // If we get this far, that means the current value is not already in 15691 // the result array, so add it. 15692 results.push(value); 15693 } 15694 15695 return results; 15696}; 15697 15698/** 15699Executes the supplied function on each item in the array. Returns a new array 15700containing the items for which the supplied function returned a truthy value. 15701 15702@method filter 15703@param {Array} a Array to filter. 15704@param {Function} f Function to execute on each item. 15705@param {Object} [o] Optional context object. 15706@return {Array} Array of items for which the supplied function returned a 15707 truthy value (empty if it never returned a truthy value). 15708@static 15709*/ 15710A.filter = L._isNative(ArrayProto.filter) ? 15711 function(a, f, o) { 15712 return ArrayProto.filter.call(a, f, o); 15713 } : 15714 function(a, f, o) { 15715 var i = 0, 15716 len = a.length, 15717 results = [], 15718 item; 15719 15720 for (; i < len; ++i) { 15721 if (i in a) { 15722 item = a[i]; 15723 15724 if (f.call(o, item, i, a)) { 15725 results.push(item); 15726 } 15727 } 15728 } 15729 15730 return results; 15731 }; 15732 15733/** 15734The inverse of `Array.filter()`. Executes the supplied function on each item. 15735Returns a new array containing the items for which the supplied function 15736returned `false`. 15737 15738@method reject 15739@param {Array} a the array to iterate. 15740@param {Function} f the function to execute on each item. 15741@param {object} [o] Optional context object. 15742@return {Array} The items for which the supplied function returned `false`. 15743@static 15744*/ 15745A.reject = function(a, f, o) { 15746 return A.filter(a, function(item, i, a) { 15747 return !f.call(o, item, i, a); 15748 }); 15749}; 15750 15751/** 15752Executes the supplied function on each item in the array. Iteration stops if the 15753supplied function does not return a truthy value. 15754 15755@method every 15756@param {Array} a the array to iterate. 15757@param {Function} f the function to execute on each item. 15758@param {Object} [o] Optional context object. 15759@return {Boolean} `true` if every item in the array returns `true` from the 15760 supplied function, `false` otherwise. 15761@static 15762*/ 15763A.every = L._isNative(ArrayProto.every) ? 15764 function(a, f, o) { 15765 return ArrayProto.every.call(a, f, o); 15766 } : 15767 function(a, f, o) { 15768 for (var i = 0, l = a.length; i < l; ++i) { 15769 if (i in a && !f.call(o, a[i], i, a)) { 15770 return false;
15771 } 15772 } 15773 15774 return true; 15775 }; 15776 15777/** 15778Executes the supplied function on each item in the array and returns a new array 15779containing all the values returned by the supplied function. 15780 15781@example 15782 15783 // Convert an array of numbers into an array of strings. 15784 Y.Array.map([1, 2, 3, 4], function (item) { 15785 return '' + item; 15786 }); 15787 // => ['1', '2', '3', '4'] 15788 15789@method map 15790@param {Array} a the array to iterate. 15791@param {Function} f the function to execute on each item. 15792@param {object} [o] Optional context object. 15793@return {Array} A new array containing the return value of the supplied function 15794 for each item in the original array. 15795@static 15796*/ 15797A.map = L._isNative(ArrayProto.map) ? 15798 function(a, f, o) { 15799 return ArrayProto.map.call(a, f, o); 15800 } : 15801 function(a, f, o) { 15802 var i = 0, 15803 len = a.length, 15804 results = ArrayProto.concat.call(a); 15805 15806 for (; i < len; ++i) { 15807 if (i in a) { 15808 results[i] = f.call(o, a[i], i, a); 15809 } 15810 } 15811 15812 return results; 15813 }; 15814 15815 15816/** 15817Executes the supplied function on each item in the array, "folding" the array 15818into a single value. 15819 15820@method reduce 15821@param {Array} a Array to iterate. 15822@param {Any} init Initial value to start with. 15823@param {Function} f Function to execute on each item. This function should 15824 update and return the value of the computation. It will receive the following 15825 arguments: 15826 @param {Any} f.previousValue Value returned from the previous iteration, 15827 or the initial value if this is the first iteration. 15828 @param {Any} f.currentValue Value of the current item being iterated. 15829 @param {Number} f.index Index of the current item. 15830 @param {Array} f.array Array being iterated. 15831@param {Object} [o] Optional context object. 15832@return {Any} Final result from iteratively applying the given function to each 15833 element in the array. 15834@static 15835*/ 15836A.reduce = L._isNative(ArrayProto.reduce) ? 15837 function(a, init, f, o) { 15838 // ES5 Array.reduce doesn't support a thisObject, so we need to 15839 // implement it manually. 15840 return ArrayProto.reduce.call(a, function(init, item, i, a) { 15841 return f.call(o, init, item, i, a); 15842 }, init); 15843 } : 15844 function(a, init, f, o) { 15845 var i = 0, 15846 len = a.length, 15847 result = init; 15848 15849 for (; i < len; ++i) { 15850 if (i in a) { 15851 result = f.call(o, result, a[i], i, a); 15852 } 15853 } 15854 15855 return result; 15856 }; 15857 15858/** 15859Executes the supplied function on each item in the array, searching for the 15860first item that matches the supplied function. 15861 15862@method find 15863@param {Array} a the array to search. 15864@param {Function} f the function to execute on each item. Iteration is stopped 15865 as soon as this function returns `true`. 15866@param {Object} [o] Optional context object. 15867@return {Object} the first item that the supplied function returns `true` for, 15868 or `null` if it never returns `true`. 15869@static 15870*/ 15871A.find = function(a, f, o) { 15872 for (var i = 0, l = a.length; i < l; i++) { 15873 if (i in a && f.call(o, a[i], i, a)) { 15874 return a[i]; 15875 } 15876 } 15877 return null; 15878}; 15879 15880/** 15881Iterates over an array, returning a new array of all the elements that match the 15882supplied regular expression. 15883 15884@method grep 15885@param {Array} a Array to iterate over. 15886@param {RegExp} pattern Regular expression to test against each item. 15887@return {Array} All the items in the array that produce a match against the 15888 supplied regular expression. If no items match, an empty array is returned. 15889@static 15890*/ 15891A.grep = function(a, pattern) { 15892 return A.filter(a, function(item, index) { 15893 return pattern.test(item); 15894 }); 15895}; 15896 15897/** 15898Partitions an array into two new arrays, one with the items for which the 15899supplied function returns `true`, and one with the items for which the function 15900returns `false`. 15901 15902@method partition 15903@param {Array} a Array to iterate over. 15904@param {Function} f Function to execute for each item in the array. It will 15905 receive the following arguments: 15906 @param {Any} f.item Current item. 15907 @param {Number} f.index Index of the current item. 15908 @param {Array} f.array The array being iterated. 15909@param {Object} [o] Optional execution context. 15910@return {Object} An object with two properties: `matches` and `rejects`. Each is 15911 an array containing the items that were selected or rejected by the test 15912 function (or an empty array if none). 15913@static 15914*/ 15915A.partition = function(a, f, o) { 15916 var results = { 15917 matches: [], 15918 rejects: [] 15919 }; 15920 15921 A.each(a, function(item, index) { 15922 var set = f.call(o, item, index, a) ? results.matches : results.rejects; 15923 set.push(item); 15924 }); 15925 15926 return results; 15927}; 15928 15929/** 15930Creates an array of arrays by pairing the corresponding elements of two arrays
15931together into a new array. 15932 15933@method zip 15934@param {Array} a Array to iterate over. 15935@param {Array} a2 Another array whose values will be paired with values of the 15936 first array. 15937@return {Array} An array of arrays formed by pairing each element of the first 15938 array with an item in the second array having the corresponding index. 15939@static 15940*/ 15941A.zip = function(a, a2) { 15942 var results = []; 15943 A.each(a, function(item, index) { 15944 results.push([item, a2[index]]); 15945 }); 15946 return results; 15947}; 15948 15949/** 15950Flattens an array of nested arrays at any abitrary depth into a single, flat 15951array. 15952 15953@method flatten 15954@param {Array} a Array with nested arrays to flatten. 15955@return {Array} An array whose nested arrays have been flattened. 15956@static 15957@since 3.7.0 15958**/ 15959A.flatten = function(a) { 15960 var result = [], 15961 i, len, val; 15962 15963 // Always return an array. 15964 if (!a) { 15965 return result; 15966 } 15967 15968 for (i = 0, len = a.length; i < len; ++i) { 15969 val = a[i]; 15970 15971 if (L.isArray(val)) { 15972 // Recusively flattens any nested arrays. 15973 result.push.apply(result, A.flatten(val)); 15974 } else { 15975 result.push(val); 15976 } 15977 } 15978 15979 return result; 15980}; 15981 15982 15983}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 15984 15985YUI.add('array-invoke', function (Y, NAME) { 15986 15987/** 15988@module collection 15989@submodule array-invoke 15990*/ 15991 15992/** 15993Executes a named method on each item in an array of objects. Items in the array 15994that do not have a function by that name will be skipped. 15995 15996@example 15997 15998 Y.Array.invoke(arrayOfDrags, 'plug', Y.Plugin.DDProxy); 15999 16000@method invoke 16001@param {Array} items Array of objects supporting the named method. 16002@param {String} name the name of the method to execute on each item. 16003@param {Any} [args*] Any number of additional args are passed as parameters to 16004 the execution of the named method. 16005@return {Array} All return values, indexed according to the item index. 16006@static 16007@for Array 16008**/ 16009Y.Array.invoke = function(items, name) { 16010 var args = Y.Array(arguments, 2, true), 16011 isFunction = Y.Lang.isFunction, 16012 ret = []; 16013 16014 Y.Array.each(Y.Array(items), function(item, i) { 16015 if (item && isFunction(item[name])) { 16016 ret[i] = item[name].apply(item, args); 16017 } 16018 }); 16019 16020 return ret; 16021}; 16022 16023 16024}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 16025 16026YUI.add('attribute-base', function (Y, NAME) { 16027 16028 /** 16029 * The attribute module provides an augmentable Attribute implementation, which 16030 * adds configurable attributes and attribute change events to the class being 16031 * augmented. It also provides a State class, which is used internally by Attribute, 16032 * but can also be used independently to provide a name/property/value data structure to 16033 * store state. 16034 * 16035 * @module attribute 16036 */ 16037 16038 /** 16039 * The attribute-base submodule provides core attribute handling support, with everything 16040 * aside from complex attribute handling in the provider's constructor. 16041 * 16042 * @module attribute 16043 * @submodule attribute-base 16044 */ 16045 16046 /** 16047 * <p> 16048 * Attribute provides configurable attribute support along with attribute change events. It is designed to be 16049 * augmented on to a host class, and provides the host with the ability to configure attributes to store and retrieve state, 16050 * along with attribute change events. 16051 * </p> 16052 * <p>For example, attributes added to the host can be configured:</p> 16053 * <ul> 16054 * <li>As read only.</li> 16055 * <li>As write once.</li> 16056 * <li>With a setter function, which can be used to manipulate 16057 * values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li> 16058 * <li>With a getter function, which can be used to manipulate stored values, 16059 * before they are returned by Attribute's <a href="#method_get">get</a> method.</li> 16060 * <li>With a validator function, to validate values before they are stored.</li> 16061 * </ul> 16062 * 16063 * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration 16064 * options available for attributes.</p> 16065 * 16066 * <p><strong>NOTE:</strong> Most implementations will be better off extending the <a href="Base.html">Base</a> class, 16067 * instead of augmenting Attribute directly. Base augments Attribute and will handle the initial configuration 16068 * of attributes for derived classes, accounting for values passed into the constructor.</p> 16069 * 16070 * @class Attribute 16071 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 16072 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 16073 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 16074 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 16075 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 16076 * @uses AttributeCore 16077 * @uses AttributeObservable 16078 * @uses EventTarget 16079 * @uses AttributeExtras 16080 */ 16081 function Attribute() { 16082 Y.AttributeCore.apply(this, arguments); 16083 Y.AttributeObservable.apply(this, arguments); 16084 Y.AttributeExtras.apply(this, arguments); 16085 } 16086 16087 Y.mix(Attribute, Y.AttributeCore, false, null, 1); 16088 Y.mix(Attribute, Y.AttributeExtras, false, null, 1); 16089 16090 // Needs to be `true`, to overwrite methods from AttributeCore 16091 Y.mix(Attribute, Y.AttributeObservable, true, null, 1); 16092 16093 /** 16094 * <p>The value to return from an attribute setter in order to prevent the set from going through.</p> 16095 * 16096 * <p>You can return this value from your setter if you wish to combine validator and setter 16097 * functionality into a single setter function, which either returns the massaged value to be stored or 16098 * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p> 16099 * 16100 * @property INVALID_VALUE 16101 * @type Object 16102 * @static 16103 * @final 16104 */ 16105 Attribute.INVALID_VALUE = Y.AttributeCore.INVALID_VALUE; 16106 16107 /** 16108 * The list of properties which can be configured for 16109 * each attribute (e.g. setter, getter, writeOnce etc.). 16110 * 16111 * This property is used internally as a whitelist for faster 16112 * Y.mix operations. 16113 * 16114 * @property _ATTR_CFG 16115 * @type Array 16116 * @static 16117 * @protected 16118 */ 16119 Attribute._ATTR_CFG = Y.AttributeCore._ATTR_CFG.concat(Y.AttributeObservable._ATTR_CFG); 16120 16121 /** 16122 * Utility method to protect an attribute configuration hash, by merging the 16123 * entire object and the individual attr config objects. 16124 * 16125 * @method protectAttrs 16126 * @static 16127 * @param {Object} attrs A hash of attribute to configuration object pairs. 16128 * @return {Object} A protected version of the `attrs` argument. 16129 */ 16130 Attribute.protectAttrs = Y.AttributeCore.protectAttrs; 16131 16132 Y.Attribute = Attribute; 16133 16134 16135}, 'patched-v3.18.1', {"requires": ["attribute-core", "attribute-observable", "attribute-extras"]}); 16136 16137YUI.add('attribute-complex', function (Y, NAME) { 16138 16139 /** 16140 * Adds support for attribute providers to handle complex attributes in the constructor 16141 * 16142 * @module attribute 16143 * @submodule attribute-complex 16144 * @for Attribute 16145 * @deprecated AttributeComplex's overrides are now part of AttributeCore. 16146 */ 16147 16148 var Attribute = Y.Attribute; 16149 16150 Attribute.Complex = function() {}; 16151 Attribute.Complex.prototype = { 16152 16153 /** 16154 * Utility method to split out simple attribute name/value pairs ("x") 16155 * from complex attribute name/value pairs ("x.y.z"), so that complex 16156 * attributes can be keyed by the top level attribute name. 16157 * 16158 * @method _normAttrVals 16159 * @param {Object} valueHash An object with attribute name/value pairs 16160 * 16161 * @return {Object} An object literal with 2 properties - "simple" and "complex", 16162 * containing simple and complex attribute values respectively keyed 16163 * by the top level attribute name, or null, if valueHash is falsey. 16164 * 16165 * @private 16166 */ 16167 _normAttrVals : Attribute.prototype._normAttrVals, 16168 16169 /** 16170 * Returns the initial value of the given attribute from 16171 * either the default configuration provided, or the 16172 * over-ridden value if it exists in the set of initValues 16173 * provided and the attribute is not read-only. 16174 * 16175 * @param {String} attr The name of the attribute 16176 * @param {Object} cfg The attribute configuration object 16177 * @param {Object}
16177 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals 16178 * 16179 * @return {Any} The initial value of the attribute. 16180 * 16181 * @method _getAttrInitVal 16182 * @private 16183 */ 16184 _getAttrInitVal : Attribute.prototype._getAttrInitVal 16185 16186 }; 16187 16188 // Consistency with the rest of the Attribute addons for now. 16189 Y.AttributeComplex = Attribute.Complex; 16190 16191 16192}, 'patched-v3.18.1', {"requires": ["attribute-base"]}); 16193 16194YUI.add('attribute-core', function (Y, NAME) { 16195 16196 /** 16197 * The State class maintains state for a collection of named items, with 16198 * a varying number of properties defined. 16199 * 16200 * It avoids the need to create a separate class for the item, and separate instances 16201 * of these classes for each item, by storing the state in a 2 level hash table, 16202 * improving performance when the number of items is likely to be large. 16203 * 16204 * @constructor 16205 * @class State 16206 */ 16207 Y.State = function() { 16208 /** 16209 * Hash of attributes 16210 * @property data 16211 */ 16212 this.data = {}; 16213 }; 16214 16215 Y.State.prototype = { 16216 16217 /** 16218 * Adds a property to an item. 16219 * 16220 * @method add 16221 * @param name {String} The name of the item. 16222 * @param key {String} The name of the property. 16223 * @param val {Any} The value of the property. 16224 */ 16225 add: function(name, key, val) { 16226 var item = this.data[name]; 16227 16228 if (!item) { 16229 item = this.data[name] = {}; 16230 } 16231 16232 item[key] = val; 16233 }, 16234 16235 /** 16236 * Adds multiple properties to an item. 16237 * 16238 * @method addAll 16239 * @param name {String} The name of the item. 16240 * @param obj {Object} A hash of property/value pairs. 16241 */ 16242 addAll: function(name, obj) { 16243 var item = this.data[name], 16244 key; 16245 16246 if (!item) { 16247 item = this.data[name] = {}; 16248 } 16249 16250 for (key in obj) { 16251 if (obj.hasOwnProperty(key)) { 16252 item[key] = obj[key]; 16253 } 16254 } 16255 }, 16256 16257 /** 16258 * Removes a property from an item. 16259 * 16260 * @method remove 16261 * @param name {String} The name of the item. 16262 * @param key {String} The property to remove. 16263 */ 16264 remove: function(name, key) { 16265 var item = this.data[name]; 16266 16267 if (item) { 16268 delete item[key]; 16269 } 16270 }, 16271 16272 /** 16273 * Removes multiple properties from an item, or removes the item completely. 16274 * 16275 * @method removeAll 16276 * @param name {String} The name of the item. 16277 * @param obj {Object|Array} Collection of properties to delete. If not provided, the entire item is removed. 16278 */ 16279 removeAll: function(name, obj) { 16280 var data; 16281 16282 if (!obj) { 16283 data = this.data; 16284 16285 if (name in data) { 16286 delete data[name]; 16287 } 16288 } else { 16289 Y.each(obj, function(value, key) { 16290 this.remove(name, typeof key === 'string' ? key : value); 16291 }, this); 16292 } 16293 }, 16294 16295 /** 16296 * For a given item, returns the value of the property requested, or undefined if not found. 16297 * 16298 * @method get 16299 * @param name {String} The name of the item 16300 * @param key {String} Optional. The property value to retrieve. 16301 * @return {Any} The value of the supplied property. 16302 */ 16303 get: function(name, key) { 16304 var item = this.data[name]; 16305 16306 if (item) { 16307 return item[key]; 16308 } 16309 }, 16310 16311 /** 16312 * For the given item, returns an object with all of the 16313 * item's property/value pairs. By default the object returned 16314 * is a shallow copy of the stored data, but passing in true 16315 * as the second parameter will return a reference to the stored 16316 * data. 16317 * 16318 * @method getAll 16319 * @param name {String} The name of the item 16320 * @param reference {boolean} true, if you want a reference to the stored 16321 * object 16322 * @return {Object} An object with property/value pairs for the item. 16323 */ 16324 getAll : function(name, reference) { 16325 var item = this.data[name], 16326 key, obj; 16327 16328 if (reference) { 16329 obj = item; 16330 } else if (item) { 16331 obj = {}; 16332 16333 for (key in item) { 16334 if (item.hasOwnProperty(key)) { 16335 obj[key] = item[key]; 16336 } 16337 } 16338 } 16339 16340 return obj; 16341 } 16342 }; 16343 /*For log lines*/ 16344 /*jshint maxlen:200*/ 16345 16346 /** 16347 * The attribute module provides an augmentable Attribute implementation, which 16348 * adds configurable attributes and attribute change events to the class being 16349 * augmented. It also provides a State class, which is used internally by Attribute, 16350 * but can also be used independently to provide a name/property/value data structure to 16351 * store state. 16352 * 16353 * @module attribute 16354 */ 16355 16356 /** 16357 * The attribute-core submodule provides the lightest level of attribute handling support 16358 * without Attribute change events, or lesser used methods such as reset(), modifyAttrs(), 16359 * and removeAttr(). 16360 * 16361 * @module attribute 16362 * @submodule attribute-core 16363 */ 16364 var O = Y.Object, 16365 Lang = Y.Lang, 16366 16367 DOT = ".", 16368 16369 // Externally configurable props 16370 GETTER = "getter", 16371 SETTER = "setter", 16372 READ_ONLY = "readOnly", 16373 WRITE_ONCE = "writeOnce", 16374 INIT_ONLY = "initOnly", 16375 VALIDATOR = "validator", 16376 VALUE = "value", 16377 VALUE_FN = "valueFn", 16378 LAZY_ADD = "lazyAdd", 16379 16380 // Used for internal state management 16381 ADDED = "added", 16382 BYPASS_PROXY = "_bypassProxy", 16383 INIT_VALUE = "initValue", 16384 LAZY = "lazy", 16385 16386 INVALID_VALUE; 16387 16388 /** 16389 * <p> 16390 * AttributeCore provides the lightest level of configurable attribute support. It is designed to be 16391 * augmented on to a host class, and provides the host with the ability to configure 16392 * attributes to store and retrieve state, <strong>but without support for attribute change events</strong>. 16393 * </p> 16394 * <p>For example, attributes added to the host can be configured:</p> 16395 * <ul> 16396 * <li>As read only.</li> 16397 * <li>As write once.</li> 16398 * <li>With a setter function, which can be used to manipulate 16399 * values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li> 16400 * <li>With a getter function, which can be used to manipulate stored values, 16401 * before they are returned by Attribute's <a href="#method_get">get</a> method.</li> 16402 * <li>With a validator function, to validate values before they are stored.</li> 16403 * </ul> 16404 * 16405 * <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration 16406 * options available for attributes.</p> 16407 * 16408 * <p>Object/Classes based on AttributeCore can augment <a href="AttributeObservable.html">AttributeObservable</a>
16409 * (with true for overwrite) and <a href="AttributeExtras.html">AttributeExtras</a> to add attribute event and 16410 * additional, less commonly used attribute methods, such as `modifyAttr`, `removeAttr` and `reset`.</p> 16411 * 16412 * @class AttributeCore 16413 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 16414 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 16415 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 16416 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 16417 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 16418 */ 16419 function AttributeCore(attrs, values, lazy) { 16420 // HACK: Fix #2531929 16421 // 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. 16422 // Too late in the release cycle to do anything about the core problem. 16423 // 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). 16424 this._yuievt = null; 16425 16426 this._initAttrHost(attrs, values, lazy); 16427 } 16428 16429 /** 16430 * <p>The value to return from an attribute setter in order to prevent the set from going through.</p> 16431 * 16432 * <p>You can return this value from your setter if you wish to combine validator and setter 16433 * functionality into a single setter function, which either returns the massaged value to be stored or 16434 * AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p> 16435 * 16436 * @property INVALID_VALUE 16437 * @type Object 16438 * @static 16439 * @final 16440 */ 16441 AttributeCore.INVALID_VALUE = {}; 16442 INVALID_VALUE = AttributeCore.INVALID_VALUE; 16443 16444 /** 16445 * The list of properties which can be configured for 16446 * each attribute (e.g. setter, getter, writeOnce etc.). 16447 * 16448 * This property is used internally as a whitelist for faster 16449 * Y.mix operations. 16450 * 16451 * @property _ATTR_CFG 16452 * @type Array 16453 * @static 16454 * @protected 16455 */ 16456 AttributeCore._ATTR_CFG = [SETTER, GETTER, VALIDATOR, VALUE, VALUE_FN, WRITE_ONCE, READ_ONLY, LAZY_ADD, BYPASS_PROXY]; 16457 16458 /** 16459 * Utility method to protect an attribute configuration hash, by merging the 16460 * entire object and the individual attr config objects. 16461 * 16462 * @method protectAttrs 16463 * @static 16464 * @param {Object} attrs A hash of attribute to configuration object pairs. 16465 * @return {Object} A protected version of the `attrs` argument. 16466 */ 16467 AttributeCore.protectAttrs = function (attrs) { 16468 if (attrs) { 16469 attrs = Y.merge(attrs); 16470 for (var attr in attrs) { 16471 if (attrs.hasOwnProperty(attr)) { 16472 attrs[attr] = Y.merge(attrs[attr]); 16473 } 16474 } 16475 } 16476 16477 return attrs; 16478 }; 16479 16480 AttributeCore.prototype = { 16481 16482 /** 16483 * Constructor logic for attributes. Initializes the host state, and sets up the inital attributes passed to the 16484 * constructor. 16485 * 16486 * @method _initAttrHost 16487 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 16488 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 16489 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 16490 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 16491 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 16492 * @private 16493 */ 16494 _initAttrHost : function(attrs, values, lazy) { 16495 this._state = new Y.State(); 16496 this._initAttrs(attrs, values, lazy); 16497 }, 16498 16499 /** 16500 * <p> 16501 * Adds an attribute with the provided configuration to the host object. 16502 * </p> 16503 * <p> 16504 * The config argument object supports the following properties: 16505 * </p> 16506 * 16507 * <dl> 16508 * <dt>value <Any></dt> 16509 * <dd>The initial value to set on the attribute</dd> 16510 * 16511 * <dt>valueFn <Function | String></dt> 16512 * <dd> 16513 * <p>A function, which will return the initial value to set on the attribute. This is useful 16514 * for cases where the attribute configuration is defined statically, but needs to 16515 * reference the host instance ("this") to obtain an initial value. If both the value and valueFn properties are defined, 16516 * the value returned by the valueFn has precedence over the value property, unless it returns undefined, in which 16517 * case the value property is used.</p> 16518 * 16519 * <p>valueFn can also be set to a string, representing the name of the instance method to be used to retrieve the value.</p> 16520 * </dd> 16521 * 16522 * <dt>readOnly <boolean></dt> 16523 * <dd>Whether or not the attribute is read only. Attributes having readOnly set to true 16524 * cannot be modified by invoking the set method.</dd> 16525 * 16526 * <dt>writeOnce <boolean> or <string></dt> 16527 * <dd> 16528 * Whether or not the attribute is "write once". Attributes having writeOnce set to true, 16529 * can only have their values set once, be it through the default configuration, 16530 * constructor configuration arguments, or by invoking set. 16531 * <p>The writeOnce attribute can also be set to the string "initOnly", 16532 * in which case the attribute can only be set during initialization 16533 * (when used with Base, this means it can only be set during construction)</p> 16534 * </dd> 16535 * 16536 * <dt>setter <Function | String></dt> 16537 * <dd> 16538 * <p>The setter function used to massage or normalize the value passed to the set method for the attribute. 16539 * The value returned by the setter will be the final stored value. Returning 16540 * <a href="#property_Attribute.INVALID_VALUE">Attribute.INVALID_VALUE</a>, from the setter will prevent 16541 * the value from being stored. 16542 * </p> 16543 * 16544 * <p>setter can also be set to a string, representing the name of the instance method to be used as the setter function.</p> 16545 * </dd> 16546 * 16547 * <dt>getter <Function | String></dt> 16548 * <dd> 16549 * <p> 16550 * The getter function used to massage or normalize the value returned by the get method for the attribute. 16551 * The value returned by the getter function is the value which will be returned to the user when they 16552 * invoke get. 16553 * </p> 16554 * 16555 * <p>getter can also be set to a string, representing the name of the instance method to be used as the getter function.</p> 16556 * </dd> 16557 * 16558 * <dt>validator <Function | String></dt> 16559 * <dd> 16560 * <p> 16561 * The validator function invoked prior to setting the stored value. Returning 16562 * false from the validator function will prevent the value from being stored. 16563 * </p> 16564 * 16565 * <p>validator can also be set to a string, representing the name of the instance method to be used as the validator function.</p> 16566 * </dd> 16567 * 16568 * <dt>lazyAdd <boolean></dt> 16569 * <dd>Whether or not to delay initialization of the attribute until the first call to get/set it. 16570 * This flag can be used to over-ride lazy initialization on a per attribute basis, when adding multiple attributes through 16571 * the <a href="#method_addAttrs">addAttrs</a> method.</dd> 16572 * 16573 * </dl> 16574 * 16575 * <p>The setter, getter and validator are invoked with the value and name passed in as the first and second arguments, and with 16576 * the context ("this") set to the host object.</p> 16577 * 16578 * <p>Configuration properties outside of the list mentioned above are considered private properties used internally by attribute, 16579 * and are not intended for public use.</p> 16580 * 16581 * @method addAttr 16582 * 16583 * @param {String} name The name of the attribute. 16584 * @param {Object} config An object with attribute configuration property/value pairs, specifying the configuration for the attribute. 16585 * 16586 * <p> 16587 * <strong>NOTE:</strong> The configuration object is modified when adding an attribute, so if you need 16588 * to protect the original values, you will need to merge the object. 16589 * </p> 16590 * 16591 * @param {boolean} lazy (optional) Whether or not to add this attribute lazily (on the first call to get/set). 16592 * 16593 * @return {Object} A reference to the host object. 16594 * 16595 * @chainable 16596 */ 16597 addAttr : function(name, config, lazy) { 16598 16599 16600 var host = this, // help compression 16601 state = host._state, 16602 data = state.data, 16603 value, 16604 added, 16605 hasValue; 16606 16607 config = config || {}; 16608 16609 if (LAZY_ADD in config) { 16610 lazy = config[LAZY_ADD]; 16611 } 16612 16613 added = state.get(name, ADDED); 16614 16615 if (lazy && !added) { 16616 state.data[name] = { 16617 lazy : config, 16618 added : true 16619 }; 16620 } else { 16621 16622 16623 if (!added || config.isLazyAdd) { 16624 16625 hasValue = (VALUE in config); 16626 16627 16628 if (hasValue) { 16629 16630 // We'll go through set, don't want to set value in config directly 16631 16632 // PERF TODO: VALIDATE: See if setting this to undefined is sufficient. We use to delete before. 16633 // In certain code paths/use cases, undefined may not be the same as not present. 16634 // If not, we can set it to some known fixed value (like INVALID_VALUE, say INITIALIZING_VALUE) for performance, 16635 // to avoid a delete which seems to help a lot. 16636 16637 value = config.value; 16638 config.value = undefined; 16639 } 16640 16641 config.added = true; 16642 config.initializing = true; 16643 16644 data[name] = config; 16645 16646 if (hasValue) { 16647 // Go through set, so that raw values get normalized/validated 16648 host.set(name, value); 16649 } 16650 16651 config.initializing = false;
16652 } 16653 } 16654 16655 return host; 16656 }, 16657 16658 /** 16659 * Checks if the given attribute has been added to the host 16660 * 16661 * @method attrAdded 16662 * @param {String} name The name of the attribute to check. 16663 * @return {boolean} true if an attribute with the given name has been added, false if it hasn't. 16664 * This method will return true for lazily added attributes. 16665 */ 16666 attrAdded: function(name) { 16667 return !!(this._state.get(name, ADDED)); 16668 }, 16669 16670 /** 16671 * Returns the current value of the attribute. If the attribute 16672 * has been configured with a 'getter' function, this method will delegate 16673 * to the 'getter' to obtain the value of the attribute. 16674 * 16675 * @method get 16676 * 16677 * @param {String} name The name of the attribute. If the value of the attribute is an Object, 16678 * dot notation can be used to obtain the value of a property of the object (e.g. <code>get("x.y.z")</code>) 16679 * 16680 * @return {Any} The value of the attribute 16681 */ 16682 get : function(name) { 16683 return this._getAttr(name); 16684 }, 16685 16686 /** 16687 * Checks whether or not the attribute is one which has been 16688 * added lazily and still requires initialization. 16689 * 16690 * @method _isLazyAttr 16691 * @private 16692 * @param {String} name The name of the attribute 16693 * @return {boolean} true if it's a lazily added attribute, false otherwise. 16694 */ 16695 _isLazyAttr: function(name) { 16696 return this._state.get(name, LAZY); 16697 }, 16698 16699 /** 16700 * Finishes initializing an attribute which has been lazily added. 16701 * 16702 * @method _addLazyAttr 16703 * @private 16704 * @param {Object} name The name of the attribute 16705 * @param {Object} [lazyCfg] Optional config hash for the attribute. This is added for performance 16706 * along the critical path, where the calling method has already obtained lazy config from state. 16707 */ 16708 _addLazyAttr: function(name, lazyCfg) { 16709 var state = this._state; 16710 16711 lazyCfg = lazyCfg || state.get(name, LAZY); 16712 16713 if (lazyCfg) { 16714 16715 // PERF TODO: For App's id override, otherwise wouldn't be 16716 // needed. It expects to find it in the cfg for it's 16717 // addAttr override. Would like to remove, once App override is 16718 // removed. 16719 state.data[name].lazy = undefined; 16720 16721 lazyCfg.isLazyAdd = true; 16722 16723 this.addAttr(name, lazyCfg); 16724 } 16725 }, 16726 16727 /** 16728 * Sets the value of an attribute. 16729 * 16730 * @method set 16731 * @chainable 16732 * 16733 * @param {String} name The name of the attribute. If the 16734 * current value of the attribute is an Object, dot notation can be used 16735 * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>). 16736 * @param {Any} value The value to set the attribute to. 16737 * @param {Object} [opts] Optional data providing the circumstances for the change. 16738 * @return {Object} A reference to the host object. 16739 */ 16740 set : function(name, val, opts) { 16741 return this._setAttr(name, val, opts); 16742 }, 16743 16744 /** 16745 * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details. 16746 * 16747 * @method _set 16748 * @protected 16749 * @chainable 16750 * 16751 * @param {String} name The name of the attribute. 16752 * @param {Any} val The value to set the attribute to. 16753 * @param {Object} [opts] Optional data providing the circumstances for the change. 16754 * @return {Object} A reference to the host object. 16755 */ 16756 _set : function(name, val, opts) { 16757 return this._setAttr(name, val, opts, true); 16758 }, 16759 16760 /** 16761 * Provides the common implementation for the public set and protected _set methods. 16762 * 16763 * See <a href="#method_set">set</a> for argument details. 16764 * 16765 * @method _setAttr 16766 * @protected 16767 * @chainable 16768 * 16769 * @param {String} name The name of the attribute. 16770 * @param {Any} value The value to set the attribute to. 16771 * @param {Object} [opts] Optional data providing the circumstances for the change. 16772 * @param {boolean} force If true, allows the caller to set values for 16773 * readOnly or writeOnce attributes which have already been set. 16774 * 16775 * @return {Object} A reference to the host object. 16776 */ 16777 _setAttr : function(name, val, opts, force) { 16778 var allowSet = true, 16779 state = this._state, 16780 stateProxy = this._stateProxy, 16781 tCfgs = this._tCfgs, 16782 cfg, 16783 initialSet, 16784 strPath, 16785 path, 16786 currVal, 16787 writeOnce, 16788 initializing; 16789 16790 if (name.indexOf(DOT) !== -1) { 16791 strPath = name; 16792 16793 path = name.split(DOT); 16794 name = path.shift(); 16795 } 16796 16797 // On Demand - Should be rare - handles out of order valueFn, setter, getter references 16798 if (tCfgs && tCfgs[name]) { 16799 this._addOutOfOrder(name, tCfgs[name]); 16800 } 16801 16802 cfg = state.data[name] || {}; 16803 16804 if (cfg.lazy) { 16805 cfg = cfg.lazy; 16806 this._addLazyAttr(name, cfg); 16807 } 16808 16809 initialSet = (cfg.value === undefined); 16810 16811 if (stateProxy && name in stateProxy && !cfg._bypassProxy) { 16812 // 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? 16813 initialSet = false;
16814 } 16815 16816 writeOnce = cfg.writeOnce; 16817 initializing = cfg.initializing; 16818 16819 if (!initialSet && !force) { 16820 16821 if (writeOnce) { 16822 allowSet = false; 16823 } 16824 16825 if (cfg.readOnly) { 16826 allowSet = false; 16827 } 16828 } 16829 16830 if (!initializing && !force && writeOnce === INIT_ONLY) { 16831 allowSet = false; 16832 } 16833 16834 if (allowSet) { 16835 // Don't need currVal if initialSet (might fail in custom getter if it always expects a non-undefined/non-null value) 16836 if (!initialSet) { 16837 currVal = this.get(name); 16838 } 16839 16840 if (path) { 16841 var copyVal = [currVal].reduce( 16842 function(retVal, currVal) { 16843 Object.keys(currVal).forEach( 16844 function(item) { 16845 retVal[item] = currVal[item]; 16846 } 16847 ); 16848 return retVal; 16849 }, 16850 {} 16851 ); 16852 16853 var pathNode = copyVal; 16854 var leafIdx = path.length - 1; 16855 16856 for (var i = 0; i < leafIdx && pathNode; i++) { 16857 pathNode = pathNode[path[i]]; 16858 } 16859 16860 if (pathNode) { 16861 delete pathNode[path[leafIdx]]; 16862 } 16863 16864 val = O.setValue(Y.clone(copyVal), path, val); 16865 16866 if (val === undefined) { 16867 allowSet = false; 16868 } 16869 } 16870 16871 if (allowSet) { 16872 if (!this._fireAttrChange || initializing) { 16873 this._setAttrVal(name, strPath, currVal, val, opts, cfg); 16874 } else { 16875 // HACK - no real reason core needs to know about _fireAttrChange, but 16876 // it adds fn hops if we want to break it out. Not sure it's worth it for this critical path 16877 this._fireAttrChange(name, strPath, currVal, val, opts, cfg); 16878 } 16879 } 16880 } 16881 16882 return this; 16883 }, 16884 16885 /** 16886 * Utility method used by get/set to add attributes 16887 * encountered out of order when calling addAttrs(). 16888 * 16889 * For example, if: 16890 * 16891 * this.addAttrs({ 16892 * foo: { 16893 * setter: function() { 16894 * // make sure this bar is available when foo is added 16895 * this.get("bar"); 16896 * } 16897 * }, 16898 * bar: { 16899 * value: ... 16900 * } 16901 * }); 16902 * 16903 * @method _addOutOfOrder 16904 * @private 16905 * @param name {String} attribute name 16906 * @param cfg {Object} attribute configuration 16907 */ 16908 _addOutOfOrder : function(name, cfg) { 16909 16910 var attrs = {}; 16911 attrs[name] = cfg; 16912 16913 delete this._tCfgs[name]; 16914 16915 // TODO: The original code went through addAttrs, so 16916 // sticking with it for this pass. Seems like we could 16917 // just jump straight to _addAttr() and get some perf 16918 // improvement. 16919 this._addAttrs(attrs, this._tVals); 16920 }, 16921 16922 /** 16923 * Provides the common implementation for the public get method, 16924 * allowing Attribute hosts to over-ride either method. 16925 * 16926 * See <a href="#method_get">get</a> for argument details. 16927 * 16928 * @method _getAttr 16929 * @protected 16930 * @chainable 16931 * 16932 * @param {String} name The name of the attribute. 16933 * @return {Any} The value of the attribute. 16934 */ 16935 _getAttr : function(name) { 16936 var fullName = name, 16937 tCfgs = this._tCfgs, 16938 path, 16939 getter, 16940 val, 16941 attrCfg; 16942 16943 if (name.indexOf(DOT) !== -1) { 16944 path = name.split(DOT); 16945 name = path.shift(); 16946 } 16947 16948 // On Demand - Should be rare - handles out of 16949 // order valueFn, setter, getter references 16950 if (tCfgs && tCfgs[name]) { 16951 this._addOutOfOrder(name, tCfgs[name]); 16952 } 16953 16954 attrCfg = this._state.data[name] || {}; 16955 16956 // Lazy Init 16957 if (attrCfg.lazy) { 16958 attrCfg = attrCfg.lazy; 16959 this._addLazyAttr(name, attrCfg); 16960 } 16961 16962 val = this._getStateVal(name, attrCfg); 16963 16964 getter = attrCfg.getter; 16965 16966 if (getter && !getter.call) { 16967 getter = this[getter]; 16968 } 16969 16970 val = (getter) ? getter.call(this, val, fullName) : val; 16971 val = (path) ? O.getValue(val, path) : val; 16972 16973 return val; 16974 }, 16975 16976 /** 16977 * Gets the stored value for the attribute, from either the 16978 * internal state object, or the state proxy if it exits 16979 * 16980 * @method _getStateVal 16981 * @private 16982 * @param {String} name The name of the attribute 16983 * @param {Object} [cfg] Optional config hash for the attribute. This is added for performance along the critical path, 16984 * where the calling method has already obtained the config from state. 16985 * 16986 * @return {Any} The stored value of the attribute 16987 */ 16988 _getStateVal : function(name, cfg) { 16989 var stateProxy = this._stateProxy; 16990 16991 if (!cfg) { 16992 cfg = this._state.getAll(name) || {}; 16993 } 16994 16995 return (stateProxy && (name in stateProxy) && !(cfg._bypassProxy)) ? stateProxy[name] : cfg.value; 16996 }, 16997 16998 /** 16999 * Sets the stored value for the attribute, in either the 17000 * internal state object, or the state proxy if it exits 17001 * 17002 * @method _setStateVal 17003 * @private 17004 * @param {String} name The name of the attribute 17005 * @param {Any} value The value of the attribute 17006 */ 17007 _setStateVal : function(name, value) { 17008 var stateProxy = this._stateProxy; 17009 if (stateProxy && (name in stateProxy) && !this._state.get(name, BYPASS_PROXY)) { 17010 stateProxy[name] = value; 17011 } else { 17012 this._state.add(name, VALUE, value); 17013 } 17014 }, 17015 17016 /** 17017 * Updates the stored value of the attribute in the privately held State object, 17018 * if validation and setter passes. 17019 * 17020 * @method _setAttrVal 17021 * @private 17022 * @param {String} attrName The attribute name. 17023 * @param {String} subAttrName The sub-attribute name, if setting a sub-attribute property ("x.y.z"). 17024 * @param {Any} prevVal The currently stored value of the attribute. 17025 * @param {Any} newVal The value which is going to be stored. 17026 * @param {Object} [opts] Optional data providing the circumstances for the change. 17027 * @param {Object} [attrCfg] Optional config hash for the attribute. This is added for performance along the critical path, 17028 * where the calling method has already obtained the config from state. 17029 * 17030 * @return {Boolean} true if the new attribute value was stored, false if not. 17031 */ 17032 _setAttrVal : function(attrName, subAttrName, prevVal, newVal, opts, attrCfg) { 17033 17034 var host = this, 17035 allowSet = true, 17036 cfg = attrCfg || this._state.data[attrName] || {}, 17037 validator = cfg.validator, 17038 setter = cfg.setter, 17039 initializing = cfg.initializing, 17040 prevRawVal = this._getStateVal(attrName, cfg), 17041 name = subAttrName || attrName, 17042 retVal, 17043 valid; 17044 17045 if (validator) { 17046 if (!validator.call) { 17047 // Assume string - trying to keep critical path tight, so avoiding Lang check 17048 validator = this[validator]; 17049 } 17050 if (validator) { 17051 valid = validator.call(host, newVal, name, opts); 17052 17053 if (!valid && initializing) { 17054 newVal = cfg.defaultValue; 17055 valid = true; // Assume it's valid, for perf. 17056 } 17057 } 17058 } 17059 17060 if (!validator || valid) { 17061 if (setter) { 17062 if (!setter.call) { 17063 // Assume string - trying to keep critical path tight, so avoiding Lang check 17064 setter = this[setter]; 17065 } 17066 if (setter) { 17067 retVal = setter.call(host, newVal, name, opts); 17068 17069 if (retVal === INVALID_VALUE) { 17070 if (initializing) { 17071 newVal = cfg.defaultValue; 17072 } else { 17073 allowSet = false;
17074 } 17075 } else if (retVal !== undefined){ 17076 newVal = retVal; 17077 } 17078 } 17079 } 17080 17081 if (allowSet) { 17082 if(!subAttrName && (newVal === prevRawVal) && !Lang.isObject(newVal)) { 17083 allowSet = false; 17084 } else { 17085 // Store value 17086 if (!(INIT_VALUE in cfg)) { 17087 cfg.initValue = newVal; 17088 } 17089 host._setStateVal(attrName, newVal); 17090 } 17091 } 17092 17093 } else { 17094 allowSet = false; 17095 } 17096 17097 return allowSet; 17098 }, 17099 17100 /** 17101 * Sets multiple attribute values. 17102 * 17103 * @method setAttrs 17104 * @param {Object} attrs An object with attributes name/value pairs. 17105 * @param {Object} [opts] Optional data providing the circumstances for the change. 17106 * @return {Object} A reference to the host object. 17107 * @chainable 17108 */ 17109 setAttrs : function(attrs, opts) { 17110 return this._setAttrs(attrs, opts); 17111 }, 17112 17113 /** 17114 * Implementation behind the public setAttrs method, to set multiple attribute values. 17115 * 17116 * @method _setAttrs 17117 * @protected 17118 * @param {Object} attrs An object with attributes name/value pairs. 17119 * @param {Object} [opts] Optional data providing the circumstances for the change 17120 * @return {Object} A reference to the host object. 17121 * @chainable 17122 */ 17123 _setAttrs : function(attrs, opts) { 17124 var attr; 17125 for (attr in attrs) { 17126 if ( attrs.hasOwnProperty(attr) ) { 17127 this.set(attr, attrs[attr], opts); 17128 } 17129 } 17130 return this; 17131 }, 17132 17133 /** 17134 * Gets multiple attribute values. 17135 * 17136 * @method getAttrs 17137 * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are 17138 * returned. If set to true, all attributes modified from their initial values are returned. 17139 * @return {Object} An object with attribute name/value pairs. 17140 */ 17141 getAttrs : function(attrs) { 17142 return this._getAttrs(attrs); 17143 }, 17144 17145 /** 17146 * Implementation behind the public getAttrs method, to get multiple attribute values. 17147 * 17148 * @method _getAttrs 17149 * @protected 17150 * @param {String[]|Boolean} attrs Optional. An array of attribute names. If omitted, all attribute values are 17151 * returned. If set to true, all attributes modified from their initial values are returned. 17152 * @return {Object} An object with attribute name/value pairs. 17153 */ 17154 _getAttrs : function(attrs) { 17155 var obj = {}, 17156 attr, i, len, 17157 modifiedOnly = (attrs === true); 17158 17159 // TODO - figure out how to get all "added" 17160 if (!attrs || modifiedOnly) { 17161 attrs = O.keys(this._state.data); 17162 } 17163 17164 for (i = 0, len = attrs.length; i < len; i++) { 17165 attr = attrs[i]; 17166 17167 if (!modifiedOnly || this._getStateVal(attr) != this._state.get(attr, INIT_VALUE)) { 17168 // Go through get, to honor cloning/normalization 17169 obj[attr] = this.get(attr); 17170 } 17171 } 17172 17173 return obj; 17174 }, 17175 17176 /** 17177 * Configures a group of attributes, and sets initial values. 17178 * 17179 * <p> 17180 * <strong>NOTE:</strong> This method does not isolate the configuration object by merging/cloning. 17181 * The caller is responsible for merging/cloning the configuration object if required. 17182 * </p> 17183 * 17184 * @method addAttrs 17185 * @chainable 17186 * 17187 * @param {Object} cfgs An object with attribute name/configuration pairs. 17188 * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply. 17189 * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only. 17190 * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set.
17191 * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration. 17192 * See <a href="#method_addAttr">addAttr</a>. 17193 * 17194 * @return {Object} A reference to the host object. 17195 */ 17196 addAttrs : function(cfgs, values, lazy) { 17197 if (cfgs) { 17198 this._tCfgs = cfgs; 17199 this._tVals = (values) ? this._normAttrVals(values) : null; 17200 this._addAttrs(cfgs, this._tVals, lazy); 17201 this._tCfgs = this._tVals = null; 17202 } 17203 17204 return this; 17205 }, 17206 17207 /** 17208 * Implementation behind the public addAttrs method. 17209 * 17210 * This method is invoked directly by get if it encounters a scenario 17211 * in which an attribute's valueFn attempts to obtain the 17212 * value an attribute in the same group of attributes, which has not yet 17213 * been added (on demand initialization). 17214 * 17215 * @method _addAttrs 17216 * @private 17217 * @param {Object} cfgs An object with attribute name/configuration pairs. 17218 * @param {Object} values An object with attribute name/value pairs, defining the initial values to apply. 17219 * Values defined in the cfgs argument will be over-written by values in this argument unless defined as read only. 17220 * @param {boolean} lazy Whether or not to delay the intialization of these attributes until the first call to get/set. 17221 * Individual attributes can over-ride this behavior by defining a lazyAdd configuration property in their configuration. 17222 * See <a href="#method_addAttr">addAttr</a>. 17223 */ 17224 _addAttrs : function(cfgs, values, lazy) { 17225 var tCfgs = this._tCfgs, 17226 tVals = this._tVals, 17227 attr, 17228 attrCfg, 17229 value; 17230 17231 for (attr in cfgs) { 17232 if (cfgs.hasOwnProperty(attr)) { 17233 17234 // Not Merging. Caller is responsible for isolating configs 17235 attrCfg = cfgs[attr]; 17236 attrCfg.defaultValue = attrCfg.value; 17237 17238 // Handle simple, complex and user values, accounting for read-only 17239 value = this._getAttrInitVal(attr, attrCfg, tVals); 17240 17241 if (value !== undefined) { 17242 attrCfg.value = value; 17243 } 17244 17245 if (tCfgs[attr]) { 17246 tCfgs[attr] = undefined; 17247 } 17248 17249 this.addAttr(attr, attrCfg, lazy); 17250 } 17251 } 17252 }, 17253 17254 /** 17255 * Utility method to protect an attribute configuration 17256 * hash, by merging the entire object and the individual 17257 * attr config objects. 17258 * 17259 * @method _protectAttrs 17260 * @protected 17261 * @param {Object} attrs A hash of attribute to configuration object pairs. 17262 * @return {Object} A protected version of the attrs argument. 17263 * @deprecated Use `AttributeCore.protectAttrs()` or 17264 * `Attribute.protectAttrs()` which are the same static utility method. 17265 */ 17266 _protectAttrs : AttributeCore.protectAttrs, 17267 17268 /** 17269 * Utility method to normalize attribute values. The base implementation 17270 * simply merges the hash to protect the original. 17271 * 17272 * @method _normAttrVals 17273 * @param {Object} valueHash An object with attribute name/value pairs 17274 * 17275 * @return {Object} An object literal with 2 properties - "simple" and "complex", 17276 * containing simple and complex attribute values respectively keyed 17277 * by the top level attribute name, or null, if valueHash is falsey. 17278 * 17279 * @private 17280 */ 17281 _normAttrVals : function(valueHash) { 17282 var vals, 17283 subvals, 17284 path, 17285 attr, 17286 v, k; 17287 17288 if (!valueHash) { 17289 return null; 17290 } 17291 17292 vals = {}; 17293 17294 for (k in valueHash) { 17295 if (valueHash.hasOwnProperty(k)) { 17296 if (k.indexOf(DOT) !== -1) { 17297 path = k.split(DOT); 17298 attr = path.shift(); 17299 17300 subvals = subvals || {}; 17301 17302 v = subvals[attr] = subvals[attr] || []; 17303 v[v.length] = { 17304 path : path, 17305 value: valueHash[k] 17306 }; 17307 } else { 17308 vals[k] = valueHash[k]; 17309 } 17310 } 17311 } 17312 17313 return { simple:vals, complex:subvals }; 17314 }, 17315 17316 /** 17317 * Returns the initial value of the given attribute from 17318 * either the default configuration provided, or the 17319 * over-ridden value if it exists in the set of initValues 17320 * provided and the attribute is not read-only. 17321 * 17322 * @param {String} attr The name of the attribute 17323 * @param {Object} cfg The attribute configuration object 17324 * @param {Object}
17324 initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals 17325 * 17326 * @return {Any} The initial value of the attribute. 17327 * 17328 * @method _getAttrInitVal 17329 * @private 17330 */ 17331 _getAttrInitVal : function(attr, cfg, initValues) { 17332 var val = cfg.value, 17333 valFn = cfg.valueFn, 17334 tmpVal, 17335 initValSet = false, 17336 readOnly = cfg.readOnly, 17337 simple, 17338 complex, 17339 i, 17340 l, 17341 path, 17342 subval, 17343 subvals; 17344 17345 if (!readOnly && initValues) { 17346 // Simple Attributes 17347 simple = initValues.simple; 17348 if (simple && simple.hasOwnProperty(attr)) { 17349 val = simple[attr]; 17350 initValSet = true; 17351 } 17352 } 17353 17354 if (valFn && !initValSet) { 17355 if (!valFn.call) { 17356 valFn = this[valFn]; 17357 } 17358 if (valFn) { 17359 tmpVal = valFn.call(this, attr); 17360 val = tmpVal; 17361 } 17362 } 17363 17364 if (!readOnly && initValues) { 17365 17366 // Complex Attributes (complex values applied, after simple, in case both are set) 17367 complex = initValues.complex; 17368 17369 if (complex && complex.hasOwnProperty(attr) && (val !== undefined) && (val !== null)) { 17370 subvals = complex[attr]; 17371 for (i = 0, l = subvals.length; i < l; ++i) { 17372 path = subvals[i].path; 17373 subval = subvals[i].value; 17374 O.setValue(val, path, subval); 17375 } 17376 } 17377 } 17378 17379 return val; 17380 }, 17381 17382 /** 17383 * Utility method to set up initial attributes defined during construction, 17384 * either through the constructor.ATTRS property, or explicitly passed in. 17385 * 17386 * @method _initAttrs 17387 * @protected 17388 * @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>). 17389 * These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor. 17390 * @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>). 17391 * These are not merged/cloned. The caller is responsible for isolating user provided values if required. 17392 * @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>). 17393 */ 17394 _initAttrs : function(attrs, values, lazy) { 17395 // ATTRS support for Node, which is not Base based 17396 attrs = attrs || this.constructor.ATTRS; 17397 17398 var Base = Y.Base, 17399 BaseCore = Y.BaseCore, 17400 baseInst = (Base && Y.instanceOf(this, Base)), 17401 baseCoreInst = (!baseInst && BaseCore && Y.instanceOf(this, BaseCore)); 17402 17403 if (attrs && !baseInst && !baseCoreInst) { 17404 this.addAttrs(Y.AttributeCore.protectAttrs(attrs), values, lazy); 17405 } 17406 } 17407 }; 17408 17409 Y.AttributeCore = AttributeCore; 17410 17411 17412}, 'patched-v3.18.1', {"requires": ["oop"]}); 17413 17414YUI.add('attribute-observable', function (Y, NAME) { 17415 17416 /*For log lines*/ 17417 /*jshint maxlen:200*/ 17418 17419 17420 /** 17421 * The attribute module provides an augmentable Attribute implementation, which 17422 * adds configurable attributes and attribute change events to the class being 17423 * augmented. It also provides a State class, which is used internally by Attribute, 17424 * but can also be used independently to provide a name/property/value data structure to 17425 * store state. 17426 * 17427 * @module attribute 17428 */ 17429 17430 /** 17431 * The `attribute-observable` submodule provides augmentable attribute change event support 17432 * for AttributeCore based implementations. 17433 * 17434 * @module attribute 17435 * @submodule attribute-observable 17436 */ 17437 var EventTarget = Y.EventTarget, 17438 17439 CHANGE = "Change", 17440 BROADCAST = "broadcast"; 17441 17442 /** 17443 * Provides an augmentable implementation of attribute change events for 17444 * AttributeCore. 17445 * 17446 * @class AttributeObservable 17447 * @extensionfor AttributeCore 17448 * @uses EventTarget 17449 */ 17450 function AttributeObservable() { 17451 // Perf tweak - avoid creating event literals if not required. 17452 this._ATTR_E_FACADE = {}; 17453 17454 EventTarget.call(this, {emitFacade:true}); 17455 } 17456 17457 AttributeObservable._ATTR_CFG = [BROADCAST]; 17458 17459 AttributeObservable.prototype = { 17460 17461 /** 17462 * Sets the value of an attribute. 17463 * 17464 * @method set 17465 * @chainable 17466 * 17467 * @param {String} name The name of the attribute. If the 17468 * current value of the attribute is an Object, dot notation can be used 17469 * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>). 17470 * 17471 * @param {Any} value The value to set the attribute to. 17472 * 17473 * @param {Object} opts (Optional) Optional event data to be mixed into 17474 * the event facade passed to subscribers of the attribute's change event. This 17475 * can be used as a flexible way to identify the source of a call to set, allowing 17476 * the developer to distinguish between set called internally by the host, vs. 17477 * set called externally by the application developer. 17478 * 17479 * @return {Object} A reference to the host object. 17480 */ 17481 set : function(name, val, opts) { 17482 return this._setAttr(name, val, opts); 17483 }, 17484 17485 /** 17486 * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details. 17487 * 17488 * @method _set 17489 * @protected 17490 * @chainable 17491 * 17492 * @param {String} name The name of the attribute. 17493 * @param {Any} val The value to set the attribute to. 17494 * @param {Object} opts (Optional) Optional event data to be mixed into 17495 * the event facade passed to subscribers of the attribute's change event. 17496 * @return {Object} A reference to the host object. 17497 */ 17498 _set : function(name, val, opts) { 17499 return this._setAttr(name, val, opts, true); 17500 }, 17501 17502 /** 17503 * Sets multiple attribute values. 17504 * 17505 * @method setAttrs 17506 * @param {Object} attrs An object with attributes name/value pairs. 17507 * @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set 17508 * @return {Object} A reference to the host object. 17509 * @chainable 17510 */ 17511 setAttrs : function(attrs, opts) { 17512 return this._setAttrs(attrs, opts); 17513 }, 17514 17515 /** 17516 * Implementation behind the public setAttrs method, to set multiple attribute values. 17517 * 17518 * @method _setAttrs 17519 * @protected 17520 * @param {Object} attrs An object with attributes name/value pairs. 17521 * @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set 17522 * @return {Object} A reference to the host object. 17523 * @chainable 17524 */ 17525 _setAttrs : function(attrs, opts) { 17526 var attr; 17527 for (attr in attrs) { 17528 if ( attrs.hasOwnProperty(attr) ) { 17529 this.set(attr, attrs[attr], opts); 17530 } 17531 } 17532 return this; 17533 }, 17534 17535 /** 17536 * Utility method to help setup the event payload and fire the attribute change event. 17537 * 17538 * @method _fireAttrChange 17539 * @private 17540 * @param {String} attrName The name of the attribute 17541 * @param {String} subAttrName The full path of the property being changed, 17542 * if this is a sub-attribute value being change. Otherwise null. 17543 * @param {Any} currVal The current value of the attribute 17544 * @param {Any} newVal The new value of the attribute 17545 * @param {Object} opts Any additional event data to mix into the attribute change event's event facade. 17546 * @param {Object} [cfg] The attribute config stored in State, if already available. 17547 */ 17548 _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) { 17549 var host = this, 17550 eventName = this._getFullType(attrName + CHANGE), 17551 state = host._state, 17552 facade, 17553 broadcast, 17554 e; 17555 17556 if (!cfg) { 17557 cfg = state.data[attrName] || {}; 17558 } 17559 17560 if (!cfg.published) { 17561 17562 // PERF: Using lower level _publish() for 17563 // critical path performance 17564 e = host._publish(eventName); 17565 17566 e.emitFacade = true; 17567 e.defaultTargetOnly = true; 17568 e.defaultFn = host._defAttrChangeFn; 17569 17570 broadcast = cfg.broadcast; 17571 if (broadcast !== undefined) { 17572 e.broadcast = broadcast; 17573 } 17574 17575 cfg.published = true; 17576 } 17577 17578 if (opts) { 17579 facade = Y.merge(opts); 17580 facade._attrOpts = opts; 17581 } else { 17582 facade = host._ATTR_E_FACADE; 17583 } 17584 17585 // Not using the single object signature for fire({type:..., newVal:...}), since 17586 // we don't want to override type. Changed to the fire(type, {newVal:...}) signature. 17587 17588 facade.attrName = attrName; 17589 facade.subAttrName = subAttrName; 17590 facade.prevVal = currVal; 17591 facade.newVal = newVal; 17592 17593 if (host._hasPotentialSubscribers(eventName)) { 17594 host.fire(eventName, facade); 17595 } else { 17596 this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg); 17597 } 17598 }, 17599 17600 /** 17601 * Default function for attribute change events. 17602 * 17603 * @private 17604 * @method _defAttrChangeFn 17605 * @param {EventFacade} e The event object for attribute change events. 17606 * @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not 17607 */ 17608 _defAttrChangeFn : function(e, eventFastPath) { 17609 17610 var opts = e._attrOpts; 17611 if (opts) { 17612 delete e._attrOpts; 17613 } 17614 17615 if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) { 17616 17617 17618 if (!eventFastPath) { 17619 // Prevent "after" listeners from being invoked since nothing changed. 17620 e.stopImmediatePropagation(); 17621 } 17622 17623 } else { 17624 if (!eventFastPath) { 17625 e.newVal = this.get(e.attrName); 17626 } 17627 } 17628 } 17629 }; 17630 17631 // Basic prototype augment - no lazy constructor invocation. 17632 Y.mix(AttributeObservable, EventTarget, false, null, 1); 17633 17634 Y.AttributeObservable = AttributeObservable; 17635 17636 /**
17637 The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now 17638 an alias for the `AttributeObservable` class extension. Use that class 17639 extnesion instead. This alias will be removed in a future version of YUI. 17640 17641 @class AttributeEvents 17642 @uses EventTarget 17643 @deprecated Use `AttributeObservable` instead. 17644 @see AttributeObservable 17645 **/ 17646 Y.AttributeEvents = AttributeObservable; 17647 17648 17649}, 'patched-v3.18.1', {"requires": ["event-custom"]}); 17650 17651YUI.add('attribute-extras', function (Y, NAME) { 17652 17653 /** 17654 * The attribute module provides an augmentable Attribute implementation, which 17655 * adds configurable attributes and attribute change events to the class being 17656 * augmented. It also provides a State class, which is used internally by Attribute, 17657 * but can also be used independently to provide a name/property/value data structure to 17658 * store state. 17659 * 17660 * @module attribute 17661 */ 17662 17663 /** 17664 * The attribute-extras submodule provides less commonly used attribute methods, and can 17665 * be augmented/mixed into an implemention which used attribute-core. 17666 * 17667 * @module attribute 17668 * @submodule attribute-extras 17669 */ 17670 var BROADCAST = "broadcast", 17671 PUBLISHED = "published", 17672 INIT_VALUE = "initValue", 17673 17674 MODIFIABLE = { 17675 readOnly:1, 17676 writeOnce:1, 17677 getter:1, 17678 broadcast:1 17679 }; 17680 17681 /** 17682 * A augmentable implementation for AttributeCore, providing less frequently used 17683 * methods for Attribute management such as modifyAttrs(), removeAttr and reset() 17684 * 17685 * @class AttributeExtras 17686 * @extensionfor AttributeCore 17687 */ 17688 function AttributeExtras() {} 17689 17690 AttributeExtras.prototype = { 17691 17692 /** 17693 * Updates the configuration of an attribute which has already been added. 17694 * <p> 17695 * The properties which can be modified through this interface are limited 17696 * to the following subset of attributes, which can be safely modified 17697 * after a value has already been set on the attribute: 17698 * </p> 17699 * <dl> 17700 * <dt>readOnly;</dt> 17701 * <dt>writeOnce;</dt> 17702 * <dt>broadcast; and</dt> 17703 * <dt>getter.</dt> 17704 * </dl> 17705 * <p> 17706 * Note: New attributes cannot be added using this interface. New attributes must be 17707 * added using {{#crossLink "AttributeCore/addAttr:method"}}addAttr{{/crossLink}}, or an 17708 * appropriate manner for a class which utilises Attributes (e.g. the 17709 * {{#crossLink "Base/ATTRS:property"}}ATTRS{{/crossLink}} property in 17710 * {{#crossLink "Base"}}Base{{/crossLink}}). 17711 * </p> 17712 * @method modifyAttr 17713 * @param {String} name The name of the attribute whose configuration is to be updated. 17714 * @param {Object} config An object with configuration property/value pairs, specifying the configuration properties to modify. 17715 */ 17716 modifyAttr: function(name, config) { 17717 var host = this, // help compression 17718 prop, state; 17719 17720 if (host.attrAdded(name)) { 17721 17722 if (host._isLazyAttr(name)) { 17723 host._addLazyAttr(name); 17724 } 17725 17726 state = host._state; 17727 for (prop in config) { 17728 if (MODIFIABLE[prop] && config.hasOwnProperty(prop)) { 17729 state.add(name, prop, config[prop]); 17730 17731 // If we reconfigured broadcast, need to republish 17732 if (prop === BROADCAST) { 17733 state.remove(name, PUBLISHED); 17734 } 17735 } 17736 } 17737 } else { 17738 } 17739 }, 17740 17741 /** 17742 * Removes an attribute from the host object 17743 * 17744 * @method removeAttr 17745 * @param {String} name The name of the attribute to be removed. 17746 */ 17747 removeAttr: function(name) { 17748 this._state.removeAll(name); 17749 }, 17750 17751 /** 17752 * Resets the attribute (or all attributes) to its initial value, as long as 17753 * the attribute is not readOnly, or writeOnce. 17754 * 17755 * @method reset 17756 * @param {String} name Optional. The name of the attribute to reset. If omitted, all attributes are reset. 17757 * @return {Object} A reference to the host object. 17758 * @chainable 17759 */ 17760 reset : function(name) { 17761 var host = this; // help compression 17762 17763 if (name) { 17764 if (host._isLazyAttr(name)) { 17765 host._addLazyAttr(name); 17766 } 17767 host.set(name, host._state.get(name, INIT_VALUE)); 17768 } else { 17769 Y.Object.each(host._state.data, function(v, n) { 17770 host.reset(n); 17771 }); 17772 } 17773 return host; 17774 }, 17775 17776 /** 17777 * Returns an object with the configuration properties (and value) 17778 * for the given attribute. If attrName is not provided, returns the 17779 * configuration properties for all attributes. 17780 * 17781 * @method _getAttrCfg 17782 * @protected 17783 * @param {String} name Optional. The attribute name. If not provided, the method will return the configuration for all attributes. 17784 * @return {Object} The configuration properties for the given attribute, or all attributes. 17785 */ 17786 _getAttrCfg : function(name) { 17787 var o, 17788 state = this._state; 17789 17790 if (name) { 17791 o = state.getAll(name) || {}; 17792 } else { 17793 o = {}; 17794 Y.each(state.data, function(v, n) { 17795 o[n] = state.getAll(n); 17796 }); 17797 } 17798 17799 return o; 17800 } 17801 }; 17802 17803 Y.AttributeExtras = AttributeExtras; 17804 17805 17806}, 'patched-v3.18.1', {"requires": ["oop"]}); 17807 17808YUI.add('base-base', function (Y, NAME) { 17809 17810 /** 17811 * The base module provides the Base class, which objects requiring attribute and custom event support can extend. 17812 * The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides 17813 * plugin support and also provides the BaseCore.build method which provides a way to build custom classes using extensions. 17814 * 17815 * @module base 17816 */ 17817 17818 /** 17819 * The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host, 17820 * and without the extension support provided by BaseCore.build. 17821 * 17822 * @module base 17823 * @submodule base-base 17824 */ 17825 17826 var AttributeCore = Y.AttributeCore, 17827 AttributeExtras = Y.AttributeExtras, 17828 BaseCore = Y.BaseCore, 17829 BaseObservable = Y.BaseObservable; 17830 17831 /** 17832 * <p> 17833 * A base class which objects requiring attributes and custom event support can 17834 * extend. Base also handles the chaining of initializer and destructor methods across
17835 * the hierarchy as part of object construction and destruction. Additionally, attributes configured 17836 * through the static <a href="#property_ATTRS">ATTRS</a> property for each class 17837 * in the hierarchy will be initialized by Base. 17838 * </p> 17839 * 17840 * <p> 17841 * **NOTE:** Prior to version 3.11.0, ATTRS would get added a class at a time. That is, 17842 * Base would loop through each class in the hierarchy, and add the class' ATTRS, and 17843 * then call it's initializer, and move on to the subclass' ATTRS and initializer. As of 17844 * 3.11.0, ATTRS from all classes in the hierarchy are added in one `addAttrs` call before 17845 * any initializers are called. This fixes subtle edge-case issues with subclass ATTRS overriding 17846 * superclass `setter`, `getter` or `valueFn` definitions and being unable to get/set attributes 17847 * defined by the subclass. This order of operation change may impact `setter`, `getter` or `valueFn` 17848 * code which expects a superclass' initializer to have run. This is expected to be rare, but to support 17849 * it, Base supports a `_preAddAttrs()`, method hook (same signature as `addAttrs`). Components can 17850 * implement this method on their prototype for edge cases which do require finer control over 17851 * the order in which attributes are added (see widget-htmlparser). 17852 * </p> 17853 * 17854 * <p> 17855 * The static <a href="#property_NAME">NAME</a> property of each class extending 17856 * from Base will be used as the identifier for the class, and is used by Base to prefix 17857 * all events fired by instances of that class. 17858 * </p> 17859 * 17860 * @class Base 17861 * @constructor 17862 * @uses BaseCore 17863 * @uses BaseObservable 17864 * @uses AttributeCore 17865 * @uses AttributeObservable 17866 * @uses AttributeExtras 17867 * @uses EventTarget 17868 * 17869 * @param {Object} config Object with configuration property name/value pairs. The object can be 17870 * used to provide default values for the objects published attributes. 17871 * 17872 * <p> 17873 * The config object can also contain the following non-attribute properties, providing a convenient 17874 * way to configure events listeners and plugins for the instance, as part of the constructor call: 17875 * </p> 17876 * 17877 * <dl> 17878 * <dt>on</dt> 17879 * <dd>An event name to listener function map, to register event listeners for the "on" moment of the event. 17880 * A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd> 17881 * <dt>after</dt> 17882 * <dd>An event name to listener function map, to register event listeners for the "after" moment of the event. 17883 * A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd> 17884 * <dt>bubbleTargets</dt> 17885 * <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance. 17886 * A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd> 17887 * <dt>plugins</dt> 17888 * <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details). 17889 * A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd> 17890 * </dl> 17891 */ 17892 function Base() { 17893 BaseCore.apply(this, arguments); 17894 BaseObservable.apply(this, arguments); 17895 AttributeExtras.apply(this, arguments); 17896 } 17897 17898 /** 17899 * The list of properties which can be configured for 17900 * each attribute (e.g. setter, getter, writeOnce, readOnly etc.) 17901 * 17902 * @property _ATTR_CFG 17903 * @type Array 17904 * @static 17905 * @private 17906 */ 17907 Base._ATTR_CFG = BaseCore._ATTR_CFG.concat(BaseObservable._ATTR_CFG); 17908 17909 /** 17910 * The array of non-attribute configuration properties supported by this class. 17911 * 17912 * `Base` supports "on", "after", "plugins" and "bubbleTargets" properties, 17913 * which are not set up as attributes. 17914 * 17915 * This property is primarily required so that when 17916 * <a href="#property__allowAdHocAttrs">`_allowAdHocAttrs`</a> is enabled by 17917 * a class, non-attribute configurations don't get added as ad-hoc attributes. 17918 * 17919 * @property _NON_ATTRS_CFG 17920 * @type Array 17921 * @static 17922 * @private 17923 */ 17924 Base._NON_ATTRS_CFG = BaseCore._NON_ATTRS_CFG.concat(BaseObservable._NON_ATTRS_CFG); 17925 17926 /** 17927 * <p> 17928 * The string to be used to identify instances of 17929 * this class, for example in prefixing events. 17930 * </p> 17931 * <p> 17932 * Classes extending Base, should define their own
17933 * static NAME property, which should be camelCase by 17934 * convention (e.g. MyClass.NAME = "myClass";). 17935 * </p> 17936 * @property NAME 17937 * @type String 17938 * @static 17939 */ 17940 Base.NAME = 'base'; 17941 17942 /** 17943 * The default set of attributes which will be available for instances of this class, and 17944 * their configuration. In addition to the configuration properties listed by 17945 * Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute 17946 * can also be configured with a "cloneDefaultValue" property, which defines how the statically 17947 * defined value field should be protected ("shallow", "deep" and false are supported values). 17948 * 17949 * By default if the value is an object literal or an array it will be "shallow" cloned, to 17950 * protect the default value. 17951 * 17952 * @property ATTRS 17953 * @type Object 17954 * @static 17955 */ 17956 Base.ATTRS = AttributeCore.protectAttrs(BaseCore.ATTRS); 17957 17958 /** 17959 Provides a way to safely modify a `Y.Base` subclass' static `ATTRS` after 17960 the class has been defined or created. 17961 17962 Base-based classes cache information about the class hierarchy in order to 17963 efficiently create instances. This cache includes includes the aggregated 17964 `ATTRS` configs. If the static `ATTRS` configs need to be modified after the 17965 class has been defined or create, then use this method which will make sure 17966 to clear any cached data before making any modifications. 17967 17968 @method modifyAttrs 17969 @param {Function} [ctor] The constructor function whose `ATTRS` should be 17970 modified. If a `ctor` function is not specified, then `this` is assumed 17971 to be the constructor which hosts the `ATTRS`. 17972 @param {Object} configs The collection of `ATTRS` configs to mix with the 17973 existing attribute configurations. 17974 @static 17975 @since 3.10.0 17976 **/ 17977 Base.modifyAttrs = BaseCore.modifyAttrs; 17978 17979 Y.mix(Base, BaseCore, false, null, 1); 17980 Y.mix(Base, AttributeExtras, false, null, 1); 17981 17982 // Needs to be `true`, to overwrite methods from `BaseCore`. 17983 Y.mix(Base, BaseObservable, true, null, 1); 17984 17985 // Fix constructor 17986 Base.prototype.constructor = Base; 17987 17988 Y.Base = Base; 17989 17990 17991}, 'patched-v3.18.1', {"requires": ["attribute-base", "base-core", "base-observable"]}); 17992 17993YUI.add('base-pluginhost', function (Y, NAME) { 17994 17995 /** 17996 * The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with 17997 * Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods. 17998 * 17999 * @module base 18000 * @submodule base-pluginhost 18001 * @for Base 18002 */ 18003 18004 var Base = Y.Base, 18005 PluginHost = Y.Plugin.Host; 18006 18007 Y.mix(Base, PluginHost, false, null, 1); 18008 18009 /** 18010 * Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased 18011 * method for argument and return value details. 18012 * 18013 * @method plug 18014 * @static 18015 */ 18016 Base.plug = PluginHost.plug; 18017 18018 /** 18019 * Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the 18020 * aliased method for argument and return value details. 18021 * 18022 * @method unplug 18023 * @static 18024 */ 18025 Base.unplug = PluginHost.unplug; 18026 18027 18028}, 'patched-v3.18.1', {"requires": ["base-base", "pluginhost"]}); 18029 18030YUI.add('classnamemanager', function (Y, NAME) { 18031 18032/** 18033* Contains a singleton (ClassNameManager) that enables easy creation and caching of 18034* prefixed class names. 18035* @module classnamemanager 18036*/ 18037 18038/** 18039 * A singleton class providing: 18040 * 18041 * <ul> 18042 * <li>Easy creation of prefixed class names</li> 18043 * <li>Caching of previously created class names for improved performance.</li> 18044 * </ul> 18045 * 18046 * @class ClassNameManager 18047 * @static 18048 */ 18049 18050// String constants 18051var CLASS_NAME_PREFIX = 'classNamePrefix', 18052 CLASS_NAME_DELIMITER = 'classNameDelimiter', 18053 CONFIG = Y.config; 18054 18055// Global config 18056 18057/** 18058 * Configuration property indicating the prefix for all CSS class names in this YUI instance. 18059 * 18060 * @property classNamePrefix 18061 * @type {String} 18062 * @default "yui" 18063 * @static 18064 */ 18065CONFIG[CLASS_NAME_PREFIX] = CONFIG[CLASS_NAME_PREFIX] || 'yui3'; 18066 18067/** 18068 * Configuration property indicating the delimiter used to compose all CSS class names in 18069 * this YUI instance. 18070 * 18071 * @property classNameDelimiter 18072 * @type {String} 18073 * @default "-" 18074 * @static 18075 */ 18076CONFIG[CLASS_NAME_DELIMITER] = CONFIG[CLASS_NAME_DELIMITER] || '-'; 18077 18078Y.ClassNameManager = function () { 18079 18080 var sPrefix = CONFIG[CLASS_NAME_PREFIX], 18081 sDelimiter = CONFIG[CLASS_NAME_DELIMITER]; 18082 18083 return { 18084 18085 /** 18086 * Returns a class name prefixed with the value of the 18087 * <code>Y.config.classNamePrefix</code> attribute + the provided strings. 18088 * Uses the <code>Y.config.classNameDelimiter</code> attribute to delimit the 18089 * provided strings. E.g. Y.ClassNameManager.getClassName('foo','bar'); // yui-foo-bar 18090 * 18091 * @method getClassName 18092 * @param {String} [classnameSection*] one or more classname sections to be joined 18093 * @param {Boolean} skipPrefix If set to true, the classname will not be prefixed with the default Y.config.classNameDelimiter value. 18094 */ 18095 getClassName: Y.cached(function () { 18096 18097 var args = Y.Array(arguments); 18098 18099 if (args[args.length-1] !== true) { 18100 args.unshift(sPrefix); 18101 } else { 18102 args.pop(); 18103 } 18104 18105 return args.join(sDelimiter); 18106 }) 18107 18108 }; 18109 18110}(); 18111 18112 18113}, 'patched-v3.18.1', {"requires": ["yui-base"]}); 18114 18115YUI.add('datatype-xml-format', function (Y, NAME) { 18116 18117/** 18118 * The Number Utility provides type-conversion and string-formatting 18119 * convenience methods for Numbers. 18120 * 18121 * @module datatype-xml 18122 * @submodule datatype-xml-format 18123 */ 18124 18125/** 18126 * XML provides a set of utility functions to operate against XML documents. 18127 * 18128 * @class XML 18129 * @static 18130 */ 18131var LANG = Y.Lang; 18132 18133Y.mix(Y.namespace("XML"), { 18134 /** 18135 * Converts data to type XMLDocument. 18136 * 18137 * @method format 18138 * @param data {XMLDocument} Data to convert. 18139 * @return {String} String. 18140 */ 18141 format: function(data) { 18142 try { 18143 if(!LANG.isUndefined(data.getXml)) { 18144 return data.getXml(); 18145 } 18146 18147 if(!LANG.isUndefined(XMLSerializer)) { 18148 return (new XMLSerializer()).serializeToString(data); 18149 } 18150 } 18151 catch(e) { 18152 if(data && data.xml) { 18153 return data.xml; 18154 } 18155 else { 18156 return (LANG.isValue(data) && data.toString) ? data.toString() : ""; 18157 } 18158 } 18159 } 18160}); 18161 18162Y.namespace("DataType"); 18163Y.DataType.XML = Y.XML; 18164 18165 18166}, 'patched-v3.18.1'); 18167 18168YUI.add('datatype-xml-parse', function (Y, NAME) { 18169 18170/** 18171 * Parse XML submodule. 18172 * 18173 * @module datatype-xml 18174 * @submodule datatype-xml-parse 18175 * @for XML 18176 */ 18177 18178Y.mix(Y.namespace("XML"), { 18179 /** 18180 * Converts data to type XMLDocument. 18181 * 18182 * @method parse 18183 * @param data {String} Data to convert. 18184 * @return {XMLDocument} XML Document. 18185 */ 18186 parse: function(data) { 18187 var xmlDoc = null, win; 18188 if (typeof data === "string") { 18189 win = Y.config.win; 18190 if (win.ActiveXObject !== undefined) { 18191 xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 18192 xmlDoc.async = false;
18193 xmlDoc.loadXML(data); 18194 } else if (win.DOMParser !== undefined) { 18195 xmlDoc = new DOMParser().parseFromString(data, "text/xml"); 18196 } else if (win.Windows !== undefined) { 18197 xmlDoc = new Windows.Data.Xml.Dom.XmlDocument(); 18198 xmlDoc.loadXml(data); 18199 } 18200 } 18201 18202 if (xmlDoc === null || xmlDoc.documentElement === null || xmlDoc.documentElement.nodeName === "parsererror") { 18203 } 18204 18205 return xmlDoc; 18206 } 18207}); 18208 18209// Add Parsers shortcut 18210Y.namespace("Parsers").xml = Y.XML.parse; 18211 18212Y.namespace("DataType"); 18213Y.DataType.XML = Y.XML; 18214 18215 18216}, 'patched-v3.18.1'); 18217 18218YUI.add('dom-base', function (Y, NAME) { 18219 18220/** 18221* @for DOM 18222* @module dom 18223*/ 18224var documentElement = Y.config.doc.documentElement, 18225 Y_DOM = Y.DOM, 18226 TAG_NAME = 'tagName', 18227 OWNER_DOCUMENT = 'ownerDocument', 18228 EMPTY_STRING = '', 18229 addFeature = Y.Features.add, 18230 testFeature = Y.Features.test; 18231 18232Y.mix(Y_DOM, { 18233 /** 18234 * Returns the text content of the HTMLElement. 18235 * @method getText 18236 * @param {HTMLElement} element The html element. 18237 * @return {String} The text content of the element (includes text of any descending elements). 18238 */ 18239 getText: (documentElement.textContent !== undefined) ? 18240 function(element) { 18241 var ret = ''; 18242 if (element) { 18243 ret = element.textContent; 18244 } 18245 return ret || ''; 18246 } : function(element) { 18247 var ret = ''; 18248 if (element) { 18249 ret = element.innerText || element.nodeValue; // might be a textNode 18250 } 18251 return ret || ''; 18252 }, 18253 18254 /** 18255 * Sets the text content of the HTMLElement. 18256 * @method setText 18257 * @param {HTMLElement} element The html element. 18258 * @param {String} content The content to add. 18259 */ 18260 setText: (documentElement.textContent !== undefined) ? 18261 function(element, content) { 18262 if (element) { 18263 element.textContent = content; 18264 } 18265 } : function(element, content) { 18266 if ('innerText' in element) { 18267 element.innerText = content; 18268 } else if ('nodeValue' in element) { 18269 element.nodeValue = content; 18270 } 18271 }, 18272 18273 CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8 18274 'for': 'htmlFor', 18275 'class': 'className' 18276 } : { // w3c 18277 'htmlFor': 'for', 18278 'className': 'class' 18279 }, 18280 18281 /** 18282 * Provides a normalized attribute interface. 18283 * @method setAttribute 18284 * @param {HTMLElement} el The target element for the attribute. 18285 * @param {String} attr The attribute to set. 18286 * @param {String} val The value of the attribute. 18287 */ 18288 setAttribute: function(el, attr, val, ieAttr) { 18289 if (el && attr && el.setAttribute) { 18290 attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr; 18291 el.setAttribute(attr, val, ieAttr); 18292 } 18293 }, 18294 18295 18296 /** 18297 * Provides a normalized attribute interface. 18298 * @method getAttribute 18299 * @param {HTMLElement} el The target element for the attribute. 18300 * @param {String} attr The attribute to get. 18301 * @return {String} The current value of the attribute. 18302 */ 18303 getAttribute: function(el, attr, ieAttr) { 18304 ieAttr = (ieAttr !== undefined) ? ieAttr : 2; 18305 var ret = ''; 18306 if (el && attr && el.getAttribute) { 18307 attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr; 18308 // BUTTON value issue for IE < 8 18309 ret = (el.tagName === "BUTTON" && attr === 'value') ? Y_DOM.getValue(el) : el.getAttribute(attr, ieAttr); 18310 18311 if (ret === null) { 18312 ret = ''; // per DOM spec 18313 } 18314 } 18315 return ret; 18316 }, 18317 18318 VALUE_SETTERS: {}, 18319 18320 VALUE_GETTERS: {}, 18321 18322 getValue: function(node) { 18323 var ret = '', // TODO: return null? 18324 getter; 18325 18326 if (node && node[TAG_NAME]) { 18327 getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()]; 18328 18329 if (getter) { 18330 ret = getter(node); 18331 } else { 18332 ret = node.value; 18333 } 18334 } 18335 18336 // workaround for IE8 JSON stringify bug 18337 // which converts empty string values to null 18338 if (ret === EMPTY_STRING) { 18339 ret = EMPTY_STRING; // for real 18340 } 18341 18342 return (typeof ret === 'string') ? ret : ''; 18343 }, 18344 18345 setValue: function(node, val) { 18346 var setter; 18347 18348 if (node && node[TAG_NAME]) { 18349 setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()]; 18350 val = (val === null) ? '' : val; 18351 if (setter) { 18352 setter(node, val); 18353 } else { 18354 node.value = val; 18355 } 18356 } 18357 }, 18358 18359 creators: {} 18360}); 18361 18362addFeature('value-set', 'select', { 18363 test: function() { 18364 var node = Y.config.doc.createElement('select'); 18365 node.innerHTML = '<option>1</option><option>2</option>'; 18366 node.value = '2'; 18367 return (node.value && node.value === '2'); 18368 } 18369}); 18370
18371if (!testFeature('value-set', 'select')) { 18372 Y_DOM.VALUE_SETTERS.select = function(node, val) { 18373 for (var i = 0, options = node.getElementsByTagName('option'), option; 18374 option = options[i++];) { 18375 if (Y_DOM.getValue(option) === val) { 18376 option.selected = true; 18377 //Y_DOM.setAttribute(option, 'selected', 'selected'); 18378 break; 18379 } 18380 } 18381 }; 18382} 18383 18384Y.mix(Y_DOM.VALUE_GETTERS, { 18385 button: function(node) { 18386 return (node.attributes && node.attributes.value) ? node.attributes.value.value : ''; 18387 } 18388}); 18389 18390Y.mix(Y_DOM.VALUE_SETTERS, { 18391 // IE: node.value changes the button text, which should be handled via innerHTML 18392 button: function(node, val) { 18393 var attr = node.attributes.value; 18394 if (!attr) { 18395 attr = node[OWNER_DOCUMENT].createAttribute('value'); 18396 node.setAttributeNode(attr); 18397 } 18398 18399 attr.value = val; 18400 } 18401}); 18402 18403 18404Y.mix(Y_DOM.VALUE_GETTERS, { 18405 option: function(node) { 18406 var attrs = node.attributes; 18407 return (attrs.value && attrs.value.specified) ? node.value : node.text; 18408 }, 18409 18410 select: function(node) { 18411 var val = node.value, 18412 options = node.options; 18413 18414 if (options && options.length) { 18415 // TODO: implement multipe select 18416 if (node.multiple) { 18417 } else if (node.selectedIndex > -1) { 18418 val = Y_DOM.getValue(options[node.selectedIndex]); 18419 } 18420 } 18421 18422 return val; 18423 } 18424}); 18425var addClass, hasClass, removeClass; 18426 18427Y.mix(Y.DOM, { 18428 /** 18429 * Determines whether a DOM element has the given className. 18430 * @method hasClass 18431 * @for DOM 18432 * @param {HTMLElement} element The DOM element. 18433 * @param {String} className the class name to search for 18434 * @return {Boolean} Whether or not the element has the given class. 18435 */ 18436 hasClass: function(node, className) { 18437 var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)'); 18438 return re.test(node.className); 18439 }, 18440 18441 /** 18442 * Adds a class name to a given DOM element. 18443 * @method addClass 18444 * @for DOM 18445 * @param {HTMLElement} element The DOM element. 18446 * @param {String} className the class name to add to the class attribute 18447 */ 18448 addClass: function(node, className) { 18449 if (!Y.DOM.hasClass(node, className)) { // skip if already present 18450 node.className = Y.Lang.trim([node.className, className].join(' ')); 18451 } 18452 }, 18453 18454 /** 18455 * Removes a class name from a given element. 18456 * @method removeClass 18457 * @for DOM 18458 * @param {HTMLElement} element The DOM element. 18459 * @param {String} className the class name to remove from the class attribute 18460 */ 18461 removeClass: function(node, className) { 18462 if (className && hasClass(node, className)) { 18463 node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' + 18464 className + '(?:\\s+|$)'), ' ')); 18465 18466 if ( hasClass(node, className) ) { // in case of multiple adjacent 18467 removeClass(node, className); 18468 } 18469 } 18470 }, 18471 18472 /** 18473 * Replace a class with another class for a given element. 18474 * If no oldClassName is present, the newClassName is simply added. 18475 * @method replaceClass 18476 * @for DOM 18477 * @param {HTMLElement} element The DOM element 18478 * @param {String} oldClassName the class name to be replaced 18479 * @param {String} newClassName the class name that will be replacing the old class name 18480 */ 18481 replaceClass: function(node, oldC, newC) { 18482 removeClass(node, oldC); // remove first in case oldC === newC 18483 addClass(node, newC); 18484 }, 18485 18486 /** 18487 * If the className exists on the node it is removed, if it doesn't exist it is added. 18488 * @method toggleClass 18489 * @for DOM 18490 * @param {HTMLElement} element The DOM element 18491 * @param {String} className the class name to be toggled 18492 * @param {Boolean} addClass optional boolean to indicate whether class 18493 * should be added or removed regardless of current state 18494 */ 18495 toggleClass: function(node, className, force) { 18496 var add = (force !== undefined) ? force : 18497 !(hasClass(node, className)); 18498 18499 if (add) { 18500 addClass(node, className); 18501 } else { 18502 removeClass(node, className); 18503 } 18504 } 18505}); 18506 18507hasClass = Y.DOM.hasClass; 18508removeClass = Y.DOM.removeClass; 18509addClass = Y.DOM.addClass; 18510 18511var re_tag = /<([a-z]+)/i, 18512 18513 Y_DOM = Y.DOM, 18514 18515 addFeature = Y.Features.add, 18516 testFeature = Y.Features.test, 18517 18518 creators = {}, 18519 18520 createFromDIV = function(html, tag) { 18521 var div = Y.config.doc.createElement('div'), 18522 ret = true; 18523 18524 div.innerHTML = html; 18525 if (!div.firstChild || div.firstChild.tagName !== tag.toUpperCase()) { 18526 ret = false;
18527 } 18528 18529 return ret; 18530 }, 18531 18532 re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/, 18533 18534 TABLE_OPEN = '<table>', 18535 TABLE_CLOSE = '</table>', 18536 18537 selectedIndex; 18538 18539Y.mix(Y.DOM, { 18540 _fragClones: {}, 18541 18542 _create: function(html, doc, tag) { 18543 tag = tag || 'div'; 18544 18545 var frag = Y_DOM._fragClones[tag]; 18546 if (frag) { 18547 frag = frag.cloneNode(false); 18548 } else { 18549 frag = Y_DOM._fragClones[tag] = doc.createElement(tag); 18550 } 18551 frag.innerHTML = html; 18552 return frag; 18553 }, 18554 18555 _children: function(node, tag) { 18556 var i = 0, 18557 children = node.children, 18558 childNodes, 18559 hasComments, 18560 child; 18561 18562 if (children && children.tags) { // use tags filter when possible 18563 if (tag) { 18564 children = node.children.tags(tag); 18565 } else { // IE leaks comments into children 18566 hasComments = children.tags('!').length; 18567 } 18568 } 18569 18570 if (!children || (!children.tags && tag) || hasComments) { 18571 childNodes = children || node.childNodes; 18572 children = []; 18573 while ((child = childNodes[i++])) { 18574 if (child.nodeType === 1) { 18575 if (!tag || tag === child.tagName) { 18576 children.push(child); 18577 } 18578 } 18579 } 18580 } 18581 18582 return children || []; 18583 }, 18584 18585 /** 18586 * Creates a new dom node using the provided markup string. 18587 * @method create 18588 * @param {String} html The markup used to create the element 18589 * @param {HTMLDocument} doc An optional document context 18590 * @return {HTMLElement|DocumentFragment} returns a single HTMLElement 18591 * when creating one node, and a documentFragment when creating 18592 * multiple nodes. 18593 */ 18594 create: function(html, doc) { 18595 if (typeof html === 'string') { 18596 html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML 18597 18598 } 18599 18600 doc = doc || Y.config.doc; 18601 var m = re_tag.exec(html), 18602 create = Y_DOM._create, 18603 custom = creators, 18604 ret = null, 18605 creator, tag, node, nodes; 18606 18607 if (html != undefined) { // not undefined or null 18608 if (m && m[1]) { 18609 creator = custom[m[1].toLowerCase()]; 18610 if (typeof creator === 'function') { 18611 create = creator; 18612 } else { 18613 tag = creator; 18614 } 18615 } 18616 18617 node = create(html, doc, tag); 18618 nodes = node.childNodes; 18619 18620 if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment" 18621 ret = node.removeChild(nodes[0]); 18622 } else if (nodes[0] && nodes[0].className === 'yui3-big-dummy') { // using dummy node to preserve some attributes (e.g. OPTION not selected) 18623 selectedIndex = node.selectedIndex; 18624 18625 if (nodes.length === 2) { 18626 ret = nodes[0].nextSibling; 18627 } else { 18628 node.removeChild(nodes[0]); 18629 ret = Y_DOM._nl2frag(nodes, doc); 18630 } 18631 } else { // return multiple nodes as a fragment 18632 ret = Y_DOM._nl2frag(nodes, doc); 18633 } 18634 18635 } 18636 18637 return ret; 18638 }, 18639 18640 _nl2frag: function(nodes, doc) { 18641 var ret = null, 18642 i, len; 18643 18644 if (nodes && (nodes.push || nodes.item) && nodes[0]) { 18645 doc = doc || nodes[0].ownerDocument; 18646 ret = doc.createDocumentFragment(); 18647 18648 if (nodes.item) { // convert live list to static array 18649 nodes = Y.Array(nodes, 0, true); 18650 } 18651 18652 for (i = 0, len = nodes.length; i < len; i++) { 18653 ret.appendChild(nodes[i]); 18654 } 18655 } // else inline with log for minification 18656 return ret; 18657 }, 18658 18659 /** 18660 * Inserts content in a node at the given location 18661 * @method addHTML 18662 * @param {HTMLElement} node The node to insert into 18663 * @param {HTMLElement | Array | HTMLCollection} content The content to be inserted 18664 * @param {HTMLElement} where Where to insert the content 18665 * If no "where" is given, content is appended to the node 18666 * Possible values for "where" 18667 * <dl> 18668 * <dt>HTMLElement</dt> 18669 * <dd>The element to insert before</dd> 18670 * <dt>"replace"</dt> 18671 * <dd>Replaces the existing HTML</dd> 18672 * <dt>"before"</dt> 18673 * <dd>Inserts before the existing HTML</dd> 18674 * <dt>"before"</dt> 18675 * <dd>Inserts content before the node</dd> 18676 * <dt>"after"</dt> 18677 * <dd>Inserts content after the node</dd> 18678 * </dl> 18679 */ 18680 addHTML: function(node, content, where) { 18681 var nodeParent = node.parentNode, 18682 i = 0, 18683 item, 18684 ret = content, 18685 newNode; 18686 18687 18688 if (content != undefined) { // not null or undefined (maybe 0) 18689 if (content.nodeType) { // DOM node, just add it 18690 newNode = content; 18691 } else if (typeof content == 'string' || typeof content == 'number') { 18692 ret = newNode = Y_DOM.create(content); 18693 } else if (content[0] && content[0].nodeType) { // array or collection 18694 newNode = Y.config.doc.createDocumentFragment(); 18695 while ((item = content[i++])) { 18696 newNode.appendChild(item); // append to fragment for insertion 18697 } 18698 } 18699 } 18700 18701 if (where) { 18702 if (newNode && where.parentNode) { // insert regardless of relationship to node 18703 where.parentNode.insertBefore(newNode, where); 18704 } else { 18705 switch (where) { 18706 case 'replace': 18707 while (node.firstChild) { 18708 node.removeChild(node.firstChild); 18709 } 18710 if (newNode) { // allow empty content to clear node 18711 node.appendChild(newNode); 18712 } 18713 break; 18714 case 'before': 18715 if (newNode) { 18716 nodeParent.insertBefore(newNode, node); 18717 } 18718 break; 18719 case 'after': 18720 if (newNode) { 18721 if (node.nextSibling) { // IE errors if refNo
18721de is null 18722 nodeParent.insertBefore(newNode, node.nextSibling); 18723 } else { 18724 nodeParent.appendChild(newNode); 18725 } 18726 } 18727 break; 18728 default: 18729 if (newNode) { 18730 node.appendChild(newNode); 18731 } 18732 } 18733 } 18734 } else if (newNode) { 18735 node.appendChild(newNode); 18736 } 18737 18738 // `select` elements are the only elements with `selectedIndex`. 18739 // Don't grab the dummy `option` element's `selectedIndex`. 18740 if (node.nodeName == "SELECT" && selectedIndex > 0) { 18741 node.selectedIndex = selectedIndex - 1; 18742 } 18743 18744 return ret; 18745 }, 18746 18747 wrap: function(node, html) { 18748 var parent = (html && html.nodeType) ? html : Y.DOM.create(html), 18749 nodes = parent.getElementsByTagName('*'); 18750 18751 if (nodes.length) { 18752 parent = nodes[nodes.length - 1]; 18753 } 18754 18755 if (node.parentNode) { 18756 node.parentNode.replaceChild(parent, node); 18757 } 18758 parent.appendChild(node); 18759 }, 18760 18761 unwrap: function(node) { 18762 var parent = node.parentNode, 18763 lastChild = parent.lastChild, 18764 next = node, 18765 grandparent; 18766 18767 if (parent) { 18768 grandparent = parent.parentNode; 18769 if (grandparent) { 18770 node = parent.firstChild; 18771 while (node !== lastChild) { 18772 next = node.nextSibling; 18773 grandparent.insertBefore(node, parent); 18774 node = next; 18775 } 18776 grandparent.replaceChild(lastChild, parent); 18777 } else { 18778 parent.removeChild(node); 18779 } 18780 } 18781 } 18782}); 18783 18784addFeature('innerhtml', 'table', { 18785 test: function() { 18786 var node = Y.config.doc.createElement('table'); 18787 try { 18788 node.innerHTML = '<tbody></tbody>'; 18789 } catch(e) { 18790 return false; 18791 } 18792 return (node.firstChild && node.firstChild.nodeName === 'TBODY'); 18793 } 18794}); 18795 18796addFeature('innerhtml-div', 'tr', { 18797 test: function() { 18798 return createFromDIV('<tr></tr>', 'tr'); 18799 } 18800}); 18801 18802addFeature('innerhtml-div', 'script', { 18803 test: function() { 18804 return createFromDIV('<script></script>', 'script'); 18805 } 18806}); 18807 18808if (!testFeature('innerhtml', 'table')) { 18809 // TODO: thead/tfoot with nested tbody 18810 // IE adds TBODY when creating TABLE elements (which may share this impl) 18811 creators.tbody = function(html, doc) { 18812 var frag = Y_DOM.create(TABLE_OPEN + html + TABLE_CLOSE, doc), 18813 tb = Y.DOM._children(frag, 'tbody')[0]; 18814 18815 if (frag.children.length > 1 && tb && !re_tbody.test(html)) { 18816 tb.parentNode.removeChild(tb); // strip extraneous tbody 18817 } 18818 return frag; 18819 }; 18820} 18821 18822if (!testFeature('innerhtml-div', 'script')) { 18823 creators.script = function(html, doc) { 18824 var frag = doc.createElement('div'); 18825 18826 frag.innerHTML = '-' + html; 18827 frag.removeChild(frag.firstChild); 18828 return frag; 18829 }; 18830 18831 creators.link = creators.style = creators.script; 18832} 18833 18834if (!testFeature('innerhtml-div', 'tr')) { 18835 Y.mix(creators, { 18836 option: function(html, doc) { 18837 return Y_DOM.create('<select><option class="yui3-big-dummy" selected></option>' + html + '</select>', doc); 18838 }, 18839 18840 tr: function(html, doc) { 18841 return Y_DOM.create('<tbody>' + html + '</tbody>', doc); 18842 }, 18843 18844 td: function(html, doc) { 18845 return Y_DOM.create('<tr>' + html + '</tr>', doc); 18846 }, 18847 18848 col: function(html, doc) { 18849 return Y_DOM.create('<colgroup>' + html + '</colgroup>', doc); 18850 }, 18851 18852 tbody: 'table' 18853 }); 18854 18855 Y.mix(creators, { 18856 legend: 'fieldset', 18857 th: creators.td, 18858 thead: creators.tbody, 18859 tfoot: creators.tbody, 18860 caption: creators.tbody, 18861 colgroup: creators.tbody, 18862 optgroup: creators.option 18863 }); 18864} 18865 18866Y_DOM.creators = creators; 18867Y.mix(Y.DOM, { 18868 /** 18869 * Sets the width of the element to the given size, regardless 18870 * of box model, border, padding, etc. 18871 * @method setWidth 18872 * @param {HTMLElement} element The DOM element. 18873 * @param {String|Number} size The pixel height to size to 18874 */ 18875 18876 setWidth: function(node, size) { 18877 Y.DOM._setSize(node, 'width', size); 18878 }, 18879 18880 /** 18881 * Sets the height of the element to the given size, regardless 18882 * of box model, border, padding, etc. 18883 * @method setHeight 18884 * @param {HTMLElement} element The DOM element. 18885 * @param {String|Number} size The pixel height to size to 18886 */ 18887 18888 setHeight: function(node, size) { 18889 Y.DOM._setSize(node, 'height', size); 18890 }, 18891 18892 _setSize: function(node, prop, val) { 18893 val = (val > 0) ? val : 0; 18894 var size = 0; 18895 18896 node.style[prop] = val + 'px'; 18897 size = (prop === 'height') ? node.offsetHeight : node.offsetWidth; 18898 18899 if (size > val) { 18900 val = val - (size - val); 18901 18902 if (val < 0) { 18903 val = 0; 18904 } 18905 18906 node.style[prop] = val + 'px'; 18907 } 18908 } 18909}); 18910 18911 18912}, 'patched-v3.18.1', {"requires": ["dom-core"]}); 18913 18914YUI.add('dom-core', function (Y, NAME) { 18915 18916var NODE_TYPE = 'nodeType', 18917 OWNER_DOCUMENT = 'ownerDocument', 18918 DOCUMENT_ELEMENT = 'documentElement', 18919 DEFAULT_VIEW = 'defaultView', 18920 PARENT_WINDOW = 'parentWindow', 18921 TAG_NAME = 'tagName', 18922 PARENT_NODE = 'parentNode', 18923 PREVIOUS_SIBLING = 'previousSibling', 18924 NEXT_SIBLING = 'nextSibling', 18925 CONTAINS = 'contains', 18926 COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition', 18927 EMPTY_ARRAY = [], 18928 18929 // IE < 8 throws on node.contains(textNode) 18930 supportsContainsTextNode = (function() { 18931 var node = Y.config.doc.createElement('div'), 18932 textNode = node.appendChild(Y.config.doc.createTextNode('')), 18933 result = false;
18934 18935 try { 18936 result = node.contains(textNode); 18937 } catch(e) {} 18938 18939 return result; 18940 })(), 18941 18942/** 18943 * The DOM utility provides a cross-browser abtraction layer 18944 * normalizing DOM tasks, and adds extra helper functionality 18945 * for other common tasks. 18946 * @module dom 18947 * @main dom 18948 * @submodule dom-base 18949 * @for DOM 18950 * 18951 */ 18952 18953/** 18954 * Provides DOM helper methods. 18955 * @class DOM 18956 * 18957 */ 18958 18959Y_DOM = { 18960 /** 18961 * Returns the HTMLElement with the given ID (Wrapper for document.getElementById). 18962 * @method byId 18963 * @param {String} id the id attribute 18964 * @param {Object} doc optional The document to search. Defaults to current document 18965 * @return {HTMLElement | null} The HTMLElement with the id, or null if none found. 18966 */ 18967 byId: function(id, doc) { 18968 // handle dupe IDs and IE name collision 18969 return Y_DOM.allById(id, doc)[0] || null; 18970 }, 18971 18972 getId: function(node) { 18973 var id; 18974 // HTMLElement returned from FORM when INPUT name === "id" 18975 // IE < 8: HTMLCollection returned when INPUT id === "id" 18976 // via both getAttribute and form.id 18977 if (node.id && !node.id.tagName && !node.id.item) { 18978 id = node.id; 18979 } else if (node.attributes && node.attributes.id) { 18980 id = node.attributes.id.value; 18981 } 18982 18983 return id; 18984 }, 18985 18986 setId: function(node, id) { 18987 if (node.setAttribute) { 18988 node.setAttribute('id', id); 18989 } else { 18990 node.id = id; 18991 } 18992 }, 18993 18994 /* 18995 * Finds the ancestor of the element. 18996 * @method ancestor 18997 * @param {HTMLElement} element The html element. 18998 * @param {Function} fn optional An optional boolean test to apply. 18999 * The optional function is passed the current DOM node being tested as its only argument. 19000 * If no function is given, the parentNode is returned. 19001 * @param {Boolean} testSelf optional Whether or not to include the element in the scan 19002 * @return {HTMLElement | null} The matching DOM node or null if none found. 19003 */ 19004 ancestor: function(element, fn, testSelf, stopFn) { 19005 var ret = null; 19006 if (testSelf) { 19007 ret = (!fn || fn(element)) ? element : null; 19008 19009 } 19010 return ret || Y_DOM.elementByAxis(element, PARENT_NODE, fn, null, stopFn); 19011 }, 19012 19013 /* 19014 * Finds the ancestors of the element. 19015 * @method ancestors 19016 * @param {HTMLElement} element The html element. 19017 * @param {Function} fn optional An optional boolean test to apply. 19018 * The optional function is passed the current DOM node being tested as its only argument. 19019 * If no function is given, all ancestors are returned. 19020 * @param {Boolean} testSelf optional Whether or not to include the element in the scan 19021 * @return {Array} An array containing all matching DOM nodes. 19022 */ 19023 ancestors: function(element, fn, testSelf, stopFn) { 19024 var ancestor = element, 19025 ret = []; 19026 19027 while ((ancestor = Y_DOM.ancestor(ancestor, fn, testSelf, stopFn))) { 19028 testSelf = false; 19029 if (ancestor) { 19030 ret.unshift(ancestor); 19031 19032 if (stopFn && stopFn(ancestor)) { 19033 return ret; 19034 } 19035 } 19036 } 19037 19038 return ret; 19039 }, 19040 19041 /** 19042 * Searches the element by the given axis for the first matching element. 19043 * @method elementByAxis 19044 * @param {HTMLElement} element The html element. 19045 * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling). 19046 * @param {Function} [fn] An optional boolean test to apply. 19047 * @param {Boolean} [all] Whether text nodes as well as element nodes should be returned, or 19048 * just element nodes will be returned(default) 19049 * The optional function is passed the current HTMLElement being tested as its only argument. 19050 * If no function is given, the first element is returned. 19051 * @return {HTMLElement | null} The matching element or null if none found. 19052 */ 19053 elementByAxis: function(element, axis, fn, all, stopAt) { 19054 while (element && (element = element[axis])) { // NOTE: assignment 19055 if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) { 19056 return element; 19057 } 19058 19059 if (stopAt && stopAt(element)) { 19060 return null; 19061 } 19062 } 19063 return null; 19064 }, 19065 19066 /** 19067 * Determines whether or not one HTMLElement is or contains another HTMLElement. 19068 * @method contains 19069 * @param {HTMLElement} element The containing html element. 19070 * @param {HTMLElement} needle The html element that may be contained. 19071 * @return {Boolean} Whether or not the element is or contains the needle. 19072 */ 19073 contains: function(element, needle) { 19074 var ret = false;
19075 19076 if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) { 19077 ret = false; 19078 } else if (element[CONTAINS] && 19079 // IE < 8 throws on node.contains(textNode) so fall back to brute. 19080 // Falling back for other nodeTypes as well. 19081 (needle[NODE_TYPE] === 1 || supportsContainsTextNode)) { 19082 ret = element[CONTAINS](needle); 19083 } else if (element[COMPARE_DOCUMENT_POSITION]) { 19084 // Match contains behavior (node.contains(node) === true). 19085 // Needed for Firefox < 4. 19086 if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) { 19087 ret = true; 19088 } 19089 } else { 19090 ret = Y_DOM._bruteContains(element, needle); 19091 } 19092 19093 return ret; 19094 }, 19095 19096 /** 19097 * Determines whether or not the HTMLElement is part of the document. 19098 * @method inDoc 19099 * @param {HTMLElement} element The containing html element. 19100 * @param {HTMLElement} doc optional The document to check. 19101 * @return {Boolean} Whether or not the element is attached to the document. 19102 */ 19103 inDoc: function(element, doc) { 19104 var ret = false, 19105 rootNode; 19106 19107 if (element && element.nodeType) { 19108 (doc) || (doc = element[OWNER_DOCUMENT]); 19109 19110 rootNode = doc[DOCUMENT_ELEMENT]; 19111 19112 // contains only works with HTML_ELEMENT 19113 if (rootNode && rootNode.contains && element.tagName) { 19114 ret = rootNode.contains(element); 19115 } else { 19116 ret = Y_DOM.contains(rootNode, element); 19117 } 19118 } 19119 19120 return ret; 19121 19122 }, 19123 19124 allById: function(id, root) { 19125 root = root || Y.config.doc; 19126 var nodes = [], 19127 ret = [], 19128 i, 19129 node; 19130 19131 if (root.querySelectorAll) { 19132 ret = root.querySelectorAll('[id="' + id + '"]'); 19133 } else if (root.all) { 19134 nodes = root.all(id); 19135 19136 if (nodes) { 19137 // root.all may return HTMLElement or HTMLCollection. 19138 // some elements are also HTMLCollection (FORM, SELECT). 19139 if (nodes.nodeName) { 19140 if (nodes.id === id) { // avoid false positive on name 19141 ret.push(nodes); 19142 nodes = EMPTY_ARRAY; // done, no need to filter 19143 } else { // prep for filtering 19144 nodes = [nodes]; 19145 } 19146 } 19147 19148 if (nodes.length) { 19149 // filter out matches on node.name 19150 // and element.id as reference to element with id === 'id' 19151 for (i = 0; node = nodes[i++];) { 19152 if (node.id === id || 19153 (node.attributes && node.attributes.id && 19154 node.attributes.id.value === id)) { 19155 ret.push(node); 19156 } 19157 } 19158 } 19159 } 19160 } else { 19161 ret = [Y_DOM._getDoc(root).getElementById(id)]; 19162 } 19163 19164 return ret; 19165 }, 19166 19167 19168 isWindow: function(obj) { 19169 return !!(obj && obj.scrollTo && obj.document); 19170 }, 19171 19172 _removeChildNodes: function(node) { 19173 while (node.firstChild) { 19174 node.removeChild(node.firstChild); 19175 } 19176 }, 19177 19178 siblings: function(node, fn) { 19179 var nodes = [], 19180 sibling = node; 19181 19182 while ((sibling = sibling[PREVIOUS_SIBLING])) { 19183 if (sibling[TAG_NAME] && (!fn || fn(sibling))) { 19184 nodes.unshift(sibling); 19185 } 19186 } 19187 19188 sibling = node; 19189 while ((sibling = sibling[NEXT_SIBLING])) { 19190 if (sibling[TAG_NAME] && (!fn || fn(sibling))) { 19191 nodes.push(sibling); 19192 } 19193 } 19194 19195 return nodes; 19196 }, 19197 19198 /** 19199 * Brute force version of contains. 19200 * Used for browsers without contains support for non-HTMLElement Nodes (textNodes, etc). 19201 * @method _bruteContains 19202 * @private 19203 * @param {HTMLElement} element The containing html element. 19204 * @param {HTMLElement} needle The html element that may be contained. 19205 * @return {Boolean} Whether or not the element is or contains the needle. 19206 */ 19207 _bruteContains: function(element, needle) { 19208 while (needle) { 19209 if (element === needle) { 19210 return true; 19211 } 19212 needle = needle.parentNode; 19213 } 19214 return false;
19215 }, 19216 19217// TODO: move to Lang? 19218 /** 19219 * Memoizes dynamic regular expressions to boost runtime performance. 19220 * @method _getRegExp 19221 * @private 19222 * @param {String} str The string to convert to a regular expression. 19223 * @param {String} flags optional An optinal string of flags. 19224 * @return {RegExp} An instance of RegExp 19225 */ 19226 _getRegExp: function(str, flags) { 19227 flags = flags || ''; 19228 Y_DOM._regexCache = Y_DOM._regexCache || {}; 19229 if (!Y_DOM._regexCache[str + flags]) { 19230 Y_DOM._regexCache[str + flags] = new RegExp(str, flags); 19231 } 19232 return Y_DOM._regexCache[str + flags]; 19233 }, 19234 19235// TODO: make getDoc/Win true privates? 19236 /** 19237 * returns the appropriate document. 19238 * @method _getDoc 19239 * @private 19240 * @param {HTMLElement} element optional Target element. 19241 * @return {Object} The document for the given element or the default document. 19242 */ 19243 _getDoc: function(element) { 19244 var doc = Y.config.doc; 19245 if (element) { 19246 doc = (element[NODE_TYPE] === 9) ? element : // element === document 19247 element[OWNER_DOCUMENT] || // element === DOM node 19248 element.document || // element === window 19249 Y.config.doc; // default 19250 } 19251 19252 return doc; 19253 }, 19254 19255 /** 19256 * returns the appropriate window. 19257 * @method _getWin 19258 * @private 19259 * @param {HTMLElement} element optional Target element. 19260 * @return {Object} The window for the given element or the default window. 19261 */ 19262 _getWin: function(element) { 19263 var doc = Y_DOM._getDoc(element); 19264 return doc[DEFAULT_VIEW] || doc[PARENT_WINDOW] || Y.config.win; 19265 }, 19266 19267 _batch: function(nodes, fn, arg1, arg2, arg3, etc) { 19268 fn = (typeof fn === 'string') ? Y_DOM[fn] : fn; 19269 var result, 19270 i = 0, 19271 node, 19272 ret; 19273 19274 if (fn && nodes) { 19275 while ((node = nodes[i++])) { 19276 result = result = fn.call(Y_DOM, node, arg1, arg2, arg3, etc); 19277 if (typeof result !== 'undefined') { 19278 (ret) || (ret = []); 19279 ret.push(result); 19280 } 19281 } 19282 } 19283 19284 return (typeof ret !== 'undefined') ? ret : nodes; 19285 }, 19286 19287 generateID: function(el) { 19288 var id = el.id; 19289 19290 if (!id) { 19291 id = Y.stamp(el); 19292 el.id = id; 19293 } 19294 19295 return id; 19296 } 19297}; 19298 19299 19300Y.DOM = Y_DOM; 19301 19302 19303}, 'patched-v3.18.1', {"requires": ["oop", "features"]}); 19304 19305YUI.add('dom-screen', function (Y, NAME) { 19306 19307(function(Y) { 19308 19309/** 19310 * Adds position and region management functionality to DOM. 19311 * @module dom 19312 * @submodule dom-screen 19313 * @for DOM 19314 */ 19315 19316var DOCUMENT_ELEMENT = 'documentElement', 19317 COMPAT_MODE = 'compatMode', 19318 POSITION = 'position', 19319 FIXED = 'fixed', 19320 RELATIVE = 'relative', 19321 LEFT = 'left', 19322 TOP = 'top', 19323 _BACK_COMPAT = 'BackCompat', 19324 MEDIUM = 'medium', 19325 BORDER_LEFT_WIDTH = 'borderLeftWidth', 19326 BORDER_TOP_WIDTH = 'borderTopWidth', 19327 GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect', 19328 GET_COMPUTED_STYLE = 'getComputedStyle', 19329 19330 Y_DOM = Y.DOM, 19331 19332 // TODO: how about thead/tbody/tfoot/tr? 19333 // TODO: does caption matter? 19334 RE_TABLE = /^t(?:able|d|h)$/i, 19335 19336 SCROLL_NODE; 19337 19338if (Y.UA.ie) { 19339 if (Y.config.doc[COMPAT_MODE] !== 'BackCompat') { 19340 SCROLL_NODE = DOCUMENT_ELEMENT; 19341 } else { 19342 SCROLL_NODE = 'body'; 19343 } 19344} 19345 19346Y.mix(Y_DOM, { 19347 /** 19348 * Returns the inner height of the viewport (exludes scrollbar). 19349 * @method winHeight 19350 * @return {Number} The current height of the viewport. 19351 */ 19352 winHeight: function(node) { 19353 var h = Y_DOM._getWinSize(node).height; 19354 return h; 19355 }, 19356 19357 /** 19358 * Returns the inner width of the viewport (exludes scrollbar). 19359 * @method winWidth 19360 * @return {Number} The current width of the viewport. 19361 */ 19362 winWidth: function(node) { 19363 var w = Y_DOM._getWinSize(node).width; 19364 return w; 19365 }, 19366 19367 /** 19368 * Document height 19369 * @method docHeight 19370 * @return {Number} The current height of the document. 19371 */ 19372 docHeight: function(node) { 19373 var h = Y_DOM._getDocSize(node).height; 19374 return Math.max(h, Y_DOM._getWinSize(node).height); 19375 }, 19376 19377 /** 19378 * Document width 19379 * @method docWidth 19380 * @return {Number} The current width of the document. 19381 */ 19382 docWidth: function(node) { 19383 var w = Y_DOM._getDocSize(node).width; 19384 return Math.max(w, Y_DOM._getWinSize(node).width); 19385 }, 19386 19387 /** 19388 * Amount page has been scroll horizontally 19389 * @method docScrollX 19390 * @return {Number} The current amount the screen is scrolled horizontally. 19391 */ 19392 docScrollX: function(node, doc) { 19393 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization 19394 var dv = doc.defaultView, 19395 pageOffset = (dv) ? dv.pageXOffset : 0; 19396 return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft, pageOffset); 19397 }, 19398 19399 /** 19400 * Amount page has been scroll vertically 19401 * @method docScrollY 19402 * @return {Number} The current amount the screen is scrolled vertically. 19403 */ 19404 docScrollY: function(node, doc) { 19405 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization 19406 var dv = doc.defaultView, 19407 pageOffset = (dv) ? dv.pageYOffset : 0; 19408 return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop, pageOffset); 19409 }, 19410 19411 /** 19412 * Gets the current position of an element based on page coordinates. 19413 * Element must be part of the DOM tree to have page coordinates 19414 * (display:none or elements not appended return false). 19415 * @method getXY 19416 * @param element The target element 19417 * @return {Array} The XY position of the element 19418 19419 TODO: test inDocument/display? 19420 */
19421 getXY: function() { 19422 if (Y.config.doc[DOCUMENT_ELEMENT][GET_BOUNDING_CLIENT_RECT]) { 19423 return function(node) { 19424 var xy = null, 19425 scrollLeft, 19426 scrollTop, 19427 mode, 19428 box, 19429 offX, 19430 offY, 19431 doc, 19432 win, 19433 inDoc, 19434 rootNode; 19435 19436 if (node && node.tagName) { 19437 doc = node.ownerDocument; 19438 mode = doc[COMPAT_MODE]; 19439 19440 if (mode !== _BACK_COMPAT) { 19441 rootNode = doc[DOCUMENT_ELEMENT]; 19442 } else { 19443 rootNode = doc.body; 19444 } 19445 19446 // inline inDoc check for perf 19447 if (rootNode.contains) { 19448 inDoc = rootNode.contains(node); 19449 } else { 19450 inDoc = Y.DOM.contains(rootNode, node); 19451 } 19452 19453 if (inDoc) { 19454 win = doc.defaultView; 19455 19456 // inline scroll calc for perf 19457 if (win && 'pageXOffset' in win) { 19458 scrollLeft = win.pageXOffset; 19459 scrollTop = win.pageYOffset; 19460 } else { 19461 scrollLeft = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollLeft : Y_DOM.docScrollX(node, doc); 19462 scrollTop = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollTop : Y_DOM.docScrollY(node, doc); 19463 } 19464 19465 if (Y.UA.ie) { // IE < 8, quirks, or compatMode 19466 if (!doc.documentMode || doc.documentMode < 8 || mode === _BACK_COMPAT) { 19467 offX = rootNode.clientLeft; 19468 offY = rootNode.clientTop; 19469 } 19470 } 19471 box = node[GET_BOUNDING_CLIENT_RECT](); 19472 xy = [box.left, box.top]; 19473 19474 if (offX || offY) { 19475 xy[0] -= offX; 19476 xy[1] -= offY; 19477 19478 } 19479 if ((scrollTop || scrollLeft)) { 19480 if (!Y.UA.ios || (Y.UA.ios >= 4.2)) { 19481 xy[0] += scrollLeft; 19482 xy[1] += scrollTop; 19483 } 19484 19485 } 19486 } else { 19487 xy = Y_DOM._getOffset(node); 19488 } 19489 } 19490 return xy; 19491 }; 19492 } else { 19493 return function(node) { // manually calculate by crawling up offsetParents 19494 //Calculate the Top and Left border sizes (assumes pixels) 19495 var xy = null, 19496 doc, 19497 parentNode, 19498 bCheck, 19499 scrollTop, 19500 scrollLeft; 19501 19502 if (node) { 19503 if (Y_DOM.inDoc(node)) { 19504 xy = [node.offsetLeft, node.offsetTop]; 19505 doc = node.ownerDocument; 19506 parentNode = node; 19507 // TODO: refactor with !! or just falsey 19508 bCheck = ((Y.UA.gecko || Y.UA.webkit > 519) ? true : false); 19509 19510 // TODO: worth refactoring for TOP/LEFT only? 19511 while ((parentNode = parentNode.offsetParent)) { 19512 xy[0] += parentNode.offsetLeft; 19513 xy[1] += parentNode.offsetTop; 19514 if (bCheck) { 19515 xy = Y_DOM._calcBorders(parentNode, xy); 19516 } 19517 } 19518 19519 // account for any scrolled ancestors 19520 if (Y_DOM.getStyle(node, POSITION) != FIXED) { 19521 parentNode = node; 19522 19523 while ((parentNode = parentNode.parentNode)) { 19524 scrollTop = parentNode.scrollTop; 19525 scrollLeft = parentNode.scrollLeft; 19526 19527 //Firefox does something funky with borders when overflow is not visible. 19528 if (Y.UA.gecko && (Y_DOM.getStyle(parentNode, 'overflow') !== 'visible')) { 19529 xy = Y_DOM._calcBorders(parentNode, xy); 19530 } 19531 19532 19533 if (scrollTop || scrollLeft) { 19534 xy[0] -= scrollLeft; 19535 xy[1] -= scrollTop; 19536 } 19537 } 19538 xy[0] += Y_DOM.docScrollX(node, doc); 19539 xy[1] += Y_DOM.docScrollY(node, doc); 19540 19541 } else { 19542 //Fix FIXED position -- add scrollbars 19543 xy[0] += Y_DOM.docScrollX(node, doc); 19544 xy[1] += Y_DOM.docScrollY(node, doc); 19545 } 19546 } else { 19547 xy = Y_DOM._getOffset(node); 19548 } 19549 } 19550 19551 return xy; 19552 }; 19553 } 19554 }(),// NOTE: Executing for loadtime branching 19555 19556 /** 19557 Gets the width of vertical scrollbars on overflowed containers in the body 19558 content. 19559 19560 @method getScrollbarWidth 19561 @return {Number} Pixel width of a scrollbar in the current browser 19562 **/ 19563 getScrollbarWidth: Y.cached(function () { 19564 var doc = Y.config.doc, 19565 testNode = doc.createElement('div'), 19566 body = doc.getElementsByTagName('body')[0], 19567 // 0.1 because cached doesn't support falsy refetch values 19568 width = 0.1; 19569 19570 if (body) { 19571 testNode.style.cssText = "position:absolute;visibility:hidden;overflow:scroll;width:20px;"; 19572 testNode.appendChild(doc.createElement('p')).style.height = '1px'; 19573 body.insertBefore(testNode, body.firstChild); 19574 width = testNode.offsetWidth - testNode.clientWidth; 19575 19576 body.removeChild(testNode); 19577 } 19578 19579 return width; 19580 }, null, 0.1), 19581 19582 /** 19583 * Gets the current X position of an element based on page coordinates. 19584 * Element must be part of the DOM tree to have page coordinates 19585 * (display:none or elements not appended return false). 19586 * @method getX 19587 * @param element The target element 19588 * @return {Number} The X position of the element 19589 */ 19590 19591 getX: function(node) { 19592 return Y_DOM.getXY(node)[0]; 19593 }, 19594 19595 /** 19596 * Gets the current Y position of an element based on page coordinates. 19597 * Element must be part of the DOM tree to have page coordinates 19598 * (display:none or elements not appended return false). 19599 * @method getY 19600 * @param element The target element 19601 * @return {Number} The Y position of the element 19602 */ 19603 19604 getY: function(node) { 19605 return Y_DOM.getXY(node)[1]; 19606 }, 19607 19608 /** 19609 * Set the position of an html element in page coordinates. 19610 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 19611 * @method setXY 19612 * @param element The target element 19613 * @param {Array} xy Contains X & Y values for new position (coordinates are page-based) 19614 * @param {Boolean} noRetry By default we try and set the position a second time if the first fails 19615 */ 19616 setXY: function(node, xy, noRetry) { 19617 var setStyle = Y_DOM.setStyle, 19618 pos, 19619 delta, 19620 newXY, 19621 currentXY, 19622 offsetDir, 19623 dir, 19624 x; 19625 19626 if (node && xy) { 19627 pos = Y_DOM.getStyle(node, POSITION); 19628 19629 offsetDir = Y_DOM.OFFSET_XY; 19630 19631 if (!offsetDir) { 19632 dir = Y_DOM.getComputedStyle(node, 'direction'); 19633 19634 offsetDir = (dir === 'rtl' ? 'right' : LEFT); 19635 } 19636 19637 delta = Y_DOM._getOffset(node, offsetDir); 19638 if (pos == 'static') { // default to relative 19639 pos = RELATIVE; 19640 setStyle(node, POSITION, pos); 19641 } 19642 currentXY = Y_DOM._getDirXY(node, offsetDir); 19643 19644 x = xy[0]; 19645 19646 if (offsetDir === 'right') { 19647 x = Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10)); 19648 19649 if (!delta[0] && !noRetry) { 19650 noRetry = false;
19651 } 19652 } 19653 19654 if (x !== null) { 19655 setStyle(node, offsetDir, x - currentXY[0] + delta[0] + 'px'); 19656 } 19657 19658 if (xy[1] !== null) { 19659 setStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px'); 19660 } 19661 19662 if (!noRetry) { 19663 newXY = Y_DOM.getXY(node); 19664 if (newXY[0] !== xy[0] || newXY[1] !== xy[1]) { 19665 Y_DOM.setXY(node, xy, true); 19666 } 19667 } 19668 19669 } else { 19670 } 19671 }, 19672 19673 /** 19674 * Set the X position of an html element in page coordinates, regardless of how the element is positioned. 19675 * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 19676 * @method setX 19677 * @param element The target element 19678 * @param {Number} x The X values for new position (coordinates are page-based) 19679 */ 19680 setX: function(node, x) { 19681 return Y_DOM.setXY(node, [x, null]); 19682 }, 19683 19684 /** 19685 * Set the Y position of an html element in page coordinates, regardless of how the element is positioned. 19686 * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 19687 * @method setY 19688 * @param element The target element 19689 * @param {Number} y The Y values for new position (coordinates are page-based) 19690 */ 19691 setY: function(node, y) { 19692 return Y_DOM.setXY(node, [null, y]); 19693 }, 19694 19695 /** 19696 * @method swapXY 19697 * @description Swap the xy position with another node 19698 * @param {Node} node The node to swap with 19699 * @param {Node} otherNode The other node to swap with 19700 * @return {Node} 19701 */ 19702 swapXY: function(node, otherNode) { 19703 var xy = Y_DOM.getXY(node); 19704 Y_DOM.setXY(node, Y_DOM.getXY(otherNode)); 19705 Y_DOM.setXY(otherNode, xy); 19706 }, 19707 19708 _calcBorders: function(node, xy2) { 19709 var t = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0, 19710 l = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0; 19711 if (Y.UA.gecko) { 19712 if (RE_TABLE.test(node.tagName)) { 19713 t = 0; 19714 l = 0; 19715 } 19716 } 19717 xy2[0] += l; 19718 xy2[1] += t; 19719 return xy2; 19720 }, 19721 19722 _getWinSize: function(node, doc) { 19723 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; 19724 var win = doc.defaultView || doc.parentWindow, 19725 mode = doc[COMPAT_MODE], 19726 h = win.innerHeight, 19727 w = win.innerWidth, 19728 root = doc[DOCUMENT_ELEMENT]; 19729 19730 if ( mode && !Y.UA.opera ) { // IE, Gecko 19731 if (mode != 'CSS1Compat') { // Quirks 19732 root = doc.body; 19733 } 19734 h = root.clientHeight; 19735 w = root.clientWidth; 19736 } 19737 return { height: h, width: w }; 19738 }, 19739 19740 _getDocSize: function(node) { 19741 var doc = (node) ? Y_DOM._getDoc(node) : Y.config.doc, 19742 root = doc[DOCUMENT_ELEMENT]; 19743 19744 if (doc[COMPAT_MODE] != 'CSS1Compat') { 19745 root = doc.body; 19746 } 19747 19748 return { height: root.scrollHeight, width: root.scrollWidth }; 19749 }, 19750 19751 _getDirXY: function(node, dir) { 19752 var xy = Y_DOM.getXY(node); 19753 19754 if (dir === 'right') { 19755 xy[0] = (Y_DOM.winWidth() - (xy[0] + parseInt(Y_DOM.getComputedStyle(node, 'width'), 10))); 19756 } 19757 19758 return xy; 19759 } 19760}); 19761 19762})(Y); 19763(function(Y) { 19764var TOP = 'top', 19765 RIGHT = 'right', 19766 BOTTOM = 'bottom', 19767 LEFT = 'left', 19768 19769 getOffsets = function(r1, r2) { 19770 var t = Math.max(r1[TOP], r2[TOP]), 19771 r = Math.min(r1[RIGHT], r2[RIGHT]), 19772 b = Math.min(r1[BOTTOM], r2[BOTTOM]), 19773 l = Math.max(r1[LEFT], r2[LEFT]), 19774 ret = {}; 19775 19776 ret[TOP] = t; 19777 ret[RIGHT] = r; 19778 ret[BOTTOM] = b; 19779 ret[LEFT] = l; 19780 return ret; 19781 }, 19782 19783 DOM = Y.DOM; 19784 19785Y.mix(DOM, { 19786 /** 19787 * Returns an Object literal containing the following about this element: (top, right, bottom, left) 19788 * @for DOM 19789 * @method region 19790 * @param {HTMLElement} element The DOM element. 19791 * @return {Object} Object literal containing the following about this element: (top, right, bottom, left) 19792 */ 19793 region: function(node) { 19794 var xy = DOM.getXY(node), 19795 ret = false;
19796 19797 if (node && xy) { 19798 ret = DOM._getRegion( 19799 xy[1], // top 19800 xy[0] + node.offsetWidth, // right 19801 xy[1] + node.offsetHeight, // bottom 19802 xy[0] // left 19803 ); 19804 } 19805 19806 return ret; 19807 }, 19808 19809 /** 19810 * Find the intersect information for the passed nodes. 19811 * @method intersect 19812 * @for DOM 19813 * @param {HTMLElement} element The first element 19814 * @param {HTMLElement | Object} element2 The element or region to check the interect with 19815 * @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance e.g. DragDrop) 19816 * @return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion) 19817 */ 19818 intersect: function(node, node2, altRegion) { 19819 var r = altRegion || DOM.region(node), region = {}, 19820 n = node2, 19821 off; 19822 19823 if (n.tagName) { 19824 region = DOM.region(n); 19825 } else if (Y.Lang.isObject(node2)) { 19826 region = node2; 19827 } else { 19828 return false; 19829 } 19830 19831 off = getOffsets(region, r); 19832 return { 19833 top: off[TOP], 19834 right: off[RIGHT], 19835 bottom: off[BOTTOM], 19836 left: off[LEFT], 19837 area: ((off[BOTTOM] - off[TOP]) * (off[RIGHT] - off[LEFT])), 19838 yoff: ((off[BOTTOM] - off[TOP])), 19839 xoff: (off[RIGHT] - off[LEFT]), 19840 inRegion: DOM.inRegion(node, node2, false, altRegion) 19841 }; 19842 19843 }, 19844 /** 19845 * Check if any part of this node is in the passed region 19846 * @method inRegion 19847 * @for DOM 19848 * @param {Object} node The node to get the region from 19849 * @param {Object} node2 The second node to get the region from or an Object literal of the region 19850 * @param {Boolean} all Should all of the node be inside the region 19851 * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop) 19852 * @return {Boolean} True if in region, false if not. 19853 */ 19854 inRegion: function(node, node2, all, altRegion) { 19855 var region = {}, 19856 r = altRegion || DOM.region(node), 19857 n = node2, 19858 off; 19859 19860 if (n.tagName) { 19861 region = DOM.region(n); 19862 } else if (Y.Lang.isObject(node2)) { 19863 region = node2; 19864 } else { 19865 return false; 19866 } 19867 19868 if (all) { 19869 return ( 19870 r[LEFT] >= region[LEFT] && 19871 r[RIGHT] <= region[RIGHT] && 19872 r[TOP] >= region[TOP] && 19873 r[BOTTOM] <= region[BOTTOM] ); 19874 } else { 19875 off = getOffsets(region, r); 19876 if (off[BOTTOM] >= off[TOP] && off[RIGHT] >= off[LEFT]) { 19877 return true; 19878 } else { 19879 return false; 19880 } 19881 19882 } 19883 }, 19884 19885 /** 19886 * Check if any part of this element is in the viewport 19887 * @method inViewportRegion 19888 * @for DOM 19889 * @param {HTMLElement} element The DOM element. 19890 * @param {Boolean} all Should all of the node be inside the region 19891 * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop) 19892 * @return {Boolean} True if in region, false if not. 19893 */ 19894 inViewportRegion: function(node, all, altRegion) { 19895 return DOM.inRegion(node, DOM.viewportRegion(node), all, altRegion); 19896 19897 }, 19898 19899 _getRegion: function(t, r, b, l) { 19900 var region = {}; 19901 19902 region[TOP] = region[1] = t; 19903 region[LEFT] = region[0] = l; 19904 region[BOTTOM] = b; 19905 region[RIGHT] = r; 19906 region.width = region[RIGHT] - region[LEFT]; 19907 region.height = region[BOTTOM] - region[TOP]; 19908 19909 return region; 19910 }, 19911 19912 /** 19913 * Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left) 19914 * @method viewportRegion 19915 * @for DOM 19916 * @return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left) 19917 */ 19918 viewportRegion: function(node) { 19919 node = node || Y.config.doc.documentElement; 19920 var ret = false, 19921 scrollX, 19922 scrollY; 19923 19924 if (node) { 19925 scrollX = DOM.docScrollX(node); 19926 scrollY = DOM.docScrollY(node); 19927 19928 ret = DOM._getRegion(scrollY, // top 19929 DOM.winWidth(node) + scrollX, // right 19930 scrollY + DOM.winHeight(node), // bottom 19931 scrollX); // left 19932 } 19933 19934 return ret; 19935 } 19936}); 19937})(Y); 19938 19939 19940}, 'patched-v3.18.1', {"requires": ["dom-base", "dom-style"]}); 19941 19942YUI.add('dom-style', function (Y, NAME) { 19943 19944/** 19945 * Add style management functionality to DOM. 19946 * @module dom 19947 * @submodule dom-style 19948 * @for DOM 19949 */ 19950 19951var DOCUMENT_ELEMENT = 'documentElement', 19952 DEFAULT_VIEW = 'defaultView', 19953 OWNER_DOCUMENT = 'ownerDocument', 19954 STYLE = 'style', 19955 FLOAT = 'float', 19956 CSS_FLOAT = 'cssFloat', 19957 STYLE_FLOAT = 'styleFloat', 19958 TRANSPARENT = 'transparent', 19959 GET_COMPUTED_STYLE = 'getComputedStyle', 19960 GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect', 19961 19962 DOCUMENT = Y.config.doc, 19963 19964 Y_DOM = Y.DOM, 19965 19966 TRANSFORM, 19967 TRANSFORMORIGIN, 19968 VENDOR_TRANSFORM = [ 19969 'WebkitTransform', 19970 'MozTransform', 19971 'OTransform', 19972 'msTransform', 19973 'transform' 19974 ], 19975 19976 re_unit = /width|height|top|left|right|bottom|margin|padding/i; 19977 19978Y.Array.each(VENDOR_TRANSFORM, function(val) { 19979 if (val in DOCUMENT[DOCUMENT_ELEMENT].style) { 19980 TRANSFORM = val;
19981 TRANSFORMORIGIN = val + "Origin"; 19982 } 19983}); 19984 19985Y.mix(Y_DOM, { 19986 DEFAULT_UNIT: 'px', 19987 19988 CUSTOM_STYLES: { 19989 }, 19990 19991 19992 /** 19993 * Sets a style property for a given element. 19994 * @method setStyle 19995 * @param {HTMLElement} node The HTMLElement to apply the style to. 19996 * @param {String} att The style property to set. 19997 * @param {String|Number} val The value. 19998 * @param {Object} [style] The style node. Defaults to `node.style`. 19999 */ 20000 setStyle: function(node, att, val, style) { 20001 style = style || node.style; 20002 var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES; 20003 20004 if (style) { 20005 if (val === null || val === '') { // normalize unsetting 20006 val = ''; 20007 } else if (!isNaN(Number(val)) && re_unit.test(att)) { // number values may need a unit 20008 val += Y_DOM.DEFAULT_UNIT; 20009 } 20010 20011 if (att in CUSTOM_STYLES) { 20012 if (CUSTOM_STYLES[att].set) { 20013 CUSTOM_STYLES[att].set(node, val, style); 20014 return; // NOTE: return 20015 } else if (typeof CUSTOM_STYLES[att] === 'string') { 20016 att = CUSTOM_STYLES[att]; 20017 } 20018 } else if (att === '') { // unset inline styles 20019 att = 'cssText'; 20020 val = ''; 20021 } 20022 style[att] = val; 20023 } 20024 }, 20025 20026 /** 20027 * Returns the current style value for the given property. 20028 * @method getStyle 20029 * @param {HTMLElement} node The HTMLElement to get the style from. 20030 * @param {String} att The style property to get. 20031 * @param {Object} [style] The style node. Defaults to `node.style`. 20032 */ 20033 getStyle: function(node, att, style) { 20034 style = style || node.style; 20035 var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES, 20036 val = ''; 20037 20038 if (style) { 20039 if (att in CUSTOM_STYLES) { 20040 if (CUSTOM_STYLES[att].get) { 20041 return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return 20042 } else if (typeof CUSTOM_STYLES[att] === 'string') { 20043 att = CUSTOM_STYLES[att]; 20044 } 20045 } 20046 val = style[att]; 20047 if (val === '') { // TODO: is empty string sufficient? 20048 val = Y_DOM[GET_COMPUTED_STYLE](node, att); 20049 } 20050 } 20051 20052 return val; 20053 }, 20054 20055 /** 20056 * Sets multiple style properties. 20057 * @method setStyles 20058 * @param {HTMLElement} node The HTMLElement to apply the styles to. 20059 * @param {Object} hash An object literal of property:value pairs. 20060 */ 20061 setStyles: function(node, hash) { 20062 var style = node.style; 20063 Y.each(hash, function(v, n) { 20064 Y_DOM.setStyle(node, n, v, style); 20065 }, Y_DOM); 20066 }, 20067 20068 /** 20069 * Returns the computed style for the given node. 20070 * @method getComputedStyle 20071 * @param {HTMLElement} node The HTMLElement to get the style from. 20072 * @param {String} att The style property to get. 20073 * @return {String} The computed value of the style property. 20074 */ 20075 getComputedStyle: function(node, att) { 20076 var val = '', 20077 doc = node[OWNER_DOCUMENT], 20078 computed; 20079 20080 if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) { 20081 computed = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null); 20082 if (computed) { // FF may be null in some cases (ticket #2530548) 20083 val = computed[att]; 20084 } 20085 } 20086 return val; 20087 } 20088}); 20089 20090// normalize reserved word float alternatives ("cssFloat" or "styleFloat") 20091if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== undefined) { 20092 Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT; 20093} else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== undefined) { 20094 Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT; 20095} 20096 20097// safari converts transparent to rgba(), others use "transparent" 20098if (Y.UA.webkit) { 20099 Y_DOM[GET_COMPUTED_STYLE] = function(node, att) { 20100 var view = node[OWNER_DOCUMENT][DEFAULT_VIEW], 20101 val = view[GET_COMPUTED_STYLE](node, '')[att]; 20102 20103 if (val === 'rgba(0, 0, 0, 0)') { 20104 val = TRANSPARENT; 20105 } 20106 20107 return val; 20108 }; 20109 20110} 20111 20112Y.DOM._getAttrOffset = function(node, attr) { 20113 var val = Y.DOM[GET_COMPUTED_STYLE](node, attr), 20114 offsetParent = node.offsetParent, 20115 position, 20116 parentOffset, 20117 offset; 20118 20119 if (val === 'auto') { 20120 position = Y.DOM.getStyle(node, 'position'); 20121 if (position === 'static' || position === 'relative') { 20122 val = 0; 20123 } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) { 20124 parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr]; 20125 offset = node[GET_BOUNDING_CLIENT_RECT]()[attr]; 20126 if (attr === 'left' || attr === 'top') { 20127 val = offset - parentOffset; 20128 } else { 20129 val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr]; 20130 } 20131 } 20132 } 20133 20134 return val; 20135}; 20136 20137Y.DOM._getOffset = function(node, dir) { 20138 var pos,
20139 xy = null, 20140 offset = { 20141 left: 'offsetLeft', 20142 right: 'offsetRight' 20143 }, 20144 margins = { 20145 left: 'marginLeft', 20146 right: 'marginRight' 20147 }, 20148 margin; 20149 20150 dir = dir || 'left'; 20151 20152 if (node) { 20153 pos = Y_DOM.getStyle(node, 'position'); 20154 margin = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, margins[dir]), 10); 20155 xy = [ 20156 parseInt(Y_DOM[GET_COMPUTED_STYLE](node, dir), 10), 20157 parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10) 20158 ]; 20159 20160 if ( isNaN(xy[0]) ) { // in case of 'auto' 20161 xy[0] = parseInt(Y_DOM.getStyle(node, dir), 10); // try inline 20162 if ( isNaN(xy[0]) ) { // default to offset value 20163 xy[0] = (pos === 'relative') ? 0 : (node[offset[dir]] - margin) || 0; 20164 } 20165 } 20166 20167 if ( isNaN(xy[1]) ) { // in case of 'auto' 20168 xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline 20169 if ( isNaN(xy[1]) ) { // default to offset value 20170 xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0; 20171 } 20172 } 20173 } 20174 20175 return xy; 20176 20177}; 20178 20179if (TRANSFORM) { 20180 Y_DOM.CUSTOM_STYLES.transform = { 20181 set: function(node, val, style) { 20182 style[TRANSFORM] = val; 20183 }, 20184 20185 get: function(node) { 20186 return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM); 20187 } 20188 }; 20189 20190 Y_DOM.CUSTOM_STYLES.transformOrigin = { 20191 set: function(node, val, style) { 20192 style[TRANSFORMORIGIN] = val; 20193 }, 20194 20195 get: function(node) { 20196 return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORMORIGIN); 20197 } 20198 }; 20199} 20200 20201 20202}, 'patched-v3.18.1', {"requires": ["dom-base"]}); 20203 20204YUI.add('event-base', function (Y, NAME) { 20205 20206/* 20207 * DOM event listener abstraction layer 20208 * @module event 20209 * @submodule event-base 20210 */ 20211 20212/** 20213 * The domready event fires at the moment the browser's DOM is 20214 * usable. In most cases, this is before images are fully 20215 * downloaded, allowing you to provide a more responsive user 20216 * interface. 20217 * 20218 * In YUI 3, domready subscribers will be notified immediately if 20219 * that moment has already passed when the subscription is created. 20220 * 20221 * One exception is if the yui.js file is dynamically injected into 20222 * the page. If this is done, you must tell the YUI instance that 20223 * you did this in order for DOMReady (and window load events) to 20224 * fire normally. That configuration option is 'injected' -- set 20225 * it to true if the yui.js script is not included inline. 20226 * 20227 * This method is part of the 'event-ready' module, which is a 20228 * submodule of 'event'. 20229 * 20230 * @event domready 20231 * @for YUI 20232 */ 20233Y.publish('domready', { 20234 fireOnce: true, 20235 async: true 20236}); 20237 20238if (YUI.Env.DOMReady) { 20239 Y.fire('domready'); 20240} else { 20241 Y.Do.before(function() { Y.fire('domready'); }, YUI.Env, '_ready'); 20242} 20243 20244/** 20245 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 20246 * events. 20247 * @module event 20248 * @submodule event-base 20249 */ 20250 20251/** 20252 * Wraps a DOM event, properties requiring browser abstraction are 20253 * fixed here. Provids a security layer when required. 20254 * @class DOMEventFacade 20255 * @param ev {Event} the DOM event 20256 * @param currentTarget {HTMLElement} the element the listener was attached to 20257 * @param wrapper {CustomEvent} the custom event wrapper for this DOM event 20258 */ 20259 20260 var ua = Y.UA, 20261 20262 EMPTY = {}, 20263 20264 /** 20265 * webkit key remapping required for Safari < 3.1 20266 * @property webkitKeymap 20267 * @private 20268 */ 20269 webkitKeymap = { 20270 63232: 38, // up 20271 63233: 40, // down 20272 63234: 37, // left 20273 63235: 39, // right 20274 63276: 33, // page up 20275 63277: 34, // page down 20276 25: 9, // SHIFT-TAB (Safari provides a different key code in 20277 // this case, even though the shiftKey modifier is set) 20278 63272: 46, // delete 20279 63273: 36, // home 20280 63275: 35 // end 20281 }, 20282 20283 /** 20284 * Returns a wrapped node. Intended to be used on event targets, 20285 * so it will return the node's parent if the target is a text 20286 * node. 20287 * 20288 * If accessing a property of the node throws an error, this is 20289 * probably the anonymous div wrapper Gecko adds inside text 20290 * nodes. This likely will only occur when attempting to access 20291 * the relatedTarget. In this case, we now return null because 20292 * the anonymous div is completely useless and we do not know 20293 * what the related target was because we can't even get to 20294 * the element's parent node. 20295 * 20296 * @method resolve 20297 * @private 20298 */ 20299 resolve = function(n) { 20300 if (!n) { 20301 return n; 20302 } 20303 try { 20304 if (n && 3 == n.nodeType) { 20305 n = n.parentNode; 20306 } 20307 } catch(e) { 20308 return null; 20309 } 20310 20311 return Y.one(n); 20312 }, 20313 20314 DOMEventFacade = function(ev, currentTarget, wrapper) { 20315 this._event = ev; 20316 this._currentTarget = currentTarget; 20317 this._wrapper = wrapper || EMPTY; 20318 20319 // if not lazy init 20320 this.init(); 20321 }; 20322 20323Y.extend(DOMEventFacade, Object, { 20324 20325 init: function() { 20326 20327 var e = this._event, 20328 overrides = this._wrapper.overrides, 20329 x = e.pageX, 20330 y = e.pageY, 20331 c, 20332 currentTarget = this._currentTarget; 20333 20334 this.altKey = e.altKey; 20335 this.ctrlKey = e.ctrlKey; 20336 this.metaKey = e.metaKey; 20337 this.shiftKey = e.shiftKey; 20338 this.type = (overrides && overrides.type) || e.type; 20339 this.clientX = e.clientX; 20340 this.clientY = e.clientY; 20341 20342 this.pageX = x; 20343 this.pageY = y; 20344
20345 // charCode is unknown in keyup, keydown. keyCode is unknown in keypress. 20346 // FF 3.6 - 8+? pass 0 for keyCode in keypress events. 20347 // Webkit, FF 3.6-8+?, and IE9+? pass 0 for charCode in keydown, keyup. 20348 // Webkit and IE9+? duplicate charCode in keyCode. 20349 // Opera never sets charCode, always keyCode (though with the charCode). 20350 // IE6-8 don't set charCode or which. 20351 // All browsers other than IE6-8 set which=keyCode in keydown, keyup, and 20352 // which=charCode in keypress. 20353 // 20354 // Moral of the story: (e.which || e.keyCode) will always return the 20355 // known code for that key event phase. e.keyCode is often different in 20356 // keypress from keydown and keyup. 20357 c = e.keyCode || e.charCode; 20358 20359 if (ua.webkit && (c in webkitKeymap)) { 20360 c = webkitKeymap[c]; 20361 } 20362 20363 this.keyCode = c; 20364 this.charCode = c; 20365 // Fill in e.which for IE - implementers should always use this over 20366 // e.keyCode or e.charCode. 20367 this.which = e.which || e.charCode || c; 20368 // this.button = e.button; 20369 this.button = this.which; 20370 20371 this.target = resolve(e.target); 20372 this.currentTarget = resolve(currentTarget); 20373 this.relatedTarget = resolve(e.relatedTarget); 20374 20375 if (e.type == "mousewheel" || e.type == "DOMMouseScroll") { 20376 this.wheelDelta = (e.detail) ? (e.detail * -1) : Math.round(e.wheelDelta / 80) || ((e.wheelDelta < 0) ? -1 : 1); 20377 } 20378 20379 if (this._touch) { 20380 this._touch(e, currentTarget, this._wrapper); 20381 } 20382 }, 20383 20384 stopPropagation: function() { 20385 this._event.stopPropagation(); 20386 this._wrapper.stopped = 1; 20387 this.stopped = 1; 20388 }, 20389 20390 stopImmediatePropagation: function() { 20391 var e = this._event; 20392 if (e.stopImmediatePropagation) { 20393 e.stopImmediatePropagation(); 20394 } else { 20395 this.stopPropagation(); 20396 } 20397 this._wrapper.stopped = 2; 20398 this.stopped = 2; 20399 }, 20400 20401 preventDefault: function(returnValue) { 20402 var e = this._event; 20403 e.preventDefault(); 20404 if (returnValue) { 20405 e.returnValue = returnValue; 20406 } 20407 this._wrapper.prevented = 1; 20408 this.prevented = 1; 20409 }, 20410 20411 halt: function(immediate) { 20412 if (immediate) { 20413 this.stopImmediatePropagation(); 20414 } else { 20415 this.stopPropagation(); 20416 } 20417 20418 this.preventDefault(); 20419 } 20420 20421}); 20422 20423DOMEventFacade.resolve = resolve; 20424Y.DOM2EventFacade = DOMEventFacade; 20425Y.DOMEventFacade = DOMEventFacade; 20426 20427 /** 20428 * The native event 20429 * @property _event 20430 * @type {DOMEvent} 20431 * @private 20432 */ 20433 20434 /** 20435 The name of the event (e.g. "click") 20436 20437 @property type 20438 @type {String} 20439 **/ 20440 20441 /** 20442 `true` if the "alt" or "option" key is pressed. 20443 20444 @property altKey 20445 @type {Boolean} 20446 **/ 20447 20448 /** 20449 `true` if the shift key is pressed. 20450 20451 @property shiftKey 20452 @type {Boolean} 20453 **/ 20454 20455 /** 20456 `true` if the "Windows" key on a Windows keyboard, "command" key on an 20457 Apple keyboard, or "meta" key on other keyboards is pressed. 20458 20459 @property metaKey 20460 @type {Boolean} 20461 **/ 20462 20463 /** 20464 `true` if the "Ctrl" or "control" key is pressed. 20465 20466 @property ctrlKey 20467 @type {Boolean} 20468 **/ 20469 20470 /** 20471 * The X location of the event on the page (including scroll) 20472 * @property pageX 20473 * @type {Number} 20474 */ 20475 20476 /** 20477 * The Y location of the event on the page (including scroll) 20478 * @property pageY 20479 * @type {Number} 20480 */ 20481 20482 /** 20483 * The X location of the event in the viewport 20484 * @property clientX 20485 * @type {Number} 20486 */ 20487 20488 /** 20489 * The Y location of the event in the viewport 20490 * @property clientY 20491 * @type {Number} 20492 */ 20493 20494 /** 20495 * The keyCode for key events. Uses charCode if keyCode is not available 20496 * @property keyCode 20497 * @type {Number} 20498 */ 20499 20500 /** 20501 * The charCode for key events. Same as keyCode 20502 * @property charCode 20503 * @type {Number} 20504 */ 20505 20506 /** 20507 * The button that was pushed. 1 for left click, 2 for middle click, 3 for 20508 * right click. This is only reliably populated on `mouseup` events. 20509 * @property button 20510 * @type {Number} 20511 */ 20512 20513 /** 20514 * The button that was pushed. Same as button. 20515 * @property which 20516 * @type {Number} 20517 */ 20518 20519 /** 20520 * Node reference for the targeted element 20521 * @property target 20522 * @type {Node} 20523 */ 20524 20525 /** 20526 * Node reference for the element that the listener was attached to. 20527 * @property currentTarget 20528 * @type {Node} 20529 */ 20530 20531 /** 20532 * Node reference to the relatedTarget 20533 * @property relatedTarget 20534 * @type {Node} 20535 */ 20536 20537 /** 20538 * Number representing the direction and velocity of the movement of the mousewheel. 20539 * Negative is down, the higher the number, the faster. Applies to the mousewheel event. 20540 * @property wheelDelta 20541 * @type {Number} 20542 */ 20543 20544 /** 20545 * Stops the propagation to the next bubble target 20546 * @method stopPropagation 20547 */ 20548 20549 /** 20550 * Stops the propagation to the next bubble target and 20551 * prevents any additional listeners from being exectued 20552 * on the current target. 20553 * @method stopImmediatePropagation 20554 */ 20555 20556 /** 20557 * Prevents the event's default behavior 20558 * @method preventDefault 20559 * @param returnValue {string} sets the returnValue of the event to this value 20560 * (rather than the default false value). This can be used to add a customized 20561 * confirmation query to the beforeunload event). 20562 */ 20563 20564 /** 20565 * Stops the event propagation and prevents the default 20566 * event behavior. 20567 * @method halt 20568 * @param immediate {boolean} if true additional listeners 20569 * on the current target will not be executed 20570 */ 20571(function() { 20572 20573/** 20574 * The event utility provides functions to add and remove event listeners, 20575 * event cleansing. It also tries to automatically remove listeners it 20576 * registers during the unload event. 20577 * @module event 20578 * @main event 20579 * @submodule event-base 20580 */ 20581 20582/** 20583 * The event utility provides functions to add and remove event listeners, 20584 * event cleansing. It also tries to automatically remove listeners it 20585 * registers during the unload event. 20586 * 20587 * @class Event 20588 * @static 20589 */ 20590 20591Y.Env.evt.dom_wrappers = {}; 20592Y.Env.evt.dom_map = {}; 20593 20594var _eventenv = Y.Env.evt, 20595 config = Y.config, 20596 win = config.win, 20597 add = YUI.Env.add, 20598 remove = YUI.Env.remove, 20599 20600 onLoad = function() { 20601 YUI.Env.windowLoaded = true; 20602 Y.Event._load(); 20603 remove(win, "load", onLoad); 20604 }, 20605 20606 onUnload = function() { 20607 Y.Event._unload(); 20608 }, 20609 20610 EVENT_READY = 'domready', 20611 20612 COMPAT_ARG = '~yui|2|compat~', 20613 20614 shouldIterate = function(o) { 20615 try { 20616 // TODO: See if there's a more performant way to return true early on this, for the common case 20617 return (o && typeof o !== "string" && Y.Lang.isNumber(o.length) && !o.tagName && !Y.DOM.isWindow(o)); 20618 } catch(ex) { 20619 return false;
20620 } 20621 }, 20622 20623 // aliases to support DOM event subscription clean up when the last 20624 // subscriber is detached. deleteAndClean overrides the DOM event's wrapper 20625 // CustomEvent _delete method. 20626 _ceProtoDelete = Y.CustomEvent.prototype._delete, 20627 _deleteAndClean = function(s) { 20628 var ret = _ceProtoDelete.apply(this, arguments); 20629 20630 if (!this.hasSubs()) { 20631 Y.Event._clean(this); 20632 } 20633 20634 return ret; 20635 }, 20636 20637Event = function() { 20638 20639 /** 20640 * True after the onload event has fired 20641 * @property _loadComplete 20642 * @type boolean 20643 * @static 20644 * @private 20645 */ 20646 var _loadComplete = false, 20647 20648 /** 20649 * The number of times to poll after window.onload. This number is 20650 * increased if additional late-bound handlers are requested after 20651 * the page load. 20652 * @property _retryCount 20653 * @static 20654 * @private 20655 */ 20656 _retryCount = 0, 20657 20658 /** 20659 * onAvailable listeners 20660 * @property _avail 20661 * @static 20662 * @private 20663 */ 20664 _avail = [], 20665 20666 /** 20667 * Custom event wrappers for DOM events. Key is 20668 * 'event:' + Element uid stamp + event type 20669 * @property _wrappers 20670 * @type CustomEvent 20671 * @static 20672 * @private 20673 */ 20674 _wrappers = _eventenv.dom_wrappers, 20675 20676 _windowLoadKey = null, 20677 20678 /** 20679 * Custom event wrapper map DOM events. Key is 20680 * Element uid stamp. Each item is a hash of custom event 20681 * wrappers as provided in the _wrappers collection. This 20682 * provides the infrastructure for getListeners. 20683 * @property _el_events 20684 * @static 20685 * @private 20686 */ 20687 _el_events = _eventenv.dom_map; 20688 20689 return { 20690 20691 /** 20692 * The number of times we should look for elements that are not 20693 * in the DOM at the time the event is requested after the document 20694 * has been loaded. The default is 1000@amp;40 ms, so it will poll 20695 * for 40 seconds or until all outstanding handlers are bound 20696 * (whichever comes first). 20697 * @property POLL_RETRYS 20698 * @type int 20699 * @static 20700 * @final 20701 */ 20702 POLL_RETRYS: 1000, 20703 20704 /** 20705 * The poll interval in milliseconds 20706 * @property POLL_INTERVAL 20707 * @type int 20708 * @static 20709 * @final 20710 */ 20711 POLL_INTERVAL: 40, 20712 20713 /** 20714 * addListener/removeListener can throw errors in unexpected scenarios. 20715 * These errors are suppressed, the method returns false, and this property 20716 * is set 20717 * @property lastError 20718 * @static 20719 * @type Error 20720 */ 20721 lastError: null, 20722 20723 20724 /** 20725 * poll handle 20726 * @property _interval 20727 * @static 20728 * @private 20729 */ 20730 _interval: null, 20731 20732 /** 20733 * document readystate poll handle 20734 * @property _dri 20735 * @static 20736 * @private 20737 */ 20738 _dri: null, 20739 20740 /** 20741 * True when the document is initially usable 20742 * @property DOMReady 20743 * @type boolean 20744 * @static 20745 */ 20746 DOMReady: false, 20747 20748 /** 20749 * @method startInterval 20750 * @static 20751 * @private 20752 */ 20753 startInterval: function() { 20754 if (!Event._interval) { 20755Event._interval = setInterval(Event._poll, Event.POLL_INTERVAL); 20756 } 20757 }, 20758 20759 /** 20760 * Executes the supplied callback when the item with the supplied 20761 * id is found. This is meant to be used to execute behavior as 20762 * soon as possible as the page loads. If you use this after the 20763 * initial page load it will poll for a fixed time for the element. 20764 * The number of times it will poll and the frequency are 20765 * configurable. By default it will poll for 10 seconds. 20766 * 20767 * <p>The callback is executed with a single parameter: 20768 * the custom object parameter, if provided.</p> 20769 * 20770 * @method onAvailable 20771 * 20772 * @param {string||string[]} id the id of the element, or an array 20773 * of ids to look for. 20774 * @param {function} fn what to execute when the element is found. 20775 * @param {object} p_obj an optional object to be passed back as 20776 * a parameter to fn. 20777 * @param {boolean|object} p_override If set to true, fn will execute 20778 * in the context of p_obj, if set to an object it 20779 * will execute in the context of that object 20780 * @param checkContent {boolean} check child node readiness (onContentReady) 20781 * @static 20782 * @deprecated Use Y.on("available") 20783 */ 20784 // @TODO fix arguments 20785 onAvailable: function(id, fn, p_obj, p_override, checkContent, compat) { 20786 20787 var a = Y.Array(id), i, availHandle; 20788 20789 for (i=0; i<a.length; i=i+1) { 20790 _avail.push({ 20791 id: a[i], 20792 fn: fn, 20793 obj: p_obj, 20794 override: p_override, 20795 checkReady: checkContent, 20796 compat: compat 20797 }); 20798 } 20799 _retryCount = this.POLL_RETRYS; 20800 20801 // We want the first test to be immediate, but async 20802 setTimeout(Event._poll, 0); 20803 20804 availHandle = new Y.EventHandle({ 20805 20806 _delete: function() { 20807 // set by the event system for lazy DOM listeners 20808 if (availHandle.handle) { 20809 availHandle.handle.detach(); 20810 return; 20811 } 20812 20813 var i, j; 20814 20815 // otherwise try to remove the onAvailable listener(s) 20816 for (i = 0; i < a.length; i++) { 20817 for (j = 0; j < _avail.length; j++) { 20818 if (a[i] === _avail[j].id) { 20819 _avail.splice(j, 1); 20820 } 20821 } 20822 } 20823 } 20824 20825 }); 20826 20827 return availHandle; 20828 }, 20829 20830 /** 20831 * Works the same way as onAvailable, but additionally checks the 20832 * state of sibling elements to determine if the content of the 20833 * available element is safe to modify. 20834 * 20835 * <p>The callback is executed with a single parameter:
20836 * the custom object parameter, if provided.</p> 20837 * 20838 * @method onContentReady 20839 * 20840 * @param {string} id the id of the element to look for. 20841 * @param {function} fn what to execute when the element is ready. 20842 * @param {object} obj an optional object to be passed back as 20843 * a parameter to fn. 20844 * @param {boolean|object} override If set to true, fn will execute 20845 * in the context of p_obj. If an object, fn will 20846 * exectute in the context of that object 20847 * 20848 * @static 20849 * @deprecated Use Y.on("contentready") 20850 */ 20851 // @TODO fix arguments 20852 onContentReady: function(id, fn, obj, override, compat) { 20853 return Event.onAvailable(id, fn, obj, override, true, compat); 20854 }, 20855 20856 /** 20857 * Adds an event listener 20858 * 20859 * @method attach 20860 * 20861 * @param {String} type The type of event to append 20862 * @param {Function} fn The method the event invokes 20863 * @param {String|HTMLElement|Array|NodeList} el An id, an element 20864 * reference, or a collection of ids and/or elements to assign the 20865 * listener to. 20866 * @param {Object} context optional context object 20867 * @param {Boolean|object} args 0..n arguments to pass to the callback 20868 * @return {EventHandle} an object to that can be used to detach the listener 20869 * 20870 * @static 20871 */ 20872 20873 attach: function(type, fn, el, context) { 20874 return Event._attach(Y.Array(arguments, 0, true)); 20875 }, 20876 20877 _createWrapper: function (el, type, capture, compat, facade) { 20878 20879 var cewrapper, 20880 ek = Y.stamp(el), 20881 key = 'event:' + ek + type; 20882 20883 if (false === facade) { 20884 key += 'native'; 20885 } 20886 if (capture) { 20887 key += 'capture'; 20888 } 20889 20890 20891 cewrapper = _wrappers[key]; 20892 20893 20894 if (!cewrapper) { 20895 // create CE wrapper 20896 cewrapper = Y.publish(key, { 20897 silent: true, 20898 bubbles: false, 20899 emitFacade:false, 20900 contextFn: function() { 20901 if (compat) { 20902 return cewrapper.el; 20903 } else { 20904 cewrapper.nodeRef = cewrapper.nodeRef || Y.one(cewrapper.el); 20905 return cewrapper.nodeRef; 20906 } 20907 } 20908 }); 20909 20910 cewrapper.overrides = {}; 20911 20912 // for later removeListener calls 20913 cewrapper.el = el; 20914 cewrapper.key = key; 20915 cewrapper.domkey = ek; 20916 cewrapper.type = type; 20917 cewrapper.fn = function(e) { 20918 cewrapper.fire(Event.getEvent(e, el, (compat || (false === facade)))); 20919 }; 20920 cewrapper.capture = capture; 20921 20922 if (el == win && type == "load") { 20923 // window load happens once 20924 cewrapper.fireOnce = true; 20925 _windowLoadKey = key; 20926 } 20927 cewrapper._delete = _deleteAndClean; 20928 20929 _wrappers[key] = cewrapper; 20930 _el_events[ek] = _el_events[ek] || {}; 20931 _el_events[ek][key] = cewrapper; 20932 20933 add(el, type, cewrapper.fn, capture); 20934 } 20935 20936 return cewrapper; 20937 20938 }, 20939 20940 _attach: function(args, conf) { 20941 20942 var compat, 20943 handles, oEl, cewrapper, context, 20944 fireNow = false, ret, 20945 type = args[0], 20946 fn = args[1], 20947 el = args[2] || win, 20948 facade = conf && conf.facade, 20949 capture = conf && conf.capture, 20950 overrides = conf && conf.overrides; 20951 20952 if (args[args.length-1] === COMPAT_ARG) { 20953 compat = true; 20954 } 20955 20956 if (!fn || !fn.call) { 20957 return false;
20958 } 20959 20960 // The el argument can be an array of elements or element ids. 20961 if (shouldIterate(el)) { 20962 20963 handles=[]; 20964 20965 Y.each(el, function(v, k) { 20966 args[2] = v; 20967 handles.push(Event._attach(args.slice(), conf)); 20968 }); 20969 20970 // return (handles.length === 1) ? handles[0] : handles; 20971 return new Y.EventHandle(handles); 20972 20973 // If the el argument is a string, we assume it is 20974 // actually the id of the element. If the page is loaded 20975 // we convert el to the actual element, otherwise we 20976 // defer attaching the event until the element is 20977 // ready 20978 } else if (Y.Lang.isString(el)) { 20979 20980 // oEl = (compat) ? Y.DOM.byId(el) : Y.Selector.query(el); 20981 20982 if (compat) { 20983 oEl = Y.DOM.byId(el); 20984 } else { 20985 20986 oEl = Y.Selector.query(el); 20987 20988 switch (oEl.length) { 20989 case 0: 20990 oEl = null; 20991 break; 20992 case 1: 20993 oEl = oEl[0]; 20994 break; 20995 default: 20996 args[2] = oEl; 20997 return Event._attach(args, conf); 20998 } 20999 } 21000 21001 if (oEl) { 21002 21003 el = oEl; 21004 21005 // Not found = defer adding the event until the element is available 21006 } else { 21007 21008 ret = Event.onAvailable(el, function() { 21009 21010 ret.handle = Event._attach(args, conf); 21011 21012 }, Event, true, false, compat); 21013 21014 return ret; 21015 21016 } 21017 } 21018 21019 // Element should be an html element or node 21020 if (!el) { 21021 return false; 21022 } 21023 21024 if (Y.Node && Y.instanceOf(el, Y.Node)) { 21025 el = Y.Node.getDOMNode(el); 21026 } 21027 21028 cewrapper = Event._createWrapper(el, type, capture, compat, facade); 21029 if (overrides) { 21030 Y.mix(cewrapper.overrides, overrides); 21031 } 21032 21033 if (el == win && type == "load") { 21034 21035 // if the load is complete, fire immediately. 21036 // all subscribers, including the current one 21037 // will be notified. 21038 if (YUI.Env.windowLoaded) { 21039 fireNow = true; 21040 } 21041 } 21042 21043 if (compat) { 21044 args.pop(); 21045 } 21046 21047 context = args[3]; 21048 21049 // set context to the Node if not specified 21050 // ret = cewrapper.on.apply(cewrapper, trimmedArgs); 21051 ret = cewrapper._on(fn, context, (args.length > 4) ? args.slice(4) : null); 21052 21053 if (fireNow) { 21054 cewrapper.fire(); 21055 } 21056 21057 return ret; 21058 21059 }, 21060 21061 /** 21062 * Removes an event listener. Supports the signature the event was bound 21063 * with, but the preferred way to remove listeners is using the handle 21064 * that is returned when using Y.on 21065 * 21066 * @method detach 21067 * 21068 * @param {String} type the type of event to remove. 21069 * @param {Function} fn the method the event invokes. If fn is 21070 * undefined, then all event handlers for the type of event are 21071 * removed. 21072 * @param {String|HTMLElement|Array|NodeList|EventHandle} el An 21073 * event handle, an id, an element reference, or a collection 21074 * of ids and/or elements to remove the listener from. 21075 * @return {boolean} true if the unbind was successful, false otherwise. 21076 * @static 21077 */ 21078 detach: function(type, fn, el, obj) { 21079 21080 var args=Y.Array(arguments, 0, true), compat, l, ok, i, 21081 id, ce; 21082 21083 if (args[args.length-1] === COMPAT_ARG) { 21084 compat = true; 21085 // args.pop(); 21086 } 21087 21088 if (type && type.detach) { 21089 return type.detach(); 21090 } 21091 21092 // The el argument can be a string 21093 if (typeof el == "string") { 21094 21095 // el = (compat) ? Y.DOM.byId(el) : Y.all(el); 21096 if (compat) { 21097 el = Y.DOM.byId(el); 21098 } else { 21099 el = Y.Selector.query(el); 21100 l = el.length; 21101 if (l < 1) { 21102 el = null; 21103 } else if (l == 1) { 21104 el = el[0]; 21105 } 21106 } 21107 // return Event.detach.apply(Event, args); 21108 } 21109 21110 if (!el) { 21111 return false;
21112 } 21113 21114 if (el.detach) { 21115 args.splice(2, 1); 21116 return el.detach.apply(el, args); 21117 // The el argument can be an array of elements or element ids. 21118 } else if (shouldIterate(el)) { 21119 ok = true; 21120 for (i=0, l=el.length; i<l; ++i) { 21121 args[2] = el[i]; 21122 ok = ( Y.Event.detach.apply(Y.Event, args) && ok ); 21123 } 21124 21125 return ok; 21126 } 21127 21128 if (!type || !fn || !fn.call) { 21129 return Event.purgeElement(el, false, type); 21130 } 21131 21132 id = 'event:' + Y.stamp(el) + type; 21133 ce = _wrappers[id]; 21134 21135 if (ce) { 21136 return ce.detach(fn); 21137 } else { 21138 return false; 21139 } 21140 21141 }, 21142 21143 /** 21144 * Finds the event in the window object, the caller's arguments, or 21145 * in the arguments of another method in the callstack. This is 21146 * executed automatically for events registered through the event 21147 * manager, so the implementer should not normally need to execute 21148 * this function at all. 21149 * @method getEvent 21150 * @param {Event} e the event parameter from the handler 21151 * @param {HTMLElement} el the element the listener was attached to 21152 * @return {Event} the event 21153 * @static 21154 */ 21155 getEvent: function(e, el, noFacade) { 21156 var ev = e || win.event; 21157 21158 return (noFacade) ? ev : 21159 new Y.DOMEventFacade(ev, el, _wrappers['event:' + Y.stamp(el) + e.type]); 21160 }, 21161 21162 /** 21163 * Generates an unique ID for the element if it does not already 21164 * have one. 21165 * @method generateId 21166 * @param el the element to create the id for 21167 * @return {string} the resulting id of the element 21168 * @static 21169 */ 21170 generateId: function(el) { 21171 return Y.DOM.generateID(el); 21172 }, 21173 21174 /** 21175 * We want to be able to use getElementsByTagName as a collection 21176 * to attach a group of events to. Unfortunately, different 21177 * browsers return different types of collections. This function 21178 * tests to determine if the object is array-like. It will also 21179 * fail if the object is an array, but is empty. 21180 * @method _isValidCollection 21181 * @param o the object to test 21182 * @return {boolean} true if the object is array-like and populated 21183 * @deprecated was not meant to be used directly 21184 * @static 21185 * @private 21186 */ 21187 _isValidCollection: shouldIterate, 21188 21189 /** 21190 * hook up any deferred listeners 21191 * @method _load 21192 * @static 21193 * @private 21194 */ 21195 _load: function(e) { 21196 if (!_loadComplete) { 21197 _loadComplete = true; 21198 21199 // Just in case DOMReady did not go off for some reason 21200 // E._ready(); 21201 if (Y.fire) { 21202 Y.fire(EVENT_READY); 21203 } 21204 21205 // Available elements may not have been detected before the 21206 // window load event fires. Try to find them now so that the 21207 // the user is more likely to get the onAvailable notifications 21208 // before the window load notification 21209 Event._poll(); 21210 } 21211 }, 21212 21213 /** 21214 * Polling function that runs before the onload event fires, 21215 * attempting to attach to DOM Nodes as soon as they are 21216 * available 21217 * @method _poll 21218 * @static 21219 * @private 21220 */ 21221 _poll: function() { 21222 if (Event.locked) { 21223 return; 21224 } 21225 21226 if (Y.UA.ie && !YUI.Env.DOMReady) { 21227 // Hold off if DOMReady has not fired and check current 21228 // readyState to protect against the IE operation aborted 21229 // issue. 21230 Event.startInterval(); 21231 return; 21232 } 21233 21234 Event.locked = true; 21235 21236 // keep trying until after the page is loaded. We need to 21237 // check the page load state prior to trying to bind the 21238 // elements so that we can be certain all elements have been 21239 // tested appropriately 21240 var i, len, item, el, notAvail, executeItem, 21241 tryAgain = !_loadComplete; 21242 21243 if (!tryAgain) { 21244 tryAgain = (_retryCount > 0); 21245 } 21246 21247 // onAvailable 21248 notAvail = []; 21249 21250 executeItem = function (el, item) { 21251 var context, ov = item.override; 21252 try { 21253 if (item.compat) { 21254 if (item.override) { 21255 if (ov === true) { 21256 context = item.obj; 21257 } else { 21258 context = ov; 21259 } 21260 } else { 21261 context = el; 21262 } 21263 item.fn.call(context, item.obj); 21264 } else { 21265 context = item.obj || Y.one(el); 21266 item.fn.apply(context, (Y.Lang.isArray(ov)) ? ov : []); 21267 } 21268 } catch (e) { 21269 } 21270 }; 21271 21272 // onAvailable 21273 for (i=0,len=_avail.length; i<len; ++i) { 21274 item = _avail[i]; 21275 if (item && !item.checkReady) { 21276 21277 // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id); 21278 el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true); 21279 21280 if (el) { 21281 executeItem(el, item); 21282 _avail[i] = null; 21283 } else { 21284 notAvail.push(item); 21285 } 21286 } 21287 } 21288 21289 // onContentReady 21290 for (i=0,len=_avail.length; i<len; ++i) { 21291 item = _avail[i]; 21292 if (item && item.checkReady) { 21293 21294 // el = (item.compat) ? Y.DOM.byId(item.id) : Y.one(item.id); 21295 el = (item.compat) ? Y.DOM.byId(item.id) : Y.Selector.query(item.id, null, true); 21296 21297 if (el) { 21298 // The element is available, but not necessarily ready 21299 // @todo should we test parentNode.nextSibling? 21300 if (_loadComplete || (el.get && el.get('nextSibling')) || el.nextSibling) { 21301 executeItem(el, item); 21302 _avail[i] = null; 21303 } 21304 } else { 21305 notAvail.push(item); 21306 } 21307 } 21308 } 21309 21310 _retryCount = (notAvail.length === 0) ? 0 : _retryCount - 1; 21311 21312 if (tryAgain) { 21313 // we may need to strip the nulled out items here 21314 Event.startInterval(); 21315 } else { 21316 clearInterval(Event._interval); 21317 Event._interval = null; 21318 } 21319 21320 Event.locked = false;
21321 21322 return; 21323 21324 }, 21325 21326 /** 21327 * Removes all listeners attached to the given element via addListener. 21328 * Optionally, the node's children can also be purged. 21329 * Optionally, you can specify a specific type of event to remove. 21330 * @method purgeElement 21331 * @param {HTMLElement} el the element to purge 21332 * @param {boolean} recurse recursively purge this element's children 21333 * as well. Use with caution. 21334 * @param {string} type optional type of listener to purge. If 21335 * left out, all listeners will be removed 21336 * @static 21337 */ 21338 purgeElement: function(el, recurse, type) { 21339 // var oEl = (Y.Lang.isString(el)) ? Y.one(el) : el, 21340 var oEl = (Y.Lang.isString(el)) ? Y.Selector.query(el, null, true) : el, 21341 lis = Event.getListeners(oEl, type), i, len, children, child; 21342 21343 if (recurse && oEl) { 21344 lis = lis || []; 21345 children = Y.Selector.query('*', oEl); 21346 len = children.length; 21347 for (i = 0; i < len; ++i) { 21348 child = Event.getListeners(children[i], type); 21349 if (child) { 21350 lis = lis.concat(child); 21351 } 21352 } 21353 } 21354 21355 if (lis) { 21356 for (i = 0, len = lis.length; i < len; ++i) { 21357 lis[i].detachAll(); 21358 } 21359 } 21360 21361 }, 21362 21363 /** 21364 * Removes all object references and the DOM proxy subscription for 21365 * a given event for a DOM node. 21366 * 21367 * @method _clean 21368 * @param wrapper {CustomEvent} Custom event proxy for the DOM 21369 * subscription 21370 * @private 21371 * @static 21372 * @since 3.4.0 21373 */ 21374 _clean: function (wrapper) { 21375 var key = wrapper.key, 21376 domkey = wrapper.domkey; 21377 21378 remove(wrapper.el, wrapper.type, wrapper.fn, wrapper.capture); 21379 delete _wrappers[key]; 21380 delete Y._yuievt.events[key]; 21381 if (_el_events[domkey]) { 21382 delete _el_events[domkey][key]; 21383 if (!Y.Object.size(_el_events[domkey])) { 21384 delete _el_events[domkey]; 21385 } 21386 } 21387 }, 21388 21389 /** 21390 * Returns all listeners attached to the given element via addListener. 21391 * Optionally, you can specify a specific type of event to return. 21392 * @method getListeners 21393 * @param el {HTMLElement|string} the element or element id to inspect 21394 * @param type {string} optional type of listener to return. If 21395 * left out, all listeners will be returned 21396 * @return {CustomEvent} the custom event wrapper for the DOM event(s) 21397 * @static 21398 */ 21399 getListeners: function(el, type) { 21400 var ek = Y.stamp(el, true), evts = _el_events[ek], 21401 results=[] , key = (type) ? 'event:' + ek + type : null, 21402 adapters = _eventenv.plugins; 21403 21404 if (!evts) { 21405 return null; 21406 } 21407 21408 if (key) { 21409 // look for synthetic events 21410 if (adapters[type] && adapters[type].eventDef) { 21411 key += '_synth'; 21412 } 21413 21414 if (evts[key]) { 21415 results.push(evts[key]); 21416 } 21417 21418 // get native events as well 21419 key += 'native'; 21420 if (evts[key]) { 21421 results.push(evts[key]); 21422 } 21423 21424 } else { 21425 Y.each(evts, function(v, k) { 21426 results.push(v); 21427 }); 21428 } 21429 21430 return (results.length) ? results : null; 21431 }, 21432 21433 /** 21434 * Removes all listeners registered by pe.event. Called 21435 * automatically during the unload event. 21436 * @method _unload 21437 * @static 21438 * @private 21439 */ 21440 _unload: function(e) { 21441 Y.each(_wrappers, function(v, k) { 21442 if (v.type == 'unload') { 21443 v.fire(e); 21444 } 21445 v.detachAll(); 21446 }); 21447 remove(win, "unload", onUnload); 21448 }, 21449 21450 /** 21451 * Adds a DOM event directly without the caching, cleanup, context adj, etc 21452 *
21453 * @method nativeAdd 21454 * @param {HTMLElement} el the element to bind the handler to 21455 * @param {string} type the type of event handler 21456 * @param {function} fn the callback to invoke 21457 * @param {Boolean} capture capture or bubble phase 21458 * @static 21459 * @private 21460 */ 21461 nativeAdd: add, 21462 21463 /** 21464 * Basic remove listener 21465 * 21466 * @method nativeRemove 21467 * @param {HTMLElement} el the element to bind the handler to 21468 * @param {string} type the type of event handler 21469 * @param {function} fn the callback to invoke 21470 * @param {Boolean} capture capture or bubble phase 21471 * @static 21472 * @private 21473 */ 21474 nativeRemove: remove 21475 }; 21476 21477}(); 21478 21479Y.Event = Event; 21480 21481if (config.injected || YUI.Env.windowLoaded) { 21482 onLoad(); 21483} else { 21484 add(win, "load", onLoad); 21485} 21486 21487// Process onAvailable/onContentReady items when when the DOM is ready in IE 21488if (Y.UA.ie) { 21489 Y.on(EVENT_READY, Event._poll); 21490 21491 // In IE6 and below, detach event handlers when the page is unloaded in 21492 // order to try and prevent cross-page memory leaks. This isn't done in 21493 // other browsers because a) it's not necessary, and b) it breaks the 21494 // back/forward cache. 21495 if (Y.UA.ie < 7) { 21496 try { 21497 add(win, "unload", onUnload); 21498 } catch(e) { 21499 } 21500 } 21501} 21502 21503Event.Custom = Y.CustomEvent; 21504Event.Subscriber = Y.Subscriber; 21505Event.Target = Y.EventTarget; 21506Event.Handle = Y.EventHandle; 21507Event.Facade = Y.EventFacade; 21508 21509Event._poll(); 21510 21511}()); 21512 21513/** 21514 * DOM event listener abstraction layer 21515 * @module event 21516 * @submodule event-base 21517 */ 21518 21519/** 21520 * Executes the callback as soon as the specified element 21521 * is detected in the DOM. This function expects a selector 21522 * string for the element(s) to detect. If you already have 21523 * an element reference, you don't need this event. 21524 * @event available 21525 * @param type {string} 'available' 21526 * @param fn {function} the callback function to execute. 21527 * @param el {string} an selector for the element(s) to attach 21528 * @param context optional argument that specifies what 'this' refers to. 21529 * @param args* 0..n additional arguments to pass on to the callback function. 21530 * These arguments will be added after the event object. 21531 * @return {EventHandle} the detach handle 21532 * @for YUI 21533 */ 21534Y.Env.evt.plugins.available = { 21535 on: function(type, fn, id, o) { 21536 var a = arguments.length > 4 ? Y.Array(arguments, 4, true) : null; 21537 return Y.Event.onAvailable.call(Y.Event, id, fn, o, a); 21538 } 21539}; 21540 21541/** 21542 * Executes the callback as soon as the specified element 21543 * is detected in the DOM with a nextSibling property 21544 * (indicating that the element's children are available). 21545 * This function expects a selector 21546 * string for the element(s) to detect. If you already have 21547 * an element reference, you don't need this event. 21548 * @event contentready 21549 * @param type {string} 'contentready' 21550 * @param fn {function} the callback function to execute. 21551 * @param el {string} an selector for the element(s) to attach. 21552 * @param context optional argument that specifies what 'this' refers to. 21553 * @param args* 0..n additional arguments to pass on to the callback function. 21554 * These arguments will be added after the event object. 21555 * @return {EventHandle} the detach handle 21556 * @for YUI 21557 */ 21558Y.Env.evt.plugins.contentready = { 21559 on: function(type, fn, id, o) { 21560 var a = arguments.length > 4 ? Y.Array(arguments, 4, true) : null; 21561 return Y.Event.onContentReady.call(Y.Event, id, fn, o, a); 21562 } 21563}; 21564 21565 21566}, 'patched-v3.18.1', {"requires": ["event-custom-base"]}); 21567 21568YUI.add('event-custom-base', function (Y, NAME) { 21569 21570/** 21571 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 21572 * events. 21573 * @module event-custom 21574 */ 21575 21576Y.Env.evt = { 21577 handles: {}, 21578 plugins: {} 21579}; 21580 21581/** 21582 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 21583 * events. 21584 * @module event-custom 21585 * @submodule event-custom-base 21586 */ 21587 21588/** 21589 * Allows for the insertion of methods that are executed before or after 21590 * a specified method 21591 * @class Do 21592 * @static 21593 */ 21594 21595var DO_BEFORE = 0, 21596 DO_AFTER = 1, 21597 21598DO = { 21599 21600 /** 21601 * Cache of objects touched by the utility 21602 * @property objs 21603 * @static 21604 * @deprecated Since 3.6.0. The `_yuiaop` property on the AOP'd object 21605 * replaces the role of this property, but is considered to be private, and 21606 * is only mentioned to provide a migration path. 21607 * 21608 * If you have a use case which warrants migration to the _yuiaop property,
21609 * please file a ticket to let us know what it's used for and we can see if 21610 * we need to expose hooks for that functionality more formally. 21611 */ 21612 objs: null, 21613 21614 /** 21615 * <p>Execute the supplied method before the specified function. Wrapping 21616 * function may optionally return an instance of the following classes to 21617 * further alter runtime behavior:</p> 21618 * <dl> 21619 * <dt></code>Y.Do.Halt(message, returnValue)</code></dt> 21620 * <dd>Immediatly stop execution and return 21621 * <code>returnValue</code>. No other wrapping functions will be 21622 * executed.</dd> 21623 * <dt></code>Y.Do.AlterArgs(message, newArgArray)</code></dt> 21624 * <dd>Replace the arguments that the original function will be 21625 * called with.</dd> 21626 * <dt></code>Y.Do.Prevent(message)</code></dt> 21627 * <dd>Don't execute the wrapped function. Other before phase 21628 * wrappers will be executed.</dd> 21629 * </dl> 21630 * 21631 * @method before 21632 * @param fn {Function} the function to execute 21633 * @param obj the object hosting the method to displace 21634 * @param sFn {string} the name of the method to displace 21635 * @param c The execution context for fn 21636 * @param arg* {mixed} 0..n additional arguments to supply to the subscriber 21637 * when the event fires. 21638 * @return {EventHandle} handle for the subscription 21639 * @static 21640 */ 21641 before: function(fn, obj, sFn, c) { 21642 var f = fn, a; 21643 if (c) { 21644 a = [fn, c].concat(Y.Array(arguments, 4, true)); 21645 f = Y.rbind.apply(Y, a); 21646 } 21647 21648 return this._inject(DO_BEFORE, f, obj, sFn); 21649 }, 21650 21651 /** 21652 * <p>Execute the supplied method after the specified function. Wrapping 21653 * function may optionally return an instance of the following classes to 21654 * further alter runtime behavior:</p> 21655 * <dl> 21656 * <dt></code>Y.Do.Halt(message, returnValue)</code></dt> 21657 * <dd>Immediatly stop execution and return 21658 * <code>returnValue</code>. No other wrapping functions will be 21659 * executed.</dd> 21660 * <dt></code>Y.Do.AlterReturn(message, returnValue)</code></dt> 21661 * <dd>Return <code>returnValue</code> instead of the wrapped 21662 * method's original return value. This can be further altered by 21663 * other after phase wrappers.</dd> 21664 * </dl> 21665 * 21666 * <p>The static properties <code>Y.Do.originalRetVal</code> and 21667 * <code>Y.Do.currentRetVal</code> will be populated for reference.</p> 21668 * 21669 * @method after 21670 * @param fn {Function} the function to execute 21671 * @param obj the object hosting the method to displace 21672 * @param sFn {string} the name of the method to displace 21673 * @param c The execution context for fn 21674 * @param arg* {mixed} 0..n additional arguments to supply to the subscriber 21675 * @return {EventHandle} handle for the subscription 21676 * @static 21677 */ 21678 after: function(fn, obj, sFn, c) { 21679 var f = fn, a; 21680 if (c) { 21681 a = [fn, c].concat(Y.Array(arguments, 4, true)); 21682 f = Y.rbind.apply(Y, a); 21683 } 21684 21685 return this._inject(DO_AFTER, f, obj, sFn); 21686 }, 21687 21688 /** 21689 * Execute the supplied method before or after the specified function. 21690 * Used by <code>before</code> and <code>after</code>. 21691 * 21692 * @method _inject 21693 * @param when {string} before or after 21694 * @param fn {Function} the function to execute 21695 * @param obj the object hosting the method to displace 21696 * @param sFn {string} the name of the method to displace 21697 * @param c The execution context for fn 21698 * @return {EventHandle} handle for the subscription 21699 * @private 21700 * @static 21701 */ 21702 _inject: function(when, fn, obj, sFn) { 21703 // object id 21704 var id = Y.stamp(obj), o, sid; 21705 21706 if (!obj._yuiaop) { 21707 // create a map entry for the obj if it doesn't exist, to hold overridden methods 21708 obj._yuiaop = {}; 21709 } 21710 21711 o = obj._yuiaop; 21712 21713 if (!o[sFn]) { 21714 // create a map entry for the method if it doesn't exist 21715 o[sFn] = new Y.Do.Method(obj, sFn); 21716 21717 // re-route the method to our wrapper 21718 obj[sFn] = function() { 21719 return o[sFn].exec.apply(o[sFn], arguments); 21720 }; 21721 } 21722 21723 // subscriber id 21724 sid = id + Y.stamp(fn) + sFn; 21725 21726 // register the callback 21727 o[sFn].register(sid, fn, when); 21728 21729 return new Y.EventHandle(o[sFn], sid); 21730 }, 21731 21732 /** 21733 * Detach a before or after subscription. 21734 * 21735 * @method detach 21736 * @param handle {EventHandle} the subscription handle 21737 * @static 21738 */ 21739 detach: function(handle) { 21740 if (handle.detach) { 21741 handle.detach(); 21742 } 21743 } 21744}; 21745 21746Y.Do = DO; 21747 21748////////////////////////////////////////////////////////////////////////// 21749 21750/** 21751 * Contains the return value from the wrapped method, accessible 21752 * by 'after' event listeners. 21753 * 21754 * @property originalRetVal 21755 * @static 21756 * @since 3.2.0 21757 */ 21758
21759/** 21760 * Contains the current state of the return value, consumable by 21761 * 'after' event listeners, and updated if an after subscriber 21762 * changes the return value generated by the wrapped function. 21763 * 21764 * @property currentRetVal 21765 * @static 21766 * @since 3.2.0 21767 */ 21768 21769////////////////////////////////////////////////////////////////////////// 21770 21771/** 21772 * Wrapper for a displaced method with aop enabled 21773 * @class Do.Method 21774 * @constructor 21775 * @param obj The object to operate on 21776 * @param sFn The name of the method to displace 21777 */ 21778DO.Method = function(obj, sFn) { 21779 this.obj = obj; 21780 this.methodName = sFn; 21781 this.method = obj[sFn]; 21782 this.before = {}; 21783 this.after = {}; 21784}; 21785 21786/** 21787 * Register a aop subscriber 21788 * @method register 21789 * @param sid {string} the subscriber id 21790 * @param fn {Function} the function to execute 21791 * @param when {string} when to execute the function 21792 */ 21793DO.Method.prototype.register = function (sid, fn, when) { 21794 if (when) { 21795 this.after[sid] = fn; 21796 } else { 21797 this.before[sid] = fn; 21798 } 21799}; 21800 21801/** 21802 * Unregister a aop subscriber 21803 * @method delete 21804 * @param sid {string} the subscriber id 21805 * @param fn {Function} the function to execute 21806 * @param when {string} when to execute the function 21807 */ 21808DO.Method.prototype._delete = function (sid) { 21809 delete this.before[sid]; 21810 delete this.after[sid]; 21811}; 21812 21813/** 21814 * <p>Execute the wrapped method. All arguments are passed into the wrapping 21815 * functions. If any of the before wrappers return an instance of 21816 * <code>Y.Do.Halt</code> or <code>Y.Do.Prevent</code>, neither the wrapped 21817 * function nor any after phase subscribers will be executed.</p> 21818 * 21819 * <p>The return value will be the return value of the wrapped function or one 21820 * provided by a wrapper function via an instance of <code>Y.Do.Halt</code> or 21821 * <code>Y.Do.AlterReturn</code>. 21822 * 21823 * @method exec 21824 * @param arg* {any} Arguments are passed to the wrapping and wrapped functions 21825 * @return {any} Return value of wrapped function unless overwritten (see above) 21826 */ 21827DO.Method.prototype.exec = function () { 21828 21829 var args = Y.Array(arguments, 0, true), 21830 i, ret, newRet, 21831 bf = this.before, 21832 af = this.after, 21833 prevented = false; 21834 21835 // execute before 21836 for (i in bf) { 21837 if (bf.hasOwnProperty(i)) { 21838 ret = bf[i].apply(this.obj, args); 21839 if (ret) { 21840 switch (ret.constructor) { 21841 case DO.Halt: 21842 return ret.retVal; 21843 case DO.AlterArgs: 21844 args = ret.newArgs; 21845 break; 21846 case DO.Prevent: 21847 prevented = true; 21848 break; 21849 default: 21850 } 21851 } 21852 } 21853 } 21854 21855 // execute method 21856 if (!prevented) { 21857 ret = this.method.apply(this.obj, args); 21858 } 21859 21860 DO.originalRetVal = ret; 21861 DO.currentRetVal = ret; 21862 21863 // execute after methods. 21864 for (i in af) { 21865 if (af.hasOwnProperty(i)) { 21866 newRet = af[i].apply(this.obj, args); 21867 // Stop processing if a Halt object is returned 21868 if (newRet && newRet.constructor === DO.Halt) { 21869 return newRet.retVal; 21870 // Check for a new return value 21871 } else if (newRet && newRet.constructor === DO.AlterReturn) { 21872 ret = newRet.newRetVal; 21873 // Update the static retval state 21874 DO.currentRetVal = ret; 21875 } 21876 } 21877 } 21878 21879 return ret; 21880}; 21881 21882////////////////////////////////////////////////////////////////////////// 21883 21884/** 21885 * Return an AlterArgs object when you want to change the arguments that 21886 * were passed into the function. Useful for Do.before subscribers. An 21887 * example would be a service that scrubs out illegal characters prior to 21888 * executing the core business logic. 21889 * @class Do.AlterArgs 21890 * @constructor 21891 * @param msg {String} (optional) Explanation of the altered return value 21892 * @param newArgs {Array} Call parameters to be used for the original method 21893 * instead of the arguments originally passed in. 21894 */ 21895DO.AlterArgs = function(msg, newArgs) { 21896 this.msg = msg; 21897 this.newArgs = newArgs; 21898}; 21899 21900/** 21901 * Return an AlterReturn object when you want to change the result returned 21902 * from the core method to the caller. Useful for Do.after subscribers. 21903 * @class Do.AlterReturn 21904 * @constructor 21905 * @param msg {String} (optional) Explanation of the altered return value 21906 * @param newRetVal {any} Return value passed to code that invoked the wrapped 21907 * function. 21908 */ 21909DO.AlterReturn = function(msg, newRetVal) { 21910 this.msg = msg; 21911 this.newRetVal = newRetVal; 21912}; 21913 21914/** 21915 * Return a Halt object when you want to terminate the execution 21916 * of all subsequent subscribers as well as the wrapped method 21917 * if it has not exectued yet. Useful for Do.before subscribers. 21918 * @class Do.Halt 21919 * @constructor 21920 * @param msg {String} (optional) Explanation of why the termination was done 21921 * @param retVal {any} Return value passed to code that invoked the wrapped 21922 * function. 21923 */ 21924DO.Halt = function(msg, retVal) { 21925 this.msg = msg; 21926 this.retVal = retVal; 21927}; 21928 21929/** 21930 * Return a Prevent object when you want to prevent the wrapped function 21931 * from executing, but want the remaining listeners to execute. Useful 21932 * for Do.before subscribers. 21933 * @class Do.Prevent 21934 * @constructor 21935 * @param msg {String} (optional) Explanation of why the termination was done 21936 */ 21937DO.Prevent = function(msg) { 21938 this.msg = msg; 21939}; 21940 21941/** 21942 * Return an Error object when you want to terminate the execution 21943 * of all subsequent method calls. 21944 * @class Do.Error 21945 * @constructor 21946 * @param msg {String} (optional) Explanation of the altered return value 21947 * @param retVal {any} Return value passed to code that invoked the wrapped 21948 * function. 21949 * @deprecated use Y.Do.Halt or Y.Do.Prevent 21950 */ 21951DO.Error = DO.Halt; 21952 21953
21954////////////////////////////////////////////////////////////////////////// 21955 21956/** 21957 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 21958 * events. 21959 * @module event-custom 21960 * @submodule event-custom-base 21961 */ 21962 21963 21964// var onsubscribeType = "_event:onsub", 21965var YArray = Y.Array, 21966 21967 AFTER = 'after', 21968 CONFIGS = [ 21969 'broadcast', 21970 'monitored', 21971 'bubbles', 21972 'context', 21973 'contextFn', 21974 'currentTarget', 21975 'defaultFn', 21976 'defaultTargetOnly', 21977 'details', 21978 'emitFacade', 21979 'fireOnce', 21980 'async', 21981 'host', 21982 'preventable', 21983 'preventedFn', 21984 'queuable', 21985 'silent', 21986 'stoppedFn', 21987 'target', 21988 'type' 21989 ], 21990 21991 CONFIGS_HASH = YArray.hash(CONFIGS), 21992 21993 nativeSlice = Array.prototype.slice, 21994 21995 YUI3_SIGNATURE = 9, 21996 YUI_LOG = 'yui:log', 21997 21998 mixConfigs = function(r, s, ov) { 21999 var p; 22000 22001 for (p in s) { 22002 if (CONFIGS_HASH[p] && (ov || !(p in r))) { 22003 r[p] = s[p]; 22004 } 22005 } 22006 22007 return r; 22008 }; 22009 22010/** 22011 * The CustomEvent class lets you define events for your application 22012 * that can be subscribed to by one or more independent component. 22013 * 22014 * @param {String} type The type of event, which is passed to the callback 22015 * when the event fires. 22016 * @param {object} defaults configuration object. 22017 * @class CustomEvent 22018 * @constructor 22019 */ 22020 22021 /** 22022 * The type of event, returned to subscribers when the event fires 22023 * @property type 22024 * @type string 22025 */ 22026 22027/** 22028 * By default all custom events are logged in the debug build, set silent 22029 * to true to disable debug outpu for this event. 22030 * @property silent 22031 * @type boolean 22032 */ 22033 22034Y.CustomEvent = function(type, defaults) { 22035 22036 this._kds = Y.CustomEvent.keepDeprecatedSubs; 22037 22038 this.id = Y.guid(); 22039 22040 this.type = type; 22041 this.silent = this.logSystem = (type === YUI_LOG); 22042 22043 if (this._kds) { 22044 /** 22045 * The subscribers to this event 22046 * @property subscribers 22047 * @type Subscriber {} 22048 * @deprecated 22049 */ 22050 22051 /** 22052 * 'After' subscribers 22053 * @property afters 22054 * @type Subscriber {} 22055 * @deprecated 22056 */ 22057 this.subscribers = {}; 22058 this.afters = {}; 22059 } 22060 22061 if (defaults) { 22062 mixConfigs(this, defaults, true); 22063 } 22064}; 22065 22066/** 22067 * Static flag to enable population of the <a href="#property_subscribers">`subscribers`</a> 22068 * and <a href="#property_subscribers">`afters`</a> properties held on a `CustomEvent` instance. 22069 * 22070 * These properties were changed to private properties (`_subscribers` and `_afters`), and 22071 * converted from objects to arrays for performance reasons. 22072 * 22073 * Setting this property to true will populate the deprecated `subscribers` and `afters` 22074 * properties for people who may be using them (which is expected to be rare). There will 22075 * be a performance hit, compared to the new array based implementation. 22076 * 22077 * If you are using these deprecated properties for a use case which the public API 22078 * does not support, please file an enhancement request, and we can provide an alternate 22079 * public implementation which doesn't have the performance cost required to maintiain the 22080 * properties as objects. 22081 * 22082 * @property keepDeprecatedSubs 22083 * @static 22084 * @for CustomEvent 22085 * @type boolean 22086 * @default false 22087 * @deprecated 22088 */ 22089Y.CustomEvent.keepDeprecatedSubs = false; 22090 22091Y.CustomEvent.mixConfigs = mixConfigs; 22092 22093Y.CustomEvent.prototype = { 22094 22095 constructor: Y.CustomEvent, 22096 22097 /** 22098 * Monitor when an event is attached or detached. 22099 * 22100 * @property monitored 22101 * @type boolean 22102 */ 22103 22104 /** 22105 * If 0, this event does not broadcast. If 1, the YUI instance is notified 22106 * every time this event fires. If 2, the YUI instance and the YUI global 22107 * (if event is enabled on the global) are notified every time this event 22108 * fires. 22109 * @property broadcast 22110 * @type int 22111 */ 22112 22113 /** 22114 * Specifies whether this event should be queued when the host is actively 22115 * processing an event. This will effect exectution order of the callbacks 22116 * for the various events. 22117 * @property queuable 22118 * @type boolean 22119 * @default false 22120 */ 22121 22122 /** 22123 * This event has fired if true 22124 * 22125 * @property fired 22126 * @type boolean 22127 * @default false; 22128 */ 22129 22130 /** 22131 * An array containing the arguments the custom event 22132 * was last fired with. 22133 * @property firedWith 22134 * @type Array 22135 */ 22136 22137 /** 22138 * This event should only fire one time if true, and if 22139 * it has fired, any new subscribers should be notified 22140 * immediately. 22141 * 22142 * @property fireOnce 22143 * @type boolean 22144 * @default false; 22145 */ 22146 22147 /** 22148 * fireOnce listeners will fire syncronously unless async 22149 * is set to true 22150 * @property async 22151 * @type boolean 22152 * @default false 22153 */ 22154 22155 /** 22156 * Flag for stopPropagation that is modified during fire() 22157 * 1 means to stop propagation to bubble targets. 2 means
22158 * to also stop additional subscribers on this target. 22159 * @property stopped 22160 * @type int 22161 */ 22162 22163 /** 22164 * Flag for preventDefault that is modified during fire(). 22165 * if it is not 0, the default behavior for this event 22166 * @property prevented 22167 * @type int 22168 */ 22169 22170 /** 22171 * Specifies the host for this custom event. This is used 22172 * to enable event bubbling 22173 * @property host 22174 * @type EventTarget 22175 */ 22176 22177 /** 22178 * The default function to execute after event listeners 22179 * have fire, but only if the default action was not 22180 * prevented. 22181 * @property defaultFn 22182 * @type Function 22183 */ 22184 22185 /** 22186 * Flag for the default function to execute only if the 22187 * firing event is the current target. This happens only 22188 * when using custom event delegation and setting the 22189 * flag to `true` mimics the behavior of event delegation 22190 * in the DOM. 22191 * 22192 * @property defaultTargetOnly 22193 * @type Boolean 22194 * @default false 22195 */ 22196 22197 /** 22198 * The function to execute if a subscriber calls 22199 * stopPropagation or stopImmediatePropagation 22200 * @property stoppedFn 22201 * @type Function 22202 */ 22203 22204 /** 22205 * The function to execute if a subscriber calls 22206 * preventDefault 22207 * @property preventedFn 22208 * @type Function 22209 */ 22210 22211 /** 22212 * The subscribers to this event 22213 * @property _subscribers 22214 * @type Subscriber [] 22215 * @private 22216 */ 22217 22218 /** 22219 * 'After' subscribers 22220 * @property _afters 22221 * @type Subscriber [] 22222 * @private 22223 */ 22224 22225 /** 22226 * If set to true, the custom event will deliver an EventFacade object 22227 * that is similar to a DOM event object. 22228 * @property emitFacade 22229 * @type boolean 22230 * @default false 22231 */ 22232 22233 /** 22234 * Supports multiple options for listener signatures in order to 22235 * port YUI 2 apps. 22236 * @property signature 22237 * @type int 22238 * @default 9 22239 */ 22240 signature : YUI3_SIGNATURE, 22241 22242 /** 22243 * The context the the event will fire from by default. Defaults to the YUI 22244 * instance. 22245 * @property context 22246 * @type object 22247 */ 22248 context : Y, 22249 22250 /** 22251 * Specifies whether or not this event's default function 22252 * can be cancelled by a subscriber by executing preventDefault() 22253 * on the event facade 22254 * @property preventable 22255 * @type boolean 22256 * @default true 22257 */ 22258 preventable : true, 22259 22260 /** 22261 * Specifies whether or not a subscriber can stop the event propagation 22262 * via stopPropagation(), stopImmediatePropagation(), or halt() 22263 * 22264 * Events can only bubble if emitFacade is true. 22265 * 22266 * @property bubbles 22267 * @type boolean 22268 * @default true 22269 */ 22270 bubbles : true, 22271 22272 /** 22273 * Returns the number of subscribers for this event as the sum of the on() 22274 * subscribers and after() subscribers. 22275 * 22276 * @method hasSubs 22277 * @return Number 22278 */ 22279 hasSubs: function(when) { 22280 var s = 0, 22281 a = 0, 22282 subs = this._subscribers, 22283 afters = this._afters, 22284 sib = this.sibling; 22285 22286 if (subs) { 22287 s = subs.length; 22288 } 22289 22290 if (afters) { 22291 a = afters.length; 22292 } 22293 22294 if (sib) { 22295 subs = sib._subscribers; 22296 afters = sib._afters; 22297 22298 if (subs) { 22299 s += subs.length; 22300 } 22301 22302 if (afters) { 22303 a += afters.length; 22304 } 22305 } 22306 22307 if (when) { 22308 return (when === 'after') ? a : s; 22309 } 22310 22311 return (s + a); 22312 }, 22313 22314 /** 22315 * Monitor the event state for the subscribed event. The first parameter 22316 * is what should be monitored, the rest are the normal parameters when 22317 * subscribing to an event. 22318 * @method monitor 22319 * @param what {string} what to monitor ('detach', 'attach', 'publish'). 22320 * @return {EventHandle} return value from the monitor event subscription. 22321 */ 22322 monitor: function(what) { 22323 this.monitored = true; 22324 var type = this.id + '|' + this.type + '_' + what, 22325 args = nativeSlice.call(arguments, 0); 22326 args[0] = type;
22327 return this.host.on.apply(this.host, args); 22328 }, 22329 22330 /** 22331 * Get all of the subscribers to this event and any sibling event 22332 * @method getSubs 22333 * @return {Array} first item is the on subscribers, second the after. 22334 */ 22335 getSubs: function() { 22336 22337 var sibling = this.sibling, 22338 subs = this._subscribers, 22339 afters = this._afters, 22340 siblingSubs, 22341 siblingAfters; 22342 22343 if (sibling) { 22344 siblingSubs = sibling._subscribers; 22345 siblingAfters = sibling._afters; 22346 } 22347 22348 if (siblingSubs) { 22349 if (subs) { 22350 subs = subs.concat(siblingSubs); 22351 } else { 22352 subs = siblingSubs.concat(); 22353 } 22354 } else { 22355 if (subs) { 22356 subs = subs.concat(); 22357 } else { 22358 subs = []; 22359 } 22360 } 22361 22362 if (siblingAfters) { 22363 if (afters) { 22364 afters = afters.concat(siblingAfters); 22365 } else { 22366 afters = siblingAfters.concat(); 22367 } 22368 } else { 22369 if (afters) { 22370 afters = afters.concat(); 22371 } else { 22372 afters = []; 22373 } 22374 } 22375 22376 return [subs, afters]; 22377 }, 22378 22379 /** 22380 * Apply configuration properties. Only applies the CONFIG whitelist 22381 * @method applyConfig 22382 * @param o hash of properties to apply. 22383 * @param force {boolean} if true, properties that exist on the event 22384 * will be overwritten. 22385 */ 22386 applyConfig: function(o, force) { 22387 mixConfigs(this, o, force); 22388 }, 22389 22390 /** 22391 * Create the Subscription for subscribing function, context, and bound 22392 * arguments. If this is a fireOnce event, the subscriber is immediately 22393 * notified. 22394 * 22395 * @method _on 22396 * @param fn {Function} Subscription callback 22397 * @param [context] {Object} Override `this` in the callback 22398 * @param [args] {Array} bound arguments that will be passed to the callback after the arguments generated by fire() 22399 * @param [when] {String} "after" to slot into after subscribers 22400 * @return {EventHandle} 22401 * @protected 22402 */ 22403 _on: function(fn, context, args, when) { 22404 22405 22406 var s = new Y.Subscriber(fn, context, args, when), 22407 firedWith; 22408 22409 if (this.fireOnce && this.fired) { 22410 22411 firedWith = this.firedWith; 22412 22413 // It's a little ugly for this to know about facades, 22414 // but given the current breakup, not much choice without 22415 // moving a whole lot of stuff around. 22416 if (this.emitFacade && this._addFacadeToArgs) { 22417 this._addFacadeToArgs(firedWith); 22418 } 22419 22420 if (this.async) { 22421 setTimeout(Y.bind(this._notify, this, s, firedWith), 0); 22422 } else { 22423 this._notify(s, firedWith); 22424 } 22425 } 22426 22427 if (when === AFTER) { 22428 if (!this._afters) { 22429 this._afters = []; 22430 } 22431 this._afters.push(s); 22432 } else { 22433 if (!this._subscribers) { 22434 this._subscribers = []; 22435 } 22436 this._subscribers.push(s); 22437 } 22438 22439 if (this._kds) { 22440 if (when === AFTER) { 22441 this.afters[s.id] = s; 22442 } else { 22443 this.subscribers[s.id] = s; 22444 } 22445 } 22446 22447 return new Y.EventHandle(this, s); 22448 }, 22449 22450 /** 22451 * Listen for this event 22452 * @method subscribe 22453 * @param {Function} fn The function to execute. 22454 * @return {EventHandle} Unsubscribe handle. 22455 * @deprecated use on. 22456 */ 22457 subscribe: function(fn, context) { 22458 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null; 22459 return this._on(fn, context, a, true); 22460 }, 22461 22462 /** 22463 * Listen for this event 22464 * @method on 22465 * @param {Function} fn The function to execute. 22466 * @param {object} context optional execution context. 22467 * @param {mixed} arg* 0..n additional arguments to supply to the subscriber 22468 * when the event fires. 22469 * @return {EventHandle} An object with a detach method to detch the handler(s). 22470 */ 22471 on: function(fn, context) { 22472 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null; 22473 22474 if (this.monitored && this.host) { 22475 this.host._monitor('attach', this, { 22476 args: arguments 22477 }); 22478 } 22479 return this._on(fn, context, a, true); 22480 }, 22481 22482 /** 22483 * Listen for this event after the normal subscribers have been notified and 22484 * the default behavior has been applied. If a normal subscriber prevents the 22485 * default behavior, it also prevents after listeners from firing. 22486 * @method after 22487 * @param {Function} fn The function to execute. 22488 * @param {object} context optional execution context. 22489 * @param {mixed} arg* 0..n additional arguments to supply to the subscriber 22490 * when the event fires. 22491 * @return {EventHandle} handle Unsubscribe handle. 22492 */ 22493 after: function(fn, context) { 22494 var a = (arguments.length > 2) ? nativeSlice.call(arguments, 2) : null; 22495 return this._on(fn, context, a, AFTER); 22496 }, 22497 22498 /** 22499 * Detach listeners. 22500 * @method detach 22501 * @param {Function} fn The subscribed function to remove, if not supplied 22502 * all will be removed. 22503 * @param {Object} context The context object passed to subscribe. 22504 * @return {Number} returns the number of subscribers unsubscribed. 22505 */ 22506 detach: function(fn, context) { 22507 // unsubscribe handle 22508 if (fn && fn.detach) { 22509 return fn.detach(); 22510 } 22511 22512 var i, s, 22513 found = 0, 22514 subs = this._subscribers, 22515 afters = this._afters; 22516 22517 if (subs) { 22518 for (i = subs.length; i >= 0; i--) { 22519 s = subs[i]; 22520 if (s && (!fn || fn === s.fn)) { 22521 this._delete(s, subs, i); 22522 found++; 22523 } 22524 } 22525 } 22526 22527 if (afters) { 22528 for (i = afters.length; i >= 0; i--) { 22529 s = afters[i]; 22530 if (s && (!fn || fn === s.fn)) { 22531 this._delete(s, afters, i); 22532 found++; 22533 } 22534 } 22535 } 22536 22537 return found; 22538 }, 22539 22540 /** 22541 * Detach listeners. 22542 * @method unsubscribe 22543 * @param {Function} fn The subscribed function to remove, if not supplied 22544 * all will be removed. 22545 * @param {Object} context The context object passed to subscribe. 22546 * @return {int|undefined} returns the number of subscribers unsubscribed. 22547 * @deprecated use detach. 22548 */ 22549 unsubscribe: function() { 22550 return this.detach.apply(this, arguments); 22551 }, 22552 22553 /** 22554 * Notify a single subscriber 22555 * @method _notify 22556 * @param {Subscriber} s the subscriber. 22557 * @param {Array} args the arguments array to apply to the listener. 22558 * @protected 22559 */ 22560 _notify: function(s, args, ef) { 22561 22562 22563 var ret; 22564 22565 ret = s.notify(args, this); 22566 22567 if (false === ret || this.stopped > 1) { 22568 return false;
22569 } 22570 22571 return true; 22572 }, 22573 22574 /** 22575 * Logger abstraction to centralize the application of the silent flag 22576 * @method log 22577 * @param {string} msg message to log. 22578 * @param {string} cat log category. 22579 */ 22580 log: function(msg, cat) { 22581 }, 22582 22583 /** 22584 * Notifies the subscribers. The callback functions will be executed 22585 * from the context specified when the event was created, and with the 22586 * following parameters: 22587 * <ul> 22588 * <li>The type of event</li> 22589 * <li>All of the arguments fire() was executed with as an array</li> 22590 * <li>The custom object (if any) that was passed into the subscribe() 22591 * method</li> 22592 * </ul> 22593 * @method fire 22594 * @param {Object*} arguments an arbitrary set of parameters to pass to 22595 * the handler. 22596 * @return {boolean} false if one of the subscribers returned false, 22597 * true otherwise. 22598 * 22599 */ 22600 fire: function() { 22601 22602 // push is the fastest way to go from arguments to arrays 22603 // for most browsers currently 22604 // http://jsperf.com/push-vs-concat-vs-slice/2 22605 22606 var args = []; 22607 args.push.apply(args, arguments); 22608 22609 return this._fire(args); 22610 }, 22611 22612 /** 22613 * Private internal implementation for `fire`, which is can be used directly by 22614 * `EventTarget` and other event module classes which have already converted from 22615 * an `arguments` list to an array, to avoid the repeated overhead. 22616 * 22617 * @method _fire 22618 * @private 22619 * @param {Array} args The array of arguments passed to be passed to handlers. 22620 * @return {boolean} false if one of the subscribers returned false, true otherwise. 22621 */ 22622 _fire: function(args) { 22623 22624 if (this.fireOnce && this.fired) { 22625 return true; 22626 } else { 22627 22628 // this doesn't happen if the event isn't published 22629 // this.host._monitor('fire', this.type, args); 22630 22631 this.fired = true; 22632 22633 if (this.fireOnce) { 22634 this.firedWith = args; 22635 } 22636 22637 if (this.emitFacade) { 22638 return this.fireComplex(args); 22639 } else { 22640 return this.fireSimple(args); 22641 } 22642 } 22643 }, 22644 22645 /** 22646 * Set up for notifying subscribers of non-emitFacade events. 22647 * 22648 * @method fireSimple 22649 * @param args {Array} Arguments passed to fire() 22650 * @return Boolean false if a subscriber returned false 22651 * @protected 22652 */ 22653 fireSimple: function(args) { 22654 this.stopped = 0; 22655 this.prevented = 0; 22656 if (this.hasSubs()) { 22657 var subs = this.getSubs(); 22658 this._procSubs(subs[0], args); 22659 this._procSubs(subs[1], args); 22660 } 22661 if (this.broadcast) { 22662 this._broadcast(args); 22663 } 22664 return this.stopped ? false : true; 22665 }, 22666 22667 // Requires the event-custom-complex module for full funcitonality. 22668 fireComplex: function(args) { 22669 args[0] = args[0] || {}; 22670 return this.fireSimple(args); 22671 }, 22672 22673 /** 22674 * Notifies a list of subscribers. 22675 * 22676 * @method _procSubs 22677 * @param subs {Array} List of subscribers 22678 * @param args {Array} Arguments passed to fire() 22679 * @param ef {} 22680 * @return Boolean false if a subscriber returns false or stops the event 22681 * propagation via e.stopPropagation(), 22682 * e.stopImmediatePropagation(), or e.halt() 22683 * @private 22684 */ 22685 _procSubs: function(subs, args, ef) { 22686 var s, i, l; 22687 22688 for (i = 0, l = subs.length; i < l; i++) { 22689 s = subs[i]; 22690 if (s && s.fn) { 22691 if (false === this._notify(s, args, ef)) { 22692 this.stopped = 2; 22693 } 22694 if (this.stopped === 2) { 22695 return false; 22696 } 22697 } 22698 } 22699 22700 return true; 22701 }, 22702 22703 /** 22704 * Notifies the YUI instance if the event is configured with broadcast = 1, 22705 * and both the YUI instance and Y.Global if configured with broadcast = 2. 22706 * 22707 * @method _broadcast 22708 * @param args {Array} Arguments sent to fire() 22709 * @private 22710 */ 22711 _broadcast: function(args) { 22712 if (!this.stopped && this.broadcast) { 22713 22714 var a = args.concat(); 22715 a.unshift(this.type); 22716 22717 if (this.host !== Y) { 22718 Y.fire.apply(Y, a); 22719 } 22720 22721 if (this.broadcast === 2) { 22722 Y.Global.fire.apply(Y.Global, a); 22723 } 22724 } 22725 }, 22726 22727 /** 22728 * Removes all listeners 22729 * @method unsubscribeAll 22730 * @return {Number} The number of listeners unsubscribed. 22731 * @deprecated use detachAll. 22732 */ 22733 unsubscribeAll: function() { 22734 return this.detachAll.apply(this, arguments); 22735 }, 22736 22737 /** 22738 * Removes all listeners 22739 * @method detachAll 22740 * @return {Number} The number of listeners unsubscribed. 22741 */ 22742 detachAll: function() { 22743 return this.detach(); 22744 }, 22745 22746 /** 22747 * Deletes the subscriber from the internal store of on() and after() 22748 * subscribers. 22749 * 22750 * @method _delete 22751 * @param s subscriber object. 22752 * @param subs (optional) on or after subscriber array 22753 * @param index (optional) The index found. 22754 * @private 22755 */ 22756 _delete: function(s, subs, i) { 22757 var when = s._when; 22758 22759 if (!subs) { 22760 subs = (when === AFTER) ? this._afters : this._subscribers; 22761 } 22762 22763 if (subs) { 22764 i = YArray.indexOf(subs, s, 0); 22765 22766 if (s && subs[i] === s) { 22767 subs.splice(i, 1); 22768 } 22769 } 22770 22771 if (this._kds) { 22772 if (when === AFTER) { 22773 delete this.afters[s.id]; 22774 } else { 22775 delete this.subscribers[s.id]; 22776 } 22777 } 22778 22779 if (this.monitored && this.host) { 22780 this.host._monitor('detach', this, { 22781 ce: this, 22782 sub: s 22783 }); 22784 } 22785 22786 if (s) { 22787 s.deleted = true; 22788 } 22789 } 22790}; 22791/** 22792 * Stores the subscriber information to be used when the event fires. 22793 * @param {Function} fn The wrapped function to execute. 22794 * @param {Object} context The value of the keyword 'this' in the listener. 22795 * @param {Array} args* 0..n additional arguments to supply the listener. 22796 * 22797 * @class Subscriber 22798 * @constructor 22799 */ 22800Y.Subscriber = function(fn, context, args, when) { 22801 22802 /** 22803 * The callback that will be execute when the event fires 22804 * This is wrapped by Y.rbind if obj was supplied.
22805 * @property fn 22806 * @type Function 22807 */ 22808 this.fn = fn; 22809 22810 /** 22811 * Optional 'this' keyword for the listener 22812 * @property context 22813 * @type Object 22814 */ 22815 this.context = context; 22816 22817 /** 22818 * Unique subscriber id 22819 * @property id 22820 * @type String 22821 */ 22822 this.id = Y.guid(); 22823 22824 /** 22825 * Additional arguments to propagate to the subscriber 22826 * @property args 22827 * @type Array 22828 */ 22829 this.args = args; 22830 22831 this._when = when; 22832 22833 /** 22834 * Custom events for a given fire transaction. 22835 * @property events 22836 * @type {EventTarget} 22837 */ 22838 // this.events = null; 22839 22840 /** 22841 * This listener only reacts to the event once 22842 * @property once 22843 */ 22844 // this.once = false; 22845 22846}; 22847 22848Y.Subscriber.prototype = { 22849 constructor: Y.Subscriber, 22850 22851 _notify: function(c, args, ce) { 22852 if (this.deleted && !this.postponed) { 22853 if (this.postponed) { 22854 delete this.fn; 22855 delete this.context; 22856 } else { 22857 delete this.postponed; 22858 return null; 22859 } 22860 } 22861 var a = this.args, ret; 22862 switch (ce.signature) { 22863 case 0: 22864 ret = this.fn.call(c, ce.type, args, c); 22865 break; 22866 case 1: 22867 ret = this.fn.call(c, args[0] || null, c); 22868 break; 22869 default: 22870 if (a || args) { 22871 args = args || []; 22872 a = (a) ? args.concat(a) : args; 22873 ret = this.fn.apply(c, a); 22874 } else { 22875 ret = this.fn.call(c); 22876 } 22877 } 22878 22879 if (this.once) { 22880 ce._delete(this); 22881 } 22882 22883 return ret; 22884 }, 22885 22886 /** 22887 * Executes the subscriber. 22888 * @method notify 22889 * @param args {Array} Arguments array for the subscriber. 22890 * @param ce {CustomEvent} The custom event that sent the notification. 22891 */ 22892 notify: function(args, ce) { 22893 var c = this.context, 22894 ret = true; 22895 22896 if (!c) { 22897 c = (ce.contextFn) ? ce.contextFn() : ce.context; 22898 } 22899 22900 // only catch errors if we will not re-throw them. 22901 if (Y.config && Y.config.throwFail) { 22902 ret = this._notify(c, args, ce); 22903 } else { 22904 try { 22905 ret = this._notify(c, args, ce); 22906 } catch (e) { 22907 Y.error(this + ' failed: ' + e.message, e); 22908 } 22909 } 22910 22911 return ret; 22912 }, 22913 22914 /** 22915 * Returns true if the fn and obj match this objects properties. 22916 * Used by the unsubscribe method to match the right subscriber. 22917 * 22918 * @method contains 22919 * @param {Function} fn the function to execute. 22920 * @param {Object} context optional 'this' keyword for the listener. 22921 * @return {boolean} true if the supplied arguments match this 22922 * subscriber's signature. 22923 */ 22924 contains: function(fn, context) { 22925 if (context) { 22926 return ((this.fn === fn) && this.context === context); 22927 } else { 22928 return (this.fn === fn); 22929 } 22930 }, 22931 22932 valueOf : function() { 22933 return this.id; 22934 } 22935 22936}; 22937/** 22938 * Return value from all subscribe operations 22939 * @class EventHandle 22940 * @constructor 22941 * @param {CustomEvent} evt the custom event. 22942 * @param {Subscriber} sub the subscriber. 22943 */ 22944Y.EventHandle = function(evt, sub) { 22945 22946 /** 22947 * The custom event 22948 * 22949 * @property evt 22950 * @type CustomEvent 22951 */ 22952 this.evt = evt; 22953 22954 /** 22955 * The subscriber object 22956 * 22957 * @property sub 22958 * @type Subscriber 22959 */ 22960 this.sub = sub; 22961}; 22962 22963Y.EventHandle.prototype = { 22964 batch: function(f, c) { 22965 f.call(c || this, this); 22966 if (Y.Lang.isArray(this.evt)) { 22967 Y.Array.each(this.evt, function(h) { 22968 h.batch.call(c || h, f); 22969 }); 22970 } 22971 }, 22972 22973 /** 22974 * Detaches this subscriber 22975 * @method detach 22976 * @return {Number} the number of detached listeners 22977 */ 22978 detach: function() { 22979 var evt = this.evt, detached = 0, i; 22980 if (evt) { 22981 if (Y.Lang.isArray(evt)) { 22982 for (i = 0; i < evt.length; i++) { 22983 detached += evt[i].detach(); 22984 } 22985 } else { 22986 evt._delete(this.sub); 22987 detached = 1; 22988 } 22989 22990 } 22991 22992 return detached; 22993 }, 22994 22995 /** 22996 * Monitor the event state for the subscribed event. The first parameter 22997 * is what should be monitored, the rest are the normal parameters when 22998 * subscribing to an event. 22999 * @method monitor 23000 * @param what {string} what to monitor ('attach', 'detach', 'publish'). 23001 * @return {EventHandle} return value from the monitor event subscription. 23002 */ 23003 monitor: function(what) { 23004 return this.evt.monitor.apply(this.evt, arguments); 23005 } 23006}; 23007 23008/** 23009 * Custom event engine, DOM event listener abstraction layer, synthetic DOM 23010 * events. 23011 * @module event-custom 23012 * @submodule event-custom-base 23013 */ 23014 23015/** 23016 * EventTarget provides the implementation for any object to 23017 * publish, subscribe and fire to custom events, and also 23018 * alows other EventTargets to target the object with events 23019 * sourced from the other object. 23020 * EventTarget is designed to be used with Y.augment to wrap 23021 * EventCustom in an interface that allows events to be listened to
23022 * and fired by name. This makes it possible for implementing code to 23023 * subscribe to an event that either has not been created yet, or will 23024 * not be created at all. 23025 * @class EventTarget 23026 * @param opts a configuration object 23027 * @config emitFacade {boolean} if true, all events will emit event 23028 * facade payloads by default (default false) 23029 * @config prefix {String} the prefix to apply to non-prefixed event names 23030 */ 23031 23032var L = Y.Lang, 23033 PREFIX_DELIMITER = ':', 23034 CATEGORY_DELIMITER = '|', 23035 AFTER_PREFIX = '~AFTER~', 23036 WILD_TYPE_RE = /(.*?)(:)(.*?)/, 23037 23038 _wildType = Y.cached(function(type) { 23039 return type.replace(WILD_TYPE_RE, "*$2$3"); 23040 }), 23041 23042 /** 23043 * If the instance has a prefix attribute and the 23044 * event type is not prefixed, the instance prefix is 23045 * applied to the supplied type. 23046 * @method _getType 23047 * @private 23048 */ 23049 _getType = function(type, pre) { 23050 23051 if (!pre || (typeof type !== "string") || type.indexOf(PREFIX_DELIMITER) > -1) { 23052 return type; 23053 } 23054 23055 return pre + PREFIX_DELIMITER + type; 23056 }, 23057 23058 /** 23059 * Returns an array with the detach key (if provided), 23060 * and the prefixed event name from _getType 23061 * Y.on('detachcategory| menu:click', fn) 23062 * @method _parseType 23063 * @private 23064 */ 23065 _parseType = Y.cached(function(type, pre) { 23066 23067 var t = type, detachcategory, after, i; 23068 23069 if (!L.isString(t)) { 23070 return t; 23071 } 23072 23073 i = t.indexOf(AFTER_PREFIX); 23074 23075 if (i > -1) { 23076 after = true; 23077 t = t.substr(AFTER_PREFIX.length); 23078 } 23079 23080 i = t.indexOf(CATEGORY_DELIMITER); 23081 23082 if (i > -1) { 23083 detachcategory = t.substr(0, (i)); 23084 t = t.substr(i+1); 23085 if (t === '*') { 23086 t = null; 23087 } 23088 } 23089 23090 // detach category, full type with instance prefix, is this an after listener, short type 23091 return [detachcategory, (pre) ? _getType(t, pre) : t, after, t]; 23092 }), 23093 23094 ET = function(opts) { 23095 23096 var etState = this._yuievt, 23097 etConfig; 23098 23099 if (!etState) { 23100 etState = this._yuievt = { 23101 events: {}, // PERF: Not much point instantiating lazily. We're bound to have events 23102 targets: null, // PERF: Instantiate lazily, if user actually adds target, 23103 config: { 23104 host: this, 23105 context: this 23106 }, 23107 chain: Y.config.chain 23108 }; 23109 } 23110 23111 etConfig = etState.config; 23112 23113 if (opts) { 23114 mixConfigs(etConfig, opts, true); 23115 23116 if (opts.chain !== undefined) { 23117 etState.chain = opts.chain; 23118 } 23119 23120 if (opts.prefix) { 23121 etConfig.prefix = opts.prefix; 23122 } 23123 } 23124 }; 23125 23126ET.prototype = { 23127 23128 constructor: ET, 23129 23130 /** 23131 * Listen to a custom event hosted by this object one time. 23132 * This is the equivalent to <code>on</code> except the 23133 * listener is immediatelly detached when it is executed. 23134 * @method once 23135 * @param {String} type The name of the event 23136 * @param {Function} fn The callback to execute in response to the event 23137 * @param {Object} [context] Override `this` object in callback 23138 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 23139 * @return {EventHandle} A subscription handle capable of detaching the 23140 * subscription 23141 */ 23142 once: function() { 23143 var handle = this.on.apply(this, arguments); 23144 handle.batch(function(hand) { 23145 if (hand.sub) { 23146 hand.sub.once = true; 23147 } 23148 }); 23149 return handle; 23150 }, 23151 23152 /** 23153 * Listen to a custom event hosted by this object one time. 23154 * This is the equivalent to <code>after</code> except the 23155 * listener is immediatelly detached when it is executed. 23156 * @method onceAfter 23157 * @param {String} type The name of the event 23158 * @param {Function} fn The callback to execute in response to the event 23159 * @param {Object} [context] Override `this` object in callback 23160 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 23161 * @return {EventHandle} A subscription handle capable of detaching that 23162 * subscription 23163 */ 23164 onceAfter: function() { 23165 var handle = this.after.apply(this, arguments); 23166 handle.batch(function(hand) { 23167 if (hand.sub) { 23168 hand.sub.once = true; 23169 } 23170 }); 23171 return handle; 23172 }, 23173 23174 /** 23175 * Takes the type parameter passed to 'on' and parses out the 23176 * various pieces that could be included in the type. If the 23177 * event type is passed without a prefix, it will be expanded 23178 * to include the prefix one is supplied or the event target 23179 * is configured with a default prefix. 23180 * @method parseType 23181 * @param {String} type the type 23182 * @param {String} [pre] The prefix. Defaults to this._yuievt.config.prefix 23183 * @since 3.3.0 23184 * @return {Array} an array containing: 23185 * * the detach category, if supplied, 23186 * * the prefixed event type, 23187 * * whether or not this is an after listener, 23188 * * the supplied event type 23189 */ 23190 parseType: function(type, pre) { 23191 return _parseType(type, pre || this._yuievt.config.prefix); 23192 }, 23193 23194 /** 23195 * Subscribe a callback function to a custom event fired by this object or 23196 * from an object that bubbles its events to this object. 23197 * 23198 * this.on("change", this._onChange, this); 23199 * 23200 * Callback functions for events published with `emitFacade = true` will 23201 * receive an `EventFacade` as the first argument (typically named "e"). 23202 * These callbacks can then call `e.preventDefault()` to disable the 23203 * behavior published to that event's `defaultFn`. See the `EventFacade` 23204 * API for all available properties and methods. Subscribers to 23205 * non-`emitFacade` events will receive the arguments passed to `fire()` 23206 * after the event name. 23207 * 23208 * To subscribe to multiple events at once, pass an object as the first 23209 * argument, where the key:value pairs correspond to the eventName:callback. 23210 * 23211 * this.on({ 23212 * "attrChange" : this._onAttrChange, 23213 * "change" : this._onChange 23214 * }); 23215 * 23216 * You can also pass an array of event names as the first argument to 23217 * subscribe to all listed events with the same callback. 23218 * 23219 * this.on([ "change", "attrChange" ], this._onChange); 23220 * 23221 * Returning `false` from a callback is supported as an alternative to 23222 * calling `e.preventDefault(); e.stopPropagation();`. However, it is 23223 * recommended to use the event methods whenever possible. 23224 * 23225 * @method on 23226 * @param {String} type The name of the event 23227 * @param {Function} fn The callback to execute in response to the event 23228 * @param {Object} [context] Override `this` object in callback 23229 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 23230 * @return {EventHandle} A subscription handle capable of detaching that 23231 * subscription 23232 */ 23233 on: function(type, fn, context) { 23234 23235 var yuievt = this._yuievt, 23236 parts = _parseType(type, yuievt.config.prefix), f, c, args, ret, ce, 23237 detachcategory, handle, store = Y.Env.evt.handles, after, adapt, shorttype, 23238 Node = Y.Node, n, domevent, isArr; 23239 23240 // full name, args, detachcategory, after 23241 this._monitor('attach', parts[1], { 23242 args: arguments, 23243 category: parts[0], 23244 after: parts[2] 23245 }); 23246 23247 if (L.isObject(type)) { 23248 23249 if (L.isFunction(type)) { 23250 return Y.Do.before.apply(Y.Do, arguments); 23251 } 23252 23253 f = fn; 23254 c = context; 23255 args = nativeSlice.call(arguments, 0); 23256 ret = []; 23257 23258 if (L.isArray(type)) { 23259 isArr = true; 23260 } 23261 23262 after = type._after; 23263 delete type._after; 23264 23265 Y.each(type, function(v, k) { 23266 23267 if (L.isObject(v)) { 23268 f = v.fn || ((L.isFunction(v)) ? v : f); 23269 c = v.context || c; 23270 } 23271 23272 var nv = (after) ? AFTER_PREFIX : ''; 23273 23274 args[0] = nv + ((isArr) ? v : k); 23275 args[1] = f; 23276 args[2] = c; 23277
23278 ret.push(this.on.apply(this, args)); 23279 23280 }, this); 23281 23282 return (yuievt.chain) ? this : new Y.EventHandle(ret); 23283 } 23284 23285 detachcategory = parts[0]; 23286 after = parts[2]; 23287 shorttype = parts[3]; 23288 23289 // extra redirection so we catch adaptor events too. take a look at this. 23290 if (Node && Y.instanceOf(this, Node) && (shorttype in Node.DOM_EVENTS)) { 23291 args = nativeSlice.call(arguments, 0); 23292 args.splice(2, 0, Node.getDOMNode(this)); 23293 return Y.on.apply(Y, args); 23294 } 23295 23296 type = parts[1]; 23297 23298 if (Y.instanceOf(this, YUI)) { 23299 23300 adapt = Y.Env.evt.plugins[type]; 23301 args = nativeSlice.call(arguments, 0); 23302 args[0] = shorttype; 23303 23304 if (Node) { 23305 n = args[2]; 23306 23307 if (Y.instanceOf(n, Y.NodeList)) { 23308 n = Y.NodeList.getDOMNodes(n); 23309 } else if (Y.instanceOf(n, Node)) { 23310 n = Node.getDOMNode(n); 23311 } 23312 23313 domevent = (shorttype in Node.DOM_EVENTS); 23314 23315 // Captures both DOM events and event plugins. 23316 if (domevent) { 23317 args[2] = n; 23318 } 23319 } 23320 23321 // check for the existance of an event adaptor 23322 if (adapt) { 23323 handle = adapt.on.apply(Y, args); 23324 } else if ((!type) || domevent) { 23325 handle = Y.Event._attach(args); 23326 } 23327 23328 } 23329 23330 if (!handle) { 23331 ce = yuievt.events[type] || this.publish(type); 23332 handle = ce._on(fn, context, (arguments.length > 3) ? nativeSlice.call(arguments, 3) : null, (after) ? 'after' : true); 23333 23334 // TODO: More robust regex, accounting for category 23335 if (type.indexOf("*:") !== -1) { 23336 this._hasSiblings = true; 23337 } 23338 } 23339 23340 if (detachcategory) { 23341 store[detachcategory] = store[detachcategory] || {}; 23342 store[detachcategory][type] = store[detachcategory][type] || []; 23343 store[detachcategory][type].push(handle); 23344 } 23345 23346 return (yuievt.chain) ? this : handle; 23347 23348 }, 23349 23350 /** 23351 * subscribe to an event 23352 * @method subscribe 23353 * @deprecated use on 23354 */ 23355 subscribe: function() { 23356 return this.on.apply(this, arguments); 23357 }, 23358 23359 /** 23360 * Detach one or more listeners the from the specified event 23361 * @method detach 23362 * @param type {string|Object} Either the handle to the subscriber or the 23363 * type of event. If the type 23364 * is not specified, it will attempt to remove 23365 * the listener from all hosted events. 23366 * @param fn {Function} The subscribed function to unsubscribe, if not 23367 * supplied, all subscribers will be removed. 23368 * @param context {Object} The custom object passed to subscribe. This is 23369 * optional, but if supplied will be used to 23370 * disambiguate multiple listeners that are the same 23371 * (e.g., you subscribe many object using a function 23372 * that lives on the prototype) 23373 * @return {EventTarget} the host 23374 */ 23375 detach: function(type, fn, context) { 23376 23377 var evts = this._yuievt.events, 23378 i, 23379 Node = Y.Node, 23380 isNode = Node && (Y.instanceOf(this, Node)); 23381 23382 // detachAll disabled on the Y instance. 23383 if (!type && (this !== Y)) { 23384 for (i in evts) { 23385 if (evts.hasOwnProperty(i)) { 23386 evts[i].detach(fn, context); 23387 } 23388 } 23389 if (isNode) { 23390 Y.Event.purgeElement(Node.getDOMNode(this)); 23391 } 23392 23393 return this; 23394 } 23395 23396 var parts = _parseType(type, this._yuievt.config.prefix), 23397 detachcategory = L.isArray(parts) ? parts[0] : null, 23398 shorttype = (parts) ? parts[3] : null, 23399 adapt, store = Y.Env.evt.handles, detachhost, cat, args, 23400 ce, 23401 23402 keyDetacher = function(lcat, ltype, host) { 23403 var handles = lcat[ltype], ce, i; 23404 if (handles) { 23405 for (i = handles.length - 1; i >= 0; --i) { 23406 ce = handles[i].evt; 23407 if (ce.host === host || ce.el === host) { 23408 handles[i].detach(); 23409 } 23410 } 23411 } 23412 }; 23413 23414 if (detachcategory) { 23415 23416 cat = store[detachcategory]; 23417 type = parts[1]; 23418 detachhost = (isNode) ? Y.Node.getDOMNode(this) : this; 23419 23420 if (cat) { 23421 if (type) { 23422 keyDetacher(cat, type, detachhost); 23423 } else { 23424 for (i in cat) { 23425 if (cat.hasOwnProperty(i)) { 23426 keyDetacher(cat, i, detachhost); 23427 } 23428 } 23429 } 23430 23431 return this; 23432 } 23433 23434 // If this is an event handle, use it to detach 23435 } else if (L.isObject(type) && type.detach) { 23436 type.detach(); 23437 return this; 23438 // extra redirection so we catch adaptor events too. take a look at this. 23439 } else if (isNode && ((!shorttype) || (shorttype in Node.DOM_EVENTS))) { 23440 args = nativeSlice.call(arguments, 0); 23441 args[2] = Node.getDOMNode(this); 23442 Y.detach.apply(Y, args); 23443 return this; 23444 } 23445 23446 adapt = Y.Env.evt.plugins[shorttype]; 23447 23448 // The YUI instance handles DOM events and adaptors 23449 if (Y.instanceOf(this, YUI)) { 23450 args = nativeSlice.call(arguments, 0); 23451 // use the adaptor specific detach code if 23452 if (adapt && adapt.detach) { 23453 adapt.detach.apply(Y, args); 23454 return this; 23455 // DOM event fork 23456 } else if (!type || (!adapt && Node && (type in Node.DOM_EVENTS))) { 23457 args[0] = type; 23458 Y.Event.detach.apply(Y.Event, args); 23459 return this; 23460 } 23461 } 23462 23463 // ce = evts[type]; 23464 ce = evts[parts[1]]; 23465 if (ce) { 23466 ce.detach(fn, context); 23467 } 23468 23469 return this; 23470 }, 23471 23472 /** 23473 * detach a listener 23474 * @method unsubscribe 23475 * @deprecated use detach 23476 */ 23477 unsubscribe: function() { 23478 return this.detach.apply(this, arguments); 23479 }, 23480 23481 /** 23482 * Removes all listeners from the specified event. If the event type 23483 * is not specified, all listeners from all hosted custom events will 23484 * be removed. 23485 * @method detachAll 23486 * @param type {String} The type, or name of the event 23487 */ 23488 detachAll: function(type) { 23489 return this.detach(type); 23490 }, 23491 23492 /** 23493 * Removes all listeners from the specified event. If the event type 23494 * is not specified, all listeners from all hosted custom events will 23495 * be removed. 23496 * @method unsubscribeAll 23497 * @param type {String} The type, or name of the event 23498 * @deprecated use detachAll 23499 */ 23500 unsubscribeAll: function() { 23501 return this.detachAll.apply(this, arguments); 23502 }, 23503 23504 /** 23505 * Creates a new custom event of the specified type. If a custom event 23506 * by that name already exists, it will not be re-created. In either 23507 * case the custom event is returned. 23508 * 23509 * @method publish 23510 * 23511 * @param type {String} the type, or name of the event 23512 * @param opts {object} optional config params. Valid properties are: 23513 * @param [opts.broadcast=false] {Boolean} whether or not the YUI instance and YUI global 23514 * are notified when the event is fired. 23515 * @param [opts.bubbles=true] {Boolean} Whether or not this event bubbles. Events can 23516 * only bubble if `emitFacade` is true.
23517 * @param [opts.context=this] {Object} the default execution context for the listeners. 23518 * @param [opts.defaultFn] {Function} the default function to execute when this event 23519 * fires if preventDefault was not called. 23520 * @param [opts.emitFacade=false] {Boolean} whether or not this event emits a facade. 23521 * @param [opts.prefix] {String} the prefix for this targets events, e.g., 'menu' in 'menu:click'. 23522 * @param [opts.fireOnce=false] {Boolean} if an event is configured to fire once, 23523 * new subscribers after the fire will be notified immediately. 23524 * @param [opts.async=false] {Boolean} fireOnce event listeners will fire synchronously 23525 * if the event has already fired unless `async` is `true`. 23526 * @param [opts.preventable=true] {Boolean} whether or not `preventDefault()` has an effect. 23527 * @param [opts.preventedFn] {Function} a function that is executed when `preventDefault()` is called. 23528 * @param [opts.queuable=false] {Boolean} whether or not this event can be queued during bubbling. 23529 * @param [opts.silent] {Boolean} if silent is true, debug messages are not provided for this event. 23530 * @param [opts.stoppedFn] {Function} a function that is executed when stopPropagation is called. 23531 * @param [opts.monitored] {Boolean} specifies whether or not this event should send notifications about 23532 * when the event has been attached, detached, or published. 23533 * @param [opts.type] {String} the event type (valid option if not provided as the first parameter to publish). 23534 * 23535 * @return {CustomEvent} the custom event 23536 * 23537 */ 23538 publish: function(type, opts) { 23539 23540 var ret, 23541 etState = this._yuievt, 23542 etConfig = etState.config, 23543 pre = etConfig.prefix; 23544 23545 if (typeof type === "string") { 23546 if (pre) { 23547 type = _getType(type, pre); 23548 } 23549 ret = this._publish(type, etConfig, opts); 23550 } else { 23551 ret = {}; 23552 23553 Y.each(type, function(v, k) { 23554 if (pre) { 23555 k = _getType(k, pre); 23556 } 23557 ret[k] = this._publish(k, etConfig, v || opts); 23558 }, this); 23559 23560 } 23561 23562 return ret; 23563 }, 23564 23565 /** 23566 * Returns the fully qualified type, given a short type string. 23567 * That is, returns "foo:bar" when given "bar" if "foo" is the configured prefix. 23568 * 23569 * NOTE: This method, unlike _getType, does no checking of the value passed in, and 23570 * is designed to be used with the low level _publish() method, for critical path 23571 * implementations which need to fast-track publish for performance reasons. 23572 * 23573 * @method _getFullType 23574 * @private 23575 * @param {String} type The short type to prefix 23576 * @return {String} The prefixed type, if a prefix is set, otherwise the type passed in 23577 */ 23578 _getFullType : function(type) { 23579 23580 var pre = this._yuievt.config.prefix; 23581 23582 if (pre) { 23583 return pre + PREFIX_DELIMITER + type; 23584 } else { 23585 return type; 23586 } 23587 }, 23588 23589 /** 23590 * The low level event publish implementation. It expects all the massaging to have been done 23591 * outside of this method. e.g. the `type` to `fullType` conversion. It's designed to be a fast 23592 * path publish, which can be used by critical code paths to improve performance. 23593 * 23594 * @method _publish 23595 * @private 23596 * @param {String} fullType The prefixed type of the event to publish. 23597 * @param {Object} etOpts The EventTarget specific configuration to mix into the published event. 23598 * @param {Object} ceOpts The publish specific configuration to mix into the published event. 23599 * @return {CustomEvent} The published event. If called without `etOpts` or `ceOpts`, this will 23600 * be the default `CustomEvent` instance, and can be configured independently. 23601 */ 23602 _publish : function(fullType, etOpts, ceOpts) { 23603 23604 var ce, 23605 etState = this._yuievt, 23606 etConfig = etState.config, 23607 host = etConfig.host, 23608 context = etConfig.context, 23609 events = etState.events; 23610 23611 ce = events[fullType]; 23612 23613 // PERF: Hate to pull the check out of monitor, but trying to keep critical path tight. 23614 if ((etConfig.monitored && !ce) || (ce && ce.monitored)) { 23615 this._monitor('publish', fullType, { 23616 args: arguments 23617 }); 23618 } 23619 23620 if (!ce) { 23621 // Publish event 23622 ce = events[fullType] = new Y.CustomEvent(fullType, etOpts); 23623 23624 if (!etOpts) { 23625 ce.host = host; 23626 ce.context = context; 23627 } 23628 } 23629 23630 if (ceOpts) { 23631 mixConfigs(ce, ceOpts, true); 23632 } 23633 23634 return ce; 23635 }, 23636 23637 /** 23638 * This is the entry point for the event monitoring system. 23639 * You can monitor 'attach', 'detach', 'fire', and 'publish'. 23640 * When configured, these events generate an event. click -> 23641 * click_attach, click_detach, click_publish -- these can 23642 * be subscribed to like other events to monitor the event 23643 * system. Inividual published events can have monitoring 23644 * turned on or off (publish can't be turned off before it 23645 * it published) by setting the events 'monitor' config. 23646 * 23647 * @method _monitor 23648 * @param what {String} 'attach', 'detach', 'fire', or 'publish' 23649 * @param eventType {String|CustomEvent} The prefixed name of the event being monitored, or the CustomEvent object. 23650 * @param o {Object} Information about the event interaction, such as 23651 * fire() args, subscription category, publish config 23652 * @private 23653 */ 23654 _monitor: function(what, eventType, o) {
23655 var monitorevt, ce, type; 23656 23657 if (eventType) { 23658 if (typeof eventType === "string") { 23659 type = eventType; 23660 ce = this.getEvent(eventType, true); 23661 } else { 23662 ce = eventType; 23663 type = eventType.type; 23664 } 23665 23666 if ((this._yuievt.config.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) { 23667 monitorevt = type + '_' + what; 23668 o.monitored = what; 23669 this.fire.call(this, monitorevt, o); 23670 } 23671 } 23672 }, 23673 23674 /** 23675 * Fire a custom event by name. The callback functions will be executed 23676 * from the context specified when the event was created, and with the 23677 * following parameters. 23678 * 23679 * The first argument is the event type, and any additional arguments are 23680 * passed to the listeners as parameters. If the first of these is an 23681 * object literal, and the event is configured to emit an event facade, 23682 * that object is mixed into the event facade and the facade is provided 23683 * in place of the original object. 23684 * 23685 * If the custom event object hasn't been created, then the event hasn't 23686 * been published and it has no subscribers. For performance sake, we 23687 * immediate exit in this case. This means the event won't bubble, so 23688 * if the intention is that a bubble target be notified, the event must 23689 * be published on this object first. 23690 * 23691 * @method fire 23692 * @param type {String|Object} The type of the event, or an object that contains 23693 * a 'type' property. 23694 * @param arguments {Object*} an arbitrary set of parameters to pass to 23695 * the handler. If the first of these is an object literal and the event is 23696 * configured to emit an event facade, the event facade will replace that 23697 * parameter after the properties the object literal contains are copied to 23698 * the event facade. 23699 * @return {Boolean} True if the whole lifecycle of the event went through, 23700 * false if at any point the event propagation was halted. 23701 */ 23702 fire: function(type) { 23703 23704 var typeIncluded = (typeof type === "string"), 23705 argCount = arguments.length, 23706 t = type, 23707 yuievt = this._yuievt, 23708 etConfig = yuievt.config, 23709 pre = etConfig.prefix, 23710 ret, 23711 ce, 23712 ce2, 23713 args; 23714 23715 if (typeIncluded && argCount <= 3) { 23716 23717 // PERF: Try to avoid slice/iteration for the common signatures 23718 23719 // Most common 23720 if (argCount === 2) { 23721 args = [arguments[1]]; // fire("foo", {}) 23722 } else if (argCount === 3) { 23723 args = [arguments[1], arguments[2]]; // fire("foo", {}, opts) 23724 } else { 23725 args = []; // fire("foo") 23726 } 23727 23728 } else { 23729 args = nativeSlice.call(arguments, ((typeIncluded) ? 1 : 0)); 23730 } 23731 23732 if (!typeIncluded) { 23733 t = (type && type.type); 23734 } 23735 23736 if (pre) { 23737 t = _getType(t, pre); 23738 } 23739 23740 ce = yuievt.events[t]; 23741 23742 if (this._hasSiblings) { 23743 ce2 = this.getSibling(t, ce); 23744 23745 if (ce2 && !ce) { 23746 ce = this.publish(t); 23747 } 23748 } 23749 23750 // PERF: trying to avoid function call, since this is a critical path 23751 if ((etConfig.monitored && (!ce || ce.monitored)) || (ce && ce.monitored)) { 23752 this._monitor('fire', (ce || t), { 23753 args: args 23754 }); 23755 } 23756 23757 // this event has not been published or subscribed to 23758 if (!ce) { 23759 if (yuievt.hasTargets) { 23760 return this.bubble({ type: t }, args, this); 23761 } 23762 23763 // otherwise there is nothing to be done 23764 ret = true; 23765 } else { 23766 23767 if (ce2) { 23768 ce.sibling = ce2; 23769 } 23770 23771 ret = ce._fire(args); 23772 } 23773 23774 return (yuievt.chain) ? this : ret; 23775 }, 23776 23777 getSibling: function(type, ce) { 23778 var ce2; 23779 23780 // delegate to *:type events if there are subscribers 23781 if (type.indexOf(PREFIX_DELIMITER) > -1) { 23782 type = _wildType(type); 23783 ce2 = this.getEvent(type, true); 23784 if (ce2) { 23785 ce2.applyConfig(ce); 23786 ce2.bubbles = false;
23787 ce2.broadcast = 0; 23788 } 23789 } 23790 23791 return ce2; 23792 }, 23793 23794 /** 23795 * Returns the custom event of the provided type has been created, a 23796 * falsy value otherwise 23797 * @method getEvent 23798 * @param type {String} the type, or name of the event 23799 * @param prefixed {String} if true, the type is prefixed already 23800 * @return {CustomEvent} the custom event or null 23801 */ 23802 getEvent: function(type, prefixed) { 23803 var pre, e; 23804 23805 if (!prefixed) { 23806 pre = this._yuievt.config.prefix; 23807 type = (pre) ? _getType(type, pre) : type; 23808 } 23809 e = this._yuievt.events; 23810 return e[type] || null; 23811 }, 23812 23813 /** 23814 * Subscribe to a custom event hosted by this object. The 23815 * supplied callback will execute after any listeners add 23816 * via the subscribe method, and after the default function, 23817 * if configured for the event, has executed. 23818 * 23819 * @method after 23820 * @param {String} type The name of the event 23821 * @param {Function} fn The callback to execute in response to the event 23822 * @param {Object} [context] Override `this` object in callback 23823 * @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 23824 * @return {EventHandle} A subscription handle capable of detaching the 23825 * subscription 23826 */ 23827 after: function(type, fn) { 23828 23829 var a = nativeSlice.call(arguments, 0); 23830 23831 switch (L.type(type)) { 23832 case 'function': 23833 return Y.Do.after.apply(Y.Do, arguments); 23834 case 'array': 23835 // YArray.each(a[0], function(v) { 23836 // v = AFTER_PREFIX + v; 23837 // }); 23838 // break; 23839 case 'object': 23840 a[0]._after = true; 23841 break; 23842 default: 23843 a[0] = AFTER_PREFIX + type; 23844 } 23845 23846 return this.on.apply(this, a); 23847 23848 }, 23849 23850 /** 23851 * Executes the callback before a DOM event, custom event 23852 * or method. If the first argument is a function, it 23853 * is assumed the target is a method. For DOM and custom 23854 * events, this is an alias for Y.on. 23855 * 23856 * For DOM and custom events: 23857 * type, callback, context, 0-n arguments 23858 * 23859 * For methods: 23860 * callback, object (method host), methodName, context, 0-n arguments 23861 * 23862 * @method before 23863 * @return detach handle 23864 */ 23865 before: function() { 23866 return this.on.apply(this, arguments); 23867 } 23868 23869}; 23870 23871Y.EventTarget = ET; 23872 23873// make Y an event target 23874Y.mix(Y, ET.prototype); 23875ET.call(Y, { bubbles: false }); 23876 23877YUI.Env.globalEvents = YUI.Env.globalEvents || new ET(); 23878 23879/** 23880 * Hosts YUI page level events. This is where events bubble to 23881 * when the broadcast config is set to 2. This property is 23882 * only available if the custom event module is loaded. 23883 * @property Global 23884 * @type EventTarget 23885 * @for YUI 23886 */ 23887Y.Global = YUI.Env.globalEvents; 23888 23889// @TODO implement a global namespace function on Y.Global? 23890 23891/** 23892`Y.on()` can do many things: 23893 23894<ul> 23895 <li>Subscribe to custom events `publish`ed and `fire`d from Y</li> 23896 <li>Subscribe to custom events `publish`ed with `broadcast` 1 or 2 and 23897 `fire`d from any object in the YUI instance sandbox</li> 23898 <li>Subscribe to DOM events</li> 23899 <li>Subscribe to the execution of a method on any object, effectively 23900 treating that method as an event</li> 23901</ul> 23902 23903For custom event subscriptions, pass the custom event name as the first argument 23904and callback as the second. The `this` object in the callback will be `Y` unless 23905an override is passed as the third argument. 23906 23907 Y.on('io:complete', function () { 23908 Y.MyApp.updateStatus('Transaction complete'); 23909 }); 23910 23911To subscribe to DOM events, pass the name of a DOM event as the first argument 23912and a CSS selector string as the third argument after the callback function. 23913Alternately, the third argument can be a `Node`, `NodeList`, `HTMLElement`, 23914array, or simply omitted (the default is the `window` object). 23915 23916 Y.on('click', function (e) { 23917 e.preventDefault(); 23918 23919 // proceed with ajax form submission 23920 var url = this.get('action'); 23921 ... 23922 }, '#my-form'); 23923 23924The `this` object in DOM event callbacks will be the `Node` targeted by the CSS 23925selector or other identifier. 23926 23927`on()` subscribers for DOM events or custom events `publish`ed with a 23928`defaultFn` can prevent the default behavior with `e.preventDefault()` from the 23929event object passed as the first parameter to the subscription callback. 23930 23931To subscribe to the execution of an object method, pass arguments corresponding to the call signature for 23932<a href="../classes/Do.html#methods_before">`Y.Do.before(...)`</a>. 23933 23934NOTE: The formal parameter list below is for events, not for function 23935injection. See `Y.Do.before` for that signature. 23936 23937@method on 23938@param {String} type DOM or custom event name 23939@param {Function} fn The callback to execute in response to the event 23940@param {Object} [context] Override `this` object in callback 23941@param {Any} [arg*] 0..n additional arguments to supply to the subscriber 23942@return {EventHandle} A subscription handle capable of detaching the 23943 subscription 23944@see Do.before 23945@for YUI
23946**/ 23947 23948/** 23949Listen for an event one time. Equivalent to `on()`, except that 23950the listener is immediately detached when executed. 23951 23952See the <a href="#methods_on">`on()` method</a> for additional subscription 23953options. 23954 23955@see on 23956@method once 23957@param {String} type DOM or custom event name 23958@param {Function} fn The callback to execute in response to the event 23959@param {Object} [context] Override `this` object in callback 23960@param {Any} [arg*] 0..n additional arguments to supply to the subscriber 23961@return {EventHandle} A subscription handle capable of detaching the 23962 subscription 23963@for YUI 23964**/ 23965 23966/** 23967Listen for an event one time. Equivalent to `once()`, except, like `after()`, 23968the subscription callback executes after all `on()` subscribers and the event's 23969`defaultFn` (if configured) have executed. Like `after()` if any `on()` phase 23970subscriber calls `e.preventDefault()`, neither the `defaultFn` nor the `after()` 23971subscribers will execute. 23972 23973The listener is immediately detached when executed. 23974 23975See the <a href="#methods_on">`on()` method</a> for additional subscription 23976options. 23977 23978@see once 23979@method onceAfter 23980@param {String} type The custom event name 23981@param {Function} fn The callback to execute in response to the event 23982@param {Object} [context] Override `this` object in callback 23983@param {Any} [arg*] 0..n additional arguments to supply to the subscriber 23984@return {EventHandle} A subscription handle capable of detaching the 23985 subscription 23986@for YUI 23987**/ 23988 23989/** 23990Like `on()`, this method creates a subscription to a custom event or to the 23991execution of a method on an object. 23992 23993For events, `after()` subscribers are executed after the event's 23994`defaultFn` unless `e.preventDefault()` was called from an `on()` subscriber. 23995 23996See the <a href="#methods_on">`on()` method</a> for additional subscription 23997options. 23998 23999NOTE: The subscription signature shown is for events, not for function 24000injection. See <a href="../classes/Do.html#methods_after">`Y.Do.after`</a> 24001for that signature. 24002 24003@see on 24004@see Do.after 24005@method after 24006@param {String} type The custom event name 24007@param {Function} fn The callback to execute in response to the event 24008@param {Object} [context] Override `this` object in callback 24009@param {Any} [args*] 0..n additional arguments to supply to the subscriber 24010@return {EventHandle} A subscription handle capable of detaching the 24011 subscription 24012@for YUI 24013**/ 24014 24015 24016}, 'patched-v3.18.1', {"requires": ["oop"]}); 24017 24018YUI.add('event-custom-complex', function (Y, NAME) { 24019 24020 24021/** 24022 * Adds event facades, preventable default behavior, and bubbling. 24023 * events. 24024 * @module event-custom 24025 * @submodule event-custom-complex 24026 */ 24027 24028var FACADE, 24029 FACADE_KEYS, 24030 YObject = Y.Object, 24031 key, 24032 EMPTY = {}, 24033 CEProto = Y.CustomEvent.prototype, 24034 ETProto = Y.EventTarget.prototype, 24035 24036 mixFacadeProps = function(facade, payload) { 24037 var p; 24038 24039 for (p in payload) { 24040 if (!(FACADE_KEYS.hasOwnProperty(p))) { 24041 facade[p] = payload[p]; 24042 } 24043 } 24044 }; 24045 24046/** 24047 * Wraps and protects a custom event for use when emitFacade is set to true. 24048 * Requires the event-custom-complex module 24049 * @class EventFacade 24050 * @param e {Event} the custom event 24051 * @param currentTarget {HTMLElement} the element the listener was attached to 24052 */ 24053 24054Y.EventFacade = function(e, currentTarget) { 24055 24056 if (!e) { 24057 e = EMPTY; 24058 } 24059 24060 this._event = e; 24061 24062 /** 24063 * The arguments passed to fire 24064 * @property details 24065 * @type Array 24066 */ 24067 this.details = e.details; 24068 24069 /** 24070 * The event type, this can be overridden by the fire() payload 24071 * @property type 24072 * @type string 24073 */ 24074 this.type = e.type; 24075 24076 /** 24077 * The real event type 24078 * @property _type 24079 * @type string 24080 * @private 24081 */ 24082 this._type = e.type; 24083 24084 ////////////////////////////////////////////////////// 24085 24086 /** 24087 * Node reference for the targeted eventtarget 24088 * @property target 24089 * @type Node 24090 */ 24091 this.target = e.target; 24092 24093 /** 24094 * Node reference for the element that the listener was attached to. 24095 * @property currentTarget 24096 * @type Node 24097 */ 24098 this.currentTarget = currentTarget; 24099 24100 /** 24101 * Node reference to the relatedTarget 24102 * @property relatedTarget 24103 * @type Node 24104 */ 24105 this.relatedTarget = e.relatedTarget; 24106 24107}; 24108 24109Y.mix(Y.EventFacade.prototype, { 24110 24111 /** 24112 * Stops the propagation to the next bubble target 24113 * @method stopPropagation 24114 */ 24115 stopPropagation: function() { 24116 this._event.stopPropagation(); 24117 this.stopped = 1; 24118 }, 24119 24120 /** 24121 * Stops the propagation to the next bubble target and 24122 * prevents any additional listeners from being exectued 24123 * on the current target. 24124 * @method stopImmediatePropagation 24125 */ 24126 stopImmediatePropagation: function() { 24127 this._event.stopImmediatePropagation(); 24128 this.stopped = 2; 24129 }, 24130 24131 /** 24132 * Prevents the event's default behavior 24133 * @method preventDefault 24134 */ 24135 preventDefault: function() { 24136 this._event.preventDefault(); 24137 this.prevented = 1; 24138 }, 24139 24140 /** 24141 * Stops the event propagation and prevents the default 24142 * event behavior. 24143 * @method halt 24144 * @param immediate {boolean} if true additional listeners 24145 * on the current target will not be executed 24146 */ 24147 halt: function(immediate) { 24148 this._event.halt(immediate); 24149 this.prevented = 1; 24150 this.stopped = (immediate) ? 2 : 1; 24151 } 24152 24153}); 24154 24155CEProto.fireComplex = function(args) { 24156 24157 var es, 24158 ef, 24159 q, 24160 queue, 24161 ce, 24162 ret = true, 24163 events, 24164 subs, 24165 ons, 24166 afters, 24167 afterQueue, 24168 postponed, 24169 prevented, 24170 preventedFn, 24171 defaultFn, 24172 self = this, 24173 host = self.host || self, 24174 next, 24175 oldbubble, 24176 stack = self.stack, 24177 yuievt = host._yuievt, 24178 hasPotentialSubscribers; 24179 24180 if (stack) { 24181 24182 // queue this event if the current item in the queue bubbles 24183 if (self.queuable && self.type !== stack.next.type) { 24184 24185 if (!stack.queue) { 24186 stack.queue = []; 24187 } 24188 stack.queue.push([self, args]); 24189 24190 return true; 24191 } 24192 } 24193 24194 hasPotentialSubscribers = self.hasSubs() || yuievt.hasTargets || self.broadcast; 24195 24196 self.target = self.target || host; 24197 self.currentTarget = host; 24198 24199 self.details = args.concat(); 24200 24201 if (hasPotentialSubscribers) { 24202 24203 es = stack || { 24204 24205 id: self.id, // id of the first event in the stack 24206 next: self, 24207 silent: self.silent, 24208 stopped: 0, 24209 prevented: 0, 24210 bubbling: null, 24211 type: self.type, 24212 // defaultFnQueue: new Y.Queue(), 24213 defaultTargetOnly: self.defaultTargetOnly 24214 24215 }; 24216 24217 subs = self.getSubs(); 24218 ons = subs[0]; 24219 afters = subs[1]; 24220 24221 self.stopped = (self.type !== es.type) ? 0 : es.stopped; 24222 self.prevented = (self.type !== es.type) ? 0 : es.prevented; 24223 24224 if (self.stoppedFn) { 24225 // PERF TODO: Can we replace with callback, like preventedFn. Look into history 24226 events = new Y.EventTarget({
24227 fireOnce: true, 24228 context: host 24229 }); 24230 self.events = events; 24231 events.on('stopped', self.stoppedFn); 24232 } 24233 24234 24235 self._facade = null; // kill facade to eliminate stale properties 24236 24237 ef = self._createFacade(args); 24238 24239 if (ons) { 24240 self._procSubs(ons, args, ef); 24241 } 24242 24243 // bubble if this is hosted in an event target and propagation has not been stopped 24244 if (self.bubbles && host.bubble && !self.stopped) { 24245 oldbubble = es.bubbling; 24246 24247 es.bubbling = self.type; 24248 24249 if (es.type !== self.type) { 24250 es.stopped = 0; 24251 es.prevented = 0; 24252 } 24253 24254 ret = host.bubble(self, args, null, es); 24255 24256 self.stopped = Math.max(self.stopped, es.stopped); 24257 self.prevented = Math.max(self.prevented, es.prevented); 24258 24259 es.bubbling = oldbubble; 24260 } 24261 24262 prevented = self.prevented; 24263 24264 if (prevented) { 24265 preventedFn = self.preventedFn; 24266 if (preventedFn) {
24267 preventedFn.apply(host, args); 24268 } 24269 } else { 24270 defaultFn = self.defaultFn; 24271 24272 if (defaultFn && ((!self.defaultTargetOnly && !es.defaultTargetOnly) || host === ef.target)) { 24273 defaultFn.apply(host, args); 24274 } 24275 } 24276 24277 // broadcast listeners are fired as discreet events on the 24278 // YUI instance and potentially the YUI global. 24279 if (self.broadcast) { 24280 self._broadcast(args); 24281 } 24282 24283 if (afters && !self.prevented && self.stopped < 2) { 24284 24285 // Queue the after 24286 afterQueue = es.afterQueue; 24287 24288 if (es.id === self.id || self.type !== yuievt.bubbling) { 24289 24290 self._procSubs(afters, args, ef); 24291 24292 if (afterQueue) { 24293 while ((next = afterQueue.last())) { 24294 next(); 24295 } 24296 } 24297 } else { 24298 postponed = afters; 24299 24300 if (es.execDefaultCnt) { 24301 postponed = Y.merge(postponed); 24302 24303 Y.each(postponed, function(s) { 24304 s.postponed = true; 24305 }); 24306 } 24307 24308 if (!afterQueue) { 24309 es.afterQueue = new Y.Queue(); 24310 } 24311 24312 es.afterQueue.add(function() { 24313 self._procSubs(postponed, args, ef); 24314 }); 24315 } 24316 24317 } 24318 24319 self.target = null; 24320 24321 if (es.id === self.id) { 24322 24323 queue = es.queue; 24324 24325 if (queue) { 24326 while (queue.length) { 24327 q = queue.pop(); 24328 ce = q[0]; 24329 // set up stack to allow the next item to be processed 24330 es.next = ce; 24331 ce._fire(q[1]); 24332 } 24333 } 24334 24335 self.stack = null; 24336 } 24337 24338 ret = !(self.stopped); 24339 24340 if (self.type !== yuievt.bubbling) { 24341 es.stopped = 0; 24342 es.prevented = 0; 24343 self.stopped = 0; 24344 self.prevented = 0; 24345 } 24346 24347 } else { 24348 defaultFn = self.defaultFn; 24349 24350 if(defaultFn) { 24351 ef = self._createFacade(args); 24352 24353 if ((!self.defaultTargetOnly) || (host === ef.target)) {
24354 defaultFn.apply(host, args); 24355 } 24356 } 24357 } 24358 24359 // Kill the cached facade to free up memory. 24360 // Otherwise we have the facade from the last fire, sitting around forever. 24361 self._facade = null; 24362 24363 return ret; 24364}; 24365 24366/** 24367 * @method _hasPotentialSubscribers 24368 * @for CustomEvent 24369 * @private 24370 * @return {boolean} Whether the event has potential subscribers or not 24371 */ 24372CEProto._hasPotentialSubscribers = function() { 24373 return this.hasSubs() || this.host._yuievt.hasTargets || this.broadcast; 24374}; 24375 24376/** 24377 * Internal utility method to create a new facade instance and 24378 * insert it into the fire argument list, accounting for any payload 24379 * merging which needs to happen. 24380 * 24381 * This used to be called `_getFacade`, but the name seemed inappropriate 24382 * when it was used without a need for the return value. 24383 * 24384 * @method _createFacade 24385 * @private 24386 * @param fireArgs {Array} The arguments passed to "fire", which need to be 24387 * shifted (and potentially merged) when the facade is added. 24388 * @return {EventFacade} The event facade created. 24389 */ 24390 24391// TODO: Remove (private) _getFacade alias, once synthetic.js is updated. 24392CEProto._createFacade = CEProto._getFacade = function(fireArgs) { 24393 24394 var userArgs = this.details, 24395 firstArg = userArgs && userArgs[0], 24396 firstArgIsObj = (firstArg && (typeof firstArg === "object")), 24397 ef = this._facade; 24398 24399 if (!ef) { 24400 ef = new Y.EventFacade(this, this.currentTarget); 24401 } 24402 24403 if (firstArgIsObj) { 24404 // protect the event facade properties 24405 mixFacadeProps(ef, firstArg); 24406 24407 // Allow the event type to be faked http://yuilibrary.com/projects/yui3/ticket/2528376 24408 if (firstArg.type) { 24409 ef.type = firstArg.type; 24410 } 24411 24412 if (fireArgs) { 24413 fireArgs[0] = ef; 24414 } 24415 } else { 24416 if (fireArgs) { 24417 fireArgs.unshift(ef); 24418 } 24419 } 24420 24421 // update the details field with the arguments 24422 ef.details = this.details; 24423 24424 // use the original target when the event bubbled to this target 24425 ef.target = this.originalTarget || this.target; 24426 24427 ef.currentTarget = this.currentTarget; 24428 ef.stopped = 0; 24429 ef.prevented = 0; 24430 24431 this._facade = ef; 24432 24433 return this._facade; 24434}; 24435 24436/** 24437 * Utility method to manipulate the args array passed in, to add the event facade, 24438 * if it's not already the first arg. 24439 * 24440 * @method _addFacadeToArgs 24441 * @private 24442 * @param {Array} The arguments to manipulate 24443 */ 24444CEProto._addFacadeToArgs = function(args) { 24445 var e = args[0]; 24446 24447 // Trying not to use instanceof, just to avoid potential cross Y edge case issues. 24448 if (!(e && e.halt && e.stopImmediatePropagation && e.stopPropagation && e._event)) { 24449 this._createFacade(args); 24450 } 24451}; 24452 24453/** 24454 * Stop propagation to bubble targets 24455 * @for CustomEvent 24456 * @method stopPropagation 24457 */ 24458CEProto.stopPropagation = function() { 24459 this.stopped = 1; 24460 if (this.stack) { 24461 this.stack.stopped = 1; 24462 } 24463 if (this.events) { 24464 this.events.fire('stopped', this); 24465 } 24466}; 24467 24468/** 24469 * Stops propagation to bubble targets, and prevents any remaining 24470 * subscribers on the current target from executing. 24471 * @method stopImmediatePropagation 24472 */ 24473CEProto.stopImmediatePropagation = function() { 24474 this.stopped = 2; 24475 if (this.stack) { 24476 this.stack.stopped = 2; 24477 } 24478 if (this.events) { 24479 this.events.fire('stopped', this); 24480 } 24481}; 24482 24483/** 24484 * Prevents the execution of this event's defaultFn 24485 * @method preventDefault 24486 */ 24487CEProto.preventDefault = function() { 24488 if (this.preventable) { 24489 this.prevented = 1; 24490 if (this.stack) { 24491 this.stack.prevented = 1; 24492 } 24493 } 24494}; 24495 24496/** 24497 * Stops the event propagation and prevents the default 24498 * event behavior. 24499 * @method halt 24500 * @param immediate {boolean} if true additional listeners 24501 * on the current target will not be executed 24502 */ 24503CEProto.halt = function(immediate) { 24504 if (immediate) { 24505 this.stopImmediatePropagation(); 24506 } else { 24507 this.stopPropagation(); 24508 } 24509 this.preventDefault(); 24510}; 24511 24512/** 24513 * Registers another EventTarget as a bubble target. Bubble order 24514 * is determined by the order registered. Multiple targets can 24515 * be specified. 24516 * 24517 * Events can only bubble if emitFacade is true. 24518 * 24519 * Included in the event-custom-complex submodule. 24520 * 24521 * @method addTarget 24522 * @chainable 24523 * @param o {EventTarget} the target to add 24524 * @for EventTarget 24525 */ 24526ETProto.addTarget = function(o) { 24527 var etState = this._yuievt; 24528 24529 if (!etState.targets) { 24530 etState.targets = {}; 24531 } 24532 24533 etState.targets[Y.stamp(o)] = o; 24534 etState.hasTargets = true; 24535 24536 return this; 24537}; 24538 24539/** 24540 * Returns an array of bubble targets for this object. 24541 * @method getTargets 24542 * @return EventTarget[] 24543 */ 24544ETProto.getTargets = function() { 24545 var targets = this._yuievt.targets; 24546 return targets ? YObject.values(targets) : []; 24547}; 24548 24549/** 24550 * Removes a bubble target 24551 * @method removeTarget 24552 * @chainable 24553 * @param o {EventTarget} the target to remove 24554 * @for EventTarget 24555 */ 24556ETProto.removeTarget = function(o) { 24557 var targets = this._yuievt.targets; 24558 24559 if (targets) { 24560 delete targets[Y.stamp(o, true)]; 24561 24562 if (YObject.size(targets) === 0) { 24563 this._yuievt.hasTargets = false;
24564 } 24565 } 24566 24567 return this; 24568}; 24569 24570/** 24571 * Propagate an event. Requires the event-custom-complex module. 24572 * @method bubble 24573 * @param evt {CustomEvent} the custom event to propagate 24574 * @return {boolean} the aggregated return value from Event.Custom.fire 24575 * @for EventTarget 24576 */ 24577ETProto.bubble = function(evt, args, target, es) { 24578 24579 var targs = this._yuievt.targets, 24580 ret = true, 24581 t, 24582 ce, 24583 i, 24584 bc, 24585 ce2, 24586 type = evt && evt.type, 24587 originalTarget = target || (evt && evt.target) || this, 24588 oldbubble; 24589 24590 if (!evt || ((!evt.stopped) && targs)) { 24591 24592 for (i in targs) { 24593 if (targs.hasOwnProperty(i)) { 24594 24595 t = targs[i]; 24596 24597 ce = t._yuievt.events[type]; 24598 24599 if (t._hasSiblings) { 24600 ce2 = t.getSibling(type, ce); 24601 } 24602 24603 if (ce2 && !ce) { 24604 ce = t.publish(type); 24605 } 24606 24607 oldbubble = t._yuievt.bubbling; 24608 t._yuievt.bubbling = type; 24609 24610 // if this event was not published on the bubble target, 24611 // continue propagating the event. 24612 if (!ce) { 24613 if (t._yuievt.hasTargets) { 24614 t.bubble(evt, args, originalTarget, es); 24615 } 24616 } else { 24617 24618 if (ce2) { 24619 ce.sibling = ce2; 24620 } 24621 24622 // set the original target to that the target payload on the facade is correct. 24623 ce.target = originalTarget; 24624 ce.originalTarget = originalTarget; 24625 ce.currentTarget = t; 24626 bc = ce.broadcast; 24627 ce.broadcast = false; 24628 24629 // default publish may not have emitFacade true -- that 24630 // shouldn't be what the implementer meant to do 24631 ce.emitFacade = true; 24632 24633 ce.stack = es; 24634 24635 // TODO: See what's getting in the way of changing this to use 24636 // the more performant ce._fire(args || evt.details || []). 24637 24638 // Something in Widget Parent/Child tests is not happy if we 24639 // change it - maybe evt.details related? 24640 ret = ret && ce.fire.apply(ce, args || evt.details || []); 24641 24642 ce.broadcast = bc; 24643 ce.originalTarget = null; 24644 24645 // stopPropagation() was called 24646 if (ce.stopped) { 24647 break; 24648 } 24649 } 24650 24651 t._yuievt.bubbling = oldbubble; 24652 } 24653 } 24654 } 24655 24656 return ret; 24657}; 24658 24659/** 24660 * @method _hasPotentialSubscribers 24661 * @for EventTarget 24662 * @private 24663 * @param {String} fullType The fully prefixed type name 24664 * @return {boolean} Whether the event has potential subscribers or not 24665 */ 24666ETProto._hasPotentialSubscribers = function(fullType) { 24667 24668 var etState = this._yuievt, 24669 e = etState.events[fullType]; 24670 24671 if (e) { 24672 return e.hasSubs() || etState.hasTargets || e.broadcast; 24673 } else { 24674 return false; 24675 } 24676}; 24677 24678FACADE = new Y.EventFacade(); 24679FACADE_KEYS = {}; 24680 24681// Flatten whitelist 24682for (key in FACADE) { 24683 FACADE_KEYS[key] = true; 24684} 24685 24686 24687}, 'patched-v3.18.1', {"requires": ["event-custom-base"]}); 24688 24689YUI.add('event-delegate', function (Y, NAME) { 24690 24691/** 24692 * Adds event delegation support to the library. 24693 * 24694 * @module event 24695 * @submodule event-delegate 24696 */ 24697 24698var toArray = Y.Array, 24699 YLang = Y.Lang, 24700 isString = YLang.isString, 24701 isObject = YLang.isObject, 24702 isArray = YLang.isArray, 24703 selectorTest = Y.Selector.test, 24704 detachCategories = Y.Env.evt.handles; 24705 24706/** 24707 * <p>Sets up event delegation on a container element. The delegated event 24708 * will use a supplied selector or filtering function to test if the event 24709 * references at least one node that should trigger the subscription 24710 * callback.</p> 24711 * 24712 * <p>Selector string filters will trigger the callback if the event originated 24713 * from a node that matches it or is contained in a node that matches it. 24714 * Function filters are called for each Node up the parent axis to the 24715 * subscribing container node, and receive at each level the Node and the event 24716 * object. The function should return true (or a truthy value) if that Node 24717 * should trigger the subscription callback. Note, it is possible for filters 24718 * to match multiple Nodes for a single event. In this case, the delegate 24719 * callback will be executed for each matching Node.</p> 24720 * 24721 * <p>For each matching Node, the callback will be executed with its 'this' 24722 * object set to the Node matched by the filter (unless a specific context was 24723 * provided during subscription), and the provided event's 24724 * <code>currentTarget</code> will also be set to the matching Node. The 24725 * containing Node from which the subscription was originally made can be 24726 * referenced as <code>e.container</code>. 24727 * 24728 * @method delegate 24729 * @param type {String} the event type to delegate 24730 * @param fn {Function} the callback function to execute. This function 24731 * will be provided the event object for the delegated event. 24732 * @param el {String|node} the element that is the delegation container 24733 * @param filter {string|Function} a selector that must match the target of the 24734 * event or a function to test target and its parents for a match 24735 * @param context optional argument that specifies what 'this' refers to. 24736 * @param args* 0..n additional arguments to pass on to the callback function. 24737 * These arguments will be added after the event object. 24738 * @return {EventHandle} the detach handle 24739 * @static 24740 * @for Event 24741 */ 24742function delegate(type, fn, el, filter) { 24743 var args = toArray(arguments, 0, true), 24744 query = isString(el) ? el : null,
24745 typeBits, synth, container, categories, cat, i, len, handles, handle; 24746 24747 // Support Y.delegate({ click: fnA, key: fnB }, el, filter, ...); 24748 // and Y.delegate(['click', 'key'], fn, el, filter, ...); 24749 if (isObject(type)) { 24750 handles = []; 24751 24752 if (isArray(type)) { 24753 for (i = 0, len = type.length; i < len; ++i) { 24754 args[0] = type[i]; 24755 handles.push(Y.delegate.apply(Y, args)); 24756 } 24757 } else { 24758 // Y.delegate({'click', fn}, el, filter) => 24759 // Y.delegate('click', fn, el, filter) 24760 args.unshift(null); // one arg becomes two; need to make space 24761 24762 for (i in type) { 24763 if (type.hasOwnProperty(i)) { 24764 args[0] = i; 24765 args[1] = type[i]; 24766 handles.push(Y.delegate.apply(Y, args)); 24767 } 24768 } 24769 } 24770 24771 return new Y.EventHandle(handles); 24772 } 24773 24774 typeBits = type.split(/\|/); 24775 24776 if (typeBits.length > 1) { 24777 cat = typeBits.shift(); 24778 args[0] = type = typeBits.shift(); 24779 } 24780 24781 synth = Y.Node.DOM_EVENTS[type]; 24782 24783 if (isObject(synth) && synth.delegate) { 24784 handle = synth.delegate.apply(synth, arguments); 24785 } 24786 24787 if (!handle) { 24788 if (!type || !fn || !el || !filter) { 24789 return; 24790 } 24791 24792 container = (query) ? Y.Selector.query(query, null, true) : el; 24793 24794 if (!container && isString(el)) { 24795 handle = Y.on('available', function () { 24796 Y.mix(handle, Y.delegate.apply(Y, args), true); 24797 }, el); 24798 } 24799 24800 if (!handle && container) { 24801 args.splice(2, 2, container); // remove the filter 24802 24803 handle = Y.Event._attach(args, { facade: false }); 24804 handle.sub.filter = filter; 24805 handle.sub._notify = delegate.notifySub; 24806 } 24807 } 24808 24809 if (handle && cat) { 24810 categories = detachCategories[cat] || (detachCategories[cat] = {}); 24811 categories = categories[type] || (categories[type] = []); 24812 categories.push(handle); 24813 } 24814 24815 return handle; 24816} 24817
24818/** 24819Overrides the <code>_notify</code> method on the normal DOM subscription to 24820inject the filtering logic and only proceed in the case of a match. 24821 24822This method is hosted as a private property of the `delegate` method 24823(e.g. `Y.delegate.notifySub`) 24824 24825@method notifySub 24826@param thisObj {Object} default 'this' object for the callback 24827@param args {Array} arguments passed to the event's <code>fire()</code> 24828@param ce {CustomEvent} the custom event managing the DOM subscriptions for 24829 the subscribed event on the subscribing node. 24830@return {Boolean} false if the event was stopped 24831@private 24832@static 24833@since 3.2.0 24834**/ 24835delegate.notifySub = function (thisObj, args, ce) { 24836 // Preserve args for other subscribers 24837 args = args.slice(); 24838 if (this.args) { 24839 args.push.apply(args, this.args); 24840 } 24841 24842 // Only notify subs if the event occurred on a targeted element 24843 var currentTarget = delegate._applyFilter(this.filter, args, ce), 24844 //container = e.currentTarget, 24845 e, i, len, ret; 24846 24847 if (currentTarget) { 24848 // Support multiple matches up the the container subtree 24849 currentTarget = toArray(currentTarget); 24850 24851 // The second arg is the currentTarget, but we'll be reusing this 24852 // facade, replacing the currentTarget for each use, so it doesn't 24853 // matter what element we seed it with. 24854 e = args[0] = new Y.DOMEventFacade(args[0], ce.el, ce); 24855 24856 e.container = Y.one(ce.el); 24857 24858 for (i = 0, len = currentTarget.length; i < len && !e.stopped; ++i) { 24859 e.currentTarget = Y.one(currentTarget[i]); 24860 24861 ret = this.fn.apply(this.context || e.currentTarget, args); 24862 24863 if (ret === false) { // stop further notifications 24864 break; 24865 } 24866 } 24867 24868 return ret; 24869 } 24870}; 24871 24872/** 24873Compiles a selector string into a filter function to identify whether 24874Nodes along the parent axis of an event's target should trigger event 24875notification. 24876 24877This function is memoized, so previously compiled filter functions are 24878returned if the same selector string is provided. 24879 24880This function may be useful when defining synthetic events for delegate 24881handling. 24882 24883Hosted as a property of the `delegate` method (e.g. `Y.delegate.compileFilter`). 24884 24885@method compileFilter 24886@param selector {String} the selector string to base the filtration on 24887@return {Function} 24888@since 3.2.0 24889@static 24890**/ 24891delegate.compileFilter = Y.cached(function (selector) { 24892 return function (target, e) { 24893 return selectorTest(target._node, selector, 24894 (e.currentTarget === e.target) ? null : e.currentTarget._node); 24895 }; 24896}); 24897 24898/** 24899Regex to test for disabled elements during filtering. This is only relevant to 24900IE to normalize behavior with other browsers, which swallow events that occur 24901to disabled elements. IE fires the event from the parent element instead of the 24902original target, though it does preserve `event.srcElement` as the disabled 24903element. IE also supports disabled on `<a>`, but the event still bubbles, so it 24904acts more like `e.preventDefault()` plus styling. That issue is not handled here 24905because other browsers fire the event on the `<a>`, so delegate is supported in 24906both cases. 24907 24908@property _disabledRE 24909@type {RegExp} 24910@protected 24911@since 3.8.1 24912**/ 24913delegate._disabledRE = /^(?:button|input|select|textarea)$/i; 24914 24915/** 24916Walks up the parent axis of an event's target, and tests each element 24917against a supplied filter function. If any Nodes, including the container, 24918satisfy the filter, the delegated callback will be triggered for each. 24919 24920Hosted as a protected property of the `delegate` method (e.g. 24921`Y.delegate._applyFilter`). 24922 24923@method _applyFilter 24924@param filter {Function} boolean function to test for inclusion in event 24925 notification 24926@param args {Array} the arguments that would be passed to subscribers 24927@param ce {CustomEvent} the DOM event wrapper 24928@return {Node|Node[]|undefined} The Node or Nodes that satisfy the filter 24929@protected 24930**/ 24931delegate._applyFilter = function (filter, args, ce) { 24932 var e = args[0], 24933 container = ce.el, // facadeless events in IE, have no e.currentTarget 24934 target = e.target || e.srcElement, 24935 match = [], 24936 isContainer = false;
24937 24938 // Resolve text nodes to their containing element 24939 if (target.nodeType === 3) { 24940 target = target.parentNode; 24941 } 24942 24943 // For IE. IE propagates events from the parent element of disabled 24944 // elements, where other browsers swallow the event entirely. To normalize 24945 // this in IE, filtering for matching elements should abort if the target 24946 // is a disabled form control. 24947 if (target.disabled && delegate._disabledRE.test(target.nodeName)) { 24948 return match; 24949 } 24950 24951 // passing target as the first arg rather than leaving well enough alone 24952 // making 'this' in the filter function refer to the target. This is to 24953 // support bound filter functions. 24954 args.unshift(target); 24955 24956 if (isString(filter)) { 24957 while (target) { 24958 isContainer = (target === container); 24959 if (selectorTest(target, filter, (isContainer ? null: container))) { 24960 match.push(target); 24961 } 24962 24963 if (isContainer) { 24964 break; 24965 } 24966 24967 target = target.parentNode; 24968 } 24969 } else { 24970 // filter functions are implementer code and should receive wrappers 24971 args[0] = Y.one(target); 24972 args[1] = new Y.DOMEventFacade(e, container, ce); 24973 24974 while (target) { 24975 // filter(target, e, extra args...) - this === target 24976 if (filter.apply(args[0], args)) { 24977 match.push(target); 24978 } 24979 24980 if (target === container) { 24981 break; 24982 } 24983 24984 target = target.parentNode; 24985 args[0] = Y.one(target); 24986 } 24987 args[1] = e; // restore the raw DOM event 24988 } 24989 24990 if (match.length <= 1) { 24991 match = match[0]; // single match or undefined 24992 } 24993 24994 // remove the target 24995 args.shift(); 24996 24997 return match; 24998}; 24999 25000/** 25001 * Sets up event delegation on a container element. The delegated event 25002 * will use a supplied filter to test if the callback should be executed. 25003 * This filter can be either a selector string or a function that returns 25004 * a Node to use as the currentTarget for the event. 25005 * 25006 * The event object for the delegated event is supplied to the callback 25007 * function. It is modified slightly in order to support all properties 25008 * that may be needed for event delegation. 'currentTarget' is set to 25009 * the element that matched the selector string filter or the Node returned 25010 * from the filter function. 'container' is set to the element that the 25011 * listener is delegated from (this normally would be the 'currentTarget'). 25012 * 25013 * Filter functions will be called with the arguments that would be passed to 25014 * the callback function, including the event object as the first parameter. 25015 * The function should return false (or a falsey value) if the success criteria 25016 * aren't met, and the Node to use as the event's currentTarget and 'this' 25017 * object if they are. 25018 * 25019 * @method delegate 25020 * @param type {string} the event type to delegate 25021 * @param fn {function} the callback function to execute. This function 25022 * will be provided the event object for the delegated event. 25023 * @param el {string|node} the element that is the delegation container 25024 * @param filter {string|function} a selector that must match the target of the 25025 * event or a function that returns a Node or false. 25026 * @param context optional argument that specifies what 'this' refers to. 25027 * @param args* 0..n additional arguments to pass on to the callback function. 25028 * These arguments will be added after the event object. 25029 * @return {EventHandle} the detach handle 25030 * @for YUI 25031 */ 25032Y.delegate = Y.Event.delegate = delegate; 25033 25034 25035}, 'patched-v3.18.1', {"requires": ["node-base"]}); 25036 25037YUI.add('event-focus', function (Y, NAME) { 25038 25039/** 25040 * Adds bubbling and delegation support to DOM events focus and blur. 25041 * 25042 * @module event 25043 * @submodule event-focus 25044 */ 25045var Event = Y.Event, 25046 25047 YLang = Y.Lang, 25048 25049 isString = YLang.isString, 25050 25051 arrayIndex = Y.Array.indexOf, 25052 25053 useActivate = (function() { 25054 25055 // Changing the structure of this test, so that it doesn't use inline JS in HTML, 25056 // which throws an exception in Win8 packaged apps, due to additional security restrictions:
25057 // http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences 25058 25059 var supported = false, 25060 doc = Y.config.doc, 25061 p; 25062 25063 if (doc) { 25064 25065 p = doc.createElement("p"); 25066 p.setAttribute("onbeforeactivate", ";"); 25067 25068 // onbeforeactivate is a function in IE8+. 25069 // onbeforeactivate is a string in IE6,7 (unfortunate, otherwise we could have just checked for function below). 25070 // onbeforeactivate is a function in IE10, in a Win8 App environment (no exception running the test). 25071 25072 // onbeforeactivate is undefined in Webkit/Gecko. 25073 // onbeforeactivate is a function in Webkit/Gecko if it's a supported event (e.g. onclick). 25074 25075 supported = (p.onbeforeactivate !== undefined); 25076 } 25077 25078 return supported; 25079 }()); 25080 25081function define(type, proxy, directEvent) { 25082 var nodeDataKey = '_' + type + 'Notifiers'; 25083 25084 Y.Event.define(type, { 25085 25086 _useActivate : useActivate, 25087 25088 _attach: function (el, notifier, delegate) { 25089 if (Y.DOM.isWindow(el)) { 25090 return Event._attach([type, function (e) { 25091 notifier.fire(e); 25092 }, el]); 25093 } else { 25094 return Event._attach( 25095 [proxy, this._proxy, el, this, notifier, delegate], 25096 { capture: true }); 25097 } 25098 }, 25099 25100 _proxy: function (e, notifier, delegate) { 25101 var target = e.target, 25102 currentTarget = e.currentTarget, 25103 notifiers = target.getData(nodeDataKey), 25104 yuid = Y.stamp(currentTarget._node), 25105 defer = (useActivate || target !== currentTarget), 25106 directSub; 25107 25108 notifier.currentTarget = (delegate) ? target : currentTarget; 25109 notifier.container = (delegate) ? currentTarget : null; 25110 25111 // Maintain a list to handle subscriptions from nested 25112 // containers div#a>div#b>input #a.on(focus..) #b.on(focus..), 25113 // use one focus or blur subscription that fires notifiers from 25114 // #b then #a to emulate bubble sequence. 25115 if (!notifiers) { 25116 notifiers = {}; 25117 target.setData(nodeDataKey, notifiers); 25118 25119 // only subscribe to the element's focus if the target is 25120 // not the current target ( 25121 if (defer) { 25122 directSub = Event._attach( 25123 [directEvent, this._notify, target._node]).sub; 25124 directSub.once = true; 25125 } 25126 } else { 25127 // In old IE, defer is always true. In capture-phase browsers, 25128 // The delegate subscriptions will be encountered first, which 25129 // will establish the notifiers data and direct subscription 25130 // on the node. If there is also a direct subscription to the 25131 // node's focus/blur, it should not call _notify because the 25132 // direct subscription from the delegate sub(s) exists, which 25133 // will call _notify. So this avoids _notify being called 25134 // twice, unnecessarily. 25135 defer = true; 25136 } 25137 25138 if (!notifiers[yuid]) { 25139 notifiers[yuid] = []; 25140 } 25141 25142 notifiers[yuid].push(notifier); 25143 25144 if (!defer) { 25145 this._notify(e); 25146 } 25147 }, 25148 25149 _notify: function (e, container) { 25150 var currentTarget = e.currentTarget, 25151 notifierData = currentTarget.getData(nodeDataKey), 25152 axisNodes = currentTarget.ancestors(), 25153 doc = currentTarget.get('ownerDocument'), 25154 delegates = [], 25155 // Used to escape loops when there are no more 25156 // notifiers to consider 25157 count = notifierData ? 25158 Y.Object.keys(notifierData).length : 25159 0, 25160 target, notifiers, notifier, yuid, match, tmp, i, len, sub, ret; 25161 25162 // clear the notifications list (mainly for delegation) 25163 currentTarget.clearData(nodeDataKey); 25164 25165 // Order the delegate subs by their placement in the parent axis 25166 axisNodes.push(currentTarget); 25167 // document.get('ownerDocument') returns null 25168 // which we'll use to prevent having duplicate Nodes in the list 25169 if (doc) { 25170 axisNodes.unshift(doc); 25171 } 25172 25173 // ancestors() returns the Nodes from top to bottom 25174 axisNodes._nodes.reverse(); 25175 25176 if (count) { 25177 // Store the count for step 2 25178 tmp = count; 25179 axisNodes.some(function (node) { 25180 var yuid = Y.stamp(node), 25181 notifiers = notifierData[yuid], 25182 i, len; 25183 25184 if (notifiers) { 25185 count--; 25186 for (i = 0, len = notifiers.length; i < len; ++i) { 25187 if (notifiers[i].handle.sub.filter) { 25188 delegates.push(notifiers[i]); 25189 } 25190 } 25191 } 25192 25193 return !count; 25194 }); 25195 count = tmp; 25196 } 25197 25198 // Walk up the parent axis, notifying direct subscriptions and 25199 // testing delegate filters. 25200 while (count && (target = axisNodes.shift())) { 25201 yuid = Y.stamp(target); 25202 25203 notifiers = notifierData[yuid]; 25204 25205 if (notifiers) { 25206 for (i = 0, len = notifiers.length; i < len; ++i) { 25207 notifier = notifiers[i]; 25208 sub = notifier.handle.sub; 25209 match = true; 25210 25211 e.currentTarget = target; 25212 25213 if (sub.filter) { 25214 match = sub.filter.apply(target, 25215 [target, e].concat(sub.args || [])); 25216 25217 // No longer necessary to test against this 25218 // delegate subscription for the nodes along 25219 // the parent axis. 25220 delegates.splice( 25221 arrayIndex(delegates, notifier), 1); 25222 } 25223 25224 if (match) { 25225 // undefined for direct subs 25226 e.container = notifier.container; 25227 ret = notifier.fire(e); 25228 } 25229 25230 if (ret === false || e.stopped === 2) { 25231 break; 25232 } 25233 } 25234 25235 delete notifiers[yuid]; 25236 count--; 25237 } 25238 25239 if (e.stopped !== 2) { 25240 // delegates come after subs targeting this specific node 25241 // because they would not normally report until they'd 25242 // bubbled to the container node. 25243 for (i = 0, len = delegates.length; i < len; ++i) { 25244 notifier = delegates[i]; 25245 sub = notifier.handle.sub; 25246 25247 if (sub.filter.apply(target, 25248 [target, e].concat(sub.args || []))) { 25249 25250 e.container = notifier.container; 25251 e.currentTarget = target; 25252 ret = notifier.fire(e); 25253 } 25254 25255 if (ret === false || e.stopped === 2 || 25256 // If e.stopPropagation() is called, notify any 25257 // delegate subs from the same container, but break 25258 // once the container changes. This emulates 25259 // delegate() behavior for events like 'click' which 25260 // won't notify delegates higher up the parent axis. 25261 (e.stopped && delegates[i+1] && 25262 delegates[i+1].container !== notifier.container)) { 25263 break; 25264 } 25265 } 25266 } 25267 25268 if (e.stopped) { 25269 break; 25270 } 25271 } 25272 }, 25273 25274 on: function (node, sub, notifier) { 25275 sub.handle = this._attach(node._node, notifier); 25276 }, 25277 25278 detach: function (node, sub) { 25279 sub.handle.detach(); 25280 }, 25281 25282 delegate: function (node, sub, notifier, filter) { 25283 if (isString(filter)) { 25284 sub.filter = function (target) { 25285 return Y.Selector.test(target._node, filter, 25286 node === target ? null : node._node); 25287 }; 25288 } 25289 25290 sub.handle = this._attach(node._node, notifier, true); 25291 }, 25292 25293 detachDelegate: function (node, sub) { 25294 sub.handle.detach(); 25295 } 25296 }, true); 25297} 25298 25299// For IE, we need to defer to focusin rather than focus because 25300// `el.focus(); doSomething();` executes el.onbeforeactivate, el.onactivate, 25301// el.onfocusin, doSomething, then el.onfocus. All others support capture 25302// phase focus, which executes before doSomething. To guarantee consistent 25303// behavior for this use case, IE's direct subscriptions are made against 25304// focusin so subscribers will be notified before js following el.focus() is 25305// executed. 25306if (useActivate) { 25307 // name capture phase direct subscription 25308 define("focus", "beforeactivate", "focusin");
25309 define("blur", "beforedeactivate", "focusout"); 25310} else { 25311 define("focus", "focus", "focus"); 25312 define("blur", "blur", "blur"); 25313} 25314 25315 25316}, 'patched-v3.18.1', {"requires": ["event-synthetic"]}); 25317 25318YUI.add('event-hover', function (Y, NAME) { 25319 25320/** 25321 * Adds support for a "hover" event. The event provides a convenience wrapper 25322 * for subscribing separately to mouseenter and mouseleave. The signature for 25323 * subscribing to the event is</p> 25324 * 25325 * <pre><code>node.on("hover", overFn, outFn); 25326 * node.delegate("hover", overFn, outFn, ".filterSelector"); 25327 * Y.on("hover", overFn, outFn, ".targetSelector"); 25328 * Y.delegate("hover", overFn, outFn, "#container", ".filterSelector"); 25329 * </code></pre> 25330 * 25331 * <p>Additionally, for compatibility with a more typical subscription 25332 * signature, the following are also supported:</p> 25333 * 25334 * <pre><code>Y.on("hover", overFn, ".targetSelector", outFn); 25335 * Y.delegate("hover", overFn, "#container", outFn, ".filterSelector"); 25336 * </code></pre> 25337 * 25338 * @module event 25339 * @submodule event-hover 25340 */ 25341var isFunction = Y.Lang.isFunction, 25342 noop = function () {}, 25343 conf = { 25344 processArgs: function (args) { 25345 // Y.delegate('hover', over, out, '#container', '.filter') 25346 // comes in as ['hover', over, out, '#container', '.filter'], but 25347 // node.delegate('hover', over, out, '.filter') 25348 // comes in as ['hover', over, containerEl, out, '.filter'] 25349 var i = isFunction(args[2]) ? 2 : 3; 25350 25351 return (isFunction(args[i])) ? args.splice(i,1)[0] : noop; 25352 }, 25353 25354 on: function (node, sub, notifier, filter) { 25355 var args = (sub.args) ? sub.args.slice() : []; 25356 25357 args.unshift(null); 25358 25359 sub._detach = node[(filter) ? "delegate" : "on"]({ 25360 mouseenter: function (e) { 25361 e.phase = 'over'; 25362 notifier.fire(e); 25363 }, 25364 mouseleave: function (e) { 25365 var thisObj = sub.context || this; 25366 25367 args[0] = e; 25368 25369 e.type = 'hover'; 25370 e.phase = 'out'; 25371 sub._extra.apply(thisObj, args); 25372 } 25373 }, filter); 25374 }, 25375 25376 detach: function (node, sub, notifier) { 25377 sub._detach.detach(); 25378 } 25379 }; 25380 25381conf.delegate = conf.on; 25382conf.detachDelegate = conf.detach; 25383 25384Y.Event.define("hover", conf); 25385 25386 25387}, 'patched-v3.18.1', {"requires": ["event-mouseenter"]}); 25388 25389YUI.add('event-key', function (Y, NAME) { 25390 25391/** 25392 * Functionality to listen for one or more specific key combinations. 25393 * @module event 25394 * @submodule event-key 25395 */ 25396 25397var ALT = "+alt", 25398 CTRL = "+ctrl", 25399 META = "+meta", 25400 SHIFT = "+shift", 25401 25402 trim = Y.Lang.trim, 25403 25404 eventDef = { 25405 KEY_MAP: { 25406 enter : 13, 25407 space : 32, 25408 esc : 27, 25409 backspace: 8, 25410 tab : 9, 25411 pageup : 33, 25412 pagedown : 34 25413 }, 25414 25415 _typeRE: /^(up|down|press):/, 25416 _keysRE: /^(?:up|down|press):|\+(alt|ctrl|meta|shift)/g, 25417 25418 processArgs: function (args) { 25419 var spec = args.splice(3,1)[0], 25420 mods = Y.Array.hash(spec.match(/\+(?:alt|ctrl|meta|shift)\b/g) || []), 25421 config = { 25422 type: this._typeRE.test(spec) ? RegExp.$1 : null, 25423 mods: mods, 25424 keys: null 25425 }, 25426 // strip type and modifiers from spec, leaving only keyCodes 25427 bits = spec.replace(this._keysRE, ''), 25428 chr, uc, lc, i; 25429 25430 if (bits) { 25431 bits = bits.split(','); 25432 25433 config.keys = {}; 25434 25435 // FIXME: need to support '65,esc' => keypress, keydown 25436 for (i = bits.length - 1; i >= 0; --i) { 25437 chr = trim(bits[i]); 25438 25439 // catch sloppy filters, trailing commas, etc 'a,,' 25440 if (!chr) { 25441 continue; 25442 } 25443 25444 // non-numerics are single characters or key names 25445 if (+chr == chr) { 25446 config.keys[chr] = mods; 25447 } else { 25448 lc = chr.toLowerCase(); 25449 25450 if (this.KEY_MAP[lc]) { 25451 config.keys[this.KEY_MAP[lc]] = mods; 25452 // FIXME: '65,enter' defaults keydown for both 25453 if (!config.type) { 25454 config.type = "down"; // safest 25455 } 25456 } else { 25457 // FIXME: Character mapping only works for keypress 25458 // events. Otherwise, it uses String.fromCharCode() 25459 // from the keyCode, which is wrong. 25460 chr = chr.charAt(0); 25461 uc = chr.toUpperCase(); 25462 25463 if (mods["+shift"]) { 25464 chr = uc; 25465 } 25466 25467 // FIXME: stupid assumption that 25468 // the keycode of the lower case == the 25469 // charCode of the upper case 25470 // a (key:65,char:97), A (key:65,char:65) 25471 config.keys[chr.charCodeAt(0)] = 25472 (chr === uc) ? 25473 // upper case chars get +shift free 25474 Y.merge(mods, { "+shift": true }) : 25475 mods; 25476 } 25477 } 25478 } 25479 } 25480 25481 if (!config.type) { 25482 config.type = "press"; 25483 } 25484 25485 return config; 25486 }, 25487 25488 on: function (node, sub, notifier, filter) { 25489 var spec = sub._extra, 25490 type = "key" + spec.type, 25491 keys = spec.keys, 25492 method = (filter) ? "delegate" : "on"; 25493 25494 // Note: without specifying any keyCodes, this becomes a 25495 // horribly inefficient alias for 'keydown' (et al), but I 25496 // can't abort this subscription for a simple 25497 // Y.on('keypress', ...); 25498 // Please use keyCodes or just subscribe directly to keydown, 25499 // keyup, or keypress 25500 sub._detach = node[method](type, function (e) { 25501 var key = keys ? keys[e.which] : spec.mods; 25502 25503 if (key && 25504 (!key[ALT] || (key[ALT] && e.altKey)) && 25505 (!key[CTRL] || (key[CTRL] && e.ctrlKey)) && 25506 (!key[META] || (key[META] && e.metaKey)) && 25507 (!key[SHIFT] || (key[SHIFT] && e.shiftKey))) 25508 { 25509 notifier.fire(e); 25510 } 25511 }, filter); 25512 }, 25513 25514 detach: function (node, sub, notifier) { 25515 sub._detach.detach(); 25516 } 25517 }; 25518 25519eventDef.delegate = eventDef.on; 25520eventDef.detachDelegate = eventDef.detach; 25521 25522/** 25523 * <p>Add a key listener. The listener will only be notified if the 25524 * keystroke detected meets the supplied specification. The 25525 * specification is a string that is defined as:</p> 25526 * 25527 * <dl> 25528 * <dt>spec</dt> 25529 * <dd><code>[{type}:]{code}[,{code}]*</code></dd> 25530 * <dt>type</dt> 25531 * <dd><code>"down", "up", or "press"</code></dd> 25532 * <dt>code</dt> 25533 * <dd><code>{keyCode|character|keyName}[+{modifier}]*</code></dd> 25534 * <dt>modifier</dt> 25535 * <dd><code>"shift", "ctrl", "alt", or "meta"</code></dd> 25536 * <dt>keyName</dt> 25537 * <dd><code>"enter", "space", "backspace", "esc", "tab", "pageup", or "pagedown"</code></dd> 25538 * </dl> 25539 * 25540 * <p>Examples:</p> 25541 * <ul> 25542 * <li><code>Y.on("key", callback, "press:12,65+shift+ctrl", "#my-input");</code></li> 25543 * <li><code>Y.delegate("key", preventSubmit, "#forms", "enter", "input[type=text]");</code></li> 25544 * <li><code>Y.one("doc").on("key", viNav, "j,k,l,;");</code></li> 25545 * </ul> 25546 * 25547 * @event key 25548 * @for YUI 25549 * @param type {string} 'key' 25550 * @param fn {function} the function to execute 25551 * @param id {string|HTMLElement|collection}
25551 the element(s) to bind 25552 * @param spec {string} the keyCode and modifier specification 25553 * @param o optional context object 25554 * @param args 0..n additional arguments to provide to the listener. 25555 * @return {Event.Handle} the detach handle 25556 */ 25557Y.Event.define('key', eventDef, true); 25558 25559 25560}, 'patched-v3.18.1', {"requires": ["event-synthetic"]}); 25561 25562YUI.add('event-mouseenter', function (Y, NAME) { 25563 25564/** 25565 * <p>Adds subscription and delegation support for mouseenter and mouseleave 25566 * events. Unlike mouseover and mouseout, these events aren't fired from child 25567 * elements of a subscribed node.</p> 25568 * 25569 * <p>This avoids receiving three mouseover notifications from a setup like</p> 25570 * 25571 * <pre><code>div#container > p > a[href]</code></pre> 25572 * 25573 * <p>where</p> 25574 * 25575 * <pre><code>Y.one('#container').on('mouseover', callback)</code></pre> 25576 * 25577 * <p>When the mouse moves over the link, one mouseover event is fired from 25578 * #container, then when the mouse moves over the p, another mouseover event is 25579 * fired and bubbles to #container, causing a second notification, and finally 25580 * when the mouse moves over the link, a third mouseover event is fired and 25581 * bubbles to #container for a third notification.</p> 25582 * 25583 * <p>By contrast, using mouseenter instead of mouseover, the callback would be 25584 * executed only once when the mouse moves over #container.</p> 25585 * 25586 * @module event 25587 * @submodule event-mouseenter 25588 */ 25589 25590var domEventProxies = Y.Env.evt.dom_wrappers, 25591 contains = Y.DOM.contains, 25592 toArray = Y.Array, 25593 noop = function () {}, 25594 25595 config = { 25596 proxyType: "mouseover", 25597 relProperty: "fromElement", 25598 25599 _notify: function (e, property, notifier) { 25600 var el = this._node, 25601 related = e.relatedTarget || e[property]; 25602 25603 if (el !== related && !contains(el, related)) { 25604 notifier.fire(new Y.DOMEventFacade(e, el, 25605 domEventProxies['event:' + Y.stamp(el) + e.type])); 25606 } 25607 }, 25608 25609 on: function (node, sub, notifier) { 25610 var el = Y.Node.getDOMNode(node), 25611 args = [ 25612 this.proxyType, 25613 this._notify, 25614 el, 25615 null, 25616 this.relProperty, 25617 notifier]; 25618 25619 sub.handle = Y.Event._attach(args, { facade: false }); 25620 // node.on(this.proxyType, notify, null, notifier); 25621 }, 25622 25623 detach: function (node, sub) { 25624 sub.handle.detach(); 25625 }, 25626 25627 delegate: function (node, sub, notifier, filter) { 25628 var el = Y.Node.getDOMNode(node), 25629 args = [ 25630 this.proxyType, 25631 noop, 25632 el, 25633 null, 25634 notifier 25635 ]; 25636 25637 sub.handle = Y.Event._attach(args, { facade: false }); 25638 sub.handle.sub.filter = filter; 25639 sub.handle.sub.relProperty = this.relProperty; 25640 sub.handle.sub._notify = this._filterNotify; 25641 }, 25642 25643 _filterNotify: function (thisObj, args, ce) { 25644 args = args.slice(); 25645 if (this.args) { 25646 args.push.apply(args, this.args); 25647 } 25648 25649 var currentTarget = Y.delegate._applyFilter(this.filter, args, ce), 25650 related = args[0].relatedTarget || args[0][this.relProperty], 25651 e, i, len, ret, ct; 25652 25653 if (currentTarget) { 25654 currentTarget = toArray(currentTarget); 25655 25656 for (i = 0, len = currentTarget.length && (!e || !e.stopped); i < len; ++i) { 25657 ct = currentTarget[0]; 25658 if (!contains(ct, related)) { 25659 if (!e) { 25660 e = new Y.DOMEventFacade(args[0], ct, ce); 25661 e.container = Y.one(ce.el); 25662 } 25663 e.currentTarget = Y.one(ct); 25664 25665 // TODO: where is notifier? args? this.notifier? 25666 ret = args[1].fire(e); 25667 25668 if (ret === false) { 25669 break; 25670 } 25671 } 25672 } 25673 } 25674 25675 return ret; 25676 }, 25677 25678 detachDelegate: function (node, sub) { 25679 sub.handle.detach(); 25680 } 25681 }; 25682 25683Y.Event.define("mouseenter", config, true); 25684Y.Event.define("mouseleave", Y.merge(config, { 25685 proxyType: "mouseout", 25686 relProperty: "toElement" 25687}), true); 25688 25689 25690}, 'patched-v3.18.1', {"requires": ["event-synthetic"]}); 25691 25692YUI.add('event-mousewheel', function (Y, NAME) { 25693 25694/** 25695 * Adds mousewheel event support 25696 * @module event 25697 * @submodule event-mousewheel 25698 */ 25699var DOM_MOUSE_SCROLL = 'DOMMouseScroll', 25700 fixArgs = function(args) { 25701 var a = Y.Array(args, 0, true), target; 25702 if (Y.UA.gecko) { 25703 a[0] = DOM_MOUSE_SCROLL; 25704 target = Y.config.win; 25705 } else { 25706 target = Y.config.doc; 25707 } 25708 25709 if (a.length < 3) { 25710 a[2] = target; 25711 } else { 25712 a.splice(2, 0, target); 25713 } 25714 25715 return a; 25716 }; 25717 25718/** 25719 * Mousewheel event. This listener is automatically attached to the 25720 * correct target, so one should not be supplied. Mouse wheel 25721 * direction and velocity is stored in the 'wheelDelta' field. 25722 * @event mousewheel 25723 * @param type {string} 'mousewheel' 25724 * @param fn {function} the callback to execute 25725 * @param context optional context object 25726 * @param args 0..n additional arguments to provide to the listener. 25727 * @return {EventHandle} the detach handle 25728 * @for YUI 25729 */ 25730Y.Env.evt.plugins.mousewheel = { 25731 on: function() { 25732 return Y.Event._attach(fixArgs(arguments)); 25733 }, 25734 25735 detach: function() { 25736 return Y.Event.detach.apply(Y.Event, fixArgs(arguments)); 25737 } 25738}; 25739 25740 25741}, 'patched-v3.18.1', {"requires": ["node-base"]}); 25742
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.