OSDN Git Service

Version 0.6.133, fix for closure compiler - ADVANCED_OPTIMIZATIONS
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 02_XNode.js
index 01588f9..4b2ccd3 100644 (file)
@@ -1,33 +1,71 @@
 var \r
-       X_Node_Dirty = {\r
-               CLEAN            :  0,\r
-               CHILD_IS_DIRTY   :  1,\r
-               ID               :  2, // width, height, x, y\r
-               CONTENT          :  4, // width, height, x, y textNode の内容\r
-               CLASSNAME        :  8, // X_Node_CSS_getCharSize, width, height, x, y\r
-               ATTR             : 16, // X_Node_CSS_getCharSize, width, height, x, y\r
-               CSS              : 32, // X_Node_CSS_getCharSize, width, height, x, y\r
-               IE_FILTER        : X_UA.IE < 9 && !X_UA.MacIE ? 64 : 0,\r
-               UNKNOWN_TAG_FIX  : 128,\r
-               IE4_TEXTNODE_FIX : 256\r
-       },\r
        \r
        X_Node_State = {\r
-               DESTROYED          : 0,\r
-               EXIST              : 1, // XNODE_EXIDT, ELEMENT_EXIST\r
-               BELONG_TREE        : 2, // HAS_PARENT, HAS_PARENT_ACTUAL, BELONG_TREE, BELONG_TREE_ACTUAL\r
-               DISPLAY_NONE       : 4, // VISIVILITY_HIDDEN(opacity0), DISPALY_NONE\r
-               DISPLAY_BLOCK      : 8, // remove\r
-               DISPLAY_INLINE     : 16,// remove\r
-               POSITION_ABSOLUTE  : 32,\r
-               OVERFLOW_HIDDEN    : 64,\r
-               HAS_WIDTH_LENGTH   : 128,\r
-               HAS_WIDTH_PERCENT  : 256,\r
-               HAS_HEIGHT_LENGTH  : 512,\r
-               HAS_HEIGHT_PERCENT : 1024,\r
-               IE4_ONLY_TEXT      : 2048,\r
-               IE5_DISPLAY_NONE_FIX : !X_UA.MacIE && X_UA.IE5 ? 4096 : 0 // filterがかかっていると不可? MacIE5.2- は ?\r
+               DESTROYED              : 0x0,\r
+               EXIST                  : 0x1,\r
+               IN_TREE                : 0x2, // xnode が(仮想)ツリーに追加されている -> 描画の対象\r
+               \r
+               STYLE_IS_DISPLAY_NONE  : 2 <<  1, // display    : none          \r
+               STYLE_IS_INVISIBLE     : 2 <<  2, // visibility : hidden or opacity : 0\r
+               STYLE_IS_POS_ABSOLUTE  : 2 <<  3, // position   : absolute\r
+               STYLE_IS_NO_OVERFLOW   : 2 <<  4, // overflow   : hidden\r
+               STYLE_IS_WIDTH_LENGTH  : 2 <<  5, // width  : overflow:hidden,要素無し、または要素が非表示なら、 width() のための commitUpdate が不要\r
+               STYLE_IS_WIDTH_PCT     : 2 <<  6, // width  : width() のための commitUpdate が不要かもしれない。(親で LENGTH が指定されているなら)\r
+               STYLE_IS_HEIGHT_LENGTH : 2 <<  7, // height :\r
+               STYLE_IS_HEIGHT_PCT    : 2 <<  8, // height :\r
+               STYLE_IS_FONT_LENGTH   : 2 <<  9, // fontSize :\r
+               STYLE_IS_FONT_PCT      : 2 << 10, // fontSize :\r
+\r
+               DIRTY_POSITION         : 2 << 11, // 要素位置の変更が起こった。\r
+               DIRTY_CONTENT          : 2 << 12, // width, height, x, y textNode の内容 TODO html と排他なので ID と共通でいい\r
+               DIRTY_ID               : 2 << 12, // width, height, x, y\r
+               DIRTY_CLASSNAME        : 2 << 13, // X_Node_CSS_getCharSize, width, height, x, y\r
+               DIRTY_ATTR             : 2 << 14, // X_Node_CSS_getCharSize, width, height, x, y\r
+               DIRTY_CSS              : 2 << 15, // X_Node_CSS_getCharSize, width, height, x, y\r
+               DIRTY_IE_FILTER        : X_UA[ 'IE' ] < 10 && X_UA[ 'ActiveX' ] ? 2 << 16 : 0, // \r
+\r
+               ACTUAL_LISTENING       : 2 << 17,\r
+               OLD_ATTRTEXT           : 2 << 18,\r
+               OLD_CSSTEXT            : 2 << 19,\r
+\r
+               // filter 要素が親子になると不具合が出るのを検出\r
+               IE_FILTER_NOW          : 2 << 20,\r
+\r
+               //GPU_WAITING            : 2 << 20, // 1:子のGPU解除待\r
+               GPU_RESERVED           : 2 << 21, // 2:GPU予約\r
+               GPU_NOW                : 2 << 22, // 3:GPU now!\r
+               GPU_RELEASE_RESERVED   : 2 << 23, // 4:GPU解除予約\r
+               GPU_CHILD              : 2 << 24, \r
+               \r
+               IE4_HAS_TEXTNODE       : X_UA[ 'IE4' ] ? 2 << 21 : 0,\r
+               IE4_HAS_ELEMENT        : X_UA[ 'IE4' ] ? 2 << 22 : 0,\r
+               IE4_DIRTY_CHILDREN     : X_UA[ 'IE4' ] ? 2 << 23 : 0,\r
+               IE4_FIXED              : X_UA[ 'IE4' ] ? 2 << 24 : 0,\r
+               \r
+               IE5_DISPLAY_NONE_FIX   : X_UA[ 'IE5' ] && X_UA[ 'ActiveX' ] ? 2 << 24 : 0\r
        },\r
+\r
+       X_Node_BITMASK_RESET_STYLE  = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ (\r
+               X_Node_State.STYLE_IS_DISPLAY_NONE |\r
+               X_Node_State.STYLE_IS_INVISIBLE |\r
+               X_Node_State.STYLE_IS_POS_ABSOLUTE |\r
+               X_Node_State.STYLE_IS_NO_OVERFLOW |\r
+               X_Node_State.STYLE_IS_WIDTH_LENGTH |\r
+               X_Node_State.STYLE_IS_WIDTH_PCT |\r
+               X_Node_State.STYLE_IS_HEIGHT_LENGTH |\r
+               X_Node_State.STYLE_IS_HEIGHT_PCT |\r
+               X_Node_State.STYLE_IS_FONT_LENGTH |\r
+               X_Node_State.STYLE_IS_FONT_PCT ),\r
+\r
+       X_Node_BitMask_IS_DIRTY     = X_Node_State.DIRTY_POSITION | \r
+               X_Node_State.DIRTY_CONTENT | X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME |\r
+               X_Node_State.DIRTY_ATTR | X_Node_State.DIRTY_CSS | X_Node_State.DIRTY_IE_FILTER,\r
+\r
+       X_Node_BitMask_RESET_DIRTY  = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ X_Node_BitMask_IS_DIRTY,\r
+       \r
+       X_Node_BitMask_RESET_GPU    = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ ( X_Node_State.GPU_RESERVED | X_Node_State.GPU_NOW | X_Node_State.GPU_RELEASE_RESERVED ),\r
+       \r
+       X_Node_BitMask_IE4_IS_MIX   = X_Node_State.IE4_HAS_TEXTNODE | X_Node_State.IE4_HAS_ELEMENT,\r
        \r
        X_Node_TYPE = {\r
                XNODE       : 1,\r
@@ -42,9 +80,14 @@ var
                IMAGE       : 10\r
        },\r
        \r
-       X_Node_strictElmCreation = !X_UA.MacIE && X_UA.IE5678,// && !X_UA.MacIE;\r
+       X_Node_strictElmCreation    = !X_UA[ 'MacIE' ] && X_UA[ 'IE' ] <= 8,\r
+       \r
+       X_Node_documentFragment     = document.createDocumentFragment && ( !X_UA[ 'IE' ] || 5.5 <= X_UA[ 'IE' ] ) && document.createDocumentFragment(),\r
+       \r
+       // 子の生成後に リアル文書 tree に追加する\r
+       X_Node_addTreeAfterChildren = !( X_UA[ 'IE' ] < 9 ),\r
        \r
-       X_Node_useDocumentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
+       X_Node_displayNoneFixForIE5 = !!X_Node_State.IE5_DISPLAY_NONE_FIX,\r
        \r
        X_Node_newByTag      = false,\r
        \r
@@ -52,87 +95,86 @@ var
        \r
        X_Node_outerXNode    = null,\r
        \r
-       X_Node_updateTimerID = 0,\r
-/*\r
+       X_Node_updateTimerID = 0;\r
+\r
+/**\r
  * Node( rawElement | rawTextnode | htmlString | textString )\r
- */    \r
-       Node = X.Node = X.EventDispatcher.inherits(\r
-       'XDomNode',\r
-       X.Class.POOL_OBJECT,\r
+ *     \r
+ * @alias X.Node\r
+ * @class Node HTMLElement、TextNode をラップし jQuery 風な API で操作できます。\r
+ * @constructor \r
+ * @constructs Node\r
+ * @extends {EventDispatcher}\r
+ */\r
+var    Node = X.Node = X.EventDispatcher.inherits(\r
+       'X.Node',\r
+       X.Class.POOL_OBJECT, // X.Class.FINAL\r
        {\r
                _uid       : 0,\r
-               _state     : 0,\r
-               _dirty     : 0,\r
-               \r
-               _isNew     : false, // state にまとめる\r
-               \r
-               _rawObject : null,\r
+               _flags     : X_Node_State.DESTROYED,\r
+\r
+               // _rawObject : null,\r
                _rect      : null, // \r
+               _fontSize  : 0,\r
                \r
-               _root      : null, // xnode が文書ツリーに属しているか?はこれを見る -> state\r
+               length     : 1,\r
                parent     : null, // remove された枝も親子構造は維持している。\r
-               _xnodes    : null,\r
-       \r
-               _xnodeType : 0,\r
-               _tag       : null,\r
-               _text      : null,\r
-               _id        : null,\r
-               _className : '',\r
+               _xnodes    : null, // Array.<Node>\r
+               _gpuParent : null, // TODO\r
+\r
+               _tag       : '',\r
+               _text      : '',\r
+               _id        : '', //\r
+               _className : '', //\r
 \r
                _attrs     : null, // see X_Node_Attr\r
                _newAttrs  : null,\r
-               _attrText  : '', // X_Node_Attr_objToAttrText が必要な場合は false が入っている\r
+               _attrText  : '',\r
                \r
                _css       : null, // see X_Node_CSS\r
-               _cssText   : null,\r
-               \r
-               _fontSize  : 0,\r
+               _cssText   : '',\r
                \r
-               _anime     : null,\r
+               _anime     : null, // Hash see X_Node_Anime\r
                \r
        /*\r
         * TODO Node の継承ができない!\r
         */\r
                Constructor : function( v ){\r
-                       var css, xnodes, xnode, parent, uid = X_Node_CHASHE.length;\r
+                       var uid = X_Node_CHASHE.length,\r
+                               css, xnodes, xnode, parent;\r
                        \r
                        if( X_Node_newByTag ){\r
                                X_Node_newByTag = false;\r
                                this._tag       = v.toUpperCase();\r
-                               this._xnodeType = 1;\r
-                               this._state     = X_Node_State.DISPLAY_INLINE; // TODO\r
                                arguments[ 1 ] && this.attr( arguments[ 1 ] );\r
                                css = arguments[ 2 ];\r
-                               css && this[ X.Type.isString( css ) ? 'cssText' : 'css' ]( css );\r
+                               css && this[ X_Type_isString( css ) ? 'cssText' : 'css' ]( css );\r
                        } else\r
                        if( X_Node_newByText ){\r
                                X_Node_newByText = false;\r
                                this._text       = v;\r
-                               this._xnodeType  = 3;\r
-                               this._state      = X_Node_State.DISPLAY_INLINE;\r
                        } else {\r
                                if( 1 < arguments.length ) return new X_NodeList( arguments );\r
-                               if( X.Type.isArray( v ) && v.length ) return new X_NodeList( v );\r
+                               if( X_Type_isArray( v ) && v.length ) return new X_NodeList( v );\r
 \r
                                switch( X_Node_getType( v ) ){\r
                                        case X_Node_TYPE.XNODE :\r
                                        case X_Node_TYPE.XNODE_LIST :\r
                                                return v;\r
+\r
                                        case X_Node_TYPE.RAW_HTML :\r
                                                if( xnode = X_Node_getXNode( v ) ) return xnode;\r
                                                // v.parentNode || v.parentElement : dom1 || dom0\r
                                                this.parent     = ( parent = v.parentNode || v.parentElement ) && parent.tagName /* ie7- */ && X_Node_getXNode( parent );\r
-                                               if( this.parent && this.parent._root ) this._root = this.parent._root;\r
                                                this._rawObject = v;\r
-                                               this._xnodeType = 1;\r
-                                               this._state     = X_Node_State.DISPLAY_BLOCK; // TODO\r
                                                this._tag       = v.tagName.toUpperCase();\r
                                                this._id        = v.id;\r
                                                this._className = v.className;\r
+                                               \r
                                                this.cssText( v.style.cssText );\r
-                                               // X_Node_Dirty.CSS を落とす\r
-                                               this._dirty = 0;\r
-                                               // TODO attr の回収は不可能、、、\r
+                                               this._flags &= X_Node_BitMask_RESET_DIRTY; // X_Node_State.DIRTY_CSS を落とす\r
+                                               \r
+                                               // TODO attr の回収は不可能、、、?\r
                                                if( X_UA_DOM.IE4 ){\r
                                                        v.setAttribute( 'UID', '' + uid );\r
                                                } else {\r
@@ -140,38 +182,40 @@ var
                                                };\r
                                                // childNodes...\r
                                                break;\r
+\r
                                        case X_Node_TYPE.RAW_TEXT :\r
                                                if( xnode = X_Node_getXNode( v ) ) return xnode;\r
                                                this.parent     = X_Node_getXNode( v.parentNode );\r
-                                               if( this.parent && this.parent._root ) this._root = this.parent._root;\r
                                                this._rawObject = v;\r
-                                               this._xnodeType = 3;\r
-                                               this._state     = X_Node_State.DISPLAY_INLINE;\r
                                                this._text      = v.data;\r
                                                v.UID = uid;\r
                                                break;\r
+\r
                                        case X_Node_TYPE.HTML_STRING :\r
                                        case X_Node_TYPE.STRING :\r
                                                if( xnodes = X_HtmlParser_parse( v, true ) && 1 < xnodes.length ) return new X_NodeList( xnodes );\r
                                                if( xnodes.length ) return xnodes[ 0 ];\r
                                                return X_Node_none;\r
-                                       /*\r
-                                       case X_Node_TYPE.IMAGE :\r
-                                               if( xnode = X_Node_getXNode( v ) ) return xnode;\r
-                                               this._rawObject = v;\r
-                                               this._xnodeType = 4;\r
-                                               v.UID           = uid;\r
-                                               this._state     = X_Node_State.EXIST;\r
-                                               break; */\r
+\r
                                        default :\r
+                                               this.length = 0;\r
                                                if( X_Node_none ) return X_Node_none;\r
                                                return;\r
                                };\r
                        };\r
                        \r
+                       if( this.parent && ( this.parent._flags & X_Node_State.IN_TREE ) ){\r
+                               this._flags |= X_Node_State.IN_TREE;\r
+                       };\r
+                       this._flags |= X_Node_State.EXIST;\r
                        X_Node_CHASHE[ this._uid = uid ] = this;\r
                },\r
                \r
+               // attr\r
+               // css, cssText\r
+               // find\r
+               // animate, stop\r
+               \r
                create         : X_Node_create,\r
                \r
                createAt       : X_Node_createAt,\r
@@ -188,19 +232,17 @@ var
                \r
                appendTo       : X_Node_appendTo,\r
                \r
-               appendToRoot   : X_Node_appendToRoot,\r
+               appendToRoot   : X_Node_appendToRoot, // remove\r
                \r
                before         : X_Node_before, // remove\r
                \r
-               prevNode       : X_Node_before, // -> prev\r
+               prev           : X_Node_before,\r
                \r
                after          : X_Node_after, // remove\r
                \r
-               nextNode       : X_Node_after, // -> next\r
-               \r
-               replace        : X_Node_replace, // remove\r
+               next           : X_Node_after,\r
                \r
-               swap           : X_Node_replace,\r
+               swap           : X_Node_swap,\r
                \r
                remove         : X_Node_remove,\r
                \r
@@ -241,13 +283,11 @@ function X_Node_getType( v ){
        if( v === document ) return X_Node_TYPE.DOCUMENT;\r
        if( v.constructor === Node ) return X_Node_TYPE.XNODE;\r
        if( v.constructor === X_NodeList ) return X_Node_TYPE.XNODE_LIST;\r
-       if( X.Type.isHTMLElement( v ) ) return X_Node_TYPE.RAW_HTML;\r
+       if( X_Type_isHTMLElement( v ) ) return X_Node_TYPE.RAW_HTML;\r
        if( v.nodeType === 3 ) return X_Node_TYPE.RAW_TEXT;\r
-       //if( X.Type.isImage( v ) ) return X_Node_TYPE.IMAGE;\r
-       if( X.Type.isString( v ) ){\r
+       if( X_Type_isString( v ) ){\r
                return '<' === v.charAt( 0 ) && v.charAt( v.length - 1 ) === '>' ? X_Node_TYPE.HTML_STRING : X_Node_TYPE.STRING;\r
        };\r
-       //if( v.nodeType === 11 ) return X_Node_TYPE.DOC_FRAG;\r
        return 0;\r
 };\r
 function X_Node_getXNode( v ){\r
@@ -257,7 +297,6 @@ function X_Node_getXNode( v ){
                case X_Node_TYPE.XNODE_LIST :\r
                        return v;\r
                case X_Node_TYPE.RAW_HTML :\r
-               //case X_Node_TYPE.IMAGE :\r
                        // fake TextNode too.\r
                        if( X_UA_DOM.IE4 ){\r
                                uid = v.getAttribute( 'UID' );\r
@@ -285,7 +324,7 @@ var X_Node_isXmlDocument =
                X_UA_DOM.IE4 ?\r
                        X.emptyFunction :\r
                        (function( root ){\r
-                               if( X.Type.isBoolean( root.isXML ) ) return root.isXML;\r
+                               if( X_Type_isBoolean( root.isXML ) ) return root.isXML;\r
                                return root.isXML = root._rawObject.createElement( 'p' ).tagName !== root._rawObject.createElement( 'P' ).tagName;\r
                        }),\r
        X_Node_CHASHE     = [],\r
@@ -295,35 +334,68 @@ var X_Node_isXmlDocument =
        X_Node_body, // = X_Node_CHASHE[ 3 ] <body>\r
        X_Node_systemNode, // = X_Node_CHASHE[ ? ]\r
        X_Node_fontSizeNode,\r
+/*\r
+ * remove :\r
+ *  X_Node_reserveRemoval = [] に追加。commitUpdate で remove\r
+ * add :\r
+ *  X_Node_reserveRemoval にいたら消す, new_parent._xnodes に挿入\r
+ */\r
        X_Node_reserveRemoval = [];\r
 \r
 \r
 var X_Node__ie4getRawNode = X_UA_DOM.IE4 && function ( that ){\r
-               var elm = that._rawObject;\r
-               return elm ||\r
-                       ( ( elm = document.all[ 'ie4uid' + that._uid ] ) && ( that._rawObject = elm ) ) ||\r
-                       ( that._id && ( elm = document.all[ that._id ] ) ) && ( that._rawObject = elm );\r
+               return that._rawObject ||\r
+                       ( that._rawObject = document.all[ 'ie4uid' + that._uid ] ) ||\r
+                       ( that._id && ( that._rawObject = document.all[ that._id ] ) );\r
+       };\r
+\r
+\r
+function X_Node_toggleInTreeFlag( xnodes, flag ){\r
+       var i = xnodes.length, xnode;\r
+       for( ; i; ){\r
+               xnode = xnodes[ --i ];\r
+               flag ? ( xnode._flags |= X_Node_State.IN_TREE | X_Node_State.DIRTY_POSITION ) : ( xnode._flags &= ~X_Node_State.IN_TREE & ~X_Node_State.IE5_DISPLAY_NONE_FIX );\r
+               xnode._xnodes && X_Node_toggleInTreeFlag( xnode._xnodes, flag );\r
        };\r
+};\r
 \r
+function X_Node_toggleInGPUFlag( gpuRoot, xnodes, flag ){\r
+       var i = xnodes.length, xnode;\r
+\r
+       if( flag ){\r
+               for( ; i; ){\r
+                       xnode = xnodes[ --i ];\r
+                       if( !xnode._gpuParent ){\r
+                               xnode._flags |= X_Node_State.GPU_CHILD;\r
+                               xnode._gpuParent = gpuRoot;\r
+                               xnode._xnodes && X_Node_toggleInTreeFlag( gpuRoot, xnode._xnodes, flag );       \r
+                       };\r
+               };\r
+       } else {\r
+               for( ; i; ){\r
+                       xnode = xnodes[ --i ];\r
+                       if( xnode._gpuParent === gpuRoot ){\r
+                               xnode._flags &= ~X_Node_State.GPU_CHILD;\r
+                               delete xnode._gpuParent;\r
+                               xnode._xnodes && X_Node_toggleInTreeFlag( gpuRoot, xnode._xnodes, flag );\r
+                       };\r
+               };\r
+       };\r
+};\r
 \r
 /* --------------------------------------\r
  *  Create\r
  */\r
 function X_Node_create( tag, opt_attrs, opt_css ){\r
        var xnode;\r
-       if( this._xnodeType !== 1 ) return;\r
-       if( !this._xnodes ) this._xnodes = [];\r
-       \r
-       xnode = X_Doc_create( tag, opt_attrs, opt_css );\r
-       \r
-       xnode.parent = this;\r
-       this._xnodes[ this._xnodes.length ] = xnode;\r
-       this._root && X_Node_reserveUpdate();\r
+       if( !this._tag ) return;\r
+       this.append( xnode = X_Doc_create( tag, opt_attrs, opt_css ) );\r
        return xnode;\r
 };\r
 function X_Node_createAt( index, tag, opt_attrs, opt_css ){\r
-       var xnode = X_Doc_create( tag, opt_attrs, opt_css );\r
-       this.appendAt( index, xnode );\r
+       var xnode;\r
+       if( !this._tag ) return;\r
+       this.appendAt( index, xnode = X_Doc_create( tag, opt_attrs, opt_css ) );\r
        return xnode;\r
 };\r
 \r
@@ -332,21 +404,15 @@ function X_Node_createAt( index, tag, opt_attrs, opt_css ){
  */\r
 function X_Node_createText( text ){\r
        var xnode;\r
-       if( this._xnodeType !== 1 ) return;\r
-       if( !this._xnodes ) this._xnodes = [];\r
-       \r
-       X_Node_newByText = true;\r
-       xnode = new Node( text );\r
-       xnode.parent = this;\r
-       \r
-       this._root && X_Node_reserveUpdate();\r
-       this._xnodes[ this._xnodes.length ] = xnode;\r
+       if( !this._tag ) return;\r
+       this.append( xnode = X_Doc_createText( text ) );\r
        return xnode;\r
 };\r
 function X_Node_createTextAt( index, text ){\r
-       var xtext = X_Doc_createText( text );\r
-       this.appendAt( index, xtext );\r
-       return xtext;\r
+       var xnode;\r
+       if( !this._tag ) return;\r
+       this.appendAt( index, xnode = X_Doc_createText( text ) );\r
+       return xnode;\r
 };\r
 \r
 /* --------------------------------------\r
@@ -356,27 +422,20 @@ function X_Node_createTextAt( index, text ){
  */\r
 function X_Node_clone( opt_clone_children ){\r
        var xnode, xnodes, i, l;\r
-       switch( this._xnodeType ){\r
-               case 1 :\r
-                       X_Node_newByTag = true;\r
-                       xnode = new Node( this._tag, X_Object_clone( this._attrs ), X_Object_clone( this._css ) )\r
-                               .attr( { 'id' : this._id } )\r
-                               .className( this._className );\r
-                       if( opt_clone_children && ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
-                               for( i = 0; i < l; ++i ){\r
-                                       xnode.append( xnodes[ i ].clone( true ) );\r
-                               };\r
+       if( this._tag ){\r
+               X_Node_newByTag = true;\r
+               xnode = new Node( this._tag, X_Object_clone( this._attrs ), X_Object_clone( this._css ) )\r
+                       .attr( { 'id' : this._id } )\r
+                       .className( this._className );\r
+               if( opt_clone_children && ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
+                       for( i = 0; i < l; ++i ){\r
+                               xnode.append( xnodes[ i ].clone( true ) );\r
                        };\r
-                       return xnode;\r
-               case 3 :\r
-                       X_Node_newByText = true;\r
-                       xnode = new Node( this._text );\r
-                       return xnode;\r
-               \r
-               //case 0 :\r
-               //case 2 :\r
+               };\r
+               return xnode;           \r
        };\r
-       return this;\r
+       X_Node_newByText = true;\r
+       return new Node( this._text );\r
 };\r
 \r
 /* --------------------------------------\r
@@ -386,7 +445,7 @@ function X_Node_clone( opt_clone_children ){
  */\r
 function X_Node_append( v ){\r
        var i, l, xnodes, frg;\r
-       if( this._xnodeType !== 1 ) return;\r
+       if( !this._tag ) return;\r
        \r
        if( 1 < ( l = arguments.length ) ){\r
                for( i = 0; i < l; ++i ){\r
@@ -406,22 +465,10 @@ function X_Node_append( v ){
                case X_Node_TYPE.STRING :\r
                        return this.append.apply( this, X_HtmlParser_parse( v, true ) );\r
                case X_Node_TYPE.XNODE :\r
-                       if( v._xnodeType !== 1 && v._xnodeType !== 3 ) return this;\r
                        // 親の xnodes から v を消す\r
-                       if( v.parent ){\r
-                               //if( X_UA_DOM.W3C ){\r
-                               //      v.parent._xnodes.splice( v.parent._xnodes.indexOf( v ), 1 );\r
-                               //} else\r
-                               //if( X_UA_DOM.IE4 ){\r
-                                       v.remove();\r
-                               //} else {\r
-                                       \r
-                               //};\r
-                       };// else\r
-                       //if( ( i = X_Node_reserveRemoval.indexOf( v ) ) !== -1 ){\r
-                       //      if( !this._state ) alert( 'xnode already destroyed!' );\r
-                       //      X_Node_reserveRemoval.splice( i, 1 );\r
-                       //};\r
+                       v.parent && v.remove();\r
+                       // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知\r
+                       if( X_UA[ 'IE4' ] && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
                        break;\r
                default :\r
                        return this;\r
@@ -429,7 +476,11 @@ function X_Node_append( v ){
 \r
        v.parent = this;\r
        xnodes[ xnodes.length ] = v;\r
-       this._root && X_Node_reserveUpdate();\r
+       if( this._flags & X_Node_State.IN_TREE ){\r
+               v._flags |= X_Node_State.IN_TREE;\r
+               v._xnodes && X_Node_toggleInTreeFlag( v._xnodes, true );\r
+               X_Node_reserveUpdate();\r
+       };\r
        return this;\r
 };\r
 \r
@@ -437,7 +488,7 @@ function X_Node_append( v ){
 function X_Node_appendAt( start, v ){\r
        var xnodes, l, i;\r
        \r
-       if( this._xnodeType !== 1 ) return this;\r
+       if( !this._tag ) return this;\r
        \r
        l = arguments.length;\r
        if( !( xnodes = this._xnodes ) ) xnodes = this._xnodes = [];\r
@@ -470,22 +521,10 @@ function X_Node_appendAt( start, v ){
                        };\r
                        return this;\r
                case X_Node_TYPE.XNODE :\r
-                       if( v._xnodeType !== 1 && v._xnodeType !== 3 ) return this;\r
                        // 親の xnodes から v を消す\r
-                       if( v.parent ){\r
-                               //if( X_UA_DOM.W3C ){\r
-                               //      v.parent._xnodes.splice( v.parent._xnodes.indexOf( v ), 1 );\r
-                               //} else\r
-                               //if( X_UA_DOM.IE4 ){\r
-                                       v.remove();\r
-                               //} else {\r
-                                       \r
-                               //};\r
-                       };// else\r
-                       //if( ( i = X_Node_reserveRemoval.indexOf( v ) ) !== -1 ){\r
-                       //      if( !this._state ) alert( 'xnode already destroyed!' );\r
-                       //      X_Node_reserveRemoval.splice( i, 1 );\r
-                       //};\r
+                       v.parent && v.remove();\r
+                       // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知\r
+                       if( X_UA[ 'IE4' ] && !v._tag && ( this._flags & X_Node_State.IE4_FIXED ) === 0 ) this._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
                        break;\r
                default :\r
                        return this;\r
@@ -493,7 +532,11 @@ function X_Node_appendAt( start, v ){
 \r
        v.parent = this;\r
        this._xnodes.splice( start, 0, v );\r
-       this._root && X_Node_reserveUpdate();\r
+       if( this._flags & X_Node_State.IN_TREE ){\r
+               v._flags |= X_Node_State.IN_TREE;\r
+               v._xnodes && X_Node_toggleInTreeFlag( v._xnodes, true );\r
+               X_Node_reserveUpdate();\r
+       };\r
        return this;\r
 };\r
 \r
@@ -582,7 +625,7 @@ function X_Node_after( v ){
        return this;\r
 };\r
 \r
-function X_Node_replace( v ){\r
+function X_Node_swap( v ){\r
        if( !this.parent ) return this;\r
        return arguments.length === 1 ? this.before( v ).remove() : this.before.apply( this, arguments ).remove();\r
 };\r
@@ -591,17 +634,35 @@ function X_Node_replace( v ){
  *  Remove\r
  */\r
 function X_Node_remove(){\r
-       var parent = this.parent;\r
+       var parent = this.parent,\r
+               elm;\r
        \r
        if( !parent ) return this;\r
 \r
+       delete this.parent;\r
        parent._xnodes.splice( parent._xnodes.indexOf( this ), 1 );\r
-       if( this._root ){\r
-               X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
-               X_Node_reserveUpdate();\r
+       \r
+       if( this._flags & X_Node_State.IN_TREE ){\r
+               this._flags &= ~X_Node_State.IN_TREE & ~X_Node_State.IE5_DISPLAY_NONE_FIX;\r
+               this._xnodes && X_Node_toggleInTreeFlag( this._xnodes, false );\r
+\r
+               if( X_UA_DOM.IE4 ){\r
+                       elm = this._rawObject || X_Node__ie4getRawNode( this );\r
+                       if( elm ){\r
+                               X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
+                               X_Node_reserveUpdate();                 \r
+                       } else\r
+                       if( !this._tag && ( parent._flags & X_Node_State.IE4_FIXED ) === 0 ){\r
+                               parent._flags |= X_Node_State.IE4_DIRTY_CHILDREN;\r
+                       };\r
+               } else {\r
+                       elm = this._rawObject;\r
+                       if( elm && elm.parentNode && elm.parentNode.tagName ){\r
+                               X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
+                               X_Node_reserveUpdate();                 \r
+                       };\r
+               };\r
        };\r
-       delete this.parent;\r
-       delete this._root;\r
        return this;\r
 };\r
 \r
@@ -617,14 +678,13 @@ function X_Node_empty(){
 };\r
 \r
 /* --------------------------------------\r
- *  destory\r
+ *  TODO destory -> kill\r
  */\r
-// Node._destroyChildFlag = false; // TODO\r
 \r
 function X_Node_destroy( isChild ){\r
        var xnodes = this._xnodes, i, elm;\r
        \r
-       if( !this._state ) return;\r
+       if( ( this._flags & X_Node_State.EXIST ) === 0 ) return;\r
        \r
        elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
        \r
@@ -635,18 +695,43 @@ function X_Node_destroy( isChild ){
        };\r
        elm && this._listeners && this.unlisten(); // イベントの退避\r
 \r
-       delete X_Node_CHASHE[ this._uid ];\r
-       delete this._state;\r
-       \r
-       if( this._root ){\r
+       if( this._flags & X_Node_State.IN_TREE ){\r
                !isChild && this.remove();\r
+               this._flags &= ~X_Node_State.EXIST;\r
        } else {\r
                this.parent && this.parent._xnodes.splice( this.parent._xnodes.indexOf( this ), 1 );\r
                elm && !isChild && X_Node__actualRemove( this );\r
                this.kill();\r
        };\r
+       \r
+       delete X_Node_CHASHE[ this._uid ];\r
 };\r
 \r
+function X_Node_onBeforeKill( e ){\r
+       var xnodes = this._xnodes, i, elm;\r
+       \r
+       if( ( this._flags & X_Node_State.EXIST ) === 0 ) return X.Callback.NONE;\r
+       \r
+       elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
+       elm && this._listeners && this.unlisten(); // イベントの退避\r
+\r
+       if( xnodes && ( i = xnodes.length ) ){\r
+               for( ; i; ){\r
+                       X_Node_onBeforeKill.call( xnodes[ --i ] );\r
+               };\r
+       };\r
+\r
+       delete X_Node_CHASHE[ this._uid ];\r
+\r
+       if( e ){\r
+               this.remove();\r
+               if( X_Node_reserveRemoval[ X_Node_reserveRemoval.length - 1 ] === this ){\r
+                       this._flags &= ~X_Node_State.EXIST;\r
+                       return X.Callback.PREVENT_DEFAULT;              \r
+               };              \r
+       };\r
+       return X.Callback.NONE;\r
+};\r
 \r
 \r
 /* --------------------------------------\r
@@ -654,7 +739,7 @@ function X_Node_destroy( isChild ){
  */\r
 function X_Node_contains( v ){\r
        var elm, type, xnodes, i;\r
-       if( !v || this._xnodeType !== 1 ) return false;\r
+       if( !v || !this._tag || this === v ) return false;\r
        // contains ie4+\r
        if( ( elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ) ) && document.contains && ( type = X_Node_getType( v ) ) && ( type === X_Node_TYPE.RAW_HTML || type === X_Node_TYPE.RAW_TEXT ) ){\r
                return elm.contains( v );       \r
@@ -665,7 +750,7 @@ function X_Node_contains( v ){
        xnodes = this._xnodes;\r
        if( !xnodes || !xnodes.length ) return false;\r
        if( xnodes.indexOf( v ) !== -1 ) return true; // fast\r
-       if( elm === v.parentNode ) return false;\r
+       if( elm === v.parentNode ) return true;\r
        for( i = xnodes.length; i; ){\r
                if( xnodes[ --i ].contains( v ) ) return true;\r
        };\r
@@ -676,7 +761,7 @@ function X_Node_contains( v ){
  *  getChild\r
  */\r
 function X_Node_getChildAt( i ){\r
-       var xnodes = this._xnodeType === 1 && this._xnodes;\r
+       var xnodes = this._xnodes;\r
        return xnodes && 0 <= i && i < xnodes.length && xnodes[ i ];\r
 };\r
 \r
@@ -714,7 +799,7 @@ function X_Node_className( v ){
        \r
        // setter\r
        if( this._className === v ) return this;\r
-       if( !v || typeof v !== 'string' ){\r
+       if( !v || !X_Type_isString( v ) ){\r
                delete this._className;\r
        } else {\r
                // cleanup\r
@@ -727,8 +812,8 @@ function X_Node_className( v ){
                if( this._className === v ) return this;\r
                v ? ( this._className = v ) : delete this._className;\r
        };\r
-       this._dirty |= X_Node_Dirty.CLASSNAME;\r
-       this._root && X_Node_reserveUpdate();\r
+       this._flags |= X_Node_State.DIRTY_CLASSNAME;\r
+       this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
        return this;\r
 };\r
 function X_Node_addClass( v ){\r
@@ -794,29 +879,29 @@ function X_Node_hasClass( v ){
 \r
 /* --------------------------------------\r
  *  html, text\r
+ * \r
+ * outerHTML が欲しい場合は、xnode.call('outerHTML') とできる。\r
  */\r
-\r
 function X_Node_html( html ){\r
        var _ = '', q = '"', xnodes, n, i, l;\r
        // setter\r
        if( html !== undefined ){ // String 以外に Number や false null なども許可\r
-               if( this._xnodeType === 3 ) return this.text( html );\r
+               if( !this._tag ) return this.text( html );\r
                return html ? this.empty().append.apply( this, X_HtmlParser_parse( html, true ) ) : this.empty();\r
        };\r
        \r
        // getter\r
-       if( this._xnodeType === 3 ){\r
+       if( !this._tag ){\r
                return this._text;\r
        };\r
        \r
-       if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this ) ) ){\r
-               delete this._cssText;\r
-       };\r
+       this._flags & X_Node_State.OLD_CSSTEXT && X_Node_CSS_objToCssText( this );\r
+\r
        html = !X_Node_outerXNode ? [] : [\r
                '<', this._tag,\r
                this._id ? ' id="' + this._id + q : _,\r
                this._className ? ' class="' + this._className + q : _,\r
-               this._attrText === false ? ( this._attrText = X_Node_Attr_objToAttrText( this._attrs ) ) : this._attrText,\r
+               this._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( this ) : this._attrText,\r
                this._cssText ? ' style="' + this._cssText + q : _,\r
        '>' ];\r
        \r
@@ -827,14 +912,14 @@ function X_Node_html( html ){
                        html[ n ] = xnodes[ i ].html();\r
                        ++n;\r
                };\r
-               if( X_Node_outerXNode === this )  X_Node_outerXNode = null;\r
+               if( X_Node_outerXNode === this ) X_Node_outerXNode = null;\r
        };\r
        !X_Node_outerXNode || X_Dom_DTD_EMPTY[ this._tag ] || ( html[ n ] = '<\/' + this._tag + '>' );\r
        return html.join( _ );\r
 };\r
 \r
 /*\r
- * null が来たら '', 数値等が来たら文字\r
+ * null が来たら '', 数値等が来たら文字\r
  */\r
 function X_Node_text( text ){\r
        var xnodes, texts, i, l;\r
@@ -843,24 +928,25 @@ function X_Node_text( text ){
                if( text === null ) text = '';\r
                text += '';\r
                \r
-               if( this._xnodeType === 3 ){\r
+               if( !this._tag ){\r
                        if( this._text !== text ){\r
-                               text ? ( this._text = text ) : delete this.text;\r
-                               this._root && X_Node_reserveUpdate();\r
-                               this._dirty |= X_Node_Dirty.CONTENT;\r
+                               text ? ( this._text = text ) : delete this._text;\r
+                               this._flags |= X_Node_State.DIRTY_CONTENT;                              \r
+                               this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
                        };\r
                        return this;\r
                };\r
-               if( !text ) return this.empty();\r
-               if( ( xnodes = this._xnodes ) && xnodes.length === 1 && xnodes[ 0 ]._xnodeType === 3 ){\r
+               if( ( xnodes = this._xnodes ) && xnodes.length === 1 && !xnodes[ 0 ]._tag ){\r
                        xnodes[ 0 ].text( text );\r
                        return this;\r
                };\r
+               // TODO 一つのtextnode を残すケース 完全に削除したい場合は empty()を使う\r
+               if( !text ) return this.empty();                \r
                this.empty().createText( text );\r
                return this;\r
        };\r
        // getter\r
-       if( this._xnodeType === 1 ){\r
+       if( this._tag ){\r
                if( ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
                        for( texts = [], i = 0; i < l; ++i ){\r
                                texts[ i ] = xnodes[ i ].text();\r
@@ -881,11 +967,36 @@ function X_Node_call( name /*, opt_args... */ ){
                \r
        X_Node_updateTimerID && X_Node_startUpdate();\r
        \r
+       switch( name ){\r
+               case 'nodeType' :\r
+                       return this._tag ? 1 : 3;\r
+               case 'text' :\r
+                       return this.text();\r
+               case 'html' :\r
+               case 'innerHTML' :\r
+                       return this.html();\r
+               case 'outerHTML' :\r
+                       X_Node_outerXNode = X_Node_body; // == true ならなんでもよい。型を合わすために xbody にしている\r
+                       v = this.html();\r
+                       X_Node_outerXNode = null;\r
+                       return v;\r
+               case 'fontSize' :\r
+                       return X_Node_CSS_getCharSize( this );\r
+               case 'inGPU' :\r
+                       return !!( this._flags & ( X_Node_State.GPU_NOW | X_Node_State.GPU_RELEASE_RESERVED ) );\r
+       };\r
+       \r
        raw  = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
        if( !raw ) return;\r
        \r
+       if( name === 'scrollTo' ){\r
+               raw.scrollLeft = arguments[ 1 ] || 0;\r
+               raw.scrollTop  = arguments[ 2 ] || 0;\r
+               return;\r
+       };\r
+       \r
        func = raw[ name ];\r
-       if( X.Type.isFunction( func ) ){\r
+       if( X_Type_isFunction( func ) ){\r
                if( l ){\r
                        args = X_Object_cloneArray( arguments );\r
                        args.shift();\r
@@ -893,7 +1004,7 @@ function X_Node_call( name /*, opt_args... */ ){
                };\r
                return raw[ name ]();           \r
        } else\r
-       if( X.Type.isUnknown( func ) ){\r
+       if( X_Type_isUnknown( func ) ){\r
                // typeof func === unknown に対策\r
                // http://la.ma.la/blog/diary_200509031529.htm          \r
                if( l ){\r
@@ -934,25 +1045,17 @@ function X_Node_each( func /*, opt_args */ ){
 /* --------------------------------------\r
  *  Async commit update\r
  * \r
- * state:\r
- *  0 : no_rawObject\r
- *  1 : no_parent\r
- *  2 : no_root\r
- *  3 : dirty\r
- *  4 : clean\r
- * \r
- * remove :\r
- * root._reserveRemoval = [] に追加。commitUpdate で remove して state は not_added\r
- * add :\r
- * root._reserveRemoval にいたら消す, new_parent._xnodes に挿入 steta は not_added にして commitUpdate を待つ\r
+ * TODO Timer や DOM イベントの呼び出しの最後に、まだ一度も commitUpdate していないなら commitUpdate してしまう。\r
  */\r
        \r
 function X_Node_reserveUpdate(){\r
        if( !X_Node_updateTimerID ) X_Node_updateTimerID = X.Timer.requestFrame( X_Node_startUpdate );\r
 };\r
 \r
+var X_Node_updateReservedByReleaseGPU = false;\r
+\r
 function X_Node_startUpdate( time ){\r
-       var removal, i, xnode, tmp;\r
+       var removal, i, xnode;\r
        \r
        if( !X_Node_updateTimerID || X_ViewPort_readyState < X_TEMP.SYSTEM_EVENT_INIT ){\r
                return;\r
@@ -963,207 +1066,414 @@ function X_Node_startUpdate( time ){
 \r
        if( time ){\r
                // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
-               X_System._listeners && X_System._listeners[ X.Event.BEFORE_UPDATE ] && X_System.dispatch( X.Event.BEFORE_UPDATE );\r
+               X_System._listeners && X_System._listeners[ X_Event.BEFORE_UPDATE ] && X_System.dispatch( X_Event.BEFORE_UPDATE );\r
        };\r
 \r
        removal = X_Node_reserveRemoval;\r
-       \r
-       //tmp = X_Node_body._rawObject.style.visibility;\r
-       //this._rawObject.style.visibility = 'hidden';\r
-\r
-       //console.log( '_actualRemove().' );\r
 \r
        if( i = removal.length ){\r
                for( ; i; ){\r
                        xnode = removal[ --i ];\r
+                       // TODO GPU レイヤーの子の場合、remove をスキップする。 非GPU レイヤーへ apppend される場合、clone する?\r
                        X_Node__actualRemove( xnode );\r
-                       !X_Node_body._state && xnode.kill();\r
+                       ( xnode._flags & X_Node_State.EXIST ) === 0 && xnode.kill();\r
                };\r
                removal.length = 0;\r
        };\r
-\r
-       //console.log( 'start _startUpdate().' );\r
-\r
-       /* X_Node_html._dirty ? */ X_Node__commitUpdate( X_Node_html ); /* : X_Node__commitUpdate( X_Node_body ); */;\r
        \r
-       //console.log( 'end of _startUpdate().' );\r
+       if( X_Node_html._flags & X_Node_BitMask_IS_DIRTY ){\r
+               X_Node__commitUpdate( X_Node_html, X_Node_html._rawObject.parentNode, null, X_Node_html._flags );\r
+       } else {\r
+               X_Node__commitUpdate( X_Node_head, X_Node_head._rawObject.parentNode, null, X_Node_head._flags );\r
+               X_Node__commitUpdate( X_Node_body, X_Node_body._rawObject.parentNode, null, X_Node_body._flags );\r
+       };\r
+       \r
+       if( X_Node_updateReservedByReleaseGPU ){\r
+               X_Node_reserveUpdate();\r
+               X_Node_updateReservedByReleaseGPU = false;\r
+       };\r
        \r
        if( time ){\r
                // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
-               X_System._listeners && X_System._listeners[ X.Event.UPDATED ] && X_System.dispatch( X.Event.UPDATED );  \r
+               X_System._listeners && X_System._listeners[ X_Event.UPDATED ] && X_System.dispatch( X_Event.UPDATED );  \r
        };\r
        \r
-       X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X.Event.AFTER_UPDATE );\r
-       //this._rawObject.style.visibility = tmp;\r
+       X_ViewPort._listeners && X_ViewPort._listeners[ X_Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X_Event.AFTER_UPDATE );\r
 };\r
 \r
+/*\r
+ * 1. GPU_NOW の場合、子の変更は行わない\r
+ * 2. GPU解放予約 の場合//、この要素のみ変更を行う。rAF 後にさらに更新するためフラグを立てる。\r
+ * 3. GPU予約 -> GPU\r
+ * 4. style="display:none" の場合、これ以下の変更を行わない。\r
+ * 5. ie5 非表示フラグが立っていて、親と自身の class・id によって非表示になっていて、親と自身に変更がない。accumulatedFlags を使用。\r
+ *     -> TODO これ TREE の変更を検出できない。 remove したときに 子まで X_Node_State.IE5_DISPLAY_NONE_FIXを落とす。\r
+ * 6. 要素の生成\r
+ * 7. 要素の位置のズレを補正\r
+ * 8. 更新の適用\r
+ * 9. ie5 親及び自身へのクラス・id指定で display:none になるケースがありそれを検出。\r
+ *   このままでは、生成と破棄が繰り返されてしまうので親と自身のクラス・idが変わった場合、ツリー位置の変化があった場合に再生する。\r
+ */\r
 var X_Node__commitUpdate =\r
        X_UA_DOM.W3C ?\r
-               ( function( that, parentElement, nextElement ){\r
+               ( function( that, parentElement, nextElement, accumulatedFlags ){\r
                        var elm = that._rawObject,\r
-                               xnodes, l, i, frg, next, k, v;\r
-\r
-                       if( that._state & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
-                               //alert( that._tag + ' ' + !!elm );\r
-                               // filter の効いている要素だけdisplay:none が無視される模様。filter を切ればよい?\r
-                               // 親が、display:none の場合は?\r
-                               elm && elm.parentNode && X_Node__actualRemove( that );\r
-                               return nextElement;\r
+                               created, xnodes, l, next;\r
+\r
+                       // 1. GPU 一切の更新をスキップ\r
+                       if( that._flags & X_Node_State.GPU_NOW ){\r
+                               console.log( '更新のskip ' + !!( that._flags & X_Node_BitMask_IS_DIRTY ) );\r
+                               that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
+                               return elm;\r
                        };\r
 \r
-                       if( !elm || ( parentElement && elm.parentNode !== parentElement ) || ( nextElement && elm.nextSibling !== nextElement ) ){\r
-                               nextElement ?\r
-                                       parentElement.insertBefore( X_Node__actualCreate( that ), nextElement ) :\r
-                                       parentElement.appendChild( X_Node__actualCreate( that ) );\r
-                               X_Node__afterActualCreate( that );\r
+                       // 2. GPU解放予約\r
+                       // TODO もしかしたらこのタイミングで更新できるかも。\r
+                       if( that._flags & X_Node_State.GPU_RELEASE_RESERVED ){\r
+                               console.log( 'GPU 解放 ' );\r
+                               //X_Node_updateReservedByReleaseGPU = true;\r
+                               //X_Node__updateRawNode( that, elm );\r
+                               that._flags &= X_Node_BitMask_RESET_GPU;\r
+                               //return elm;\r
+                       };\r
 \r
-                               return elm || that._rawObject;\r
-                       } else\r
-                       if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ) {\r
+                       // 3. GPU予約 -> GPU\r
+                       if( that._flags & X_Node_State.GPU_RESERVED ){\r
+                               that._flags &= X_Node_BitMask_RESET_GPU;\r
+                               that._flags |= X_Node_State.GPU_NOW;\r
+                       };\r
+\r
+                       // 4. style="display:none" の場合\r
+                       if( that._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ){\r
+                               if( X_Node_displayNoneFixForIE5 ){\r
+                                       // filter の効いている要素を含む要素は display:none が無視される。\r
+                                       // filter = '' で削除はできるが、再表示時に filter が消える。 -> filter な要素を削除してしまう。                                         \r
+                                       if( elm && elm.parentNode ){\r
+                                               X_Node__actualRemove( that );\r
+                                       };\r
+                                       return nextElement;\r
+                               };\r
+                               elm && ( elm.style.display = 'none' );\r
+                               return ( elm && elm.nextSibling === nextElement ) ? elm : nextElement;\r
+                       };\r
+                       \r
+                       // 5. ie5 非表示fixフラグ\r
+                       accumulatedFlags |= that._flags;\r
+                       \r
+                       if( that._flags & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
+                               if( accumulatedFlags & ( X_Node_State.DIRTY_POSITION | X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME ) === 0 ){\r
+                                       return nextElement;\r
+                               };\r
+                       };\r
+                       \r
+                       // 6. 要素の生成\r
+                       if( !elm ){\r
+                               if( !that._tag ){\r
+                                       that._flags &= X_Node_BitMask_RESET_DIRTY;\r
+                                       that._rawObject = elm = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
+                                       if( !X_UA[ 'IE' ] ){\r
+                                               elm.UID = that._uid;\r
+                                       };\r
+                               } else\r
+                               if( X_Node_strictElmCreation ){\r
+                                       that._flags & X_Node_State.OLD_CSSTEXT && X_Node_CSS_objToCssText( that, true ); // OLD_CSSTEXT ??\r
+               \r
+                                       that._rawObject = elm =\r
+                                               document.createElement( [\r
+                                                       '<', that._tag,\r
+                                                               ' UID="', that._uid, '"',\r
+                                                               that._id ? ' id="' + that._id + '"' : '',\r
+                                                               that._className ? ' class="' + that._className + '"' : '',\r
+                                                               X_Node_Attr_objToAttrText( that, true ),\r
+                                                               that._cssText ? ' style="' + that._cssText + '"' : '',\r
+                                                       '>' ].join( '' ) );\r
+                               } else {\r
+                                       that._rawObject = elm = document.createElement( that._tag );\r
+                               };\r
                                \r
-                               /*if( elm.childNodes.length !== l && ( frg = X_Node_useDocumentFragment ) ){\r
-                                       for( i = 0; i < l; ++i ){\r
-                                               frg.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
+                               // IE には要素追加のタイミングで起こるメモリリークがありここで追加\r
+                               if( !X_Node_addTreeAfterChildren ){\r
+                                       nextElement ?\r
+                                               parentElement.insertBefore( elm, nextElement ) :\r
+                                               parentElement.appendChild( elm );\r
+                               };\r
+\r
+                               if( that._tag ){\r
+                                       X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰                                \r
+                                       that._flags |= X_Node_State.ACTUAL_LISTENING;\r
+                                       \r
+                                       if( X_Node_documentFragment ){\r
+                                               //( frg = X_Node_documentFragment ).appendChild( elm );\r
+                                               // 連続する要素の差し替えの場合に有効\r
                                        };\r
-                                       elm.appendChild( frg );\r
-                               } else {*/\r
-                                       for( ; l; ){\r
-                                               next = X_Node__commitUpdate( xnodes[ --l ], elm, next );\r
+\r
+                                       if( X_Node_strictElmCreation ){\r
+                                               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
+                                               // ie の string から要素を作る場合、ネットワーク系属性は onload イベントなどを拾うために、要素生成->イベント復帰後に適用する\r
+                                               that._newAttrs && ( that._flags |= X_Node_State.DIRTY_ATTR ); // _newAttrs には ネットワーク系属性が入っている。Network 系の属性は遅らせて設定\r
+                                               that._flags |= X_Node_State.DIRTY_IE_FILTER;// doc 追加後に filter を指定しないと有効にならない。\r
+                                       } else {\r
+                                               elm.UID = that._uid;\r
+                                               that._newAttrs = that._attrs;\r
+                                               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
+                                               that._flags |= X_Node_State.DIRTY_ID | X_Node_State.DIRTY_CLASSNAME | X_Node_State.DIRTY_ATTR | X_Node_State.DIRTY_CSS | X_Node_State.DIRTY_IE_FILTER;\r
+                                               \r
+                                               // http://outcloud.blogspot.jp/2010/09/iframe.html\r
+                                               // この問題は firefox3.6 で確認\r
+                                               if( X_UA[ 'Gecko' ] ){\r
+                                                       if( that._tag === 'IFRAME' && ( !that._attrs || !that._attrs[ 'src' ] ) ){\r
+                                                               //elm.contentWindow.location.replace = elm.src = 'about:blank';\r
+                                                               that.attr( 'src', 'about:blank' );\r
+                                                       };\r
+                                               };\r
                                        };\r
-                               //};\r
+                               };\r
+                               \r
+                               created = true;\r
+                       } else\r
+                       // 7. 要素の位置のズレを補正\r
+                       if( elm.parentNode !== parentElement || ( nextElement && elm.nextSibling !== nextElement ) ){\r
+                               nextElement ?\r
+                                       parentElement.insertBefore( elm, nextElement ) :\r
+                                       parentElement.appendChild( elm );\r
+                       };\r
+                       \r
+                       if( that._listeners && ( that._flags & X_Node_State.ACTUAL_LISTENING ) === 0 ){\r
+                               X_EventDispatcher_toggleAllEvents( that, true );// イベントの退避\r
+                               that._flags |= X_Node_State.ACTUAL_LISTENING;\r
+                       };\r
+                       \r
+                       // 8. 更新の適用\r
+                       if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ){\r
+                               delete that._fontSize;\r
+                               X_Node__updateRawNode( that, elm );\r
+                       };\r
+\r
+                       // 9. ie5 only\r
+                       // 親及び自身へのクラス・id指定で display : none になるケースがありそれを検出\r
+                       // 生成と破棄が繰り返されてしまう、親と自身の id, class が変わった場合だけ再生成。 accumulatedFlags & ( ID | CLASSNAME )\r
+                       // currentStyle を観ていたときはエラーで停止する、alert と挟むと正常に動いて支離滅裂\r
+                       if( X_Node_displayNoneFixForIE5 && that._tag ){\r
+                               if( elm.runtimeStyle.display === 'none' ){\r
+                                       X_Node__actualRemove( that );\r
+                                       that._flags |= X_Node_State.IE5_DISPLAY_NONE_FIX;\r
+                                       return nextElement;                                     \r
+                               } else {\r
+                                       that._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX;\r
+                               };\r
+                       };\r
+                       \r
+                       // 10. 子要素の更新。\r
+                       if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ) {\r
+                               for( ; l; ){\r
+                                       next = X_Node__commitUpdate( xnodes[ --l ], elm, next, accumulatedFlags );\r
+                               };\r
                        };\r
 \r
-                       delete that._fontSize;\r
-                       that._dirty && X_Node__updateRawNode( that, elm );\r
-                       if( that._state & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
-                               return nextElement;\r
+                       if( created && X_Node_addTreeAfterChildren ){\r
+                               nextElement ?\r
+                                       parentElement.insertBefore( elm, nextElement ) :\r
+                                       parentElement.appendChild( elm );\r
+                               \r
+                               if( X_UA[ 'Gecko' ] && that._tag === 'IFRAME' && elm.contentWindow ){\r
+                                       // tree に追加されるまで contentWindow は存在しない。\r
+                                       elm.contentWindow.location.replace = elm.src;\r
+                               };\r
                        };\r
+\r
                        return elm;\r
                }) :\r
        X_UA_DOM.IE4 ? \r
-               ( function( that, parentElement, prevElement ){\r
-                       var elm    = that._rawObject || X_Node__ie4getRawNode( that ),\r
-                               xnodes, l, i, html, text, prev;\r
+               ( function( that, parentElement, prevElement, accumulatedFlags ){\r
+                       var elm = that._rawObject || X_Node__ie4getRawNode( that ),\r
+                               xnodes, l, i, dirty, mix, html, text, prev;\r
 \r
+                       if( !that._tag ){\r
+                               that._flags & X_Node_State.DIRTY_CONTENT && X_Node__updateRawNode( that, elm );\r
+                               return elm;\r
+                       };\r
+                       \r
+                       // 4. style="display:none" の場合\r
+                       if( that._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ){\r
+                               if( elm ){\r
+                                       elm.style.display = 'none';\r
+                                       if( elm.style.display !== 'none' ){ // ie4 の style は currentStyle 相当らしい、、、? div 以外への display:none が効かないので remove する。\r
+                                               X_Node__actualRemove( that );\r
+                                               return prevElement;\r
+                                       };\r
+                               };\r
+                               return elm || prevElement;\r
+                       };\r
+                       \r
                        if( !elm ){\r
                                prevElement ?\r
-                                       prevElement.insertAdjacentHTML( 'AfterEnd', X_Node__actualCreate( that ) ) :\r
-                                       parentElement.insertAdjacentHTML( 'AfterBegin', X_Node__actualCreate( that ) );\r
+                                       prevElement.insertAdjacentHTML( 'AfterEnd', X_Node__actualCreate( that, false ) ) :\r
+                                       parentElement.insertAdjacentHTML( 'AfterBegin', X_Node__actualCreate( that, false ) );\r
                                X_Node__afterActualCreate( that );\r
                                return that._rawObject || X_Node__ie4getRawNode( that );\r
                        };\r
                        \r
+                       accumulatedFlags |= that._flags;\r
+                       \r
                        xnodes = that._xnodes;\r
                        l      = xnodes ? xnodes.length : 0;\r
+                       dirty  = !!( that._flags & X_Node_State.IE4_DIRTY_CHILDREN );\r
                        \r
-                       if( that._dirty & X_Node_Dirty.IE4_TEXTNODE_FIX || ( that._state & X_Node_State.IE4_ONLY_TEXT && ( l !== 1 || xnodes[ 0 ]._xnodeType !== 3 ) ) ){ // 1 < l && elm.children.length === 0\r
+                       /*\r
+                        * HTML の下に TextNode だけ 。MIX_FIXED でない場合、削除、追加 を親に通知\r
+                        * HTML の下に HTML だけ\r
+                        * HTML の下は MIX -> TextNode, html の削除、変更、追加\r
+                        * HTML の下は MIX_FIXED -> TextNode を <font> に置き換えてあるのでW3C DON 的に触ることができる\r
+                        */\r
+                       if( dirty ){\r
+                               that._flags &= ~X_Node_State.IE4_DIRTY_CHILDREN;\r
+                               for( i = 0; i < l; ++i ){\r
+                                       if( xnodes[ i ]._tag ){\r
+                                               that._flags |= X_Node_State.IE4_HAS_ELEMENT;\r
+                                       } else {\r
+                                               that._flags |= X_Node_State.IE4_HAS_TEXTNODE;\r
+                                       };\r
+                                       if( that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){\r
+                                               mix = true;\r
+                                               break;\r
+                                       };\r
+                               };\r
+                       };\r
+                       \r
+                       if( that._flags & X_Node_State.IE4_FIXED || that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_State.IE4_HAS_ELEMENT ){\r
+                               for( i = 0; i < l; ++i ){\r
+                                       prev = X_Node__commitUpdate( xnodes[ i ], elm, prev, accumulatedFlags );\r
+                               };\r
+                       } else\r
+                       if( mix ){\r
                                html = [];\r
                                for( i = 0; i < l; ++i ){\r
-                                       html[ i ] = X_Node__actualCreate( xnodes[ i ] );\r
+                                       html[ i ] = X_Node__actualCreate( xnodes[ i ], false );\r
                                };\r
                                elm.innerHTML = html.join( '' );\r
                                for( i = 0; i < l; ++i ){\r
                                        X_Node__afterActualCreate( xnodes[ i ] );\r
                                };\r
-                               that._state &= ~X_Node_State.IE4_ONLY_TEXT;\r
+                               that._flags |= X_Node_State.IE4_FIXED;\r
                        } else\r
-                       if( that._state & X_Node_State.IE4_ONLY_TEXT ){ // textNode が swap した場合の検出は、_root で行う\r
-                               text = xnodes[ 0 ];\r
-                               if( text._dirty || !text._root ){\r
-                                       elm.innerHTML = text._text;\r
-                                       delete text._dirty;\r
-                                       text._root = that._root;                                        \r
-                               };\r
-                       } else\r
-                       if( l ){\r
+                       if( that._flags & X_Node_State.IE4_HAS_TEXTNODE ){\r
+                               dirty = dirty || false;\r
                                for( i = 0; i < l; ++i ){\r
-                                       prev = X_Node__commitUpdate( xnodes[ i ], elm, prev );\r
+                                       text = xnodes[ i ];\r
+                                       if( text._flags & X_Node_BitMask_IS_DIRTY ){\r
+                                               text._flags &= X_Node_BitMask_RESET_DIRTY;\r
+                                               dirty = true;\r
+                                       };\r
                                };\r
+                               if( dirty ) elm.innerHTML = that.text();\r
                        };\r
                        \r
-                       delete that._fontSize;\r
-                       that._dirty && X_Node__updateRawNode( that, elm );\r
+                       if( accumulatedFlags & X_Node_BitMask_IS_DIRTY ) delete that._fontSize;\r
+                       \r
+                       that._flags &= ~X_Node_State.DIRTY_POSITION;\r
+                       that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
                        return elm;\r
                }) :\r
                (function(){});\r
 \r
+/*\r
+ * GPU レイヤーするブラウザは、子要素から変更を当てていく? <- とりあえず、親要素から。\r
+ */\r
 var X_Node__updateRawNode =\r
        X_UA_DOM.W3C ?\r
                ( function( that, elm ){\r
                        var attrs, rename, k, v;\r
 \r
                        // textNode\r
-                       if( that._dirty & X_Node_Dirty.CONTENT ){\r
+                       if( !that._tag ){\r
                                elm.data = X_String_chrReferanceTo( that._text );\r
-                               delete that._dirty;\r
+                               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                                return;\r
                        };\r
                        // id\r
-                       if( that._dirty & X_Node_Dirty.ID ){\r
+                       if( that._flags & X_Node_State.DIRTY_ID ){\r
                                that._id ? ( elm.id = that._id ) : ( elm.id && elm.removeAttribute( 'id' ) );           \r
                        };\r
                        // className\r
-                       if( that._dirty & X_Node_Dirty.CLASSNAME ){\r
-                               that._className ? ( elm.className = that._className ) : ( elm.className && elm.removeAttribute( X_UA.IE5678 ? 'className' : 'class' ) ); // className は ie7-?                         \r
-\r
-                               // ie5 only\r
-                               if( X_Node_State.IE5_DISPLAY_NONE_FIX && elm.currentStyle.display === 'none' ){\r
-                                       X_Node__actualRemove( that );\r
-                                       that._state |= X_Node_State.IE5_DISPLAY_NONE_FIX;\r
-                                       return;\r
+                       if( that._flags & X_Node_State.DIRTY_CLASSNAME ){\r
+                               that._className ? ( elm.className = that._className ) : ( elm.className && elm.removeAttribute( X_UA[ 'IE' ] < 8 ? 'className' : 'class' ) ); // className は ie7-                     \r
+                       };\r
+                       \r
+                       // attr\r
+                       if( that._flags & X_Node_State.DIRTY_ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
+                               rename = X_Node_Attr_renameForDOM;\r
+                                               \r
+                               for( k in attrs ){\r
+                                       v = attrs[ k ];\r
+                                       \r
+                                       switch( that._tag + k ){\r
+                                               case 'TEXTAREAvalue' :\r
+                                                       // IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので\r
+                                                       if( !X_UA[ 'MacIE' ] && X_UA[ 'IE5x' ] ){\r
+                                                               elm.firstChild ?\r
+                                                                       ( elm.firstChild.data = v || '' ) :\r
+                                                                       elm.appendChild( document.createTextNode( v || '' ) );\r
+                                                               continue;\r
+                                                       };\r
+                                                       break;\r
+                                               \r
+                                               case 'IFRAMEsrc' :\r
+                                                       // http://outcloud.blogspot.jp/2010/09/iframe.html\r
+                                                       // この問題は firefox3.6 で確認\r
+                                                       if( X_UA[ 'Gecko' ] && elm.contentWindow ){\r
+                                                               elm.contentWindow.location.replace = elm.src = v || '';\r
+                                                               continue;\r
+                                                       };\r
+                                                       break;\r
+                                               \r
+                                               case 'IFRAMEname' :\r
+                                                       // http://d.hatena.ne.jp/NeoCat/20080921/1221940658\r
+                                                       // こちらに名前をsetしないとtargetが動作しない\r
+                                                       // これってあとから name を変更できないバグでは? itozyun\r
+                                                       // if( X_UA[ 'IE' ] ) elm.name = elm.contentWindow.name = v || '';\r
+                                       };\r
+                                       \r
+                                       //if( X_EMPTY_OBJECT[ k ] ) continue;\r
+                                       // TODO IE では input, なぜか button, object も type, name の変更が出来ない、同値で置き換えようとしても不可\r
+                                       v === undefined ?\r
+                                               elm.removeAttribute( rename[ k ] || k ) :\r
+                                               ( elm[ rename[ k ] || k ] = X_Node_Attr_noValue[ k ] ? k : v );\r
                                };\r
+                               delete that._newAttrs;\r
                        };\r
                        \r
                        // style\r
-                       // TODO display:none の場合、更新をスキップ\r
-                       if( that._dirty & X_Node_Dirty.CSS ){\r
-                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
-                                       X_UA.Opera78 || X_UA.NN6 ?\r
+                       if( that._flags & X_Node_State.DIRTY_CSS ){\r
+                               if( that._flags & X_Node_State.OLD_CSSTEXT ? X_Node_CSS_objToCssText( that ) : that._cssText ){\r
+                                       X_UA[ 'Opera78' ] || X_UA[ 'NN6' ] ?\r
                                                elm.setAttribute( 'style', that._cssText ) : // opera8用\r
                                                ( elm.style.cssText = that._cssText );\r
                                } else {\r
                                        elm.style.cssText = ''; // IE5.5以下 Safari3.2 で必要\r
                                        elm.removeAttribute( 'style' );\r
-                                       delete that._cssText;\r
                                };\r
-                       };\r
-                       \r
-                       if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                               elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
-                       };\r
-                       \r
-                       // attr\r
-                       // TODO display:none の場合、更新をスキップ\r
-                       if( that._dirty & X_Node_Dirty.ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
-                               rename = X_Node_Attr_renameForDOM;\r
-                               for( k in attrs ){\r
-                                       if( !X_UA.MacIE && ( X_UA.IE5 || X_UA.IE55 ) ){ // IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので\r
-                                               if( that._tag === 'TEXTAREA' && k === 'value' ){\r
-                                                       elm.firstChild ?\r
-                                                               ( elm.firstChild.data = attrs[ k ] ) :\r
-                                                               elm.appendChild( document.createTextNode( attrs[ k ] ) );\r
-                                                       continue;\r
-                                               };\r
-                                       };\r
-                                       // TODO IE では input, なぜか buttonも、type の変更が出来ない、object も 同値で置き換えようとしても不可\r
-                                       ( v = attrs[ k ] ) === undefined ?\r
-                                               elm.removeAttribute( rename[ k ] || k ) :\r
-                                               ( elm[ rename[ k ] || k ] = X_Node_Attr_noValue[ k ] ? k : v );                         \r
-\r
+                       } else\r
+                       if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
+                               v = X_Node_CSS_objToIEFilterText( that );\r
+                               if( v ){\r
+                                       elm.style.filter = v;\r
+                                       that._flags |= X_Node_State.IE_FILTER_NOW;\r
+                               } else {\r
+                                       elm.style.removeAttribute( 'filter' );\r
+                                       that._flags &= ~X_Node_State.IE_FILTER_NOW;\r
                                };\r
-                               delete that._newAttrs;\r
                        };\r
                        \r
-                       delete that._dirty;\r
+                       that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                }) :\r
        X_UA_DOM.IE4 ? \r
                ( function( that, elm ){\r
                        var attrs, rename, k, v;\r
 \r
                        // fake textNode\r
-                       if( that._dirty & X_Node_Dirty.CONTENT ){\r
+                       if( !that._tag ){\r
                                elm.innerText = that._text;\r
-                               delete that._dirty;\r
+                               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                                return;\r
                        };\r
                        \r
@@ -1172,41 +1482,45 @@ var X_Node__updateRawNode =
                 * title、className、id、lang、language には setAttribute でなく、element.id で直接読み書きできる\r
                 */     \r
                        // id\r
-                       if( that._dirty & X_Node_Dirty.CONTENT ) elm.setAttribute( 'id', that._id || ( 'ie4uid' + xnode._uid ) );\r
+                       if( that._flags & X_Node_State.DIRTY_ID ) elm.setAttribute( 'id', that._id || ( 'ie4uid' + that._uid ) );\r
 \r
                        // className\r
-                       if( that._dirty & X_Node_Dirty.CLASSNAME ){\r
+                       if( that._flags & X_Node_State.DIRTY_CLASSNAME ){\r
                                that._className ? ( elm.className = that._className ) : elm.removeAttribute( 'class' );\r
                        };\r
                        // style\r
-                       if( that._dirty & X_Node_Dirty.CSS ){\r
-                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
+                       if( that._flags & X_Node_State.DIRTY_CSS ){\r
+                               if( that._flags & X_Node_State.OLD_CSSTEXT ? X_Node_CSS_objToCssText( that ) : that._cssText ){\r
                                        elm.style.cssText = that._cssText;\r
                                } else {\r
                                        elm.style.cssText = '';\r
                                        elm.removeAttribute( 'style' );\r
-                                       delete that._cssText;\r
                                };\r
-                       };\r
-                       \r
-                       if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                               that._rawObject.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
+                       } else\r
+                       if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
+                               v = X_Node_CSS_objToIEFilterText( that );\r
+                               if( v ){\r
+                                       elm.style.filter = v;\r
+                                       that._flags |= X_Node_State.IE_FILTER_NOW;\r
+                               } else {\r
+                                       elm.style.removeAttribute( 'filter' );\r
+                                       that._flags &= ~X_Node_State.IE_FILTER_NOW;\r
+                               };\r
                        };\r
                        \r
                        // attr\r
-                       if( that._dirty & X_Node_Dirty.ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
+                       if( that._flags & X_Node_State.DIRTY_ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
                                rename = X_Node_Attr_renameForDOM;\r
                                for( k in attrs ){\r
+                                       //if( X_EMPTY_OBJECT[ k ] ) continue;\r
                                        ( v = attrs[ k ] ) === undefined ?\r
                                                elm.removeAttribute( rename[ k ] || k ) :\r
-                                       //that._tag === 'TEXTAREA' && k === 'value' ?\r
-                                       //      ( elm.innerText = v ) :\r
                                                elm.setAttribute( rename[ k ] || k, X_Node_Attr_noValue[ k ] ? k : v );\r
                                };\r
                                delete that._newAttrs;\r
                        };\r
-                       \r
-                       delete that._dirty;\r
+\r
+                       that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                }) :\r
                (function(){});\r
 \r
@@ -1228,170 +1542,133 @@ var X_Node__updateRawNode =
  * document.createElement of ie4 is only for OPTION & IMAGE.\r
  */\r
 var X_Node__actualCreate =\r
-       X_UA_DOM.W3C ? (function( that, isChild ){\r
-               var elm = that._rawObject,\r
-                       xnodes, frg, i, l;\r
-               \r
-               if( that._xnodeType === 3 ){\r
-                       if( elm ) return elm;\r
-                       delete that._dirty;\r
-                       return that._rawObject = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
-               };\r
-               \r
-               if( !elm ){\r
-                       if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
-                               delete that._cssText;\r
-                       };\r
-                       that._isNew = true;\r
-                       that._rawObject = elm =\r
-                               X_Node_strictElmCreation ?\r
-                                       document.createElement( [\r
-                                               '<', that._tag,\r
-                                                       ' UID="', that._uid, '"',\r
-                                                       that._id ? ' id="' + that._id + '"' : '',\r
-                                                       that._className ? ' class="' + that._className + '"' : '',\r
-                                                       that._attrText === false ? ( that._attrText = X_Node_Attr_objToAttrText( that._attrs ) ) : that._attrText,\r
-                                                       that._cssText ? ' style="' + that._cssText + '"' : '',\r
-                                               '>' ].join( '' ) ) :\r
-                                       document.createElement( that._tag );\r
-               };\r
-               if( X_Node_useDocumentFragment ){\r
-                       if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
-                               !isChild && ( frg = X_Node_useDocumentFragment ).appendChild( elm );\r
-                               for( i = 0; i < l; ++i ){\r
-                                       elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
-                               };\r
-                               return frg || elm;\r
-                       };\r
-               };\r
-               \r
-               return elm;\r
-       }) :\r
-       X_UA_DOM.IE4 ? (function( that, isChild ){\r
+       X_UA_DOM.IE4 && (function( that, isChild ){\r
                var uid = that._uid,\r
                        html, xnodes, n, i, l;\r
                \r
-               if( that._xnodeType === 3 ){\r
+               if( !that._tag ){\r
                        html = [ '<FONT id=ie4uid', uid, ' UID="', uid, '">', that._text, '</FONT>' ];// fake textNode\r
                        delete that._rawObject;\r
                } else {\r
-                       if( that._rawObject && !isChild ) X_Node__actualRemove( that, true );\r
+                       if( !isChild ) X_Node__actualRemove( that, /* true */ false );\r
                        \r
-                       if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
-                               delete that._cssText;\r
-                       };\r
+                       that._flags & X_Node_State.OLD_CSSTEXT && X_Node_CSS_objToCssText( that, true );\r
                        \r
                        html = [\r
                                '<', that._tag, ' id=', ( that._id || ( 'ie4uid' + uid ) ), ' UID="', uid, '"',\r
                                that._className ? ' class="' + that._className + '"' : '',\r
-                               that._attrText === false ? ( that._attrText = X_Node_Attr_objToAttrText( that._attrs ) ) : that._attrText,\r
+                               X_Node_Attr_objToAttrText( that, true ),\r
                                that._cssText ? ' style="' + that._cssText + '"' : '',\r
                        '>' ];\r
                        \r
                        n = html.length;\r
                        if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
-                               if( l === 1 && xnodes[ 0 ]._xnodeType === 3 ){\r
+                               \r
+                               that._flags &= ~X_Node_State.IE4_DIRTY_CHILDREN;\r
+                               for( i = 0; i < l; ++i ){\r
+                                       if( xnodes[ i ]._tag ){\r
+                                               that._flags |= X_Node_State.IE4_HAS_ELEMENT;\r
+                                       } else {\r
+                                               that._flags |= X_Node_State.IE4_HAS_TEXTNODE;\r
+                                       };\r
+                                       if( that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_BitMask_IE4_IS_MIX ){\r
+                                               break;\r
+                                       };\r
+                               };\r
+                               \r
+                               if( that._flags & X_Node_BitMask_IE4_IS_MIX === X_Node_State.IE4_HAS_TEXTNODE ){\r
                                        // only textnode\r
-                                       html[ n ] = xnodes[ 0 ]._text;\r
+                                       html[ n ] = that.text();\r
                                        ++n;\r
-                                       that._state |= X_Node_State.IE4_ONLY_TEXT;\r
                                } else {\r
                                        for( i = 0; i < l; ++i ){\r
                                                html[ n ] = X_Node__actualCreate( xnodes[ i ], true );\r
                                                ++n;\r
-                                       };                                      \r
+                                       };\r
+                                       that._flags |= X_Node_State.IE4_FIXED;\r
                                };\r
                        };\r
                        X_Dom_DTD_EMPTY[ that._tag ] || ( html[ n ] = '<\/' + that._tag + '>' );\r
                        \r
-                       delete that._newAttrs;\r
+                       that._newAttrs && ( that._flags |= X_Node_State.DIRTY_ATTR );\r
                };\r
                \r
                return html.join( '' );\r
-       }) :\r
-       (function(){});\r
+       });\r
 \r
 var X_Node__afterActualCreate =\r
-       X_UA_DOM.W3C ? (function( that ){\r
-               var elm = that._rawObject, xnodes, l, attrs, k, i;\r
-\r
-               that._root  = that.parent._root;\r
+       X_UA_DOM.IE4 && (function( that ){\r
+               var xnodes, i, v;\r
                \r
-               if( that._xnodeType === 3 ){\r
-                       that._dirty && X_Node__updateRawNode( that, elm );\r
-                       return that;\r
-               };\r
-                       \r
-               xnodes = that._xnodes;\r
-               l      = xnodes && xnodes.length;\r
-               \r
-               if( that._isNew ){\r
-                       if( !X_Node_useDocumentFragment && l ){// docFrg が使えない場合、doc 追加後に子を追加\r
-                               for( i = 0; i < l; ++i ){\r
-                                       elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
-                               };\r
-                       };\r
-                       if( X_Node_strictElmCreation ){\r
-                               if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                                       elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
-                               };\r
-                               delete that._dirty;\r
-                       } else {\r
-                               elm.UID = that._uid;\r
-                               that._newAttrs = that._attrs;\r
-                               that._dirty = X_Node_Dirty.ID | X_Node_Dirty.CLASSNAME | X_Node_Dirty.CSS | X_Node_Dirty.ATTR | X_Node_Dirty.IE_FILTER;\r
-                               X_Node__updateRawNode( that, elm );\r
-                       };\r
-                       \r
-                       delete that._isNew;\r
-               } else {\r
-                       that._dirty && X_Node__updateRawNode( that, elm );\r
-               };\r
-               \r
-               for( i = 0; i < l; ++i ){\r
-                       X_Node__afterActualCreate( xnodes[ i ] );\r
-               };\r
-               // src の onload があるので先ではないか?\r
-               // TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
-               X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
-       }) :\r
-       X_UA_DOM.IE4 ? (function( that ){\r
-               var xnodes, i;\r
-               that._root = that.parent._root;\r
-               \r
-               if( that._xnodeType !== 1 ) return that;\r
+               if( !that._tag ) return that;\r
                \r
                if( ( xnodes = that._xnodes ) && ( i = xnodes.length ) ){\r
                        for( ; i; ){\r
                                X_Node__afterActualCreate( xnodes[ --i ] );\r
                        };\r
                };\r
-               // textarea への value の適用はここで\r
-               if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
-                       X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_objToIEFilterText( that );;\r
+               // ネットワーク系属性と filter は要素生成後に適用\r
+               if( that._flags & ( X_Node_State.DIRTY_ATTR | X_Node_State.DIRTY_IE_FILTER ) ){\r
+                       X_Node__updateRawNode( that, that._rawObject || X_Node__ie4getRawNode( that ) );\r
+               } else {\r
+                       that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                };\r
-               delete that._dirty;\r
                X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
-       }) :\r
-       (function(){});\r
+       });\r
 \r
 var X_Node__actualRemove =\r
        X_UA_DOM.W3C ?\r
+               // GPUレイヤーにいるうちは remove しない。-> GPU解除してから remove する\r
+               // Firefox34 では遭遇せず、Safari で何度かアニメーションしているうちに発生\r
                ( function( that, isChild ){\r
                        var xnodes = that._xnodes,\r
                                elm    = that._rawObject,\r
                                child, i, l;\r
+\r
                        if( xnodes && ( l = xnodes.length ) ){\r
                                for( i = 0; i < l; ++i ){\r
                                        child = xnodes[ i ];\r
-                                       child._xnodeType === 1 && X_Node__actualRemove( child, true );\r
+                                       child._tag && X_Node__actualRemove( child, true );\r
                                };\r
                        };\r
 \r
                        if( !elm ) return;\r
-                       that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
-                       if( !X_UA.MacIE ){\r
-                               // elm.parentNode.tagName for ie7 -> that.state & BELONG_TREE_ACTUAL\r
+                       \r
+                       if( that._flags & X_Node_State.ACTUAL_LISTENING ){\r
+                               that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
+                               that._flags &= ~X_Node_State.ACTUAL_LISTENING;\r
+                       };\r
+                       \r
+                       // ie5では filter の効いている要素をremove時に破棄して、再度append 時に新規生成する\r
+                       // ちなみに elm.filters に触ると ie8 でなぜかカラム落ちが発生、、、\r
+                       if( X_Node_displayNoneFixForIE5 ){\r
+                               if( elm.filters && elm.filters.length ){\r
+                                       //elm.style.removeAttribute( 'filter' );\r
+                                       isChild = false;\r
+                                       delete that._rawObject;\r
+                                       // 破棄前にインタラクティブな属性値を控える\r
+                                       if( X_Node_Attr_HAS_VALUE[ that._tag ] && ( !that._newAttrs || !X_Object_inObject( 'value', that._newAttrs ) ) ){\r
+                                               if( !that._attrs ) that._attrs = {};\r
+                                               that._attrs.value = elm.value;\r
+                                       };\r
+                                       if( that._tag === 'OPTION' && ( !that._newAttrs || !X_Object_inObject( 'selected', that._newAttrs ) ) ){\r
+                                               if( !that._attrs ) that._attrs = {};\r
+                                               that._attrs.selected = elm.selected;\r
+                                       };\r
+                                       if( that._tag === 'SELECT' && ( !that._newAttrs || !X_Object_inObject( 'selectedIndex', that._newAttrs ) ) ){\r
+                                               if( !that._attrs ) that._attrs = {};\r
+                                               that._attrs.selectedIndex = elm.selectedIndex;\r
+                                       };\r
+                                       if( that._tag === 'INPUT' && that._attr && ( that._attr.type === 'checkbox' || that._attr.type === 'radio' ) && ( !that._newAttrs || !X_Object_inObject( 'checked', that._newAttrs ) ) ){\r
+                                               that._attrs.checked = elm.checked;\r
+                                       };\r
+                                       // 子要素への参照を外す\r
+                                       elm.innerHTML = '';\r
+                               };\r
+                       };\r
+                       \r
+                       if( !X_UA[ 'MacIE' ] ){\r
+                               // elm.parentNode.tagName for ie7\r
                                !isChild && elm.parentNode && elm.parentNode.tagName && elm.parentNode.removeChild( elm );\r
                        } else {\r
                                !isChild && elm.parentNode && elm.parentNode.tagName && X_TEMP._fixed_remove( elm, that );\r
@@ -1411,9 +1688,24 @@ var X_Node__actualRemove =
                        if( !elm ) return;\r
                        that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
                        \r
+                       // 破棄前にインタラクティブな属性値を控える\r
                        if( X_Node_Attr_HAS_VALUE[ that._tag ] && ( !that._newAttrs || !X_Object_inObject( 'value', that._newAttrs ) ) ){\r
+                               if( !that._attrs ) that._attrs = {};\r
                                that._attrs.value = elm.value;\r
                        };\r
+                       if( that._tag === 'OPTION' && ( !that._newAttrs || !X_Object_inObject( 'selected', that._newAttrs ) ) ){\r
+                               if( !that._attrs ) that._attrs = {};\r
+                               that._attrs.selected = elm.selected;\r
+                       };\r
+                       if( that._tag === 'SELECT' && ( !that._newAttrs || !X_Object_inObject( 'selectedIndex', that._newAttrs ) ) ){\r
+                               if( !that._attrs ) that._attrs = {};\r
+                               that._attrs.selectedIndex = elm.selectedIndex;\r
+                       };\r
+                       if( that._tag === 'INPUT' && that._attr && ( that._attr.type === 'checkbox' || that._attr.type === 'radio' ) && ( !that._newAttrs || !X_Object_inObject( 'checked', that._newAttrs ) ) ){\r
+                               if( !that._attrs ) that._attrs = {};\r
+                               that._attrs.checked = elm.checked;\r
+                       };\r
+\r
                        elm.removeAttribute( 'id' ); // ?\r
                        //document.all[ that._id || ( 'ie4uid' + that._uid ) ] = null; // MacIE5 でエラー\r
                        if( !isChild ) elm.outerHTML = '';\r
@@ -1421,5 +1713,5 @@ var X_Node__actualRemove =
                }) :\r
                (function(){});\r
 \r
-X_ViewPort.listenOnce( X.Event.UNLOAD, X_Node__actualRemove, [ X_Node_html, true ] );\r
+X_ViewPort.listenOnce( X_Event.UNLOAD, X_Node__actualRemove, [ X_Node_html, true ] );\r
 \r