OSDN Git Service

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