OSDN Git Service

Version 0.6.176, add X.Script.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 08_XNodeSelector.js
index cbe5621..ca7fcd5 100644 (file)
@@ -1,4 +1,4 @@
-/**\r
+/*\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
@@ -8,21 +8,21 @@
  */\r
 \r
 var\r
-       X_Node_Selector__PSEUDO    = {\r
+       X_Node_Selector__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
+               '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
@@ -41,22 +41,22 @@ var
                '@'   : 6  // XML 用の拡張、属性ノードを辿る http://www.marguerite.jp/Nihongo/WWW/RefDOM/_Attr_interface.html\r
        },\r
        X_Node_Selector__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
+               ''      : 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
        X_Node_Selector__OPERATORS = { '==' : 1, '!=': 2, '~=': 3, '^=': 4, '$=': 5, '*=': 6, '|=': 7 }, // '':0 は属性が存在するならtrue\r
        // TODO { a : 1, A : 2, _ : 3,,, }\r
        X_Node_Selector__ALPHABET  = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789\\',\r
        X_Node_Selector__NUMBER    = '+-0123456789';\r
-                       \r
+               \r
 /*\r
  * セレクタ文字列の解析、但し一挙に行わず、ひと塊づつ\r
  * 結合子 + 単体セレクタ( タグ,*,#,.,[],: )\r
@@ -78,10 +78,11 @@ function X_Node_Selector__parse( query, last ){
                chr, chrCode, nameChr, name1st,\r
                tmp, escape, quot, start,\r
                name, key, value, operator, a, b, not;\r
+\r
        query += ' ';\r
        while( i < l ){\r
                chr     = query.charAt( ++i );\r
-               chrCode = ALPHABET.indexOf( chr );\r
+               chrCode = ALPHABET.indexOf( chr ); // TODO この関数無くす!\r
                nameChr = chrCode !== -1;\r
                name1st = nameChr && chrCode < 52;\r
                switch( phase ){\r
@@ -116,6 +117,7 @@ function X_Node_Selector__parse( query, last ){
                        case 0x4 : // start attr filter\r
                                name1st ?\r
                                        ( ( phase = 0x5 ) && ( start = i ) ) :\r
+                               chr !== ' ' &&\r
                                        ( phase = 0xf );\r
                                break;\r
                        case 0x5 : // attr filter key\r
@@ -166,7 +168,7 @@ function X_Node_Selector__parse( query, last ){
                                break;\r
                        case 0xa :\r
                                chr === ')' && ( phase = 0xe ) && ++i && ( b = parseFloat( query.substring( start, i ) ) || 0 );\r
-                               console.log( '0xa: ' + start + ' ' + i );\r
+                               //console.log( '0xa: ' + start + ' ' + i );\r
                                break;\r
                        // contains, lang\r
                        case 0xb :\r
@@ -181,35 +183,41 @@ function X_Node_Selector__parse( query, last ){
                                break;\r
                        default :\r
                };\r
+               \r
+               if( phase === 0xf ) return i;\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
+                                       if( not ){\r
+                                               return i; // error\r
+                                       } else {\r
+                                               not      = true;\r
+                                               selector = 0;\r
+                                               phase    = 0x0;\r
+                                               name     = null;                                        \r
+                                       };\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
+                                       result = [ not ? 0 : combinator, SELECTOR[ name ] || selector, name, a, b ];\r
                                        break;  \r
                                };\r
+                       } else {\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
                        };\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
 \r
                escape = chr === '\\' && !escape;\r
        };\r
@@ -218,8 +226,32 @@ function X_Node_Selector__parse( query, last ){
        return not ? [ i + tmp + 1, [ combinator, 6, result ] ] : [ i, result ];\r
 };\r
 \r
-       // セレクター\r
-       X.Doc.find = X._shortcut = Node.prototype.find = X_NodeList.prototype.find = function( queryString ){\r
+       /**\r
+        * selector を使って Node, NodeList を取得する\r
+        * @alias X.Doc.find\r
+        * @function\r
+        * @param {string} セレクター文字列\r
+        * @return {Node|NodeList}\r
+        */\r
+       X[ 'Doc' ][ 'find' ] = X_shortcutFunction =\r
+\r
+       /**\r
+        * selector を使って Node, NodeList を取得する\r
+        * @alias NodeList.prototype.find\r
+        * @function\r
+        * @param {string} セレクター文字列\r
+        * @return {Node|NodeList}\r
+        */\r
+       X_NodeList.prototype[ 'find' ] = X_Node_find;\r
+       \r
+       /**\r
+        * selector を使って Node, NodeList を取得する\r
+        * @alias Node.prototype.find\r
+        * @function\r
+        * @param {string} セレクター文字列\r
+        * @return {Node|NodeList}\r
+        */     \r
+       function X_Node_find( queryString ){\r
                var HTML      = X_Node_html,\r
                        scope     = this.constructor === X_NodeList && this.length ? this : [ this.constructor === Node ? this : X_Node_body ],\r
                        parents   = scope, // 探索元の親要素 XNodeList の場合あり\r
@@ -236,19 +268,20 @@ function X_Node_Selector__parse( query, last ){
                        l, i, n, parsed,\r
                        xnodes, // 一時保存用\r
                        merge, // 要素がコメントノードで汚染されている場合使う\r
+                       parent, children, j, m,\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_ViewPort_readyState < X.Event.XDOM_READY ){\r
-                       alert( 'not ready! use X.ViewPort.listenOnce( X.Event.XDOM_READY, callback )' );\r
+               if( X_ViewPort_readyState < X_EVENT_XDOM_READY ){\r
+                       alert( 'not ready! use X.ViewPort.listenOnce( X_EVENT_XDOM_READY, callback )' );\r
                        return;\r
                };\r
                /*]@+debug*/\r
 \r
                // 文字列以外は空で返す\r
-               if( typeof queryString !== 'string' ) return ret;\r
+               if( !X_Type_isString( queryString ) ) return ret;\r
                \r
                xnodes = [];\r
                \r
@@ -260,7 +293,7 @@ function X_Node_Selector__parse( query, last ){
                        if( !parsed ){\r
                                parsed = X_Node_Selector__parse( queryString );\r
                                \r
-                               if( typeof parsed === 'number' ){\r
+                               if( X_Type_isNumber( parsed ) ){\r
                                        // error\r
                                        return [];\r
                                };\r
@@ -310,29 +343,49 @@ function X_Node_Selector__parse( query, last ){
                                // > 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
+                                               parent = parents[ i ];\r
+                                               if( ( children = parent[ '_xnodes' ] ) && ( m = children.length ) ){\r
+                                                       for( j = 0; j < m; ++j ){\r
+                                                               xnode = children[ j ];\r
+                                                               if( xnode[ '_tag' ] && ( isAll || tagName === xnode[ '_tag' ] ) ) xnodes[ ++n ] = xnode;\r
+                                                       };\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
+                                               \r
+                                               xnode = parents[ i ];\r
+                                               j = xnode[ 'getOrder' ]() + 1;\r
+                                               parent = xnode.parent;\r
+                                               if( parent && ( children = parent[ '_xnodes' ] ) && ( m = children.length ) ){\r
+                                                       for( ; j < m; ++j ){\r
+                                                               xnode = children[ j ];\r
+                                                               if( xnode[ '_tag' ] ){\r
+                                                                       if( isAll || tagName === xnode[ '_tag' ] ){\r
+                                                                               xnodes[ ++n ] = xnode;\r
+                                                                       };\r
+                                                                       break;\r
+                                                               };\r
+                                                       };\r
+                                               };\r
+                                               /*\r
+                                               for( xnode = parents[ i ][ 'next' ](); xnode; xnode = xnode[ 'next' ]() ){\r
+                                                       if( xnode[ '_tag' ] ){\r
+                                                               if( isAll || tagName === xnode[ '_tag' ] ) xnodes[ ++n ] = xnode;\r
                                                                break;\r
                                                        };                                                                      \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
+                                               for( xnode = parents[ i ][ 'next' ](); xnode; xnode = xnode[ 'next' ]() ){\r
+                                                       if( xnode[ '_tag' ] && ( isAll || tagName === xnode[ '_tag' ] ) ){\r
+                                                               uid = xnode[ '_uid' ];\r
                                                                if( merge[ uid ] ){\r
                                                                        break;\r
                                                                } else {\r
@@ -346,13 +399,26 @@ function X_Node_Selector__parse( query, last ){
                                \r
                                // case 6 : 属性ノードは実装しない\r
                                \r
-                               default :\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_Node_Selector__fetchElements( xnodes, xnode, isAll ? null : tagName );\r
+                                               if( isStart ){\r
+                                                       if( tagName === 'HTML' ){\r
+                                                               xnodes[ 0 ] = X_Node_html;\r
+                                                               break;\r
+                                                       };\r
+                                                       if( tagName === 'HEAD' ){\r
+                                                               xnodes[ 0 ] = X_Node_head;\r
+                                                               break;\r
+                                                       };\r
+                                                       if( tagName === 'BODY' ){\r
+                                                               xnodes[ 0 ] = X_Node_body;\r
+                                                               break;\r
+                                                       };\r
+                                                       \r
                                                };\r
+                                               //console.log( l + ' > ' + xnodes.length + ' tag:' + tagName );\r
+                                               merge = {};\r
+                                               X_Node_Selector__fetchElements( xnodes, parents, isAll ? '' : tagName, merge );\r
                                                //console.log( l + ' >> ' + xnodes.length + ' tag:' + tagName );\r
                                        };\r
                        };\r
@@ -381,7 +447,27 @@ function X_Node_Selector__parse( query, last ){
                                case 6 :\r
                                        isNot  = true;\r
                                        parsed = parsed[ 2 ];\r
-                                       continue;\r
+                                       name   = parsed[ 2 ];\r
+                                       switch( parsed[ 1 ] ) {\r
+                                               case 1 :\r
+                                                       filter = [ 'tag', 1, isXML ? name : name.toUpperCase() ]; break;\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_Node_Selector__filter[ name ] ) ){\r
+                                                               return [];\r
+                                                       };\r
+                                                       break;\r
+                                               // [] 属性\r
+                                               case 5 :\r
+                                                       filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break;\r
+                                       };\r
+                                       break;\r
                                // scope\r
                                case 7 :\r
                                        xnodes = scope; break;\r
@@ -393,7 +479,7 @@ function X_Node_Selector__parse( query, last ){
                                case 9 :\r
                                        if( links = document.links ){\r
                                                for( xnodes = [], i = links.length; i; ){\r
-                                                       xnodes[ --i ] = new Node( links[ i ] );\r
+                                                       xnodes[ --i ] = Node( links[ i ] );\r
                                                };\r
                                        } else {\r
                                                // area[href],a[href]\r
@@ -413,7 +499,7 @@ function X_Node_Selector__parse( query, last ){
                                        );\r
                                } else\r
                                // filterが関数の場合\r
-                               if( typeof filter === 'function' ){\r
+                               if( X_Type_isFunction( filter ) ){\r
                                        tmp = [];\r
                                        for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){\r
                                                if( ( !!filter( xnode ) ) ^ isNot ) tmp[ ++n ] = xnode; \r
@@ -432,7 +518,7 @@ function X_Node_Selector__parse( query, last ){
                                        if( !isXML && key === 'class' && op === 3 ){\r
                                                val = _ + val + _;\r
                                                for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){\r
-                                                       className = xnode._className;\r
+                                                       className = xnode[ '_className' ];\r
                                                        if( !!( className && ( _ + className + _ ).indexOf( val ) > -1 ) ^ isNot ) tmp[ ++n ] = xnode;\r
                                                };\r
                                        } else {\r
@@ -440,7 +526,7 @@ function X_Node_Selector__parse( query, last ){
                                                // 諦めて、funcAttrを呼ぶ\r
                                                // flag_call  = ($.browser.safari && key === 'selected');\r
                                                // getAttributeを使わない\r
-                                               useName = X.UA.IE && key !== 'href' && key !== 'src';\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
@@ -448,15 +534,16 @@ function X_Node_Selector__parse( query, last ){
                                                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
+                                                               key === 'tag' ? xnode[ '_tag' ] :\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_Node_Attr_renameForDOM[ key ] || key ] :\r
                                                                //      elem.getAttribute( key, 2 );\r
-                                                       flag = attr != null;// && ( !useName || attr !== '' );\r
+                                                       flag = !!attr;// && ( !useName || attr !== '' );\r
                                                        if( flag && op ){\r
                                                                if( toLower ) attr = attr.toLowerCase();\r
                                                                \r
@@ -509,13 +596,12 @@ function X_Node_Selector__parse( query, last ){
                        for( i = 0, n = -1; i < l; ++i ){\r
                                //alert( 'multi:' + i )\r
                                xnode = ret[ i ];\r
-                               if( !merge[ uid = xnode._uid ] ){\r
+                               if( !merge[ uid = xnode[ '_uid' ] ] ){\r
                                        merge[ uid ] = true;\r
                                        xnodes[ ++n ] = xnode;\r
                                };\r
                        };\r
-                       X_Node_Selector__sortElementOrder( ret = [], xnodes, hasRoot ? [ HTML ] : HTML._xnodes );\r
-                       xnodes = ret;\r
+                       xnodes = X_Node_Selector__sortElementOrder( [], xnodes, hasRoot ? [ HTML ] : HTML[ '_xnodes' ] );\r
                };\r
 \r
                return xnodes.length === 1 ? xnodes[ 0 ] : new X_NodeList( xnodes );\r
@@ -527,58 +613,105 @@ function X_Node_Selector__parse( query, last ){
                        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
+                       if( !child[ '_tag' ] ) continue;\r
+\r
+                       j = list.indexOf( child );\r
+                       if( j !== -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
+                               if( list.length === 2 ){\r
+                                       newList[ newList.length ] = list[ j === 0 ? 1 : 0 ];\r
+                                       return newList;\r
                                };\r
-                               if( list.length === 0 ) return true;\r
+                               list.splice( j, 1 );\r
                        };\r
-                       if( ( _xnodes = child._xnodes ) && X_Node_Selector__sortElementOrder( newList, list, _xnodes ) ){\r
-                               return true;\r
+\r
+                       if( ( _xnodes = child[ '_xnodes' ] ) && X_Node_Selector__sortElementOrder( newList, list, _xnodes ) ){\r
+                               return newList;\r
                        };\r
                };\r
        };\r
-       \r
-       function X_Node_Selector__fetchElements( list, parent, tag ){\r
-               var xnodes = parent._xnodes,\r
-                       l      = xnodes.length,\r
+\r
+       function X_Node_Selector__fetchElements( list, xnodes, tag, merge ){\r
+               var l      = xnodes.length,\r
                        i      = 0,\r
-                       child;\r
+                       child, uid, _tag, _xnodes;\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_Node_Selector__fetchElements( list, child, tag );\r
+                       uid   = child[ '_uid' ];\r
+                       _tag  = child[ '_tag' ];\r
+                       if( !merge[ uid ] && _tag ){\r
+                               merge[ uid ] = true;\r
+                               ( !tag || tag === _tag ) && ( list[ list.length ] = child );\r
+                               if( ( _xnodes = child[ '_xnodes' ] ) && ( 1 < _xnodes.length || ( _xnodes[ 0 ] && _xnodes[ 0 ][ '_tag' ] ) ) ){\r
+                                       X_Node_Selector__fetchElements( list, _xnodes, tag, merge );\r
+                               };\r
                        };\r
                };\r
        };\r
-\r
+/*\r
+       function X_Node_Selector__fetchElements( list, parent, tag, merge ){\r
+               \r
+               var xnodes   = parent[ '_xnodes' ],\r
+                       memory   = {\r
+                               i      : 0,\r
+                               l      : xnodes.length,\r
+                               xnodes : xnodes\r
+                       },              \r
+                       memories = [ memory ],\r
+                       i, l, xnode,\r
+                       uid, _xnodes;\r
+               \r
+               while( memories.length ){\r
+                       memory = memories.pop();\r
+                       xnodes = memory.xnodes;\r
+                       i      = memory.i;\r
+                       l      = memory.l;\r
+                       for( ; i < l; ++i ){\r
+                               xnode = xnodes[ i ];\r
+                               uid   = xnode[ '_uid' ];\r
+                               if( !merge[ uid ] && xnode[ '_tag' ] ){\r
+                                       if( !tag || xnode[ '_tag' ] === tag ) list[ list.length ] = xnode;\r
+                                       \r
+                                       if( _xnodes = xnode[ '_xnodes' ] ){\r
+                                               if( 1 < _xnodes.length || ( _xnodes[ 0 ] && _xnodes[ 0 ][ '_tag' ] ) ){\r
+                                                       memory.i = i + 1;\r
+                                                       memory.l = l;\r
+                                                       memory.xnodes = xnodes;\r
+                                                       memories[ memories.length ] = memory;\r
+                                                       memories[ memories.length ] = {\r
+                                                               i      : 0,\r
+                                                               l      : _xnodes.length,\r
+                                                               xnodes : _xnodes\r
+                                                       };\r
+                                                       merge[ uid ] = true;\r
+                                                       break;\r
+                                               };\r
+                                       };\r
+                               };\r
+                               merge[ uid ] = true;\r
+                       };\r
+               };\r
+       };\r
+ */\r
        function X_Node_Selector__funcSelectorChild( 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
+                       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
+                               for( node = xnode[ 'prev' ](); node; node = node[ 'prev' ]() ){\r
+                                       if( node[ '_tag' ] && ( 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
+                               for( node = xnode[ 'next' ](); node; node = node[ 'next' ]() ){\r
+                                       if( node[ '_tag' ] && ( flag_all || tagName === node[ '_tag' ] ) ){\r
                                                tmp = false;\r
                                                break;\r
                                        };              \r
@@ -590,20 +723,19 @@ function X_Node_Selector__parse( query, last ){
                return res;\r
        };\r
        function X_Node_Selector__funcSelectorNth( pointer, sibling, flag_all, flags, xnodes, a, b ){\r
-               var _data    = funcData,\r
-                       res      = [],\r
+               var 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
+                       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
+                               for( c = 0, node = xnode.parent[ pointer ](), tagName = flag_all || xnode[ '_tag' ]; node; node = node[ sibling ]() ){\r
+                                       if( node[ '_tag' ] && ( flag_all || tagName === node[ '_tag' ] ) ){\r
                                                ++c;\r
-                                               checked[ node._uid ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0;\r
+                                               checked[ node[ '_uid' ] ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0;\r
                                        };                                                      \r
                                };\r
                                tmp = checked[ uid ];\r
@@ -617,23 +749,23 @@ function X_Node_Selector__parse( query, last ){
                        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
+                       if( xnode[ '_attrs' ] && xnode[ '_attrs' ][ prop ] ^ flag_not ) res[ ++n ] = xnode;\r
                };\r
                return res;\r
        };\r
 \r
 var X_Node_Selector__filter = {\r
-       root : function( elem ){\r
-               return elem === ( elem.ownerDocument || elem.document ).documentElement;\r
+       'root' : function(){\r
+               return X_Node_html;\r
        },\r
-       target : {\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
+                               if( ( ( xnode[ '_id' ] || xnode[ '_attrs' ] && xnode[ '_attrs' ][ 'name' ] ) === hash ) ^ flag_not ) res[ ++n ] = xnode;                                                \r
                        };\r
                        return res;\r
                }\r
@@ -657,26 +789,26 @@ var X_Node_Selector__filter = {
                m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorChild( 0, false, flags, xnodes ); }\r
        },\r
        'nth-child' : {\r
-               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'firstChild', 'nextNode', true, flags, xnodes, a, b ); }\r
+               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'firstChild', 'next', true, flags, xnodes, a, b ); }\r
        },\r
        'nth-last-child' : {\r
-               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'lastChild', 'prevNode', true, flags, xnodes, a, b ); }\r
+               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'lastChild', 'prev', true, flags, xnodes, a, b ); }\r
        },\r
        'nth-of-type' : {\r
-               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'firstChild', 'nextNode', false, flags, xnodes, a, b ); }\r
+               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'firstChild', 'next', false, flags, xnodes, a, b ); }\r
        },\r
        'nth-last-of-type' : {\r
-               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'lastChild', 'prevNode', false, flags, xnodes, a, b ); }\r
+               m : function( flags, xnodes, a, b ){ return X_Node_Selector__funcSelectorNth( 'lastChild', 'prev', false, flags, xnodes, a, b ); }\r
        },\r
-       empty : {\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
+                               for( node = xnode[ 'firstChild' ](); node; node = node[ 'next' ]() ){\r
+                                       if( node[ '_tag' ] || node[ '_text' ] ){\r
                                                tmp = false;\r
                                                break;\r
                                        };                              \r
@@ -686,25 +818,24 @@ var X_Node_Selector__filter = {
                        return res;\r
                }\r
        },\r
-       link : {\r
+       'link' : {\r
                m : function( flags, xnodes ){\r
-                       var links = ( xnodes[ 0 ].ownerDocument || xnodes[ 0 ].document ).links,\r
-                               _data = funcData,\r
+                       var links = document.links,\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
+                               checked[ ( 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
+                               if( checked[ xnode[ '_uid' ] ] ^ flag_not ) res[ ++n ] = xnode;\r
                        };\r
                        return res;\r
                }\r
        },\r
-       lang : {\r
+       'lang' : {\r
                m : function( flags, xnodes, arg ){\r
                        var res = [],\r
                                //reg = new RegExp('^' + arg, 'i'),\r
@@ -712,7 +843,7 @@ var X_Node_Selector__filter = {
                                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
+                               while( tmp && !( lang = tmp[ '_attrs' ] && tmp[ '_attrs' ][ 'lang' ] ) ){\r
                                        tmp = tmp.parent;\r
                                };\r
                                //tmp = !!(tmp && reg.test(tmp.getAttribute('lang')));\r
@@ -721,22 +852,22 @@ var X_Node_Selector__filter = {
                        return res;\r
                }\r
        },\r
-       enabled : {\r
+       'enabled' : {\r
                m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorProp( 'disabled', false, flags, xnodes ); }\r
        },\r
-       disabled : {\r
+       'disabled' : {\r
                m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorProp( 'disabled', true, flags, xnodes ); }\r
        },\r
-       checked : {\r
+       'checked' : {\r
                m : function( flags, xnodes ){ return X_Node_Selector__funcSelectorProp( 'checked', true, flags, xnodes ); }\r
        },\r
-       contains : {\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
+                               if ( ( -1 < ( xnode[ 'text' ]() ).indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xnode;                                             \r
                        };\r
                        return res;\r
                }\r