OSDN Git Service

Version 0.6.125, bugfix X.Node.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 06_XNodeCSS.js
index a3b6db6..3f9f250 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;+65
+               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,25 @@ 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, flags;
        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;
+               flags    = this._flags;
                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;
+                       flags = X_Node_CSS_setStyle( css, flags, name, v );
                };
-               this._flags |= X_Node_State.DIRTY_CSS;
-               this.parent && X_Node_reserveUpdate();
+               this._flags = 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 +518,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 +621,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 +706,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;visivility:hidden;line-height:1;height:1em;">X</div>' );
+                               elm = document.all[ 'ie4charsize' ];
+                               v = elm.offsetHeight;
+                               elm.removeAttribute( 'id' ); // ?
+                               elm.outerHTML = '';
+                               return that._fontSize = v;
                        };
 
                        switch( u ){