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