2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
8 YUI.add('selector-css3', function(Y) {
11 * The selector css3 module provides support for css3 selectors.
13 * @submodule selector-css3
18 an+b = get every _a_th node starting at the _b_th
19 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
20 1n+b = get every element starting from b ("1" may may be omitted, e.g. "1n+0" or "n+0" or "n")
21 an+0 = get every _a_th element, "0" may be omitted
24 Y.Selector._reNth = /^(?:([\-]?\d*)(n){1}|(odd|even)$)*([\-+]?\d*)$/;
26 Y.Selector._getNth = function(node, expr, tag, reverse) {
27 Y.Selector._reNth.test(expr);
28 var a = parseInt(RegExp.$1, 10), // include every _a_ elements (zero means no repeat, just first _a_)
30 oddeven = RegExp.$3, // "odd" or "even"
31 b = parseInt(RegExp.$4, 10) || 0, // start scan from element _b_
33 siblings = Y.Selector._children(node.parentNode, tag),
37 a = 2; // always every other
40 b = (oddeven === 'odd') ? 1 : 0;
41 } else if ( isNaN(a) ) {
42 a = (n) ? 1 : 0; // start from the first or no repeat
45 if (a === 0) { // just the first
47 b = siblings.length - b + 1;
50 if (siblings[b - 1] === node) {
62 for (var i = b - 1, len = siblings.length; i < len; i += a) {
63 if ( i >= 0 && siblings[i] === node ) {
68 for (var i = siblings.length - b, len = siblings.length; i >= 0; i -= a) {
69 if ( i < len && siblings[i] === node ) {
77 Y.mix(Y.Selector.pseudos, {
78 'root': function(node) {
79 return node === node.ownerDocument.documentElement;
82 'nth-child': function(node, expr) {
83 return Y.Selector._getNth(node, expr);
86 'nth-last-child': function(node, expr) {
87 return Y.Selector._getNth(node, expr, null, true);
90 'nth-of-type': function(node, expr) {
91 return Y.Selector._getNth(node, expr, node.tagName);
94 'nth-last-of-type': function(node, expr) {
95 return Y.Selector._getNth(node, expr, node.tagName, true);
98 'last-child': function(node) {
99 var children = Y.Selector._children(node.parentNode);
100 return children[children.length - 1] === node;
103 'first-of-type': function(node) {
104 return Y.Selector._children(node.parentNode, node.tagName)[0] === node;
107 'last-of-type': function(node) {
108 var children = Y.Selector._children(node.parentNode, node.tagName);
109 return children[children.length - 1] === node;
112 'only-child': function(node) {
113 var children = Y.Selector._children(node.parentNode);
114 return children.length === 1 && children[0] === node;
117 'only-of-type': function(node) {
118 var children = Y.Selector._children(node.parentNode, node.tagName);
119 return children.length === 1 && children[0] === node;
122 'empty': function(node) {
123 return node.childNodes.length === 0;
126 'not': function(node, expr) {
127 return !Y.Selector.test(node, expr);
130 'contains': function(node, expr) {
131 var text = node.innerText || node.textContent || '';
132 return text.indexOf(expr) > -1;
135 'checked': function(node) {
136 return (node.checked === true || node.selected === true);
139 enabled: function(node) {
140 return (node.disabled !== undefined && !node.disabled);
143 disabled: function(node) {
144 return (node.disabled);
148 Y.mix(Y.Selector.operators, {
149 '^=': '^{val}', // Match starts with value
150 '$=': '{val}$', // Match ends with value
151 '*=': '{val}' // Match contains value as substring
154 Y.Selector.combinators['~'] = {
155 axis: 'previousSibling'
159 }, '3.3.0' ,{requires:['dom-base', 'selector-native', 'selector-css2']});