Browse files

Initial Commit

  • Loading branch information...
0 parents commit 1ab9cbb67b432761bd636283fe5beae43cdb6520 @davglass committed Jan 30, 2012
Showing with 14,891 additions and 0 deletions.
  1. +30 −0 LICENSE
  2. +2 −0 Makefile
  3. +93 −0 README.md
  4. +1 −0 build/loader-min.js
  5. BIN build/loader-zip.js.gz
  6. +7,307 −0 build/loader.js
  7. +1,208 −0 js/get.js
  8. +2,545 −0 js/loader-base.js
  9. +3,528 −0 js/yui-core.js
  10. +18 −0 scripts/concat.sh
  11. +1 −0 test/bar.js
  12. +1 −0 test/foo/foo.js
  13. +60 −0 test/index-resolve.html
  14. +58 −0 test/index.html
  15. +12 −0 test/my/css/files.css
  16. +1 −0 test/path/to/baz.js
  17. +22 −0 wrap/bottom.js
  18. +4 −0 wrap/top.js
30 LICENSE
@@ -0,0 +1,30 @@
+Software License Agreement (BSD License)
+
+Copyright (c) 2012, Dav Glass <davglass@gmail.com>.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+* The name of Dav Glass may not be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of Dav Glass.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
2 Makefile
@@ -0,0 +1,2 @@
+all:
+ ./scripts/concat.sh
93 README.md
@@ -0,0 +1,93 @@
+Prototype YUI Loader Stand Alone
+================================
+
+This repo contains a little build script to create a stand alone version
+of the latest YUI 3.5.0pr2 Loader.
+
+It includes:
+
+ yui-core
+ get
+ loader-base
+
+Currently it's 225k raw, 43k minimized and 16K minned and gzipped.
+
+This can easily be worked on once I modularize the YUI core more so it doesn't
+contain things that are not needed all the time.
+
+Example here:
+http://dl.dropbox.com/u/5669457/loader-alone/test/index.html
+
+**Notice that YUI is not loaded on the page, it's there but wrapped up in an anonymous function.**
+
+Usage
+-----
+
+Everything you need to use Loader is already on this repo, the `build` directory contains
+a loader.js and loader-min.js
+
+```javascript
+var loader = new YUILoader({
+ root: '',
+ base: '',
+ groups: {
+ local: {
+ modules: {
+ foo: {
+ type: 'js',
+ path: 'foo/foo.js',
+ requires: [ 'bar', 'baz' ]
+ },
+ baz: 'path/to/baz.js',
+ bar: 'bar.js',
+ somecss: 'my/css/files.css'
+ }
+ }
+ },
+ require: [ 'foo', 'somecss' ]
+});
+
+loader.load(function(e) {
+ log('All items have been loaded..', e);
+});
+```
+
+
+Concept
+-------
+
+The concept here is pretty simple, it concats `yui-core`, `get` &amp; `loader-base` into a single file.
+Then it wraps that code with something like this:
+
+```javascript
+(function() {
+ var YUI;
+ var exports = {};
+
+ //Concatted Source here
+
+ YUI.Env.core.push('loader-base');
+
+ var Y = YUI();
+
+ window.YUILoader = Y.Loader;
+
+ Y.Loader.prototype.load = function(cb) {
+ var self = this,
+ out = self.resolve(true);
+
+ self.data = out;
+
+ self.onEnd = function() {
+ cb.apply(self.context || window, arguments);
+ }
+
+ self.insert();
+ }
+
+}());
+```
+
+This wrapping code is boilerplate for forcing YUI to attach itself to the `exports` object.
+Then augment the core to autoload the `loader-base` module, then expose a global `YUILoader` var.
+Then it adds a `load` method into Loader's prototype and does all the `Loader` magic.
1 build/loader-min.js
@@ -0,0 +1 @@
+(function(){var b;var a={};if(typeof b!="undefined"){b._YUI=b}var b=function(){var f=0,j=this,e=arguments,d=e.length,h=function(k,i){return(k&&k.hasOwnProperty&&(k instanceof i))},g=(typeof YUI_config!=="undefined")&&YUI_config;if(!(h(j,b))){j=new b()}else{j._init();if(b.GlobalConfig){j.applyConfig(b.GlobalConfig)}if(g){j.applyConfig(g)}if(!d){j._setup()}}if(d){for(;f<d;f++){j.applyConfig(e[f])}j._setup()}j.instanceOf=h;return j};(function(){var t,e,u="@VERSION@",l=".",r="http://yui.yahooapis.com/",x="yui3-js-enabled",g="yui3-css-stamp",p=function(){},k=Array.prototype.slice,v={"io.xdrReady":1,"io.xdrResponse":1,"SWF.eventHandler":1},j=(typeof window!="undefined"),i=(j)?window:null,z=(j)?i.document:null,h=z&&z.documentElement,d=h&&h.className,f={},m=new Date().getTime(),q=function(D,C,B,A){if(D&&D.addEventListener){D.addEventListener(C,B,A)}else{if(D&&D.attachEvent){D.attachEvent("on"+C,B)}}},y=function(E,D,C,A){if(E&&E.removeEventListener){try{E.removeEventListener(D,C,A)}catch(B){}}else{if(E&&E.detachEvent){E.detachEvent("on"+D,C)}}},w=function(){b.Env.windowLoaded=true;b.Env.DOMReady=true;if(j){y(window,"load",w)}},n=function(C,B){var A=C.Env._loader;if(A){A.ignoreRegistered=false;A.onEnd=null;A.data=null;A.required=[];A.loadType=null}else{A=new C.Loader(C.config);C.Env._loader=A}b.Env.core=C.Array.dedupe([].concat(b.Env.core,["loader-base","loader-rollup","loader-yui3"]));return A},s=function(C,B){for(var A in B){if(B.hasOwnProperty(A)){C[A]=B[A]}}},o={success:true};if(h&&d.indexOf(x)==-1){if(d){d+=" "}d+=x;h.className=d}if(u.indexOf("@")>-1){u="3.3.0"}t={applyConfig:function(G){G=G||p;var C,E,D=this.config,F=D.modules,B=D.groups,A=this.Env._loader;for(E in G){if(G.hasOwnProperty(E)){C=G[E];if(F&&E=="modules"){s(F,C)}else{if(B&&E=="groups"){s(B,C)}else{if(E=="win"){D[E]=(C&&C.contentWindow)||C;D.doc=D[E]?D[E].document:null}else{if(E=="_yuid"){}else{D[E]=C}}}}}}if(A){A._config(G)}},_config:function(A){this.applyConfig(A)},_init:function(){var D,C,E=this,A=b.Env,B=E.Env,F;E.version=u;if(!B){E.Env={core:["get","intl-base"],mods:{},versions:{},base:r,cdn:r+u+"/build/",_idx:0,_used:{},_attached:{},_missed:[],_yidx:0,_uidx:0,_guidp:"y",_loaded:{},_BASE_RE:/(?:\?(?:[^&]*&)*([^&]*))?\b(simpleyui|yui(?:-\w+)?)\/\2(?:-(min|debug))?\.js/,parseBasePath:function(K,I){var G=K.match(I),J,H;if(G){J=RegExp.leftContext||K.slice(0,K.indexOf(G[0]));H=G[3];if(G[1]){J+="?"+G[1]}J={filter:H,path:J}}return J},getBase:A&&A.getBase||function(K){var I=(z&&z.getElementsByTagName("script"))||[],L=B.cdn,H,J,G,M;for(J=0,G=I.length;J<G;++J){M=I[J].src;if(M){H=E.Env.parseBasePath(M,K);if(H){D=H.filter;L=H.path;break}}}return L}};B=E.Env;B._loaded[u]={};if(A&&E!==b){B._yidx=++A._yidx;B._guidp=("yui_"+u+"_"+B._yidx+"_"+m).replace(/\./g,"_")}else{if(b._YUI){A=b._YUI.Env;B._yidx+=A._yidx;B._uidx+=A._uidx;for(F in A){if(!(F in B)){B[F]=A[F]}}delete b._YUI}}E.id=E.stamp(E);f[E.id]=E}E.constructor=b;E.config=E.config||{win:i,doc:z,debug:true,useBrowserConsole:true,throwFail:true,bootstrap:true,cacheUse:true,fetchCSS:true};if(z&&!z.getElementById(g)){C=z.createElement("div");C.innerHTML='<div id="'+g+'" style="position: absolute !important; visibility: hidden !important"></div>';b.Env.cssStampEl=C.firstChild;h.insertBefore(b.Env.cssStampEl,h.firstChild)}E.config.lang=E.config.lang||"en-US";E.config.base=b.config.base||E.Env.getBase(E.Env._BASE_RE);if(!D||(!("mindebug").indexOf(D))){D="min"}D=(D)?"-"+D:D;E.config.loaderPath=b.config.loaderPath||"loader/loader"+D+".js"},_setup:function(F){var B,E=this,A=[],D=b.Env.mods,C=E.config.core||[].concat(b.Env.core);for(B=0;B<C.length;B++){if(D[C[B]]){A.push(C[B])}}E._attach(["yui-base"]);E._attach(A);if(E.Loader){n(E)}},applyTo:function(G,F,C){if(!(F in v)){this.log(F+": applyTo not allowed","warn","yui");return null}var B=f[G],E,A,D;if(B){E=F.split(".");A=B;for(D=0;D<E.length;D=D+1){A=A[E[D]];if(!A){this.log("applyTo not found: "+F,"warn","yui")}}return A&&A.apply(B,C)}return null},add:function(B,G,F,A){A=A||{};var E=b.Env,H={name:B,fn:G,version:F,details:A},I,D,C=E.versions;E.mods[B]=H;C[F]=C[F]||{};C[F][B]=H;for(D in f){if(f.hasOwnProperty(D)){I=f[D].Env._loader;if(I){if(!I.moduleInfo[B]){I.addModule(A,B)}}}}return this},_attach:function(F,Q){var J,R,P,M,A,H,C,D=b.Env.mods,K=b.Env.aliases,B=this,I,E=B.Env._loader,G=B.Env._attached,L=F.length,E,O=[];for(J=0;J<L;J++){R=F[J];P=D[R];O.push(R);if(E&&E.conditions[R]){B.Object.each(E.conditions[R],function(T){var S=T&&((T.ua&&B.UA[T.ua])||(T.test&&T.test(B)));if(S){O.push(T.name)}})}}F=O;L=F.length;for(J=0;J<L;J++){if(!G[F[J]]){R=F[J];P=D[R];if(K&&K[R]){B._attach(K[R]);continue}if(!P){if(E&&E.moduleInfo[R]){P=E.moduleInfo[R];Q=true}if(!Q&&R){if((R.indexOf("skin-")===-1)&&(R.indexOf("css")===-1)){B.Env._missed.push(R);B.Env._missed=B.Array.dedupe(B.Env._missed);B.message("NOT loaded: "+R,"warn","yui")}}}else{G[R]=true;for(I=0;I<B.Env._missed.length;I++){if(B.Env._missed[I]===R){B.message("Found: "+R+" (was reported as missing earlier)","warn","yui");B.Env._missed.splice(I,1)}}M=P.details;A=M.requires;H=M.use;C=M.after;if(A){for(I=0;I<A.length;I++){if(!G[A[I]]){if(!B._attach(A)){return false}break}}}if(C){for(I=0;I<C.length;I++){if(!G[C[I]]){if(!B._attach(C,true)){return false}break}}}if(P.fn){try{P.fn(B,R)}catch(N){B.error("Attach error: "+R,N,R);return false}}if(H){for(I=0;I<H.length;I++){if(!G[H[I]]){if(!B._attach(H)){return false}break}}}}}}return true},use:function(){var D=k.call(arguments,0),H=D[D.length-1],G=this,F=0,B=[],C,A=G.Env,E=true;if(G.Lang.isFunction(H)){D.pop()}else{H=null}if(G.Lang.isArray(D[0])){D=D[0]}if(G.config.cacheUse){while((C=D[F++])){if(!A._attached[C]){E=false;break}}if(E){if(D.length){}G._notify(H,o,D);return G}}if(G._loading){G._useQueue=G._useQueue||new G.Queue();G._useQueue.add([D,H])}else{G._use(D,function(J,I){J._notify(H,I,D)})}return G},_notify:function(D,A,B){if(!A.success&&this.config.loadErrorFn){this.config.loadErrorFn.call(this,this,D,A,B)}else{if(D){try{D(this,A)}catch(C){this.error("use callback error",C,B)}}}},_use:function(C,E){if(!this.Array){this._attach(["yui-base"])}var R,J,S,O,B=this,T=b.Env,D=T.mods,A=B.Env,G=A._used,Q=T.aliases,N=T._loaderQueue,W=C[0],I=B.Array,U=B.config,H=U.bootstrap,P=[],L=[],V=true,F=U.fetchCSS,M=function(aa,Z){var Y=0,X=[];if(!aa.length){return}if(Q){for(Y=0;Y<aa.length;Y++){if(Q[aa[Y]]){X=[].concat(X,Q[aa[Y]])}else{X.push(aa[Y])}}aa=X}I.each(aa,function(ad){if(!Z){L.push(ad)}if(G[ad]){return}var ab=D[ad],ae,ac;if(ab){G[ad]=true;ae=ab.details.requires;ac=ab.details.use}else{if(!T._loaded[u][ad]){P.push(ad)}else{G[ad]=true}}if(ae&&ae.length){M(ae)}if(ac&&ac.length){M(ac,1)}})},K=function(ab){var Z=ab||{success:true,msg:"not dynamic"},Y,X,aa=true,ac=Z.data;B._loading=false;if(ac){X=P;P=[];L=[];M(ac);Y=P.length;if(Y){if(P.sort().join()==X.sort().join()){Y=false}}}if(Y&&ac){B._loading=false;B._use(C,function(){if(B._attach(ac)){B._notify(E,Z,ac)}})}else{if(ac){aa=B._attach(ac)}if(aa){B._notify(E,Z,C)}}if(B._useQueue&&B._useQueue.size()&&!B._loading){B._use.apply(B,B._useQueue.next())}};if(W==="*"){V=B._attach(B.Object.keys(D));if(V){K()}return B}if(D.loader&&!B.Loader){B._attach(["loader"])}if(H&&B.Loader&&C.length){J=n(B);J.require(C);J.ignoreRegistered=true;J._boot=true;J.calculate(null,(F)?null:"js");C=J.sorted;J._boot=false}M(C);R=P.length;if(R){P=B.Object.keys(I.hash(P));R=P.length}if(H&&R&&B.Loader){B._loading=true;J=n(B);J.onEnd=K;J.context=B;J.data=C;J.ignoreRegistered=false;J.require(C);J.insert(null,(F)?null:"js")}else{if(H&&R&&B.Get&&!A.bootstrapped){B._loading=true;S=function(){B._loading=false;N.running=false;A.bootstrapped=true;T._bootstrapping=false;if(B._attach(["loader"])){B._use(C,E)}};if(T._bootstrapping){N.add(S)}else{T._bootstrapping=true;B.Get.script(U.base+U.loaderPath,{onEnd:S})}}else{V=B._attach(C);if(V){K()}}}return B},namespace:function(){var B=arguments,F,D=0,C,E,A;for(;D<B.length;D++){F=this;A=B[D];if(A.indexOf(l)>-1){E=A.split(l);for(C=(E[0]=="YAHOO")?1:0;C<E.length;C++){F[E[C]]=F[E[C]]||{};F=F[E[C]]}}else{F[A]=F[A]||{};F=F[A]}}return F},log:p,message:p,dump:function(A){return""+A},error:function(E,B,D){var C=this,A;if(C.config.errorFn){A=C.config.errorFn.apply(C,arguments)}if(C.config.throwFail&&!A){throw (B||new Error(E))}else{C.message(E,"error",""+D)}return C},guid:function(A){var B=this.Env._guidp+"_"+(++this.Env._uidx);return(A)?(A+B):B},stamp:function(C,D){var A;if(!C){return C}if(C.uniqueID&&C.nodeType&&C.nodeType!==9){A=C.uniqueID}else{A=(typeof C==="string")?C:C._yuid}if(!A){A=this.guid();if(!D){try{C._yuid=A}catch(B){A=null}}}return A},destroy:function(){var A=this;if(A.Event){A.Event._unload()}delete f[A.id];delete A.Env;delete A.config}};b.prototype=t;for(e in t){if(t.hasOwnProperty(e)){b[e]=t[e]}}b.applyConfig=function(A){if(!A){return}if(b.GlobalConfig){this.prototype.applyConfig.call(this,b.GlobalConfig)}this.prototype.applyConfig.call(this,A);b.GlobalConfig=this.config};b._init();if(j){q(window,"load",w)}else{w()}b.Env.add=q;b.Env.remove=y;if(typeof a=="object"){a.YUI=b}}());b.add("yui-base",function(e){var m=e.Lang||(e.Lang={}),r=String.prototype,o=Object.prototype.toString,d={"undefined":"undefined",number:"number","boolean":"boolean",string:"string","[object Function]":"function","[object RegExp]":"regexp","[object Array]":"array","[object Date]":"date","[object Error]":"error"},f=/\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,v=/^\s+|\s+$/g,h=/\{\s*\[(?:native code|function)\]\s*\}/i;m._isNative=function(z){return !!(z&&h.test(z))};m.isArray=m._isNative(Array.isArray)?Array.isArray:function(z){return m.type(z)==="array"};m.isBoolean=function(z){return typeof z==="boolean"};m.isDate=function(z){return m.type(z)==="date"&&z.toString()!=="Invalid Date"&&!isNaN(z)};m.isFunction=function(z){return m.type(z)==="function"};m.isNull=function(z){return z===null};m.isNumber=function(z){return typeof z==="number"&&isFinite(z)};m.isObject=function(B,A){var z=typeof B;return(B&&(z==="object"||(!A&&(z==="function"||m.isFunction(B)))))||false};m.isString=function(z){return typeof z==="string"};m.isUndefined=function(z){return typeof z==="undefined"};m.isValue=function(A){var z=m.type(A);switch(z){case"number":return isFinite(A);case"null":case"undefined":return false;default:return !!z}};m.now=Date.now||function(){return new Date().getTime()};m.sub=function(z,A){return z.replace?z.replace(f,function(B,C){return m.isUndefined(A[C])?B:A[C]}):z};m.trim=r.trim?function(z){return z&&z.trim?z.trim():z}:function(z){try{return z.replace(v,"")}catch(A){return z}};m.trimLeft=r.trimLeft?function(z){return z.trimLeft()}:function(z){return z.replace(/^\s+/,"")};m.trimRight=r.trimRight?function(z){return z.trimRight()}:function(z){return z.replace(/\s+$/,"")};m.type=function(z){return d[typeof z]||d[o.call(z)]||(z?"object":"null")};var j=e.Lang,u=Array.prototype,s=Object.prototype.hasOwnProperty;function n(B,E,D){var A,z;E||(E=0);if(D||n.test(B)){try{return u.slice.call(B,E)}catch(C){z=[];for(A=B.length;E<A;++E){z.push(B[E])}return z}}return[B]}e.Array=n;n.dedupe=function(E){var D={},B=[],A,C,z;for(A=0,z=E.length;A<z;++A){C=E[A];if(!s.call(D,C)){D[C]=1;B.push(C)}}return B};n.each=n.forEach=j._isNative(u.forEach)?function(B,z,A){u.forEach.call(B||[],z,A||e);return e}:function(D,B,C){for(var A=0,z=(D&&D.length)||0;A<z;++A){if(A in D){B.call(C||e,D[A],A,D)}}return e};n.hash=function(C,A){var D={},E=(A&&A.length)||0,B,z;for(B=0,z=C.length;B<z;++B){if(B in C){D[C[B]]=E>B&&B in A?A[B]:true}}return D};n.indexOf=j._isNative(u.indexOf)?function(A,z){return u.indexOf.call(A,z)}:function(C,B){for(var A=0,z=C.length;A<z;++A){if(A in C&&C[A]===B){return A}}return -1};n.numericSort=function(A,z){return A-z};n.some=j._isNative(u.some)?function(B,z,A){return u.some.call(B,z,A)}:function(D,B,C){for(var A=0,z=D.length;A<z;++A){if(A in D&&B.call(C,D[A],A,D)){return true}}return false};n.test=function(B){var z=0;if(j.isArray(B)){z=1}else{if(j.isObject(B)){try{if("length" in B&&!B.tagName&&!B.alert&&!B.apply){z=2}}catch(A){}}}return z};function x(){this._init();this.add.apply(this,arguments)}x.prototype={_init:function(){this._q=[]},next:function(){return this._q.shift()},last:function(){return this._q.pop()},add:function(){this._q.push.apply(this._q,arguments);return this},size:function(){return this._q.length}};e.Queue=x;b.Env._loaderQueue=b.Env._loaderQueue||new x();var q="__",s=Object.prototype.hasOwnProperty,p=e.Lang.isObject,i=e.config.win;e.cached=function(B,z,A){z||(z={});return function(C){var D=arguments.length>1?Array.prototype.join.call(arguments,q):String(C);if(!(D in z)||(A&&z[D]==A)){z[D]=B.apply(B,arguments)}return z[D]}};e.getLocation=function(){return i&&i.location};e.merge=function(){var B=arguments,C=0,A=B.length,z={};for(;C<A;++C){e.mix(z,B[C],true)}return z};e.mix=function(z,A,G,B,D,H){var E,K,J,C,L,F,I;if(!z||!A){return z||e}if(D){if(D===2){e.mix(z.prototype,A.prototype,G,B,0,H)}J=D===1||D===3?A.prototype:A;I=D===1||D===4?z.prototype:z;if(!J||!I){return z}}else{J=A;I=z}E=G&&!H;if(B){for(C=0,F=B.length;C<F;++C){L=B[C];if(!s.call(J,L)){continue}K=E?false:L in I;if(H&&K&&p(I[L],true)&&p(J[L],true)){e.mix(I[L],J[L],G,null,0,H)}else{if(G||!K){I[L]=J[L]}}}}else{for(L in J){if(!s.call(J,L)){continue}K=E?false:L in I;if(H&&K&&p(I[L],true)&&p(J[L],true)){e.mix(I[L],J[L],G,null,0,H)}else{if(G||!K){I[L]=J[L]}}}if(e.Object._hasEnumBug){e.mix(I,J,G,e.Object._forceEnum,D,H)}}return z};var j=e.Lang,s=Object.prototype.hasOwnProperty,y,k=e.Object=j._isNative(Object.create)?function(z){return Object.create(z)}:(function(){function z(){}return function(A){z.prototype=A;return new z()}}()),g=k._forceEnum=["hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toString","toLocaleString","valueOf"],w=k._hasEnumBug=!{valueOf:0}.propertyIsEnumerable("valueOf"),t=k._hasProtoEnumBug=(function(){}).propertyIsEnumerable("prototype"),l=k.owns=function(A,z){return !!A&&s.call(A,z)};k.hasKey=l;k.keys=j._isNative(Object.keys)?Object.keys:function(D){if(!j.isObject(D)){throw new TypeError("Object.keys called on a non-object")}var C=[],B,A,z;if(t&&typeof D==="function"){for(A in D){if(l(D,A)&&A!=="prototype"){C.push(A)}}}else{for(A in D){if(l(D,A)){C.push(A)}}}if(w){for(B=0,z=g.length;B<z;++B){A=g[B];if(l(D,A)){C.push(A)}}}return C};k.values=function(D){var C=k.keys(D),B=0,z=C.length,A=[];for(;B<z;++B){A.push(D[C[B]])}return A};k.size=function(A){try{return k.keys(A).length}catch(z){return 0}};k.hasValue=function(A,z){return e.Array.indexOf(k.values(A),z)>-1};k.each=function(C,A,D,B){var z;for(z in C){if(B||l(C,z)){A.call(D||e,C[z],z,C)}}return e};k.some=function(C,A,D,B){var z;for(z in C){if(B||l(C,z)){if(A.call(D||e,C[z],z,C)){return true}}}return false};k.getValue=function(D,C){if(!j.isObject(D)){return y}var A,B=e.Array(C),z=B.length;for(A=0;D!==y&&A<z;A++){D=D[B[A]]}return D};k.setValue=function(F,D,E){var z,C=e.Array(D),B=C.length-1,A=F;if(B>=0){for(z=0;A!==y&&z<B;z++){A=A[C[z]]}if(A!==y){A[C[z]]=E}else{return y}}return F};k.isEmpty=function(z){return !k.keys(Object(z)).length};b.Env.parseUA=function(F){var E=function(I){var J=0;return parseFloat(I.replace(/\./g,function(){return(J++==1)?"":"."}))},H=e.config.win,z=H&&H.navigator,C={ie:0,opera:0,gecko:0,webkit:0,safari:0,chrome:0,mobile:null,air:0,ipad:0,iphone:0,ipod:0,ios:null,android:0,silk:0,accel:false,webos:0,caja:z&&z.cajaVersion,secure:false,os:null,nodejs:0},A=F||z&&z.userAgent,G=H&&H.location,B=G&&G.href,D;C.userAgent=A;C.secure=B&&(B.toLowerCase().indexOf("https")===0);if(A){if((/windows|win32/i).test(A)){C.os="windows"}else{if((/macintosh/i).test(A)){C.os="macintosh"}else{if((/rhino/i).test(A)){C.os="rhino"}}}if((/KHTML/).test(A)){C.webkit=1}D=A.match(/AppleWebKit\/([^\s]*)/);if(D&&D[1]){C.webkit=E(D[1]);C.safari=C.webkit;if(/ Mobile\//.test(A)){C.mobile="Apple";D=A.match(/OS ([^\s]*)/);if(D&&D[1]){D=E(D[1].replace("_","."))}C.ios=D;C.ipad=C.ipod=C.iphone=0;D=A.match(/iPad|iPod|iPhone/);if(D&&D[0]){C[D[0].toLowerCase()]=C.ios}}else{D=A.match(/NokiaN[^\/]*|webOS\/\d\.\d/);if(D){C.mobile=D[0]}if(/webOS/.test(A)){C.mobile="WebOS";D=A.match(/webOS\/([^\s]*);/);if(D&&D[1]){C.webos=E(D[1])}}if(/ Android/.test(A)){if(/Mobile/.test(A)){C.mobile="Android"}D=A.match(/Android ([^\s]*);/);if(D&&D[1]){C.android=E(D[1])}}if(/Silk/.test(A)){D=A.match(/Silk\/([^\s]*)\)/);if(D&&D[1]){C.silk=E(D[1])}if(!C.android){C.android=2.34;C.os="Android"}if(/Accelerated=true/.test(A)){C.accel=true}}}D=A.match(/Chrome\/([^\s]*)/);if(D&&D[1]){C.chrome=E(D[1]);C.safari=0}else{D=A.match(/AdobeAIR\/([^\s]*)/);if(D){C.air=D[0]}}}if(!C.webkit){D=A.match(/Opera[\s\/]([^\s]*)/);if(D&&D[1]){C.opera=E(D[1]);D=A.match(/Version\/([^\s]*)/);if(D&&D[1]){C.opera=E(D[1])}D=A.match(/Opera Mini[^;]*/);if(D){C.mobile=D[0]}}else{D=A.match(/MSIE\s([^;]*)/);if(D&&D[1]){C.ie=E(D[1])}else{D=A.match(/Gecko\/([^\s]*)/);if(D){C.gecko=1;D=A.match(/rv:([^\s\)]*)/);if(D&&D[1]){C.gecko=E(D[1])}}}}}}if(!F){if(typeof process=="object"){if(process.versions&&process.versions.node){C.os=process.platform;C.nodejs=process.versions.node}}b.Env.UA=C}return C};e.UA=b.Env.UA||b.Env.parseUA();b.Env.aliases={anim:["anim-base","anim-color","anim-curve","anim-easing","anim-node-plugin","anim-scroll","anim-xy"],app:["app-base","model","model-list","router","view"],attribute:["attribute-base","attribute-complex"],autocomplete:["autocomplete-base","autocomplete-sources","autocomplete-list","autocomplete-plugin"],base:["base-base","base-pluginhost","base-build"],button:["button-base","button-group","cssbutton"],cache:["cache-base","cache-offline","cache-plugin"],collection:["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"],controller:["router"],dataschema:["dataschema-base","dataschema-json","dataschema-xml","dataschema-array","dataschema-text"],datasource:["datasource-local","datasource-io","datasource-get","datasource-function","datasource-cache","datasource-jsonschema","datasource-xmlschema","datasource-arrayschema","datasource-textschema","datasource-polling"],datatable:["datatable-core","datatable-head","datatable-body","datatable-base","datatable-column-widths","datatable-mutable","datatable-scroll","datatable-datasource","datatable-sort"],datatype:["datatype-number","datatype-date","datatype-xml"],"datatype-date":["datatype-date-parse","datatype-date-format"],"datatype-number":["datatype-number-parse","datatype-number-format"],"datatype-xml":["datatype-xml-parse","datatype-xml-format"],dd:["dd-ddm-base","dd-ddm","dd-ddm-drop","dd-drag","dd-proxy","dd-constrain","dd-drop","dd-scroll","dd-delegate"],dom:["dom-base","dom-screen","dom-style","selector-native","selector"],editor:["frame","editor-selection","exec-command","editor-base","editor-para","editor-br","editor-bidi","editor-tab","createlink-base"],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-custom":["event-custom-base","event-custom-complex"],"event-gestures":["event-flick","event-move"],handlebars:["handlebars-compiler"],highlight:["highlight-base","highlight-accentfold"],history:["history-base","history-hash","history-hash-ie","history-html5"],io:["io-base","io-xdr","io-form","io-upload-iframe","io-queue"],json:["json-parse","json-stringify"],loader:["loader-base","loader-rollup","loader-yui3"],node:["node-base","node-event-delegate","node-pluginhost","node-screen","node-style"],pluginhost:["pluginhost-base","pluginhost-config"],querystring:["querystring-parse","querystring-stringify"],recordset:["recordset-base","recordset-sort","recordset-filter","recordset-indexer"],resize:["resize-base","resize-proxy","resize-constrain"],slider:["slider-base","slider-value-range","clickable-rail","range-slider"],text:["text-accentfold","text-wordbreak"],widget:["widget-base","widget-htmlparser","widget-uievents","widget-skin"]}},"@VERSION@");b.add("get",function(f){var e=f.Lang,g,d;f.Get=g={cssOptions:{attributes:{rel:"stylesheet"},doc:f.config.linkDoc||f.config.doc,pollInterval:50},jsOptions:{autopurge:true,doc:f.config.scriptDoc||f.config.doc},options:{attributes:{charset:"utf-8"},purgethreshold:20},REGEX_CSS:/\.css(?:[?;].*)?$/i,REGEX_JS:/\.js(?:[?;].*)?$/i,_insertCache:{},_pending:null,_purgeNodes:[],_queue:[],abort:function(m){var j,n,k,h,l;if(!m.abort){n=m;l=this._pending;m=null;if(l&&l.transaction.id===n){m=l.transaction;this._pending=null}else{for(j=0,h=this._queue.length;j<h;++j){k=this._queue[j].transaction;if(k.id===n){m=k;this._queue.splice(j,1);break}}}}m&&m.abort()},css:function(i,h,j){return this._load("css",i,h,j)},js:function(i,h,j){return this._load("js",i,h,j)},load:function(i,h,j){return this._load(null,i,h,j)},_autoPurge:function(h){if(h&&this._purgeNodes.length>=h){this._purge(this._purgeNodes)}},_getEnv:function(){var i=f.config.doc,h=f.UA;return(this._env={async:i&&i.createElement("script").async===true,cssLoad:!!(h.gecko?h.gecko>=9:!h.webkit),preservesScriptOrder:!!(h.gecko||h.opera)})},_getTransaction:function(n,k){var o=[],l,h,m,j;if(!e.isArray(n)){n=[n]}for(l=0,h=n.length;l<h;++l){j=n[l];m={attributes:{}};if(typeof j==="string"){m.url=j}else{if(j.url){f.mix(m,j,false,null,0,true);j=j.url}else{continue}}f.mix(m,k,false,null,0,true);f.mix(m,this.options,false,null,0,true);if(!m.type){if(this.REGEX_CSS.test(j)){m.type="css"}else{if(!this.REGEX_JS.test(j)){}m.type="js"}}f.mix(m,m.type==="js"?this.jsOptions:this.cssOptions,false,null,0,true);m.attributes.id||(m.attributes.id=f.guid());if(m.win){m.doc=m.win.document}else{m.win=m.doc.defaultView||m.doc.parentWindow}if(m.charset){m.attributes.charset=m.charset}o.push(m)}return new d(o,k)},_load:function(i,j,h,l){var k;if(typeof h==="function"){l=h;h={}}h||(h={});h.type=i;if(!this._env){this._getEnv()}k=this._getTransaction(j,h);this._queue.push({callback:l,transaction:k});this._next();return k},_next:function(){var h;if(this._pending){return}h=this._queue.shift();if(h){this._pending=h;h.transaction.execute(function(){h.callback&&h.callback.apply(this,arguments);g._pending=null;g._next()})}},_purge:function(h){var j=this._purgeNodes,l=h!==j,i,k;while(k=h.pop()){if(!k._yuiget_finished){continue}k.parentNode&&k.parentNode.removeChild(k);if(l){i=f.Array.indexOf(j,k);if(i>-1){j.splice(i,1)}}}}};g.script=g.js;g.Transaction=d=function(j,i){var h=this;h.id=d._lastId+=1;h.data=i.data;h.errors=[];h.nodes=[];h.options=i;h.requests=j;h._callbacks=[];h._queue=[];h._waiting=0;h.tId=h.id;h.win=i.win||f.config.win};d._lastId=0;d.prototype={_state:"new",abort:function(h){this._pending=null;this._pendingCSS=null;this._pollTimer=clearTimeout(this._pollTimer);this._queue=[];this._waiting=0;this.errors.push({error:h||"Aborted"});this._finish()},execute:function(p){var k=this,o=k.requests,n=k._state,l,j,h,m;if(n==="done"){p&&p(k.errors.length?k.errors:null,k);return}else{p&&k._callbacks.push(p);if(n==="executing"){return}}k._state="executing";k._queue=h=[];if(k.options.timeout){k._timeout=setTimeout(function(){k.abort("Timeout")},k.options.timeout)}for(l=0,j=o.length;l<j;++l){m=k.requests[l];if(m.async||m.type==="css"){k._insert(m)}else{h.push(m)}}k._next()},purge:function(){g._purge(this.nodes)},_createNode:function(j,i,l){var k=l.createElement(j),h;for(h in i){if(i.hasOwnProperty(h)){k.setAttribute(h,i[h])}}return k},_finish:function(){var n=this.errors.length?this.errors:null,j=this.options,m=j.context||this,l,k,h;if(this._state==="done"){return}this._state="done";for(k=0,h=this._callbacks.length;k<h;++k){this._callbacks[k].call(m,n,this)}l=this._getEventData();if(n){if(j.onTimeout&&n[n.length-1].error==="Timeout"){j.onTimeout.call(m,l)}if(j.onFailure){j.onFailure.call(m,l)}}else{if(j.onSuccess){j.onSuccess.call(m,l)}}if(j.onEnd){j.onEnd.call(m,l)}},_getEventData:function(h){if(h){return f.merge(this,{abort:this.abort,purge:this.purge,request:h,url:h.url,win:h.win})}else{return this}},_getInsertBefore:function(l){var m=l.doc,j=l.insertBefore,i,k,h;if(j){return typeof j==="string"?m.getElementById(j):j}i=g._insertCache;h=f.stamp(m);if((j=i[h])){return j}if((j=m.getElementsByTagName("base")[0])){return(i[h]=j)}j=m.head||m.getElementsByTagName("head")[0];if(j){j.appendChild(m.createTextNode(""));return(i[h]=j.lastChild)}return(i[h]=m.getElementsByTagName("script")[0])},_insert:function(p){var m=g._env,n=this._getInsertBefore(p),j=p.type==="js",i=p.node,q=this,h=f.UA,k;if(!i){if(j){k="script"}else{if(!m.cssLoad&&h.gecko){k="style"}else{k="link"}}i=p.node=this._createNode(k,p.attributes,p.doc)}function l(){q._progress("Failed to load "+p.url,p)}function o(){q._progress(null,p)}if(j){i.setAttribute("src",p.url);if(p.async){i.async=true}else{if(m.async){i.async=false}if(!m.preservesScriptOrder){this._pending=p}}}else{if(!m.cssLoad&&h.gecko){i.innerHTML=(p.attributes.charset?'@charset "'+p.attributes.charset+'";':"")+'@import "'+p.url+'";'}else{i.setAttribute("href",p.url)}}if(j&&h.ie&&h.ie<9){i.onreadystatechange=function(){if(/loaded|complete/.test(i.readyState)){i.onreadystatechange=null;o()}}}else{if(!j&&!m.cssLoad){this._poll(p)}else{i.onerror=l;i.onload=o}}this._waiting+=1;this.nodes.push(i);n.parentNode.insertBefore(i,n)},_next:function(){if(this._pending){return}if(this._queue.length){this._insert(this._queue.shift())}else{if(!this._waiting){this._finish()}}},_poll:function(p){var s=this,t=s._pendingCSS,n=f.UA.webkit,l,h,k,r,q,m;if(p){t||(t=s._pendingCSS=[]);t.push(p);if(s._pollTimer){return}}s._pollTimer=null;for(l=0;l<t.length;++l){q=t[l];if(n){m=q.doc.styleSheets;k=m.length;r=q.node.href;while(--k>=0){if(m[k].href===r){t.splice(l,1);l-=1;s._progress(null,q);break}}}else{try{h=!!q.node.sheet.cssRules;t.splice(l,1);l-=1;s._progress(null,q)}catch(o){}}}if(t.length){s._pollTimer=setTimeout(function(){s._poll.call(s)},s.options.pollInterval)}},_progress:function(j,i){var h=this.options;if(j){i.error=j;this.errors.push({error:j,request:i})}i.node._yuiget_finished=i.finished=true;if(h.onProgress){h.onProgress.call(h.context||this,this._getEventData(i))}if(i.autopurge){g._autoPurge(this.options.purgethreshold);g._purgeNodes.push(i.node)}if(this._pending===i){this._pending=null}this._waiting-=1;this._next()}}},"@VERSION@",{requires:["yui-base"]});b.add("loader-base",function(g){if(!b.Env[g.version]){(function(){var L=g.version,H="/build/",I=L+H,G=g.Env.base,D="gallery-2012.01.25-21-14",F="2in3",E="4",C="2.9.0",J=G+"combo?",K={version:L,root:I,base:g.Env.base,comboBase:J,skin:{defaultSkin:"sam",base:"assets/skins/",path:"skin.css",after:["cssreset","cssfonts","cssgrids","cssbase","cssreset-context","cssfonts-context"]},groups:{},patterns:{}},B=K.groups,A=function(N,O){var M=F+"."+(N||E)+"/"+(O||C)+H;B.yui2.base=G+M;B.yui2.root=M},z=function(M){var N=(M||D)+H;B.gallery.base=G+N;B.gallery.root=N};B[L]={};B.gallery={ext:false,combine:true,comboBase:J,update:z,patterns:{"gallery-":{},"lang/gallery-":{},"gallerycss-":{type:"css"}}};B.yui2={combine:true,ext:false,comboBase:J,update:A,patterns:{"yui2-":{configFn:function(M){if(/-skin|reset|fonts|grids|base/.test(M.name)){M.type="css";M.path=M.path.replace(/\.js/,".css");M.path=M.path.replace(/\/yui2-skin/,"/assets/skins/sam/yui2-skin")}}}}};z();A();b.Env[L]=K}())}var i={},f=[],p=1024,d=b.Env,s=d._loaded,t="css",n="js",y="intl",v=g.version,x="",h=g.Object,u=h.each,m=g.Array,k=d._loaderQueue,w=d[v],e="skin-",l=g.Lang,q=d.mods,o,r,j=function(A,B,C,z){var D=A+"/"+B;if(!z){D+="-min"}D+="."+(C||t);return D};g.Env.meta=w;g.Loader=function(D){var C=w.modules,A=this;D=D||{};o=w.md5;A.context=g;A.base=g.Env.meta.base+g.Env.meta.root;A.comboBase=g.Env.meta.comboBase;A.combine=D.base&&(D.base.indexOf(A.comboBase.substr(0,20))>-1);A.comboSep="&";A.maxURLLength=p;A.root=g.Env.meta.root;A.timeout=0;A.forceMap={};A.allowRollup=false;A.filters={};A.required={};A.patterns={};A.moduleInfo={};A.groups=g.merge(g.Env.meta.groups);A.skin=g.merge(g.Env.meta.skin);A.conditions={};A.config=D;A._internal=true;r=d._renderedMods;if(r){u(r,function B(F,E){A.moduleInfo[E]=g.merge(F)});r=d._conditions;u(r,function z(F,E){A.conditions[E]=g.merge(F)})}else{u(C,A.addModule,A)}A.loaded=s[v];A._inspectPage();A._internal=false;A._config(D);A.forceMap=(A.force)?g.Array.hash(A.force):{};A.testresults=null;if(g.config.tests){A.testresults=g.config.tests}A.sorted=[];A.dirty=true;A.inserted={};A.skipped={};A.tested={}};g.Loader.prototype={REGEX_CSS:/\.css(?:[?;].*)?$/i,FILTER_DEFS:{RAW:{searchExp:"-min\\.js",replaceStr:".js"},DEBUG:{searchExp:"-min\\.js",replaceStr:"-debug.js"}},_inspectPage:function(){u(this.moduleInfo,function(A,z){if(A.type&&A.type===t){if(this.isCSSLoaded(A.name)){this.loaded[z]=true}}},this);u(q,function(B,A){if(B.details){var z=this.moduleInfo[A],D=B.details.requires,C=z&&z.requires;if(z){if(!z._inspected&&D&&C.length!=D.length){delete z.expanded}}else{z=this.addModule(B.details,A)}z._inspected=true}},this)},_requires:function(F,E){var B,D,G,H,z=this.moduleInfo,A=z[F],C=z[E];if(!A||!C){return false}D=A.expanded_map;G=A.after_map;if(G&&(E in G)){return true}G=C.after_map;if(G&&(F in G)){return false}H=z[E]&&z[E].supersedes;if(H){for(B=0;B<H.length;B++){if(this._requires(F,H[B])){return true}}}H=z[F]&&z[F].supersedes;if(H){for(B=0;B<H.length;B++){if(this._requires(E,H[B])){return false}}}if(D&&(E in D)){return true}if(A.ext&&A.type==t&&!C.ext&&C.type==t){return true}return false},_config:function(F){var B,A,E,C,D,G,z=this;if(F){for(B in F){if(F.hasOwnProperty(B)){E=F[B];if(B=="require"){z.require(E)}else{if(B=="skin"){if(typeof E==="string"){z.skin.defaultSkin=F.skin;E={defaultSkin:E}}g.mix(z.skin,E,true)}else{if(B=="groups"){for(A in E){if(E.hasOwnProperty(A)){G=A;D=E[A];z.addGroup(D,G)}}}else{if(B=="modules"){u(E,z.addModule,z)}else{if(B=="gallery"){this.groups.gallery.update(E)}else{if(B=="yui2"||B=="2in3"){this.groups.yui2.update(F["2in3"],F.yui2)}else{z[B]=E}}}}}}}}}C=z.filter;if(l.isString(C)){C=C.toUpperCase();z.filterName=C;z.filter=z.FILTER_DEFS[C];if(C=="DEBUG"){z.require("yui-log","dump")}}if(z.lang){z.require("intl-base","intl")}},formatSkin:function(B,z){var A=e+B;if(z){A=A+"-"+z}return A},_addSkin:function(I,G,H){var F,E,A,z,D=this.moduleInfo,B=this.skin,C=D[G]&&D[G].ext;if(G){A=this.formatSkin(I,G);if(!D[A]){F=D[G];E=F.pkg||G;z={name:A,group:F.group,type:"css",after:B.after,path:(H||E)+"/"+B.base+I+"/"+G+".css",ext:C};if(F.base){z.base=F.base}if(F.configFn){z.configFn=F.configFn}this.addModule(z,A)}}return A},addGroup:function(C,A){var B=C.modules,z=this;A=A||C.name;C.name=A;z.groups[A]=C;if(C.patterns){u(C.patterns,function(E,D){E.group=A;z.patterns[D]=E})}if(B){u(B,function(E,D){if(typeof E==="string"){E={name:D,fullpath:E}}E.group=A;z.addModule(E,D)},z)}},addModule:function(Q,X){X=X||Q.name;if(typeof Q==="string"){Q={name:X,fullpath:Q}}if(this.moduleInfo[X]&&this.moduleInfo[X].temp){Q=g.merge(this.moduleInfo[X],Q)}Q.name=X;if(!Q||!Q.name){return null}if(!Q.type){Q.type=n;var O=Q.path||Q.fullpath;if(O&&this.REGEX_CSS.test(O)){Q.type=t}}if(!Q.path&&!Q.fullpath){Q.path=j(X,X,Q.type)}Q.supersedes=Q.supersedes||Q.use;Q.ext=("ext" in Q)?Q.ext:(this._internal)?false:true;Q.requires=this.filterRequires(Q.requires)||[];var U=Q.submodules,T,R,K,z,L,B,P,A,S,M,I,F,D,C,W,V,J,E,G,H=this.conditions,N;this.moduleInfo[X]=Q;if(!Q.langPack&&Q.lang){M=m(Q.lang);for(S=0;S<M.length;S++){W=M[S];I=this.getLangPackName(W,X);B=this.moduleInfo[I];if(!B){B=this._addLangPack(W,Q,I)}}}if(U){z=Q.supersedes||[];R=0;for(T in U){if(U.hasOwnProperty(T)){L=U[T];L.path=L.path||j(X,T,Q.type);L.pkg=X;L.group=Q.group;if(L.supersedes){z=z.concat(L.supersedes)}B=this.addModule(L,T);z.push(T);if(B.skinnable){Q.skinnable=true;J=this.skin.overrides;if(J&&J[T]){for(S=0;S<J[T].length;S++){E=this._addSkin(J[T][S],T,X);z.push(E)}}E=this._addSkin(this.skin.defaultSkin,T,X);z.push(E)}if(L.lang&&L.lang.length){M=m(L.lang);for(S=0;S<M.length;S++){W=M[S];I=this.getLangPackName(W,X);F=this.getLangPackName(W,T);B=this.moduleInfo[I];if(!B){B=this._addLangPack(W,Q,I)}D=D||m.hash(B.supersedes);if(!(F in D)){B.supersedes.push(F)}Q.lang=Q.lang||[];C=C||m.hash(Q.lang);if(!(W in C)){Q.lang.push(W)}I=this.getLangPackName(x,X);F=this.getLangPackName(x,T);B=this.moduleInfo[I];if(!B){B=this._addLangPack(W,Q,I)}if(!(F in D)){B.supersedes.push(F)}}}R++}}Q.supersedes=m.dedupe(z);if(this.allowRollup){Q.rollup=(R<4)?R:Math.min(R-1,4)}}P=Q.plugins;if(P){for(T in P){if(P.hasOwnProperty(T)){A=P[T];A.pkg=X;A.path=A.path||j(X,T,Q.type);A.requires=A.requires||[];A.group=Q.group;this.addModule(A,T);if(Q.skinnable){this._addSkin(this.skin.defaultSkin,T,X)}}}}if(Q.condition){K=Q.condition.trigger;if(b.Env.aliases[K]){K=b.Env.aliases[K]}if(!g.Lang.isArray(K)){K=[K]}for(T=0;T<K.length;T++){N=K[T];G=Q.condition.when;H[N]=H[N]||{};H[N][X]=Q.condition;if(G&&G!="after"){if(G=="instead"){Q.supersedes=Q.supersedes||[];Q.supersedes.push(N)}else{}}else{Q.after=Q.after||[];Q.after.push(N)}}}if(Q.supersedes){Q.supersedes=this.filterRequires(Q.supersedes)}if(Q.after){Q.after=this.filterRequires(Q.after);Q.after_map=m.hash(Q.after)}if(Q.configFn){V=Q.configFn(Q);if(V===false){delete this.moduleInfo[X];delete d._renderedMods[X];Q=null}}if(Q){if(!d._renderedMods){d._renderedMods={}}d._renderedMods[X]=g.merge(Q);d._conditions=H}return Q},require:function(A){var z=(typeof A==="string")?m(arguments):A;this.dirty=true;this.required=g.merge(this.required,m.hash(this.filterRequires(z)));this._explodeRollups()},_explodeRollups:function(){var A=this,z,B=A.required;if(!A.allowRollup){u(B,function(C,D){z=A.getModule(D);if(z&&z.use){m.each(z.use,function(E){z=A.getModule(E);if(z&&z.use){m.each(z.use,function(F){B[F]=true})}else{B[E]=true}})}});A.required=B}},filterRequires:function(C){if(C){if(!g.Lang.isArray(C)){C=[C]}C=g.Array(C);var E=[],B,A,D,z;for(B=0;B<C.length;B++){A=this.getModule(C[B]);if(A&&A.use){for(D=0;D<A.use.length;D++){z=this.getModule(A.use[D]);if(z&&z.use){E=g.Array.dedupe([].concat(E,this.filterRequires(z.use)))}else{E.push(A.use[D])}}}else{E.push(C[B])}}C=E}return C},getRequires:function(U){if(!U){return f}if(U._parsed){return U.expanded||f}var O,K,N,G,F,W,D=this.testresults,X=U.name,E,V=q[X]&&q[X].details,Q,L,z,H,R,I,C,S,T,B,J=U.lang||U.intl,P=this.moduleInfo,M=g.Features&&g.Features.tests.load,A;if(U.temp&&V){R=U;U=this.addModule(V,X);U.group=R.group;U.pkg=R.pkg;delete U.expanded}if(U.expanded&&(!this.lang||U.langCache===this.lang)){return U.expanded}Q=[];A={};H=this.filterRequires(U.requires);if(U.lang){Q.unshift("intl");H.unshift("intl");J=true}I=this.filterRequires(U.optional);U._parsed=true;U.langCache=this.lang;for(O=0;O<H.length;O++){if(!A[H[O]]){Q.push(H[O]);A[H[O]]=true;K=this.getModule(H[O]);if(K){G=this.getRequires(K);J=J||(K.expanded_map&&(y in K.expanded_map));for(N=0;N<G.length;N++){Q.push(G[N])}}}}H=this.filterRequires(U.supersedes);if(H){for(O=0;O<H.length;O++){if(!A[H[O]]){if(U.submodules){Q.push(H[O])}A[H[O]]=true;K=this.getModule(H[O]);if(K){G=this.getRequires(K);J=J||(K.expanded_map&&(y in K.expanded_map));for(N=0;N<G.length;N++){Q.push(G[N])}}}}}if(I&&this.loadOptional){for(O=0;O<I.length;O++){if(!A[I[O]]){Q.push(I[O]);A[I[O]]=true;K=P[I[O]];if(K){G=this.getRequires(K);J=J||(K.expanded_map&&(y in K.expanded_map));for(N=0;N<G.length;N++){Q.push(G[N])}}}}}E=this.conditions[X];if(E){U._parsed=false;if(D&&M){u(D,function(Y,aa){var Z=M[aa].name;if(!A[Z]&&M[aa].trigger==X){if(Y&&M[aa]){A[Z]=true;Q.push(Z)}}})}else{u(E,function(aa,Z){if(!A[Z]){var Y=aa&&((!aa.ua&&!aa.test)||(aa.ua&&g.UA[aa.ua])||(aa.test&&aa.test(g,H)));if(Y){A[Z]=true;Q.push(Z);K=this.getModule(Z);if(K){G=this.getRequires(K);for(N=0;N<G.length;N++){Q.push(G[N])}}}}},this)}}if(U.skinnable){S=this.skin.overrides;u(b.Env.aliases,function(Y,Z){if(g.Array.indexOf(Y,X)>-1){T=Z}});if(S&&(S[X]||(T&&S[T]))){B=X;if(S[T]){B=T}for(O=0;O<S[B].length;O++){C=this._addSkin(S[B][O],X);if(!this.isCSSLoaded(C,this._boot)){Q.push(C)}}}else{C=this._addSkin(this.skin.defaultSkin,X);if(!this.isCSSLoaded(C,this._boot)){Q.push(C)}}}U._parsed=false;if(J){if(U.lang&&!U.langPack&&g.Intl){W=g.Intl.lookupBestLang(this.lang||x,U.lang);F=this.getLangPackName(W,X);if(F){Q.unshift(F)}}Q.unshift(y)}U.expanded_map=m.hash(Q);U.expanded=h.keys(U.expanded_map);return U.expanded},isCSSLoaded:function(A,D){if(!A||!b.Env.cssStampEl||(!D&&this.ignoreRegistered)){return false}var C=b.Env.cssStampEl,z=false,B=C.currentStyle;C.className=A;if(!B){B=g.config.doc.defaultView.getComputedStyle(C,null)}if(B.display==="none"){z=true}C.className="";return z},getProvides:function(A){var z=this.getModule(A),C,B;if(!z){return i}if(z&&!z.provides){C={};B=z.supersedes;if(B){m.each(B,function(D){g.mix(C,this.getProvides(D))},this)}C[A]=true;z.provides=C}return z.provides},calculate:function(A,z){if(A||z||this.dirty){if(A){this._config(A)}if(!this._init){this._setup()}this._explode();if(this.allowRollup){this._rollup()}else{this._explodeRollups()}this._reduce();this._sort()}},_addLangPack:function(F,z,E){var C=z.name,A,B,D=this.moduleInfo[E];if(!D){A=j((z.pkg||C),E,n,true);B={path:A,intl:true,langPack:true,ext:z.ext,group:z.group,supersedes:[]};if(z.configFn){B.configFn=z.configFn}this.addModule(B,E);if(F){g.Env.lang=g.Env.lang||{};g.Env.lang[F]=g.Env.lang[F]||{};g.Env.lang[F][C]=true}}return this.moduleInfo[E]},_setup:function(){var F=this.moduleInfo,C,D,B,z,A,E;for(C in F){if(F.hasOwnProperty(C)){z=F[C];if(z){z.requires=m.dedupe(z.requires);if(z.lang&&z.lang.length){E=this.getLangPackName(x,C);this._addLangPack(null,z,E)}}}}A={};if(!this.ignoreRegistered){g.mix(A,d.mods)}if(this.ignore){g.mix(A,m.hash(this.ignore))}for(B in A){if(A.hasOwnProperty(B)){g.mix(A,this.getProvides(B))}}if(this.force){for(D=0;D<this.force.length;D++){if(this.force[D] in A){delete A[this.force[D]]}}}g.mix(this.loaded,A);this._init=true},getLangPackName:function(A,z){return("lang/"+z+((A)?"_"+A:""))},_explode:function(){var D=this.required,z,C,A={},B=this;B.dirty=false;B._explodeRollups();D=B.required;u(D,function(E,F){if(!A[F]){A[F]=true;z=B.getModule(F);if(z){var G=z.expound;if(G){D[G]=B.getModule(G);C=B.getRequires(D[G]);g.mix(D,m.hash(C))}C=B.getRequires(z);g.mix(D,m.hash(C))}}})},getModule:function(E){if(!E){return null}var D,C,A,z=this.moduleInfo[E],B=this.patterns;if(!z){for(A in B){if(B.hasOwnProperty(A)){D=B[A];if(!D.test){D.test=function(G,F){return(G.indexOf(F)>-1)}}if(D.test(E,A)){C=D;break}}}if(C){if(D.action){D.action.call(this,E,A)}else{z=this.addModule(g.merge(C),E);z.temp=true}}}return z},_rollup:function(){},_reduce:function(E){E=E||this.required;var B,A,D,z,C=this.loadType,F=this.ignore?m.hash(this.ignore):false;for(B in E){if(E.hasOwnProperty(B)){z=this.getModule(B);if(((this.loaded[B]||q[B])&&!this.forceMap[B]&&!this.ignoreRegistered)||(C&&z&&z.type!=C)){delete E[B]}if(F&&F[B]){delete E[B]}D=z&&z.supersedes;if(D){for(A=0;A<D.length;A++){if(D[A] in E){delete E[D[A]]}}}}}return E},_finish:function(B,A){k.running=false;var z=this.onEnd;if(z){z.call(this.context,{msg:B,data:this.data,success:A})}this._continue()},_onSuccess:function(){var B=this,A=g.merge(B.skipped),D,z=[],C=B.requireRegistration,F,E;u(A,function(G){delete B.inserted[G]});B.skipped={};u(B.inserted,function(H,G){var I=B.getModule(G);if(I&&C&&I.type==n&&!(G in b.Env.mods)){z.push(G)}else{g.mix(B.loaded,B.getProvides(G))}});D=B.onSuccess;E=(z.length)?"notregistered":"success";F=!(z.length);if(D){D.call(B.context,{msg:E,data:B.data,success:F,failed:z,skipped:A})}B._finish(E,F)},_onProgress:function(A){var z=this;if(z.onProgress){z.onProgress.call(z.context,{name:A.url,data:A.data})}},_onFailure:function(D){var B=this.onFailure,C=[],A=0,z=D.errors.length;for(A;A<z;A++){C.push(D.errors[A].error)}C=C.join(",");if(B){B.call(this.context,{msg:C,data:this.data,success:false})}this._finish(C,false)},_onTimeout:function(){var z=this.onTimeout;if(z){z.call(this.context,{msg:"timeout",data:this.data,success:false})}this._finish("timeout",false)},_sort:function(){var I=h.keys(this.required),E={},z=0,B,H,G,D,C,F,A;for(;;){B=I.length;F=false;for(D=z;D<B;D++){H=I[D];for(C=D+1;C<B;C++){A=H+I[C];if(!E[A]&&this._requires(H,I[C])){G=I.splice(C,1);I.splice(D,0,G[0]);E[A]=true;F=true;break}}if(F){break}else{z++}}if(!F){break}}this.sorted=I},_insert:function(z,C,G,B){if(z){this._config(z)}if(!B){this.calculate(C)}var D=this.resolve(),H=this,F=0,E=0;if(G){D[((G===n)?t:n)]=[]}if(D.js.length){F++}if(D.css.length){F++}var A=function(M){E++;var I={},K=0,J="",L;if(M&&M.errors){for(K=0;K<M.errors.length;K++){if(M.errors[K].request){J=M.errors[K].request.url}else{J=M.errors[K]}I[J]=J}}if(M&&M.data&&M.data.length){for(K=0;K<M.data.length;K++){H.inserted[M.data[K].name]=true}}if(E===F){H._loading=null;if(M&&M.fn){L=M.fn;delete M.fn;L.call(H,M)}}};this._loading=true;if(!D.js.length&&!D.css.length){E=-1;A({fn:H._onSuccess});return}if(D.css.length){g.Get.css(D.css,{data:D.cssMods,insertBefore:H.insertBefore,charset:H.charset,timeout:H.timeout,context:H,onProgress:function(I){H._onProgress.call(H,I)},onTimeout:function(I){I.fn=H._onTimeout;A.call(H,I)},onSuccess:function(I){I.fn=H._onSuccess;A.call(H,I)},onFailure:function(I){I.fn=H._onFailure;A.call(H,I)}})}if(D.js.length){g.Get.script(D.js,{data:D.jsMods,insertBefore:H.insertBefore,charset:H.charset,timeout:H.timeout,autopurge:false,context:H,async:true,onProgress:function(I){H._onProgress.call(H,I)},onTimeout:function(I){I.fn=H._onTimeout;A.call(H,I)},onSuccess:function(I){I.fn=H._onSuccess;A.call(H,I)},onFailure:function(I){I.fn=H._onFailure;A.call(H,I)}})}},_continue:function(){if(!(k.running)&&k.size()>0){k.running=true;k.next()()}},insert:function(C,A,B){var z=this,D=g.merge(this);delete D.require;delete D.dirty;k.add(function(){z._insert(D,C,A,B)});this._continue()},loadNext:function(z){return},_filter:function(B,A){var D=this.filter,z=A&&(A in this.filters),C=z&&this.filters[A],E=this.moduleInfo[A]?this.moduleInfo[A].group:null;if(E&&this.groups[E]&&this.groups[E].filter){C=this.groups[E].filter;z=true}if(B){if(z){D=(l.isString(C))?this.FILTER_DEFS[C.toUpperCase()]||null:C}if(D){B=B.replace(new RegExp(D.searchExp,"g"),D.replaceStr)}}return B},_url:function(B,z,A){return this._filter((A||this.base||"")+B,z)},resolve:function(A,R){var aa,Z,X,H,M,J,W,L,Q,Y,B,K,U,G,ad,I,ab,P=[],N,T,D={},S=this,z,C,ac=[],E=(S.ignoreRegistered)?{}:S.inserted,V={js:[],jsMods:[],css:[],cssMods:[]},F=S.loadType||"js";if(A){S.calculate()}R=R||S.sorted;var O=function(ae){if(ae){L=(ae.group&&S.groups[ae.group])||i;H=(ae.fullpath)?S._filter(ae.fullpath,R[Z]):S._url(ae.path,R[Z],L.base||ae.base);V[ae.type].push(H);V[ae.type+"Mods"].push(ae)}else{}};aa=R.length;ad=S.comboBase;H=ad;U={};for(Z=0;Z<aa;Z++){K=ad;X=S.getModule(R[Z]);Q=X&&X.group;L=S.groups[Q];if(Q&&L){if(!L.combine){O(X);continue}X.combine=true;if(L.comboBase){K=L.comboBase}if("root" in L&&l.isValue(L.root)){X.root=L.root}X.comboSep=L.comboSep||S.comboSep;X.maxURLLength=L.maxURLLength||S.maxURLLength}else{if(!S.combine){O(X);continue}}U[K]=U[K]||[];U[K].push(X)}for(Y in U){if(U.hasOwnProperty(Y)){D[Y]=D[Y]||{js:[],jsMods:[],css:[],cssMods:[]};H=Y;G=U[Y];aa=G.length;if(aa){for(Z=0;Z<aa;Z++){if(E[G[Z]]){continue}X=G[Z];if(X&&(X.combine||!X.ext)){D[Y].comboSep=X.comboSep;D[Y].maxURLLength=X.maxURLLength;B=((l.isValue(X.root))?X.root:S.root)+(X.path||X.fullpath);B=S._filter(B,X.name);D[Y][X.type].push(B);D[Y][X.type+"Mods"].push(X)}else{if(G[Z]){O(G[Z])}}}}}}for(Y in D){I=Y;z=D[I].comboSep||S.comboSep;C=D[I].maxURLLength||S.maxURLLength;for(F in D[I]){if(F===n||F===t){ab=D[I][F];G=D[I][F+"Mods"];aa=ab.length;N=I+ab.join(z);T=N.length;if(C<=I.length){C=p}if(aa){if(T>C){P=[];for(R=0;R<aa;R++){P.push(ab[R]);N=I+P.join(z);if(N.length>C){X=P.pop();N=I+P.join(z);V[F].push(N);P=[];if(X){P.push(X)}}}if(P.length){N=I+P.join(z);V[F].push(N)}}else{V[F].push(N)}}V[F+"Mods"]=V[F+"Mods"].concat(G)}}}D=null;return V}}},"@VERSION@",{requires:["get","features"]});b.Env.core.push("loader-base");var c=b();window.YUILoader=c.Loader;c.Loader.prototype.load=function(d){var e=this,f=e.resolve(true);e.data=f;e.onEnd=function(){d.apply(e.context||window,arguments)};e.insert()}}());
BIN build/loader-zip.js.gz
Binary file not shown.
7,307 build/loader.js
7,307 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
1,208 js/get.js
@@ -0,0 +1,1208 @@
+YUI.add('get', function(Y) {
+
+/*jslint boss:true, expr:true, laxbreak: true */
+
+/**
+Provides dynamic loading of remote JavaScript and CSS resources.
+
+@module get
+@class Get
+@static
+**/
+
+var Lang = Y.Lang,
+ Get, Transaction;
+
+Y.Get = Get = {
+ // -- Public Properties ----------------------------------------------------
+
+ /**
+ Default options for CSS requests. Options specified here will override
+ global defaults for CSS requests.
+
+ See the `options` property for all available options.
+
+ @property cssOptions
+ @type Object
+ @static
+ @since 3.5.0
+ **/
+ cssOptions: {
+ attributes: {
+ rel: 'stylesheet'
+ },
+
+ doc : Y.config.linkDoc || Y.config.doc,
+ pollInterval: 50
+ },
+
+ /**
+ Default options for JS requests. Options specified here will override global
+ defaults for JS requests.
+
+ See the `options` property for all available options.
+
+ @property jsOptions
+ @type Object
+ @static
+ @since 3.5.0
+ **/
+ jsOptions: {
+ autopurge: true,
+ doc : Y.config.scriptDoc || Y.config.doc
+ },
+
+ /**
+ Default options to use for all requests.
+
+ Note that while all available options are documented here for ease of
+ discovery, some options (like callback functions) only make sense at the
+ transaction level.
+
+ Callback functions specified via the options object or the `options`
+ parameter of the `css()`, `js()`, or `load()` methods will receive the
+ transaction object as a parameter. See `Y.Get.Transaction` for details on
+ the properties and methods available on transactions.
+
+ @static
+ @since 3.5.0
+ @property {Object} options
+
+ @property {Boolean} [options.async=false] Whether or not to load scripts
+ asynchronously, meaning they're requested in parallel and execution
+ order is not guaranteed. Has no effect on CSS, since CSS is always
+ loaded asynchronously.
+
+ @property {Object} [options.attributes] HTML attribute name/value pairs that
+ should be added to inserted nodes. By default, the `charset` attribute
+ will be set to "utf-8" and nodes will be given an auto-generated `id`
+ attribute, but you can override these with your own values if desired.
+
+ @property {Boolean} [options.autopurge] Whether or not to automatically
+ purge inserted nodes after the purge threshold is reached. This is
+ `true` by default for JavaScript, but `false` for CSS since purging a
+ CSS node will also remove any styling applied by the referenced file.
+
+ @property {Object} [options.context] `this` object to use when calling
+ callback functions. Defaults to the transaction object.
+
+ @property {Mixed} [options.data] Arbitrary data object to pass to "on*"
+ callbacks.
+
+ @property {Document} [options.doc] Document into which nodes should be
+ inserted. By default, the current document is used.
+
+ @property {HTMLElement|String} [options.insertBefore] HTML element or id
+ string of an element before which all generated nodes should be
+ inserted. If not specified, Get will automatically determine the best
+ place to insert nodes for maximum compatibility.
+
+ @property {Function} [options.onEnd] Callback to execute after a transaction
+ is complete, regardless of whether it succeeded or failed.
+
+ @property {Function} [options.onFailure] Callback to execute after a
+ transaction fails, times out, or is aborted.
+
+ @property {Function} [options.onProgress] Callback to execute after each
+ individual request in a transaction either succeeds or fails.
+
+ @property {Function} [options.onSuccess] Callback to execute after a
+ transaction completes successfully with no errors. Note that in browsers
+ that don't support the `error` event on CSS `<link>` nodes, a failed CSS
+ request may still be reported as a success because in these browsers
+ it can be difficult or impossible to distinguish between success and
+ failure for CSS resources.
+
+ @property {Function} [options.onTimeout] Callback to execute after a
+ transaction times out.
+
+ @property {Number} [options.pollInterval=50] Polling interval (in
+ milliseconds) for detecting CSS load completion in browsers that don't
+ support the `load` event on `<link>` nodes. This isn't used for
+ JavaScript.
+
+ @property {Number} [options.purgethreshold=20] Number of nodes to insert
+ before triggering an automatic purge when `autopurge` is `true`.
+
+ @property {Number} [options.timeout] Number of milliseconds to wait before
+ aborting a transaction. When a timeout occurs, the `onTimeout` callback
+ is called, followed by `onFailure` and finally `onEnd`. By default,
+ there is no timeout.
+
+ @property {String} [options.type] Resource type ("css" or "js"). This option
+ is set automatically by the `css()` and `js()` functions and will be
+ ignored there, but may be useful when using the `load()` function. If
+ not specified, the type will be inferred from the URL, defaulting to
+ "js" if the URL doesn't contain a recognizable file extension.
+ **/
+ options: {
+ attributes: {
+ charset: 'utf-8'
+ },
+
+ purgethreshold: 20
+ },
+
+ // -- Protected Properties -------------------------------------------------
+
+ /**
+ Regex that matches a CSS URL. Used to guess the file type when it's not
+ specified.
+
+ @property REGEX_CSS
+ @type RegExp
+ @final
+ @protected
+ @static
+ @since 3.5.0
+ **/
+ REGEX_CSS: /\.css(?:[?;].*)?$/i,
+
+ /**
+ Regex that matches a JS URL. Used to guess the file type when it's not
+ specified.
+
+ @property REGEX_JS
+ @type RegExp
+ @final
+ @protected
+ @static
+ @since 3.5.0
+ **/
+ REGEX_JS : /\.js(?:[?;].*)?$/i,
+
+ /**
+ Contains information about the current environment, such as what script and
+ link injection features it supports.
+
+ This object is created and populated the first time the `_getEnv()` method
+ is called.
+
+ @property _env
+ @type Object
+ @protected
+ @static
+ @since 3.5.0
+ **/
+
+ /**
+ Mapping of document _yuid strings to <head> or <base> node references so we
+ don't have to look the node up each time we want to insert a request node.
+
+ @property _insertCache
+ @type Object
+ @protected
+ @static
+ @since 3.5.0
+ **/
+ _insertCache: {},
+
+ /**
+ Information about the currently pending transaction, if any.
+
+ This is actually an object with two properties: `callback`, containing the
+ optional callback passed to `css()`, `load()`, or `js()`; and `transaction`,
+ containing the actual transaction instance.
+
+ @property _pending
+ @type Object
+ @protected
+ @static
+ @since 3.5.0
+ **/
+ _pending: null,
+
+ /**
+ HTML nodes eligible to be purged next time autopurge is triggered.
+
+ @property _purgeNodes
+ @type HTMLElement[]
+ @protected
+ @static
+ @since 3.5.0
+ **/
+ _purgeNodes: [],
+
+ /**
+ Queued transactions and associated callbacks.
+
+ @property _queue
+ @type Object[]
+ @protected
+ @static
+ @since 3.5.0
+ **/
+ _queue: [],
+
+ // -- Public Methods -------------------------------------------------------
+
+ /**
+ Aborts the specified transaction.
+
+ This will cause the transaction's `onFailure` callback to be called and
+ will prevent any new script and link nodes from being added to the document,
+ but any resources that have already been requested will continue loading
+ (there's no safe way to prevent this, unfortunately).
+
+ *Note:* This method is deprecated as of 3.5.0, and will be removed in a
+ future version of YUI. Use the transaction-level `abort()` method instead.
+
+ @method abort
+ @param {Get.Transaction} transaction Transaction to abort.
+ @deprecated Use the `abort()` method on the transaction instead.
+ @static
+ **/
+ abort: function (transaction) {
+ var i, id, item, len, pending;
+
+
+ if (!transaction.abort) {
+ id = transaction;
+ pending = this._pending;
+ transaction = null;
+
+ if (pending && pending.transaction.id === id) {
+ transaction = pending.transaction;
+ this._pending = null;
+ } else {
+ for (i = 0, len = this._queue.length; i < len; ++i) {
+ item = this._queue[i].transaction;
+
+ if (item.id === id) {
+ transaction = item;
+ this._queue.splice(i, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ transaction && transaction.abort();
+ },
+
+ /**
+ Loads one or more CSS files.
+
+ The _urls_ parameter may be provided as a URL string, a request object,
+ or an array of URL strings and/or request objects.
+
+ A request object is just an object that contains a `url` property and zero
+ or more options that should apply specifically to that request.
+ Request-specific options take priority over transaction-level options and
+ default options.
+
+ URLs may be relative or absolute, and do not have to have the same origin
+ as the current page.
+
+ The `options` parameter may be omitted completely and a callback passed in
+ its place, if desired.
+
+ @example
+
+ // Load a single CSS file and log a message on completion.
+ Y.Get.css('foo.css', function (err) {
+ if (err) {
+ } else {
+ }
+ });
+
+ // Load multiple CSS files and log a message when all have finished
+ // loading.
+ var urls = ['foo.css', 'http://example.com/bar.css', 'baz/quux.css'];
+
+ Y.Get.css(urls, function (err) {
+ if (err) {
+ } else {
+ }
+ });
+
+ // Specify transaction-level options, which will apply to all requests
+ // within the transaction.
+ Y.Get.css(urls, {
+ attributes: {'class': 'my-css'},
+ timeout : 5000
+ });
+
+ // Specify per-request options, which override transaction-level and
+ // default options.
+ Y.Get.css([
+ {url: 'foo.css', attributes: {id: 'foo'}},
+ {url: 'bar.css', attributes: {id: 'bar', charset: 'iso-8859-1'}}
+ ]);
+
+ @method css
+ @param {String|Object|Array} urls URL string, request object, or array
+ of URLs and/or request objects to load.
+ @param {Object} [options] Options for this transaction. See the
+ `Y.Get.options` property for a complete list of available options.
+ @param {Function} [callback] Callback function to be called on completion.
+ This is a general callback and will be called before any more granular
+ callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
+ object.
+
+ @param {Array|null} callback.err Array of errors that occurred during
+ the transaction, or `null` on success.
+ @param {Get.Transaction} callback.transaction Transaction object.
+
+ @return {Get.Transaction} Transaction object.
+ @static
+ **/
+ css: function (urls, options, callback) {
+ return this._load('css', urls, options, callback);
+ },
+
+ /**
+ Loads one or more JavaScript resources.
+
+ The _urls_ parameter may be provided as a URL string, a request object,
+ or an array of URL strings and/or request objects.
+
+ A request object is just an object that contains a `url` property and zero
+ or more options that should apply specifically to that request.
+ Request-specific options take priority over transaction-level options and
+ default options.
+
+ URLs may be relative or absolute, and do not have to have the same origin
+ as the current page.
+
+ The `options` parameter may be omitted completely and a callback passed in
+ its place, if desired.
+
+ Scripts will be executed in the order they're specified unless the `async`
+ option is `true`, in which case they'll be loaded in parallel and executed
+ in whatever order they finish loading.
+
+ @example
+
+ // Load a single JS file and log a message on completion.
+ Y.Get.js('foo.js', function (err) {
+ if (err) {
+ } else {
+ }
+ });
+
+ // Load multiple JS files, execute them in order, and log a message when
+ // all have finished loading.
+ var urls = ['foo.js', 'http://example.com/bar.js', 'baz/quux.js'];
+
+ Y.Get.js(urls, function (err) {
+ if (err) {
+ } else {
+ }
+ });
+
+ // Specify transaction-level options, which will apply to all requests
+ // within the transaction.
+ Y.Get.js(urls, {
+ attributes: {'class': 'my-js'},
+ timeout : 5000
+ });
+
+ // Specify per-request options, which override transaction-level and
+ // default options.
+ Y.Get.js([
+ {url: 'foo.js', attributes: {id: 'foo'}},
+ {url: 'bar.js', attributes: {id: 'bar', charset: 'iso-8859-1'}}
+ ]);
+
+ @method js
+ @param {String|Object|Array} urls URL string, request object, or array
+ of URLs and/or request objects to load.
+ @param {Object} [options] Options for this transaction. See the
+ `Y.Get.options` property for a complete list of available options.
+ @param {Function} [callback] Callback function to be called on completion.
+ This is a general callback and will be called before any more granular
+ callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
+ object.
+
+ @param {Array|null} callback.err Array of errors that occurred during
+ the transaction, or `null` on success.
+ @param {Get.Transaction} callback.transaction Transaction object.
+
+ @return {Get.Transaction} Transaction object.
+ @since 3.5.0
+ @static
+ **/
+ js: function (urls, options, callback) {
+ return this._load('js', urls, options, callback);
+ },
+
+ /**
+ Loads one or more CSS and/or JavaScript resources in the same transaction.
+
+ Use this method when you want to load both CSS and JavaScript in a single
+ transaction and be notified when all requested URLs have finished loading,
+ regardless of type.
+
+ Behavior and options are the same as for the `css()` and `js()` methods. If
+ a resource type isn't specified in per-request options or transaction-level
+ options, Get will guess the file type based on the URL's extension (`.css`
+ or `.js`, with or without a following query string). If the file type can't
+ be guessed from the URL, a warning will be logged and Get will assume the
+ URL is a JavaScript resource.
+
+ @example
+
+ // Load both CSS and JS files in a single transaction, and log a message
+ // when all files have finished loading.
+ Y.Get.load(['foo.css', 'bar.js', 'baz.css'], function (err) {
+ if (err) {
+ } else {
+ }
+ });
+
+ @method load
+ @param {String|Object|Array} urls URL string, request object, or array
+ of URLs and/or request objects to load.
+ @param {Object} [options] Options for this transaction. See the
+ `Y.Get.options` property for a complete list of available options.
+ @param {Function} [callback] Callback function to be called on completion.
+ This is a general callback and will be called before any more granular
+ callbacks (`onSuccess`, `onFailure`, etc.) specified in the `options`
+ object.
+
+ @param {Array|null} err Array of errors that occurred during the
+ transaction, or `null` on success.
+ @param {Get.Transaction} Transaction object.
+
+ @return {Get.Transaction} Transaction object.
+ @since 3.5.0
+ @static
+ **/
+ load: function (urls, options, callback) {
+ return this._load(null, urls, options, callback);
+ },
+
+ // -- Protected Methods ----------------------------------------------------
+
+ /**
+ Triggers an automatic purge if the purge threshold has been reached.
+
+ @method _autoPurge
+ @param {Number} threshold Purge threshold to use, in milliseconds.
+ @protected
+ @since 3.5.0
+ @static
+ **/
+ _autoPurge: function (threshold) {
+ if (threshold && this._purgeNodes.length >= threshold) {
+ this._purge(this._purgeNodes);
+ }
+ },
+
+ /**
+ Populates the `_env` property with information about the current
+ environment.
+
+ @method _getEnv
+ @return {Object} Environment information.
+ @protected
+ @since 3.5.0
+ @static
+ **/
+ _getEnv: function () {
+ var doc = Y.config.doc,
+ ua = Y.UA;
+
+ // Note: some of these checks require browser sniffs since it's not
+ // feasible to load test files on every pageview just to perform a
+ // feature test. I'm sorry if this makes you sad.
+ return (this._env = {
+ // True if this is a browser that supports disabling async mode on
+ // dynamically created script nodes. See
+ // https://developer.mozilla.org/En/HTML/Element/Script#Attributes
+ async: doc && doc.createElement('script').async === true,
+
+ // True if this browser fires an event when a dynamically injected
+ // link node finishes loading. This is currently true for IE, Opera,
+ // and Firefox 9+. Note that IE versions <9 fire the DOM 0 "onload"
+ // event, but not "load". All versions of IE fire "onload".
+ cssLoad: !!(ua.gecko ? ua.gecko >= 9 : !ua.webkit),
+
+ // True if this browser preserves script execution order while
+ // loading scripts in parallel as long as the script node's `async`
+ // attribute is set to false to explicitly disable async execution.
+ preservesScriptOrder: !!(ua.gecko || ua.opera)
+ });
+ },
+
+ _getTransaction: function (urls, options) {
+ var requests = [],
+ i, len, req, url;
+
+ if (!Lang.isArray(urls)) {
+ urls = [urls];
+ }
+
+ for (i = 0, len = urls.length; i < len; ++i) {
+ url = urls[i];
+ req = {attributes: {}};
+
+ // If `url` is a string, we create a URL object for it, then mix in
+ // global options and request-specific options. If it's an object
+ // with a "url" property, we assume it's a request object containing
+ // URL-specific options.
+ if (typeof url === 'string') {
+ req.url = url;
+ } else if (url.url) {
+ // URL-specific options override both global defaults and
+ // request-specific options.
+ Y.mix(req, url, false, null, 0, true);
+ url = url.url; // Make url a string so we can use it later.
+ } else {
+ continue;
+ }
+
+ Y.mix(req, options, false, null, 0, true);
+ Y.mix(req, this.options, false, null, 0, true);
+
+ // If we didn't get an explicit type for this URL either in the
+ // request options or the URL-specific options, try to determine
+ // one from the file extension.
+ if (!req.type) {
+ if (this.REGEX_CSS.test(url)) {
+ req.type = 'css';
+ } else {
+ if (!this.REGEX_JS.test(url)) {
+ }
+
+ req.type = 'js';
+ }
+ }
+
+ // Mix in type-specific default options, but don't overwrite any
+ // options that have already been set.
+ Y.mix(req, req.type === 'js' ? this.jsOptions : this.cssOptions,
+ false, null, 0, true);
+
+ // Give the node an id attribute if it doesn't already have one.
+ req.attributes.id || (req.attributes.id = Y.guid());
+
+ // Backcompat for <3.5.0 behavior.
+ if (req.win) {
+ req.doc = req.win.document;
+ } else {
+ req.win = req.doc.defaultView || req.doc.parentWindow;
+ }
+
+ if (req.charset) {
+ req.attributes.charset = req.charset;
+ }
+
+ requests.push(req);
+ }
+
+ return new Transaction(requests, options);
+ },
+
+ _load: function (type, urls, options, callback) {
+ var transaction;
+
+ // Allow callback as third param.
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+
+ options || (options = {});
+ options.type = type;
+
+ if (!this._env) {
+ this._getEnv();
+ }
+
+ transaction = this._getTransaction(urls, options);
+
+ this._queue.push({
+ callback : callback,
+ transaction: transaction
+ });
+
+ this._next();
+
+ return transaction;
+ },
+
+ _next: function () {
+ var item;
+
+ if (this._pending) {
+ return;
+ }
+
+ item = this._queue.shift();
+
+ if (item) {
+ this._pending = item;
+
+ item.transaction.execute(function () {
+ item.callback && item.callback.apply(this, arguments);
+
+ Get._pending = null;
+ Get._next();
+ });
+ }
+ },
+
+ _purge: function (nodes) {
+ var purgeNodes = this._purgeNodes,
+ isTransaction = nodes !== purgeNodes,
+ index, node;
+
+ while (node = nodes.pop()) { // assignment
+ // Don't purge nodes that haven't finished loading (or errored out),
+ // since this can hang the transaction.
+ if (!node._yuiget_finished) {
+ continue;
+ }
+
+ node.parentNode && node.parentNode.removeChild(node);
+
+ // If this is a transaction-level purge and this node also exists in
+ // the Get-level _purgeNodes array, we need to remove it from
+ // _purgeNodes to avoid creating a memory leak. The indexOf lookup
+ // sucks, but until we get WeakMaps, this is the least troublesome
+ // way to do this (we can't just hold onto node ids because they may
+ // not be in the same document).
+ if (isTransaction) {
+ index = Y.Array.indexOf(purgeNodes, node);
+
+ if (index > -1) {
+ purgeNodes.splice(index, 1);
+ }
+ }
+ }
+ }
+};
+
+/**
+Alias for `js()`.
+
+@method script
+@static
+**/
+Get.script = Get.js;
+
+/**
+Represents a Get transaction, which may contain requests for one or more JS or
+CSS files.
+
+This class should not be instantiated manually. Instances will be created and
+returned as needed by Y.Get's `css()`, `js()`, and `load()` methods.
+
+@class Get.Transaction
+@constructor
+@since 3.5.0
+**/
+Get.Transaction = Transaction = function (requests, options) {
+ var self = this;
+
+ self.id = Transaction._lastId += 1;
+ self.data = options.data;
+ self.errors = [];
+ self.nodes = [];
+ self.options = options;
+ self.requests = requests;
+
+ self._callbacks = []; // callbacks to call after execution finishes
+ self._queue = [];
+ self._waiting = 0;
+
+ // Deprecated pre-3.5.0 properties.
+ self.tId = self.id; // Use `id` instead.
+ self.win = options.win || Y.config.win;
+};
+
+/**
+Arbitrary data object associated with this transaction.
+
+This object comes from the options passed to `Get.css()`, `Get.js()`, or
+`Get.load()`, and will be `undefined` if no data object was specified.
+
+@property {Object} data
+**/
+
+/**
+Array of errors that have occurred during this transaction, if any.
+
+@since 3.5.0
+@property {Object[]} errors
+@property {String} errors.error Error message.
+@property {Object} errors.request Request object related to the error.
+**/
+
+/**
+Numeric id for this transaction, unique among all transactions within the same
+YUI sandbox in the current pageview.
+
+@property {Number} id
+@since 3.5.0
+**/
+
+/**
+HTMLElement nodes (native ones, not YUI Node instances) that have been inserted
+during the current transaction.
+
+@property {HTMLElement[]} nodes
+**/
+
+/**
+Options associated with this transaction.
+
+See `Get.options` for the full list of available options.
+
+@property {Object} options
+@since 3.5.0
+**/
+
+/**
+Request objects contained in this transaction. Each request object represents
+one CSS or JS URL that will be (or has been) requested and loaded into the page.
+
+@property {Object} requests
+@since 3.5.0
+**/
+
+/**
+Id of the most recent transaction.
+
+@property _lastId
+@type Number
+@protected
+@static
+**/
+Transaction._lastId = 0;
+
+Transaction.prototype = {
+ // -- Public Properties ----------------------------------------------------
+
+ /**
+ Current state of this transaction. One of "new", "executing", or "done".
+
+ @property _state
+ @type String
+ @protected
+ **/
+ _state: 'new', // "new", "executing", or "done"
+
+ // -- Public Methods -------------------------------------------------------
+
+ /**
+ Aborts this transaction.
+
+ This will cause the transaction's `onFailure` callback to be called and
+ will prevent any new script and link nodes from being added to the document,
+ but any resources that have already been requested will continue loading
+ (there's no safe way to prevent this, unfortunately).
+
+ @method abort
+ @param {String} [msg="Aborted."] Optional message to use in the `errors`
+ array describing why the transaction was aborted.
+ **/
+ abort: function (msg) {
+ this._pending = null;
+ this._pendingCSS = null;
+ this._pollTimer = clearTimeout(this._pollTimer);
+ this._queue = [];
+ this._waiting = 0;
+
+ this.errors.push({error: msg || 'Aborted'});
+ this._finish();
+ },
+
+ /**
+ Begins execting the transaction.
+
+ There's usually no reason to call this manually, since Get will call it
+ automatically when other pending transactions have finished. If you really
+ want to execute your transaction before Get does, you can, but be aware that
+ this transaction's scripts may end up executing before the scripts in other
+ pending transactions.
+
+ If the transaction is already executing, the specified callback (if any)
+ will be queued and called after execution finishes. If the transaction has
+ already finished, the callback will be called immediately (the transaction
+ will not be executed again).
+
+ @method execute
+ @param {Function} callback Callback function to execute after all requests
+ in the transaction are complete, or after the transaction is aborted.
+ **/
+ execute: function (callback) {
+ var self = this,
+ requests = self.requests,
+ state = self._state,
+ i, len, queue, req;
+
+ if (state === 'done') {
+ callback && callback(self.errors.length ? self.errors : null, self);
+ return;
+ } else {
+ callback && self._callbacks.push(callback);
+
+ if (state === 'executing') {
+ return;
+ }
+ }
+
+ self._state = 'executing';
+ self._queue = queue = [];
+
+ if (self.options.timeout) {
+ self._timeout = setTimeout(function () {
+ self.abort('Timeout');
+ }, self.options.timeout);
+ }
+
+ for (i = 0, len = requests.length; i < len; ++i) {
+ req = self.requests[i];
+
+ if (req.async || req.type === 'css') {
+ // No need to queue CSS or fully async JS.
+ self._insert(req);
+ } else {
+ queue.push(req);
+ }
+ }
+
+ self._next();
+ },
+
+ /**
+ Manually purges any `<script>` or `<link>` nodes this transaction has
+ created.
+
+ Be careful when purging a transaction that contains CSS requests, since
+ removing `<link>` nodes will also remove any styles they applied.
+
+ @method purge
+ **/
+ purge: function () {
+ Get._purge(this.nodes);
+ },
+
+ // -- Protected Methods ----------------------------------------------------
+ _createNode: function (name, attrs, doc) {
+ var node = doc.createElement(name),
+ attr;
+
+ for (attr in attrs) {
+ if (attrs.hasOwnProperty(attr)) {
+ node.setAttribute(attr, attrs[attr]);
+ }
+ }
+
+ return node;
+ },
+
+ _finish: function () {
+ var errors = this.errors.length ? this.errors : null,
+ options = this.options,
+ thisObj = options.context || this,
+ data, i, len;
+
+ if (this._state === 'done') {
+ return;
+ }
+
+ this._state = 'done';
+
+ for (i = 0, len = this._callbacks.length; i < len; ++i) {
+ this._callbacks[i].call(thisObj, errors, this);
+ }
+
+ data = this._getEventData();
+
+ if (errors) {
+ if (options.onTimeout && errors[errors.length - 1].error === 'Timeout') {
+ options.onTimeout.call(thisObj, data);
+ }
+
+ if (options.onFailure) {
+ options.onFailure.call(thisObj, data);
+ }
+ } else if (options.onSuccess) {
+ options.onSuccess.call(thisObj, data);
+ }
+
+ if (options.onEnd) {
+ options.onEnd.call(thisObj, data);
+ }
+ },
+
+ _getEventData: function (req) {
+ if (req) {
+ // This merge is necessary for backcompat. I hate it.
+ return Y.merge(this, {
+ abort : this.abort, // have to copy these because the prototype isn't preserved
+ purge : this.purge,
+ request: req,
+ url : req.url,
+ win : req.win
+ });
+ } else {
+ return this;
+ }
+ },
+
+ _getInsertBefore: function (req) {
+ var doc = req.doc,
+ el = req.insertBefore,
+ cache, cachedNode, docStamp;
+
+ if (el) {
+ return typeof el === 'string' ? doc.getElementById(el) : el;
+ }
+
+ cache = Get._insertCache;
+ docStamp = Y.stamp(doc);
+
+ if ((el = cache[docStamp])) { // assignment
+ return el;
+ }
+
+ // Inserting before a <base> tag apparently works around an IE bug
+ // (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
+ // bug that is, exactly. Better safe than sorry?
+ if ((el = doc.getElementsByTagName('base')[0])) { // assignment
+ return (cache[docStamp] = el);
+ }
+
+ // Look for a <head> element.
+ el = doc.head || doc.getElementsByTagName('head')[0];
+
+ if (el) {
+ // Create a marker node at the end of <head> to use as an insertion
+ // point. Inserting before this node will ensure that all our CSS
+ // gets inserted in the correct order, to maintain style precedence.
+ el.appendChild(doc.createTextNode(''));
+ return (cache[docStamp] = el.lastChild);
+ }
+
+ // If all else fails, just insert before the first script node on the
+ // page, which is virtually guaranteed to exist.
+ return (cache[docStamp] = doc.getElementsByTagName('script')[0]);
+ },
+
+ _insert: function (req) {
+ var env = Get._env,
+ insertBefore = this._getInsertBefore(req),
+ isScript = req.type === 'js',
+ node = req.node,
+ self = this,
+ ua = Y.UA,
+ nodeType;
+
+ if (!node) {
+ if (isScript) {
+ nodeType = 'script';
+ } else if (!env.cssLoad && ua.gecko) {
+ nodeType = 'style';
+ } else {
+ nodeType = 'link';
+ }
+
+ node = req.node = this._createNode(nodeType, req.attributes,
+ req.doc);
+ }
+
+ function onError() {
+ self._progress('Failed to load ' + req.url, req);
+ }
+
+ function onLoad() {
+ self._progress(null, req);
+ }
+
+ // Deal with script asynchronicity.
+ if (isScript) {
+ node.setAttribute('src', req.url);
+
+ if (req.async) {
+ // Explicitly indicate that we want the browser to execute this
+ // script asynchronously. This is necessary for older browsers
+ // like Firefox <4.
+ node.async = true;
+ } else {
+ if (env.async) {
+ // This browser treats injected scripts as async by default
+ // (standard HTML5 behavior) but asynchronous loading isn't
+ // desired, so tell the browser not to mark this script as
+ // async.
+ node.async = false;
+ }
+
+ // If this browser doesn't preserve script execution order based
+ // on insertion order, we'll need to avoid inserting other
+ // scripts until this one finishes loading.
+ if (!env.preservesScriptOrder) {
+ this._pending = req;
+ }
+ }
+ } else {
+ if (!env.cssLoad && ua.gecko) {
+ // In Firefox <9, we can import the requested URL into a <style>
+ // node and poll for the existence of node.sheet.cssRules. This
+ // gives us a reliable way to determine CSS load completion that
+ // also works for cross-domain stylesheets.
+ //
+ // Props to Zach Leatherman for calling my attention to this
+ // technique.
+ node.innerHTML = (req.attributes.charset ?
+ '@charset "' + req.attributes.charset + '";' : '') +
+ '@import "' + req.url + '";';
+ } else {
+ node.setAttribute('href', req.url);
+ }
+ }
+
+ // Inject the node.
+ if (isScript && ua.ie && ua.ie < 9) {
+ // Script on IE6, 7, and 8.
+ node.onreadystatechange = function () {
+ if (/loaded|complete/.test(node.readyState)) {
+ node.onreadystatechange = null;
+ onLoad();
+ }
+ };
+ } else if (!isScript && !env.cssLoad) {
+ // CSS on Firefox <9 or WebKit.
+ this._poll(req);
+ } else {
+ // Script or CSS on everything else. Using DOM 0 events because that
+ // evens the playing field with older IEs.
+ node.onerror = onError;
+ node.onload = onLoad;
+ }
+
+ this._waiting += 1;
+
+ this.nodes.push(node);
+ insertBefore.parentNode.insertBefore(node, insertBefore);
+ },
+
+ _next: function () {
+ if (this._pending) {
+ return;
+ }
+
+ // If there are requests in the queue, insert the next queued request.
+ // Otherwise, if we're waiting on already-inserted requests to finish,
+ // wait longer. If there are no queued requests and we're not waiting
+ // for anything to load, then we're done!
+ if (this._queue.length) {
+ this._insert(this._queue.shift());
+ } else if (!this._waiting) {
+ this._finish();
+ }
+ },
+
+ _poll: function (newReq) {
+ var self = this,
+ pendingCSS = self._pendingCSS,
+ isWebKit = Y.UA.webkit,
+ i, hasRules, j, nodeHref, req, sheets;
+
+ if (newReq) {
+ pendingCSS || (pendingCSS = self._pendingCSS = []);
+ pendingCSS.push(newReq);
+
+ if (self._pollTimer) {
+ // A poll timeout is already pending, so no need to create a
+ // new one.
+ return;
+ }
+ }
+
+ self._pollTimer = null;
+
+ // Note: in both the WebKit and Gecko hacks below, a CSS URL that 404s
+ // will still be treated as a success. There's no good workaround for
+ // this.
+
+ for (i = 0; i < pendingCSS.length; ++i) {
+ req = pendingCSS[i];
+
+ if (isWebKit) {
+ // Look for a stylesheet matching the pending URL.
+ sheets = req.doc.styleSheets;
+ j = sheets.length;
+ nodeHref = req.node.href;
+
+ while (--j >= 0) {
+ if (sheets[j].href === nodeHref) {
+ pendingCSS.splice(i, 1);
+ i -= 1;
+ self._progress(null, req);
+ break;
+ }
+ }
+ } else {
+ // Many thanks to Zach Leatherman for calling my attention to
+ // the @import-based cross-domain technique used here, and to
+ // Oleg Slobodskoi for an earlier same-domain implementation.
+ //
+ // See Zach's blog for more details:
+ // http://www.zachleat.com/web/2010/07/29/load-css-dynamically/
+ try {
+ // We don't really need to store this value since we never
+ // use it again, but if we don't store it, Closure Compiler
+ // assumes the code is useless and removes it.
+ hasRules = !!req.node.sheet.cssRules;
+
+ // If we get here, the stylesheet has loaded.
+ pendingCSS.splice(i, 1);
+ i -= 1;
+ self._progress(null, req);
+ } catch (ex) {
+ // An exception means the stylesheet is still loading.
+ }
+ }
+ }
+
+ if (pendingCSS.length) {
+ self._pollTimer = setTimeout(function () {
+ self._poll.call(self);
+ }, self.options.pollInterval);
+ }
+ },
+
+ _progress: function (err, req) {
+ var options = this.options;
+
+ if (err) {
+ req.error = err;
+
+ this.errors.push({
+ error : err,
+ request: req
+ });
+
+ }
+
+ req.node._yuiget_finished = req.finished = true;
+
+ if (options.onProgress) {
+ options.onProgress.call(options.context || this,
+ this._getEventData(req));
+ }
+
+ if (req.autopurge) {
+ // Pre-3.5.0 Get always excludes the most recent node from an
+ // autopurge. I find this odd, but I'm keeping that behavior for
+ // the sake of backcompat.
+ Get._autoPurge(this.options.purgethreshold);
+ Get._purgeNodes.push(req.node);
+ }
+
+ if (this._pending === req) {
+ this._pending = null;
+ }
+
+ this._waiting -= 1;
+ this._next();
+ }
+};
+
+
+}, '@VERSION@' ,{requires:['yui-base']});
2,545 js/loader-base.js
@@ -0,0 +1,2545 @@
+YUI.add('loader-base', function(Y) {
+
+/**
+ * The YUI loader core
+ * @module loader
+ * @submodule loader-base
+ */
+
+if (!YUI.Env[Y.version]) {
+
+ (function() {
+ var VERSION = Y.version,
+ BUILD = '/build/',
+ ROOT = VERSION + BUILD,
+ CDN_BASE = Y.Env.base,
+ GALLERY_VERSION = 'gallery-2012.01.25-21-14',
+ TNT = '2in3',
+ TNT_VERSION = '4',
+ YUI2_VERSION = '2.9.0',
+ COMBO_BASE = CDN_BASE + 'combo?',
+ META = { version: VERSION,
+ root: ROOT,
+ base: Y.Env.base,
+ comboBase: COMBO_BASE,
+ skin: { defaultSkin: 'sam',
+ base: 'assets/skins/',
+ path: 'skin.css',
+ after: ['cssreset',
+ 'cssfonts',
+ 'cssgrids',
+ 'cssbase',
+ 'cssreset-context',
+ 'cssfonts-context']},
+ groups: {},
+ patterns: {} },
+ groups = META.groups,
+ yui2Update = function(tnt, yui2) {
+ var root = TNT + '.' +
+ (tnt || TNT_VERSION) + '/' +
+ (yui2 || YUI2_VERSION) + BUILD;
+ groups.yui2.base = CDN_BASE + root;
+ groups.yui2.root = root;
+ },
+ galleryUpdate = function(tag) {
+ var root = (tag || GALLERY_VERSION) + BUILD;
+ groups.gallery.base = CDN_BASE + root;
+ groups.gallery.root = root;
+ };
+
+ groups[VERSION] = {};
+
+ groups.gallery = {
+ ext: false,
+ combine: true,
+ comboBase: COMBO_BASE,
+ update: galleryUpdate,
+ patterns: { 'gallery-': { },
+ 'lang/gallery-': {},
+ 'gallerycss-': { type: 'css' } }
+ };
+
+ groups.yui2 = {
+ combine: true,
+ ext: false,
+ comboBase: COMBO_BASE,
+ update: yui2Update,
+ patterns: {
+ 'yui2-': {
+ configFn: function(me) {
+ if (/-skin|reset|fonts|grids|base/.test(me.name)) {
+ me.type = 'css';
+ me.path = me.path.replace(/\.js/, '.css');
+ // this makes skins in builds earlier than
+ // 2.6.0 work as long as combine is false
+ me.path = me.path.replace(/\/yui2-skin/,
+ '/assets/skins/sam/yui2-skin');
+ }
+ }
+ }
+ }
+ };
+
+ galleryUpdate();
+ yui2Update();
+
+ YUI.Env[VERSION] = META;
+ }());
+}
+
+
+/**
+ * Loader dynamically loads script and css files. It includes the dependency
+ * information for the version of the library in use, and will automatically pull in
+ * dependencies for the modules requested. It can also load the
+ * files from the Yahoo! CDN, and it can utilize the combo service provided on
+ * this network to reduce the number of http connections required to download
+ * YUI files.
+ *
+ * @module loader
+ * @main loader
+ * @submodule loader-base
+ */
+
+var NOT_FOUND = {},
+ NO_REQUIREMENTS = [],
+ MAX_URL_LENGTH = 1024,
+ GLOBAL_ENV = YUI.Env,
+ GLOBAL_LOADED = GLOBAL_ENV._loaded,
+ CSS = 'css',
+ JS = 'js',
+ INTL = 'intl',
+ VERSION = Y.version,
+ ROOT_LANG = '',
+ YObject = Y.Object,
+ oeach = YObject.each,
+ YArray = Y.Array,
+ _queue = GLOBAL_ENV._loaderQueue,
+ META = GLOBAL_ENV[VERSION],
+ SKIN_PREFIX = 'skin-',
+ L = Y.Lang,
+ ON_PAGE = GLOBAL_ENV.mods,
+ modulekey,
+ cache,
+ _path = function(dir, file, type, nomin) {
+ var path = dir + '/' + file;
+ if (!nomin) {
+ path += '-min';
+ }
+ path += '.' + (type || CSS);
+
+ return path;
+ };
+
+/**
+ * The component metadata is stored in Y.Env.meta.
+ * Part of the loader module.
+ * @property meta
+ * @for YUI
+ */
+Y.Env.meta = META;
+
+/**
+ * Loader dynamically loads script and css files. It includes the dependency
+ * info for the version of the library in use, and will automatically pull in
+ * dependencies for the modules requested. It supports rollup files and will
+ * automatically use these when appropriate in order to minimize the number of
+ * http connections required to load all of the dependencies. It can load the
+ * files from the Yahoo! CDN, and it can utilize the combo service provided on
+ * this network to reduce the number of http connections required to download
+ * YUI files.
+ *
+ * While the loader can be instantiated by the end user, it normally is not.
+ * @see YUI.use for the normal use case. The use function automatically will
+ * pull in missing dependencies.
+ *
+ * @constructor
+ * @class Loader
+ * @param {object} o an optional set of configuration options. Valid options:
+ * <ul>
+ * <li>base:
+ * The base dir</li>
+ * <li>comboBase:
+ * The YUI combo service base dir. Ex: http://yui.yahooapis.com/combo?</li>
+ * <li>root:
+ * The root path to prepend to module names for the combo service.
+ * Ex: 2.5.2/build/</li>
+ * <li>filter:.
+ *
+ * A filter to apply to result urls. This filter will modify the default
+ * path for all modules. The default path for the YUI library is the
+ * minified version of the files (e.g., event-min.js). The filter property
+ * can be a predefined filter or a custom filter. The valid predefined
+ * filters are:
+ * <dl>
+ * <dt>DEBUG</dt>
+ * <dd>Selects the debug versions of the library (e.g., event-debug.js).
+ * This option will automatically include the Logger widget</dd>
+ * <dt>RAW</dt>
+ * <dd>Selects the non-minified version of the library (e.g., event.js).
+ * </dd>
+ * </dl>
+ * You can also define a custom filter, which must be an object literal
+ * containing a search expression and a replace string:
+ * <pre>
+ * myFilter: &#123;
+ * 'searchExp': "-min\\.js",
+ * 'replaceStr': "-debug.js"
+ * &#125;
+ * </pre>
+ *
+ * </li>
+ * <li>filters: per-component filter specification. If specified
+ * for a given component, this overrides the filter config. _Note:_ This does not work on combo urls, use the filter property instead.</li>
+ * <li>combine:
+ * Use the YUI combo service to reduce the number of http connections
+ * required to load your dependencies</li>
+ * <li>ignore:
+ * A list of modules that should never be dynamically loaded</li>
+ * <li>force:
+ * A list of modules that should always be loaded when required, even if
+ * already present on the page</li>
+ * <li>insertBefore:
+ * Node or id for a node that should be used as the insertion point for
+ * new nodes</li>
+ * <li>charset:
+ * charset for dynamic nodes (deprecated, use jsAttributes or cssAttributes)
+ * </li>
+ * <li>jsAttributes: object literal containing attributes to add to script
+ * nodes</li>
+ * <li>cssAttributes: object literal containing attributes to add to link
+ * nodes</li>
+ * <li>timeout:
+ * The number of milliseconds before a timeout occurs when dynamically
+ * loading nodes. If not set, there is no timeout</li>
+ * <li>context:
+ * execution context for all callbacks</li>
+ * <li>onSuccess:
+ * callback for the 'success' event</li>
+ * <li>onFailure: callback for the 'failure' event</li>
+ * <li>onCSS: callback for the 'CSSComplete' event. When loading YUI
+ * components with CSS the CSS is loaded first, then the script. This
+ * provides a moment you can tie into to improve
+ * the presentation of the page while the script is loading.</li>
+ * <li>onTimeout:
+ * callback for the 'timeout' event</li>
+ * <li>onProgress:
+ * callback executed each time a script or css file is loaded</li>
+ * <li>modules:
+ * A list of module definitions. See Loader.addModule for the supported
+ * module metadata</li>
+ * <li>groups:
+ * A list of group definitions. Each group can contain specific definitions
+ * for base, comboBase, combine, and accepts a list of modules. See above
+ * for the description of these properties.</li>
+ * <li>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.</li>
+ * <li>yui2: when using the 2in3 project, you can select the version of
+ * YUI 2 to use. Valid values * are 2.2.2, 2.3.1, 2.4.1, 2.5.2, 2.6.0,
+ * 2.7.0, 2.8.0, and 2.8.1 [default] -- plus all versions of YUI 2
+ * going forward.</li>
+ * </ul>
+ */
+Y.Loader = function(o) {
+
+ var defaults = META.modules,
+ self = this;
+
+ //Catch no config passed.
+ o = o || {};
+
+ modulekey = META.md5;
+
+ /**
+ * Internal callback to handle multiple internal insert() calls
+ * so that css is inserted prior to js
+ * @property _internalCallback
+ * @private
+ */
+ // self._internalCallback = null;
+
+ /**
+ * Callback that will be executed when the loader is finished
+ * with an insert
+ * @method onSuccess
+ * @type function
+ */
+ // self.onSuccess = null;
+
+ /**
+ * Callback that will be executed if there is a failure
+ * @method onFailure
+ * @type function
+ */
+ // self.onFailure = null;
+
+ /**
+ * Callback for the 'CSSComplete' event. When loading YUI components
+ * with CSS the CSS is loaded first, then the script. This provides
+ * a moment you can tie into to improve the presentation of the page
+ * while the script is loading.
+ * @method onCSS
+ * @type function
+ */
+ // self.onCSS = null;
+
+ /**
+ * Callback executed each time a script or css file is loaded
+ * @method onProgress
+ * @type function
+ */
+ // self.onProgress = null;
+
+ /**
+ * Callback that will be executed if a timeout occurs
+ * @method onTimeout
+ * @type function
+ */
+ // self.onTimeout = null;
+
+ /**
+ * The execution context for all callbacks
+ * @property context
+ * @default {YUI} the YUI instance
+ */
+ self.context = Y;
+
+ /**
+ * Data that is passed to all callbacks
+ * @property data
+ */
+ // self.data = null;
+
+ /**
+ * Node reference or id where new nodes should be inserted before
+ * @property insertBefore
+ * @type string|HTMLElement
+ */
+ // self.insertBefore = null;
+
+ /**
+ * The charset attribute for inserted nodes
+ * @property charset
+ * @type string
+ * @deprecated , use cssAttributes or jsAttributes.
+ */
+ // self.charset = null;
+
+ /**
+ * An object literal containing attributes to add to link nodes
+ * @property cssAttributes
+ * @type object
+ */
+ // self.cssAttributes = null;
+
+ /**
+ * An object literal containing attributes to add to script nodes
+ * @property jsAttributes
+ * @type object
+ */
+ // self.jsAttributes = null;
+
+ /**
+ * The base directory.
+ * @property base
+ * @type string
+ * @default http://yui.yahooapis.com/[YUI VERSION]/build/
+ */
+ self.base = Y.Env.meta.base + Y.Env.meta.root;
+
+ /**
+ * Base path for the combo service
+ * @property comboBase
+ * @type string
+ * @default http://yui.yahooapis.com/combo?
+ */
+ self.comboBase = Y.Env.meta.comboBase;
+
+ /*
+ * Base path for language packs.
+ */
+ // self.langBase = Y.Env.meta.langBase;
+ // self.lang = "";
+
+ /**
+ * If configured, the loader will attempt to use the combo
+ * service for YUI resources and configured external resources.
+ * @property combine
+ * @type boolean
+ * @default true if a base dir isn't in the config
+ */
+ self.combine = o.base &&
+ (o.base.indexOf(self.comboBase.substr(0, 20)) > -1);
+
+ /**
+ * The default seperator to use between files in a combo URL
+ * @property comboSep
+ * @type {String}
+ * @default Ampersand
+ */
+ self.comboSep = '&';
+ /**
+ * Max url length for combo urls. The default is 2048. This is the URL
+ * limit for the Yahoo! hosted combo servers. If consuming
+ * a different combo service that has a different URL limit
+ * it is possible to override this default by supplying
+ * the maxURLLength config option. The config option will
+ * only take effect if lower than the default.
+ *
+ * @property maxURLLength
+ * @type int
+ */
+ self.maxURLLength = MAX_URL_LENGTH;
+
+ /**
+ * Ignore modules registered on the YUI global
+ * @property ignoreRegistered
+ * @default false
+ */
+ //self.ignoreRegistered = false;
+
+ /**
+ * Root path to prepend to module path for the combo
+ * service
+ * @property root
+ * @type string
+ * @default [YUI VERSION]/build/
+ */
+ self.root = Y.Env.meta.root;
+
+ /**
+ * Timeout value in milliseconds. If set, self value will be used by
+ * the get utility. the timeout event will fire if
+ * a timeout occurs.
+ * @property timeout
+ * @type int
+ */
+ self.timeout = 0;
+
+ /**
+ * A list of modules that should not be loaded, even if
+ * they turn up in the dependency tree
+ * @property ignore
+ * @type string[]
+ */
+ // self.ignore = null;
+
+ /**
+ * A list of modules that should always be loaded, even
+ * if they have already been inserted into the page.
+ * @property force
+ * @type string[]
+ */
+ // self.force = null;
+
+ self.forceMap = {};
+
+ /**
+ * Should we allow rollups
+ * @property allowRollup
+ * @type boolean
+ * @default false
+ */
+ self.allowRollup = false;
+
+ /**
+ * A filter to apply to result urls. This filter will modify the default
+ * path for all modules. The default path for the YUI library is the
+ * minified version of the files (e.g., event-min.js). The filter property
+ * can be a predefined filter or a custom filter. The valid predefined
+ * filters are:
+ * <dl>
+ * <dt>DEBUG</dt>
+ * <dd>Selects the debug versions of the library (e.g., event-debug.js).
+ * This option will automatically include the Logger widget</dd>
+ * <dt>RAW</dt>
+ * <dd>Selects the non-minified version of the library (e.g., event.js).
+ * </dd>
+ * </dl>
+ * You can also define a custom filter, which must be an object literal
+ * containing a search expression and a replace string:
+ * <pre>
+ * myFilter: &#123;
+ * 'searchExp': "-min\\.js",
+ * 'replaceStr': "-debug.js"
+ * &#125;
+ * </pre>
+ * @property filter
+ * @type string| {searchExp: string, replaceStr: string}
+ */
+ // self.filter = null;
+
+ /**
+ * per-component filter specification. If specified for a given
+ * component, this overrides the filter config.
+ * @property filters
+ * @type object
+ */
+ self.filters = {};
+
+ /**
+ * The list of requested modules
+ * @property required
+ * @type {string: boolean}
+ */
+ self.required = {};
+
+ /**
+ * If a module name is predefined when requested, it is checked againsts
+ * the patterns provided in this property. If there is a match, the
+ * module is added with the default configuration.
+ *
+ * At the moment only supporting module prefixes, but anticipate
+ * supporting at least regular expressions.
+ * @property patterns
+ * @type Object
+ */
+ // self.patterns = Y.merge(Y.Env.meta.patterns);
+ self.patterns = {};
+
+ /**
+ * The library metadata
+ * @property moduleInfo
+ */
+ // self.moduleInfo = Y.merge(Y.Env.meta.moduleInfo);
+ self.moduleInfo = {};
+
+ self.groups = Y.merge(Y.Env.meta.groups);
+
+ /**
+ * Provides the information used to skin the skinnable components.
+ * The following skin definition would result in 'skin1' and 'skin2'
+ * being loaded for calendar (if calendar was requested), and
+ * 'sam' for all other skinnable components:
+ *
+ * <code>
+ * skin: {
+ *
+ * // The default skin, which is automatically applied if not
+ * // overriden by a component-specific skin definition.
+ * // Change this in to apply a different skin globally
+ * defaultSkin: 'sam',
+ *
+ * // This is combined with the loader base property to get
+ * // the default root directory for a skin. ex:
+ * // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/
+ * base: 'assets/skins/',
+ *
+ * // Any component-specific overrides can be specified here,
+ * // making it possible to load different skins for different
+ * // components. It is possible to load more than one skin
+ * // for a given component as well.
+ * overrides: {
+ * calendar: ['skin1', 'skin2']
+ * }
+ * }
+ * </code>
+ * @property skin
+ */
+ self.skin = Y.merge(Y.Env.meta.skin);
+
+ /*
+ * Map of conditional modules
+ * @since 3.2.0
+ */
+ self.conditions = {};
+
+ // map of modules with a hash of modules that meet the requirement
+ // self.provides = {};
+
+ self.config = o;
+ self._internal = true;
+
+
+ cache = GLOBAL_ENV._renderedMods;
+
+ if (cache) {
+ oeach(cache, function modCache(v, k) {
+ self.moduleInfo[k] = Y.merge(v);
+ });
+
+ cache = GLOBAL_ENV._conditions;
+
+ oeach(cache, function condCache(v, k) {
+ self.conditions[k] = Y.merge(v);
+ });
+
+ } else {
+ oeach(defaults, self.addModule, self);
+ }
+
+
+ /**
+ * Set when beginning to compute the dependency tree.
+ * Composed of what YUI reports to be loaded combined
+ * with what has been loaded by any instance on the page
+ * with the version number specified in the metadata.
+ * @property loaded
+ * @type {string: boolean}
+ */
+ self.loaded = GLOBAL_LOADED[VERSION];
+
+
+ self._inspectPage();
+
+ self._internal = false;
+
+ self._config(o);
+
+ self.forceMap = (self.force) ? Y.Array.hash(self.force) : {};
+
+ self.testresults = null;
+
+ if (Y.config.tests) {
+ self.testresults = Y.config.tests;
+ }
+
+ /**
+ * List of rollup files found in the library metadata
+ * @property rollups
+ */
+ // self.rollups = null;
+
+ /**
+ * Whether or not to load optional dependencies for
+ * the requested modules
+ * @property loadOptional
+ * @type boolean
+ * @default false
+ */
+ // self.loadOptional = false;
+
+ /**
+ * All of the derived dependencies in sorted order, which
+ * will be populated when either calculate() or insert()
+ * is called
+ * @property sorted
+ * @type string[]
+ */
+ self.sorted = [];
+
+ /*
+ * A list of modules to attach to the YUI instance when complete.
+ * If not supplied, the sorted list of dependencies are applied.
+ * @property attaching
+ */
+ // self.attaching = null;
+
+ /**
+ * Flag to indicate the dependency tree needs to be recomputed
+ * if insert is called again.
+ * @property dirty
+ * @type boolean
+ * @default true
+ */
+ self.dirty = true;
+
+ /**
+ * List of modules inserted by the utility
+ * @property inserted
+ * @type {string: boolean}
+ */
+ self.inserted = {};
+
+ /**
+ * List of skipped modules during insert() because the module
+ * was not defined
+ * @property skipped
+ */
+ self.skipped = {};
+
+ // Y.on('yui:load', self.loadNext, self);
+
+ self.tested = {};
+
+ /*
+ * Cached sorted calculate results
+ * @property results
+ * @since 3.2.0
+ */
+ //self.results = {};
+
+};
+
+Y.Loader.prototype = {
+ /**
+ Regex that matches a CSS URL. Used to guess the file type when it's not
+ specified.
+
+ @property REGEX_CSS
+ @type RegExp
+ @final
+ @protected
+ @since 3.5.0
+ **/
+ REGEX_CSS: /\.css(?:[?;].*)?$/i,
+
+ /**
+ * Default filters for raw and debug
+ * @property FILTER_DEFS
+ * @type Object
+ * @final
+ * @protected
+ */
+ FILTER_DEFS: {
+ RAW: {
+ 'searchExp': '-min\\.js',
+ 'replaceStr': '.js'
+ },
+ DEBUG: {
+ 'searchExp': '-min\\.js',
+ 'replaceStr': '-debug.js'
+ }
+ },
+ /*
+ * Check the pages meta-data and cache the result.
+ * @method _inspectPage
+ * @private
+ */
+ _inspectPage: function() {
+
+ //Inspect the page for CSS only modules and mark them as loaded.
+ oeach(this.moduleInfo, function(v, k) {
+ if (v.type && v.type === CSS) {
+ if (this.isCSSLoaded(v.name)) {
+ this.loaded[k] = true;
+ }
+ }
+ }, this);
+
+ oeach(ON_PAGE, function(v, k) {
+ if (v.details) {
+ var m = this.moduleInfo[k],
+ req = v.details.requires,
+ mr = m && m.requires;
+ if (m) {
+ if (!m._inspected && req && mr.length != req.length) {
+ // console.log('deleting ' + m.name);
+ delete m.expanded;
+ }
+ } else {
+ m = this.addModule(v.details, k);
+ }
+ m._inspected = true;
+ }
+ }, this);
+ },
+ /*
+ * returns true if b is not loaded, and is required directly or by means of modules it supersedes.
+ * @private
+ * @method _requires
+ * @param {String} mod1 The first module to compare
+ * @param {String} mod2 The second module to compare
+ */
+ _requires: function(mod1, mod2) {
+
+ var i, rm, after_map, s,
+ info = this.moduleInfo,
+ m = info[mod1],
+ other = info[mod2];
+
+ if (!m || !other) {
+ return false;
+ }
+
+ rm = m.expanded_map;
+ after_map = m.after_map;
+
+ // check if this module should be sorted after the other
+ // do this first to short circut circular deps
+ if (after_map && (mod2 in after_map)) {
+ return true;
+ }
+
+ after_map = other.after_map;
+
+ // and vis-versa
+ if (after_map && (mod1 in after_map)) {
+ return false;
+ }
+
+ // check if this module requires one the other supersedes
+ s = info[mod2] && info[mod2].supersedes;
+ if (s) {
+ for (i = 0; i < s.length; i++) {
+ if (this._requires(mod1, s[i])) {
+ return true;
+ }
+ }
+ }
+
+ s = info[mod1] && info[mod1].supersedes;
+ if (s) {
+ for (i = 0; i < s.length; i++) {
+ if (this._requires(mod2, s[i])) {
+ return false;
+ }
+ }
+ }
+
+ // check if this module requires the other directly
+ // if (r && YArray.indexOf(r, mod2) > -1) {
+ if (rm && (mod2 in rm)) {
+ return true;
+ }
+
+ // external css files should be sorted below yui css
+ if (m.ext && m.type == CSS && !other.ext && other.type == CSS) {
+ return true;
+ }
+
+ return false;
+ },
+ /**
+ * Apply a new config to the Loader instance
+ * @method _config
+ * @param {Object} o The new configuration
+ */
+ _config: function(o) {
+ var i, j, val, f, group, groupName, self = this;
+ // apply config values
+ if (o) {
+ for (i in o) {
+ if (o.hasOwnProperty(i)) {
+ val = o[i];
+ if (i == 'require') {
+ self.require(val);
+ } else if (i == 'skin') {
+ //If the config.skin is a string, format to the expected object
+ if (typeof val === 'string') {
+ self.skin.defaultSkin = o.skin;
+ val = {
+ defaultSkin: val
+ };
+ }
+
+ Y.mix(self.skin, val, true);
+ } else if (i == 'groups') {
+ for (j in val) {
+ if (val.hasOwnProperty(j)) {
+ groupName = j;
+ group = val[j];
+ self.addGroup(group, groupName);
+ }
+ }
+
+ } else if (i == 'modules') {
+ // add a hash of module definitions
+ oeach(val, self.addModule, self);
+ } else if (i == 'gallery') {
+ this.groups.gallery.update(val);
+ } else if (i == 'yui2' || i == '2in3') {
+ this.groups.yui2.update(o['2in3'], o.yui2);
+ } else {
+ self[i] = val;
+ }
+ }
+ }
+ }
+
+ // fix filter
+ f = self.filter;
+
+ if (L.isString(f)) {
+ f = f.toUpperCase();
+ self.filterName = f;
+ self.filter = self.FILTER_DEFS[f];
+ if (f == 'DEBUG') {
+ self.require('yui-log', 'dump');
+ }
+ }
+
+ if (self.lang) {
+ self.require('intl-base', 'intl');
+ }
+
+ },
+
+ /**
+ * Returns the skin module name for the specified skin name. If a
+ * module name is supplied, the returned skin module name is
+ * specific to the module passed in.
+ * @method formatSkin
+ * @param {string} skin the name of the skin.
+ * @param {string} mod optional: the name of a module to skin.
+ * @return {string} the full skin module name.
+ */
+ formatSkin: function(skin, mod) {
+ var s = SKIN_PREFIX + skin;
+ if (mod) {
+ s = s + '-' + mod;
+ }
+
+ return s;
+ },
+
+ /**
+ * Adds the skin def to the module info
+ * @method _addSkin
+ * @param {string} skin the name of the skin.
+ * @param {string} mod the name of the module.
+ * @param {string} parent parent module if this is a skin of a
+ * submodule or plugin.
+ * @return {string} the module name for the skin.
+ * @private
+ */
+ _addSkin: function(skin, mod, parent) {
+ var mdef, pkg, name, nmod,
+ info = this.moduleInfo,
+ sinf = this.skin,
+ ext = info[mod] && info[mod].ext;
+
+ // Add a module definition for the module-specific skin css
+ if (mod) {
+ name = this.formatSkin(skin, mod);
+ if (!info[name]) {
+ mdef = info[mod];
+ pkg = mdef.pkg || mod;
+ nmod = {
+ name: name,
+ group: mdef.group,
+ type: 'css',
+ after: sinf.after,
+ path: (parent || pkg) + '/' + sinf.base + skin +
+ '/' + mod + '.css',
+ ext: ext
+ };
+ if (mdef.base) {
+ nmod.base = mdef.base;
+ }
+ if (mdef.configFn) {
+ nmod.configFn = mdef.configFn;
+ }
+ this.addModule(nmod, name);
+
+ }
+ }
+
+ return name;
+ },
+
+ /**
+ * Add a new module group
+ * <dl>
+ * <dt>name:</dt> <dd>required, the group name</dd>
+ * <dt>base:</dt> <dd>The base dir for this module group</dd>
+ * <dt>root:</dt> <dd>The root path to add to each combo
+ * resource path</dd>
+ * <dt>combine:</dt> <dd>combo handle</dd>
+ * <dt>comboBase:</dt> <dd>combo service base path</dd>
+ * <dt>modules:</dt> <dd>the group of modules</dd>
+ * </dl>
+ * @method addGroup
+ * @param {object} o An object containing the module data.
+ * @param {string} name the group name.
+ */
+ addGroup: function(o, name) {
+ var mods = o.modules,
+ self = this;
+ name = name || o.name;
+ o.name = name;
+ self.groups[name] = o;
+
+ if (o.patterns) {
+ oeach(o.patterns, function(v, k) {
+ v.group = name;
+ self.patterns[k] = v;
+ });
+ }
+
+ if (mods) {
+ oeach(mods, function(v, k) {
+ if (typeof v === 'string') {
+ v = { name: k, fullpath: v };
+ }
+ v.group = name;
+ self.addModule(v, k);
+ }, self);
+ }
+ },
+
+ /**
+ * Add a new module to the component metadata.
+ * <dl>
+ * <dt>name:</dt> <dd>required, the component name</dd>
+ * <dt>type:</dt> <dd>required, the component type (js or css)
+ * </dd>
+ * <dt>path:</dt> <dd>required, the path to the script from
+ * "base"</dd>
+ * <dt>requires:</dt> <dd>array of modules required by this
+ * component</dd>
+ * <dt>optional:</dt> <dd>array of optional modules for this
+ * component</dd>
+ * <dt>supersedes:</dt> <dd>array of the modules this component
+ * replaces</dd>
+ * <dt>after:</dt> <dd>array of modules the components which, if
+ * present, should be sorted above this one</dd>
+ * <dt>after_map:</dt> <dd>faster alternative to 'after' -- supply
+ * a hash instead of an array</dd>
+ * <dt>rollup:</dt> <dd>the number of superseded modules required
+ * for automatic rollup</dd>
+ * <dt>fullpath:</dt> <dd>If fullpath is specified, this is used
+ * instead of the configured base + path</dd>
+ * <dt>skinnable:</dt> <dd>flag to determine if skin assets should
+ * automatically be pulled in</dd>
+ * <dt>submodules:</dt> <dd>a hash of submodules</dd>
+ * <dt>group:</dt> <dd>The group the module belongs to -- this
+ * is set automatically when it is added as part of a group
+ * configuration.</dd>
+ * <dt>lang:</dt>
+ * <dd>array of BCP 47 language tags of languages for which this
+ * module has localized resource bundles,
+ * e.g., ["en-GB","zh-Hans-CN"]</dd>
+ * <dt>condition:</dt>
+ * <dd>Specifies that the module should be loaded automatically if
+ * a condition is met. This is an object with up to three fields:
+ * [trigger] - the name of a module that can trigger the auto-load
+ * [test] - a function that returns true when the module is to be