1 X.Dom.find = function( v ){
2 var selectors = parser( v ),
3 l, i, nodes, _nodes, selector,
4 name, key, operator, value,
7 if( !selectors ) return;
13 selector = selectors[ i ];
14 if( 2 <= selector.length ){
15 operator = selector[ 2 ];
16 value = selector[ 3 ];
17 name = key = selector[ 1 ];
18 selector = selector[ 0 ];
22 nodes = [ X.Dom.getById( name ) ];
24 case 5 : // . classname
26 for( j = 0, m = nodes.length; j < m; ++j ){
27 _nodes = _nodes.concat( nodes[ j ].getByClass( name ) );
31 case 6 : // :focus, :disabled ...
59 for( j = 0, m = nodes.length ; j < m; ++j ){
60 _nodes = _nodes.concat( nodes[ j ].getByTag( name ) );
66 return new X.Dom.NodeList( nodes );
83 OPERATORS = { "!=": 2, "~=": 3, "^=": 4, "$=": 5, "*=": 6, "|=": 7 };
84 ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789\\';
86 function parser( query ){
94 chr, index, start, name, key, value, operator, nameChr, name1st, escape;
96 chr = query.charAt( i );
97 index = ALPHABET.indexOf( chr );
98 nameChr = index !== -1;
99 name1st = nameChr && index < 52;
105 ( ( selector = 8 ) && ( phase = 2 ) && ( start = i ) ) :
106 ( index = HASH_SELECTOR.indexOf( chr ) ) === 7 ? // [
107 ( ( selector = 7 ) && ( phase = 3 ) ) :
109 ( ( selector = index ) && ( phase = index < 4 ? 9 : 1 ) ) :
115 ( ( start = i ) && ( phase = 2 ) ) :
120 !( escape && ( selector === 4 || selector === 5 ) && ( chr === ':' || chr === '.' ) ) // id or class の場合 : . を直前にエスケープした場合に限り使える
121 && ( name = query.substring( start, i ) ) && ( phase = 9 );
123 case 3 : // start attr filter
125 ( ( phase = 4 ) && ( start = i ) ) :
128 case 4 : // attr filter key
130 ( ( operator = 1 ) && ( phase = 5 ) && ( key = query.substring( start, i ) ) && ( start = i ) ) :
131 ( index = OPERATORS[ query.substr( i, 2 ) ] ) ?
132 ( ( operator = index ) && ( phase = 5 ) && ( key = query.substring( start, i ) ) && ( start = i ) && ++i ) :
136 case 5 : // attr filter value
138 ( ( phase = 9 ) && ( value = query.substring( start, i ) ) ) :
144 //alert( chr + ' ' + phase + ' ' + selector + ' ' + name + ' ' + name1st )
146 if( last < 4 && selector < 4 ){
148 result[ result.length - 1 ] = selector; // override
153 } else { // 前回今回とも子孫セレクタの場合、保存しない
154 result[ result.length ] =
158 [ selector, key, operator, value ] :
159 [ selector, name.split( '\\' ).join( '' ) ];
165 if( phase === 99 ) return;
167 escape = chr === '\\' && !escape;