OSDN Git Service

Version 0.6.124, remove xnode._root.
authoritozyun <itozyun@user.sourceforge.jp>
Fri, 23 Jan 2015 02:33:53 +0000 (11:33 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Fri, 23 Jan 2015 02:33:53 +0000 (11:33 +0900)
0.6.x/js/01_core/16_XViewPort.js
0.6.x/js/02_dom/02_XNode.js
0.6.x/js/02_dom/04_XBoxModel.js
0.6.x/js/02_dom/05_XNodeAttr.js
0.6.x/js/02_dom/06_XNodeCSS.js
0.6.x/js/02_dom/22_XTreeBuilder.js

index 5627a85..a290fea 100644 (file)
@@ -287,12 +287,12 @@ X.ViewPort = {
                        X_ViewPort_rootElement = document.compatMode !== 'CSS1Compat' ? elmBody : elmHtml || elmBody;
 
                        html = X.Doc.html = X_Node_html = elmHtml && new Node( elmHtml );
-               
+                       html._flags |= X_Node_State.IN_TREE;
+                       
                        head = X.Doc.head = X_Node_head = elmHead && new Node( elmHead );
                
                        body = X.Doc.body = X_Node_body = new Node( elmBody );
-                       
-                       body._root   = html._root = head._root = body;// _root は html だろ
+
                        body.parent  = head.parent = html;
                        html._xnodes = [ head, body ];
                        
index 9f5fa99..d526b36 100644 (file)
@@ -1,48 +1,63 @@
 var \r
        \r
        X_Node_State = {\r
-               DESTROYED              : 0,\r
-               EXIST                  : 1,\r
-               IN_TREE                : 2,\r
+               DESTROYED              : 0x0,\r
+               EXIST                  : 0x1,\r
+               IN_TREE                : 0x2, // xnode が(仮想)ツリーに追加されている -> 描画の対象\r
                \r
-               ELM_EXIST              : 2 <<  1,\r
-               ELM_IN_TREE            : 2 <<  2,\r
+               ELM_NEED_INIT          : 2 <<  1,\r
                \r
-               STYLE_IS_DISPLAY_NONE  : 2 <<  4, // display:none               \r
-               STYLE_IS_HIDDEN        : 2 <<  5, // visibility:hidden opacity:0\r
-               STYLE_IS_POS_ABSOLUTE  : 2 <<  6, // position:absolute\r
-               STYLE_IS_NO_OVERFLOW   : 2 <<  7, // overflow:hidden\r
-               STYLE_IS_WIDTH_LENGTH  : 2 <<  8, // width  : width() のための commitUpdate が不要\r
-               STYLE_IS_WIDTH_PCT     : 2 <<  9, // width  : width() のための commitUpdate が不要かもしれない。(親で LENGTH が指定されているなら)\r
-               STYLE_IS_HEIGHT_LENGTH : 2 << 10, // height :\r
-               STYLE_IS_HEIGHT_PCT    : 2 << 11, // height :\r
-               STYLE_IS_FONT_LENGTH   : 2 << 12, // fontSize :\r
-               STYLE_IS_FONT_PCT      : 2 << 13, // fontSize :\r
+               STYLE_IS_DISPLAY_NONE  : 2 <<  2, // display    : none          \r
+               STYLE_IS_INVISIBLE     : 2 <<  3, // visibility : hidden or opacity : 0\r
+               STYLE_IS_POS_ABSOLUTE  : 2 <<  4, // position   : absolute\r
+               STYLE_IS_NO_OVERFLOW   : 2 <<  5, // overflow   : hidden\r
+               STYLE_IS_WIDTH_LENGTH  : 2 <<  6, // width  : width() のための commitUpdate が不要\r
+               STYLE_IS_WIDTH_PCT     : 2 <<  7, // width  : width() のための commitUpdate が不要かもしれない。(親で LENGTH が指定されているなら)\r
+               STYLE_IS_HEIGHT_LENGTH : 2 <<  8, // height :\r
+               STYLE_IS_HEIGHT_PCT    : 2 <<  9, // height :\r
+               STYLE_IS_FONT_LENGTH   : 2 << 10, // fontSize :\r
+               STYLE_IS_FONT_PCT      : 2 << 11, // fontSize :\r
+\r
+               //DIRTY_CHILD            : 2 << 18, // 使っていない\r
+               DIRTY_CONTENT          : 2 << 12, // width, height, x, y textNode の内容 TODO html と排他なので ID と共通でいい\r
+               DIRTY_ID               : 2 << 13, // width, height, x, y\r
+               DIRTY_CLASSNAME        : 2 << 14, // X_Node_CSS_getCharSize, width, height, x, y\r
+               DIRTY_ATTR             : 2 << 15, // X_Node_CSS_getCharSize, width, height, x, y\r
+               DIRTY_CSS              : 2 << 16, // X_Node_CSS_getCharSize, width, height, x, y\r
+               DIRTY_IE_FILTER        : X_UA.IE < 10 && X_UA.ActiveX ? 2 << 17 : 0, // \r
+\r
+               OLD_ATTRTEXT           : 2 << 18,\r
+               OLD_CSSTEXT            : 2 << 19,\r
+\r
+               GPU_WAITING            : 2 << 20,                     // 1:子のGPU解除待\r
+               GPU_RESERVED           : 2 << 21,                     // 2:GPU予約\r
+               GPU_NOW                : 2 << 20 | 2 << 21,           // 3:GPU now!()\r
+               GPU_RELEASE_RESERVED   : 2 << 20 | 2 << 21 | 2 << 22, // 4:GPU解除予約\r
                \r
-               IE4_ONLY_TEXT          : 2 << 14,\r
-               IE5_DISPLAY_NONE_FIX   : X_UA.IE5 && X_UA.ActiveX ? 2 << 15 : 0, // filterがかかっていると不可ってことかも? MacIE5.2- は ?\r
-               UNKNOWN_TAG_FIX        : 2 << 16, // 使っていない\r
-               IE4_TEXTNODE_FIX       : 2 << 17,\r
-               \r
-               DIRTY_CHILD            : 2 << 18, // 使っていない\r
-               DIRTY_CONTENT          : 2 << 19, // width, height, x, y textNode の内容\r
-               DIRTY_ID               : 2 << 20, // width, height, x, y\r
-               DIRTY_CLASSNAME        : 2 << 21, // X_Node_CSS_getCharSize, width, height, x, y\r
-               DIRTY_ATTR             : 2 << 22, // X_Node_CSS_getCharSize, width, height, x, y\r
-               DIRTY_CSS              : 2 << 23, // X_Node_CSS_getCharSize, width, height, x, y\r
-               DIRTY_IE_FILTER        : X_UA.IE < 10 && X_UA.ActiveX ? 2 << 24 : 0, // \r
-               \r
-               GPU_WAITING            : 2 << 25, // 1:子のGPU解除待\r
-               GPU_RESERVED           : 2 << 26, // 2:GPU予約\r
-               GPU_NOW                : 2 << 25 | 2 << 26, // 3:GPU now!()\r
-               GPU_RELEASE_RESERVED   : 2 << 27  // 4:GPU解除予約\r
+               /* 子要素は一つのテキストノード */\r
+               IE4_ONLY_TEXT          : 2 << 23,\r
+               /* 子要素に html要素とテキストノードが混在する */\r
+               IE4_TEXTNODE_FIX       : 2 << 24,\r
+               IE4_TEXTNODE_EXIST     : 2 << 25\r
        },\r
 \r
-       X_Node_DIRTY_MASK = \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 = \r
                X_Node_State.DIRTY_CHILD | 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_DIRTY_MASK_RESET = ( ( 2 << 29 ) - 1 ) ^ X_Node_DIRTY_MASK,\r
+       X_Node_BitMask_RESET_DIRTY = ( ( 2 << 29 ) - 1 + ( 2 << 29 ) ) ^ X_Node_BitMask_IS_DIRTY,\r
        \r
        X_Node_TYPE = {\r
                XNODE       : 1,\r
@@ -61,6 +76,8 @@ var
        \r
        X_Node_useDocumentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
        \r
+       X_Node_displayNoneFixForIE5 = X_UA.IE5 && X_UA.ActiveX,\r
+       \r
        X_Node_newByTag      = false,\r
        \r
        X_Node_newByText     = false,\r
@@ -77,30 +94,25 @@ var
        {\r
                _uid       : 0,\r
                _flags     : X_Node_State.DESTROYED,\r
-               \r
-               _isNew     : false, // state にまとめる\r
-               _root      : null, // xnode が文書ツリーに属しているか?はこれを見る -> state               \r
-               _xnodeType : 0,    // state へ\r
-                               \r
+\r
                _rawObject : null,\r
                _rect      : null, // \r
+               _fontSize  : 0,\r
                \r
                parent     : null, // remove された枝も親子構造は維持している。\r
                _xnodes    : null, // Array.<Node>\r
 \r
                _tag       : '',\r
-               _text      : null,\r
-               _id        : null,\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, // String | null\r
-               \r
-               _fontSize  : 0,\r
+               _cssText   : '',\r
                \r
                _anime     : null, // Hash see X_Node_Anime\r
                \r
@@ -113,7 +125,7 @@ var
                        if( X_Node_newByTag ){\r
                                X_Node_newByTag = false;\r
                                this._tag       = v.toUpperCase();\r
-                               this._flags     |= X_Node_State.EXIST;\r
+                               this._flags    |= X_Node_State.EXIST;\r
                                arguments[ 1 ] && this.attr( arguments[ 1 ] );\r
                                css = arguments[ 2 ];\r
                                css && this[ X.Type.isString( css ) ? 'cssText' : 'css' ]( css );\r
@@ -121,7 +133,7 @@ var
                        if( X_Node_newByText ){\r
                                X_Node_newByText = false;\r
                                this._text       = v;\r
-                               this._flags      |= X_Node_State.EXIST;\r
+                               this._flags     |= X_Node_State.EXIST;\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
@@ -135,19 +147,18 @@ var
                                                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 ){\r
-                                                       this._root = this.parent._root;\r
-                                                       this._flags |= X_Node_State.IN_TREE | X_Node_State.ELM_IN_TREE;\r
+                                               if( this.parent && ( this.parent._flags & X_Node_State.IN_TREE ) ){\r
+                                                       this._flags |= X_Node_State.IN_TREE;\r
                                                };\r
                                                this._rawObject = v;\r
-                                               this._flags     |= X_Node_State.EXIST | X_Node_State.ELM_EXIST;\r
+                                               this._flags    |= X_Node_State.EXIST;\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_State.DIRTY_CSS を落とす\r
-                                               //this._flags = 0;\r
-                                               this._flags &= X_Node_DIRTY_MASK_RESET;\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
@@ -160,9 +171,11 @@ var
                                        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
+                                               if( this.parent && ( this.parent._flags & X_Node_State.IN_TREE ) ){\r
+                                                       this._flags |= X_Node_State.IN_TREE;\r
+                                               };\r
                                                this._rawObject = v;\r
-                                               this._flags     |= X_Node_State.EXIST;\r
+                                               this._flags    |= X_Node_State.EXIST;\r
                                                this._text      = v.data;\r
                                                v.UID = uid;\r
                                                break;\r
@@ -324,6 +337,15 @@ var X_Node__ie4getRawNode = X_UA_DOM.IE4 && function ( that ){
        };\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 ) : ( xnode._flags &= ~X_Node_State.IN_TREE );\r
+               xnode._xnodes && X_Node_toggleInTreeFlag( xnode._xnodes, flag );\r
+       };\r
+};\r
+\r
 /* --------------------------------------\r
  *  Create\r
  */\r
@@ -336,7 +358,11 @@ function X_Node_create( tag, opt_attrs, opt_css ){
        \r
        xnode.parent = this;\r
        this._xnodes[ this._xnodes.length ] = xnode;\r
-       this._root && X_Node_reserveUpdate();\r
+       if( this._flags & X_Node_State.IN_TREE ){\r
+               xnode._flags |= X_Node_State.IN_TREE;\r
+               xnode._xnodes && X_Node_toggleInTreeFlag( xnode._xnodes, true );\r
+               X_Node_reserveUpdate();\r
+       };\r
        return xnode;\r
 };\r
 function X_Node_createAt( index, tag, opt_attrs, opt_css ){\r
@@ -356,9 +382,13 @@ function X_Node_createText( text ){
        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
+       \r
+       if( this._flags & X_Node_State.IN_TREE ){\r
+               xnode._flags |= X_Node_State.IN_TREE;\r
+               xnode._xnodes && X_Node_toggleInTreeFlag( xnode._xnodes, true );\r
+               X_Node_reserveUpdate();\r
+       };\r
        return xnode;\r
 };\r
 function X_Node_createTextAt( index, text ){\r
@@ -428,7 +458,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
@@ -480,7 +514,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,13 +620,15 @@ function X_Node_remove(){
        \r
        if( !parent ) return this;\r
 \r
+       delete this.parent;\r
        parent._xnodes.splice( parent._xnodes.indexOf( this ), 1 );\r
-       if( this._root ){\r
+       if( this._flags & X_Node_State.IN_TREE ){\r
+               this._flags ^= X_Node_State.IN_TREE;\r
+               this._xnodes && X_Node_toggleInTreeFlag( this._xnodes, false );\r
+               \r
                X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
                X_Node_reserveUpdate();\r
        };\r
-       delete this.parent;\r
-       delete this._root;\r
        return this;\r
 };\r
 \r
@@ -606,7 +646,6 @@ function X_Node_empty(){
 /* --------------------------------------\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
@@ -625,7 +664,7 @@ function X_Node_destroy( isChild ){
        delete X_Node_CHASHE[ this._uid ];\r
        delete this._flags;\r
        \r
-       if( this._root ){\r
+       if( this._flags & X_Node_State.IN_TREE ){\r
                !isChild && this.remove();\r
        } else {\r
                this.parent && this.parent._xnodes.splice( this.parent._xnodes.indexOf( this ), 1 );\r
@@ -634,6 +673,19 @@ function X_Node_destroy( isChild ){
        };\r
 };\r
 \r
+function X_Node_onKill( e ){\r
+       var elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
+       \r
+       delete X_Node_CHASHE[ this._uid ];\r
+       delete this._flags;\r
+       \r
+       if( this._flags & X_Node_State.IN_TREE ){\r
+               this.remove();\r
+       } else {\r
+               this.parent && this.parent._xnodes.splice( this.parent._xnodes.indexOf( this ), 1 );\r
+               elm && X_Node__actualRemove( this );\r
+       };\r
+};\r
 \r
 \r
 /* --------------------------------------\r
@@ -715,7 +767,7 @@ function X_Node_className( v ){
                v ? ( this._className = v ) : delete this._className;\r
        };\r
        this._flags |= X_Node_State.DIRTY_CLASSNAME;\r
-       this._root && X_Node_reserveUpdate();\r
+       this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
        return this;\r
 };\r
 function X_Node_addClass( v ){\r
@@ -797,14 +849,13 @@ function X_Node_html( html ){
                return this._text;\r
        };\r
        \r
-       if( this._flags & X_Node_State.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
@@ -815,7 +866,7 @@ 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
@@ -834,8 +885,8 @@ function X_Node_text( text ){
                if( !this._tag ){\r
                        if( this._text !== text ){\r
                                text ? ( this._text = text ) : delete this.text;\r
-                               this._root && X_Node_reserveUpdate();\r
-                               this._flags |= X_Node_State.DIRTY_CONTENT;\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
@@ -970,7 +1021,7 @@ function X_Node_startUpdate( time ){
                removal.length = 0;\r
        };\r
        \r
-       if( X_Node_html._flags & X_Node_DIRTY_MASK ){\r
+       if( X_Node_html._flags & X_Node_BitMask_IS_DIRTY ){\r
                X_Node__commitUpdate( X_Node_html );\r
        } else {\r
                X_Node__commitUpdate( X_Node_head );\r
@@ -991,7 +1042,7 @@ var X_Node__commitUpdate =
                        var elm = that._rawObject,\r
                                xnodes, l, i, frg, next, k, v;\r
 \r
-                       if( that._flags & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
+                       if( X_Node_displayNoneFixForIE5 && that._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ){\r
                                // filter の効いている要素だけdisplay:none が無視される模様。filter を切ればよい?\r
                                // 親が、display:none の場合は?\r
                                elm && elm.parentNode && X_Node__actualRemove( that );\r
@@ -1014,14 +1065,14 @@ var X_Node__commitUpdate =
 \r
                        delete that._fontSize;\r
 \r
-                       if( that._flags & X_Node_DIRTY_MASK ){\r
+                       if( that._flags & X_Node_BitMask_IS_DIRTY ){\r
                                X_Node__updateRawNode( that, elm );\r
                        } else\r
-                       if( X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
+                       if( that._tag && X_Node_displayNoneFixForIE5 && elm.currentStyle.display === 'none' ){\r
                                // TODO 親要素への変更で display:none が変わる場合もあるのでここで調べる\r
                        };\r
                        \r
-                       if( that._flags & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
+                       if( X_Node_displayNoneFixForIE5 && that._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ){\r
                                return nextElement;\r
                        };\r
                        return elm;\r
@@ -1042,7 +1093,7 @@ var X_Node__commitUpdate =
                        xnodes = that._xnodes;\r
                        l      = xnodes ? xnodes.length : 0;\r
                        \r
-                       if( that._flags & X_Node_State.IE4_TEXTNODE_FIX || ( that._flags & X_Node_State.IE4_ONLY_TEXT && ( l !== 1 || xnodes[ 0 ]._tag ) ) ){ // 1 < l && elm.children.length === 0\r
+                       if( ( that._flags & X_Node_State.IE4_ONLY_TEXT && ( l !== 1 || xnodes[ 0 ]._tag ) ) || that._flags & X_Node_State.IE4_TEXTNODE_FIX ){\r
                                html = [];\r
                                for( i = 0; i < l; ++i ){\r
                                        html[ i ] = X_Node__actualCreate( xnodes[ i ] );\r
@@ -1051,16 +1102,16 @@ var X_Node__commitUpdate =
                                for( i = 0; i < l; ++i ){\r
                                        X_Node__afterActualCreate( xnodes[ i ] );\r
                                };\r
+                               that._flags &= ~X_Node_State.IE4_TEXTNODE_FIX;\r
                                that._flags &= ~X_Node_State.IE4_ONLY_TEXT;\r
                        } else\r
-                       if( that._flags & X_Node_State.IE4_ONLY_TEXT ){ // textNode が swap した場合の検出は、_root で行う\r
+                       // TODO textNode だけが 2つ以上ある場合\r
+                       if( that._flags & X_Node_State.IE4_ONLY_TEXT ){\r
                                text = xnodes[ 0 ];\r
-                               //if( text._flags || !text._root ){\r
-                               if( text._flags & X_Node_State.DIRTY_CONTENT || !text._root ){\r
+                               if( text._flags & X_Node_State.DIRTY_CONTENT || ( text._flags & X_Node_State.IE4_TEXTNODE_EXIST ) === 0 ){\r
                                        elm.innerHTML = text._text;\r
-                                       //delete text._flags;\r
-                                       text._flags &= X_Node_DIRTY_MASK_RESET;\r
-                                       text._root = that._root;                                        \r
+                                       text._flags  &= X_Node_BitMask_RESET_DIRTY;\r
+                                       /* if( taht._flags & X_Node_State.IN_TREE ) */ text._flags |= X_Node_State.IE4_TEXTNODE_EXIST;\r
                                };\r
                        } else\r
                        if( l ){\r
@@ -1070,8 +1121,7 @@ var X_Node__commitUpdate =
                        };\r
                        \r
                        delete that._fontSize;\r
-                       //that._flags && X_Node__updateRawNode( that, elm );\r
-                       that._flags & X_Node_DIRTY_MASK && X_Node__updateRawNode( that, elm );\r
+                       that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
                        return elm;\r
                }) :\r
                (function(){});\r
@@ -1088,8 +1138,7 @@ var X_Node__updateRawNode =
                        // textNode\r
                        if( !that._tag ){\r
                                elm.data = X_String_chrReferanceTo( that._text );\r
-                               //delete that._flags;\r
-                               that._flags &= X_Node_DIRTY_MASK_RESET;\r
+                               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                                return;\r
                        };\r
                        // id\r
@@ -1099,16 +1148,16 @@ var X_Node__updateRawNode =
                        // className\r
                        if( that._flags & X_Node_State.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
-                               // TODO 親へのクラス・id指定で display : none になるケースもある\r
-                               if( X_Node_State.IE5_DISPLAY_NONE_FIX && elm.currentStyle.display === 'none' ){\r
-                                       X_Node__actualRemove( that );\r
-                                       that._flags |= X_Node_State.IE5_DISPLAY_NONE_FIX;\r
-                                       return;\r
-                               };\r
                        };\r
                        \r
+                       // ie5 only\r
+                       // TODO 親へのクラス・id指定で display : none になるケースもある\r
+                       if( X_Node_displayNoneFixForIE5 && elm.currentStyle.display === 'none' ){\r
+                               X_Node__actualRemove( that );\r
+                               that._flags |= X_Node_State.STYLE_IS_DISPLAY_NONE;\r
+                               return;\r
+                       };                      \r
+                       \r
                        if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
                                elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
                        };\r
@@ -1145,7 +1194,7 @@ var X_Node__updateRawNode =
                        // style\r
                        // TODO display:none の場合、更新をスキップ\r
                        if( that._flags & X_Node_State.DIRTY_CSS ){\r
-                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\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
@@ -1156,8 +1205,7 @@ var X_Node__updateRawNode =
                                };\r
                        };\r
                        \r
-                       //delete that._flags;\r
-                       that._flags &= X_Node_DIRTY_MASK_RESET;\r
+                       that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                }) :\r
        X_UA_DOM.IE4 ? \r
                ( function( that, elm ){\r
@@ -1166,8 +1214,7 @@ var X_Node__updateRawNode =
                        // fake textNode\r
                        if( !that._tag ){\r
                                elm.innerText = that._text;\r
-                               //delete that._flags;\r
-                               that._flags &= X_Node_DIRTY_MASK_RESET;\r
+                               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                                return;\r
                        };\r
                        \r
@@ -1184,7 +1231,7 @@ var X_Node__updateRawNode =
                        };\r
                        // style\r
                        if( that._flags & X_Node_State.DIRTY_CSS ){\r
-                               if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\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
@@ -1208,9 +1255,8 @@ var X_Node__updateRawNode =
                                };\r
                                delete that._newAttrs;\r
                        };\r
-                       \r
-                       //delete that._flags;\r
-                       that._flags &= X_Node_DIRTY_MASK_RESET;\r
+\r
+                       that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                }) :\r
                (function(){});\r
 \r
@@ -1238,16 +1284,14 @@ var X_Node__actualCreate =
                \r
                if( !that._tag ){\r
                        if( elm ) return elm;\r
-                       //delete that._flags;\r
-                       that._flags &= X_Node_DIRTY_MASK_RESET;\r
+                       that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                        return that._rawObject = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
                };\r
                \r
                if( !elm ){\r
-                       if( that._flags & X_Node_State.DIRTY_CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
-                               delete that._cssText;\r
-                       };\r
-                       that._isNew = true;\r
+                       that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that );\r
+\r
+                       that._flags |= X_Node_State.ELM_NEED_INIT;\r
                        that._rawObject = elm =\r
                                X_Node_strictElmCreation ?\r
                                        document.createElement( [\r
@@ -1255,10 +1299,13 @@ var X_Node__actualCreate =
                                                        ' 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._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( that ) : that._attrText,\r
                                                        that._cssText ? ' style="' + that._cssText + '"' : '',\r
                                                '>' ].join( '' ) ) :\r
                                        document.createElement( that._tag );\r
+                               \r
+                                       \r
+       console.log( '##' + that._attrText + '##' );\r
                };\r
                if( X_Node_useDocumentFragment ){\r
                        if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
@@ -1282,14 +1329,12 @@ var X_Node__actualCreate =
                } else {\r
                        if( that._rawObject && !isChild ) X_Node__actualRemove( that, true );\r
                        \r
-                       if( that._flags & X_Node_State.DIRTY_CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
-                               delete that._cssText;\r
-                       };\r
+                       that._flags & X_Node_State.DIRTY_CSS && X_Node_CSS_objToCssText( that );\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
+                               that._flags & X_Node_State.OLD_ATTRTEXT ? X_Node_Attr_objToAttrText( that ) : that._attrText,\r
                                that._cssText ? ' style="' + that._cssText + '"' : '',\r
                        '>' ];\r
                        \r
@@ -1319,20 +1364,17 @@ var X_Node__actualCreate =
 var X_Node__afterActualCreate =\r
        X_UA_DOM.W3C ? (function( that ){\r
                var elm = that._rawObject, xnodes, l, i;\r
-\r
-               that._root  = that.parent._root;\r
                \r
                if( !that._tag ){\r
-                       // that._flags && X_Node__updateRawNode( that, elm );\r
-                       that._flags & X_Node_DIRTY_MASK && X_Node__updateRawNode( that, elm );\r
+                       that._flags & X_Node_BitMask_IS_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
+               if( that._flags & X_Node_State.ELM_NEED_INIT ){\r
+                       if( !X_Node_useDocumentFragment ){// docFrg が使えない場合、doc 追加後に子を追加\r
                                for( i = 0; i < l; ++i ){\r
                                        elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
                                        X_Node__afterActualCreate( xnodes[ i ] );\r
@@ -1347,8 +1389,7 @@ var X_Node__afterActualCreate =
                                if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
                                        elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
                                };\r
-                               //delete that._flags;\r
-                               that._flags &= X_Node_DIRTY_MASK_RESET;\r
+                               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                        } else {\r
                                elm.UID = that._uid;\r
                                that._newAttrs = that._attrs;\r
@@ -1364,7 +1405,7 @@ var X_Node__afterActualCreate =
                                };\r
                        };\r
                        \r
-                       delete that._isNew;\r
+                       that._flags ^= X_Node_State.ELM_NEED_INIT;\r
                } else {\r
                        \r
                        for( i = 0; i < l; ++i ){\r
@@ -1372,8 +1413,7 @@ var X_Node__afterActualCreate =
                        };\r
                        // 親要素の updateRawNode 前に子要素の updateRawNode を行う\r
                        // 親要素が GPU レイヤーに転送されるケースがあるので、先に子要素の変更を済ませる\r
-                       //that._flags && X_Node__updateRawNode( that, elm );\r
-                       that._flags & X_Node_DIRTY_MASK && X_Node__updateRawNode( that, elm );\r
+                       that._flags & X_Node_BitMask_IS_DIRTY && X_Node__updateRawNode( that, elm );\r
                };      \r
 \r
                // src の onload があるので先ではないか?\r
@@ -1382,7 +1422,7 @@ var X_Node__afterActualCreate =
        }) :\r
        X_UA_DOM.IE4 ? (function( that ){\r
                var xnodes, i;\r
-               that._root = that.parent._root;\r
+               that._flags |= X_Node_State.IE4_TEXTNODE_EXIST;\r
                \r
                if( !that._tag ) return that;\r
                \r
@@ -1394,8 +1434,7 @@ var X_Node__afterActualCreate =
                if( that._flags & X_Node_State.DIRTY_IE_FILTER ){\r
                        X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_objToIEFilterText( that );;\r
                };\r
-               //delete that._flags;\r
-               that._flags &= X_Node_DIRTY_MASK_RESET;\r
+               that._flags &= X_Node_BitMask_RESET_DIRTY;\r
                X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
        }) :\r
        (function(){});\r
@@ -1418,7 +1457,7 @@ var X_Node__actualRemove =
                        if( !elm ) return;\r
                        that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
                        if( !X_UA.MacIE ){\r
-                               // elm.parentNode.tagName for ie7 -> that.state & ELM_IN_TREE\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
index 4dc8d66..7c4bf3e 100644 (file)
@@ -69,7 +69,7 @@ Node.prototype.width = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.width() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -91,7 +91,7 @@ Node.prototype.height = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.height() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -113,7 +113,7 @@ Node.prototype.clientWidth = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.width() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -135,7 +135,7 @@ Node.prototype.clientHeight = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.height() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -157,7 +157,7 @@ Node.prototype.scrollWidth = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.width() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -179,7 +179,7 @@ Node.prototype.scrollHeight = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.height() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -201,7 +201,7 @@ Node.prototype.scrollLeft = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.scrollLeft() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -223,7 +223,7 @@ Node.prototype.scrollTop = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.scrollTop() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -253,7 +253,7 @@ Node.prototype.x = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.x() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -276,7 +276,7 @@ Node.prototype.y = function(){
                return 0;\r
        };\r
        X_Node_updateTimerID && X_Node_startUpdate();\r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.y() : not belong tree.' );\r
                return 0;\r
        };\r
@@ -301,7 +301,7 @@ Node.prototype.offset = function( /* xnodeParent */ ){
                return { x : 0, y : 0 };\r
        };\r
        \r
-       if( !this._root ){\r
+       if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){\r
                console.log( 'xnode.offset() : not belong tree.' );\r
                return { x : 0, y : 0 };\r
        };\r
index cd96a45..2e306bf 100644 (file)
@@ -66,19 +66,32 @@ X_Node_Attr_renameForTag = {};
        // checked -> defaultChecked\r
        // 動的に生成した input 要素を文書ツリーに挿入する前に設定した checked 属性は反映されず、defaultChecked だと反映される\r
        // 先頭にスペース\r
-function X_Node_Attr_objToAttrText( obj ){\r
-               var noValue = X_Node_Attr_noValue,\r
-                       attrs = [ '' ], n = 0, k, v;\r
-               if( !obj ) return ''; // Opera7\r
-               for( k in obj ){\r
-                       //if( X_EMPTY_OBJECT[ k ] ) continue;\r
-                       v = obj[ k ];\r
-                       if( k === 'value' ){\r
-                               v = v.split( '"' ).join( '&quot;' ).split( '>' ).join( '&gt;' ).split( '<' ).join( '&lt;' );\r
-                       };\r
-                       attrs[ ++n ] = noValue[ k ] ? k : [ k, '="', v, '"' ].join( '' );\r
+function X_Node_Attr_objToAttrText( that ){\r
+       var obj     = that._attrs,\r
+               noValue = X_Node_Attr_noValue,\r
+               attrs   = [ '' ],\r
+               plain   = X_EMPTY_OBJECT,\r
+               n = 0, k, v;\r
+\r
+       that._flags &= ~X_Node_State.OLD_ATTRTEXT;\r
+\r
+       if( !obj ){ // Opera7\r
+               delete that._attrText;\r
+               return '';\r
+       };\r
+       for( k in obj ){\r
+               if( plain[ k ] ) continue;\r
+               v = obj[ k ];\r
+               if( k === 'value' ){\r
+                       v = v.split( '"' ).join( '&quot;' ).split( '>' ).join( '&gt;' ).split( '<' ).join( '&lt;' );\r
                };\r
-               return 0 < n ? attrs.join( ' ' ) : '';\r
+               attrs[ ++n ] = noValue[ k ] ? k : [ k, '="', v, '"' ].join( '' );\r
+       };\r
+       if( 0 < n ){\r
+               return that._attrText = attrs.join( ' ' );\r
+       };\r
+       delete that._attrText;\r
+       return '';\r
 };\r
 \r
 (function( renameForDOM, renameForTag ){\r
@@ -112,18 +125,18 @@ Node.prototype.attr = function( nameOrObj /* v */ ){
                        if( X_Node_Attr_setAttr( this, attrs, newAttrs, k, nameOrObj[ k ] ) === true ) f = true;\r
                };\r
                if( f ){\r
-                       this._attrText = false;\r
-                       this._flags |= X_Node_State.DIRTY_ATTR;\r
-                       this._root && X_Node_reserveUpdate();\r
+                       delete this._attrText;\r
+                       this._flags |= X_Node_State.DIRTY_ATTR | X_Node_State.OLD_ATTRTEXT;\r
+                       this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
                };\r
                return this;\r
        } else\r
        if( 1 < arguments.length ){\r
                // setter\r
                if( X_Node_Attr_setAttr( this, attrs || ( this._attrs = {} ), this._newAttrs || ( this._newAttrs = {} ), nameOrObj, arguments[ 1 ] ) === true ){\r
-                       this._attrText = false;\r
-                       this._flags |= X_Node_State.DIRTY_ATTR;\r
-                       this._root && X_Node_reserveUpdate();\r
+                       delete this._attrText;\r
+                       this._flags |= X_Node_State.DIRTY_ATTR | X_Node_State.OLD_ATTRTEXT;\r
+                       this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
                };\r
                return this;\r
        } else\r
@@ -177,7 +190,7 @@ function X_Node_Attr_setAttr( that, attrs, newAttrs, name, v ){
                        if( v !== that._id ){\r
                                that._id = v;\r
                                that._flags |= X_Node_State.DIRTY_ID;\r
-                               that._root && X_Node_reserveUpdate();\r
+                               that._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
                        };\r
                        return; \r
                case 'class' :\r
index a3b6db6..b185bdc 100644 (file)
@@ -250,8 +250,13 @@ function X_Node_CSS_objToCssText( that ){
                css   = [],
                n     = -1,
                p, v, specialFix, filterFix;
-               
-       if( !obj ) return ''; // Opera7.5 未満?
+       
+       that._flags &= ~X_Node_State.OLD_CSSTEXT;
+       
+       if( !obj ){ // Opera7.5 未満?
+               delete that._cssText;
+               return '';
+       };
        
        for( p in obj ){
                // object の拡張に備えて plain なオブジェクトを用意し、そのメンバーと一致するものは処理の対象外。
@@ -263,11 +268,9 @@ function X_Node_CSS_objToCssText( that ){
                
                if( specialFix = X_Node_CSS_SPECIAL_FIX_PROP[ p ] ){
                        css[ ++n ] = p + ':' + specialFix( v );
-                       
                } else
                if( X_Node_CSS_FILTER_FIX_PROPS && X_Node_CSS_FILTER_FIX_PROPS[ p ] ){
                        ( filterFix || ( filterFix = {} ) )[ p ] = v;
-                       
                } else {
                        css[ ++n ] = p + ':' + v;
                };
@@ -275,7 +278,11 @@ function X_Node_CSS_objToCssText( that ){
        
        filterFix && ( css[ ++n ] = 'filter:' + X_Node_CSS_objToIEFilterText( that, filterFix ) );
        
-       return css.join( ';' );
+       if( 0 <= n ){
+               return that._cssText = css.join( ';' );
+       };
+       delete that._cssText;
+       return '';
 };
 
 var
@@ -393,7 +400,7 @@ function X_Node_CSS_objToIEFilterText( that, opt_css ){
 };
 
 function X_Node_CSS_onAfterUpdateForIEFilterFix(){
-       if( this._root ){ // 要素があり、要素がツリーに属している
+       if( this._flags & X_Node_State.IN_TREE ){ // 要素があり、要素がツリーに属している
                this._flags |= X_Node_State.DIRTY_IE_FILTER;
                X_Node_reserveUpdate();
        };
@@ -483,31 +490,24 @@ function X_Node_CSS__splitValueAndUnit( v ){
 // name, value setter
 
 Node.prototype.css = function( nameOrObj /* orUnitID, valuOrUnitOrName */ ){
-       var plain = X_EMPTY_OBJECT,
-               args  = arguments,
-               css   = this._css,
-               p, name, v, camelize, unit, ieFix;
+       var args = arguments,
+               css  = this._css,
+               p, name, v, plain, camelize;
        if( !this._tag ) return this;
 // setter:object
        if( X.Type.isObject( nameOrObj ) ){
                if( !css ) css = this._css = {};
+               plain    = X_EMPTY_OBJECT;
                camelize = X_Node_CSS_camelize;
-               ieFix    = X_Node_CSS_FILTER_FIX_PROPS;
                for( p in nameOrObj ){
                        if( plain[ p ] ) continue;
-                       
-                       if( ieFix && ieFix[ p ] ){
-                               this._flags |= X_Node_State.DIRTY_IE_FILTER;
-                       };
-                       v = nameOrObj[ p ];
-                       v || v === 0 ? css[ camelize( p ) ] = v : delete css[ camelize( p ) ];
-                       if( p === 'display' ){
-                               v === 'none' ? ( this._flags |= X_Node_State.IE5_DISPLAY_NONE_FIX ) : ( this._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX );
-                               v === 'none' ? ( this._flags |= X_Node_State.STYLE_IS_DISPLAY_NONE ) : ( this._flags &= ~X_Node_State.STYLE_IS_DISPLAY_NONE );
-                       };
+                       name = camelize( p );
+                       v    = nameOrObj[ p ];
+                       if( css[ name ] === v ) continue;
+                       this._flags = X_Node_CSS_setStyle( css, this._flags, name, v );
                };
-               this._flags |= X_Node_State.DIRTY_CSS;
-               this.parent && X_Node_reserveUpdate();
+               this._flags |= X_Node_State.DIRTY_CSS | X_Node_State.OLD_CSSTEXT;
+               this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();
                delete this._cssText;
                return this;
        } else
@@ -517,44 +517,100 @@ Node.prototype.css = function( nameOrObj /* orUnitID, valuOrUnitOrName */ ){
                name = X_Node_CSS_camelize( nameOrObj );
                v    = args[ 1 ];
                if( css[ name ] === v ) return this;
-               if( X_Node_CSS_FILTER_FIX_PROPS && X_Node_CSS_FILTER_FIX_PROPS[ name ] ){
-                       this._flags |= X_Node_State.DIRTY_IE_FILTER;
-               };
-               if( !v && v !== 0 ){
-                       delete css[ name ];
-               } else {
-                       css[ name ] = v;
-               };
+               this._flags = X_Node_CSS_setStyle( css, this._flags, name, v ) | X_Node_State.DIRTY_CSS | X_Node_State.OLD_CSSTEXT;
+               this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();
                delete this._cssText;
-               this._flags |= X_Node_State.DIRTY_CSS;
-               if( name === 'display' ){
-                       v === 'none' ? ( this._flags |= X_Node_State.IE5_DISPLAY_NONE_FIX ) : ( this._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX );
-                       v === 'none' ? ( this._flags |= X_Node_State.STYLE_IS_DISPLAY_NONE ) : ( this._flags &= ~X_Node_State.STYLE_IS_DISPLAY_NONE );
-               };
-               // TODO this._flags & in tree
-               this.parent && X_Node_reserveUpdate();
                return this;
        };
 // getter
        if( !css ) return;
        // 集計 border, padding, margin, backgroundPosition, clip
-       // border で正確なデータを返せない時は、null を返す
+       // TODO border で正確なデータを返せない時は、null を返す
        return css[ X_Node_CSS_camelize( nameOrObj ) ];
 };
 
+function X_Node_CSS_setStyle( css, flags, name, newValue ){
+
+       if( X_Node_CSS_FILTER_FIX_PROPS && X_Node_CSS_FILTER_FIX_PROPS[ name ] ){
+               flags |= X_Node_State.DIRTY_IE_FILTER;
+       };
+       if( !newValue && newValue !== 0 ){
+               delete css[ name ];
+       } else {
+               css[ name ] = newValue;
+       };
+       
+       switch( name ){
+               case 'display' :
+                       newValue === 'none' ? ( flags |= X_Node_State.STYLE_IS_DISPLAY_NONE ) : ( flags &= ~X_Node_State.STYLE_IS_DISPLAY_NONE );
+                       return flags;
+                       
+               case 'visibility' :
+                       // すでに opacity:0 で invisible
+                       if( flags & X_Node_State.STYLE_IS_INVISIBLE && css[ 'opacity' ] == 0 ) return flags;
+                       newValue === 'hidden' ? ( flags |= X_Node_State.STYLE_IS_INVISIBLE ) : ( flags &= ~X_Node_State.STYLE_IS_INVISIBLE );
+                       return flags;
+                       
+               case 'opacity' :
+                       // すでに visibility:hidden で invisible
+                       if( flags & X_Node_State.STYLE_IS_INVISIBLE && css[ 'visibility' ] === 'hidden' ) return flags;
+                       newValue == 0 ? ( flags |= X_Node_State.STYLE_IS_INVISIBLE ) : ( flags &= ~X_Node_State.STYLE_IS_INVISIBLE );
+                       return flags;
+                       
+               case 'overflow' :
+                       newValue === 'hidden' ? ( flags |= X_Node_State.STYLE_IS_NO_OVERFLOW ) : ( flags &= ~X_Node_State.STYLE_IS_NO_OVERFLOW );
+                       return flags;
+                       
+               case 'position' :
+                       newValue === 'absolute' ? ( flags |= X_Node_State.STYLE_IS_POS_ABSOLUTE ) : ( flags &= ~X_Node_State.STYLE_IS_POS_ABSOLUTE );
+                       return flags;
+                       
+               case 'width'    :
+                       newValue = X_Node_CSS__splitValueAndUnit( newValue );
+                       if( newValue[ 1 ] !== '%' ){
+                               flags |= X_Node_State.STYLE_IS_WIDTH_LENGTH;
+                               flags &= ~X_Node_State.STYLE_IS_WIDTH_PCT;
+                       } else {
+                               flags &= ~X_Node_State.STYLE_IS_WIDTH_LENGTH;
+                               flags |= X_Node_State.STYLE_IS_WIDTH_PCT;
+                       };
+                       return flags;
+                       
+               case 'height'   :
+                       newValue = X_Node_CSS__splitValueAndUnit( newValue );
+                       if( newValue[ 1 ] !== '%' ){
+                               flags |= X_Node_State.STYLE_IS_HEIGHT_LENGTH;
+                               flags &= ~X_Node_State.STYLE_IS_HEIGHT_PCT;
+                       } else {
+                               flags &= ~X_Node_State.STYLE_IS_HEIGHT_LENGTH;
+                               flags |= X_Node_State.STYLE_IS_HEIGHT_PCT;
+                       };
+                       return flags;
+                       
+               case 'fontSize' :
+                       
+       };
+       return flags;
+};
+
 Node.prototype.cssText = function( v ){
        var obj, i, l, attr, name;
+       
+       if( v === this._cssText && ( this._flags & X_Node_State.OLD_CSSTEXT ) === 0 ){
+               return this;
+       };      
+       
        if( v === '' ){
                delete this._css;
-               this._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX;
-               this._flags |= X_Node_State.DIRTY_CSS;
-               this.parent && X_Node_reserveUpdate();
                delete this._cssText;
+               this._flags |= X_Node_State.DIRTY_CSS;
+               this._flags &= ~X_Node_State.OLD_CSSTEXT; // ~X_Node_State.DIRTY_IE_FILTER
+               this._flags &= X_Node_BITMASK_RESET_STYLE;
+               this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();
                return this;
        } else
        if( X.Type.isString( v ) ){
                delete this._css;
-               this._flags &= ~X_Node_State.IE5_DISPLAY_NONE_FIX;
                obj = {};
                v   = v.split( ';' ); // TODO content ";" などにも対応
                for( i = 0, l = v.length; i < l; ++i ){
@@ -564,9 +620,7 @@ Node.prototype.cssText = function( v ){
                return this.css( obj );
        };
        // getter
-       if( this._flags & X_Node_State.DIRTY_CSS && !( this._cssText = X_Node_CSS_objToCssText( this ) ) ){
-               delete this._cssText;
-       };
+       this._flags & X_Node_State.OLD_CSSTEXT && X_Node_CSS_objToCssText( this );
        return this._cssText;
 };
 
@@ -651,8 +705,13 @@ X_Node_CSS_getCharSize =
                                        if( _v = X_Node_CSS__UNIT_RATIO[ u ] ) return that._fontSize = v / _v;
                                };
                        } else {
-                               v = 1;
-                               u = 'em';
+                               // 要素を生成して測定!
+                               ( that._rawObject || X_Node__ie4getRawNode( that ) ).insertAdjacentHTML( 'BeforeEnd', '<div id="ie4charsize" style="position:absolute;top:0;left:0;">X</div>' );
+                               elm = document.all[ 'ie4charsize' ];
+                               v = elm.offsetHeight;
+                               elm.removeAttribute( 'id' ); // ?
+                               elm.outerHTML = '';
+                               return that._fontSize = v;
                        };
 
                        switch( u ){
index 533f6d9..3ba6c19 100644 (file)
@@ -367,8 +367,8 @@ X_TEMP.bindElementToXnode =
                                                        if( tag.charAt( 0 ) === '/' ) tag = tag.slice( 1 );\r
                                                        xnode._tag = tag;\r
                                                //};\r
-                                               xnode._root   = parent._root;\r
-                                               xnode._flags &= X_Node_DIRTY_MASK_RESET;\r
+                                               xnode._flags |= X_Node_State.IN_TREE;\r
+                                               xnode._flags &= X_Node_BitMask_RESET_DIRTY;\r
                                                elm.UID       = xnode._uid;\r
                                                current.xtext = null;\r
                                                \r
@@ -376,10 +376,6 @@ X_TEMP.bindElementToXnode =
                                                        xnode.attr( 'value', xnode.html() ).empty();\r
                                                        \r
                                                } else\r
-                                               //if( X_TEMP._isCleanupTarget( elm ) ){// !xnode.hasClass( 'skip-cleanup' ) && ( X_Dom_DTD_CLEANUP_TAGS[ tag ] || xnode.hasClass( 'cleanup-target' ) ) ){ // ie で body 内の script が2度よばれるのに対処\r
-                                                       //alert( '[' +parent._tag + '>' + xnode._tag + '] remove ... ' );\r
-                                                       //xnode.destroy();\r
-                                               //} else\r
                                                if( elm.childNodes && elm.childNodes.length ){\r
                                                        //alert( '[' +parent._tag + '>' + xnode._tag + ' ' + (xnode._xnodes ? xnode._xnodes.length : '' ) + '] === ' + tag + ' ' + (elm.childNodes ? elm.childNodes.length : '' ) + ' Hit\n' + elm.outerHTML );\r
                                                        //current.xtext = null;\r
@@ -419,9 +415,10 @@ X_TEMP.bindElementToXnode =
                                \r
                                ++current.j;\r
                                xnode._rawObject = elm;\r
-                               xnode._flags    &= X_Node_DIRTY_MASK_RESET;\r
+                               xnode._flags    |= X_Node_State.IN_TREE;\r
+                               xnode._flags    &= X_Node_BitMask_RESET_DIRTY;\r
                                xnode._text      = elm.data; // 正確\r
-                               xnode._root      = parent._root;\r
+                               \r
                                if( !skipCleanup ){\r
                                        if( !( text = xnode._text ) || ( text = X_String_cleanupWhiteSpace( text ) ) === ' ' ){\r
                                                console.log( '[' +parent._tag + '>' + xnode._uid + '] destroy ... ' );\r
@@ -500,8 +497,8 @@ X_TEMP.bindElementToXnode =
                                        ++current.j;\r
                                        \r
                                        xnode._rawObject = elm;\r
-                                       xnode._flags    &= X_Node_DIRTY_MASK_RESET;\r
-                                       xnode._root      = parent._root;\r
+                                       xnode._flags    |= X_Node_State.IN_TREE;\r
+                                       xnode._flags    &= X_Node_BitMask_RESET_DIRTY;\r
                                        //xnode._tag     = X_Dom_DTD_TAG_FIX[ tag ] || tag;\r
                                        if( X_TEMP._isCleanupTarget( elm ) ){ //!xnode.hasClass( 'skip-cleanup' ) && ( X_Dom_DTD_CLEANUP_TAGS[ tag ] || xnode.hasClass( 'cleanup-target' ) ) ){\r
                                                xnode.destroy();\r