OSDN Git Service

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