Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge remote-tracking branch 'upstream/master'

  • Loading branch information...
commit 30b21764ed876fae35ca28f850fd3e850e53b838 2 parents ff0441a + 3a601e5
tripp bridges authored March 16, 2012

Showing 28 changed files with 1,660 additions and 306 deletions. Show diff stats Hide diff stats

  1. 70  build/selector-css2/selector-css2-debug.js
  2. 2  build/selector-css2/selector-css2-min.js
  3. 70  build/selector-css2/selector-css2.js
  4. 84  build/selector-native/selector-native-debug.js
  5. 2  build/selector-native/selector-native-min.js
  6. 84  build/selector-native/selector-native.js
  7. 219  src/base/tests/base-core.html
  8. 472  src/base/tests/base.html
  9. 594  src/datatable/docs/index.mustache
  10. 12  src/datatable/js/body.js
  11. 2  src/dial/docs/duck.mustache
  12. 4  src/dial/docs/index.mustache
  13. 70  src/dom/js/selector-css2.js
  14. 84  src/dom/js/selector-native.js
  15. 9  src/dom/tests/selector.html
  16. 8  src/graphics/docs/graphics-path-tool.mustache
  17. 4  src/graphics/docs/graphics-radial-tool.mustache
  18. 2  src/node/docs/properties.mustache
  19. 16  src/overlay/docs/overlay-tooltip.mustache
  20. 10  src/overlay/docs/overlay-xy.mustache
  21. 2  src/overlay/docs/partials/overlay-align-source.mustache
  22. 2  src/panel/docs/dialog.mustache
  23. 40  src/pluginhost/tests/plugins.html
  24. 23  src/scrollview/js/scrollview-base.js
  25. 2  src/slider/docs/index.mustache
  26. 2  src/sortable/docs/sortable-fish.mustache
  27. 73  src/widget/tests/widget.html
  28. 4  src/yui/docs/yui-core.mustache
70  build/selector-css2/selector-css2-debug.js
@@ -22,11 +22,6 @@ var PARENT_NODE = 'parentNode',
22 22
     SelectorCSS2 = {
23 23
         _reRegExpTokens: /([\^\$\?\[\]\*\+\-\.\(\)\|\\])/,
24 24
         SORT_RESULTS: true,
25  
-        _re: {
26  
-            attr: /(\[[^\]]*\])/g,
27  
-            esc: /\\[:\[\]\(\)#\.\'\>+~"]/gi,
28  
-            pseudos: /(\([^\)]*\))/g
29  
-        },
30 25
 
31 26
         // TODO: better detection, document specific
32 27
         _isXML: (function() {
@@ -319,7 +314,7 @@ var PARENT_NODE = 'parentNode',
319 314
          */
320 315
         _tokenize: function(selector) {
321 316
             selector = selector || '';
322  
-            selector = Selector._replaceShorthand(Y.Lang.trim(selector)); 
  317
+            selector = Selector._parseSelector(Y.Lang.trim(selector)); 
323 318
             var token = Selector._getToken(),     // one token per simple selector (left selector holds combinator)
324 319
                 query = selector, // original query for debug report
325 320
                 tokens = [],    // array of tokens
@@ -380,28 +375,18 @@ var PARENT_NODE = 'parentNode',
380 375
             return tokens;
381 376
         },
382 377
 
383  
-        _replaceShorthand: function(selector) {
384  
-            var shorthand = Selector.shorthand,
385  
-                esc = selector.match(Selector._re.esc), // pull escaped colon, brackets, etc. 
386  
-                attrs,
387  
-                pseudos,
388  
-                re, i, len;
389  
-
390  
-            if (esc) {
391  
-                selector = selector.replace(Selector._re.esc, '\uE000');
392  
-            }
393  
-
394  
-            pseudos = selector.match(Selector._re.pseudos);
395  
-
396  
-            if (pseudos) {
397  
-                selector = selector.replace(Selector._re.pseudos, '\uE002');
398  
-            }
  378
+        _replaceMarkers: function(selector) {
  379
+            selector = selector.replace(/\[/g, '\uE003');
  380
+            selector = selector.replace(/\]/g, '\uE004');
399 381
 
400  
-            attrs = selector.match(Selector._re.attr);
  382
+            selector = selector.replace(/\(/g, '\uE005');
  383
+            selector = selector.replace(/\)/g, '\uE006');
  384
+            return selector;
  385
+        },
401 386
 
402  
-            if (attrs) {
403  
-                selector = selector.replace(Selector._re.attr, '\uE001');
404  
-            }
  387
+        _replaceShorthand: function(selector) {
  388
+            var shorthand = Y.Selector.shorthand,
  389
+                re;
405 390
 
406 391
             for (re in shorthand) {
407 392
                 if (shorthand.hasOwnProperty(re)) {
@@ -409,29 +394,24 @@ var PARENT_NODE = 'parentNode',
409 394
                 }
410 395
             }
411 396
 
412  
-            if (attrs) {
413  
-                for (i = 0, len = attrs.length; i < len; ++i) {
414  
-                    selector = selector.replace(/\uE001/, attrs[i]);
415  
-                }
416  
-            }
  397
+            return selector;
  398
+        },
417 399
 
418  
-            if (pseudos) {
419  
-                for (i = 0, len = pseudos.length; i < len; ++i) {
420  
-                    selector = selector.replace(/\uE002/, pseudos[i]);
421  
-                }
422  
-            }
  400
+        _parseSelector: function(selector) {
  401
+            var replaced = Y.Selector._replaceSelector(selector),
  402
+                selector = replaced.selector;
423 403
 
424  
-            selector = selector.replace(/\[/g, '\uE003');
425  
-            selector = selector.replace(/\]/g, '\uE004');
  404
+            // replace shorthand (".foo, #bar") after pseudos and attrs
  405
+            // to avoid replacing unescaped chars
  406
+            selector = Y.Selector._replaceShorthand(selector);
426 407
 
427  
-            selector = selector.replace(/\(/g, '\uE005');
428  
-            selector = selector.replace(/\)/g, '\uE006');
  408
+            selector = Y.Selector._restore('attr', selector, replaced.attrs);
  409
+            selector = Y.Selector._restore('pseudo', selector, replaced.pseudos);
429 410
 
430  
-            if (esc) {
431  
-                for (i = 0, len = esc.length; i < len; ++i) {
432  
-                    selector = selector.replace('\uE000', esc[i]);
433  
-                }
434  
-            }
  411
+            // replace braces and parens before restoring escaped chars
  412
+            // to avoid replacing ecaped markers
  413
+            selector = Y.Selector._replaceMarkers(selector);
  414
+            selector = Y.Selector._restore('esc', selector, replaced.esc);
435 415
 
436 416
             return selector;
437 417
         },
2  build/selector-css2/selector-css2-min.js
... ...
@@ -1 +1 @@
1  
-YUI.add("selector-css2",function(g){var h="parentNode",d="tagName",e="attributes",a="combinator",f="pseudos",c=g.Selector,b={_reRegExpTokens:/([\^\$\?\[\]\*\+\-\.\(\)\|\\])/,SORT_RESULTS:true,_re:{attr:/(\[[^\]]*\])/g,esc:/\\[:\[\]\(\)#\.\'\>+~"]/gi,pseudos:/(\([^\)]*\))/g},_isXML:(function(){var i=(g.config.doc.createElement("div").tagName!=="DIV");return i;}()),shorthand:{"\\#(-?[_a-z0-9]+[-\\w\\uE000]*)":"[id=$1]","\\.(-?[_a-z]+[-\\w\\uE000]*)":"[className~=$1]"},operators:{"":function(j,i){return g.DOM.getAttribute(j,i)!=="";},"~=":"(?:^|\\s+){val}(?:\\s+|$)","|=":"^{val}-?"},pseudos:{"first-child":function(i){return g.DOM._children(i[h])[0]===i;}},_bruteQuery:function(n,r,t){var o=[],i=[],q=c._tokenize(n),m=q[q.length-1],s=g.DOM._getDoc(r),k,j,p,l;if(m){j=m.id;p=m.className;l=m.tagName||"*";if(r.getElementsByTagName){if(j&&(r.all||(r.nodeType===9||g.DOM.inDoc(r)))){i=g.DOM.allById(j,r);}else{if(p){i=r.getElementsByClassName(p);}else{i=r.getElementsByTagName(l);}}}else{k=r.firstChild;while(k){if(k.tagName&&(l==="*"||k.tagName===l)){i.push(k);}k=k.nextSibling||k.firstChild;}}if(i.length){o=c._filterNodes(i,q,t);}}return o;},_filterNodes:function(u,q,s){var z=0,y,A=q.length,t=A-1,p=[],w=u[0],D=w,B=g.Selector.getters,o,x,m,r,k,v,l,C;for(z=0;(D=w=u[z++]);){t=A-1;r=null;testLoop:while(D&&D.tagName){m=q[t];l=m.tests;y=l.length;if(y&&!k){while((C=l[--y])){o=C[1];if(B[C[0]]){v=B[C[0]](D,C[0]);}else{v=D[C[0]];if(C[0]==="tagName"&&!c._isXML){v=v.toUpperCase();}if(typeof v!="string"&&v!==undefined&&v.toString){v=v.toString();}else{if(v===undefined&&D.getAttribute){v=D.getAttribute(C[0],2);}}}if((o==="="&&v!==C[2])||(typeof o!=="string"&&o.test&&!o.test(v))||(!o.test&&typeof o==="function"&&!o(D,C[0],C[2]))){if((D=D[r])){while(D&&(!D.tagName||(m.tagName&&m.tagName!==D.tagName))){D=D[r];}}continue testLoop;}}}t--;if(!k&&(x=m.combinator)){r=x.axis;D=D[r];while(D&&!D.tagName){D=D[r];}if(x.direct){r=null;}}else{p.push(w);if(s){return p;}break;}}}w=D=null;return p;},combinators:{" ":{axis:"parentNode"},">":{axis:"parentNode",direct:true},"+":{axis:"previousSibling",direct:true}},_parsers:[{name:e,re:/^\uE003(-?[a-z]+[\w\-]*)+([~\|\^\$\*!=]=?)?['"]?([^\uE004'"]*)['"]?\uE004/i,fn:function(l,m){var k=l[2]||"",i=c.operators,j=(l[3])?l[3].replace(/\\/g,""):"",n;if((l[1]==="id"&&k==="=")||(l[1]==="className"&&g.config.doc.documentElement.getElementsByClassName&&(k==="~="||k==="="))){m.prefilter=l[1];l[3]=j;m[l[1]]=(l[1]==="id")?l[3]:j;}if(k in i){n=i[k];if(typeof n==="string"){l[3]=j.replace(c._reRegExpTokens,"\\$1");n=new RegExp(n.replace("{val}",l[3]));}l[2]=n;}if(!m.last||m.prefilter!==l[1]){return l.slice(1);}}},{name:d,re:/^((?:-?[_a-z]+[\w-]*)|\*)/i,fn:function(j,k){var i=j[1];if(!c._isXML){i=i.toUpperCase();}k.tagName=i;if(i!=="*"&&(!k.last||k.prefilter)){return[d,"=",i];}if(!k.prefilter){k.prefilter="tagName";}}},{name:a,re:/^\s*([>+~]|\s)\s*/,fn:function(i,j){}},{name:f,re:/^:([\-\w]+)(?:\uE005['"]?([^\uE005]*)['"]?\uE006)*/i,fn:function(i,j){var k=c[f][i[1]];if(k){if(i[2]){i[2]=i[2].replace(/\\/g,"");}return[i[2],k];}else{return false;}}}],_getToken:function(i){return{tagName:null,id:null,className:null,attributes:{},combinator:null,tests:[]};},_tokenize:function(l){l=l||"";l=c._replaceShorthand(g.Lang.trim(l));var k=c._getToken(),q=l,p=[],r=false,n,o,m,j;outer:do{r=false;for(m=0;(j=c._parsers[m++]);){if((n=j.re.exec(l))){if(j.name!==a){k.selector=l;}l=l.replace(n[0],"");if(!l.length){k.last=true;}if(c._attrFilters[n[1]]){n[1]=c._attrFilters[n[1]];}o=j.fn(n,k);if(o===false){r=false;break outer;}else{if(o){k.tests.push(o);}}if(!l.length||j.name===a){p.push(k);k=c._getToken(k);if(j.name===a){k.combinator=g.Selector.combinators[n[1]];}}r=true;}}}while(r&&l.length);if(!r||l.length){p=[];}return p;},_replaceShorthand:function(k){var m=c.shorthand,l=k.match(c._re.esc),n,q,p,o,j;if(l){k=k.replace(c._re.esc,"\uE000");}q=k.match(c._re.pseudos);if(q){k=k.replace(c._re.pseudos,"\uE002");}n=k.match(c._re.attr);if(n){k=k.replace(c._re.attr,"\uE001");}for(p in m){if(m.hasOwnProperty(p)){k=k.replace(new RegExp(p,"gi"),m[p]);}}if(n){for(o=0,j=n.length;o<j;++o){k=k.replace(/\uE001/,n[o]);}}if(q){for(o=0,j=q.length;o<j;++o){k=k.replace(/\uE002/,q[o]);}}k=k.replace(/\[/g,"\uE003");k=k.replace(/\]/g,"\uE004");k=k.replace(/\(/g,"\uE005");k=k.replace(/\)/g,"\uE006");if(l){for(o=0,j=l.length;o<j;++o){k=k.replace("\uE000",l[o]);}}return k;},_attrFilters:{"class":"className","for":"htmlFor"},getters:{href:function(j,i){return g.DOM.getAttribute(j,i);},id:function(j,i){return g.DOM.getId(j);}}};g.mix(g.Selector,b,true);g.Selector.getters.src=g.Selector.getters.rel=g.Selector.getters.href;if(g.Selector.useNative&&g.config.doc.querySelector){g.Selector.shorthand["\\.(-?[_a-z]+[-\\w]*)"]="[class~=$1]";}},"@VERSION@",{requires:["selector-native"]});
  1
+YUI.add("selector-css2",function(g){var h="parentNode",d="tagName",e="attributes",a="combinator",f="pseudos",c=g.Selector,b={_reRegExpTokens:/([\^\$\?\[\]\*\+\-\.\(\)\|\\])/,SORT_RESULTS:true,_isXML:(function(){var i=(g.config.doc.createElement("div").tagName!=="DIV");return i;}()),shorthand:{"\\#(-?[_a-z0-9]+[-\\w\\uE000]*)":"[id=$1]","\\.(-?[_a-z]+[-\\w\\uE000]*)":"[className~=$1]"},operators:{"":function(j,i){return g.DOM.getAttribute(j,i)!=="";},"~=":"(?:^|\\s+){val}(?:\\s+|$)","|=":"^{val}-?"},pseudos:{"first-child":function(i){return g.DOM._children(i[h])[0]===i;}},_bruteQuery:function(n,r,t){var o=[],i=[],q=c._tokenize(n),m=q[q.length-1],s=g.DOM._getDoc(r),k,j,p,l;if(m){j=m.id;p=m.className;l=m.tagName||"*";if(r.getElementsByTagName){if(j&&(r.all||(r.nodeType===9||g.DOM.inDoc(r)))){i=g.DOM.allById(j,r);}else{if(p){i=r.getElementsByClassName(p);}else{i=r.getElementsByTagName(l);}}}else{k=r.firstChild;while(k){if(k.tagName&&(l==="*"||k.tagName===l)){i.push(k);}k=k.nextSibling||k.firstChild;}}if(i.length){o=c._filterNodes(i,q,t);}}return o;},_filterNodes:function(u,q,s){var z=0,y,A=q.length,t=A-1,p=[],w=u[0],D=w,B=g.Selector.getters,o,x,m,r,k,v,l,C;for(z=0;(D=w=u[z++]);){t=A-1;r=null;testLoop:while(D&&D.tagName){m=q[t];l=m.tests;y=l.length;if(y&&!k){while((C=l[--y])){o=C[1];if(B[C[0]]){v=B[C[0]](D,C[0]);}else{v=D[C[0]];if(C[0]==="tagName"&&!c._isXML){v=v.toUpperCase();}if(typeof v!="string"&&v!==undefined&&v.toString){v=v.toString();}else{if(v===undefined&&D.getAttribute){v=D.getAttribute(C[0],2);}}}if((o==="="&&v!==C[2])||(typeof o!=="string"&&o.test&&!o.test(v))||(!o.test&&typeof o==="function"&&!o(D,C[0],C[2]))){if((D=D[r])){while(D&&(!D.tagName||(m.tagName&&m.tagName!==D.tagName))){D=D[r];}}continue testLoop;}}}t--;if(!k&&(x=m.combinator)){r=x.axis;D=D[r];while(D&&!D.tagName){D=D[r];}if(x.direct){r=null;}}else{p.push(w);if(s){return p;}break;}}}w=D=null;return p;},combinators:{" ":{axis:"parentNode"},">":{axis:"parentNode",direct:true},"+":{axis:"previousSibling",direct:true}},_parsers:[{name:e,re:/^\uE003(-?[a-z]+[\w\-]*)+([~\|\^\$\*!=]=?)?['"]?([^\uE004'"]*)['"]?\uE004/i,fn:function(l,m){var k=l[2]||"",i=c.operators,j=(l[3])?l[3].replace(/\\/g,""):"",n;if((l[1]==="id"&&k==="=")||(l[1]==="className"&&g.config.doc.documentElement.getElementsByClassName&&(k==="~="||k==="="))){m.prefilter=l[1];l[3]=j;m[l[1]]=(l[1]==="id")?l[3]:j;}if(k in i){n=i[k];if(typeof n==="string"){l[3]=j.replace(c._reRegExpTokens,"\\$1");n=new RegExp(n.replace("{val}",l[3]));}l[2]=n;}if(!m.last||m.prefilter!==l[1]){return l.slice(1);}}},{name:d,re:/^((?:-?[_a-z]+[\w-]*)|\*)/i,fn:function(j,k){var i=j[1];if(!c._isXML){i=i.toUpperCase();}k.tagName=i;if(i!=="*"&&(!k.last||k.prefilter)){return[d,"=",i];}if(!k.prefilter){k.prefilter="tagName";}}},{name:a,re:/^\s*([>+~]|\s)\s*/,fn:function(i,j){}},{name:f,re:/^:([\-\w]+)(?:\uE005['"]?([^\uE005]*)['"]?\uE006)*/i,fn:function(i,j){var k=c[f][i[1]];if(k){if(i[2]){i[2]=i[2].replace(/\\/g,"");}return[i[2],k];}else{return false;}}}],_getToken:function(i){return{tagName:null,id:null,className:null,attributes:{},combinator:null,tests:[]};},_tokenize:function(l){l=l||"";l=c._parseSelector(g.Lang.trim(l));var k=c._getToken(),q=l,p=[],r=false,n,o,m,j;outer:do{r=false;for(m=0;(j=c._parsers[m++]);){if((n=j.re.exec(l))){if(j.name!==a){k.selector=l;}l=l.replace(n[0],"");if(!l.length){k.last=true;}if(c._attrFilters[n[1]]){n[1]=c._attrFilters[n[1]];}o=j.fn(n,k);if(o===false){r=false;break outer;}else{if(o){k.tests.push(o);}}if(!l.length||j.name===a){p.push(k);k=c._getToken(k);if(j.name===a){k.combinator=g.Selector.combinators[n[1]];}}r=true;}}}while(r&&l.length);if(!r||l.length){p=[];}return p;},_replaceMarkers:function(i){i=i.replace(/\[/g,"\uE003");i=i.replace(/\]/g,"\uE004");i=i.replace(/\(/g,"\uE005");i=i.replace(/\)/g,"\uE006");return i;},_replaceShorthand:function(i){var j=g.Selector.shorthand,k;for(k in j){if(j.hasOwnProperty(k)){i=i.replace(new RegExp(k,"gi"),j[k]);}}return i;},_parseSelector:function(i){var j=g.Selector._replaceSelector(i),i=j.selector;i=g.Selector._replaceShorthand(i);i=g.Selector._restore("attr",i,j.attrs);i=g.Selector._restore("pseudo",i,j.pseudos);i=g.Selector._replaceMarkers(i);i=g.Selector._restore("esc",i,j.esc);return i;},_attrFilters:{"class":"className","for":"htmlFor"},getters:{href:function(j,i){return g.DOM.getAttribute(j,i);},id:function(j,i){return g.DOM.getId(j);}}};g.mix(g.Selector,b,true);g.Selector.getters.src=g.Selector.getters.rel=g.Selector.getters.href;if(g.Selector.useNative&&g.config.doc.querySelector){g.Selector.shorthand["\\.(-?[_a-z]+[-\\w]*)"]="[class~=$1]";}},"@VERSION@",{requires:["selector-native"]});
70  build/selector-css2/selector-css2.js
@@ -22,11 +22,6 @@ var PARENT_NODE = 'parentNode',
22 22
     SelectorCSS2 = {
23 23
         _reRegExpTokens: /([\^\$\?\[\]\*\+\-\.\(\)\|\\])/,
24 24
         SORT_RESULTS: true,
25  
-        _re: {
26  
-            attr: /(\[[^\]]*\])/g,
27  
-            esc: /\\[:\[\]\(\)#\.\'\>+~"]/gi,
28  
-            pseudos: /(\([^\)]*\))/g
29  
-        },
30 25
 
31 26
         // TODO: better detection, document specific
32 27
         _isXML: (function() {
@@ -319,7 +314,7 @@ var PARENT_NODE = 'parentNode',
319 314
          */
320 315
         _tokenize: function(selector) {
321 316
             selector = selector || '';
322  
-            selector = Selector._replaceShorthand(Y.Lang.trim(selector)); 
  317
+            selector = Selector._parseSelector(Y.Lang.trim(selector)); 
323 318
             var token = Selector._getToken(),     // one token per simple selector (left selector holds combinator)
324 319
                 query = selector, // original query for debug report
325 320
                 tokens = [],    // array of tokens
@@ -379,28 +374,18 @@ var PARENT_NODE = 'parentNode',
379 374
             return tokens;
380 375
         },
381 376
 
382  
-        _replaceShorthand: function(selector) {
383  
-            var shorthand = Selector.shorthand,
384  
-                esc = selector.match(Selector._re.esc), // pull escaped colon, brackets, etc. 
385  
-                attrs,
386  
-                pseudos,
387  
-                re, i, len;
388  
-
389  
-            if (esc) {
390  
-                selector = selector.replace(Selector._re.esc, '\uE000');
391  
-            }
392  
-
393  
-            pseudos = selector.match(Selector._re.pseudos);
394  
-
395  
-            if (pseudos) {
396  
-                selector = selector.replace(Selector._re.pseudos, '\uE002');
397  
-            }
  377
+        _replaceMarkers: function(selector) {
  378
+            selector = selector.replace(/\[/g, '\uE003');
  379
+            selector = selector.replace(/\]/g, '\uE004');
398 380
 
399  
-            attrs = selector.match(Selector._re.attr);
  381
+            selector = selector.replace(/\(/g, '\uE005');
  382
+            selector = selector.replace(/\)/g, '\uE006');
  383
+            return selector;
  384
+        },
400 385
 
401  
-            if (attrs) {
402  
-                selector = selector.replace(Selector._re.attr, '\uE001');
403  
-            }
  386
+        _replaceShorthand: function(selector) {
  387
+            var shorthand = Y.Selector.shorthand,
  388
+                re;
404 389
 
405 390
             for (re in shorthand) {
406 391
                 if (shorthand.hasOwnProperty(re)) {
@@ -408,29 +393,24 @@ var PARENT_NODE = 'parentNode',
408 393
                 }
409 394
             }
410 395
 
411  
-            if (attrs) {
412  
-                for (i = 0, len = attrs.length; i < len; ++i) {
413  
-                    selector = selector.replace(/\uE001/, attrs[i]);
414  
-                }
415  
-            }
  396
+            return selector;
  397
+        },
416 398
 
417  
-            if (pseudos) {
418  
-                for (i = 0, len = pseudos.length; i < len; ++i) {
419  
-                    selector = selector.replace(/\uE002/, pseudos[i]);
420  
-                }
421  
-            }
  399
+        _parseSelector: function(selector) {
  400
+            var replaced = Y.Selector._replaceSelector(selector),
  401
+                selector = replaced.selector;
422 402
 
423  
-            selector = selector.replace(/\[/g, '\uE003');
424  
-            selector = selector.replace(/\]/g, '\uE004');
  403
+            // replace shorthand (".foo, #bar") after pseudos and attrs
  404
+            // to avoid replacing unescaped chars
  405
+            selector = Y.Selector._replaceShorthand(selector);
425 406
 
426  
-            selector = selector.replace(/\(/g, '\uE005');
427  
-            selector = selector.replace(/\)/g, '\uE006');
  407
+            selector = Y.Selector._restore('attr', selector, replaced.attrs);
  408
+            selector = Y.Selector._restore('pseudo', selector, replaced.pseudos);
428 409
 
429  
-            if (esc) {
430  
-                for (i = 0, len = esc.length; i < len; ++i) {
431  
-                    selector = selector.replace('\uE000', esc[i]);
432  
-                }
433  
-            }
  410
+            // replace braces and parens before restoring escaped chars
  411
+            // to avoid replacing ecaped markers
  412
+            selector = Y.Selector._replaceMarkers(selector);
  413
+            selector = Y.Selector._restore('esc', selector, replaced.esc);
434 414
 
435 415
             return selector;
436 416
         },
84  build/selector-native/selector-native-debug.js
@@ -21,6 +21,23 @@ var COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
21 21
     OWNER_DOCUMENT = 'ownerDocument';
22 22
 
23 23
 var Selector = {
  24
+    _types: {
  25
+        esc: {
  26
+            token: '\uE000',
  27
+            re: /\\[:\[\]\(\)#\.\'\>+~"]/gi
  28
+        },
  29
+
  30
+        attr: {
  31
+            token: '\uE001',
  32
+            re: /(\[[^\]]*\])/g
  33
+        },
  34
+
  35
+        pseudo: {
  36
+            token: '\uE002',
  37
+            re: /(\([^\)]*\))/g
  38
+        }
  39
+    },
  40
+
24 41
     useNative: true,
25 42
 
26 43
     _escapeId: function(id) {
@@ -142,10 +159,55 @@ var Selector = {
142 159
 
143 160
     },
144 161
 
  162
+    _replaceSelector: function(selector) {
  163
+        var esc = Y.Selector._parse('esc', selector), // pull escaped colon, brackets, etc. 
  164
+            attrs,
  165
+            pseudos;
  166
+
  167
+        // first replace escaped chars, which could be present in attrs or pseudos
  168
+        selector = Y.Selector._replace('esc', selector);
  169
+
  170
+        // then replace pseudos before attrs to avoid replacing :not([foo])
  171
+        pseudos = Y.Selector._parse('pseudo', selector);
  172
+        selector = Selector._replace('pseudo', selector);
  173
+
  174
+        attrs = Y.Selector._parse('attr', selector);
  175
+        selector = Y.Selector._replace('attr', selector);
  176
+
  177
+        return {
  178
+            esc: esc,
  179
+            attrs: attrs,
  180
+            pseudos: pseudos,
  181
+            selector: selector
  182
+        }
  183
+    },
  184
+
  185
+    _restoreSelector: function(replaced) {
  186
+        var selector = replaced.selector;
  187
+        selector = Y.Selector._restore('attr', selector, replaced.attrs);
  188
+        selector = Y.Selector._restore('pseudo', selector, replaced.pseudos);
  189
+        selector = Y.Selector._restore('esc', selector, replaced.esc);
  190
+        return selector;
  191
+    },
  192
+
  193
+    _replaceCommas: function(selector) {
  194
+        var replaced = Y.Selector._replaceSelector(selector),
  195
+            selector = replaced.selector;
  196
+
  197
+        if (selector) {
  198
+            selector = selector.replace(',', '\uE007', 'g');
  199
+            replaced.selector = selector;
  200
+            selector = Y.Selector._restoreSelector(replaced);
  201
+        }
  202
+        return selector;
  203
+    },
  204
+
145 205
     // allows element scoped queries to begin with combinator
146 206
     // e.g. query('> p', document.body) === query('body > p')
147 207
     _splitQueries: function(selector, node) {
148  
-        var groups = selector.split(','),
  208
+        // avoid picking up from attrs and pseudos
  209
+        selector = Y.Selector._replaceCommas(selector);
  210
+        var groups = selector.split('\uE007'),
149 211
             queries = [],
150 212
             prefix = '',
151 213
             id,
@@ -280,6 +342,26 @@ var Selector = {
280 342
         return Y.DOM.ancestor(element, function(n) {
281 343
             return Y.Selector.test(n, selector);
282 344
         }, testSelf);
  345
+    },
  346
+
  347
+    _parse: function(name, selector) {
  348
+        return selector.match(Y.Selector._types[name].re);
  349
+    },
  350
+
  351
+    _replace: function(name, selector) {
  352
+        var o = Y.Selector._types[name];
  353
+        return selector.replace(o.re, o.token);
  354
+    },
  355
+
  356
+    _restore: function(name, selector, items) {
  357
+        if (items) {
  358
+            var token = Y.Selector._types[name].token,
  359
+                i, len;
  360
+            for (i = 0, len = items.length; i < len; ++i) {
  361
+                selector = selector.replace(token, items[i]);
  362
+            }
  363
+        }
  364
+        return selector;
283 365
     }
284 366
 };
285 367
 
2  build/selector-native/selector-native-min.js
... ...
@@ -1 +1 @@
1  
-YUI.add("selector-native",function(a){(function(e){e.namespace("Selector");var c="compareDocumentPosition",d="ownerDocument";var b={useNative:true,_escapeId:function(f){if(f){f=f.replace(/([:\[\]\(\)#\.'<>+~"])/g,"\\$1");}return f;},_compare:("sourceIndex" in e.config.doc.documentElement)?function(i,h){var g=i.sourceIndex,f=h.sourceIndex;if(g===f){return 0;}else{if(g>f){return 1;}}return -1;}:(e.config.doc.documentElement[c]?function(g,f){if(g[c](f)&4){return -1;}else{return 1;}}:function(j,i){var h,f,g;if(j&&i){h=j[d].createRange();h.setStart(j,0);f=i[d].createRange();f.setStart(i,0);g=h.compareBoundaryPoints(1,f);}return g;}),_sort:function(f){if(f){f=e.Array(f,0,true);if(f.sort){f.sort(b._compare);}}return f;},_deDupe:function(f){var g=[],h,j;for(h=0;(j=f[h++]);){if(!j._found){g[g.length]=j;j._found=true;}}for(h=0;(j=g[h++]);){j._found=null;j.removeAttribute("_found");}return g;},query:function(g,o,p,f){o=o||e.config.doc;var l=[],h=(e.Selector.useNative&&e.config.doc.querySelector&&!f),k=[[g,o]],m,q,j,n=(h)?e.Selector._nativeQuery:e.Selector._bruteQuery;if(g&&n){if(!f&&(!h||o.tagName)){k=b._splitQueries(g,o);}for(j=0;(m=k[j++]);){q=n(m[0],m[1],p);if(!p){q=e.Array(q,0,true);}if(q){l=l.concat(q);}}if(k.length>1){l=b._sort(b._deDupe(l));}}return(p)?(l[0]||null):l;},_splitQueries:function(h,l){var g=h.split(","),j=[],m="",n,k,f;if(l){if(l.nodeType===1){n=e.Selector._escapeId(e.DOM.getId(l));if(!n){n=e.guid();e.DOM.setId(l,n);}m='[id="'+n+'"] ';}for(k=0,f=g.length;k<f;++k){h=m+g[k];j.push([h,l]);}}return j;},_nativeQuery:function(f,g,h){if(e.UA.webkit&&f.indexOf(":checked")>-1&&(e.Selector.pseudos&&e.Selector.pseudos.checked)){return e.Selector.query(f,g,h,true);}try{return g["querySelector"+(h?"":"All")](f);}catch(i){return e.Selector.query(f,g,h,true);}},filter:function(g,f){var h=[],j,k;if(g&&f){for(j=0;(k=g[j++]);){if(e.Selector.test(k,f)){h[h.length]=k;}}}else{}return h;},test:function(k,l,q){var o=false,g=false,h,r,u,p,t,f,n,m,s;if(k&&k.tagName){if(typeof l=="function"){o=l.call(k,k);}else{h=l.split(",");if(!q&&!e.DOM.inDoc(k)){r=k.parentNode;if(r){q=r;}else{t=k[d].createDocumentFragment();t.appendChild(k);q=t;g=true;}}q=q||k[d];f=e.Selector._escapeId(e.DOM.getId(k));if(!f){f=e.guid();e.DOM.setId(k,f);}for(n=0;(s=h[n++]);){s+='[id="'+f+'"]';p=e.Selector.query(s,q);for(m=0;u=p[m++];){if(u===k){o=true;break;}}if(o){break;}}if(g){t.removeChild(k);}}}return o;},ancestor:function(g,f,h){return e.DOM.ancestor(g,function(i){return e.Selector.test(i,f);},h);}};e.mix(e.Selector,b,true);})(a);},"@VERSION@",{requires:["dom-base"]});
  1
+YUI.add("selector-native",function(a){(function(e){e.namespace("Selector");var c="compareDocumentPosition",d="ownerDocument";var b={_types:{esc:{token:"\uE000",re:/\\[:\[\]\(\)#\.\'\>+~"]/gi},attr:{token:"\uE001",re:/(\[[^\]]*\])/g},pseudo:{token:"\uE002",re:/(\([^\)]*\))/g}},useNative:true,_escapeId:function(f){if(f){f=f.replace(/([:\[\]\(\)#\.'<>+~"])/g,"\\$1");}return f;},_compare:("sourceIndex" in e.config.doc.documentElement)?function(i,h){var g=i.sourceIndex,f=h.sourceIndex;if(g===f){return 0;}else{if(g>f){return 1;}}return -1;}:(e.config.doc.documentElement[c]?function(g,f){if(g[c](f)&4){return -1;}else{return 1;}}:function(j,i){var h,f,g;if(j&&i){h=j[d].createRange();h.setStart(j,0);f=i[d].createRange();f.setStart(i,0);g=h.compareBoundaryPoints(1,f);}return g;}),_sort:function(f){if(f){f=e.Array(f,0,true);if(f.sort){f.sort(b._compare);}}return f;},_deDupe:function(f){var g=[],h,j;for(h=0;(j=f[h++]);){if(!j._found){g[g.length]=j;j._found=true;}}for(h=0;(j=g[h++]);){j._found=null;j.removeAttribute("_found");}return g;},query:function(g,o,p,f){o=o||e.config.doc;var l=[],h=(e.Selector.useNative&&e.config.doc.querySelector&&!f),k=[[g,o]],m,q,j,n=(h)?e.Selector._nativeQuery:e.Selector._bruteQuery;if(g&&n){if(!f&&(!h||o.tagName)){k=b._splitQueries(g,o);}for(j=0;(m=k[j++]);){q=n(m[0],m[1],p);if(!p){q=e.Array(q,0,true);}if(q){l=l.concat(q);}}if(k.length>1){l=b._sort(b._deDupe(l));}}return(p)?(l[0]||null):l;},_replaceSelector:function(f){var g=e.Selector._parse("esc",f),h,i;f=e.Selector._replace("esc",f);i=e.Selector._parse("pseudo",f);f=b._replace("pseudo",f);h=e.Selector._parse("attr",f);f=e.Selector._replace("attr",f);return{esc:g,attrs:h,pseudos:i,selector:f};},_restoreSelector:function(g){var f=g.selector;f=e.Selector._restore("attr",f,g.attrs);f=e.Selector._restore("pseudo",f,g.pseudos);f=e.Selector._restore("esc",f,g.esc);return f;},_replaceCommas:function(f){var g=e.Selector._replaceSelector(f),f=g.selector;if(f){f=f.replace(",","\uE007","g");g.selector=f;f=e.Selector._restoreSelector(g);}return f;},_splitQueries:function(h,l){h=e.Selector._replaceCommas(h);var g=h.split("\uE007"),j=[],m="",n,k,f;if(l){if(l.nodeType===1){n=e.Selector._escapeId(e.DOM.getId(l));if(!n){n=e.guid();e.DOM.setId(l,n);}m='[id="'+n+'"] ';}for(k=0,f=g.length;k<f;++k){h=m+g[k];j.push([h,l]);}}return j;},_nativeQuery:function(f,g,h){if(e.UA.webkit&&f.indexOf(":checked")>-1&&(e.Selector.pseudos&&e.Selector.pseudos.checked)){return e.Selector.query(f,g,h,true);}try{return g["querySelector"+(h?"":"All")](f);}catch(i){return e.Selector.query(f,g,h,true);}},filter:function(g,f){var h=[],j,k;if(g&&f){for(j=0;(k=g[j++]);){if(e.Selector.test(k,f)){h[h.length]=k;}}}else{}return h;},test:function(k,l,q){var o=false,g=false,h,r,u,p,t,f,n,m,s;if(k&&k.tagName){if(typeof l=="function"){o=l.call(k,k);}else{h=l.split(",");if(!q&&!e.DOM.inDoc(k)){r=k.parentNode;if(r){q=r;}else{t=k[d].createDocumentFragment();t.appendChild(k);q=t;g=true;}}q=q||k[d];f=e.Selector._escapeId(e.DOM.getId(k));if(!f){f=e.guid();e.DOM.setId(k,f);}for(n=0;(s=h[n++]);){s+='[id="'+f+'"]';p=e.Selector.query(s,q);for(m=0;u=p[m++];){if(u===k){o=true;break;}}if(o){break;}}if(g){t.removeChild(k);}}}return o;},ancestor:function(g,f,h){return e.DOM.ancestor(g,function(i){return e.Selector.test(i,f);},h);},_parse:function(g,f){return f.match(e.Selector._types[g].re);},_replace:function(g,f){var h=e.Selector._types[g];return f.replace(h.re,h.token);},_restore:function(j,g,h){if(h){var l=e.Selector._types[j].token,k,f;for(k=0,f=h.length;k<f;++k){g=g.replace(l,h[k]);}}return g;}};e.mix(e.Selector,b,true);})(a);},"@VERSION@",{requires:["dom-base"]});
84  build/selector-native/selector-native.js
@@ -21,6 +21,23 @@ var COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
21 21
     OWNER_DOCUMENT = 'ownerDocument';
22 22
 
23 23
 var Selector = {
  24
+    _types: {
  25
+        esc: {
  26
+            token: '\uE000',
  27
+            re: /\\[:\[\]\(\)#\.\'\>+~"]/gi
  28
+        },
  29
+
  30
+        attr: {
  31
+            token: '\uE001',
  32
+            re: /(\[[^\]]*\])/g
  33
+        },
  34
+
  35
+        pseudo: {
  36
+            token: '\uE002',
  37
+            re: /(\([^\)]*\))/g
  38
+        }
  39
+    },
  40
+
24 41
     useNative: true,
25 42
 
26 43
     _escapeId: function(id) {
@@ -141,10 +158,55 @@ var Selector = {
141 158
 
142 159
     },
143 160
 
  161
+    _replaceSelector: function(selector) {
  162
+        var esc = Y.Selector._parse('esc', selector), // pull escaped colon, brackets, etc. 
  163
+            attrs,
  164
+            pseudos;
  165
+
  166
+        // first replace escaped chars, which could be present in attrs or pseudos
  167
+        selector = Y.Selector._replace('esc', selector);
  168
+
  169
+        // then replace pseudos before attrs to avoid replacing :not([foo])
  170
+        pseudos = Y.Selector._parse('pseudo', selector);
  171
+        selector = Selector._replace('pseudo', selector);
  172
+
  173
+        attrs = Y.Selector._parse('attr', selector);
  174
+        selector = Y.Selector._replace('attr', selector);
  175
+
  176
+        return {
  177
+            esc: esc,
  178
+            attrs: attrs,
  179
+            pseudos: pseudos,
  180
+            selector: selector
  181
+        }
  182
+    },
  183
+
  184
+    _restoreSelector: function(replaced) {
  185
+        var selector = replaced.selector;
  186
+        selector = Y.Selector._restore('attr', selector, replaced.attrs);
  187
+        selector = Y.Selector._restore('pseudo', selector, replaced.pseudos);
  188
+        selector = Y.Selector._restore('esc', selector, replaced.esc);
  189
+        return selector;
  190
+    },
  191
+
  192
+    _replaceCommas: function(selector) {
  193
+        var replaced = Y.Selector._replaceSelector(selector),
  194
+            selector = replaced.selector;
  195
+
  196
+        if (selector) {
  197
+            selector = selector.replace(',', '\uE007', 'g');
  198
+            replaced.selector = selector;
  199
+            selector = Y.Selector._restoreSelector(replaced);
  200
+        }
  201
+        return selector;
  202
+    },
  203
+
144 204
     // allows element scoped queries to begin with combinator
145 205
     // e.g. query('> p', document.body) === query('body > p')
146 206
     _splitQueries: function(selector, node) {
147  
-        var groups = selector.split(','),
  207
+        // avoid picking up from attrs and pseudos
  208
+        selector = Y.Selector._replaceCommas(selector);
  209
+        var groups = selector.split('\uE007'),
148 210
             queries = [],
149 211
             prefix = '',
150 212
             id,
@@ -275,6 +337,26 @@ var Selector = {
275 337
         return Y.DOM.ancestor(element, function(n) {
276 338
             return Y.Selector.test(n, selector);
277 339
         }, testSelf);
  340
+    },
  341
+
  342
+    _parse: function(name, selector) {
  343
+        return selector.match(Y.Selector._types[name].re);
  344
+    },
  345
+
  346
+    _replace: function(name, selector) {
  347
+        var o = Y.Selector._types[name];
  348
+        return selector.replace(o.re, o.token);
  349
+    },
  350
+
  351
+    _restore: function(name, selector, items) {
  352
+        if (items) {
  353
+            var token = Y.Selector._types[name].token,
  354
+                i, len;
  355
+            for (i = 0, len = items.length; i < len; ++i) {
  356
+                selector = selector.replace(token, items[i]);
  357
+            }
  358
+        }
  359
+        return selector;
278 360
     }
279 361
 };
280 362
 
219  src/base/tests/base-core.html
@@ -219,7 +219,7 @@
219 219
 
220 220
                 initOnly : {
221 221
                     writeOnce:"initOnly"
222  
-                }    
  222
+                }
223 223
             };
224 224
 
225 225
             Y.extend(AttrHost, Y.BaseCore);
@@ -344,9 +344,220 @@
344 344
                }
345 345
             });
346 346
 
  347
+            function CoreTestsHost(config) {
  348
+                CoreTestsHost.superclass.constructor.apply(this, arguments);
  349
+            }
  350
+
  351
+            CoreTestsHost.NAME = "coreTestsHost";
  352
+            CoreTestsHost.ATTRS = {
  353
+                cloneDefaultObject : {
  354
+                    value : {
  355
+                        a:1, 
  356
+                        b:2, 
  357
+                        c:3
  358
+                    }
  359
+                },
  360
+
  361
+                cloneDefaultArray : {
  362
+                    value : ["foo", "bar", "foobar"]
  363
+                },
  364
+                
  365
+                cloneDefaultString : {
  366
+                    value : "foo"
  367
+                },
  368
+
  369
+                cloneDefaultOverride : {
  370
+                    value : {
  371
+                        a:1, b:2, c:3
  372
+                    },
  373
+                    cloneDefaultValue : false
  374
+                },
  375
+
  376
+                cloneDefaultShallow : {
  377
+                    value : {
  378
+                        a: {foo: "bar"}
  379
+                    },
  380
+                    cloneDefaultValue : "shallow"
  381
+                },
  382
+
  383
+                cloneDefaultDeep : {
  384
+                    value : {
  385
+                        a: {foo: "bar"}
  386
+                    },
  387
+                    cloneDefaultValue : "deep"
  388
+                },
  389
+
  390
+                cloneDefaultComplex : {
  391
+                    value : new Y.BaseCore()
  392
+                }
  393
+            };
  394
+            Y.extend(CoreTestsHost, Y.BaseCore);
  395
+
  396
+            var coreTemplate = {
  397
+
  398
+                name: "Core Tests",
  399
+
  400
+                testInit : function() {
  401
+                    var h = new CoreTestsHost();
  402
+                    Y.Assert.isTrue(h.get("initialized"));
  403
+                },
  404
+
  405
+                testDestroy : function() {
  406
+                    var h = new CoreTestsHost();
  407
+                    
  408
+                    Y.Assert.isFalse(h.get("destroyed"));
  409
+
  410
+                    h.destroy();
  411
+
  412
+                    Y.Assert.isTrue(h.get("destroyed"));
  413
+                },
  414
+
  415
+                testToString : function() {
  416
+                    var h = new CoreTestsHost(),
  417
+                        re = /^coreTestsHost\[.*?\]$/,
  418
+                        str = h.toString();
  419
+
  420
+                    Y.Assert.isTrue(re.test(str));                    
  421
+                },
  422
+
  423
+                testCloneDefaultValueObject : function() {
  424
+                    var h = new CoreTestsHost(),
  425
+                        val = h.get("cloneDefaultObject");
  426
+
  427
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultObject.value !== val);
  428
+
  429
+                    Y.ObjectAssert.areEqual({
  430
+                        a:1,
  431
+                        b:2,
  432
+                        c:3
  433
+                    }, val);
  434
+                },
  435
+
  436
+                testCloneDefaultValueArray : function() {
  437
+                    var h = new CoreTestsHost(),
  438
+                        val = h.get("cloneDefaultArray");
  439
+
  440
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultArray.value !== val);
  441
+                    Y.ArrayAssert.itemsAreEqual(["foo", "bar", "foobar"], val);
  442
+                },
  443
+
  444
+                testCloneDefaultValueString : function() {
  445
+                    var h = new CoreTestsHost(),
  446
+                        val = h.get("cloneDefaultString");
  447
+
  448
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultString.value === val);
  449
+                },
  450
+
  451
+                testCloneDefaultComplex : function() {
  452
+                    var h = new CoreTestsHost(),
  453
+                        val = h.get("cloneDefaultComplex");
  454
+
  455
+                    // Don't try to clone by default. We may hurt our backs
  456
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultComplex.value === val);
  457
+                },
  458
+
  459
+                testCloneDefaultShallow : function() {
  460
+                    var h = new CoreTestsHost(),
  461
+                        val = h.get("cloneDefaultShallow");
  462
+
  463
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultShallow.value !== val);
  464
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultShallow.value.a === val.a);
  465
+                    
  466
+                    Y.ObjectAssert.areEqual({
  467
+                        foo:"bar"
  468
+                    }, val.a);
  469
+                },
  470
+
  471
+                testCloneDefaultDeep : function() {
  472
+                    var h = new CoreTestsHost(),
  473
+                        val = h.get("cloneDefaultDeep");
  474
+
  475
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultDeep.value !== val);
  476
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultDeep.value.a !== val.a);
  477
+                    
  478
+                    Y.ObjectAssert.areEqual({
  479
+                        foo:"bar"
  480
+                    }, val.a);
  481
+                },
  482
+
  483
+                testCloneDefaultOverride : function() {
  484
+                    var h = new CoreTestsHost(),
  485
+                        val = h.get("cloneDefaultOverride");
  486
+
  487
+                    Y.Assert.isTrue(CoreTestsHost.ATTRS.cloneDefaultOverride.value === val);
  488
+
  489
+                    Y.ObjectAssert.areEqual({
  490
+                        a:1,
  491
+                        b:2,
  492
+                        c:3
  493
+                    }, val);
  494
+                },
  495
+
  496
+                testInitializerDestructorInvocation : function() {
  497
+
  498
+                    var expected = ["beforeConstructorTwo", "beforeConstructorOne", "initializerOne", "initializerTwo", "afterConstructorOne", "afterConstructorTwo", "destructorTwo", "destructorOne"],
  499
+                        actual = [],
  500
+                        initCfg = {
  501
+                            foo: 1
  502
+                        };
  503
+
  504
+                    function One(cfg) {
  505
+                        actual.push("beforeConstructorOne");
  506
+                        One.superclass.constructor.apply(this, arguments);
  507
+                        actual.push("afterConstructorOne");
  508
+                    }
  509
+
  510
+                    Y.extend(One, Y.BaseCore, {
  511
+                        initializer : function(cfg) {
  512
+                            Y.Assert.areSame(initCfg, cfg);
  513
+                            actual.push("initializerOne");
  514
+                        },
  515
+                        destructor : function() {
  516
+                            actual.push("destructorOne");
  517
+                        }
  518
+                    }, {
  519
+                        NAME : "one",
  520
+                        ATTRS : {
  521
+                            "a" : {
  522
+                                value: 1
  523
+                            }                        
  524
+                        }
  525
+                    });
  526
+
  527
+                    function Two(cfg) {
  528
+                        actual.push("beforeConstructorTwo");
  529
+                        Two.superclass.constructor.apply(this, arguments);
  530
+                        actual.push("afterConstructorTwo");
  531
+                    }
  532
+
  533
+                    Y.extend(Two, One, {
  534
+                        initializer : function(cfg) {
  535
+                            Y.Assert.areSame(initCfg, cfg);
  536
+                            actual.push("initializerTwo");
  537
+                        },
  538
+                        destructor : function() {
  539
+                            actual.push("destructorTwo");
  540
+                        }
  541
+                    }, {
  542
+                        NAME : "two",
  543
+                        ATTRS : {
  544
+                            "b" : {
  545
+                                value: 2
  546
+                            }                        
  547
+                        }
  548
+                    });
  549
+                    
  550
+                    var o = new Two(initCfg);
  551
+                    o.destroy();
  552
+
  553
+                    Y.ArrayAssert.itemsAreEqual(expected, actual);                    
  554
+
  555
+                }
  556
+            };
  557
+
347 558
             var basicTemplate = {
348 559
 
349  
-                name: "Core Base Class Tests",
  560
+                name: "Base Class Tests",
350 561
 
351 562
                 createHost : function(cfg) {
352 563
                     return new AttrHost(cfg);
@@ -654,7 +865,7 @@
654 865
 
655 866
             var extendedTemplate = {
656 867
 
657  
-                name: "Core Extended Class Tests",
  868
+                name: "Extended Class Tests",
658 869
 
659 870
                 createHost : function(cfg) {
660 871
                     return new ExtendedAttrHost(cfg);
@@ -969,6 +1180,8 @@
969 1180
 
970 1181
             var suite = new Y.Test.Suite({name:"Base Core Unit Tests"});
971 1182
 
  1183
+            suite.add(new Y.Test.Case(coreTemplate));
  1184
+
972 1185
             suite.add(new Y.Test.Case(basicTemplate));
973 1186
             suite.add(new Y.Test.Case(extendedTemplate));
974 1187
 
472  src/base/tests/base.html
@@ -43,9 +43,134 @@
43 43
 
44 44
     // NOTE: Attribute's unit tests cover a large section of Base's functionality when it comes to dealing with attributes.
45 45
 
  46
+    function EventTests(config) {
  47
+        EventTests.superclass.constructor.apply(this, arguments);
  48
+    }
  49
+
  50
+    EventTests.NAME = "eventTestsHost";
  51
+
  52
+    EventTests.ATTRS = {
  53
+        attr1 : {
  54
+            value: "foo"
  55
+        }
  56
+    };
  57
+
  58
+    Y.extend(EventTests, Y.Base);
  59
+
46 60
     var suite = new Y.Test.Suite("Base Tests");
47 61
 
48 62
     suite.add(new Y.Test.Case({
  63
+        name : "Base Event Tests",
  64
+
  65
+        testEventPrefix : function() {
  66
+            var h = new EventTests();
  67
+            Y.Assert.areEqual("eventTestsHost", h._eventPrefix);            
  68
+        },
  69
+
  70
+        testEventRegistrationThroughConstructor : function() {
  71
+
  72
+            var expectedEvents = ["OnInit", "AfterInit", "OnAttr1Change", "AfterAttr1Change"];
  73
+            var actualEvents = [];
  74
+
  75
+            var h = new EventTests({
  76
+                on: {
  77
+                    "attr1Change" : function() {
  78
+                        actualEvents.push("OnAttr1Change");
  79
+                    },
  80
+
  81
+                    "init" : function() {
  82
+                        actualEvents.push("OnInit");
  83
+                    }
  84
+                },
  85
+
  86
+                after: {
  87
+                    "attr1Change" : function() {
  88
+                        actualEvents.push("AfterAttr1Change");
  89
+                    },
  90
+
  91
+                    "init" : function() {
  92
+                        actualEvents.push("AfterInit");
  93
+                    }
  94
+                }
  95
+            });
  96
+
  97
+            h.set("attr1", "bar");
  98
+
  99
+            Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
  100
+        },
  101
+
  102
+        testBubbleTargetsThroughConstructor : function() {
  103
+
  104
+            var expectedEvents = ["bubbleTargetOne", "bubbleTargetTwo", "bubbleTargetThree"];
  105
+            var actualEvents = [];
  106
+
  107
+            var bubbleTargetOne = new Y.EventTarget();
  108
+            bubbleTargetOne.on("eventTestsHost:attr1Change", function() {
  109
+                actualEvents.push("bubbleTargetOne");
  110
+            });
  111
+
  112
+            var bubbleTargetTwo = new Y.EventTarget();
  113
+            bubbleTargetTwo.on("eventTestsHost:attr1Change", function() {
  114
+                actualEvents.push("bubbleTargetTwo");
  115
+            });
  116
+
  117
+            var bubbleTargetThree = new Y.EventTarget();
  118
+            bubbleTargetThree.on("eventTestsHost:attr1Change", function() {
  119
+                actualEvents.push("bubbleTargetThree");
  120
+            });
  121
+
  122
+            var h1 = new EventTests({
  123
+               bubbleTargets : [bubbleTargetOne, bubbleTargetTwo]  
  124
+            });
  125
+
  126
+            h1.set("attr1", "bar");
  127
+
  128
+            var h2 = new EventTests({
  129
+                bubbleTargets : bubbleTargetThree
  130
+            });
  131
+
  132
+            h2.set("attr1", "foobar");
  133
+
  134
+            Y.ArrayAssert.itemsAreEqual(expectedEvents, actualEvents);
  135
+        },
  136
+
  137
+        testInitEvent : function() {
  138
+            var actual = [];
  139
+            var expected = ["onInit", "afterInit"];
  140
+
  141
+            var h = new EventTests({
  142
+                on : {
  143
+                    init : function() {
  144
+                        actual.push("onInit");
  145
+                    }
  146
+                }, 
  147
+                after : {
  148
+                    init : function() {
  149
+                        actual.push("afterInit");                        
  150
+                    }
  151
+                }
  152
+            });
  153
+
  154
+            Y.ArrayAssert.itemsAreEqual(expected, actual);  
  155
+        },
  156
+
  157
+        testDestroyEvent : function() {
  158
+            var actual = [];
  159
+            var expected = ["onDestroy", "afterDestroy"];
  160
+
  161
+            var h = new EventTests();
  162
+
  163
+            h.on("destroy", function() {
  164
+                actual.push("onDestroy");
  165
+            });
  166
+            
  167
+            h.after("destroy", function() {
  168
+                actual.push("afterDestroy");
  169
+            });        
  170
+        }
  171
+    }));
  172
+
  173
+    suite.add(new Y.Test.Case({
49 174
 
50 175
         name : "BaseBuild",
51 176
 
@@ -828,6 +953,7 @@
828 953
             });
829 954
 
830 955
             var o = new MyClassTwo();
  956
+
831 957
             o.methodOne();
832 958
             o.methodTwo();
833 959
             o.extOne();
@@ -836,6 +962,304 @@
836 962
             Y.ArrayAssert.itemsAreEqual(expectedMethodCalls, actualMethodCalls, "Unexpected method calls");
837 963
         },
838 964
 
  965
+        "test:mainclass-statics" : function() {
  966
+
  967
+            function Ext1() {}
  968
+
  969
+            Ext1.prototype.extOne = function() {};
  970
+            Ext1.prototype.initializer = function() {};
  971
+            Ext1.prototype.methodOne = function() {
  972
+                return "methodOne";
  973
+            };
  974
+
  975
+            Ext1.STATIC_ONE = "static_one";
  976
+            Ext1.STATIC_TWO = "static_two";
  977
+            Ext1.STATIC_THREE = "static_three";
  978
+            
  979
+            var MyClass = Y.extend(function() {
  980
+                MyClass.superclass.constructor.apply(this, arguments);                
  981
+            }, Y.Base, null, {
  982
+                NAME : "myClass",
  983
+                _buildCfg : {
  984
+                    statics : ["STATIC_ONE", "STATIC_TWO"]
  985
+                }
  986
+            });
  987
+
  988
+            var MyBuiltClass = Y.Base.create("myBuiltClass", MyClass, [Ext1]);
  989
+
  990
+            var o = new MyBuiltClass();
  991
+
  992
+            Y.Assert.isTrue(o instanceof MyBuiltClass);
  993
+
  994
+            Y.Assert.isFunction(o.methodOne); // prototype properties copied
  995
+            Y.Assert.isFunction(o.init); // but prototype not switched completely by mistake
  996
+
  997
+            Y.Assert.areEqual("static_one", MyBuiltClass.STATIC_ONE);
  998
+            Y.Assert.areEqual("static_two", MyBuiltClass.STATIC_TWO);
  999
+            Y.Assert.isFalse("STATIC_THREE" in MyBuiltClass);
  1000
+
  1001
+            Y.Assert.isFalse(MyBuiltClass.ATTRS === Ext1.ATTRS, "Ext1.ATTRS shouldn't have been copied over, it should be aggregated");            
  1002
+        },
  1003
+
  1004
+        "test:mainclass-statics" : function() {
  1005
+
  1006
+            function Ext1() {}
  1007
+
  1008
+            Ext1.prototype.extOne = function() {};
  1009
+            Ext1.prototype.initializer = function() {};
  1010
+            Ext1.prototype.methodOne = function() {
  1011
+                return "methodOne";
  1012
+            };
  1013
+
  1014
+            Ext1.STATIC_ONE = "static_one";
  1015
+            Ext1.STATIC_TWO = "static_two";
  1016
+            Ext1.STATIC_THREE = "static_three";
  1017
+
  1018
+            var MyClass = Y.extend(function() {
  1019
+                MyClass.superclass.constructor.apply(this, arguments);                
  1020
+            }, Y.Base, null, {
  1021
+                NAME : "myClass",
  1022
+                _buildCfg : {
  1023
+                    statics : ["STATIC_ONE", "STATIC_TWO"]
  1024
+                }
  1025
+            });
  1026
+
  1027
+            var MyBuiltClass = Y.Base.create("myBuiltClass", MyClass, [Ext1]);
  1028
+
  1029
+            var o = new MyBuiltClass();
  1030
+
  1031
+            Y.Assert.isTrue(o instanceof MyBuiltClass);
  1032
+
  1033
+            Y.Assert.isFunction(o.methodOne); // prototype properties copied
  1034
+            Y.Assert.isFunction(o.init); // but prototype not switched completely by mistake
  1035
+
  1036
+            Y.Assert.areEqual("static_one", MyBuiltClass.STATIC_ONE);
  1037
+            Y.Assert.areEqual("static_two", MyBuiltClass.STATIC_TWO);
  1038
+            Y.Assert.isFalse("STATIC_THREE" in MyBuiltClass);
  1039
+
  1040
+            Y.Assert.isFalse(MyBuiltClass.ATTRS === Ext1.ATTRS, "Ext1.ATTRS shouldn't have been copied over, it should be aggregated");            
  1041
+        },
  1042
+
  1043
+        "test:mainclass-aggregates" : function() {
  1044
+
  1045
+            function Ext1() {}
  1046
+            Ext1.AGG = {
  1047
+                "foo": true
  1048
+            };
  1049
+            
  1050
+            function Ext2() {}
  1051
+            Ext2.AGG = {
  1052
+                "bar": true
  1053
+            };
  1054
+
  1055
+            var MyClass = Y.extend(function() {
  1056
+                MyClass.superclass.constructor.apply(this, arguments);          
  1057
+            }, Y.Base, null, {
  1058
+                NAME : "myClass",
  1059
+                _buildCfg : {
  1060
+                    aggregates : ["AGG"]
  1061
+                }
  1062
+            });
  1063
+
  1064
+            var MyBuiltClass = Y.Base.create("myBuiltClass", MyClass, [Ext1, Ext2]);
  1065
+
  1066
+            var o = new MyBuiltClass();
  1067
+
  1068
+            Y.ObjectAssert.areEqual({
  1069
+                foo:true,
  1070
+                bar:true
  1071
+            }, MyBuiltClass.AGG);
  1072
+        },
  1073
+
  1074
+        "test:mainclass-custom" : function() {
  1075
+
  1076
+            function Ext1() {}
  1077
+
  1078
+            Ext1.prototype.extOne = function() {};
  1079
+            Ext1.prototype.methodOne = function() {
  1080
+                return "methodOne";
  1081
+            };
  1082
+
  1083
+            Ext1.CUST = {
  1084
+                foo: [1],
  1085
+                bar: [1]
  1086
+            };
  1087
+
  1088
+            function Ext2() {}
  1089
+
  1090
+            Ext2.prototype.extTwo = function() {};
  1091
+            Ext2.prototype.methodTwo = function() {
  1092
+                return "methodOne";
  1093
+            };
  1094
+
  1095
+            Ext2.CUST = {
  1096
+                foo: [2, 3],
  1097
+                bar: [2, 3, 4]
  1098
+            };
  1099
+
  1100
+            // ---
  1101
+
  1102
+            var MyClass = Y.extend(function() {
  1103
+                MyClass.superclass.constructor.apply(this, arguments);
  1104
+            }, Y.Base, null, {
  1105
+                NAME : "myClass",
  1106
+                _buildCfg : {
  1107
+                    custom : {
  1108
+                        CUST : function(p, r, s) {
  1109
+
  1110
+                            r[p] = r[p] || {
  1111
+                                foo:[],
  1112
+                                bar:[]
  1113
+                            };
  1114
+    
  1115
+                            if (s[p]) {
  1116
+                                if (s[p].foo) {
  1117
+                                    r[p].foo = r[p].foo.concat(s[p].foo);    
  1118
+                                }
  1119
+                                if (s[p].bar) {
  1120
+                                    r[p].bar = r[p].bar.concat(s[p].bar);    
  1121
+                                }
  1122
+                            }
  1123
+    
  1124
+                        }
  1125
+                    }
  1126
+                }
  1127
+            });
  1128
+
  1129
+            var MyClass1 = Y.Base.create("myClass1", MyClass, [Ext1]);
  1130
+            var myclass1 = new MyClass1();
  1131
+
  1132
+            Y.Assert.isTrue(myclass1 instanceof MyClass1);
  1133
+
  1134
+            Y.Assert.isFunction(myclass1.methodOne);
  1135
+            Y.Assert.isFunction(myclass1.init);
  1136
+
  1137
+            // ObjectAssert.areEqual doesn't work: values don't == compare
  1138
+            Y.ObjectAssert.hasKeys({
  1139
+                bar:[1],
  1140
+                foo:[1]
  1141
+            }, MyClass1.CUST, "Class1 - object assert");
  1142
+            
  1143
+            Y.ArrayAssert.itemsAreEqual([1], MyClass1.CUST.foo, "Class1 foo assert");
  1144
+            Y.ArrayAssert.itemsAreEqual([1], MyClass1.CUST.bar, "Class1 bar assert");
  1145
+
  1146
+            Y.Assert.isFalse(MyClass1.CUST === Ext1.CUST, "Ext1.CUST shouldn't have been copied over");
  1147
+
  1148
+            // ---
  1149
+
  1150
+            var MyClass2 = Y.Base.create("myClass2", MyClass, [Ext1, Ext2]);
  1151
+            var myclass2 = new MyClass2();
  1152
+
  1153
+            Y.Assert.isTrue(myclass2 instanceof MyClass2);
  1154
+
  1155
+            Y.Assert.isFunction(myclass2.methodTwo); // prototype properties copied
  1156
+            Y.Assert.isFunction(myclass2.init); // but prototype not switched completely by mistake
  1157
+
  1158
+            // ObjectAssert.areEqual doesn't work: values don't == compare
  1159
+            Y.ObjectAssert.hasKeys({
  1160
+                foo:[1,2,3],
  1161
+                bar:[1,2,3,4]
  1162
+            }, MyClass2.CUST);
  1163
+
  1164
+            Y.ArrayAssert.itemsAreEqual([1,2,3], MyClass2.CUST.foo);
  1165
+            Y.ArrayAssert.itemsAreEqual([1,2,3,4], MyClass2.CUST.bar);
  1166
+
  1167
+            Y.Assert.isFalse(MyClass2.CUST === Ext1.CUST, "Ext1.CUST shouldn't have been copied over");
  1168
+            Y.Assert.isFalse(MyClass2.CUST === Ext2.CUST, "Ext2.CUST shouldn't have been copied over");
  1169
+        },
  1170
+
  1171
+        "test:extCfg-custom" : function() {
  1172
+
  1173
+            function Ext1() {}
  1174
+
  1175
+            Ext1.prototype.extOne = function() {};
  1176
+            Ext1.prototype.methodOne = function() {
  1177
+                return "methodOne";
  1178
+            };
  1179
+
  1180
+            Ext1.CUST = {
  1181
+                foo: [1],
  1182
+                bar: [1]
  1183
+            };
  1184
+
  1185
+            Ext1._buildCfg = {
  1186
+                custom : {
  1187
+                    CUST : function(p, r, s) {
  1188
+                        
  1189
+                        r[p] = r[p] || {
  1190
+                            foo:[],
  1191
+                            bar:[]
  1192
+                        };
  1193
+
  1194
+                        if (s[p]) {
  1195
+                            if (s[p].foo) {
  1196
+                                r[p].foo = r[p].foo.concat(s[p].foo);    
  1197
+                            }
  1198
+                            if (s[p].bar) {
  1199
+                                r[p].bar = r[p].bar.concat(s[p].bar);    
  1200
+                            }
  1201
+                        }
  1202
+
  1203
+                    }
  1204
+                }
  1205
+            };
  1206
+
  1207
+            function Ext2() {}
  1208
+
  1209
+            Ext2.prototype.extTwo = function() {};
  1210
+            Ext2.prototype.methodTwo = function() {
  1211
+                return "methodOne";
  1212
+            };
  1213
+
  1214
+            Ext2.CUST = {
  1215
+                foo: [2, 3],
  1216
+                bar: [2, 3, 4]
  1217
+            };
  1218
+
  1219
+            // ---
  1220
+
  1221
+            var MyClass1 = Y.Base.create("myClass1", Y.Base, [Ext1]);
  1222
+            var myclass1 = new MyClass1();
  1223
+
  1224
+            Y.Assert.isTrue(myclass1 instanceof MyClass1);
  1225
+
  1226
+            Y.Assert.isFunction(myclass1.methodOne);
  1227
+            Y.Assert.isFunction(myclass1.init);
  1228
+
  1229
+            // ObjectAssert.areEqual doesn't work: values don't == compare
  1230
+            Y.ObjectAssert.hasKeys({
  1231
+                bar:[1],
  1232
+                foo:[1]
  1233
+            }, MyClass1.CUST, "Class1 - object assert");
  1234
+            
  1235
+            Y.ArrayAssert.itemsAreEqual([1], MyClass1.CUST.foo, "Class1 foo assert");
  1236
+            Y.ArrayAssert.itemsAreEqual([1], MyClass1.CUST.bar, "Class1 bar assert");
  1237
+
  1238
+            Y.Assert.isFalse(MyClass1.CUST === Ext1.CUST, "Ext1.CUST shouldn't have been copied over");
  1239
+
  1240
+            // ---
  1241
+