OSDN Git Service

Version 0.6.17, X.Dom.Query work a little.
authoritozyun <itozyun@user.sourceforge.jp>
Tue, 11 Feb 2014 21:50:54 +0000 (06:50 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Tue, 11 Feb 2014 21:50:54 +0000 (06:50 +0900)
0.4.x/test/index.html
0.6.x/js/core/00_X.js
0.6.x/js/core/00_builtin.js
0.6.x/js/core/06_XEventDispatcher.js
0.6.x/js/dom/10_XDom.js
0.6.x/js/dom/11_XDomNode.js
0.6.x/js/dom/12_XDomEvent.js
0.6.x/js/dom/14_XDomAttr.js
0.6.x/js/dom/17_XDomNodeList.js
0.6.x/js/dom/18_XDomQuery.js
0.6.x/js/dom/19_XDomParser.js

index 01f0bb4..d99f1ce 100644 (file)
@@ -35,6 +35,8 @@
                                        <h2>テストインデックス</h2>\r
                                        <h3>ぺったんR html 実証サンプル</h3>\r
                                        <dl class="dl-table clearfix">\r
+                                               <dt><a href="html2comic_0.4.html">version 0.4 (14.01.11)</a></dt>\r
+                                               <dd>ぺったんR html 実証サンプル version 0.4</dd>      \r
                                                <dt><a href="html2comic_0.3.html">version 0.3 (13.09.23)</a></dt>\r
                                                <dd>ぺったんR html 実証サンプル version 0.3</dd>      \r
                                                <dt><a href="html2comic_0.2.html">version 0.2 (13.08.10)</a></dt>\r
index 5dfe13e..93757f8 100644 (file)
@@ -1,9 +1,9 @@
-if( !window['console'] ) console = { log : function(){} };\r
+if( !window['console'] ) console = { log : function(a){alert(a)} };\r
 \r
 var undefined,\r
        X = X || {\r
                \r
-               VERSION : '0.6.13',\r
+               VERSION : '0.6.17',\r
                \r
                bootTime : + new Date,\r
                \r
@@ -11,11 +11,13 @@ var undefined,
                \r
                emptyFunction : new Function,\r
                \r
+               // defer の場合もあるので、document.readyState を見る\r
                inHead        : (function( s ){\r
+                       if( !s ) return;\r
                        s = s[ s.length - 1 ];\r
                        // Dom0 || Dom1\r
                        return ( s.parentElement || s.parentNode ).tagName.toLowerCase() === 'head';\r
-               })( document.scripts || document.getElementsByTagName( 'script' ) || document.all.tags( 'script' ) ),\r
+               })( document.scripts || document.getElementsByTagName && document.getElementsByTagName( 'script' ) || document.all && document.all.tags( 'script' ) ),\r
 \r
                parse : function( v ){\r
                        var _v, n;\r
@@ -39,23 +41,6 @@ var undefined,
                        return v;\r
                },\r
                \r
-               skipCleanupTagNames : 'pre,textarea,code,kbd,samp,xmp,plaintext,listing'.split( ',' ),\r
-               \r
-               cleanupWhiteSpace : function( text ){\r
-                       var _ = ' ', __ = '  ';\r
-                       text.indexOf( '\r\n' ) !== -1 && ( text = text.split( '\r\n' ).join( _ ) );\r
-                       text.indexOf( '\n\r' ) !== -1 && ( text = text.split( '\n\r' ).join( _ ) );\r
-                       text.indexOf( '\t' )   !== -1 && ( text = text.split( '\t' ).join( _ ) );\r
-                       text.indexOf( '\r' )   !== -1 && ( text = text.split( '\r' ).join( _ ) );\r
-                       text.indexOf( '\n' )   !== -1 && ( text = text.split( '\n' ).join( _ ) );\r
-                       text.indexOf( '\f' )   !== -1 && ( text = text.split( '\f' ).join( _ ) );\r
-                       text.indexOf( '\b' )   !== -1 && ( text = text.split( '\b' ).join( _ ) );\r
-                       while( text.indexOf( __ ) !== -1 ){\r
-                               text = text.split( __ ).join( _ );\r
-                       };\r
-                       return text;\r
-               },\r
-               \r
                isEmptyObject : function( v ){\r
                        if( v.length !== 0 ) return false;\r
                        for( var p in v ){\r
@@ -70,6 +55,10 @@ var undefined,
                                if( array1.indexOf( array2[ --i ] ) === -1 ) return false;\r
                        };\r
                        return true;\r
+               },\r
+               \r
+               findFromArray : function( fakeArray, elm ){\r
+                       \r
                }\r
        };\r
        \r
index f2a5207..71dc2cd 100644 (file)
@@ -12,7 +12,10 @@ Function.prototype.apply || (Function.prototype.apply = function (x, y) {
        if( x === window ){\r
                x.__apply = void 0;\r
        } else {\r
-               delete x.__apply ? x.__apply : x.constructor.prototype.__apply ;\r
+               if( x.constructor && x.constructor.prototype.__apply ){\r
+                       delete x.__apply;\r
+               } else\r
+               if( x.__apply ) delete x.__apply;\r
        };\r
        \r
        x.__apply = this;\r
@@ -41,7 +44,11 @@ Function.prototype.apply || (Function.prototype.apply = function (x, y) {
        if( x === window ){\r
                x.__apply = void 0;\r
        } else {\r
-               delete x.__apply ? x.__apply : x.constructor.prototype.__apply ;\r
+               //delete x.__apply ? x.__apply : x.constructor.prototype.__apply ;\r
+               if( x.constructor && x.constructor.prototype.__apply ){\r
+                       delete x.__apply;\r
+               } else\r
+               if( x.__apply ) delete x.__apply;\r
        };\r
        return r;\r
 });\r
@@ -161,7 +168,7 @@ window.decodeURI || (window.decodeURI = function (x) {
 */\r
 \r
 // 手抜き\r
-window.decodeURIComponent || (window.decodeURIComponent = window.decodeURI);\r
+//window.decodeURIComponent || (window.decodeURIComponent = window.decodeURI);\r
 \r
 \r
 /*\r
@@ -169,6 +176,7 @@ window.decodeURIComponent || (window.decodeURIComponent = window.decodeURI);
  */\r
 \r
 // replace(RegExp, Function)対応\r
+/*\r
 if (window.ActiveXObject ? !Number.prototype.toFixed : (!navigator.taintEnabled && !document.createElement("input").setSelectionRange))\r
        (function () {\r
                var g = String.prototype.replace;\r
@@ -204,4 +212,6 @@ if (window.ActiveXObject ? !Number.prototype.toFixed : (!navigator.taintEnabled
                        }\r
                        return g.call(s, x, z);\r
                };\r
-       })();
\ No newline at end of file
+       })(); */\r
+       \r
+\r
index 0cf8f6c..5c4aac4 100644 (file)
@@ -10,12 +10,21 @@ X.EventDispatcher =
                        _dispatching  : 0, // dispatch 中の unlisten で使用\r
                        _unlistens    : null, // dispatch 中の unlisten で使用\r
                        _needsIndex   : false, // listening で index を返す\r
+                       _reserves     : null,\r
                        _killReserved : false,\r
                        \r
                        listen : function( type, arg1, arg2, arg3 ){\r
                                var list = this._listeners,\r
-                                       f;\r
+                                       r, f;\r
+                               if( this._dispatching ){\r
+                                       // todo\r
+                                       // reserve\r
+                                       if( !this._reserves ) this._reserves = [];\r
+                                       this._reserves[ this._reserves.length ] = [ type, arg1, arg2, arg3 ];\r
+                                       return this;\r
+                               } else\r
                                if( this.listening( type, arg1, arg2, arg3 ) ) return this;\r
+\r
                                if( !list ) list = this._listeners = {};\r
                                if( !( list = list[ type ] ) ) list = this._listeners[ type ] = [];\r
                                list[ list.length ] = f =\r
@@ -33,7 +42,7 @@ X.EventDispatcher =
                        },\r
                        unlisten : function( type, arg1, arg2, arg3 ){\r
                                var list = this._listeners,\r
-                                       i, f;\r
+                                       unlistens, i, f;\r
                                if( !list ) return this;\r
                                if( type === undefined ){\r
                                        // 全て削除\r
@@ -51,14 +60,27 @@ X.EventDispatcher =
                                        return this;\r
                                };\r
                                \r
+                               if( this._reserves ){\r
+                                       for( i = this._reserves.length; i; ){\r
+                                               f = this._reserves[ --i ];\r
+                                               if( f[ 0 ] === type && f[ 1 ] === arg1 && f[ 2 ] === arg2 && f[ 3 ] === arg3 ){\r
+                                                       this._reserves.splice( i, 1 );\r
+                                                       if( !this._reserves.legth ) delete this._reserves;\r
+                                                       return this;\r
+                                               };\r
+                                       };\r
+                               };\r
+                               \r
                                this._needsIndex = true;\r
                                i = this.listening( type, arg1, arg2, arg3 );\r
                                delete this._needsIndex;\r
                                if( i === false ) return this;\r
 \r
                                f = ( list = list[ type ] )[ i ];\r
-                               if( this._dispatching ){\r
-                                       this._unlistens[ this._unlistens.length ] = f;\r
+                               if( unlistens = this._unlistens ){\r
+                                       ( unlistens = unlistens[ type ] ) ?\r
+                                               ( unlistens[ unlistens.length ] = f ) :\r
+                                               ( this._unlistens[ type ] = [ f ] );\r
                                } else {\r
                                        delete f.once;\r
                                        f.kill === X.Callback._kill && f.kill();\r
@@ -71,10 +93,16 @@ X.EventDispatcher =
                                return this;\r
                        },\r
                        listening : function( type, arg1, arg2, arg3 ){\r
-                               var list = this._listeners, i, f;\r
+                               var list = this._listeners, unlistens, i, f;\r
                                if( type === undefined ) return !!list;\r
                                if( !list || !( list = list[ type ] ) ) return false;\r
                                if( arg1 === undefined ) return true;\r
+                               if( ( unlistens = this._unlistens ) && ( unlistens = unlistens[ type ] ) ){\r
+                                       for( i = unlistens.length; i; ){\r
+                                               f = unlistens[ --i ];\r
+                                               if( f === arg1 || ( f.same && f.same( arg1, arg2, arg3 ) ) ) return false;\r
+                                       };\r
+                               };\r
                                for( i = list.length; i; ){\r
                                        f = list[ --i ];\r
                                        if( f === arg1 || ( f.same && f.same( arg1, arg2, arg3 ) ) ) return this._needsIndex ? i : true;\r
@@ -89,25 +117,30 @@ X.EventDispatcher =
                         */\r
                        dispatch : function( e ){\r
                                // dispatch 中の listen は?\r
-                               var list = this._listeners,\r
-                                       ret  = X.Callback.NONE,\r
-                                       i, f, r, sysOnly;\r
+                               var list  = this._listeners,\r
+                                       ret   = X.Callback.NONE,\r
+                                       type  = e.type,\r
+                                       unlistens, i, l, f, r, sysOnly;\r
 \r
-                               if( !list || !( list = list[ e.type ] ) ) return ret;\r
+                               if( !list || !( list = list[ type ] ) ) return ret;\r
                                \r
                                ++this._dispatching;\r
-                               this._unlistens = this._unlistens || [];\r
+                               \r
+                               // todo:\r
+                               // type も保存\r
+                               this._unlistens = this._unlistens || {};\r
+                               unlistens = this._unlistens[ type ];\r
                                \r
                                for( i = 0; i < list.length; ++i ){\r
                                        f = list[ i ];\r
-                                       if( this._unlistens.length && this._unlistens.indexOf( f ) !== -1 ){\r
-                                               continue;\r
-                                       };\r
+                                       if( unlistens && unlistens.indexOf( f ) !== -1 ) continue;\r
 \r
                                        r = typeof f === 'function' ? f( e ) : f.handleEvent( e );\r
                                        \r
                                        if( f.once === true || r & X.Callback.UN_LISTEN ){\r
-                                               this._unlistens[ this._unlistens.length ] = f;\r
+                                               unlistens ?\r
+                                                       ( unlistens[ unlistens.length ] = f ) :\r
+                                                       ( unlistens = this._unlistens[ type ] = [ f ] );\r
                                        };\r
 \r
                                        if( r & X.Callback.STOP_NOW ){\r
@@ -118,13 +151,30 @@ X.EventDispatcher =
                                \r
                                if( ( --this._dispatching ) === 0 ){\r
                                        // dispatch 中に unlisten された要素の削除\r
-                                       for( i = this._unlistens.length ; i; ){\r
-                                               this.unlisten( e.type, this._unlistens[ --i ] );\r
-                                       };\r
+                                       unlistens = this._unlistens;\r
                                        delete this._dispatching;\r
-                                       delete this._unlistens;\r
+                                       delete this._unlistens;                                 \r
+                                       \r
+                                       for( type in unlistens ){\r
+                                               list = unlistens[ type ];\r
+                                               for( i = list.length; i; ){\r
+                                                       this.unlisten( type, list[ --i ] );\r
+                                               };\r
+                                               unlistens.length = 0;\r
+                                       };\r
                                        \r
-                                       this._killReserved && this.kill();\r
+                                       if( this._killReserved ){\r
+                                               this.kill();\r
+                                       } else\r
+                                       if( list = this._reserves ){\r
+                                               for( i = 0, l = list.length; i < l; ++i ){\r
+                                                       f = list[ i ];\r
+                                                       this.listen( f[ 0 ], f[ 1 ], f[ 2 ], f[ 3 ] );\r
+                                                       f.length = 0;\r
+                                               };\r
+                                               list.length = 0;\r
+                                               delete this._reserves;\r
+                                       };\r
                                };\r
                                \r
                                return ret;\r
index 0cdeed8..d51ae76 100644 (file)
 \r
 })( window, document );\r
 \r
-X.Dom.Dirty = {\r
-       CLEAN     :  0,\r
-       TREE      :  1, // width, height, x, y\r
-       CONTENT   :  2,  // width, height, x, y textNode の内容\r
-       CLASSNAME :  4, // _getCharSize, width, height, x, y\r
-       CSS       :  8, // _getCharSize, width, height, x, y\r
-       ATTR      : 16  // _getCharSize, width, height, x, y\r
+X.Dom.skipCleanupTagNames = 'pre,textarea,code,kbd,samp,xmp,plaintext,listing'.split( ',' );\r
+               \r
+X.Dom.cleanupWhiteSpace = function( text ){\r
+       var _ = ' ', __ = '  ';\r
+       text.indexOf( '\r\n' ) !== -1 && ( text = text.split( '\r\n' ).join( _ ) );\r
+       text.indexOf( '\n\r' ) !== -1 && ( text = text.split( '\n\r' ).join( _ ) );\r
+       text.indexOf( '\t' )   !== -1 && ( text = text.split( '\t' ).join( _ ) );\r
+       text.indexOf( '\r' )   !== -1 && ( text = text.split( '\r' ).join( _ ) );\r
+       text.indexOf( '\n' )   !== -1 && ( text = text.split( '\n' ).join( _ ) );\r
+       text.indexOf( '\f' )   !== -1 && ( text = text.split( '\f' ).join( _ ) );\r
+       text.indexOf( '\b' )   !== -1 && ( text = text.split( '\b' ).join( _ ) );\r
+       while( text.indexOf( __ ) !== -1 ){\r
+               text = text.split( __ ).join( _ );\r
+       };\r
+       return text;\r
 };\r
 \r
-\r
 /*\r
  * original\r
  * AS3で相対パスを絶対パスに変換する\r
@@ -162,3 +169,13 @@ X.Dom.getAbsolutePath = function( path ){
        };\r
        return [ _ary[ 0 ], ss, ary.join( s ), s, path ].join( '' );\r
 };\r
+\r
+\r
+X.Dom.Dirty = {\r
+       CLEAN     :  0,\r
+       TREE      :  1, // width, height, x, y\r
+       CONTENT   :  2,  // width, height, x, y textNode の内容\r
+       CLASSNAME :  4, // _getCharSize, width, height, x, y\r
+       CSS       :  8, // _getCharSize, width, height, x, y\r
+       ATTR      : 16  // _getCharSize, width, height, x, y\r
+};
\ No newline at end of file
index 960cc1f..cf650fb 100644 (file)
@@ -21,6 +21,7 @@ X.Dom.Node = X.EventDispatcher.inherits(
 \r
                _attrs     : null, // X.Dom.Attr\r
                _attrText  : '',\r
+               _attrUpdated : false,\r
                _css       : null, // X.Dom.Style\r
                _cssText   : '',\r
                _styleText : '',\r
@@ -147,6 +148,20 @@ Node.createText = function( text ){
        return new Node( text );\r
 };\r
 \r
+\r
+Node.getRoot = function( xnode ){\r
+       return Node._document;\r
+       //return xnode.root._rawNode.documentElement ? node : node.ownerDocument || node.document;\r
+};\r
+       // XMLかどうかを判別する\r
+Node.isXmlDocument =\r
+       X.UA.IE && X.UA.IE < 5 ?\r
+               X.emptyFunction :\r
+               (function( root ){\r
+                       return root._rawNode.createElement( 'p' ).tagName !== root._rawNode.createElement( 'P' ).tagName;\r
+               });\r
+\r
+\r
 /* --------------------------------------\r
  *  Dom Core 1\r
  */\r
@@ -187,7 +202,7 @@ Node._systemNode = null;// = Node._chashe[ ? ]
  */\r
 Node.prototype._create =\r
        // document.createElement of ie4 is only for OPTION & IMAGE.\r
-       document.appendChild ? (function( isChild ){\r
+       document.getElementById ? (function( isChild ){\r
                var tag = this._tag, node, frg;\r
 /*\r
  * http://d.hatena.ne.jp/uupaa/20080718/1216362040\r
@@ -203,7 +218,7 @@ Node.prototype._create =
                                tag && X.UA.IE ?\r
                                        document.createElement( [\r
                                                '<', this._tag,\r
-                                                       'UID="', this._uid, '"',\r
+                                                       ' UID="', this._uid, '"',\r
                                                        this._id ? ' id="' + this._id + '"' : '',\r
                                                        this._classText,\r
                                                        ( this._attrUpdated ? ( this._attrText = X.Dom.Attr.objToAttrText( this._attrs ) ) : this._attrText ),\r
@@ -212,6 +227,7 @@ Node.prototype._create =
                                tag ?\r
                                        document.createElement( tag ) :\r
                                        document.createTextNode( this._text ) );\r
+                       delete this._attrUpdated;\r
                };\r
                // fragument がある場合 children も足して\r
                // Mozilla: 1.0+, IE: 6.0+, Netscape: 2.0+, Safari: 1.0+, Opera: 7.0+\r
@@ -242,14 +258,13 @@ Node.prototype._create =
                        };\r
                };\r
                html = [\r
-                       '<', this._tag, ' id="', ( this._id || ( 'ie4uid' + this._uid ) ), '"',\r
+                       '<', this._tag, ' id=', ( this._id || ( 'ie4uid' + this._uid ) ),\r
                        this._classText,\r
                        ( this._attrUpdated ? ( this._attrText = X.Dom.Attr.objToAttrText( this._attrs ) ) : this._attrText ),\r
                        this._styleText,\r
                '>' ];\r
                delete this._attrUpdated;\r
                \r
-               \r
                if( ( children = this._xnodes ) && ( l = children.length ) ){\r
                        for( i = 0; i < l; ++i ){\r
                                html[ html.length ] = children[ i ]._create( true, true );\r
@@ -261,10 +276,10 @@ Node.prototype._create =
        (function(){});\r
 \r
 Node.prototype._afterCreate =\r
-       ( document.appendChild ) ? (function( parent ){\r
+       ( document.getElementById ) ? (function( parent ){\r
                var _children = this._xnodes,\r
                        node      = this._rawNode,\r
-                       eChildren = node.childNodes,\r
+                       eChildren = node && node.nodeType === 1 && node.childNodes,\r
                        attrs, p, _child, i, l;\r
                this.parent = parent;\r
                if( this._xnodeType !== 1 ) return this;\r
@@ -338,7 +353,7 @@ Node.prototype.create = function( tag, opt_attrs, opt_css ){
        elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
        \r
        if( elm && !Node.skipCreate ){\r
-               if( document.appendChild ){\r
+               if( document.getElementById ){\r
                        // ie では iframe の frameborder が無視されるので、<iframe class=> を渡す\r
                        elm.appendChild( document.createElement( tag ) );\r
                        xnode = new Node( elm.lastChild );\r
@@ -466,7 +481,7 @@ Node.prototype.append = function( v ){
                case Node.IS_RAW_HTML :\r
                case Node.IS_RAW_TEXT :\r
                        if( elm ){\r
-                               if( document.appendChild ){\r
+                               if( document.getElementById ){\r
                                        elm.appendChild( v );\r
                                } else\r
                                if( document.all ){\r
@@ -487,7 +502,7 @@ Node.prototype.append = function( v ){
                        // 親の xnodes から v を消す\r
                        v.parent && ( i = v.parent._xnodes.indexOf( v ) ) !== -1 && v.parent._xnodes.splice( i, 1 );\r
                        if( elm ){\r
-                               if( document.appendChild ){\r
+                               if( document.getElementById ){\r
                                        elm.appendChild( v._create() );\r
                                        v._afterCreate( this );\r
                                } else\r
@@ -549,7 +564,7 @@ Node.prototype.appendAt = function( start, v ){
                case Node.IS_RAW_HTML :\r
                case Node.IS_RAW_TEXT :\r
                        if( elm ){\r
-                               if( document.appendChild ){\r
+                               if( document.getElementById ){\r
                                        elm.insertBefore( v, elm.childNodes[ start ] );\r
                                } else\r
                                if( document.all ){\r
@@ -594,7 +609,7 @@ Node.prototype.appendAt = function( start, v ){
                        // 親の xnodes から v を消す\r
                        v.parent && ( i = v.parent._xnodes.indexOf( v ) ) !== -1 && v.parent._xnodes.splice( i, 1 );\r
                        if( elm ){\r
-                               if( document.appendChild ){\r
+                               if( document.getElementById ){\r
                                        elm.insertBefore( v._create(), elm.childNodes[ start ] );\r
                                        v._afterCreate( this );\r
                                } else\r
@@ -667,10 +682,10 @@ Node.prototype.replace = function( v ){
  *  Remove\r
  */\r
 Node.prototype.remove = function(){\r
-       var parent = this.parent;\r
+       var parent = this.parent, elm;\r
                \r
        if( !parent ) return this;\r
-       if( document.removeChild ){\r
+       if( document.getElementById ){\r
                if( this._rawNode ){\r
                        this._xnodeType === 1 && this._beforeRemove();\r
                        parent._rawNode.removeChild( this._rawNode );\r
@@ -698,7 +713,7 @@ Node.prototype.remove = function(){
 };\r
 \r
 Node.prototype._beforeRemove = \r
-       document.removeChild ?\r
+       document.getElementById ?\r
                ( function(){\r
                        var elm = this._rawNode, children,\r
                                child, i, l;\r
@@ -728,7 +743,7 @@ Node.prototype._beforeRemove =
                (function(){});\r
 \r
 Node.prototype.empty =\r
-       document.removeChild ?\r
+       document.getElementById ?\r
                ( function(){\r
                        var elm = this._rawNode, children,\r
                                child, i, l;\r
@@ -775,7 +790,7 @@ Node.prototype.destroy = function(){
                // stop()\r
                // remove() empty()\r
                \r
-               document.removeChild && this.parent._rawNode.removeChild( elm );\r
+               document.getElementById && this.parent._rawNode.removeChild( elm );\r
        };\r
        delete Node._chashe[ this._uid ];\r
        this.kill();\r
@@ -818,14 +833,18 @@ if( !document.getElementById && document.all ){
                var children = this._xnodes,\r
                        i, l, html;\r
                if( !this._ie4dirtyChildren ){\r
-                       for( i = 0, l = children.length; i < l; ++i ){\r
-                               children[ i ]._ie4commitUpdate();\r
+                       if( children && ( l = children.length ) ){\r
+                               for( i = 0; i < l; ++i ){\r
+                                       children[ i ]._ie4commitUpdate();\r
+                               };                              \r
                        };\r
                        return this;\r
                };\r
                html = [];\r
-               for( i = 0, l = children.length; i < l; ++i ){\r
-                       html[ html.length ] = children[ i ]._create( true );\r
+               if( children && ( l = children.length ) ){\r
+                       for( i = 0; i < l; ++i ){\r
+                               html[ html.length ] = children[ i ]._create( true );\r
+                       };      \r
                };\r
                this._rawNode.innerHTML = html.join( '' );\r
                return this;\r
@@ -835,13 +854,17 @@ if( !document.getElementById && document.all ){
                var children = this._xnodes,\r
                        i, l;\r
                if( !this._ie4dirtyChildren ){\r
-                       for( i = 0, l = children.length; i < l; ++i ){\r
-                               children[ i ]._ie4afterUpdate();\r
+                       if( children && ( l = children.length ) ){\r
+                               for( i = 0; i < l; ++i ){\r
+                                       children[ i ]._ie4afterUpdate();\r
+                               };                              \r
                        };\r
                        return this;\r
                };\r
-               for( i = 0, l = children.length; i < l; ++i ){\r
-                       children[ i ]._afterCreate( this );\r
+               if( children && ( l = children.length ) ){\r
+                       for( i = 0; i < l; ++i ){\r
+                               children[ i ]._afterCreate( this );\r
+                       };      \r
                };\r
                delete this._ie4dirtyChildren;\r
        };\r
@@ -879,9 +902,12 @@ Node.prototype.contains = function( v ){
                                return false;\r
                };              \r
        };\r
+       //if( document.compareDocumentPosition ){\r
+       //      \r
+       //};\r
        children = this._xnodes;\r
        if( children.indexOf( v ) !== -1 ) return true;\r
-       if( ( node = this._rawNode ) && node === v.parentNode ) return;\r
+       if( ( node = this._rawNode ) && node === v.parentNode ) return false;\r
        for( i = children.length; i; ){\r
                if( children[ --i ].contains( v ) ) return true;\r
        };\r
@@ -946,7 +972,7 @@ Node.prototype.className = function( v ){
        // getter\r
        if(  typeof v !== 'string' ) return this._className;\r
        // setter\r
-       if( this._className === v ) return;\r
+       if( this._className === v ) return this;\r
        if( !v ) delete this._className;\r
        node = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
        if( node ) node.className = v;\r
@@ -964,14 +990,18 @@ Node.prototype.toggleClass = function(){
        \r
 };\r
 Node.prototype.hasClass = function( className ){\r
-       var cnames  = ( this._className || '' ).split( ' ' ),\r
-               _cnames = className.split( ' ' ),\r
-               i       = _cnames.length,\r
-               _cname;\r
-       for( ; i; ){\r
-               _cname = _cnames[ --i ];\r
-               if( _cname === '' ) continue;\r
-               if( cnames.indexOf( _cname ) === -1 ) return false;\r
+       var _ = ' ',\r
+               _className = this._className, i, name;\r
+       if( _className === className ) return true;\r
+       if( !_className ) return false;\r
+       \r
+       _className = _ + _className + _;\r
+       if( _className.indexOf( _ + className + _ ) !== -1 ) return true; // lucky hit\r
+       \r
+       for( className = className.split( _ ), i = className.length; i; ){\r
+               name = className[ --i ];\r
+               if( name === '' ) continue;\r
+               if( _className.indexOf( _ + name + _ ) === -1 ) return false;\r
        };\r
        return true;\r
 };\r
index 781cd59..c601263 100644 (file)
@@ -101,8 +101,8 @@ if( window.addEventListener ){
                        this.offsetX       = e.offsetX; // イベントターゲット左上からの座標
                        this.offsetY       = e.offsetY;                 
                } else {
-                       this.offsetX       = e.x - e.srcElement.offsetLeft; // e.x はイベントが発生要素の親要素を基準にした座標。
-                       this.offsetY       = e.y - e.srcElement.offsetTop;      
+                       //this.offsetX       = e.x - e.srcElement.offsetLeft; // e.x はイベント発生要素の親要素を基準にした座標。
+                       //this.offsetY       = e.y - e.srcElement.offsetTop;    
                };
                
                this.keyCode       = e.keyCode;
@@ -187,13 +187,11 @@ X.Dom.Node.prototype._addEvent =
 
 X.Dom.Node.prototype.unlisten = function( type /* , arg2, arg3, arg4 */ ){
        var list = this._listeners,
-               l    = list && type && list[ type ] && list[ type ].length;
+               l    = !this._dispatching && list && type !== undefined && list[ type ] && list[ type ].length;
        
        X.EventDispatcher.prototype.unlisten.apply( this, arguments );
        
-       if( type !== undefined && !this._dispatching && l && !list[ type ] ){
-               this._removeEvent( type );
-       };
+       l && !list[ type ] && this._removeEvent( type );
        
        return this;
 };
@@ -312,7 +310,7 @@ X.Dom.listenOnce( X.Dom.Event.VIEW_RESIZED, function(e){ console.log( 'X.Dom VIE
 X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
        
        Node._html = document.documentElement ? new Node( document.documentElement ) : null;
-       
+       //alert( document.all.tags('html')[ 0 ].tagName );
        var r    = Node.root = new Node( document.body ),
                body = r._rawNode,
                createTree, n = 0, s;
@@ -335,10 +333,10 @@ X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
                                                xnode._xnodes[ xnode._xnodes.length ] = _xnode = new Node( child );
                                                // attr の取得
                                                _xnode.parent = xnode;
-                                               child.childNodes.length && createTree( _xnode, child, skipCleanup || 0 <= X.skipCleanupTagNames.indexOf( child.tagName.toLowerCase() ) );
+                                               child.childNodes.length && createTree( _xnode, child, skipCleanup || 0 <= X.Dom.skipCleanupTagNames.indexOf( child.tagName ) );//.toLowerCase() ) );
                                                break;
                                        case 3 :
-                                               if( skipCleanup || ( ( text = child.data ) && ( text = X.cleanupWhiteSpace( text ) ) !== ' ' ) ){
+                                               if( skipCleanup || ( ( text = child.data ) && ( text = X.Dom.cleanupWhiteSpace( text ) ) !== ' ' ) ){
                                                        if( !skipCleanup ) child.data = text;
                                                        if( !xnode._xnodes ) xnode._xnodes = [];
                                                        xnode._xnodes[ xnode._xnodes.length ] = _xnode = new Node( child );
@@ -372,21 +370,22 @@ X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
                                        _xnode.parent    = xnode;
                                        _xnode._ie4dirty = true;
                                        if( _xnode._xnodeType === 1 ){
-                                               tag = child.tagName.toLowerCase();
+                                               tag = child.tagName; //.toLowerCase();
                                                if( _xnode._tag !== tag ){
                                                        alert( _xnode._tag + ' !== ' + child.tagName + ' * ' + child.outerHTML );
                                                } else {
                                                        _xnode._rawNode = child;
-                                                       !( _xnode._id = child.getAttribute( 'id' ) ) && child.setAttribute( 'id', ( _xnode._ie4uid = 'ie4uid' + _xnode._uid ) );
+                                                       //!( _xnode._id = child.getAttribute( 'id' ) ) && child.setAttribute( 'id', ( _xnode._ie4uid = 'ie4uid' + _xnode._uid ) );
+                                                       !_xnode._id && child.setAttribute( 'id', ( _xnode._ie4uid = 'ie4uid' + _xnode._uid ) );
                                                        child.setAttribute( 'UID', '' + _xnode._uid );
-                                                       child.children.length && createTree( _xnode, child.children, skipCleanup || 0 <= X.skipCleanupTagNames.indexOf( tag ) );
+                                                       child.children.length && createTree( _xnode, child.children, skipCleanup || 0 <= X.Dom.skipCleanupTagNames.indexOf( tag ) );
                                                        f = true;
                                                        ++j;
                                                        break;
                                                };
                                        } else
                                        if( _xnode._xnodeType === 3 ){
-                                               if( !skipCleanup && ( !( text = _xnode._text ) || ( text = X.cleanupWhiteSpace( text ) ) === ' ' ) ){
+                                               if( !skipCleanup && ( !( text = _xnode._text ) || ( text = X.Dom.cleanupWhiteSpace( text ) ) === ' ' ) ){
                                                        _xnode.remove();
                                                        ++n;
                                                        continue;
@@ -410,10 +409,11 @@ X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
                r._xnodes.push.apply( r._xnodes, X.Dom.parse( body.innerHTML, true ) );
                delete Node.skipCreate;
                createTree( r, body.children );
+               //alert(n +  ' ' + body.innerHTML);
                r._ie4reserveUpdate();
                //alert(n +  ' ' + body.innerHTML);
                r._ie4startUpdate();
-               //alert(n +  ' ' + body.innerHTML);
+               alert(n +  ' ' + body.innerHTML);
        } else {
                
        };
index 39c88ba..a9566b0 100644 (file)
@@ -216,6 +216,7 @@ X.Dom.Node.prototype.attr = function( nameOrObj /* v */ ){
                        this.__attr( node, attrs, p, nameOrObj[ p ] );\r
                };\r
                delete this._attrText; // = X.Dom.Attr.objToAttrText( attrs );\r
+               this._attrUpdated = true;\r
                return this;\r
        } else\r
        if( 1 < arguments.length ){\r
@@ -227,6 +228,7 @@ X.Dom.Node.prototype.attr = function( nameOrObj /* v */ ){
                        attrs, nameOrObj, arguments[ 1 ]\r
                );\r
                delete this._attrText; // = X.Dom.Attr.objToAttrText( attrs );\r
+               this._attrUpdated = true;\r
                return this;\r
        } else\r
        if( typeof nameOrObj === 'string' ){\r
@@ -257,7 +259,7 @@ X.Dom.Node.prototype.__attr = function( node, attrs, name, v ){
        };\r
        // id\r
        if( name === 'id' ){\r
-               this._id = v === 'ie4uid' + this._uid ? undefined : !v ? undefined : v;\r
+               this._id = v === 'ie4uid' + this._uid ? undefined : v || undefined;\r
                return;\r
        };\r
        // update this._attrs\r
index 8f98950..4894dc0 100644 (file)
@@ -3,26 +3,43 @@ X.Dom.NodeList = function( v ){
        var args = [],\r
                l    = arguments.length,\r
                i    = 0,\r
-               indexOf, xnode;\r
+               indexOf, xnode, j, n = 0, skip;\r
        for( ; i < l; ++i ){\r
+               //args.push( arguments[ i ] );\r
                args.push.apply( args, arguments[ i ] );\r
        };\r
+       //alert( arguments[ 0 ].length + ' , ' + args.length )\r
        if( ( l = args.length ) === 1 ) return new X.Dom.Node( args[ 0 ] );\r
-       if( !this || this.append !== Node.prototype.append ) return new X.Dom.NodeList( args );\r
+       if( !this || this.append !== X.Dom.NodeList.prototype.append ) return new X.Dom.NodeList( args );\r
        \r
-       this.__ = { type : 2 };\r
-       indexOf = Array.prototype.indexOf;\r
        for( i = 0; i < l; ++i ){\r
                xnode = args[ i ];\r
-               xnode = xnode && xnode.constructor === X.Dom.Node ? xnode : new X.Dom.Node( xnode );\r
-               if( xnode._xnodeType !== 0 && indexOf.call( this, xnode ) === -1 ){\r
-                       this[ this.length ] = xnode;\r
-                       ++this.length;\r
+               //xnode = xnode && xnode.constructor === X.Dom.Node ? xnode : new X.Dom.Node( xnode );\r
+               skip  = false;\r
+               if( xnode._xnodeType === 0 ) continue;\r
+               for( j = 0; j < n; ++j ){\r
+                       if( this[ j ] === xnode ){\r
+                               skip = true;\r
+                               break;\r
+                       };\r
+               };\r
+               if( !skip ){\r
+                       this[ n ] = xnode;\r
+                       n = ++this.length;      \r
                };\r
        };\r
 };\r
 X.Dom.NodeList.prototype.length = 0;\r
 \r
+X.Dom.NodeList.prototype.each = function( func ){\r
+       var l = this.length,\r
+               i = 0;\r
+       for( i = 0, l = this.length; i < l; ++i ){\r
+               if( func.call( this[ i ], i ) === false ) break;\r
+       };\r
+       return this;\r
+};\r
+\r
 /* --------------------------------------\r
  *  Fuction Base, multi, getter, setter,\r
  */\r
@@ -35,14 +52,12 @@ X.Dom.NodeList.prototype.length = 0;
                v = src[ p ];\r
                if( typeof v === 'funciton' && !target[ p ] ){\r
                        target[ p ] = multi = new Function( [\r
-                               'function functionBase(){',\r
-                                       'var a=arguments,s=a.callee,f=s.f,t=this,i,l=t.length;',\r
-                                       'if(0<l){',\r
-                                               'for(i=0;i<l;++i)if(i===l-1)return f.apply(t[i],a)else f.apply(t[i],a);',\r
-                                       '}',\r
-                                       'return f.apply(t,a)',\r
-                               '}'                     \r
-                       ].join( '' ));\r
+                               'var a=arguments,s=a.callee,f=s.f,t=this,i,l=t.length;',\r
+                               'if(0<l){',\r
+                                       'for(i=0;i<l;++i)if(i===l-1)return f.apply(t[i],a)else f.apply(t[i],a);',\r
+                               '}',\r
+                               'return f.apply(t,a)'\r
+                       ].join( '' ) );\r
                        multi.f = src[ p ];\r
                };\r
        };\r
index 2ea6a34..6796d0d 100644 (file)
-/* --------------------------------------
- *  getByID
- */
-X.Dom.getByID =
-       document.getElementById ?
-               (function( id ){
-                       return new X.Dom.Node( document.getElementById( id ) );
-               }) :
-       document.all ?
-               (function( id ){
-                       return new X.Dom.Node( document.all[ id ] );    
-               }) :
-               (function( id ){});
-
-/* --------------------------------------
- *  getByTag
- */
-Node.prototype.getByTag =
-       document.getElementsByTagName ?
-               function( tag ){
-                       var parent = this.parent, elm, tags;
-                       if( !parent || this._xnodeType !== -1 ) return;
-                       if( !( elm = this._rawNode ) ) return;
-                       return new X.Dom.NodeList( document.getElementsByTagName( tag ) );
-               } :
-       document.all ?
-               (function( tag ){
-                       var parent = this.parent, elm, tags;
-                       if( !parent || this._xnodeType !== -1 ) return;
-                       if( !( elm = this._ie4getRawNode() ) ) return;
-                       Node.root._ie4reserved === true && Node.root._ie4startUpdate();
-                       return new X.Dom.NodeList( elm.all.tags( tag ) );       
-               }) :
-               (function( tag ){});
-
-/* --------------------------------------
- *  getByClass
- */
-Node.prototype.getByClass =
-               document.getElementsByClassName ?
-                       (function( className ){
-                               var parent = this.parent, elm;
-                               if( !parent ) return;
-                               if( !( elm = this._rawNode ) || elm.nodeType !== 1 ) return;
-                               return new X.Dom.NodeList( elm.getElementsByClassName( className ) );
-                       }) :
-               document.getElementsByTagName ?
-                       (function( className ){
-                               var parent = this.parent,
-                                       live   = parent.getElementsByTagName( '*' ),
-                                       nodes  = [],
-                    test   = X.matchTest,
-                    node, i;
-                className = className.split( ' ' );
-                for( i = live.length; i; ){
-                       nodes[ --i ] = live[ i ];
-                };
-                               for( i = nodes.length; i; ){
-                                       node = nodes[ --i ];
-                                       ( node.nodeType !== 1 || !node.className || !node.className.length || !test( node.className.split( ' ' ), className ) ) && nodes.splice( i, 1 );
-                               };
-                               return new X.Dom.NodeList( nodes );
-                       }) :
-               document.all ?
-                       (function( parent, className ){
-                               var live  = parent.all,
-                                       nodes = [],
-                    test  = X.matchTest,
-                    node, i;
-                for( i = live.length; i; ){
-                       nodes[ --i ] = live[ i ];
-                };
-                               for( i = nodes.length; i; ){
-                                       node = nodes[ --i ];
-                                       ( !node.className || !node.className.length || !test( node.className.split( ' ' ), className ) ) && nodes.splice( i, 1 );
-                               };
-                               return new X.Dom.NodeList( nodes );
-                       }) :
-                       (function(){});
-
-X.Dom.find = Node.prototype.find = function( v ){
-       var root      = this.cnstructor === Node ? this : Node.root,
-               selectors = X.Dom.Query._parse( v ),
-               l, i, nodes, _nodes, selector,
-               name, key, operator, value,
-               j, m;
-       
-       if( !selectors ) return;
-       l     = selectors.length;
-       i     = 0;
-       nodes = [];
-       
-       for( ; i < l; ++i ){
-               selector = selectors[ i ];
-               if( 2 <= selector.length ){
-                       operator = selector[ 2 ];
-                       value    = selector[ 3 ];
-                       name     = key = selector[ 1 ];
-                       selector = selector[ 0 ];
-               };
-               switch( selector ){
-                       case 4 : // # id
-                               nodes = [ X.Dom.getById( name ) ];
-                               break;
-                       case 5 : // . classname
-                               _nodes = [];
-                               for( j = 0, m = nodes.length; j < m; ++j ){
-                                       _nodes = _nodes.concat( nodes[ j ].getByClass( name ) );
-                               };
-                               nodes = _nodes;
-                               break;
-                       case 6 : // :focus, :disabled ...
-                               switch( name ){
-                                       case 'focus' :
-                                       case 'disabled' :
-                                       case 'checked' :
-                                       case 'enabled' :
-                                       case 'empty' :
-                                       case 'only-of-type' :
-                                       case '' :
-                                       case 'target' :
-                                       case 'link' :
-                                       case 'visited' :
-                                       case 'hover' :
-                                       case 'active' :
-                                       case 'first-line' :
-                                       case 'first-letter' :
-                                       case 'before' :
-                                       case 'after' :
-                                       case ':selection' :
-                                       case 'lang()' :
-                                       case 'not()' :
-                               };
-                               break;
-                       case 7 : // [
-                               
-                               break;  
-                       case 8 : // . tagname
-                               _nodes = [];
-                               for( j = 0, m = nodes.length ; j < m; ++j ){
-                                       _nodes = _nodes.concat( nodes[ j ].getByTag( name ) );
-                               };
-                               nodes = _nodes;
-                               break;
-               };
-       };
-       return new X.Dom.NodeList( nodes );
-};
-
-X.Dom.Query = {
-       
-};
-
-X.Dom.Query._parse = function( query ){
-       var HASH_SELECTOR = {
-               ' '   : 0,
-               '>'   : 1,
-               '+'   : 2,
-               '~'   : 3,
-               '#'   : 4,
-               '.'   : 5,
-               ':'   : 6,
-               '['   : 7,
-               scope : 9,
-               root  : 10,
-               link  : 11
-       };
-       var OPERATORS = { "!=": 2, "~=": 3, "^=": 4, "$=": 5, "*=": 6, "|=": 7 };
-       var ALPHABET  = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789\\';
-
-       query += ' ';
-       var result    = [],
-               i         = 0,
-               l         = query.length,
-               phase     = 0,
-               selector  = -1,
-               last      = 0,
-               chr, index, start, name, key, value, operator, nameChr, name1st, escape;
-       while( i < l ){
-               chr     = query.charAt( i );
-               index   = ALPHABET.indexOf( chr );
-               nameChr = index !== -1;
-               name1st = nameChr && index < 52;
-               switch( phase ){
-                       case 99 :
-                               return;
-                       case 0 :
-                               name1st ? // tagName
-                                       ( ( selector = 8 ) && ( phase = 2 ) && ( start = i ) ) :
-                               ( index = HASH_SELECTOR.indexOf( chr ) ) === 7 ? // [
-                                       ( ( selector = 7 ) && ( phase = 3 ) ) :
-                               0 <= index ?
-                                       ( ( selector = index ) && ( phase = index < 4 ? 9 : 1 ) ) :
-                               chr !== ' ' &&
-                                       ( phase = 99 );
-                               break;
-                       case 1 :
-                               name1st ?
-                                       ( ( start = i ) && ( phase = 2 ) ) :
-                                       ( phase = 99 );
-                               break;
-                       case 2 :
-                               !nameChr &&
-                               !( escape && ( selector === 4 || selector === 5 ) &&  ( chr === ':' || chr === '.' ) ) // id or class の場合 : . を直前にエスケープした場合に限り使える
-                                       && ( name = query.substring( start, i ) ) && ( phase = 9 );
-                               break;
-                       case 3 : // start attr filter
-                               name1st ?
-                                       ( ( phase = 4 ) && ( start = i ) ) :
-                                       ( phase = 99 );
-                               break;
-                       case 4 : // attr filter key
-                               chr === '=' ?
-                                       ( ( operator = 1 ) && ( phase = 5 ) && ( key = query.substring( start, i ) ) && ( start = i ) ) :
-                               ( index = OPERATORS[ query.substr( i, 2 ) ] ) ?
-                                       ( ( operator = index ) && ( phase = 5 ) && ( key = query.substring( start, i ) )  && ( start = i ) && ++i ) :
-                               chr !== ' ' &&
-                                       ( phase = 99 );
-                               break;
-                       case 5 : // attr filter value
-                               chr === ']' ?
-                                       ( ( phase = 9 ) && ( value = query.substring( start, i ) ) ) :
-                               !nameChr &&
-                                       ( phase = 99 );
-                               break;
-                       default :
-               };
-               //alert( chr + ' ' + phase + ' ' + selector + ' ' + name + ' ' + name1st )
-               if( phase === 9 ){
-                       if( last < 4 && selector < 4 ){
-                               if( last === 0 ){
-                                       result[ result.length - 1 ] = selector; // override
-                                       last = selector;
-                               } else {
-                                       return; // error
-                               };
-                       } else { // 前回今回とも子孫セレクタの場合、保存しない
-                               result[ result.length ] =
-                                       selector < 4 ?
-                                               selector :
-                                       selector === 7 ?
-                                               [ selector, key, operator, value ] :
-                                               [ selector, name.split( '\\' ).join( '' ) ];
-                               last = selector;
-                       };
-                       selector = -1;
-                       phase    = 0;
-               } else
-               if( phase === 99 ) return;
-
-               escape = chr === '\\' && !escape;
-       };
-       return result;
-};
-
+/**\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
+ *\r
+ * セレクタ Level 3\r
+ * http://standards.mitsue.co.jp/resources/w3c/TR/css3-selectors/#nth-child-pseudo\r
+ */\r
+\r
+X.Dom.Query = {\r
+       _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
+               'last-child'       : 10,\r
+               'only-child'       : 10,                        \r
+               'first-child'      : 11,\r
+               'last-of-type'     : 12,\r
+               'only-of-type'     : 12,                \r
+               'first-of-type'    : 13\r
+       },\r
+       \r
+       _COMBINATOR : {\r
+               ''    : 0, // none\r
+               ' '   : 1, // 子孫セレクタ\r
+               '>'   : 2, // 子セレクタ\r
+               '+'   : 3, // 兄弟セレクタ,共通の親を持つ、1番目要素が2番目要素の1つ前にある\r
+               '~'   : 4, // 一般兄弟セレクタ,共通の親を持つ、1番目要素が2番目要素の前 (直前でなくともよい) にある\r
+               ','   : 5\r
+       },\r
+       _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
+       },\r
+       _OPERATORS : { '==' : 1, '!=': 2, '~=': 3, '^=': 4, '$=': 5, '*=': 6, '|=': 7 },\r
+       _ALPHABET  : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789\\',\r
+       _NUMBER    : '+-0123456789'\r
+};\r
+                       \r
+/*\r
+ * セレクタ文字の解析\r
+ * 結合子 + 単体セレクタ( タグ,*,#,.,[],: )\r
+ * ' ' 子孫セレクタ, '>' 直下,'+','~' の場合、tagName|* を返す\r
+ * return [ pointer, [ selector, ... ] ] error: return pointer\r
+ */\r
+X.Dom.Query._parse = function( query, last ){\r
+       var COMBINATOR = X.Dom.Query._COMBINATOR,\r
+               SELECTOR   = X.Dom.Query._SELECTOR,\r
+               OPERATORS  = X.Dom.Query._OPERATORS,\r
+               ALPHABET   = X.Dom.Query._ALPHABET,\r
+               NUMBER     = X.Dom.Query._NUMBER,\r
+               result     = [],\r
+               i          = -1,\r
+               l          = query.length,\r
+               phase      = 0x0,\r
+               combinator = 0,\r
+               selector   = 0,\r
+               chr, chrCode, nameChr, name1st,\r
+               tmp, escape, quot, start,\r
+               name, key, value, operator, a, b, not;\r
+       query += ' ';\r
+       while( i < l ){\r
+               chr     = query.charAt( ++i );\r
+               chrCode = ALPHABET.indexOf( chr );\r
+               nameChr = chrCode !== -1;\r
+               name1st = nameChr && chrCode < 52;\r
+               switch( phase ){\r
+                       case 0x0 :\r
+                               name1st ? // tagName\r
+                                       ( ( selector = 1 ) && ( phase = 0x2 ) && ( start = i ) ) :\r
+                               !not && ( tmp = COMBINATOR[ chr ] ) ? (\r
+                                       ( 1 < tmp && 1 < combinator ) ?\r
+                                               ( phase = 0xf ) :\r
+                                               ( phase = tmp === 5 ? 0xe : 0x0 ) & ( ( 1 < tmp || combinator < 1 ) && ( combinator = tmp ) ) & ( tmp === 5 && ++i ) ) : // ' ' でない結合子の上書きはエラー\r
+                               ( tmp = SELECTOR[ chr ] ) ? // [\r
+                                       ( selector = tmp ) && ( phase = selector === 5 ? 0x4 : 0x1 ) : // 7:[, 0<:\r
+                               chr === '*' ?\r
+                                       ( ( selector = 1 ) && ( name = chr ) && ( phase = 0xe ) && ++i ) :\r
+                                       chr !== ' ' && ( phase = 0xf );\r
+                               //console.log( '0x0: ' + name1st + ' ' + chrCode + ' ' + chr + ' ' + phase + ' tmp:' + tmp + ' comb:' + combinator );\r
+                               break;\r
+                       case 0x1 :\r
+                               name1st ?\r
+                                       ( ( start = i ) && ( phase = 0x2 ) ) :\r
+                                       chr !== ' ' && ( phase = 0xf );\r
+                               break;\r
+                       case 0x2 :\r
+                               !nameChr && !( escape && ( selector === 2 || selector === 3 ) && ( chr === ':' || chr === '.' ) ) ? // id or class の場合 : . を直前にエスケープした場合に限り使える\r
+                                       ( name = query.substring( start, i ) ) && ( phase = selector === 4 && name !== 'not' && chr === '(' ? 0x8 : 0xe ) :\r
+                               SELECTOR[ chr ] < 4 && ( phase = 0xe );\r
+                               break;\r
+                       \r
+                       case 0x3 : //:nth-\r
+                               break;\r
+                       \r
+                       case 0x4 : // start attr filter\r
+                               name1st ?\r
+                                       ( ( phase = 0x5 ) && ( start = i ) ) :\r
+                                       ( phase = 0xf );\r
+                               break;\r
+                       case 0x5 : // attr filter key\r
+                               chr === '=' ?\r
+                                       ( ( operator = 1 ) && ( phase = 0x6 ) && ( key || ( key = query.substring( start, i ) ) ) && ( start = i + 1 ) ) :\r
+                               chr === ']' ?\r
+                                       ( !( operator = 0 ) && ( phase = 0xe ) && ( key || ( key = query.substring( start, i ) ) ) && ++i ) :\r
+                               chr === ' ' ?\r
+                                       ( key || ( key = query.substring( start, i ) ) ) :\r
+                               ( operator = OPERATORS[ query.substr( i, 2 ) ] ) ?\r
+                                       ( ( phase = 0x6 ) && ( key || ( key = query.substring( start, i ) ) ) && ( start = ++i ) ) :\r
+                                       !nameChr && ( phase = 0xf );\r
+                               //console.log( name1st + ' ' + chrCode + chr + phase );\r
+                               break;\r
+                       case 0x6 :\r
+                               ( chr === '"' || chr === "'" ) && !escape && !quot ?\r
+                                       ( quot = chr ) && ( start = i + 1 ) && ( phase = 0x7 ) :\r
+                                       chr !== ' ' && ( start = i ) && ( phase = 0x7 );\r
+                               break;\r
+                               \r
+                       case 0x7 : // attr filter value\r
+                               chr === quot ?\r
+                                       !escape && !value && ( value = query.substring( start, i ) ) :\r
+                               chr === ']' ?\r
+                                       ( ( value || ( value = query.substring( start, i ) ) ) && ( phase = 0xe ) && ++i ) :    \r
+                               chr === ' ' && !quot && !value && ( value = query.substring( start, i ) );                      \r
+                                       //( chr === '"' || chr === "'" ) && !quot && ( quot = chr ) && ( start = i + 1 );\r
+                               break;\r
+                               \r
+                       case 0x8 : // 4, 2n, even, odd, -n+4,\r
+                               NUMBER.indexOf( chr ) !== -1 ?\r
+                                       ( start = i ) && ( phase = 0x9 ) :\r
+                               chr === 'n' ?\r
+                                       ( phase = 0xa ) && ( a = 1 ) && ( start = i + 1 ) :\r
+                               query.substr( i, 4 ) === 'even' ?\r
+                                       ( ( a = 2 ) && !( b = 0 ) && ( i += 3 ) ) :\r
+                               query.substr( i, 3 ) === 'odd' ?\r
+                                       ( ( a = 2 ) && ( b = 1 ) && ( i += 2 ) ) :                                      \r
+                               chr === ')' && ( phase = a ? 0xe : 0xf ) && ++i;\r
+                               //console.log( '0x8: ' + name1st + ' ' + chrCode + ' ' + chr + ' ' + phase );\r
+                               break;\r
+                       case 0x9 :\r
+                               tmp = query.substring( start, i );\r
+                               chr === 'n' ?\r
+                                       ( phase = 0xa ) && ( start = i + 1 ) && ( a = tmp === '+' ? 1 : tmp === '-' ? -1 : parseFloat( tmp ) ) :\r
+                               chr === ')' && ( phase = 0xe ) && ( b = parseFloat( tmp ) ) && ++i && ( a = 0 );\r
+                               //console.log( '0x9: ' + name1st + ' ' + chrCode + ' ' + chr + ' ' + phase );\r
+                               break;\r
+                       case 0xa :\r
+                               chr === ')' && ( phase = 0xe ) && ++i && ( b = parseFloat( query.substring( start, i ) ) || 0 );\r
+                               //console.log( '0xa: ' + start + ' ' + i );\r
+                               break;\r
+                       default :\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
+                               } else {\r
+                                       if( a !== a || b !== b ) return i;\r
+                                       result = [ not ? 0 : combinator, selector, name, a, b ];\r
+                                       break;  \r
+                               };\r
+                               // lang result = [ not ? 0 : combinator, selector, name, lan ];\r
+                               // contains result = [ not ? 0 : combinator, selector, name, text ];\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
+               escape = chr === '\\' && !escape;\r
+       };\r
+       //if( phase !== 0xe ) return i;\r
+       if( not && ( tmp = query.substr( i ).indexOf( ')' ) ) === -1 ) return i;\r
+       return not ? [ i + tmp + 1, [ combinator, 6, result ] ] : [ i, result ];\r
+};\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
+                       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
+                       l, i, n, parsed,\r
+                       xnodes, // 一時保存用\r
+                       merge, // 要素がコメントノードで汚染されている場合使う\r
+                       combinator, selector, name, tagName, \r
+                       isAll, isStart = true, isNot,\r
+                       uid, tmp, xnode, filter, key, op, val, toLower, useName,\r
+            links, className, attr, flag;\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
+                       \r
+                       // 初期化処理\r
+                       if( !parsed ){\r
+                               parsed = X.Dom.Query._parse( queryString );\r
+                               \r
+                               if( typeof parsed === 'number' ){\r
+                                       // error\r
+                                       return [];\r
+                               };\r
+                               \r
+                               queryString = queryString.substr( parsed[ 0 ] );\r
+                               parsed      = parsed[ 1 ];\r
+                               \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
+                                       isStart = true;\r
+                                       continue;\r
+                               };\r
+                       };\r
+                       \r
+\r
+                       \r
+                       combinator  = parsed[ 0 ];\r
+                       selector    = parsed[ 1 ];\r
+                       name        = parsed[ 2 ];\r
+                       tagName     = selector === 1 ? ( isXML ? name : name.toUpperCase() ) : '*';\r
+                       isAll       = tagName === '*';\r
+       \r
+                       if( !isStart ){\r
+                               if( !xnodes.length ){\r
+                                       parsed = null;\r
+                                       continue;                                       \r
+                               } else\r
+                               if( combinator !== 0 ){\r
+                                       parents = xnodes;\r
+                                       xnodes  = [];\r
+                                       console.log( 'cobinator !== 0 ' + parents.length + ' : ' + xnodes.length );\r
+                               };\r
+                       };\r
+                       \r
+                       i = 0;\r
+                       l = parents.length;\r
+                       n = -1; \r
+                       isMulti = isMulti || 1 < l;\r
+                       \r
+                       //console.log( 'combinator ' + combinator );\r
+       \r
+                       switch( combinator ){\r
+                               // > 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
+                                       };\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
+                                                               break;\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
+                                                               if( merge[ uid ] ){\r
+                                                                       break;\r
+                                                               } else {\r
+                                                                       merge[ uid ] = true;\r
+                                                                       xnodes[ ++n ] = xnode;\r
+                                                               };\r
+                                                       };                                                                      \r
+                                               };                                                              \r
+                                       };\r
+                                       break;\r
+                                       \r
+                               default :\r
+                                       if( combinator === 1 || isStart ){\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
+                                       };\r
+                       };\r
+                       \r
+                       isStart = false;\r
+                       \r
+                       //alert( 'pre-selector:' + ( xnodes && xnodes.length ) )\r
+                       \r
+                       switch( selector ){\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.Dom.Query._filter[ name ] ) ){\r
+                                               return [];\r
+                                       };\r
+                                       break;\r
+                               // [] 属性\r
+                               case 5 :\r
+                                       filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break;\r
+                               // :not\r
+                               case 6 :\r
+                                       isNot  = true;\r
+                                       parsed = parsed[ 2 ];\r
+                                       continue;\r
+                               // scope\r
+                               case 7 :\r
+                                       xnodes = scope; break;\r
+                               // root\r
+                               case 8 :\r
+                                       xnodes = [ Node._html ]; break;\r
+                               // link\r
+                               case 9 :\r
+                                       if( links = root._rawNode.links ){\r
+                                               for( xnodes = [], i = links.length; i; ){\r
+                                                       xnodes[ --i ] = new Node( links[ i ] );\r
+                                               };\r
+                                       };\r
+                       };\r
+                       \r
+                       if( filter && xnodes.length ){\r
+                               // filter.mが関数の場合\r
+                               if( filter.m ){\r
+                                       xnodes = filter.m(\r
+                                               {\r
+                                                       not : isNot,\r
+                                                       xml : isXML\r
+                                               },\r
+                                               xnodes,\r
+                                               parsed[ 3 ], parsed[ 4 ]\r
+                                       );\r
+                               } else\r
+                               // filterが関数の場合\r
+                               if( typeof filter === 'function' ){\r
+                                       tmp = [];\r
+                                       for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){\r
+                                               if( ( !!filter( xnode ) ) ^ isNot ) tmp[ ++n ] = xnode; \r
+                                       };\r
+                                       xnodes = tmp;\r
+                               } else {\r
+                               // 属性セレクター                        \r
+                                       tmp = [];\r
+                                       key = filter[ 0 ];\r
+                                       op  = filter[ 1 ];\r
+                                       val = filter[ 2 ]; \r
+                                       // [class~='val']\r
+                                       if( !isXML && key === 'class' && op === 3 ){\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
+                                               };\r
+                                       } else {\r
+                                       // 通常\r
+                                               // 諦めて、funcAttrを呼ぶ\r
+                                               // flag_call  = ($.browser.safari && key === 'selected');\r
+                                               // getAttributeを使わない\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
+\r
+                                               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
+                                                               //flag_call ?\r
+                                                               //      funcAttr( elem, key ) :\r
+                                                               //useName ?\r
+                                                               //      elem[ X.Dom.Attr.renameForDOM[ key ] || key ] :\r
+                                                               //      elem.getAttribute( key, 2 );\r
+                                                       flag = attr != null && ( !useName || attr !== '' );\r
+                                                       if( flag && op ){\r
+                                                               if( toLower ) attr = attr.toLowerCase();\r
+                                                               \r
+                                                               switch( op ){\r
+                                                                       case 1: // =\r
+                                                                               flag = attr === val;\r
+                                                                               break;\r
+                                                                       case 2: // !=\r
+                                                                               flag = attr !== val;\r
+                                                                               break;\r
+                                                                       case 3: // ~=\r
+                                                                               flag = ( ' ' + attr + ' ' ).indexOf( val ) !== -1;\r
+                                                                               break;\r
+                                                                       case 4: // ^=\r
+                                                                               flag = attr.indexOf( val ) === 0;\r
+                                                                               break;\r
+                                                                       case 5: // $=\r
+                                                                               flag = attr.lastIndexOf( val ) + val.length === attr.length;\r
+                                                                               break;\r
+                                                                       case 6: // *=\r
+                                                                               flag = attr.indexOf( val ) !== -1;\r
+                                                                               break;\r
+                                                                       case 7: // |=\r
+                                                                               flag = attr === val || attr.substring( 0, val.length + 1 ) === val + '-';\r
+                                                                               break;\r
+                                                               };\r
+                                                       };\r
+                                                       if( !!flag ^ isNot ) tmp[ ++n ] = xnode;\r
+                                               };\r
+                                       };\r
+                                       xnodes = tmp;\r
+                               };\r
+                       };\r
+                       filter  = null;\r
+                       isNot   = false;\r
+                       parsed  = null;\r
+                       \r
+                       alert( '//end :' + ( xnodes && xnodes.length ) );\r
+               };\r
+               console.log( 'multi:' + ( xnodes && xnodes.length ) )\r
+               \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
+                       xnodes = [];\r
+                       merge  = {};\r
+                       for( i = 0, n = -1, l = ret.length; i < l; ++i ){\r
+                               //alert( 'multi:' + i )\r
+                               xnode = ret[ i ];\r
+                               uid   = xnode._uid;\r
+                               if( !merge[ uid ] ){\r
+                                       merge[ uid ] = true;\r
+                                       xnodes[ ++n ] = xnode;\r
+                               };\r
+                       };\r
+               };\r
+\r
+               return xnodes.length === 1 ? xnodes[ 0 ] : new X.Dom.NodeList( xnodes );\r
+       };\r
+       \r
+       X.Dom.Query._fetchElements = function( list, parent, tag ){\r
+               var xnodes = parent._xnodes,\r
+                       l      = xnodes.length,\r
+                       i      = 0,\r
+                       child;\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.Dom.Query._fetchElements( list, child, tag );\r
+                       };\r
+               };\r
+       };\r
+\r
+       X.Dom.Query._funcSelectorChild = function( 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
+                       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
+                                               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
+                                               tmp = false;\r
+                                               break;\r
+                                       };              \r
+                               };                                              \r
+                       };\r
+                       if( tmp === null ) tmp = true;\r
+                       if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+               };\r
+               return res;\r
+       };\r
+       X.Dom.Query._funcSelectorNth = function( pointer, sibling, flag_all, flags, xnodes, a, b ){\r
+               var _data    = funcData,\r
+                       res      = [],\r
+                       checked  = {},\r
+                       flag_not = flags.not,\r
+                       i = 0, n = -1, elem, uid,\r
+                       c, xnode, tmp, node, tagName;\r
+               for( ; xnode = xnodes[ i ]; ++i ){\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
+                                               ++c;\r
+                                               checked[ node._uid ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0;\r
+                                       };                                                      \r
+                               };\r
+                               tmp = checked[ uid ];\r
+                       };\r
+                       if( tmp ^ flag_not ) res[ ++n ] = elem;\r
+               };\r
+               return res;\r
+       };\r
+       X.Dom.Query._funcSelectorProp = function( prop, flag, flags, xnodes ){\r
+               var res = [],\r
+                       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
+               };\r
+               return res;\r
+       };\r
+\r
+X.Dom.Query._filter = {\r
+       root : function( elem ){\r
+               return elem === ( elem.ownerDocument || elem.document ).documentElement;\r
+       },\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
+                       };\r
+                       return res;\r
+               }\r
+       },\r
+       'first-child' : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( -1, true, flags, xnodes ); }\r
+       },\r
+       'last-child' : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 1, true, flags, xnodes ); }\r
+       },\r
+       'only-child' : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 0, true, flags, xnodes ); }\r
+       },\r
+       'first-of-type' : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( -1, false, flags, xnodes ); }\r
+       },\r
+       'last-of-type' : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 1, false, flags, xnodes ); }\r
+       },\r
+       'only-of-type' : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorChild( 0, false, flags, xnodes ); }\r
+       },\r
+       'nth-child' : {\r
+               m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'firstChild', 'nextNode', true, flags, xnodes, a, b ); }\r
+       },\r
+       'nth-last-child' : {\r
+               m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'lastChild', 'prevNode', true, flags, xnodes, a, b ); }\r
+       },\r
+       'nth-of-type' : {\r
+               m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'firstChild', 'nextNode', false, flags, xnodes, a, b ); }\r
+       },\r
+       'nth-last-of-type' : {\r
+               m : function( flags, xnodes, a, b ){ return X.Dom.Query._funcSelectorNth( 'lastChild', 'prevNode', false, flags, xnodes, a, b ); }\r
+       },\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
+                                               tmp = false;\r
+                                               break;\r
+                                       };                              \r
+                               };\r
+                               if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+                       };\r
+                       return res;\r
+               }\r
+       },\r
+       link : {\r
+               m : function( flags, xnodes ){\r
+                       var links = ( xnodes[ 0 ].ownerDocument || xnodes[ 0 ].document ).links,\r
+                               _data = funcData,\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
+                       };\r
+                       for( i = 0, n = -1; xnode = xnodes[ i ]; ++i ){\r
+                               if( checked[ xnode._uid ] ^ flag_not ) res[ ++n ] = xnode;\r
+                       };\r
+                       return res;\r
+               }\r
+       },\r
+       lang : {\r
+               m : function( flags, xnodes, arg ){\r
+                       var res = [],\r
+                               //reg = new RegExp('^' + arg, 'i'),\r
+                               flag_not = flags.not,\r
+                               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
+                                       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
+                       };\r
+                       return res;\r
+               }\r
+       },\r
+       enabled : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'disabled', false, flags, xnodes ); }\r
+       },\r
+       disabled : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'disabled', true, flags, xnodes ); }\r
+       },\r
+       checked : {\r
+               m : function( flags, xnodes ){ return X.Dom.Query._funcSelectorProp( 'checked', true, flags, xnodes ); }\r
+       },\r
+       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
+                       };\r
+                       return res;\r
+               }\r
+       }\r
+};
\ No newline at end of file
index 8ffdcdc..311de29 100644 (file)
@@ -56,7 +56,7 @@
                        last  = stack[ stack.length - 1 ];
                        
                        // Make sure we're not in a script or style element
-                       if ( last && special[ last ] === 1 ) {
+                       if ( last && special[ last.toLowerCase() ] === 1 ) {
                                if( 0 <= ( index = _parseEndTag( stack, handler, html ) ) ){
                                        //handler.chars( html.substring( 0, index ) );
                                        html = html.substring( index );
                        ++i;
                };
                if( phase === 9 ){
-                       if( parseStartTag( stack, last, handler, tagName.toLowerCase(), attrs, empty, i ) === false ) return false;;
+                       if( parseStartTag( stack, last, handler, tagName /*.toLowerCase() */, attrs, empty, i ) === false ) return false;
                        return i;
                };
                return 0; // error
                        ++i;
                };
                if( phase === 9 ){
-                       parseEndTag( stack, handler, tagName.toLowerCase() );
+                       parseEndTag( stack, handler, tagName ); //.toLowerCase()
                        return i;
                };
                return 0; // error
        };
 
        function parseStartTag( stack, last, handler, tagName, attrs, unary, index ) {
-               if ( block[ tagName ] === 1 ) {
-                       while ( last && inline[ last ] === 1 ) {
+               if ( block[ tagName.toLowerCase() ] === 1 ) {
+                       while ( last && inline[ last.toLowerCase() ] === 1 ) {
                                parseEndTag( stack, handler, last );
                                last = stack[ stack.length - 1 ];
                        };
                };
-               closeSelf[ tagName ] === 1 && ( last === tagName || ( sisters[ tagName ] && sisters[ tagName ][ last ] === 1 ) ) && parseEndTag( stack, handler, last );
-               unary = empty[ tagName ] === 1 || !!unary;
+               closeSelf[ tagName.toLowerCase() ] === 1 && ( last === tagName || ( sisters[ tagName.toLowerCase() ] && sisters[ tagName.toLowerCase() ][ last.toLowerCase() ] === 1 ) ) && parseEndTag( stack, handler, last );
+               unary = empty[ tagName.toLowerCase() ] === 1 || !!unary;
                !unary && ( stack[ stack.length ] = tagName );
                
                return handler.start( tagName, attrs, unary, index );
@@ -274,8 +274,7 @@ X.Dom._htmlStringToXNode = {
                        nest   = this.nest,
                        flat   = this.flat,
                        l      = nest.length,
-                       _attrs = {},
-                       attr, name, i, toIndex;
+                       attr, name, i, _attrs; //, toIndex;
                if( l ){
                        xnode = nest[ l - 1 ].create( tagName );
                } else {
@@ -283,10 +282,10 @@ X.Dom._htmlStringToXNode = {
                };
                if( !noChild ) nest[ l ] = xnode;
                if( i = attrs.length ){
-                       toIndex = X.Dom.Attr.toIndex;
+                       //toIndex = X.Dom.Attr.toIndex;
+                       _attrs = {};
                        for( ; i; ){
-                               attr = attrs[ --i ];
-                               if( attr ){
+                               if( attr = attrs[ --i ] ){
                                        if( typeof attr === 'string' ){
                                                name = attr;
                                                //i    = toIndex[ name ];
@@ -300,9 +299,7 @@ X.Dom._htmlStringToXNode = {
                                        };
                                };
                        };
-                       //xnode._attrs = _attrs;
                        xnode.attr( _attrs );
-                       // xnode.css()
                };
        },
        end : function(){
@@ -315,9 +312,7 @@ X.Dom._htmlStringToXNode = {
                        this.flat[ this.flat.length ] = X.Dom.Node.createText( text );
                };
        },
-       comment : function(){
-               
-       }
+       comment : X.emptyFunction
 };
 
 X.Dom.parse = function( html, ignoreError ){