OSDN Git Service

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