4 * style 値の変更は、enterFrame 後にまとめて適用
5 * width(), height(), x(), y() 1em の取得時にも適用
6 * css3 の ie用 fix は X.UI レベルで行う
30 AUTO : Number.POSITIVE_INFINITY,
31 FULL : X.Dom // something unigue value; 100%
52 /* font-size -> fontSize */
53 _DICTIONARY_CAMELIZE : {},
55 camelize : function( cssProp ){
57 parts, l, i, camelized;
59 if( camelized = me._DICTIONARY_CAMELIZE[ cssProp ] ) return camelized;
60 parts = cssProp.split( ' ' ).join( '' ).split( '-' );
62 if( l === 1 ) return parts[ 0 ];
64 camelized = cssProp.charAt(0) === '-'
65 ? parts[ 0 ].charAt( 0 ).toUpperCase() + parts[ 0 ].substring( 1 )
68 for( i = 1; i < l; ++i ){
69 camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 );
71 return me._DICTIONARY_CAMELIZE[ cssProp ] = camelized;
74 /* fontSize -> font-size */
77 uncamelize: function( str ){
78 return str.split( ' ' ).join( '' ).replace( X.Dom.Style.REG_LARGE, '-$&' ).toLowerCase();
81 CHAR_CODE_A : 'A'.charCodeAt( 0 ),
83 _DICTIONARY_UNCAMELIZE : {},
85 uncamelize : function( str ){
89 uncamelized, l, chr, code;
90 str = str.split( ' ' ).join( '' );
91 if( uncamelized = me._DICTIONARY_UNCAMELIZE[ str ] ) return uncamelized;
93 for( i = 0, l = str.length; i < l; ++i ){
94 chr = str.charAt( i );
95 code = chr.charCodeAt( 0 );
96 uncamelized += ( A <= code && code <= Z ) ? '-' + chr : chr;
98 return me._DICTIONARY_UNCAMELIZE[ str ] = uncamelized.toLowerCase();
101 objToCssText : function( obj ){
104 uncamelize = me.uncamelize,
105 VENDER_PREFIX = me.VENDER_PREFIX,
106 FIX_PROP = me.SPECIAL_FIX_PROP,
107 SPECIAL_FIX = me.SPECIAL_FIX,
110 name = uncamelize( p );
111 if( FIX_PROP[ name ] ){
114 css[ css.length ] = [ VENDER_PREFIX[ name ] || name, obj[ p ] ].join( ':' );
117 sp && ( css[ css.length ] = SPECIAL_FIX( obj ) );
118 return css.join( ';' );
122 _FONT_SIZE_RATIO : null,
124 // https://developer.mozilla.org/en-US/docs/Web/CSS/transform
125 // Firefox 3.5, ie9, Opera 10.5, Safari 3.1, Chrome
126 // 3D support Firefox 10, ie10, Safari 4.0, Chrome 12.0
127 // transform : void 0,
129 // https://developer.mozilla.org/ja/docs/Web/Guide/CSS/Using_CSS_transitions
130 // Chrome 1.0, Firefox 4.0, ie10, Opera 10.5, Safari 3.2
131 // Android 2.1, Firefox Android 4.0, Opera Mobile 10, Safari Mobile 3.2
132 // transition : void 0
134 // ブラウザ毎の getComputedStyle の戻り値 http://d.hatena.ne.jp/uupaa/20080928/1222543331
156 SLATEGRAY : 0x708090,
158 GAINSBORO : 0xDCDCDC,
159 MIDNIGHTBLUE : 0x191970,
160 SLATEBLUE : 0x6A5ACD,
161 MEDIUMBLUE : 0x0000CD,
162 ROYALBLUE : 0x4169E1,
163 DODGERBLUE : 0x1E90FF,
165 STEELBLUE : 0x4682B4,
166 LIGHTBLUE : 0xADD8E6,
167 PALETURQUOISE : 0xAFEEEE,
168 TURQUOISE : 0x40E0D0,
169 LIGHTCYAN : 0xE0FFFF,
170 AQUAMARINE : 0x7FFFD4,
171 DARKGREEN : 0x006400,
173 LIGHTGREEN : 0x90EE90,
174 CHARTREUSE : 0x7FFF00,
175 GREENYELLOW : 0xADFF2F,
176 LIMEGREEN : 0x32CD32,
177 YELLOWGREEN : 0x9ACD32,
178 OLIVEDRAB : 0x6B8E23,
179 DARKKHAKI : 0xBCB76B,
180 PALEGOLDENROD : 0xEEE8AA,
181 LIGHTYELLOW : 0xFFFFE0,
183 GOLDENROD : 0xDAA520,
184 DARKGOLDENROD : 0xB8860B,
185 ROSYBROWN : 0xBC8F8F,
186 INDIANRED : 0xCD5C5C,
187 SADDLEBROWN : 0x8B4513,
190 BURLYWOOD : 0xDEB887,
193 SANDYBROWN : 0xF4A460,
195 CHOCOLATE : 0xD2691E,
196 FIREBRICK : 0xB22222,
205 PALEVIOLETRED : 0xDB7093,
209 DARKVIOLET : 0x9400D3,
210 BLUEVIOLET : 0x8A2BE2,
211 MEDIUMPURPLE : 0x9370DB,
214 MISTYROSE : 0xFFE4E1,
216 LEMONCHIFFON : 0xFFFACD
219 PARAMS : ( function(){
221 register( ret.percent = {},
222 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent'
224 register( ret.offset = {},
225 'height,width,bottom,left,right,top'
227 register( ret.size = {},
228 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing,wordSpacing'
230 register( ret.color = {},
231 'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color'
233 register( ret.region = {},
234 'margin,padding,borderWidth,borderColor'
236 register( ret.special = {},
237 'clip,backgroundPosition,backgroundPositionX,backgroundPositionY,opacity,lineHeight,zIndex'
239 register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' );
241 register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' );
242 register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' );
243 register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' );
244 register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' );
246 function register( obj, params ){
247 params = params.split( ',' );
248 for( var i = params.length; i; ) obj[ params[ --i ] ] = true;
253 _CLIP_SEPARATOR : X.UA.IE && X.UA.IE < 8 ? ' ' : ',',
258 Property : X.Class.create(
262 Constructor : function( name, value, unit, xnode ){
272 equal : function( prop ){
273 if( this.unit === prop.unit ){
274 return this.value === prop.value;
276 return Math.abs( this.toPx() - prop.toPx() ) < 1;
278 convert: function( prop ){
279 var u = prop.unit, v;
280 if( this.unit === u ) return;
281 this.value = v = this.toPx();
284 // bgpX, bgpY の場合 X.Dom.Image.getActualDimension( backgroundImage url を使用 )
288 v / this.xnode._getCharSize() :
289 v / ( X.Dom.Style._UNIT_RATIO[ u ] || 1 );
292 setValue: function( v ){
295 getValue: function(){
298 getOffset: function( prop ){
299 return prop.value - this.value;
304 getValueText: function(){
305 return this.value === 0 ? '0' : this.value + this.unit;
308 var v = this.value, u = this.unit;
312 ( u === 'em' || ( u === '' && this.name === 'lineHeight' ) ) ?
313 v * this.xnode._getCharSize() :
315 v / ( X.Dom.Style._UNIT_RATIO[ u ] || 1 );
318 var p = X.Dom.Style.PARAMS,
322 z = u !== '' ? true : v === 0;
323 if( p.percent[ n ] === true ) return z;
324 if( p.offset[ n ] === true ) return z;
325 if( p.size[ n ] === true ) return z && u !== '%';
326 if( p.special[ n ] === true ){
327 if( n === 'lineHeight' ) return true;
328 if( n === 'opacity' ) return 0 <= v && v <= 1 && u === '';
329 if( n === 'zIndex' ) return u === '';
337 * backgroundPosition, clip
339 PropertyGroup : X.Class.create(
343 Constructor : function( name ){
346 for( var i = 1, l = arguments.length; i<l; ++i ){
347 this.props[ this.props.length ] = arguments[ i ];
351 equal : function( prop ){
352 var ps = this.props, i = ps.length;
355 if( ps[ i ].equal( prop[ i ] ) === false ) return false;
359 convert : function( prop ){
360 var ps = this.props, i = ps.length;
363 ps[ i ].convert( prop[ i ] );
366 setValue : function( ary ){
367 var ps = this.props, i = 0, l = ps.length;
369 ps[ i ].setValue( ary[ i ] );
372 getValue : function(){
373 var ret = [], ps = this.props, i = 0, l = ps.length;
375 ret[ ret.length ] = ps[ i ].getValue();
379 getOffset : function( prop ){
386 ret[ ret.length ] = ps[ i ].getOffset( _ps[ i ] );
390 getUnit : function(){
391 var ret = [], ps = this.props, i = 0, l = ps.length;
393 ret[ ret.length ] = ps[ i ].getUnit();
397 getValueText : function(){
398 var ret = [], ps = this.props, i = 0, l = ps.length;
400 ret[ ret.length ] = ps[ i ].getValueText();
402 if( this.name === 'clip' ){
403 return 'rect(' + ret.join( X.Dom.Style._CLIP_SEPARATOR ) + ')';
405 return ret.join( ' ' );
408 var ps = this.props, i = ps.length;
413 isValid : function( t ){
415 var ps = t.props, i = ps.length;
417 if( ps[ --i ].isValid() === false ) return false;
425 * http://css-eblog.com/ie-css-problems/rgba-pe.html
426 * ie67 では rgb() は background-color で反応しない、、、
429 ColorProperty : X.Class.create(
431 X.Class.POOL_OBJECT, {
432 Constructor : function( name, x ){
439 if( X.Type.isNumber( rgb = x ) || X.Type.isNumber( rgb = X.Dom.Style.COLOR[ x.toUpperCase() ] ) ){
440 r = ( rgb & 0xff0000 ) >> 16;
441 g = ( rgb & 0xff00 ) >> 8;
444 if( x.charAt( 0 ) === '#' ){
445 if( x.length === 7 ){
446 r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 );
447 g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 );
448 b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 );
450 if( x.length === 4 ){
451 r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
452 g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 );
453 b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 );
455 if( x.length === 2 ){
456 r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
457 g = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
458 b = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
461 if( x.indexOf( 'rgb(' ) === 0 ){
462 rgb = x.substr( 4 ).split( ',' );
463 r = parseFloat( rgb[ 0 ] );
464 g = parseFloat( rgb[ 1 ] );
465 b = parseFloat( rgb[ 2 ] );
466 if( x.indexOf( '%' ) !== -1 ) pct = true;
468 if( x.indexOf( 'rgba(' ) === 0 ){
469 rgb = x.substr( 5 ).split( ',' );
470 r = parseFloat( rgb[ 0 ] );
471 g = parseFloat( rgb[ 1 ] );
472 b = parseFloat( rgb[ 2 ] );
473 a = parseFloat( rgb[ 3 ] );
474 if( x.indexOf( '%' ) !== -1 ) pct = true;
494 equal : function( prop ){
495 if( this.pct === prop.pct ){
496 return this.r === prop.r && this.g === prop.g && this.b === prop.b;
498 var rgb = this._toPct(),
499 _rgb = prop._toPct(),
503 if( Math.abs( rgb[ i ] - _rgb[ i ] ) > 1 ) return false;
507 convert : function( prop ){
509 if( this.pct === u ) return;
510 x = u === true ? 100 / 255 : 2.55;
516 setValue : function( rgb ){
521 getValue : function(){
522 return [ this.r, this.g, this.b ];
524 getOffset : function( prop ){
525 return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ];
527 getUnit : function(){
528 return this.pct === true ? '%' : '';
530 getValueText : function(){
531 if( this.pct === true ){
532 return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' );
534 var round = Math.round;
536 var rgb = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 );
537 return '#' + rgb.substr( rgb.length - 6 );
540 if( this.pct === true ) return [ this.r, this.g, this.b ];
541 return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ];
543 isValid : function( t ){
544 var isFinite = window.isFinite;
545 if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false;
546 if( 0 > this.r || 0 > this.g || 0 > this.b ) return false;
547 if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100;
548 return this.r <= 255 && this.g <= 255 && this.b <= 255;
553 _getProperty : function( xnode, css, unit, p ){
555 var XDomStyle = X.Dom.Style,
556 me = XDomStyle._getProperty,
557 PARAMS = XDomStyle.PARAMS,
558 PropertyGroup = XDomStyle.PropertyGroup,
559 Property = XDomStyle.Property,
560 ColorProperty = XDomStyle.ColorProperty,
563 if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){
566 // rect(...) クリップします。<top>, <bottom> は上端からの、 <right>, <left> は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。
567 // position:absolute または position:fixed を適用した要素に対してのみ有効です。
568 var top = me( p + 'Top' ),
569 right = me( p + 'Right' ),
570 bottom = me( p + 'Bottom' ),
571 left = me( p + 'Left' ),
572 ret = new PropertyGroup( p, top, right, bottom, left ),
574 if( ret.isValid() === true ) return ret;
576 all = css[ p ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( XDomStyle._CLIP_SEPARATOR );
580 new Property( p + 'Top', all[ 0 ], 'px', xnode ),
581 new Property( p + 'Right', all[ 1 ], 'px', xnode ),
582 new Property( p + 'Bottom', all[ 2 ], 'px', xnode ),
583 new Property( p + 'Left', all[ 3 ], 'px', xnode )
591 var props = '$1Top$2,$1Right$2,$1Bottom$2,$1Left$2'.split( '$1' ).join( name || 'border' ).split( '$2' ).join( width || 'Width' ).split( ',' ),
592 top = me( props[ 0 ] ),
593 right = me( props[ 1 ] ),
594 bottom = me( props[ 2 ] ),
595 left = me( props[ 3 ] ),
596 ret = new PropertyGroup( p, top, right, bottom, left ),
597 all, _0, _1, _2, _3, vu, v, u;
598 if( ret.isValid() === true ) return ret;
600 all = css[ p ].split( ' ' );
605 vu = XDomStyle._Util._splitValueAndUnit( _0 );
608 switch( all.length ){
610 top = new Property( props[ 0 ], v, u, xnode );
611 right = new Property( props[ 1 ], v, u, xnode );
612 bottom = new Property( props[ 2 ], v, u, xnode );
613 left = new Property( props[ 3 ], v, u, xnode );
616 top = new Property( props[ 0 ], v, u, xnode );
617 bottom = new Property( props[ 2 ], v, u, xnode );
618 vu = XDomStyle._Util._splitValueAndUnit( _1 );
621 right = new Property( props[ 1 ], v, u, xnode );
622 left = new Property( props[ 3 ], v, u, xnode );
625 top = new Property( props[ 0 ], v, u, xnode );
626 vu = XDomStyle._Util._splitValueAndUnit( _1 );
629 right = new Property( props[ 1 ], v, u, xnode );
630 left = new Property( props[ 3 ], v, u, xnode );
631 vu = XDomStyle._Util._splitValueAndUnit( _2 );
634 bottom = new Property( props[ 2 ], v, u, xnode );
637 top = new Property( props[ 0 ], v, u, xnode );
638 vu = XDomStyle._Util._splitValueAndUnit( _1 );
641 right = new Property( props[ 1 ], v, u, xnode );
642 vu = XDomStyle._Util._splitValueAndUnit( _2 );
645 bottom = new Property( props[ 2 ], v,u, xnode );
646 vu = XDomStyle._Util._splitValueAndUnit( _3 );
649 left = new Property( props[ 3 ], v, u, xnode );
652 return new PropertyGroup( p, top, right, bottom, left );
655 var props = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ),
656 top = me( props[ 0 ] ),
657 right = me( props[ 1 ] ),
658 bottom = me( props[ 2 ] ),
659 left = me( props[ 3 ] ),
660 ret = new PropertyGroup( p, top, right, bottom, left ),
662 if( ret.isValid() === true ) return ret;
664 all = css[ p ].split( ' ' );
667 switch( all.length ){
669 top = new ColorProperty( props[ 0 ], _0 );
670 right = new ColorProperty( props[ 1 ], _0 );
671 bottom = new ColorProperty( props[ 2 ], _0 );
672 left = new ColorProperty( props[ 3 ], _0 );
675 top = new ColorProperty( props[ 0 ], _0 );
676 right = new ColorProperty( props[ 1 ], _1 );
677 bottom = new ColorProperty( props[ 2 ], _0 );
678 left = new ColorProperty( props[ 3 ], _1 );
681 top = new ColorProperty( props[ 0 ], _0 );
682 right = new ColorProperty( props[ 1 ], _1 );
683 bottom = new ColorProperty( props[ 2 ], all[ 2 ] );
684 left = new ColorProperty( props[ 3 ], _1 );
687 top = new ColorProperty( props[ 0 ], _0 );
688 right = new ColorProperty( props[ 1 ], _1 );
689 bottom = new ColorProperty( props[ 2 ], all[ 2 ] );
690 left = new ColorProperty( props[ 3 ], all[ 3 ] );
693 return new PropertyGroup( p, top, right, bottom, left );
695 case 'backgroundPosition' :
696 var x = me( p + 'X' ),
698 ret = new PropertyGroup( p, x, y ),
700 if( ret.isValid() === true ) return ret;
702 xy = css[ p ].split( ' ' );
703 x = XDomStyle._Util._splitValueAndUnit( xy[ 0 ] );
704 y = XDomStyle._Util._splitValueAndUnit( xy[ 1 ] );
708 new Property( p + 'X', x[ 0 ], x[ 1 ], xnode ),
709 new Property( p + 'Y', y[ 0 ], y[ 1 ], xnode )
712 // opacity, zindex, lineHeight
713 vu = XDomStyle._Util._splitValueAndUnit( css[ p ] );
714 return new Property( p, vu[ 0 ], vu[ 1 ], xnode );
716 var x = css[ p ], e, v, u;
718 if( PARAMS.offset[ p ] === true ){
719 return new Property( p, vu[ 0 ], vu[ 1 ], xnode );
722 if( p === 'width' ) v = e.offsetWidth;
723 if( p === 'height' ) v = e.offsetHeight;
724 if( p === 'top' ) v = e.offsetTop;
725 if( p === 'bottom' ) v = e.offsetBottom;
726 if( p === 'left' ) v = e.offsetLeft;
727 if( p === 'right' ) v = e.offsetRight;
728 u = _getUnit( x, p );
729 // alert( p + XDomStyle._Util.pxTo( v, u ) + u )
730 return new Property( p, XDomStyle._Util.pxTo( v, u ), u, xnode );
732 if( p === 'fontSize' && ( v = XDomStyle._FONT_SIZE_RATIO[ x ] ) ){ // xx-small 等
733 return new Property( p, v, 'px', xnode );
735 if( PARAMS.offset[ p ] || PARAMS.percent[ p ] || PARAMS.size[ p ] ){
736 vu = XDomStyle._Util._splitValueAndUnit( x );
737 return new Property( p, vu[ 0 ], vu[ 1 ], xnode );
740 if( PARAMS.color[ p ] ) return new ColorProperty( p, x );
745 getValue: function( x ){
746 return X.Type.isString( x ) ? parseInt( x ) :
747 X.Type.isNumber( x ) ? x : 0;
749 getUnit: function( x, p ){
752 var REG_UINIT = /.*\d(\w{1,2})?/,
757 if( X.Type.isString( x ) === true ){
758 u = x.replace( REG_UINIT, $1 );
759 if( p === 'lineHeight' ) return u;
760 if( PARAMS.unit[ u ] !== true ) return 'px';
765 _splitValueAndUnit : function( v ){
767 if( X.Type.isNumber( v ) ) return [ v || 0, '' ];
768 if( isNaN( num = parseInt( v ) ) ) return [ 0, '' ];
770 i = v.indexOf( _num ) + _num.length;
772 return [ num, X.Dom.Style.UNIT[ u ] ? u : 'px' ];
777 X.Dom.Style._GET_VALUE_WITH_UNIT = {
778 borderWidth : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH,
779 //borderStyle : X.Dom.Style.Type.QUARTET,
780 borderRadius : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH,
781 margin : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
782 padding : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
783 clip : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
785 backgroundColor : X.Dom.Style.Type.COLOR,
786 backgroundPosition : X.Dom.Style.Type.COMBI,
790 fontSize : X.Dom.Style.Type.LENGTH,
791 lineHeight : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT | X.Dom.Style.Type.NUMERICAL,
792 textIndent : X.Dom.Style.Type.LENGTH,
793 letterSpacing : X.Dom.Style.Type.LENGTH,
794 wordSpacing : X.Dom.Style.Type.LENGTH,
796 textShadowColor : X.Dom.Style.Type.COLOR,
797 textShadowOffsetX : X.Dom.Style.Type.LENGTH,
798 textShadowOffsetY : X.Dom.Style.Type.LENGTH,
799 textShadowBlur : X.Dom.Style.Type.LENGTH, */
801 width : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
802 height : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
804 left : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
805 top : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
806 bottom : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
807 right : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
810 borderSpacing : X.Dom.Style.Type.LENGTH
814 X.Dom.Style.SPECIAL_FIX =
816 X.UA.IE && X.UA.IE < 9 ?
818 var test = X.Dom.Style.SPECIAL_FIX_PROP,
819 filters = [], p, id, v;
821 if( !( id = test[ p ] ) ) continue;
824 case 1 : //'filter' :
825 filters[ filters.length ] = v;
827 case 2 : //'opacity' :
828 filters[ filters.length ] = 'aplha(opacity=' + v +')';
830 case 3 : //'boxShadow' :
831 // box-shadow: 10px 10px 10px 10px rgba(0,0,0,0.4) inset;
832 // スペース区切りで、水平方向の距離 垂直方向の距離 ぼかし距離 広がり距離 影の色 insetキーワードを指定する。 ぼかし距離 広がり距離 影の色 insetキーワードは省略可
833 // shadow(color=#cccccc, strength=10, direction=135);
834 parseValue( 'boxShadow', v, 'px' );
835 dir = Math.atan2( ary[1], ary[0] ) * 180 / Math.PI + 90;
836 dir += dir < 0 ? 360 : 0;
838 case 4 : //'textShadow' :
839 //text-shadow: 5px 5px 2px blue; 水平方向の距離 垂直方向の距離 影のぼかし半径 影の色 none
840 //glow(Color=yellow,Strength=10);
841 //どうやらCSSのbackgroundプロパティと同時に使えないようです。
843 case 5 : //'backgroundImage' :
847 if( filters ) return filters.join( ' ' );
849 // IE9 textShadow に filter を使用
850 X.UA.IE && 9 <= X.UA.IE && X.UA.IE < 10 ?
852 var test = X.Dom.Style.SPECIAL_FIX_PROP,
853 filters = [], p, id, v;
855 if( !( id = test[ p ] ) ) continue;
858 case 1 : //'filter' :
859 filters[ filters.length ] = v;
863 if( filters ) return filters.join( ' ' );
866 var test = X.Dom.Style.SPECIAL_FIX_PROP,
869 if( !( id = test[ p ] ) ) continue;
872 case 1 : //'backgroundPositionX' :
875 case 2 : //'backgroundPositionY' :
878 case 3 : //'backgroundPositionX' :
881 case 4 : //'backgroundPositionX' :
884 case 5 : //'backgroundPositionX' :
887 case 6 : //'backgroundPositionX' :
892 if( bgpX || bgpY ) ret[ ret.length ] = 'background-position:';
893 if( clipT || clipB || clipL || clipR ){
894 ret[ ret.length ] = 'clip:rect(';
896 return ret.join( ';' );
904 // unitID, name 単位指定のプロパティ取得 geter
906 // name, value setter
907 X.Dom.Node.prototype.css = function( nameOrObj /* orUnitID, valuOrUnitOrName */ ){
908 var XDomStyle = X.Dom.Style,
911 p, valOrUnit, name, v, node, camelize, unit;
912 if( this._xnodeType !== 1 ) return this;
914 if( X.Type.isObject( nameOrObj ) ){
915 if( !css ) css = this._css = {};
916 camelize = XDomStyle.camelize;
917 for( p in nameOrObj ){
918 css[ camelize( p ) ] = nameOrObj[ p ];
920 this._cssText = XDomStyle.objToCssText( this._css );
921 if( node = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode ){
923 node.style.cssText = this._cssText;
924 this._styleText = ' style="' + this._cssText + '"';
926 node.removeAttribute( 'style' );
927 delete this._cssText;
928 delete this._styleText;
933 if( 1 < args.length ){
934 if( !( unit = XDomStyle.UNIT[ nameOrObj ] ) ){
935 // setter name, value
936 if( !css ) css = this._css = {};
937 name = XDomStyle.camelize( nameOrObj );
939 node = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;
940 if( css[ name ] === v ) return this;
944 node.style[ name ] = ''; // val
946 this._cssText = XDomStyle.objToCssText( css );
947 if( !this._cssText ){
948 delete this._cssText;
949 delete this._styleText;
950 node && node.removeAttribute( 'style' );
955 node.style[ name ] = v; // val
958 this._cssText = [ this._cssText, this._cssText ? ';' : '', XDomStyle.uncamelize( nameOrObj ), ':', v ].join( '' );
962 this._cssText = XDomStyle.objToCssText( css );
964 this._styleText = ' style="' + this._cssText + '"';
968 // unit 付の値取得は fontSize と 画像サイズが確定していないと正確に取れない。内部のみにする?
970 if( !X.Dom.Style._GET_VALUE_WITH_UNIT[ name = XDomStyle.camelize( args[ 1 ] ) ] ) return null;
971 p = XDomStyle._getProperty( this, css, unit, name );
978 // 集計 border, padding, margin, backgroundPosition, clip
979 // border で正確なデータを返せない時は、null を返す
980 return css[ XDomStyle.camelize( nameOrObj ) ];
983 X.Dom.Node.prototype.cssText = function( v ){
984 var camelize, obj, i, l, attr, name;
985 if( X.Type.isString( v ) ){
986 camelize = X.Dom.Style.camelize;
990 for( i = 0, l = v.length; i < l; ++i ){
991 attr = v[ i ].split( ':' );
992 name = camelize( attr[ 0 ] );
993 name && ( obj[ name ] = attr[ 1 ] || true );
995 return this.css( obj );
997 return this._cssText;
1001 * ここでは HTMLElement かのチャックは行わない!
1003 X.Dom.Node.prototype._getCharSize =
1004 window.getComputedStyle ?
1006 return parseInt( getComputedStyle( this._rawNode, null ).fontSize );
1008 document.defaultView && document.defaultView.getComputedStyle ?
1010 return parseInt( document.defaultView.getComputedStyle( this._rawNode, null ).fontSize );
1012 X.UA.IE && 5 <= X.UA.IE ?
1014 var font = this._rawNode.currentStyle.fontSize,
1015 vu = X.Dom.Style._Util._splitValueAndUnit( font ),
1022 // body まで辿ってしまった場合は?
1023 return this.parent._getCharSize() * v;
1025 // body まで辿ってしまった場合は?
1026 return this.parent._getCharSize() * v / 100;
1029 ( X.Dom.Style._FONT_SIZE_RATIO[ font ] || 0 ) :
1030 v / ( X.Dom.Style._UNIT_RATIO[ u ] || 1 );
1034 document.removeChild ?
1036 var elm = document.createElement( 'span' ),
1038 elm.style.cssText = 'display:block;position:absolute;top:0;left:0;visivility:hidden;line-height:1;height:1em;';
1039 elm.innerHTML = 'X';
1040 this._rawNode.appendChild( elm );
1041 v = elm.offsetHeight;
1042 this._rawNode.removeChild( elm );
1047 var elm = this._rawNode, v;
1048 elm.insertAdjacentHTML( 'BeforeEnd', '<span style="visivility:hidden;line-height:1;">X</span>' );
1049 elm = elm.children[ elm.children.length - 1 ];
1050 v = elm.offsetHeight;
1058 X.Dom.listenOnce( X.Dom.Event.DOM_PRE_INIT, function(){
1059 var testStyle = X.Dom._root;
1061 X.Dom.Style.VENDER_PREFIX = (function(){
1063 vendors = 'webkit,Webkit,Moz,moz,ms,Ms,O,o,khtml,Khtml'.split( ',' ),
1065 'opacity,boxSizing,' +
1066 'transform,transformOrigin,perspective,' +
1067 'transisiton,transitionDelay,transitionProperty,transitionDuration,transitionTimingFunction,' +
1068 'userSelect,touchAction,touchCallout,contentZooming,userDrag,tapHighlightColor'.split( ',' ),
1069 vendor, i, search, prop;
1071 vendors.unshift( '' );
1073 function findVenderPrefix( prop ){
1074 var v, i = vendors.length;
1078 if( testStyle[ v + prop ] !== undefined ){
1085 for( i = searches.length; i; ){
1086 search = searches[ --i ];
1087 prop = findVenderPrefix( search );
1088 if( search === 'transform' ) ret.transVender = vendor;
1089 if( prop ) ret[ search ] = prop;
1094 X.Dom.Style.SPECIAL_FIX_PROP =
1096 X.UA.IE && X.UA.IE < 9 ?
1099 opacity : 2//, uinode ChromeNode で行う
1102 //backgroundImage : 5
1105 X.UA.IE && 9 <= X.UA.IE && X.UA.IE < 10 ?
1111 backgroundPositionX : testStyle.backgroundPositionX === undefined ? 3 : 0,
1112 backgroundPosiitonY : testStyle.backgroundPositionX === undefined ? 3 : 0,
1113 clipTop : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 3 : 0,
1114 clipBottom : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 4 : 0,
1115 clipLeft : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 5 : 0,
1116 clipRight : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 6 : 0
1120 X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
1121 var xnode = Node._systemNode,
1122 output = X.Dom.Style._UNIT_RATIO = {},
1123 list = 'em,cm,mm,in,pt,pc'.split( ',' ),
1126 for( i = list.length; i; ){
1128 output[ unit ] = xnode.css( 'width', 100 + unit ).width() / 100;
1131 output = X.Dom.Style._FONT_SIZE_RATIO = {},
1132 list = 'xx-large,x-large,large,larger,medium,small,smaller,x-small,xx-small'.split( ',' );
1133 base = xnode.css( 'lineHeight', 1 ).text( 'X' ).height();
1135 for( i = list.length; i; ){
1137 output[ size ] = xnode.css( 'fontSize', size ).height() / base;
1140 xnode.empty().cssText( '' );