X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F06_XNodeCSS.js;h=77bb0675073318ccbf3cd0b574a2c41f46ba89d6;hb=HEAD;hp=1f1fe700560ca5a1f82f197a2ea5d826f74a502f;hpb=35daae003b3b017a92d0c883f120bf3baf604fba;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/02_dom/06_XNodeCSS.js b/0.6.x/js/02_dom/06_XNodeCSS.js index 1f1fe70..77bb067 100644 --- a/0.6.x/js/02_dom/06_XNodeCSS.js +++ b/0.6.x/js/02_dom/06_XNodeCSS.js @@ -246,7 +246,7 @@ function X_Node_CSS_parseColor( x ){ function X_Node_CSS_objToCssText( that, skipFilter ){ var obj = that[ '_css' ], - plain = X_EMPTY_OBJECT, + //plain = X_EMPTY_OBJECT, css = [], n = -1, p, v, specialFix, filterFix; @@ -260,7 +260,7 @@ function X_Node_CSS_objToCssText( that, skipFilter ){ for( p in obj ){ // object の拡張に備えて plain なオブジェクトを用意し、そのメンバーと一致するものは処理の対象外。 - if( plain[ p ] ) continue; + //if( plain[ p ] ) continue; v = obj[ p ]; @@ -277,8 +277,11 @@ function X_Node_CSS_objToCssText( that, skipFilter ){ }; if( filterFix ){ - v = X_Node_CSS_objToIEFilterText( that, filterFix ); - if( v ) css[ ++n ] = 'filter:' + v; + v = X_Node_CSS_objToIEFilterText( that, filterFix, css ); + n = css.length; /* css が変更されている場合あり */ + if( v ){ + css[ ++n ] = 'filter:' + v; + }; skipFilter = skipFilter && v; } else { skipFilter = false; @@ -287,6 +290,7 @@ function X_Node_CSS_objToCssText( that, skipFilter ){ if( 0 <= n ){ // cssText には完全なものを控えるが、戻すのは filter を抜いたもの that[ '_cssText' ] = css.join( ';' ); + //console.log( that[ '_cssText' ] ); if( skipFilter ){ --css.length; return css.join( ';' ); @@ -301,10 +305,11 @@ var X_Node_CSS_FILTER_FIX_PROPS = X_UA[ 'ActiveX' ] && X_UA[ 'IE' ] < 9 ? { - 'opacity' : 2, - 'boxShadow' : 3, - 'textShadow' : 4, - 'transform' : 5 + 'opacity' : 2, + 'boxShadow' : 3, + 'textShadow' : 4, + 'transform' : 5, + 'dxtransform' : 7 // X.NodeAnime で使用 } : X_UA[ 'ActiveX' ] && X_UA[ 'IE9' ] ? // == 9 { @@ -312,15 +317,16 @@ X_Node_CSS_FILTER_FIX_PROPS = } : null; -function X_Node_CSS_objToIEFilterText( that, opt_css ){ +function X_Node_CSS_objToIEFilterText( that, opt_css, opt_cssList ){ var obj = opt_css || that[ '_css' ], test = X_Node_CSS_FILTER_FIX_PROPS, filters = [], n = -1, - p, id, v, num, ary, params, i, l, dir, - afterUpdate, impossible; + p, id, v, num, vu, u, _v, ary, params, i, l, dir, + afterUpdate, impossible, color; + for( p in obj ){ - if( X_EMPTY_OBJECT[ p ] ) continue; + //if( X_EMPTY_OBJECT[ p ] ) continue; if( !( id = test[ p ] ) ) continue; v = obj[ p ]; @@ -330,7 +336,11 @@ function X_Node_CSS_objToIEFilterText( that, opt_css ){ filters[ ++n ] = v; break; case 2 : //'opacity' : - filters[ ++n ] = 'alpha(opacity=' + ( v * 100 | 0 ) +')'; + if( v === 0 ){ + console.log( '@opacity:0 ' + !!opt_cssList ); + opt_cssList && ( opt_cssList[ opt_cssList.length ] = 'visibility:hidden' ); + } else + if( v < 1 ) filters[ ++n ] = 'alpha(opacity=' + ( v * 100 | 0 ) +')'; break; case 3 : //'boxShadow' : // TODO カンマ区切りの複数指定 @@ -396,25 +406,131 @@ function X_Node_CSS_objToIEFilterText( that, opt_css ){ X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, that, X_Node_CSS_onAfterUpdateForIEFilterFix ); break; }; - dir = Math.atan2( params[ 1 ] + params[ 3 ], params[ 0 ] + params[ 3 ] ) * 180 / Math.PI + 90; - dir += dir < 0 ? 360 : 0; + dir = X_Node_CSS_ieMathRangeFix( Math.atan2( params[ 1 ] + params[ 3 ], params[ 0 ] + params[ 3 ] ) * 180 / Math.PI + 90 ); filters[ ++n ] = 'shadow(color=' + color + ',strength=' + params[ 3 ] + ',direction=' + ( dir | 0 ) + ')'; break; case 4 : //'textShadow' : //text-shadow: 5px 5px 2px blue; 水平方向の距離 垂直方向の距離 影のぼかし半径 影の色 none //glow(Color=yellow,Strength=10); - //どうやらCSSのbackgroundプロパティと同時に使えないようです。 s + //どうやらCSSのbackgroundプロパティと同時に使えないようです。 break; case 6 : //'backgroundImage' : // - + break; + case 5 : // transform scale, matrix - + break; + case 7 : // dxtransform + that[ '_flags' ] |= X_NodeFlags_IE_FILTER_FIX_AFTER; + break; }; }; - return filters.join( ' ' ); + return filters.join( ' ' );//n !== -1 ? filters.join( ' ' ) : ''; }; + + //0 ~ 360の範囲に収める. + function X_Node_CSS_ieMathRangeFix( a ){ + a %= 360; + return a < 0 ? 360 + a : a; + }; + +/* + * http://p2b.jp/200912-CSS3-Transform-for-IE8 + * http://rtilabs.rti-giken.jp/files/2011_09_16/rotate.html + */ + function X_Node_CSS_IETransform( elm, params ){ + var PI_180 = Math.PI / 180, + + rotate = X_Node_CSS_ieMathRangeFix( params[ 2 ] ),//回転 + radian = rotate * PI_180, + cosX = Math.cos( radian ), + sinY = Math.sin( radian ), + + skewX = X_Node_CSS_ieMathRangeFix( params[ 3 ] ), //skew + skewY = X_Node_CSS_ieMathRangeFix( params[ 4 ] ), + + _skX = Math.tan( skewX * PI_180 ), + _skY = Math.tan( skewY * PI_180 ), + + scaleX = params[ 5 ], //拡大 + scaleY = params[ 6 ], + + m11 = cosX * scaleX, + m12 = ( -sinY + _skX ) * scaleX, + m21 = ( sinY + _skY ) * scaleY, + m22 = cosX * scaleY, + + //absolute時には軸を補正してあげないとだめだ。 + //ブラウザとして軸がずれている。 + //計算式元ネタ http://p2b.jp/200912-CSS3-Transform-for-IE8 + + //offset*系のサイズは回転によって生じたゆがみも考慮されるらしい。 + + //拡大縮小も同じ. + //this.get(0).style.width や height には拡縮の影響を受けない元の数字が入っている + ow = elm.offsetWidth, + oh = elm.offsetHeight, + + absCosX = Math.abs( cosX ), + absSinY = Math.abs( sinY ), + + //回転の補正 + dx = ( ow - ( ow * absCosX + oh * absSinY ) ) / 2 + //skewの補正(rotate しながらskew すると補正がおかしくなります。 これがわからない) + - ow / 2 * _skX + //拡大の補正 + - ( ( ow * scaleX - ow ) / 2 | 0 ) + // x + + params[ 0 ], + dy = ( oh - ( ow * absSinY + oh * absCosX ) ) / 2 + //skewの補正( + - oh / 2 * _skY + //拡大の補正 + - ( ( oh * scaleY - oh ) / 2 | 0 ) + // y + + params[ 1 ]; + + //console.log( ow + ' ' + oh ) + elm.style[ params[ 7 ] ] = dx + 'px'; // left or right + elm.style[ params[ 8 ] ] = dy + 'px'; // top or bottom + + //フィルターで回転と拡大縮小を加えます。 + return 'progid:DXImageTransform.Microsoft.Matrix(' + + // 'Dx=' + dx + + //',Dy=' + dy + + 'M11=' + m11 + + ',M12=' + m12 + + ',M21=' + m21 + + ',M22=' + m22 + + ',FilterType="bilinear",sizingMethod="auto expand")'; + }; + +function X_Node_CSS_onAfterUpdateIEFilterFix( that ){ + var PI_180 = Math.PI / 180, + test = X_Node_CSS_FILTER_FIX_PROPS, + css = that[ '_css' ], + elm = that[ '_rawObject' ], + filter = elm.style.filter || '', + origin = filter, + p, v, plus, id; + + for( p in css ){ + if( !( id = test[ p ] ) ) continue; + plus = 0; + switch( id ){ + case 7 : // dxtransform + plus = X_Node_CSS_IETransform( elm, css[ p ] ); + break; + default : + continue; + }; + if( plus ) filter += ( filter ? ' ' : '' ) + plus; + }; + if( filter !== origin ) elm.style.filter = filter; +}; + + function X_Node_CSS_onAfterUpdateForIEFilterFix(){ if( this[ '_flags' ] & X_NodeFlags_IN_TREE ){ // 要素があり、要素がツリーに属している this[ '_flags' ] |= X_NodeFlags_DIRTY_IE_FILTER; @@ -526,11 +642,11 @@ function X_Node_css( nameOrObj /* value */ ){ // setter:object if( X_Type_isObject( nameOrObj ) ){ if( !css ) css = this[ '_css' ] = {}; - plain = X_EMPTY_OBJECT; + //plain = X_EMPTY_OBJECT; camelize = X_Node_CSS_camelize; flags = this[ '_flags' ]; for( p in nameOrObj ){ - if( plain[ p ] ) continue; + //if( plain[ p ] ) continue; name = camelize( p ); v = nameOrObj[ p ]; if( css[ name ] === v ) continue; @@ -584,6 +700,7 @@ function X_Node_CSS_setStyle( css, flags, name, newValue ){ return flags; case 'opacity' : + flags |= X_NodeFlags_IE8_OPACITY_FIX; // すでに visibility:hidden で invisible if( flags & X_NodeFlags_STYLE_IS_INVISIBLE && css[ 'visibility' ] === 'hidden' ) return flags; newValue == 0 ? // 0 or "0" @@ -667,7 +784,7 @@ function X_Node_cssText( v ){ }; /* - * ここでは HTMLElement のチ1ェックは行わない! + * ここでは HTMLElement のチ1ェックは行わない! <- 行う! * TODO * body に css attr がセットされた場合には X_ViewPort_baseFontSize をクリア * class, id, attr() の変更があった場合は、変更の適用の後、charSize を取得 @@ -681,12 +798,13 @@ X_Node_CSS_getCharSize = X_Node_updateTimerID && X_Node_startUpdate(); if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize; if( that[ '_fontSize' ] ) return that[ '_fontSize' ]; - return that[ '_fontSize' ] = parseFloat( X_Node_CSS_getComputedStyle( that[ '_rawObject' ], null ).fontSize ); + return that[ '_fontSize' ] = that[ '_rawObject' ] ? parseFloat( X_Node_CSS_getComputedStyle( that[ '_rawObject' ], null ).fontSize ) : 0; }) : 5 <= X_UA[ 'IE' ] ? (function( that ){ var font, vu, v, u, _v; + X_Node_updateTimerID && X_Node_startUpdate(); if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize; if( that[ '_fontSize' ] ) return that[ '_fontSize' ]; @@ -731,11 +849,12 @@ X_Node_CSS_getCharSize = }) : X_UA_DOM.IE4 ? (function( that ){ - var font, vu, v, u, _v; + var font, vu, v, u, _v, elm; + X_Node_updateTimerID && X_Node_startUpdate(); if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize; if( that[ '_fontSize' ] ) return that[ '_fontSize' ]; - + if( that[ '_css' ] && ( font = that[ '_css' ].fontSize ) ){ vu = X_Node_CSS__splitValueAndUnit( font ); v = vu[ 0 ]; @@ -747,7 +866,7 @@ X_Node_CSS_getCharSize = if( _v = X_Node_CSS__UNIT_RATIO[ u ] ) return that[ '_fontSize' ] = v / _v; }; } else { - // 要素を生成して測定! + // TODO 要素を生成して測定! ではなくて elm.style.fontSize が使えそう ( that[ '_rawObject' ] || X_Node__ie4getRawNode( that ) ).insertAdjacentHTML( 'BeforeEnd', '
X
' ); elm = document.all[ 'ie4charsize' ]; v = elm.offsetHeight; @@ -789,11 +908,14 @@ var X_Node_CSS_Support = {}, * @namespace X.CSS */ X[ 'CSS' ] = { - + /** + * @alias X.CSS.VENDER_PREFIX + */ 'VENDER_PREFIX' : X_Node_CSS_VENDER_PREFIX, - // iscroll で使用 - 'uncamelize' : X_Node_CSS_uncamelize, - + + /** + * @alias X.CSS.Support + */ 'Support' : X_Node_CSS_Support }; @@ -825,7 +947,7 @@ X[ 'CSS' ] = { for( j = vendors.length; j; ){ v = vendors[ --j ]; if( testStyle[ v + prop ] !== undefined ){ - if( v === 'ms' ) v = 'Ms';// for ie9 + if( v === 'ms'/* && !( 10 <= X_UA[ 'IEHost' ] )*/ ) v = 'Ms';// for ie9, 但し ie11 のieには不要 if( v === 'o' ) v = 'O';//for opera12 X_Node_CSS_VENDER_PREFIX[ search ] = v + prop; break; @@ -837,41 +959,62 @@ X[ 'CSS' ] = { }; testStyle.cssText = 'background:rgba(0,0,0,0.5);border-color:transparent'; +/** + * 色指定に rgba() が使用できるか? + * @alias X.CSS.Support.rgba + * @type {boolean} + */ X_Node_CSS_Support[ 'rgba' ] = !!testStyle[ 'background' ]; + +/** + * 色指定に transparent が使用できるか? + * @alias X.CSS.Support.transparent + * @type {boolean} + */ X_Node_CSS_Support[ 'transparent' ] = !!testStyle[ 'borderColor' ]; // TODO border による三角形の可否 // 2:完全、 1:透過に非対応(IE7-) 0:borderの描画が非標準で三角形が作れない - - /* - * chrome 1+, ff3.5(1.9.1), ie9+, opera10.5+, Safari3+(522) - */ + if( prop = X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ){ testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0'; + + /** + * boxShadow が使用できるか? + * chrome 1+, ff3.5(1.9.1), ie9+, opera10.5+, Safari3+(522) + * @alias X.CSS.Support.boxShadow + * @type {boolean} + */ X_Node_CSS_Support[ 'boxShadow' ] = !!testStyle[ prop ]; - /* + testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0, 0 0'; + + /** + * boxShadow の複数指定が使用できるか?
* chrome 4+, ff3.5(1.9.1), ie9+, opera10.5+, Safari5+(533) + * @alias X.CSS.Support.boxShadowMulti + * @type {boolean} */ - testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0, 0 0'; X_Node_CSS_Support[ 'boxShadowMulti' ] = !!testStyle[ prop ]; - /* - * https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow - * この値を用いる場合には、spread-radius を省略出来ません。box-shadow が効かないケースに遭遇した時はこの事を思い出して下さい。 - * chrome 4+, ff3.5(1.9.1), ie9+, opera10.5+, Safari5+(533) + testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0 inset'; + + /** + * https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow
+ * この値を用いる場合には、spread-radius を省略出来ません。box-shadow が効かないケースに遭遇した時はこの事を思い出して下さい。
+ * chrome 4+, ff3.5(1.9.1), ie9+, opera10.5+, Safari5+(533)
* - * http://unformedbuilding.com/articles/considerations-when-using-the-box-shadow/ - * box-shadow:inset と border-radius を指定しているときの Google Chrome の表示 - * このバグは Windows と Linux で発生するようです。 - * Windows 版 Chrome 10.0.648.127 で修正されているのを確認しました。 + * http://unformedbuilding.com/articles/considerations-when-using-the-box-shadow/
+ * box-shadow:inset と border-radius を指定しているときの Google Chrome の表示
+ * このバグは Windows と Linux で発生するようです。
+ * Windows 版 Chrome 10.0.648.127 で修正されているのを確認しました。
+ * @alias X.CSS.Support.boxShadowInset + * @type {boolean} */ - testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0 inset'; X_Node_CSS_Support[ 'boxShadowInset' ] = testStyle[ prop ] && testStyle[ prop ].indexOf( 'inset' ) !== -1; }; - testStyle.cssText = temp; })();