X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F08_XNodeSelector.js;h=1208076d2f473a3ee8cdfc6e4078d32cfb8d733b;hb=5633b955bc9fcd998e8ecf7e8e30c311aafc588c;hp=2e065e8caf98f0635185e9bafb85f699c65a815a;hpb=d9cca45398f61025472f2858818519562a746e61;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/02_dom/08_XNodeSelector.js b/0.6.x/js/02_dom/08_XNodeSelector.js index 2e065e8..1208076 100644 --- a/0.6.x/js/02_dom/08_XNodeSelector.js +++ b/0.6.x/js/02_dom/08_XNodeSelector.js @@ -1,4 +1,4 @@ -/** +/* * Original code by ofk ( kQuery, ksk ) * http://d.hatena.ne.jp/ofk/comment/20090106/1231258010 * http://d.hatena.ne.jp/ofk/20090111/1231668170 @@ -7,22 +7,22 @@ * http://standards.mitsue.co.jp/resources/w3c/TR/css3-selectors/#nth-child-pseudo */ -X.Dom.Query = { - _PSEUDO : { +var + X_Node_Selector__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, + '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, @@ -31,7 +31,7 @@ X.Dom.Query = { 'first-of-type' : 13 }, - _COMBINATOR : { + X_Node_Selector__COMBINATOR = { '' : 0, // none ' ' : 1, // 子孫セレクタ '>' : 2, // 子セレクタ @@ -40,36 +40,35 @@ X.Dom.Query = { ',' : 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 + X_Node_Selector__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 + X_Node_Selector__OPERATORS = { '==' : 1, '!=': 2, '~=': 3, '^=': 4, '$=': 5, '*=': 6, '|=': 7 }, // '':0 は属性が存在するならtrue // TODO { a : 1, A : 2, _ : 3,,, } - _ALPHABET : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789\\', - _NUMBER : '+-0123456789' -}; - + X_Node_Selector__ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789\\', + X_Node_Selector__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, +function X_Node_Selector__parse( query, last ){ + var COMBINATOR = X_Node_Selector__COMBINATOR, + SELECTOR = X_Node_Selector__SELECTOR, + OPERATORS = X_Node_Selector__OPERATORS, + ALPHABET = X_Node_Selector__ALPHABET, + NUMBER = X_Node_Selector__NUMBER, result = [], i = -1, l = query.length, @@ -79,10 +78,11 @@ X.Dom.Query._parse = function( query, last ){ 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 ); + chrCode = ALPHABET.indexOf( chr ); // TODO この関数無くす! nameChr = chrCode !== -1; name1st = nameChr && chrCode < 52; switch( phase ){ @@ -117,6 +117,7 @@ X.Dom.Query._parse = function( query, last ){ case 0x4 : // start attr filter name1st ? ( ( phase = 0x5 ) && ( start = i ) ) : + chr !== ' ' && ( phase = 0xf ); break; case 0x5 : // attr filter key @@ -167,7 +168,7 @@ X.Dom.Query._parse = function( query, last ){ break; case 0xa : chr === ')' && ( phase = 0xe ) && ++i && ( b = parseFloat( query.substring( start, i ) ) || 0 ); - console.log( '0xa: ' + start + ' ' + i ); + //console.log( '0xa: ' + start + ' ' + i ); break; // contains, lang case 0xb : @@ -182,35 +183,41 @@ X.Dom.Query._parse = function( query, last ){ break; default : }; + + if( phase === 0xf ) return i; + //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; + if( not ){ + return i; // error + } else { + 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 ]; + result = [ not ? 0 : combinator, SELECTOR[ name ] || selector, name, a, b ]; break; }; + } else { + result = + combinator === 5 ? + 5 : + selector === 5 ? + [ not ? 0 : combinator, selector, key, operator, value ] : + [ not ? 0 : combinator, selector, name.split( '\\' ).join( '' ) ]; + 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; }; @@ -219,17 +226,41 @@ X.Dom.Query._parse = function( query, last ){ 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 ], + /** + * selector を使って Node, NodeList を取得する + * @alias X.Doc.find + * @function + * @param {string} セレクター文字列 + * @return {Node|NodeList} + */ + X[ 'Doc' ][ 'find' ] = X_shortcutFunction = + + /** + * selector を使って Node, NodeList を取得する + * @alias NodeList.prototype.find + * @function + * @param {string} セレクター文字列 + * @return {Node|NodeList} + */ + X_NodeList.prototype[ 'find' ] = X_Node_find; + + /** + * selector を使って Node, NodeList を取得する + * @alias Node.prototype.find + * @function + * @param {string} セレクター文字列 + * @return {Node|NodeList} + */ + function X_Node_find( queryString ){ + var HTML = X_Node_html, + scope = this.constructor === X_NodeList && this.length ? this : [ this.constructor === Node ? this : X_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 ), + root = X_Node_getRoot( scope[ 0 ] ), + isXML = !!X_Node_isXmlDocument( root ), isMulti = 1 < scope.length,// 要素をマージする必要がある isStart = true, _ = ' ', @@ -237,19 +268,20 @@ X.Dom.Query._parse = function( query, last ){ l, i, n, parsed, xnodes, // 一時保存用 merge, // 要素がコメントノードで汚染されている場合使う + parent, children, j, m, combinator, selector, name, tagName, uid, tmp, xnode, filter, key, op, val, toLower, useName, links, className, attr, flag; /*@+debug[*/ - if( X_ViewPort_readyState < X.Event.XDOM_READY ){ - alert( 'not ready! use X.ViewPort.listenOnce( X.Event.XDOM_READY, callback )' ); + if( X_ViewPort_readyState < X_EVENT_XDOM_READY ){ + alert( 'not ready! use X.ViewPort.listenOnce( X_EVENT_XDOM_READY, callback )' ); return; }; /*]@+debug*/ // 文字列以外は空で返す - if( typeof queryString !== 'string' ) return ret; + if( !X_Type_isString( queryString ) ) return ret; xnodes = []; @@ -259,9 +291,9 @@ X.Dom.Query._parse = function( query, last ){ // 初期化処理 if( !parsed ){ - parsed = X.Dom.Query._parse( queryString ); + parsed = X_Node_Selector__parse( queryString ); - if( typeof parsed === 'number' ){ + if( X_Type_isNumber( parsed ) ){ // error return []; }; @@ -269,7 +301,7 @@ X.Dom.Query._parse = function( query, last ){ queryString = queryString.substr( parsed[ 0 ] ); parsed = parsed[ 1 ]; - //console.log( 'X.Dom.Query._parse ' + parsed ); + //console.log( 'X_Node_Selector__parse ' + parsed ); if( parsed === 5 ){ isMulti = true; @@ -311,29 +343,49 @@ X.Dom.Query._parse = function( query, last ){ // > 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; - }; + parent = parents[ i ]; + if( ( children = parent[ '_xnodes' ] ) && ( m = children.length ) ){ + for( j = 0; j < m; ++j ){ + xnode = children[ j ]; + if( xnode[ '_tag' ] && ( 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; + + xnode = parents[ i ]; + j = xnode[ 'getOrder' ]() + 1; + parent = xnode.parent; + if( parent && ( children = parent[ '_xnodes' ] ) && ( m = children.length ) ){ + for( ; j < m; ++j ){ + xnode = children[ j ]; + if( xnode[ '_tag' ] ){ + if( isAll || tagName === xnode[ '_tag' ] ){ + xnodes[ ++n ] = xnode; + }; + break; + }; + }; + }; + /* + for( xnode = parents[ i ][ 'next' ](); xnode; xnode = xnode[ 'next' ]() ){ + if( xnode[ '_tag' ] ){ + 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; + for( xnode = parents[ i ][ 'next' ](); xnode; xnode = xnode[ 'next' ]() ){ + if( xnode[ '_tag' ] && ( isAll || tagName === xnode[ '_tag' ] ) ){ + uid = xnode[ '_uid' ]; if( merge[ uid ] ){ break; } else { @@ -347,13 +399,26 @@ X.Dom.Query._parse = function( query, last ){ // case 6 : 属性ノードは実装しない - default : + 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 ); + if( isStart ){ + if( tagName === 'HTML' ){ + xnodes[ 0 ] = X_Node_html; + break; + }; + if( tagName === 'HEAD' ){ + xnodes[ 0 ] = X_Node_head; + break; + }; + if( tagName === 'BODY' ){ + xnodes[ 0 ] = X_Node_body; + break; + }; + }; + //console.log( l + ' > ' + xnodes.length + ' tag:' + tagName ); + merge = {}; + X_Node_Selector__fetchElements( xnodes, parents, isAll ? '' : tagName, merge ); //console.log( l + ' >> ' + xnodes.length + ' tag:' + tagName ); }; }; @@ -371,7 +436,7 @@ X.Dom.Query._parse = function( query, last ){ filter = [ 'class', 3 /*'~='*/, name ]; break; // :, 擬似クラス case 4 : - if( !( filter = X.Dom.Query._filter[ name ] ) ){ + if( !( filter = X_Node_Selector__filter[ name ] ) ){ return []; }; break; @@ -382,7 +447,27 @@ X.Dom.Query._parse = function( query, last ){ case 6 : isNot = true; parsed = parsed[ 2 ]; - continue; + name = parsed[ 2 ]; + switch( parsed[ 1 ] ) { + case 1 : + filter = [ 'tag', 1, isXML ? name : name.toUpperCase() ]; break; + // #, ID + case 2 : + filter = [ 'id', 1, name ]; break; + // ., class + case 3 : + filter = [ 'class', 3, name ]; break; + // :, 擬似クラス + case 4 : + if( !( filter = X_Node_Selector__filter[ name ] ) ){ + return []; + }; + break; + // [] 属性 + case 5 : + filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break; + }; + break; // scope case 7 : xnodes = scope; break; @@ -394,7 +479,7 @@ X.Dom.Query._parse = function( query, last ){ case 9 : if( links = document.links ){ for( xnodes = [], i = links.length; i; ){ - xnodes[ --i ] = new Node( links[ i ] ); + xnodes[ --i ] = Node( links[ i ] ); }; } else { // area[href],a[href] @@ -414,7 +499,7 @@ X.Dom.Query._parse = function( query, last ){ ); } else // filterが関数の場合 - if( typeof filter === 'function' ){ + if( X_Type_isFunction( filter ) ){ tmp = []; for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){ if( ( !!filter( xnode ) ) ^ isNot ) tmp[ ++n ] = xnode; @@ -427,13 +512,13 @@ X.Dom.Query._parse = function( query, last ){ op = filter[ 1 ]; val = filter[ 2 ]; - key = X_Node_Attr.renameForTag[ key ] || key; + key = X_Node_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; + className = xnode[ '_className' ]; if( !!( className && ( _ + className + _ ).indexOf( val ) > -1 ) ^ isNot ) tmp[ ++n ] = xnode; }; } else { @@ -441,7 +526,7 @@ X.Dom.Query._parse = function( query, last ){ // 諦めて、funcAttrを呼ぶ // flag_call = ($.browser.safari && key === 'selected'); // getAttributeを使わない - useName = X.UA.IE && key !== 'href' && key !== 'src'; + 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 + _; @@ -449,15 +534,16 @@ X.Dom.Query._parse = function( query, last ){ 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 ]; + key === 'tag' ? xnode[ '_tag' ] : + key === 'id' ? xnode[ '_id' ] : + key === 'class' ? xnode[ '_className' ] : + xnode[ '_attrs' ] && xnode[ '_attrs' ][ key ]; //flag_call ? // funcAttr( elem, key ) : //useName ? - // elem[ X_Node_Attr.renameForDOM[ key ] || key ] : + // elem[ X_Node_Attr_renameForDOM[ key ] || key ] : // elem.getAttribute( key, 2 ); - flag = attr != null;// && ( !useName || attr !== '' ); + flag = !!attr;// && ( !useName || attr !== '' ); if( flag && op ){ if( toLower ) attr = attr.toLowerCase(); @@ -503,83 +589,129 @@ X.Dom.Query._parse = function( query, last ){ if( isMulti ){ xnodes && xnodes.length && ARY_PUSH.apply( ret, xnodes ); l = ret.length; - if( l < 2 ) return ret[ 0 ] || Node.none; + if( l < 2 ) return ret[ 0 ] || X_Node_none; xnodes = []; merge = {}; for( i = 0, n = -1; i < l; ++i ){ //alert( 'multi:' + i ) xnode = ret[ i ]; - if( !merge[ uid = xnode._uid ] ){ + if( !merge[ uid = xnode[ '_uid' ] ] ){ merge[ uid ] = true; xnodes[ ++n ] = xnode; }; }; - X.Dom.Query._sortElementOrder( ret = [], xnodes, hasRoot ? [ HTML ] : HTML._xnodes ); - xnodes = ret; + xnodes = X_Node_Selector__sortElementOrder( [], xnodes, hasRoot ? [ HTML ] : HTML[ '_xnodes' ] ); }; - return xnodes.length === 1 ? xnodes[ 0 ] : new X.Dom.NodeList( xnodes ); + return xnodes.length === 1 ? xnodes[ 0 ] : new X_NodeList( xnodes ); }; - X.Dom.Query._sortElementOrder = function( newList, list, xnodes ){ + function X_Node_Selector__sortElementOrder( 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 ){ + if( !child[ '_tag' ] ) continue; + + j = list.indexOf( child ); + if( j !== -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 === 2 ){ + newList[ newList.length ] = list[ j === 0 ? 1 : 0 ]; + return newList; }; - if( list.length === 0 ) return true; + list.splice( j, 1 ); }; - if( ( _xnodes = child._xnodes ) && X.Dom.Query._sortElementOrder( newList, list, _xnodes ) ){ - return true; + + if( ( _xnodes = child[ '_xnodes' ] ) && X_Node_Selector__sortElementOrder( newList, list, _xnodes ) ){ + return newList; }; }; }; - - X.Dom.Query._fetchElements = function( list, parent, tag ){ - var xnodes = parent._xnodes, - l = xnodes.length, + + function X_Node_Selector__fetchElements( list, xnodes, tag, merge ){ + var l = xnodes.length, i = 0, - child; + child, uid, _tag, _xnodes; 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 ); + uid = child[ '_uid' ]; + _tag = child[ '_tag' ]; + if( !merge[ uid ] && _tag ){ + merge[ uid ] = true; + ( !tag || tag === _tag ) && ( list[ list.length ] = child ); + if( ( _xnodes = child[ '_xnodes' ] ) && ( 1 < _xnodes.length || ( _xnodes[ 0 ] && _xnodes[ 0 ][ '_tag' ] ) ) ){ + X_Node_Selector__fetchElements( list, _xnodes, tag, merge ); + }; }; }; }; - - X.Dom.Query._funcSelectorChild = function( type, flag_all, flags, xnodes ){ +/* + function X_Node_Selector__fetchElements( list, parent, tag, merge ){ + + var xnodes = parent[ '_xnodes' ], + memory = { + i : 0, + l : xnodes.length, + xnodes : xnodes + }, + memories = [ memory ], + i, l, xnode, + uid, _xnodes; + + while( memories.length ){ + memory = memories.pop(); + xnodes = memory.xnodes; + i = memory.i; + l = memory.l; + for( ; i < l; ++i ){ + xnode = xnodes[ i ]; + uid = xnode[ '_uid' ]; + if( !merge[ uid ] && xnode[ '_tag' ] ){ + if( !tag || xnode[ '_tag' ] === tag ) list[ list.length ] = xnode; + + if( _xnodes = xnode[ '_xnodes' ] ){ + if( 1 < _xnodes.length || ( _xnodes[ 0 ] && _xnodes[ 0 ][ '_tag' ] ) ){ + memory.i = i + 1; + memory.l = l; + memory.xnodes = xnodes; + memories[ memories.length ] = memory; + memories[ memories.length ] = { + i : 0, + l : _xnodes.length, + xnodes : _xnodes + }; + merge[ uid ] = true; + break; + }; + }; + }; + merge[ uid ] = true; + }; + }; + }; + */ + function X_Node_Selector__funcSelectorChild( 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; + 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 ) ){ + for( node = xnode[ 'prev' ](); node; node = node[ 'prev' ]() ){ + if( node[ '_tag' ] && ( 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 ) ){ + for( node = xnode[ 'next' ](); node; node = node[ 'next' ]() ){ + if( node[ '_tag' ] && ( flag_all || tagName === node[ '_tag' ] ) ){ tmp = false; break; }; @@ -590,21 +722,20 @@ X.Dom.Query._parse = function( query, last ){ }; return res; }; - X.Dom.Query._funcSelectorNth = function( pointer, sibling, flag_all, flags, xnodes, a, b ){ - var _data = funcData, - res = [], + function X_Node_Selector__funcSelectorNth( pointer, sibling, flag_all, flags, xnodes, a, b ){ + var res = [], checked = {}, flag_not = flags.not, i = 0, n = -1, uid, c, xnode, tmp, node, tagName; for( ; xnode = xnodes[ i ]; ++i ){ - uid = xnode._uid; + 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 ) ){ + for( c = 0, node = xnode.parent[ pointer ](), tagName = flag_all || xnode[ '_tag' ]; node; node = node[ sibling ]() ){ + if( node[ '_tag' ] && ( flag_all || tagName === node[ '_tag' ] ) ){ ++c; - checked[ node._uid ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0; + checked[ node[ '_uid' ] ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0; }; }; tmp = checked[ uid ]; @@ -613,71 +744,71 @@ X.Dom.Query._parse = function( query, last ){ }; return res; }; - X.Dom.Query._funcSelectorProp = function( prop, flag, flags, xnodes ){ + function X_Node_Selector__funcSelectorProp( 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; + 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; +var X_Node_Selector__filter = { + 'root' : function(){ + return X_Node_html; }, - target : { + '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; + 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 ); } + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorChild( -1, true, flags, xnodes ); } }, 'last-child' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 1, true, flags, xnodes ); } + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorChild( 1, true, flags, xnodes ); } }, 'only-child' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 0, true, flags, xnodes ); } + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorChild( 0, true, flags, xnodes ); } }, 'first-of-type' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( -1, false, flags, xnodes ); } + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorChild( -1, false, flags, xnodes ); } }, 'last-of-type' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 1, false, flags, xnodes ); } + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorChild( 1, false, flags, xnodes ); } }, 'only-of-type' : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 0, false, flags, xnodes ); } + m : function( flags, xnodes ){ return X_Node_Selector__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 ); } + m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'firstChild', 'next', 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 ); } + m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'lastChild', 'prev', 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 ); } + m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'firstChild', 'next', 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 ); } + m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'lastChild', 'prev', false, flags, xnodes, a, b ); } }, - empty : { + '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 ) ){ + for( node = xnode[ 'firstChild' ](); node; node = node[ 'next' ]() ){ + if( node[ '_tag' ] || node[ '_text' ] ){ tmp = false; break; }; @@ -687,25 +818,24 @@ X.Dom.Query._filter = { return res; } }, - link : { + 'link' : { m : function( flags, xnodes ){ - var links = ( xnodes[ 0 ].ownerDocument || xnodes[ 0 ].document ).links, - _data = funcData, + var links = document.links, 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; + checked[ ( Node( link ) )[ '_uid' ] ] = true; }; for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){ - if( checked[ xnode._uid ] ^ flag_not ) res[ ++n ] = xnode; + if( checked[ xnode[ '_uid' ] ] ^ flag_not ) res[ ++n ] = xnode; }; return res; } }, - lang : { + 'lang' : { m : function( flags, xnodes, arg ){ var res = [], //reg = new RegExp('^' + arg, 'i'), @@ -713,7 +843,7 @@ X.Dom.Query._filter = { i = 0, n = -1, xnode, tmp, lang; arg = arg.toLowerCase(); for( ; tmp = xnode = xnodes[ i ]; ++i ){ - while( tmp && !( lang = tmp._attrs && tmp._attrs[ 'lang' ] ) ){ + while( tmp && !( lang = tmp[ '_attrs' ] && tmp[ '_attrs' ][ 'lang' ] ) ){ tmp = tmp.parent; }; //tmp = !!(tmp && reg.test(tmp.getAttribute('lang'))); @@ -722,27 +852,24 @@ X.Dom.Query._filter = { return res; } }, - enabled : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'disabled', false, flags, xnodes ); } + 'enabled' : { + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorProp( 'disabled', false, flags, xnodes ); } }, - disabled : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'disabled', true, flags, xnodes ); } + 'disabled' : { + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorProp( 'disabled', true, flags, xnodes ); } }, - checked : { - m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'checked', true, flags, xnodes ); } + 'checked' : { + m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorProp( 'checked', true, flags, xnodes ); } }, - contains : { + '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; + if ( ( -1 < ( xnode[ 'text' ]() ).indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xnode; }; return res; } } }; - - -