selector-css3.js revision 7bd6c48178788dd4f19fa028e0294192ee2c7278
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller/*
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller an+b = get every _a_th node starting at the _b_th
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller 0n+b = no repeat ("0" and "n" may both be omitted (together) , e.g. "0n+1" or "1", not "0+1"), return only the _b_th element
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller 1n+b = get every element starting from b ("1" may may be omitted, e.g. "1n+0" or "n+0" or "n")
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller an+0 = get every _a_th element, "0" may be omitted
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller*/
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan MmillerY.Selector._reNth = /^(?:([-]?\d*)(n){1}|(odd|even)$)*([-+]?\d*)$/;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan MmillerY.Selector._getNth = function(node, expr, tag, reverse) {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller Y.Selector._reNth.test(expr);
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller var a = parseInt(RegExp.$1, 10), // include every _a_ elements (zero means no repeat, just first _a_)
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller n = RegExp.$2, // "n"
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller oddeven = RegExp.$3, // "odd" or "even"
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller b = parseInt(RegExp.$4, 10) || 0, // start scan from element _b_
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller result = [],
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller op;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller var siblings = node.parentNode.children || Selector._children(node.parentNode);
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller if (oddeven) {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller a = 2; // always every other
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller op = '+';
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller n = 'n';
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller b = (oddeven === 'odd') ? 1 : 0;
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller } else if ( isNaN(a) ) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller a = (n) ? 1 : 0; // start from the first or no repeat
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller }
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller if (a === 0) { // just the first
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller if (reverse) {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller b = siblings.length - b + 1;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller }
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller if (siblings[b - 1] === node) {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller return true;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller } else {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller return false;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller }
470b8b61c1e994020f9a8611860732b7532a859bBrendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller } else if (a < 0) {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller reverse = !!reverse;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller a = Math.abs(a);
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller }
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller if (!reverse) {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller for (var i = b - 1, len = siblings.length; i < len; i += a) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller if ( i >= 0 && siblings[i] === node ) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller return true;
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller }
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller }
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller } else {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller for (var i = siblings.length - b, len = siblings.length; i >= 0; i -= a) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller if ( i < len && siblings[i] === node ) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller return true;
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller }
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller }
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller }
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller return false;
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller};
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller
3a666413480ef97101461705e1f47cbab0266301Brendan MmillerY.mix(Y.Selector.pseudos, {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller 'root': function(node) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller return node === node.ownerDocument.documentElement;
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller },
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller 'nth-child': function(node, m) {
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller return Y.Selector._getNth(node, m[1]);
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller },
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller 'nth-last-child': function(node, m) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller return Y.Selector._getNth(node, m[1], null, true);
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller },
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller 'nth-of-type': function(node, m) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller return Y.Selector._getNth(node, m[1], node.tagName);
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller },
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller 'nth-last-of-type': function(node, m) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller return Y.Selector._getNth(node, m[1], node.tagName, true);
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller },
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller 'last-child': function(node) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller var children = node.children || Y.Selector._children(node.parentNode);
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller return children[children.length - 1] === node;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller },
ba208d3f0e9d48f3c841cdd627f200a7bb04cea8Brendan Mmiller
ba208d3f0e9d48f3c841cdd627f200a7bb04cea8Brendan Mmiller 'first-of-type': function(node) {
ba208d3f0e9d48f3c841cdd627f200a7bb04cea8Brendan Mmiller return Y.DOM._childrenByTag(node.parentNode, node.tagName)[0];
ba208d3f0e9d48f3c841cdd627f200a7bb04cea8Brendan Mmiller },
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller 'last-of-type': function(node) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller var children = Y.DOM._childrenByTag(node.parentNode, node.tagName);
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller return children[children.length - 1];
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller },
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller
ba208d3f0e9d48f3c841cdd627f200a7bb04cea8Brendan Mmiller 'only-child': function(node) {
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller var children = node.children || Y.Selector._children(node.parentNode);
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller return children.length === 1 && children[0] === node;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller },
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller 'only-of-type': function(node) {
ba208d3f0e9d48f3c841cdd627f200a7bb04cea8Brendan Mmiller return Y.DOM._childrenByTag(node.parentNode, node.tagName).length === 1;
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller },
52a38c0fe76475c93300961068ea9332cb9854d6Brendan Mmiller
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller 'empty': function(node) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller return node.childNodes.length === 0;
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller },
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller 'not': function(node, m) {
52a38c0fe76475c93300961068ea9332cb9854d6Brendan Mmiller return !Y.Selector.test(node, m[1]);
52a38c0fe76475c93300961068ea9332cb9854d6Brendan Mmiller },
52a38c0fe76475c93300961068ea9332cb9854d6Brendan Mmiller
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller 'contains': function(node, m) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller var text = node.innerText || node.textContent || '';
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller return text.indexOf(m[1]) > -1;
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller },
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller 'checked': function(node) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller return node.checked === true;
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller }
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller});
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller
99054f32a1766b8a8f60509cb724359413171d1dBrendan MmillerY.mix(Y.Selector.operators, {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller '^=': '^{val}', // Match starts with value
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller '$=': '{val}$', // Match ends with value
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller '*=': '{val}' // Match contains value as substring
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller});
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller
99054f32a1766b8a8f60509cb724359413171d1dBrendan MmillerY.Selector.combinators['~'] = function(node, token) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller var sib = node.previousSibling;
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller while (sib) {
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller if (sib.nodeType === 1 && Y.Selector._testToken(sib, null, null, token.previous)) {
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller return true;
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller }
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller sib = sib.previousSibling;
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller }
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller return false;
3f424ffdb194d6ff7ac053c5b3e53211a2de2d64Brendan Mmiller}
99054f32a1766b8a8f60509cb724359413171d1dBrendan Mmiller