X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F08_XNodeSelector.js;h=5a0857ecf2416e431eeed4c79972aa9f3f3a3313;hb=50462b7b22a3c42bdbf2fb84d782937f817368f4;hp=1268ac33acab85dba041747d26e0e10d44f627e7;hpb=83a329e3210a40f383282389a48a33ea34ccfa1f;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 1268ac3..5a0857e 100644 --- a/0.6.x/js/02_dom/08_XNodeSelector.js +++ b/0.6.x/js/02_dom/08_XNodeSelector.js @@ -119,6 +119,7 @@ function X_Node_Selector__parse( query, last ){ case 0x4 : // start attr filter name1st ? ( ( phase = 0x5 ) && ( start = i ) ) : + chr !== ' ' && ( phase = 0xf ); break; case 0x5 : // attr filter key @@ -169,7 +170,7 @@ function X_Node_Selector__parse( 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 : @@ -206,7 +207,7 @@ function X_Node_Selector__parse( query, last ){ 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 { @@ -245,6 +246,7 @@ function X_Node_Selector__parse( 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; @@ -319,20 +321,40 @@ function X_Node_Selector__parse( query, last ){ // > TagName|* case 2 : for( ; i < l; ++i ){ - for( xnode = parents[ i ][ 'firstChild' ](); xnode; xnode = xnode[ 'next' ]() ){ - if( xnode[ '_tag' ] && ( 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 ){ + + 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|* @@ -355,13 +377,26 @@ function X_Node_Selector__parse( 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_Node_Selector__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 ); }; }; @@ -390,7 +425,27 @@ function X_Node_Selector__parse( 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; @@ -402,7 +457,7 @@ function X_Node_Selector__parse( 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] @@ -457,6 +512,7 @@ function X_Node_Selector__parse( query, last ){ for( i = 0, n = -1, l = xnodes.length; i < l; ++i ){ xnode = xnodes[ i ]; attr = + key === 'tag' ? xnode[ '_tag' ] : key === 'id' ? xnode[ '_id' ] : key === 'class' ? xnode[ '_className' ] : xnode[ '_attrs' ] && xnode[ '_attrs' ][ key ]; @@ -465,7 +521,7 @@ function X_Node_Selector__parse( query, last ){ //useName ? // 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(); @@ -523,8 +579,7 @@ function X_Node_Selector__parse( query, last ){ xnodes[ ++n ] = xnode; }; }; - X_Node_Selector__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_NodeList( xnodes ); @@ -537,38 +592,85 @@ function X_Node_Selector__parse( query, last ){ for( ; i < l; ++i ){ child = xnodes[ i ]; if( !child[ '_tag' ] ) continue; - //console.log( child[ '_tag' ] ); - if( ( j = list.indexOf( child ) ) !== -1 ){ + + 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_Node_Selector__sortElementOrder( newList, list, _xnodes ) ){ - return true; + return newList; }; }; }; - - function X_Node_Selector__fetchElements( 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[ '_tag' ] ){ - ( !tag || child[ '_tag' ] === tag ) && ( list[ list.length ] = child ); - //console.log( parent[ '_tag' ] + ' > ' + child[ '_tag' ] + ' == ' + tag+ ' l:' + list.length ); - child[ '_xnodes' ] && child[ '_xnodes' ].length && X_Node_Selector__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 ); + }; }; }; }; - +/* + 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, @@ -599,8 +701,7 @@ function X_Node_Selector__parse( query, last ){ return res; }; function X_Node_Selector__funcSelectorNth( pointer, sibling, flag_all, flags, xnodes, a, b ){ - var _data = funcData, - res = [], + var res = [], checked = {}, flag_not = flags.not, i = 0, n = -1, uid, @@ -704,7 +805,7 @@ var X_Node_Selector__filter = { 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;