X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2Fdom%2F18_XDomQuery.js;h=7dc8d9c6b1636dbeea69f1bcf07a1757b39067be;hb=c2184d5500fe31de24e248c9cdf92b31e547fd0c;hp=6796d0deda1345b8b644cd6f1206df969eddb689;hpb=df4575c24267b984d159fa0e69a60831d18bdc8d;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/dom/18_XDomQuery.js b/0.6.x/js/dom/18_XDomQuery.js index 6796d0d..7dc8d9c 100644 --- a/0.6.x/js/dom/18_XDomQuery.js +++ b/0.6.x/js/dom/18_XDomQuery.js @@ -205,33 +205,41 @@ X.Dom.Query._parse = function( query, last ){ }; // セレクター - X.Dom.find = Node.prototype.find = function( queryString ){ - var scope = [ this.cnstructor === Node ? this : Node.root ], - noLower = 'title id name class for href src', + 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.root ], + parents = scope, // 探索元の親要素 XNodeList の場合あり + 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,// 要素をマージする必要がある - parents = scope, // 探索元の親要素 + isStart = true, + _ = ' ', + isAll, isNot, hasRoot, l, i, n, parsed, xnodes, // 一時保存用 merge, // 要素がコメントノードで汚染されている場合使う - combinator, selector, name, tagName, - isAll, isStart = true, isNot, + 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 + ']' + queryString.length ); + //console.log( 'queryString[' + queryString + ']' ); // 初期化処理 if( !parsed ){ @@ -245,21 +253,19 @@ 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.Dom.Query._parse ' + parsed ); if( parsed === 5 ){ isMulti = true; parents = scope; xnodes && xnodes.length && ARY_PUSH.apply( ret, xnodes ); parsed = null; - xnodes = null; + xnodes = []; isStart = true; continue; }; }; - - combinator = parsed[ 0 ]; selector = parsed[ 1 ]; name = parsed[ 2 ]; @@ -274,7 +280,7 @@ X.Dom.Query._parse = function( query, last ){ if( combinator !== 0 ){ parents = xnodes; xnodes = []; - console.log( 'cobinator !== 0 ' + parents.length + ' : ' + xnodes.length ); + //console.log( 'cobinator !== 0 ' + parents.length + ' : ' + xnodes.length ); }; }; @@ -324,13 +330,13 @@ X.Dom.Query._parse = function( query, last ){ break; default : - if( combinator === 1 || isStart ){ - console.log( l + ' > ' + xnodes.length + ' tag:' + tagName ); + 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 ); + //console.log( l + ' >> ' + xnodes.length + ' tag:' + tagName ); }; }; @@ -364,14 +370,17 @@ X.Dom.Query._parse = function( query, last ){ xnodes = scope; break; // root case 8 : - xnodes = [ Node._html ]; break; + hasRoot = true; + xnodes = [ HTML ]; break; // link case 9 : - if( links = root._rawNode.links ){ + 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 ){ @@ -398,13 +407,16 @@ X.Dom.Query._parse = function( query, last ){ tmp = []; key = filter[ 0 ]; op = filter[ 1 ]; - val = filter[ 2 ]; + val = filter[ 2 ]; + + key = X.Dom.Attr.renameForTag[ key ] || key; + // [class~='val'] if( !isXML && key === 'class' && op === 3 ){ - val = ' ' + val + ' '; + val = _ + val + _; for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){ className = xnode._className; - if( !!( className && ( ' ' + className + ' ' ).indexOf( val ) > -1 ) ^ isNot ) tmp[ ++n ] = xnode; + if( !!( className && ( _ + className + _ ).indexOf( val ) > -1 ) ^ isNot ) tmp[ ++n ] = xnode; }; } else { // 通常 @@ -414,7 +426,7 @@ X.Dom.Query._parse = function( query, last ){ 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 + ' '; + if( op === 3 ) val = _ + val + _; for( i = 0, n = -1, l = xnodes.length; i < l; ++i ){ xnode = xnodes[ i ]; @@ -427,7 +439,7 @@ X.Dom.Query._parse = function( query, last ){ //useName ? // elem[ X.Dom.Attr.renameForDOM[ key ] || key ] : // elem.getAttribute( key, 2 ); - flag = attr != null && ( !useName || attr !== '' ); + flag = attr != null;// && ( !useName || attr !== '' ); if( flag && op ){ if( toLower ) attr = attr.toLowerCase(); @@ -439,7 +451,7 @@ X.Dom.Query._parse = function( query, last ){ flag = attr !== val; break; case 3: // ~= - flag = ( ' ' + attr + ' ' ).indexOf( val ) !== -1; + flag = ( _ + attr + _ ).indexOf( val ) !== -1; break; case 4: // ^= flag = attr.indexOf( val ) === 0; @@ -465,31 +477,57 @@ X.Dom.Query._parse = function( query, last ){ isNot = false; parsed = null; - alert( '//end :' + ( xnodes && xnodes.length ) ); + //console.log( '//end :' + ( xnodes && xnodes.length ) ); }; - console.log( 'multi:' + ( xnodes && xnodes.length ) ) + //console.log( 'multi:' + ( xnodes && xnodes.length ) ); + // tree 順に並び替え、同一要素の排除 if( isMulti ){ xnodes && xnodes.length && ARY_PUSH.apply( ret, xnodes ); - //for( i = 0, l = xnodes.length, n = ret.length - 1; i < l; ++i ){ - // ret[ ++n ] = xnodes[ i ]; - //}; + l = ret.length; + if( l < 2 ) return ret[ 0 ] || Node.none; + xnodes = []; merge = {}; - for( i = 0, n = -1, l = ret.length; i < l; ++i ){ + for( i = 0, n = -1; i < l; ++i ){ //alert( 'multi:' + i ) xnode = ret[ i ]; - uid = xnode._uid; - if( !merge[ uid ] ){ + 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, @@ -539,7 +577,7 @@ X.Dom.Query._parse = function( query, last ){ res = [], checked = {}, flag_not = flags.not, - i = 0, n = -1, elem, uid, + i = 0, n = -1, uid, c, xnode, tmp, node, tagName; for( ; xnode = xnodes[ i ]; ++i ){ uid = xnode._uid; @@ -553,7 +591,7 @@ X.Dom.Query._parse = function( query, last ){ }; tmp = checked[ uid ]; }; - if( tmp ^ flag_not ) res[ ++n ] = elem; + if( tmp ^ flag_not ) res[ ++n ] = xnode; }; return res; }; @@ -661,7 +699,7 @@ X.Dom.Query._filter = { tmp = tmp.parent; }; //tmp = !!(tmp && reg.test(tmp.getAttribute('lang'))); - if( ( !!( tmp && lang && lang.toLowerCase().indexOf( arg ) === 0 ) ) ^ flag_not ) res[ ++n ] = xnode; + if( ( !!lang && lang.toLowerCase().indexOf( arg ) === 0 ) ^ flag_not ) res[ ++n ] = xnode; }; return res; } @@ -678,13 +716,15 @@ X.Dom.Query._filter = { contains : { m : function( flags, xnodes, arg ){ var res = [], - textContent = $.browser.msie || $.browser.opera ? 'innerText' : 'textContent', flag_not = flags.not, - i = 0, n = -1, elem; - for( ; elem = xnodes[ i ]; ++i ){ - if ( ( -1 < ( elem[ textContent ] || '' ).indexOf( arg ) ) ^ flag_not ) res[ ++n ] = elem; + i = 0, n = -1, xnode; + for( ; xnode = xnodes[ i ]; ++i ){ + if ( ( -1 < ( xnode.text() ).indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xnode; }; return res; } } -}; \ No newline at end of file +}; + + +