OSDN Git Service

Version 0.6.90, files & folders renamed.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 16_XDomStyle.js
1
2
3 /*
4  * style 値の変更は、enterFrame 後にまとめて適用
5  * width(), height(), x(), y() 1em の取得時にも適用
6  * css3 の ie用 fix は X.UI レベルで行う
7  * 
8  * use X.Dom.Event
9  */
10 X.Dom.Style = {
11         
12         Type : {
13                 LENGTH            : 1,
14                 PERCENT           : 2,
15                 COLOR             : 2 < 2,
16                 U_DECIMAL         : 2 < 3,
17                 NUMERICAL         : 2 < 4,
18                 BOOLEAN           : 2 < 5,
19                 QUARTET           : 2 < 6,
20                 URL               : 2 < 7,
21                 FONT_NAME         : 2 < 8,
22                 TIME              : 2 < 9,
23                 CONTENT           : 2 < 10,
24                 LIST              : 2 < 11,
25                 AUTO              : 2 < 12,
26                 COMBI             : 2 < 13
27         },
28         
29         UNIT : {
30                 'px'   : 0,
31                 'em'   : 1,
32                 'cm'   : 2,
33                 'mm'   : 3,
34                 'in'   : 4,
35                 '%'    : 5,
36                 'pct'  : 5,
37                 'ms'   : 6,
38                 's'    : 7,
39                 '#'    : 8,
40                 'rgb'  : 9,
41                 'rgba' : 10
42         },
43         
44         /* font-size -> fontSize */
45         _DICTIONARY_CAMELIZE : {},
46         
47         camelize : function( cssProp ){
48                 var me  = X.Dom.Style,
49                         parts, l, i, camelized;
50                 
51                 if( camelized = me._DICTIONARY_CAMELIZE[ cssProp ] ) return camelized;
52                 parts = cssProp.split( ' ' ).join( '' ).split( '-' );
53                 l     = parts.length;
54                 if( l === 1 ) return parts[ 0 ];
55                 
56                 camelized = cssProp.charAt(0) === '-'
57                   ? parts[ 0 ].charAt( 0 ).toUpperCase() + parts[ 0 ].substring( 1 )
58                   : parts[ 0 ];
59                 
60                 for( i = 1; i < l; ++i ){
61                         camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 );
62                 };
63                 return me._DICTIONARY_CAMELIZE[ cssProp ] = camelized;
64         },
65         
66         /* fontSize -> font-size */
67         CHAR_CODE_A : 'A'.charCodeAt( 0 ),
68         
69         _DICTIONARY_UNCAMELIZE : {},
70         
71         uncamelize : function( str ){
72                 var me  = X.Dom.Style,
73                         A   = me.CHAR_CODE_A,
74                         Z   = A + 25,
75                         uncamelized, l, chr, code;
76                 str = str.split( ' ' ).join( '' );
77                 if( uncamelized = me._DICTIONARY_UNCAMELIZE[ str ] ) return uncamelized;
78                 uncamelized = '';
79                 for( i = 0, l = str.length; i < l; ++i ){
80                         chr = str.charAt( i );
81                         code = chr.charCodeAt( 0 );
82                         uncamelized += ( A <= code && code <= Z ) ? '-' + chr : chr;
83                 };
84                 return me._DICTIONARY_UNCAMELIZE[ str ] = uncamelized.toLowerCase();
85         },
86         
87 /*
88  * CSS における display, position, float プロパティの相互関係
89  * http://d.hatena.ne.jp/elm200/20080201/1201874740
90  * 
91  * CSS21:9.7 Relationships between ’display’, ’position’, and ’float’ 
92  * http://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo
93  * 
94  *   display:none? -yes-> 非表示
95  *    ↓
96  *   position:absolute? -yes-> float:none,display:block;
97  *    ↓
98  *   float:none? -no-> display:block;
99  *    ↓
100  *   display:そのまま
101  * 
102  *
103 display         position                        float
104 block           static|relative         none
105 block           static|relative         right|left
106 block           absolute                        none
107 inline          static|relative         none
108
109 _DISPLAY_NONE
110 _ABSOLUTE_BOX
111 _FLOAT_BOX
112 _GRNERAL
113  */
114         VENDER_PREFIX : {},
115
116         objToCssText : function( obj ){
117                 var css           = [],
118                         me            = X.Dom.Style,
119                         uncamelize    = me.uncamelize,
120                         VENDER_PREFIX = me.VENDER_PREFIX,
121                         FIX_PROP      = me.SPECIAL_FIX_PROP,
122                         SPECIAL_FIX   = me.SPECIAL_FIX,
123                         n             = -1,
124                         p, v, name, sp;
125                 if( !obj ) return ''; // Opera7.5 未満?
126                 for( p in obj ){
127                         // TODO Object が拡張されていると error...
128                         name = uncamelize( VENDER_PREFIX[ p ] || p );
129                         if( FIX_PROP[ name ] ){
130                                 sp = true;
131                         } else {
132                                 css[ ++n ] = [ name, obj[ p ] ].join( ':' );
133                         };
134                 };
135                 sp && ( css[ ++n ] = 'filter:' + SPECIAL_FIX( obj ) );
136                 return css.join( ';' );
137         },
138         
139         IE_FILTER_FIX :
140                 X.UA.IE && X.UA.IE < 9 && !X.UA.MacIE ?
141                         {
142                                 opacity : 1,
143                                 textShadow : 1
144                         } :
145                 9 <= X.UA.IE && X.UA.IE < 10 ? // == 9
146                         {} :
147                         {},
148         
149         _UNIT_RATIO      : null,
150         _FONT_SIZE_RATIO : null,
151
152         //  https://developer.mozilla.org/en-US/docs/Web/CSS/transform
153         //  Firefox 3.5, ie9, Opera 10.5, Safari 3.1, Chrome
154         //  3D support Firefox 10, ie10, Safari 4.0, Chrome 12.0
155         // transform : void 0,
156         
157         //  https://developer.mozilla.org/ja/docs/Web/Guide/CSS/Using_CSS_transitions
158         //  Chrome 1.0, Firefox 4.0, ie10, Opera 10.5, Safari 3.2
159         //  Android 2.1, Firefox Android 4.0, Opera Mobile 10, Safari Mobile 3.2        
160         // transition : void 0
161         
162         // ブラウザ毎の getComputedStyle の戻り値 http://d.hatena.ne.jp/uupaa/20080928/1222543331
163
164         COLOR : {
165                 BLACK         : 0x0,
166                 RED           : 0xFF0000,
167                 LIME          : 0x00FF00,
168                 BLUE          : 0x0000FF,
169                 YELLOW        : 0xFFFF00,
170                 AQUA          : 0x00FFFF,
171                 CYAN          : 0x00FFFF,
172                 MAGENTA       : 0xFF00FF,
173                 FUCHSIA       : 0xFF00FF,
174                 WHITE         : 0xFFFFFF,
175                 GREEN         : 0x008000,
176                 PURPLE        : 0x800080,
177                 MAROON        : 0x800000,
178                 NAVY          : 0x000080,
179                 OLIVE         : 0x808000,
180                 TEAL          : 0x008080,
181                 GRAY          : 0x808080,
182                 SILVER        : 0xC0C0C0,
183                 DIMGRAY       : 0x696969,
184                 SLATEGRAY     : 0x708090,
185                 DARKGRAY      : 0xA9A9A9,
186                 GAINSBORO     : 0xDCDCDC,
187                 MIDNIGHTBLUE  : 0x191970,
188                 SLATEBLUE     : 0x6A5ACD,
189                 MEDIUMBLUE    : 0x0000CD,
190                 ROYALBLUE     : 0x4169E1,
191                 DODGERBLUE    : 0x1E90FF,
192                 SKYBLUE       : 0x87CEEB,
193                 STEELBLUE     : 0x4682B4,
194                 LIGHTBLUE     : 0xADD8E6,
195                 PALETURQUOISE : 0xAFEEEE,
196                 TURQUOISE     : 0x40E0D0,
197                 LIGHTCYAN     : 0xE0FFFF,
198                 AQUAMARINE    : 0x7FFFD4,
199                 DARKGREEN     : 0x006400,
200                 SEAGREEN      : 0x2E8B57,
201                 LIGHTGREEN    : 0x90EE90,
202                 CHARTREUSE    : 0x7FFF00,
203                 GREENYELLOW   : 0xADFF2F,
204                 LIMEGREEN     : 0x32CD32,
205                 YELLOWGREEN   : 0x9ACD32,
206                 OLIVEDRAB     : 0x6B8E23,
207                 DARKKHAKI     : 0xBCB76B,
208                 PALEGOLDENROD : 0xEEE8AA,
209                 LIGHTYELLOW   : 0xFFFFE0,
210                 GOLD          : 0xFFD700,
211                 GOLDENROD     : 0xDAA520,
212                 DARKGOLDENROD : 0xB8860B,
213                 ROSYBROWN     : 0xBC8F8F,
214                 INDIANRED     : 0xCD5C5C,
215                 SADDLEBROWN   : 0x8B4513,
216                 SIENNA        : 0xA0522D,
217                 PERU          : 0xCD853F,
218                 BURLYWOOD     : 0xDEB887,
219                 BEIGE         : 0xF5F5DC,
220                 WHEAT         : 0xF5DEB3,
221                 SANDYBROWN    : 0xF4A460,
222                 TAN           : 0xD2B48C,
223                 CHOCOLATE     : 0xD2691E,
224                 FIREBRICK     : 0xB22222,
225                 BROWN         : 0xA52A2A,
226                 SALMON        : 0xFA8072,
227                 ORANGE        : 0xFFA500,
228                 CORAL         : 0xFF7F50,
229                 TOMATO        : 0xFF6347,
230                 HOTPINK       : 0xFF69B4,
231                 PINK          : 0xFFC0CB,
232                 DEEPPINK      : 0xFF1493,
233                 PALEVIOLETRED : 0xDB7093,
234                 VIOLET        : 0xEE82EE,
235                 PLUM          : 0xDDA0DD,
236                 ORCHILD       : 0xDA70D6,
237                 DARKVIOLET    : 0x9400D3,
238                 BLUEVIOLET    : 0x8A2BE2,
239                 MEDIUMPURPLE  : 0x9370DB,
240                 THISTLE       : 0xD8BFD8,
241                 LAVENDER      : 0xE6E6FA,
242                 MISTYROSE     : 0xFFE4E1,
243                 IVORY         : 0xFFFFF0,
244                 LEMONCHIFFON  : 0xFFFACD
245         },
246         
247         parseColor : function( x ){
248                 var rgb, r, g, b;
249                 
250                 if( X.Type.isNumber( x ) ){
251                         return ( 0x0 <= x && x <= 0xFFFFFF ) ? x : undefined;
252                 } else
253                 if( !X.Type.isString( x ) ) return;
254                 
255                 if( X.Type.isNumber( rgb = X.Dom.Style.COLOR[ x.toUpperCase() ] ) && 0x0 <= rgb && rgb <= 0xFFFFFF ){
256                         return rgb;
257                 } else
258                 if( x.charAt( 0 ) === '#' ){
259                         switch( x.length ){
260                                 case 7 :
261                                         r = parseInt( x.substr( 1, 2 ), 16 );
262                                         g = parseInt( x.substr( 3, 2 ), 16 );
263                                         b = parseInt( x.substr( 5, 2 ), 16 );
264                                         break;
265                                 case 4 :
266                                         r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
267                                         g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 );
268                                         b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 );
269                                         break;
270                                 case 2 :
271                                         r = g = b = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
272                                         break;
273                                 default :
274                                         return;                                                                                 
275                         };
276                 } else
277                 if( x.indexOf( 'rgb(' ) === 0 ){
278                         rgb = x.substr( 4 ).split( ',' );
279                         r = parseFloat( rgb[ 0 ] );
280                         g = parseFloat( rgb[ 1 ] );
281                         b = parseFloat( rgb[ 2 ] );
282                         if( x.indexOf( '%' ) !== -1 ){
283                                 r *= 2.55;
284                                 g *= 2.55;
285                                 b *= 2.55;
286                         };
287                 } else
288                 if( x.indexOf( 'rgba(' ) === 0 ){
289                         rgb = x.substr( 5 ).split( ',' );
290                         r = parseFloat( rgb[ 0 ] );
291                         g = parseFloat( rgb[ 1 ] );
292                         b = parseFloat( rgb[ 2 ] );
293                         //a = parseFloat( rgb[ 3 ] );
294                         if( x.indexOf( '%' ) !== -1 ){
295                                 r *= 2.55;
296                                 g *= 2.55;
297                                 b *= 2.55;
298                         };
299                 } else {
300                         return undefined;
301                 };
302                 return isFinite( r + b + g ) ? ( r << 16 ) + ( g << 8 ) + b : undefined;
303         },
304         
305         PARAMS : ( function(){
306                 var ret = {};
307                 register( ret.percent = {},
308                         'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent'
309                 );
310                 register( ret.offset = {},
311                         'height,width,bottom,left,right,top'
312                 );              
313                 register( ret.size = {},
314                         'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing,wordSpacing'
315                 );
316                 register( ret.color = {},
317                         'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color'
318                 );
319                 register( ret.region = {},
320                         'margin,padding,borderWidth,borderColor'
321                 );              
322                 register( ret.special = {},
323                         'clip,backgroundPosition,backgroundPositionX,backgroundPositionY,opacity,lineHeight,zIndex'
324                 );
325                 register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' );
326                 
327                 register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' );
328                 register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' );
329                 register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' );
330                 register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' );
331                 
332                 function register( obj, params ){
333                         params = params.split( ',' );
334                         for( var i = params.length; i; ) obj[ params[ --i ] ] = true;
335                 };
336                 return ret;
337         })(),
338         
339         _CLIP_SEPARATOR : X.UA.IE && X.UA.IE < 8 ? ' ' : ',',
340         
341         /*
342          * 
343          */
344         Property : X.Class.create(
345                 'Property',
346                 X.Class.POOL_OBJECT,
347                 {
348                         Constructor : function( name, value, unit, xnode ){
349                                 this.name  = name;
350                                 this.value = value;
351                                 this.unit  = unit;
352                                 this.xnode = xnode;
353                         },
354                         name    : '',
355                         value   : 0,
356                         unit    : '',
357                         xnode   : null,
358                         equal : function( prop ){
359                                 if( this.unit === prop.unit ){
360                                         return this.value === prop.value;
361                                 };
362                                 return Math.abs( this.toPx() - prop.toPx() ) < 1;
363                         },
364                         convert: function( prop ){
365                                 var u = prop.unit, v;
366                                 if( this.unit === u ) return;
367                                 this.value = v = this.toPx();
368                                 this.unit  = u;
369                                 // %
370                                 // bgpX, bgpY の場合 X.Dom.Image.getActualDimension( backgroundImage url を使用 )
371                                 if( u !== 'px' ){
372                                         this.value =
373                                                 u === 'em' ?
374                                                         v / this.xnode._getCharSize() :
375                                                         v / ( X.Dom.Style._UNIT_RATIO[ u ] || 1 );
376                                 };
377                         },
378                         setValue: function( v ){
379                                 this.value = v;
380                         },
381                         getValue: function(){
382                                 return this.value;
383                         },
384                         getOffset: function( prop ){
385                                 return prop.value - this.value;
386                         },
387                         getUnit: function(){
388                                 return this.unit;
389                         },
390                         getValueText: function(){
391                                 return this.value === 0 ? '0' : this.value + this.unit;
392                         },
393                         toPx: function(){
394                                 var v = this.value, u = this.unit;
395                                 return
396                                         u === 'px' ?
397                                                 v :
398                                         ( u === 'em' || ( u === '' && this.name === 'lineHeight' ) ) ?
399                                                 v * this.xnode._getCharSize() :
400                                         // u === '%'
401                                                 v / ( X.Dom.Style._UNIT_RATIO[ u ] || 1 );
402                         },
403                         isValid: function(){
404                                 var p = X.Dom.Style.PARAMS,
405                                         n = this.name,
406                                         v = this.value,
407                                         u = this.unit,
408                                         z = u !== '' ? true : v === 0;
409                                 if( p.percent[ n ] === true ) return z;
410                                 if( p.offset[ n ]  === true ) return z;
411                                 if( p.size[ n ]    === true ) return z && u !== '%';
412                                 if( p.special[ n ] === true ){
413                                         if( n === 'lineHeight' ) return true;
414                                         if( n === 'opacity' )    return 0 <= v && v <= 1 && u === '';
415                                         if( n === 'zIndex'  )    return u === '';
416                                 };
417                                 return false;
418                         }
419                 }
420         ),
421         
422         /**
423          * backgroundPosition, clip
424          */
425         PropertyGroup : X.Class.create(
426                 'PropertyGroup',
427                 X.Class.POOL_OBJECT,
428                 {
429                         Constructor : function( name ){
430                                 this.name  = name;
431                                 this.props = [];
432                                 for( var i = 1, l = arguments.length; i<l; ++i ){
433                                         this.props[ this.props.length ] = arguments[ i ];
434                                 };
435                         },
436                         name  : '',
437                         equal : function( prop ){
438                                 var ps = this.props, i = ps.length;
439                                 for( ; i; ){
440                                         --i;
441                                         if( ps[ i ].equal( prop[ i ] ) === false ) return false;
442                                 };
443                                 return true;
444                         },
445                         convert : function( prop ){
446                                 var ps = this.props, i = ps.length;
447                                 for( ; i; ){
448                                         --i;
449                                         ps[ i ].convert( prop[ i ] );
450                                 };
451                         },
452                         setValue : function( ary ){
453                                 var ps = this.props, i = 0, l = ps.length;
454                                 for( ; i<l; ++i ){
455                                         ps[ i ].setValue( ary[ i ] );
456                                 };
457                         },
458                         getValue : function(){
459                                 var ret = [], ps = this.props, i = 0, l = ps.length;
460                                 for( ; i<l; ++i ){
461                                         ret[ ret.length ] = ps[ i ].getValue();
462                                 };
463                                 return ret;
464                         },
465                         getOffset : function( prop ){
466                                 var ret = [],
467                                         ps  = this.props,
468                                         _ps = prop.props,
469                                         i   = 0,
470                                         l = ps.length;
471                                 for( ; i<l; ++i ){
472                                         ret[ ret.length ] = ps[ i ].getOffset( _ps[ i ] );
473                                 };
474                                 return ret;
475                         },
476                         getUnit : function(){
477                                 var ret = [], ps = this.props, i = 0, l = ps.length;
478                                 for( ; i<l; ++i ){
479                                         ret[ ret.length ] = ps[ i ].getUnit();
480                                 };
481                                 return ret;
482                         },
483                         getValueText : function(){
484                                 var ret = [], ps = this.props, i = 0, l = ps.length;
485                                 for( ; i<l; ++i ){
486                                         ret[ ret.length ] = ps[ i ].getValueText();
487                                 };
488                                 if( this.name === 'clip' ){
489                                         return 'rect(' + ret.join( X.Dom.Style._CLIP_SEPARATOR ) + ')';
490                                 };
491                                 return ret.join( ' ' );
492                         },
493                         onKill : function(){
494                                 var ps = this.props, i = ps.length;
495                                 for( ; i; ){
496                                         ps[ --i ].kill();
497                                 };
498                         },
499                         isValid : function( t ){
500                                 t = t || this;
501                                 var ps = t.props, i = ps.length;
502                                 for( ; i; ){
503                                         if( ps[ --i ].isValid() === false ) return false;
504                                 };
505                                 return true;
506                         }
507                 }
508         ),
509
510         /*
511          * http://css-eblog.com/ie-css-problems/rgba-pe.html
512          * ie67 では rgb() は background-color で反応しない、、、
513          */
514
515         ColorProperty : X.Class.create(
516                 'ColorProperty',
517                 X.Class.POOL_OBJECT, {
518                         Constructor : function( name, x ){
519                                 var pct = false,
520                                         r   = 0,
521                                         g   = 0,
522                                         b   = 0,
523                                         a   = 1,
524                                         rgb;
525                                 if( X.Type.isNumber( rgb = x ) || X.Type.isNumber( rgb = X.Dom.Style.COLOR[ x.toUpperCase() ] ) ){
526                                         r = ( rgb & 0xff0000 ) >> 16;
527                                         g = ( rgb & 0xff00 ) >> 8;
528                                         b = ( rgb & 0xff );
529                                 } else
530                                 if( x.charAt( 0 ) === '#' ){
531                                         if( x.length === 7 ){
532                                                 r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 );
533                                                 g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 );
534                                                 b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 );
535                                         } else                  
536                                         if( x.length === 4 ){
537                                                 r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
538                                                 g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 );
539                                                 b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 );
540                                         } else
541                                         if( x.length === 2 ){
542                                                 r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
543                                                 g = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
544                                                 b = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 );
545                                         };
546                                 } else
547                                 if( x.indexOf( 'rgb(' ) === 0 ){
548                                         rgb = x.substr( 4 ).split( ',' );
549                                         r = parseFloat( rgb[ 0 ] );
550                                         g = parseFloat( rgb[ 1 ] );
551                                         b = parseFloat( rgb[ 2 ] );
552                                         if( x.indexOf( '%' ) !== -1 ) pct = true;
553                                 } else
554                                 if( x.indexOf( 'rgba(' ) === 0 ){
555                                         rgb = x.substr( 5 ).split( ',' );
556                                         r = parseFloat( rgb[ 0 ] );
557                                         g = parseFloat( rgb[ 1 ] );
558                                         b = parseFloat( rgb[ 2 ] );
559                                         a = parseFloat( rgb[ 3 ] );
560                                         if( x.indexOf( '%' ) !== -1 ) pct = true;
561                                 } else {
562                                         r = 255;
563                                         g = 255;
564                                         b = 255;
565                                 };
566                                 
567                                 this.name = name;
568                                 this.r    = r;
569                                 this.g    = g;
570                                 this.b    = b;
571                                 this.a    = a;
572                                 this.pct  = pct;
573                         },
574                         name  : '',
575                         r     : 0,
576                         g     : 0,
577                         b     : 0,
578                         a     : 0,
579                         pct   : false,
580                         equal : function( prop ){
581                                 if( this.pct === prop.pct ){
582                                         return this.r === prop.r && this.g === prop.g && this.b === prop.b;
583                                 };
584                                 var rgb  = this._toPct(),
585                                         _rgb = prop._toPct(),
586                                         i    = rgb.length;
587                                 for( ; i; ){
588                                         --i;
589                                         if( Math.abs( rgb[ i ] - _rgb[ i ] ) > 1 ) return false;
590                                 };
591                                 return true;
592                         },
593                         convert : function( prop ){
594                                 var u = prop.pct, x;
595                                 if( this.pct === u ) return;
596                                 x = u === true ? 100 / 255 : 2.55;
597                                 this.r  *= x;
598                                 this.g  *= x;
599                                 this.b  *= x;
600                                 this.pct = u;
601                         },
602                         setValue : function( rgb ){
603                                 this.r = rgb[ 0 ];
604                                 this.g = rgb[ 1 ];
605                                 this.b = rgb[ 2 ];
606                         },
607                         getValue : function(){
608                                 return [ this.r, this.g, this.b ];
609                         },
610                         getOffset : function( prop ){
611                                 return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ];
612                         },
613                         getUnit : function(){
614                                 return this.pct === true ? '%' : '';
615                         },
616                         getValueText : function(){
617                                 if( this.pct === true ){
618                                         return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' );
619                                 };
620                                 var round = Math.round;
621                                 
622                                 var rgb   = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 );
623                                 return '#' + rgb.substr( rgb.length - 6 );
624                         },
625                         _toPct : function(){
626                                 if( this.pct === true ) return [ this.r, this.g, this.b ];
627                                 return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ];
628                         },
629                         isValid : function( t ){
630                                 var isFinite = window.isFinite;
631                                 if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false;
632                                 if( 0 > this.r || 0 > this.g || 0 > this.b ) return false;
633                                 if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100;
634                                 return this.r <= 255 && this.g <= 255 && this.b <= 255;
635                         }
636                 }
637         ),
638         
639         _getProperty : function( xnode, css, unit, p ){
640                 
641                 var XDomStyle     = X.Dom.Style,
642                         me            = XDomStyle._getProperty,
643                         PARAMS        = XDomStyle.PARAMS,
644                         PropertyGroup = XDomStyle.PropertyGroup,
645                         Property      = XDomStyle.Property,
646                         ColorProperty = XDomStyle.ColorProperty,
647                         name, width;
648                 
649                 if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){
650                         switch( p ){
651                                 case 'clip' :
652                                         // rect(...)    クリップします。<top>, <bottom> は上端からの、 <right>, <left> は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。
653                                         // position:absolute または position:fixed を適用した要素に対してのみ有効です。
654                                         var top    = me( p + 'Top' ),
655                                                 right  = me( p + 'Right' ),
656                                                 bottom = me( p + 'Bottom' ),
657                                                 left   = me( p + 'Left' ),
658                                                 ret    = new PropertyGroup( p, top, right, bottom, left ),
659                                     all;
660                                         if( ret.isValid() === true ) return ret;
661                                         ret.kill();
662                                         all = css[ p ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( XDomStyle._CLIP_SEPARATOR );
663                                         return
664                                                 new PropertyGroup( 
665                                                         p,
666                                                         new Property( p + 'Top',    all[ 0 ], 'px', xnode ),
667                                                         new Property( p + 'Right',  all[ 1 ], 'px', xnode ),
668                                                         new Property( p + 'Bottom', all[ 2 ], 'px', xnode ),
669                                                         new Property( p + 'Left',   all[ 3 ], 'px', xnode )
670                                                 );
671
672                                 case 'margin' :
673                                 case 'padding' :
674                                         name  = p;
675                                         width = '';
676                                 case 'borderWidth' :
677                                         var props  = '$1Top$2,$1Right$2,$1Bottom$2,$1Left$2'.split( '$1' ).join( name || 'border' ).split( '$2' ).join( width || 'Width' ).split( ',' ),
678                                                 top    = me( props[ 0 ] ),
679                                                 right  = me( props[ 1 ] ),
680                                                 bottom = me( props[ 2 ] ),
681                                                 left   = me( props[ 3 ] ),
682                                                 ret    = new PropertyGroup( p, top, right, bottom, left ),
683                                                 all, _0, _1, _2, _3, vu, v, u;
684                                         if( ret.isValid() === true ) return ret;
685                                         ret.kill();
686                                         all = css[ p ].split( ' ' );
687                                         _0  = all[ 0 ];
688                                         _1  = all[ 1 ];
689                                         _2  = all[ 2 ];
690                                         _3  = all[ 3 ];
691                                         vu  = XDomStyle._splitValueAndUnit( _0 );
692                                         v   = vu[ 0 ];
693                                         u   = vu[ 1 ];
694                                         switch( all.length ){
695                                                 case 1 :
696                                                         top    = new Property( props[ 0 ], v, u, xnode );
697                                                         right  = new Property( props[ 1 ], v, u, xnode );
698                                                         bottom = new Property( props[ 2 ], v, u, xnode );
699                                                         left   = new Property( props[ 3 ], v, u, xnode );
700                                                         break;
701                                                 case 2 :
702                                                         top    = new Property( props[ 0 ], v, u, xnode );
703                                                         bottom = new Property( props[ 2 ], v, u, xnode );
704                                                         vu     = XDomStyle._splitValueAndUnit( _1 );
705                                                         v      = vu[ 0 ];
706                                                         u      = vu[ 1 ];
707                                                         right  = new Property( props[ 1 ], v, u, xnode );
708                                                         left   = new Property( props[ 3 ], v, u, xnode );
709                                                         break;
710                                                 case 3 :
711                                                         top    = new Property( props[ 0 ], v, u, xnode );
712                                                         vu     = XDomStyle._splitValueAndUnit( _1 );
713                                                         v      = vu[ 0 ];
714                                                         u      = vu[ 1 ];
715                                                         right  = new Property( props[ 1 ], v, u, xnode );
716                                                         left   = new Property( props[ 3 ], v, u, xnode );
717                                                         vu     = XDomStyle._splitValueAndUnit( _2 );
718                                                         v      = vu[ 0 ];
719                                                         u      = vu[ 1 ];
720                                                         bottom = new Property( props[ 2 ], v, u, xnode );
721                                                         break;
722                                                 case 4 :
723                                                         top    = new Property( props[ 0 ], v, u, xnode );
724                                                         vu     = XDomStyle._splitValueAndUnit( _1 );
725                                                         v      = vu[ 0 ];
726                                                         u      = vu[ 1 ];
727                                                         right  = new Property( props[ 1 ], v, u, xnode );
728                                                         vu     = XDomStyle._splitValueAndUnit( _2 );
729                                                         v      = vu[ 0 ];
730                                                         u      = vu[ 1 ];
731                                                         bottom = new Property( props[ 2 ], v,u, xnode );
732                                                         vu     = XDomStyle._splitValueAndUnit( _3 );
733                                                         v      = vu[ 0 ];
734                                                         u      = vu[ 1 ];
735                                                         left   = new Property( props[ 3 ], v, u, xnode );
736                                                         break;
737                                         };
738                                         return new PropertyGroup( p, top, right, bottom, left );
739
740                                 case 'borderColor' :
741                                         var props  = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ),
742                                                 top    = me( props[ 0 ] ),
743                                                 right  = me( props[ 1 ] ),
744                                                 bottom = me( props[ 2 ] ),
745                                                 left   = me( props[ 3 ] ),
746                                                 ret    = new PropertyGroup( p, top, right, bottom, left ),
747                                                 all, _0, _1;
748                                         if( ret.isValid() === true ) return ret;
749                                         ret.kill();
750                                         all = css[ p ].split( ' ' );
751                                         _0  = all[ 0 ];
752                                         _1  = all[ 1 ];
753                                         switch( all.length ){
754                                                 case 1 :
755                                                         top    = new ColorProperty( props[ 0 ], _0 );
756                                                         right  = new ColorProperty( props[ 1 ], _0 );
757                                                         bottom = new ColorProperty( props[ 2 ], _0 );
758                                                         left   = new ColorProperty( props[ 3 ], _0 );
759                                                         break;
760                                                 case 2 :
761                                                         top    = new ColorProperty( props[ 0 ], _0 );
762                                                         right  = new ColorProperty( props[ 1 ], _1 );
763                                                         bottom = new ColorProperty( props[ 2 ], _0 );
764                                                         left   = new ColorProperty( props[ 3 ], _1 );
765                                                         break;
766                                                 case 3 :
767                                                         top    = new ColorProperty( props[ 0 ], _0 );
768                                                         right  = new ColorProperty( props[ 1 ], _1 );
769                                                         bottom = new ColorProperty( props[ 2 ], all[ 2 ] );
770                                                         left   = new ColorProperty( props[ 3 ], _1 );
771                                                         break;
772                                                 case 4 :
773                                                         top    = new ColorProperty( props[ 0 ], _0 );
774                                                         right  = new ColorProperty( props[ 1 ], _1 );
775                                                         bottom = new ColorProperty( props[ 2 ], all[ 2 ] );
776                                                         left   = new ColorProperty( props[ 3 ], all[ 3 ] );
777                                                         break;
778                                         };
779                                         return new PropertyGroup( p, top, right, bottom, left );
780                                         
781                                 case 'backgroundPosition' :
782                                         var x   = me( p + 'X' ),
783                                                 y   = me( p + 'Y' ),
784                                                 ret = new PropertyGroup( p, x, y ),
785                                                 xy;
786                                         if( ret.isValid() === true ) return ret;
787                                         ret.kill();
788                                         xy = css[ p ].split( ' ' );
789                                         x  = XDomStyle._splitValueAndUnit( xy[ 0 ] );
790                                         y  = XDomStyle._splitValueAndUnit( xy[ 1 ] );
791                                         return
792                                                 new PropertyGroup(
793                                                         p,
794                                                         new Property( p + 'X', x[ 0 ], x[ 1 ], xnode ),
795                                                         new Property( p + 'Y', y[ 0 ], y[ 1 ], xnode )
796                                                 );
797                         };
798                         // opacity, zindex, lineHeight
799                         vu = XDomStyle._splitValueAndUnit( css[ p ] );
800                         return new Property( p, vu[ 0 ], vu[ 1 ], xnode );
801                 };
802                 var x = css[ p ], e, v, u;
803                 /*
804                 if( PARAMS.offset[ p ] === true ){
805                         return new Property( p, vu[ 0 ], vu[ 1 ], xnode );
806
807                         e = this.elm;
808                         if( p === 'width'  ) v = e.offsetWidth;
809                         if( p === 'height' ) v = e.offsetHeight;
810                         if( p === 'top'    ) v = e.offsetTop;
811                         if( p === 'bottom' ) v = e.offsetBottom;
812                         if( p === 'left'   ) v = e.offsetLeft;
813                         if( p === 'right'  ) v = e.offsetRight;
814                         u = _getUnit( x, p );
815                         // alert( p + XDomStyle._Util.pxTo( v, u ) + u )
816                         return new Property( p, XDomStyle._Util.pxTo( v, u ), u, xnode );
817                 }; */
818                 if( p === 'fontSize' && ( v = XDomStyle._FONT_SIZE_RATIO[ x ] ) ){ // xx-small 等
819                         return new Property( p, v, 'px', xnode );
820                 };
821                 if( PARAMS.offset[ p ] || PARAMS.percent[ p ] || PARAMS.size[ p ] ){
822                         vu = XDomStyle._splitValueAndUnit( x );
823                         return new Property( p, vu[ 0 ], vu[ 1 ], xnode );
824                 };
825
826                 if( PARAMS.color[ p ] ) return new ColorProperty( p, x );
827         },
828         
829         _splitValueAndUnit : function( v ){
830                 var num, _num, u;
831                 if( X.Type.isNumber( v ) ) return [ v || 0, '' ];
832                 if( isNaN( num = parseFloat( v ) ) ) return [ 0, '' ];
833                 _num = '' + num;
834                 if( _num.indexOf( '0.' ) === 0 ) _num = _num.slice( 1 );
835                 u = v.substr( v.indexOf( _num ) + _num.length );
836                 return [ num, X.Dom.Style.UNIT[ u ] ? u : 'px' ];
837         }
838 };
839
840 X.Dom.Style._GET_VALUE_WITH_UNIT = {
841         borderWidth  : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH,
842         //borderStyle  : X.Dom.Style.Type.QUARTET,
843         borderRadius : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH,
844         margin       : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH  | X.Dom.Style.Type.PERCENT,
845         padding      : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH  | X.Dom.Style.Type.PERCENT,
846         clip         : X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH  | X.Dom.Style.Type.PERCENT,
847         
848         backgroundColor    : X.Dom.Style.Type.COLOR,
849         backgroundPosition : X.Dom.Style.Type.COMBI,
850         
851         // boxShadow
852         
853         fontSize      : X.Dom.Style.Type.LENGTH,
854         lineHeight    : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT | X.Dom.Style.Type.NUMERICAL,
855         textIndent    : X.Dom.Style.Type.LENGTH,
856         letterSpacing : X.Dom.Style.Type.LENGTH,
857         wordSpacing   : X.Dom.Style.Type.LENGTH,
858         /*
859         textShadowColor   : X.Dom.Style.Type.COLOR,
860         textShadowOffsetX : X.Dom.Style.Type.LENGTH,
861         textShadowOffsetY : X.Dom.Style.Type.LENGTH,
862         textShadowBlur    : X.Dom.Style.Type.LENGTH, */
863         
864         width         : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
865         height        : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
866         
867         left          : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
868         top           : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
869         bottom        : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
870         right         : X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT,
871         
872         // table
873         borderSpacing : X.Dom.Style.Type.LENGTH
874 };
875
876         
877 X.Dom.Style.SPECIAL_FIX =
878         // ~IE8
879         X.UA.IE && X.UA.IE < 9 && !X.UA.MacIE?
880                 (function( obj ){
881                         var test    = X.Dom.Style.SPECIAL_FIX_PROP,
882                                 filters = [],
883                                 n       = -1,
884                                 p, id, v, dir;
885                         for( p in obj ){
886                                 if( !( id = test[ p ] ) ) continue;
887                                 v = obj[ p ];
888                                 switch( id ){
889                                         case 1 : //'filter' :
890                                                 filters[ ++n ] = v;
891                                                 break;
892                                         case 2 : //'opacity' :
893                                                 filters[ ++n ] = 'alpha(opacity=' + v * 100 +')';
894                                                 break;
895                                         case 3 : //'boxShadow' :
896                                                 // box-shadow: 10px 10px 10px 10px rgba(0,0,0,0.4) inset;
897                                                 // スペース区切りで、水平方向の距離 垂直方向の距離 ぼかし距離 広がり距離 影の色 insetキーワードを指定する。 ぼかし距離 広がり距離 影の色 insetキーワードは省略可
898                                                 // shadow(color=#cccccc, strength=10, direction=135);
899                                                 v = X.Dom.Style._getProperty( this, css, 'px', 'boxShadow' );
900                                                 dir = Math.atan2( v[ 1 ], v[ 0 ] ) * 180 / Math.PI + 90;
901                                                 dir += dir < 0 ? 360 : 0;
902                                                 filters[ ++n ] = 'shadow(color=' + v[ 4 ] + ',strength=' + v[ 3 ] + ',direction=' + dir + ')';
903                                                 break;
904                                         case 4 : //'textShadow' :
905                                                 //text-shadow: 5px 5px 2px blue; 水平方向の距離 垂直方向の距離 影のぼかし半径 影の色 none
906                                                 //glow(Color=yellow,Strength=10);
907                                                 //どうやらCSSのbackgroundプロパティと同時に使えないようです。 
908                                                 
909                                                 
910                                                 break;
911                                         case 5 : //'backgroundImage' :
912                                                 //
913                                 };
914                         };
915                         return filters.join( ' ' );
916                 }) :
917         // IE9 textShadow に filter を使用
918         X.UA.IE && 9 <= X.UA.IE && X.UA.IE < 10 ?
919                 (function( obj ){
920                         var test    = X.Dom.Style.SPECIAL_FIX_PROP,
921                                 filters = [], p, id, v;
922                         for( p in obj ){
923                                 if( !( id = test[ p ] ) ) continue;
924                                 v = obj[ p ];
925                                 switch( id ){
926                                         case 1 : //'filter' :
927                                                 filters[ filters.length ] = v;
928                                                 break;
929                                 };
930                         };
931                         if( filters ) return filters.join( ' ' );
932                 }) :
933                 (function( obj ){
934                         var test    = X.Dom.Style.SPECIAL_FIX_PROP,
935                                 ret = [], p, id, v, bgpX, bgpY, clipT, clipB, clipL, clipR;
936                         for( p in obj ){
937                                 if( !( id = test[ p ] ) ) continue;
938                                 v = obj[ p ];
939                                 switch( id ){
940                                         case 1 : //'backgroundPositionX' :
941                                                 bgpX = v;
942                                                 break;
943                                         case 2 : //'backgroundPositionY' :
944                                                 bgpY = v;
945                                                 break;
946                                         case 3 : //'backgroundPositionX' :
947                                                 clipT = v;
948                                                 break;
949                                         case 4 : //'backgroundPositionX' :
950                                                 clipB = v;
951                                                 break;
952                                         case 5 : //'backgroundPositionX' :
953                                                 clipL = v;
954                                                 break;
955                                         case 6 : //'backgroundPositionX' :
956                                                 clipR = v;
957                                                 break;
958                                 };
959                         };
960                         if( bgpX || bgpY ) ret[ ret.length ] = 'background-position:';
961                         if( clipT || clipB || clipL || clipR ){
962                                 ret[ ret.length ] = 'clip:rect(';
963                         };
964                         return ret.join( ';' );
965                 });
966
967
968
969
970 // export
971 // name getter
972 // unitID, name 単位指定のプロパティ取得 geter
973 // obj setter
974 // name, value setter
975
976 X.Dom.Node.prototype.css = function( nameOrObj /* orUnitID, valuOrUnitOrName */ ){
977         var XDomStyle = X.Dom.Style,
978                 args = arguments,
979                 css  = this._css,
980                 p, name, v, camelize, unit, ieFix;
981         if( this._xnodeType !== 1 ) return this;
982 // setter:object
983         if( X.Type.isObject( nameOrObj ) ){
984                 if( !css ) css = this._css = {};
985                 camelize = XDomStyle.camelize;
986                 ieFix    = X.Dom.Style.IE_FILTER_FIX;
987                 for( p in nameOrObj ){
988                         if( ieFix[ p ] ){
989                                 this._dirty |= X.Dom.Dirty.IE_FILTER;
990                         };
991                         v = nameOrObj[ p ];
992                         v || v === 0 ? css[ camelize( p ) ] = v : delete css[ camelize( p ) ];
993                         if( p === 'display' ){
994                                 v === 'none' ? ( this._state |= X.Dom.State.IE5_DISPLAY_NONE_FIX ) : ( this._state &= ~X.Dom.State.IE5_DISPLAY_NONE_FIX );
995                                 v === 'none' ? ( this._state |= X.Dom.State.DISPLAY_NONE ) : ( this._state &= ~X.Dom.State.DISPLAY_NONE );
996                         };
997                 };
998                 this._dirty |= X.Dom.Dirty.CSS;
999                 this.parent && this._reserveUpdate();
1000                 delete this._cssText;
1001                 return this;
1002         } else
1003         if( 1 < args.length ){
1004                 if( !XDomStyle.UNIT[ nameOrObj ] ){
1005 // setter name, value
1006                         if( !css ) css = this._css = {};
1007                         name = XDomStyle.camelize( nameOrObj );
1008                         v    = args[ 1 ];
1009                         if( css[ name ] === v ) return this;
1010                         if( X.Dom.Style.IE_FILTER_FIX[ name ] ){
1011                                 this._dirty |= X.Dom.Dirty.IE_FILTER;
1012                         };
1013                         if( !v && v !== 0 ){
1014                                 delete css[ name ];
1015                         } else {
1016                                 css[ name ] = v;
1017                         };
1018                         delete this._cssText;
1019                         this._dirty |= X.Dom.Dirty.CSS;
1020                         if( name === 'display' ){
1021                                 v === 'none' ? ( this._state |= X.Dom.State.IE5_DISPLAY_NONE_FIX ) : ( this._state &= ~X.Dom.State.IE5_DISPLAY_NONE_FIX );
1022                                 v === 'none' ? ( this._state |= X.Dom.State.DISPLAY_NONE ) : ( this._state &= ~X.Dom.State.DISPLAY_NONE );
1023                         };
1024                         // parent でなく this._root! でなくて this._state & in tree
1025                         this.parent && this._reserveUpdate();
1026                         return this;
1027                 };
1028 // getter unit
1029 // unit 付の値取得は fontSize と 画像サイズが確定していないと正確に取れない。内部のみにする?
1030                 if( !css ) return;
1031                 if( !XDomStyle._GET_VALUE_WITH_UNIT[ name = XDomStyle.camelize( args[ 1 ] ) ] ) return null;
1032                 p = XDomStyle._getProperty( this, css, nameOrObj, name );
1033                 v = p.pxTo( nameOrObj );
1034                 p.kill();
1035                 return v;
1036         };
1037 // getter
1038         if( !css ) return;
1039         // 集計 border, padding, margin, backgroundPosition, clip
1040         // border で正確なデータを返せない時は、null を返す
1041         return css[ XDomStyle.camelize( nameOrObj ) ];
1042 };
1043
1044 X.Dom.Node.prototype.cssText = function( v ){
1045         var obj, i, l, attr, name;
1046         if( v === '' ){
1047                 delete this._css;
1048                 this._state &= ~X.Dom.State.IE5_DISPLAY_NONE_FIX;
1049                 this._dirty |= X.Dom.Dirty.CSS;
1050                 this.parent && this._reserveUpdate();
1051                 delete this._cssText;
1052                 return this;
1053         } else
1054         if( X.Type.isString( v ) ){
1055                 delete this._css;
1056                 this._state &= ~X.Dom.State.IE5_DISPLAY_NONE_FIX;
1057                 obj = {};
1058                 v   = v.split( ';' ); // TODO content ";" などにも対応
1059                 for( i = 0, l = v.length; i < l; ++i ){
1060                         attr = v[ i ].split( ':' );
1061                         ( name = attr[ 0 ] ) && ( obj[ name ] = attr[ 1 ] || true );
1062                 };
1063                 return this.css( obj );
1064         };
1065         // getter
1066         if( this._dirty & X.Dom.Dirty.CSS && !( this._cssText = X.Dom.Style.objToCssText( this._css ) ) ){
1067                 delete this._cssText;
1068         };
1069         return this._cssText;
1070 };
1071
1072 /*
1073  * ここでは HTMLElement のチ1ェックは行わない!
1074  * TODO
1075  * body に css attr がセットされた場合には X.Dom.baseFontSize をクリア
1076  */
1077
1078 X.Dom.Node.prototype._getCharSize =
1079         window.getComputedStyle ?
1080                 (function(){
1081                         Node._body._updateTimerID && Node._body._startUpdate();
1082                         if( this === Node._body && X.Dom.baseFontSize ) return X.Dom.baseFontSize;
1083                         if( this._fontSize ) return this._fontSize;
1084                         return this._fontSize = parseFloat( getComputedStyle( this._rawObject, null ).fontSize );
1085                 }) :
1086
1087         document.defaultView && document.defaultView.getComputedStyle ?
1088                 (function(){
1089                         Node._body._updateTimerID && Node._body._startUpdate();
1090                         if( this === Node._body && X.Dom.baseFontSize ) return X.Dom.baseFontSize;
1091                         if( this._fontSize ) return this._fontSize;
1092                         return this._fontSize = parseFloat( document.defaultView.getComputedStyle( this._rawObject, null ).fontSize );
1093                 }) :
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103         5.5 <= X.UA.IE ?
1104                 (function(){
1105                         var font, vu, v, u, _v;
1106                         Node._body._updateTimerID && Node._body._startUpdate();
1107                         if( this === Node._body && X.Dom.baseFontSize ) return X.Dom.baseFontSize;
1108                         if( this._fontSize ) return this._fontSize;
1109                         
1110                         font = this._rawObject.currentStyle.fontSize;
1111                         //font = this._css && this._css.fontSize || '1em';
1112                         vu   = X.Dom.Style._splitValueAndUnit( font );
1113                         v    = vu[ 0 ];
1114                         u    = vu[ 1 ];
1115
1116                         if( v === 0 ){
1117                                 if( v = X.Dom.Style._FONT_SIZE_RATIO[ font ] ) return this._fontSize = v;
1118                         } else {
1119                                 if( _v = X.Dom.Style._UNIT_RATIO[ u ] ) return this._fontSize = v / _v;
1120                         };
1121                         switch( u ){
1122                                 case 'px' :
1123                                         return this._fontSize = v;
1124                                 case 'em' :
1125                                 // body まで辿ってしまった場合は?
1126                                         if( this.parent ) return this._fontSize = this.parent._getCharSize() * v;
1127                                         break;
1128                                 case '%' :
1129                                 // body まで辿ってしまった場合は?
1130                                         if( this.parent ) return this._fontSize = this.parent._getCharSize() * v / 100;
1131                         };
1132                         return 0;
1133                 }) :
1134         X.Dom.DOM_W3C ?
1135                 (function(){
1136                         var elm, v;
1137                         Node._body._updateTimerID && Node._body._startUpdate();
1138                         if( this === Node._body && X.Dom.baseFontSize ) return X.Dom.baseFontSize;
1139                         if( this._fontSize ) return this._fontSize;
1140
1141                         this._rawObject.appendChild( elm = document.createElement( 'span' ) );
1142                         elm.style.cssText = 'display:block;position:absolute;top:0;left:0;visivility:hidden;line-height:1;height:1em;';
1143                         elm.innerHTML = 'X';
1144                         v = elm.offsetHeight;
1145                         this._rawObject.removeChild( elm );
1146                         return this._fontSize = v;
1147                 }) :
1148         X.Dom.DOM_IE4 ?
1149                 (function(){
1150                         var font, vu, v, u, _v;
1151                         Node._body._updateTimerID && Node._body._startUpdate();
1152                         if( this === Node._body && X.Dom.baseFontSize ) return X.Dom.baseFontSize;
1153                         if( this._fontSize ) return this._fontSize;
1154                         
1155                         if( this._css && ( font = this._css.fontSize ) ){
1156                                 vu = X.Dom.Style._splitValueAndUnit( font );
1157                                 v  = vu[ 0 ];
1158                                 u  = vu[ 1 ];
1159                                 
1160                                 if( v === 0 ){
1161                                         if( _v = X.Dom.Style._FONT_SIZE_RATIO[ font ] ) return this._fontSize = _v;
1162                                 } else {
1163                                         if( _v = X.Dom.Style._UNIT_RATIO[ u ] ) return this._fontSize = v / _v;
1164                                 };
1165                         } else {
1166                                 v = 1;
1167                                 u = 'em';
1168                         };
1169
1170                         switch( u ){
1171                                 case 'px' :
1172                                         return this._fontSize = v;
1173                                 case 'em' :
1174                                 // body まで辿ってしまった場合は?
1175                                         if( this.parent ) return this._fontSize = this.parent._getCharSize() * v;
1176                                         break;
1177                                 case '%' :
1178                                 // body まで辿ってしまった場合は?
1179                                         if( this.parent ) return this._fontSize = this.parent._getCharSize() * v / 100;
1180                         };
1181                         return 0;
1182                 }) :
1183                 (function(){
1184                         var elm, v;
1185                         if( this === Node._body && X.Dom.baseFontSize ) return X.Dom.baseFontSize;
1186                         Node._body._updateTimerID && Node._body._startUpdate();
1187                         if( this._fontSize ) return this._fontSize;
1188                         
1189                         elm = this._rawObject || this._ie4getRawNode();
1190                         elm.insertAdjacentHTML( 'BeforeEnd', '<span style="visivility:hidden;line-height:1;">X</span>' );
1191                         elm = elm.children[ elm.children.length - 1 ];
1192                         v   = elm.offsetHeight;
1193                         elm.outerHTML = '';
1194                         return this._fontSize = v * 0.75;
1195                 });
1196
1197
1198 ( function(){
1199         var testStyle = X.UA.IE4 ? {} : ( document.documentElement || document.createElement( 'div' ) ).style,
1200                 temp      = testStyle.cssText,
1201                 prefix    = X.Dom.Style.VENDER_PREFIX,
1202                 vendors   = 'webkit,Webkit,Moz,moz,Ms,ms,O,o,khtml,Khtml'.split( ',' ),
1203                 searches  = (
1204                         'opacity,boxSizing,' +
1205                         'transform,transformOrigin,perspective,' +
1206                         'transisiton,transitionDelay,transitionProperty,transitionDuration,transitionTimingFunction,' +
1207                         'userSelect,touchSelect,touchAction,touchCallout,contentZooming,userDrag,tapHighlightColor' ).split( ',' ),
1208                 vendor, i, search, prop, j, v;
1209
1210         for( i = searches.length; i; ){
1211                 search = prop = searches[ --i ];
1212                 
1213                 if( testStyle[ prop ] === undefined ){
1214                         prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 );
1215                         for( j = vendors.length; j; ){
1216                                 v = vendors[ --j ];
1217                                 if( testStyle[ v + prop ] !== undefined ){
1218                                         if( v === 'ms' ) v = 'Ms';// for ie9
1219                                         if( v === 'o' ) v = 'O';//for opera12
1220                                         prefix[ search ] = v + prop;
1221                                         break;
1222                                 };
1223                         };                              
1224                 } else {
1225                         prefix[ search ] = prop;
1226                 };
1227         };
1228         
1229         testStyle.cssText = 'background:rgba(0,0,0,0.5)';
1230         
1231         X.Dom.Style.Support = {
1232                 rgba : !!testStyle.background
1233         };
1234         
1235         testStyle.cssText = temp;
1236         
1237         X.Dom.Style.SPECIAL_FIX_PROP =
1238                 // ~IE8
1239                 X.UA.IE < 9 && !X.UA.MacIE ?
1240                         {
1241                                 filter          : 1,
1242                                 opacity         : 2//, uinode ChromeNode で行う
1243                                 //boxShadow       : 3,
1244                                 //textShadow      : 4,
1245                                 //backgroundImage : 5
1246                         } :
1247                 // IE9
1248                 9 <= X.UA.IE && X.UA.IE < 10 ?
1249                         {
1250                                 filter          : 1//,
1251                                 //textShadow      : 1
1252                         } :
1253                 {
1254                         backgroundPositionX : testStyle.backgroundPositionX === undefined ? 3 : 0,
1255                         backgroundPosiitonY : testStyle.backgroundPositionX === undefined ? 3 : 0,
1256                         clipTop             : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 3 : 0,
1257                         clipBottom          : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 4 : 0,
1258                         clipLeft            : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 5 : 0,
1259                         clipRight           : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 6 : 0
1260                 };
1261 } )();
1262
1263 X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
1264         var xnode  = Node._systemNode,
1265                 output = X.Dom.Style._UNIT_RATIO = {},
1266                 list   = 'cm,mm,in,pt,pc'.split( ',' ),
1267                 unit,size, base, i;
1268         
1269         for( i = list.length; i; ){
1270                 unit = list[ --i ];
1271                 output[ unit ] = xnode.css( 'width', 10 + unit ).width() / 10;
1272         };
1273
1274         output = X.Dom.Style._FONT_SIZE_RATIO = {},
1275         list   = 'xx-large,x-large,large,larger,medium,small,smaller,x-small,xx-small'.split( ',' );
1276         xnode.css( { lineHeight : '100%', height : '1em' } ).text( 'X' );
1277         
1278         for( i = list.length; i; ){
1279                 size = list[ --i ];
1280                 output[ size ] = xnode.css( 'fontSize', size ).height();// / base;
1281         };
1282         
1283         xnode.cssText( '' ).empty();
1284 } );
1285