X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F01_dom%2F18_XDomQuery.js;fp=0.6.x%2Fjs%2F01_dom%2F18_XDomQuery.js;h=0000000000000000000000000000000000000000;hb=51e22031f9629d4bc32444a0228930642144ee9e;hp=c09136d1af69068856244566f33f5d82939b2d84;hpb=05ae2ffbbca8b1bdb4c3fcbfdd4e1708c0485360;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/01_dom/18_XDomQuery.js b/0.6.x/js/01_dom/18_XDomQuery.js deleted file mode 100644 index c09136d..0000000 --- a/0.6.x/js/01_dom/18_XDomQuery.js +++ /dev/null @@ -1,748 +0,0 @@ -/** - * Original code by ofk ( kQuery, ksk ) - * http://d.hatena.ne.jp/ofk/comment/20090106/1231258010 - * http://d.hatena.ne.jp/ofk/20090111/1231668170 - * - * セレクタ Level 3 - * http://standards.mitsue.co.jp/resources/w3c/TR/css3-selectors/#nth-child-pseudo - */ - -X.Dom.Query = { - _PSEUDO : { - 'nth-child' : 9, - 'nth-last-child' : 14, - 'nth-of-type' : 11, - 'nth-last-of-type' : 16, - root : 4, - link : 4, - lang : 4, - empty : 5, - target : 6, - invalid : 7, - enabled : 7, - checked : 7, - disabled : 8, - contains : 8, - 'last-child' : 10, - 'only-child' : 10, - 'first-child' : 11, - 'last-of-type' : 12, - 'only-of-type' : 12, - 'first-of-type' : 13 - }, - - _COMBINATOR : { - '' : 0, // none - ' ' : 1, // 子孫セレクタ - '>' : 2, // 子セレクタ - '+' : 3, // 兄弟セレクタ,共通の親を持つ、1番目要素が2番目要素の1つ前にある - '~' : 4, // 一般兄弟セレクタ,共通の親を持つ、1番目要素が2番目要素の前 (直前でなくともよい) にある - ',' : 5, - '@' : 6 // XML 用の拡張、属性ノードを辿る http://www.marguerite.jp/Nihongo/WWW/RefDOM/_Attr_interface.html - }, - _SELECTOR : { - '' : 0, // none - tag : 1, - '#' : 2, - '.' : 3, - ':' : 4, - '[' : 5, - not : 6, - scope : 7, - root : 8, - link : 9 - }, - _OPERATORS : { '==' : 1, '!=': 2, '~=': 3, '^=': 4, '$=': 5, '*=': 6, '|=': 7 }, // '':0 は属性が存在するならtrue - // TODO { a : 1, A : 2, _ : 3,,, } - _ALPHABET : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789\\', - _NUMBER : '+-0123456789' -}; - -/* - * セレクタ文字列の解析、但し一挙に行わず、ひと塊づつ - * 結合子 + 単体セレクタ( タグ,*,#,.,[],: ) - * ' ' 子孫セレクタ, '>' 直下,'+','~' の場合、tagName|* を返す - * return [ 今回のパースで解析した終端位置, [ selector, ... ] ] error: return pointer - */ -X.Dom.Query._parse = function( query, last ){ - var COMBINATOR = X.Dom.Query._COMBINATOR, - SELECTOR = X.Dom.Query._SELECTOR, - OPERATORS = X.Dom.Query._OPERATORS, - ALPHABET = X.Dom.Query._ALPHABET, - NUMBER = X.Dom.Query._NUMBER, - result = [], - i = -1, - l = query.length, - phase = 0x0, - combinator = 0, - selector = 0, - chr, chrCode, nameChr, name1st, - tmp, escape, quot, start, - name, key, value, operator, a, b, not; - query += ' '; - while( i < l ){ - chr = query.charAt( ++i ); - chrCode = ALPHABET.indexOf( chr ); - nameChr = chrCode !== -1; - name1st = nameChr && chrCode < 52; - switch( phase ){ - case 0x0 : - name1st ? // tagName - ( ( selector = 1 ) && ( phase = 0x2 ) && ( start = i ) ) : - !not && ( tmp = COMBINATOR[ chr ] ) ? ( - ( 1 < tmp && 1 < combinator ) ? - ( phase = 0xf ) : - ( phase = tmp === 5 ? 0xe : 0x0 ) & ( ( 1 < tmp || combinator < 1 ) && ( combinator = tmp ) ) & ( tmp === 5 && ++i ) ) : // ' ' でない結合子の上書きはエラー - ( tmp = SELECTOR[ chr ] ) ? // [ - ( selector = tmp ) && ( phase = selector === 5 ? 0x4 : 0x1 ) : // 7:[, 0<: - chr === '*' ? - ( ( selector = 1 ) && ( name = chr ) && ( phase = 0xe ) && ++i ) : - chr !== ' ' && ( phase = 0xf ); - //console.log( '0x0: ' + name1st + ' ' + chrCode + ' ' + chr + ' ' + phase + ' tmp:' + tmp + ' comb:' + combinator ); - break; - case 0x1 : - name1st ? - ( ( start = i ) && ( phase = 0x2 ) ) : - chr !== ' ' && ( phase = 0xf ); - break; - case 0x2 : - !nameChr && !( escape && ( selector === 2 || selector === 3 ) && ( chr === ':' || chr === '.' ) ) ? // id or class の場合 : . を直前にエスケープした場合に限り使える - ( name = query.substring( start, i ) ) && ( phase = selector === 4 && name !== 'not' && chr === '(' ? ( name !== 'lang' && name !== 'contains' ? 0x8 : 0xb ) : 0xe ) : - SELECTOR[ chr ] < 4 && ( phase = 0xe ); - break; - - case 0x3 : //:nth- - break; - - case 0x4 : // start attr filter - name1st ? - ( ( phase = 0x5 ) && ( start = i ) ) : - ( phase = 0xf ); - break; - case 0x5 : // attr filter key - chr === '=' ? - ( ( operator = 1 ) && ( phase = 0x6 ) && ( key || ( key = query.substring( start, i ) ) ) && ( start = i + 1 ) ) : - chr === ']' ? - ( !( operator = 0 ) && ( phase = 0xe ) && ( key || ( key = query.substring( start, i ) ) ) && ++i ) : - chr === ' ' ? - ( key || ( key = query.substring( start, i ) ) ) : - ( operator = OPERATORS[ query.substr( i, 2 ) ] ) ? - ( ( phase = 0x6 ) && ( key || ( key = query.substring( start, i ) ) ) && ( start = ++i ) ) : - !nameChr && ( phase = 0xf ); - //console.log( name1st + ' ' + chrCode + chr + phase ); - break; - case 0x6 : - ( chr === '"' || chr === "'" ) && !escape && !quot ? - ( quot = chr ) && ( start = i + 1 ) && ( phase = 0x7 ) : - chr !== ' ' && ( start = i ) && ( phase = 0x7 ); - break; - - case 0x7 : // attr filter value - chr === quot ? - !escape && !value && ( value = query.substring( start, i ) ) : - chr === ']' ? - ( ( value || ( value = query.substring( start, i ) ) ) && ( phase = 0xe ) && ++i ) : - chr === ' ' && !quot && !value && ( value = query.substring( start, i ) ); - //( chr === '"' || chr === "'" ) && !quot && ( quot = chr ) && ( start = i + 1 ); - break; - - case 0x8 : // 4, 2n, even, odd, -n+4, - NUMBER.indexOf( chr ) !== -1 ? - ( start = i ) && ( phase = 0x9 ) : - chr === 'n' ? - ( phase = 0xa ) && ( a = 1 ) && ( start = i + 1 ) : - query.substr( i, 4 ) === 'even' ? - ( ( a = 2 ) && !( b = 0 ) && ( i += 3 ) ) : - query.substr( i, 3 ) === 'odd' ? - ( ( a = 2 ) && ( b = 1 ) && ( i += 2 ) ) : - chr === ')' && ( phase = a ? 0xe : 0xf ) && ++i; - //console.log( '0x8: ' + name1st + ' ' + chrCode + ' ' + chr + ' ' + phase + ' ' + name ); - break; - case 0x9 : - tmp = query.substring( start, i ); - chr === 'n' ? - ( phase = 0xa ) && ( start = i + 1 ) && ( a = tmp === '+' ? 1 : tmp === '-' ? -1 : parseFloat( tmp ) ) : - chr === ')' && ( phase = 0xe ) && ++i && ( b = parseFloat( tmp ) ) && ( a = 0 ); - //console.log( '0x9: ' + name1st + ' ' + chrCode + ' ' + chr + ' ' + phase ); - break; - case 0xa : - chr === ')' && ( phase = 0xe ) && ++i && ( b = parseFloat( query.substring( start, i ) ) || 0 ); - console.log( '0xa: ' + start + ' ' + i ); - break; - // contains, lang - case 0xb : - ( chr === '"' || chr === "'" ) && !escape && !quot && - ( quot = chr ) && ( start = i + 1 ) && ( phase = 0xc ); - break; - case 0xc : - chr === quot && !escape && ( value = query.substring( start, i ) ) && ( phase = 0xd ); - break; - case 0xd : - chr === ')' && ( phase = 0xe ) && ++i; - break; - default : - }; - //alert( chr + ' ' + phase + ' ' + selector + ' ' + name + ' ' + name1st ) - if( phase === 0xe ){ - if( selector === 4 ){// :not - if( name === 'not' ){ - if( not ) return i; // error - not = true; - selector = 0; - phase = 0x0; - name = null; - continue; - } else - if( name === 'lang' || name === 'contains' ){ - result = [ not ? 0 : combinator, selector, name, value ]; - break; - } else { - if( a !== a || b !== b ) return i; - result = [ not ? 0 : combinator, selector, name, a, b ]; - break; - }; - }; - result = - combinator === 5 ? - 5 : - selector === 5 ? - [ not ? 0 : combinator, selector, key, operator, value ] : - [ not ? 0 : combinator, selector, name.split( '\\' ).join( '' ) ]; - break; - } else - if( phase === 0xf ) return i; - - escape = chr === '\\' && !escape; - }; - //if( phase !== 0xe ) return i; - if( not && ( tmp = query.substr( i ).indexOf( ')' ) ) === -1 ) return i; - return not ? [ i + tmp + 1, [ combinator, 6, result ] ] : [ i, result ]; -}; - - // セレクター - X.Dom.find = X._shortcut = Node.prototype.find = X.Dom.NodeList.prototype.find = function( queryString ){ - var HTML = Node._html, - scope = this.constructor === X.Dom.NodeList && this.length ? this : [ this.constructor === Node ? this : Node._body ], - parents = scope, // 探索元の親要素 XNodeList の場合あり - // TODO { title : true,,, } - noLower = 'title id name class for action archive background cite classid codebase data href longdesc profile src usemap',// + X.Dom.DTD.ATTR_VAL_IS_URI.join( ' ' ), - ARY_PUSH = Array.prototype.push, - ret = [], // 結果要素 - root = X.Dom.Node.getRoot( scope[ 0 ] ), - isXML = !!X.Dom.Node.isXmlDocument( root ), - isMulti = 1 < scope.length,// 要素をマージする必要がある - isStart = true, - _ = ' ', - isAll, isNot, hasRoot, - l, i, n, parsed, - xnodes, // 一時保存用 - merge, // 要素がコメントノードで汚染されている場合使う - combinator, selector, name, tagName, - uid, tmp, xnode, filter, key, op, val, toLower, useName, - links, className, attr, flag; - - /*@+debug[*/ - if( X.Dom.readyState < X.Dom.Event.XDOM_READY ){ - alert( 'not ready! use X.Dom.listenOnce( X.Dom.Event.XDOM_READY, callback )' ); - return; - }; - /*]@+debug*/ - - // 文字列以外は空で返す - if( typeof queryString !== 'string' ) return ret; - - xnodes = []; - - // 以下、パースと探索 - for( ; queryString.length; ){ - //console.log( 'queryString[' + queryString + ']' ); - - // 初期化処理 - if( !parsed ){ - parsed = X.Dom.Query._parse( queryString ); - - if( typeof parsed === 'number' ){ - // error - return []; - }; - - queryString = queryString.substr( parsed[ 0 ] ); - parsed = parsed[ 1 ]; - - //console.log( 'X.Dom.Query._parse ' + parsed ); - - if( parsed === 5 ){ - isMulti = true; - parents = scope; - xnodes && xnodes.length && ARY_PUSH.apply( ret, xnodes ); - parsed = null; - xnodes = []; - isStart = true; - continue; - }; - }; - - combinator = parsed[ 0 ]; - selector = parsed[ 1 ]; - name = parsed[ 2 ]; - tagName = selector === 1 ? ( isXML ? name : name.toUpperCase() ) : '*'; - isAll = tagName === '*'; - - if( !isStart ){ - if( !xnodes.length ){ - parsed = null; - continue; - } else - if( combinator !== 0 ){ - parents = xnodes; - xnodes = []; - //console.log( 'cobinator !== 0 ' + parents.length + ' : ' + xnodes.length ); - }; - }; - - i = 0; - l = parents.length; - n = -1; - isMulti = isMulti || 1 < l; - - //console.log( 'combinator ' + combinator ); - - switch( combinator ){ - // > TagName|* - case 2 : - for( ; i < l; ++i ){ - for( xnode = parents[ i ].firstChild(); xnode; xnode = xnode.nextNode() ){ - if( xnode._xnodeType === 1 && ( isAll || tagName === xnode._tag ) ) xnodes[ ++n ] = xnode; - }; - }; - break; - // + TagName|* - case 3 : - for( ; i < l; ++i ){ - for( xnode = parents[ i ].nextNode(); xnode; xnode = xnode.nextNode() ){ - if( xnode._xnodeType === 1 ){ - if( isAll || tagName === xnode._tag ) xnodes[ ++n ] = xnode; - break; - }; - }; - }; - break; - // ~ TagName|* - case 4 : - merge = {}; - for( ; i < l; ++i ){ - for( xnode = parents[ i ].nextNode(); xnode; xnode = xnode.nextNode() ){ - if( xnode._xnodeType === 1 && ( isAll || tagName === xnode._tag ) ){ - uid = xnode._uid; - if( merge[ uid ] ){ - break; - } else { - merge[ uid ] = true; - xnodes[ ++n ] = xnode; - }; - }; - }; - }; - break; - - // case 6 : 属性ノードは実装しない - - default : - if( combinator === 1 || ( isStart && selector < 7 ) ){ - //console.log( l + ' > ' + xnodes.length + ' tag:' + tagName ); - for( ; i < l; ++i ){ - xnode = parents[ i ]; - xnode._xnodes && xnode._xnodes.length && X.Dom.Query._fetchElements( xnodes, xnode, isAll ? null : tagName ); - }; - //console.log( l + ' >> ' + xnodes.length + ' tag:' + tagName ); - }; - }; - - isStart = false; - - //alert( 'pre-selector:' + ( xnodes && xnodes.length ) ) - - switch( selector ){ - // #, ID - case 2 : - filter = [ 'id', 1, name ]; break; - // ., class - case 3 : - filter = [ 'class', 3 /*'~='*/, name ]; break; - // :, 擬似クラス - case 4 : - if( !( filter = X.Dom.Query._filter[ name ] ) ){ - return []; - }; - break; - // [] 属性 - case 5 : - filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break; - // :not - case 6 : - isNot = true; - parsed = parsed[ 2 ]; - continue; - // scope - case 7 : - xnodes = scope; break; - // root - case 8 : - hasRoot = true; - xnodes = [ HTML ]; break; - // link - case 9 : - if( links = document.links ){ - for( xnodes = [], i = links.length; i; ){ - xnodes[ --i ] = new Node( links[ i ] ); - }; - } else { - // area[href],a[href] - }; - }; - - if( filter && xnodes.length ){ - // filter.mが関数の場合 - if( filter.m ){ - xnodes = filter.m( - { - not : isNot, - xml : isXML - }, - xnodes, - parsed[ 3 ], parsed[ 4 ] - ); - } else - // filterが関数の場合 - if( typeof filter === 'function' ){ - tmp = []; - for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){ - if( ( !!filter( xnode ) ) ^ isNot ) tmp[ ++n ] = xnode; - }; - xnodes = tmp; - } else { - // 属性セレクター - tmp = []; - key = filter[ 0 ]; - op = filter[ 1 ]; - val = filter[ 2 ]; - - key = X.Dom.Attr.renameForTag[ key ] || key; - - // [class~='val'] - if( !isXML && key === 'class' && op === 3 ){ - val = _ + val + _; - for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){ - className = xnode._className; - if( !!( className && ( _ + className + _ ).indexOf( val ) > -1 ) ^ isNot ) tmp[ ++n ] = xnode; - }; - } else { - // 通常 - // 諦めて、funcAttrを呼ぶ - // flag_call = ($.browser.safari && key === 'selected'); - // getAttributeを使わない - useName = X.UA.IE && key !== 'href' && key !== 'src'; - toLower = !!val && !isXML && noLower.indexOf( key ) === -1; //!noLower.test(key); - if( toLower ) val = val.toLowerCase(); - if( op === 3 ) val = _ + val + _; - - for( i = 0, n = -1, l = xnodes.length; i < l; ++i ){ - xnode = xnodes[ i ]; - attr = - key === 'id' ? xnode._id : - key === 'class' ? xnode._className : - xnode._attrs && xnode._attrs[ key ]; - //flag_call ? - // funcAttr( elem, key ) : - //useName ? - // elem[ X.Dom.Attr.renameForDOM[ key ] || key ] : - // elem.getAttribute( key, 2 ); - flag = attr != null;// && ( !useName || attr !== '' ); - if( flag && op ){ - if( toLower ) attr = attr.toLowerCase(); - - switch( op ){ - case 1: // = - flag = attr === val; - break; - case 2: // != - flag = attr !== val; - break; - case 3: // ~= - flag = ( _ + attr + _ ).indexOf( val ) !== -1; - break; - case 4: // ^= - flag = attr.indexOf( val ) === 0; - break; - case 5: // $= - flag = attr.lastIndexOf( val ) + val.length === attr.length; - break; - case 6: // *= - flag = attr.indexOf( val ) !== -1; - break; - case 7: // |= - flag = attr === val || attr.substring( 0, val.length + 1 ) === val + '-'; - break; - }; - }; - if( !!flag ^ isNot ) tmp[ ++n ] = xnode; - }; - }; - xnodes = tmp; - }; - }; - filter = null; - isNot = false; - parsed = null; - - //console.log( '//end :' + ( xnodes && xnodes.length ) ); - }; - //console.log( 'multi:' + ( xnodes && xnodes.length ) ); - - // tree 順に並び替え、同一要素の排除 - if( isMulti ){ - xnodes && xnodes.length && ARY_PUSH.apply( ret, xnodes ); - l = ret.length; - if( l < 2 ) return ret[ 0 ] || Node.none; - - xnodes = []; - merge = {}; - for( i = 0, n = -1; i < l; ++i ){ - //alert( 'multi:' + i ) - xnode = ret[ i ]; - if( !merge[ uid = xnode._uid ] ){ - merge[ uid ] = true; - xnodes[ ++n ] = xnode; - }; - }; - X.Dom.Query._sortElementOrder( ret = [], xnodes, hasRoot ? [ HTML ] : HTML._xnodes ); - xnodes = ret; - }; - - return xnodes.length === 1 ? xnodes[ 0 ] : new X.Dom.NodeList( xnodes ); - }; - - X.Dom.Query._sortElementOrder = function( newList, list, xnodes ){ - var l = xnodes.length, - i = 0, - j, child, _xnodes; - for( ; i < l; ++i ){ - child = xnodes[ i ]; - if( child._xnodeType !== 1 ) continue; - //console.log( child._tag ); - if( ( j = list.indexOf( child ) ) !== -1 ){ - newList[ newList.length ] = child; - list.splice( j, 1 ); - if( list.length === 1 ){ - newList[ newList.length ] = list[ 0 ]; - list.length = 0; - return true; - }; - if( list.length === 0 ) return true; - }; - if( ( _xnodes = child._xnodes ) && X.Dom.Query._sortElementOrder( newList, list, _xnodes ) ){ - return true; - }; - }; - }; - - X.Dom.Query._fetchElements = function( list, parent, tag ){ - var xnodes = parent._xnodes, - l = xnodes.length, - i = 0, - child; - for( ; i < l; ++i ){ - child = xnodes[ i ]; - if( child._xnodeType === 1 ){ - ( !tag || child._tag === tag ) && ( list[ list.length ] = child ); - //console.log( parent._tag + ' > ' + child._tag + ' == ' + tag+ ' l:' + list.length ); - child._xnodes && child._xnodes.length && X.Dom.Query._fetchElements( list, child, tag ); - }; - }; - }; - - X.Dom.Query._funcSelectorChild = function( type, flag_all, flags, xnodes ){ - var res = [], - flag_not = flags.not, - i = 0, n = -1, xnode, node, - tagName, tmp; - for( ; xnode = xnodes[ i ]; ++i ){ - tagName = flag_all || xnode._tag; - tmp = null; - if( /* tmp === null && */ type <= 0 ){ - for( node = xnode.prevNode(); node; node = node.prevNode() ){ - if( node._xnodeType === 1 && ( flag_all || tagName === node._tag ) ){ - tmp = false; - break; - }; - }; - }; - if( tmp === null && 0 <= type ){ - for( node = xnode.nextNode(); node; node = node.nextNode() ){ - if( node._xnodeType === 1 && ( flag_all || tagName === node._tag ) ){ - tmp = false; - break; - }; - }; - }; - if( tmp === null ) tmp = true; - if( tmp ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - }; - X.Dom.Query._funcSelectorNth = function( pointer, sibling, flag_all, flags, xnodes, a, b ){ - var _data = funcData, - res = [], - checked = {}, - flag_not = flags.not, - i = 0, n = -1, uid, - c, xnode, tmp, node, tagName; - for( ; xnode = xnodes[ i ]; ++i ){ - uid = xnode._uid; - tmp = checked[ uid ]; - if( tmp === void 0 ){ - for( c = 0, node = xnode.parent[ pointer ](), tagName = flag_all || xnode._tag; node; node = node[ sibling ]() ){ - if( node._xnodeType === 1 && ( flag_all || tagName === node._tag ) ){ - ++c; - checked[ node._uid ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0; - }; - }; - tmp = checked[ uid ]; - }; - if( tmp ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - }; - X.Dom.Query._funcSelectorProp = function( prop, flag, flags, xnodes ){ - var res = [], - flag_not = flag ? flags.not : !flags.not, - i = 0, n = -1, xnode; - for( ; xnode = xnodes[ i ]; ++i ){ - if( xnode._attrs && xnode._attrs[ prop ] ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - }; - -X.Dom.Query._filter = { - root : function( elem ){ - return elem === ( elem.ownerDocument || elem.document ).documentElement; - }, - target : { - m : function( flags, xnodes ){ - var res = [], - hash = location.hash.slice( 1 ), - flag_not = flags.not, - i = 0, n = -1, xnode; - for ( ; xnode = xnodes[ i ]; ++i ){ - if( ( ( xnode._id || xnode._attrs && xnode._attrs.name ) === hash ) ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - } - }, - 'first-child' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( -1, true, flags, xnodes ); } - }, - 'last-child' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 1, true, flags, xnodes ); } - }, - 'only-child' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 0, true, flags, xnodes ); } - }, - 'first-of-type' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( -1, false, flags, xnodes ); } - }, - 'last-of-type' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 1, false, flags, xnodes ); } - }, - 'only-of-type' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 0, false, flags, xnodes ); } - }, - 'nth-child' : { - m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'firstChild', 'nextNode', true, flags, xnodes, a, b ); } - }, - 'nth-last-child' : { - m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'lastChild', 'prevNode', true, flags, xnodes, a, b ); } - }, - 'nth-of-type' : { - m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'firstChild', 'nextNode', false, flags, xnodes, a, b ); } - }, - 'nth-last-of-type' : { - m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'lastChild', 'prevNode', false, flags, xnodes, a, b ); } - }, - empty : { - m : function( flags, xnodes ){ - var res = [], - flag_not = flags.not, - i = 0, n = -1, xnode, tmp, node; - for( ; xnode = xnodes[i]; ++i ){ - tmp = true; - for( node = xnode.firstChild(); node; node = node.nextSibling() ){ - if( node._xnodeType === 1 || ( node._xnodeType === 3 && node._text ) ){ - tmp = false; - break; - }; - }; - if( tmp ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - } - }, - link : { - m : function( flags, xnodes ){ - var links = ( xnodes[ 0 ].ownerDocument || xnodes[ 0 ].document ).links, - _data = funcData, - res = [], - checked, flag_not, i, link, xnode, n; - if( !links ) return res; - checked = {}; - flag_not = flags.not; - for( i = 0; link = links[ i ]; ++i ){ - checked[ ( new Node( link ) )._uid ] = true; - }; - for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){ - if( checked[ xnode._uid ] ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - } - }, - lang : { - m : function( flags, xnodes, arg ){ - var res = [], - //reg = new RegExp('^' + arg, 'i'), - flag_not = flags.not, - i = 0, n = -1, xnode, tmp, lang; - arg = arg.toLowerCase(); - for( ; tmp = xnode = xnodes[ i ]; ++i ){ - while( tmp && !( lang = tmp._attrs && tmp._attrs[ 'lang' ] ) ){ - tmp = tmp.parent; - }; - //tmp = !!(tmp && reg.test(tmp.getAttribute('lang'))); - if( ( !!lang && lang.toLowerCase().indexOf( arg ) === 0 ) ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - } - }, - enabled : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'disabled', false, flags, xnodes ); } - }, - disabled : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'disabled', true, flags, xnodes ); } - }, - checked : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'checked', true, flags, xnodes ); } - }, - contains : { - m : function( flags, xnodes, arg ){ - var res = [], - flag_not = flags.not, - i = 0, n = -1, xnode; - for( ; xnode = xnodes[ i ]; ++i ){ - if ( ( -1 < ( xnode.text() ).indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xnode; - }; - return res; - } - } -}; - - -