OSDN Git Service

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