OSDN Git Service

Version 0.6.12.
[pettanr/clientJs.git] / 0.6.x / js / dom / 13_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         SPECIAL_VALUES : {
30                 AUTO : Number.POSITIVE_INFINITY,
31                 FULL : X.Dom // something unigue value; 100%
32         },
33         
34         PropNo : {},
35         
36         UNIT : {
37                 'px' : 0,
38                 'em' : 1,
39                 'cm' : 2,
40                 'mm' : 3,
41                 'in' : 4,
42                 '%'  : 5,
43                 'pct' : 5,
44                 'ms'  : 6,
45                 's'   : 7,
46                 '#'   : 8,
47                 'rgb' : 9,
48                 'rgba' : 10
49         },
50         
51         /* font-size -> fontSize */
52         _DICTIONARY_CAMELIZE : {},
53         
54         camelize : function( cssProp ){
55                 var me  = X.Dom.Style,
56                         parts, l, i, camelized;
57                 
58                 if( camelized = me._DICTIONARY_CAMELIZE[ cssProp ] ) return camelized;
59                 parts = cssProp.split( ' ' ).join( '' ).split( '-' );
60                 l     = parts.length;
61                 if( l === 1 ) return parts[ 0 ];
62                 
63                 camelized = cssProp.charAt(0) === '-'
64                   ? parts[ 0 ].charAt( 0 ).toUpperCase() + parts[ 0 ].substring( 1 )
65                   : parts[ 0 ];
66                 
67                 for( i = 1; i < l; ++i ){
68                         camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 );
69                 };
70                 return me._DICTIONARY_CAMELIZE[ cssProp ] = camelized;
71         },
72         
73         /* fontSize -> font-size */
74         /*
75         REG_LARGE : /[A-Z]/g,
76         uncamelize: function( str ){
77                 return str.split( ' ' ).join( '' ).replace( X.Dom.Style.REG_LARGE, '-$&' ).toLowerCase();
78         }, */
79         
80         CHAR_CODE_A : 'A'.charCodeAt( 0 ),
81         
82         _DICTIONARY_UNCAMELIZE : {},
83         
84         uncamelize : function( str ){
85                 var me  = X.Dom.Style,
86                         A   = me.CHAR_CODE_A,
87                         Z   = A + 25,
88                         uncamelized, l, chr, code;
89                 str = str.split( ' ' ).join( '' );
90                 if( uncamelized = me._DICTIONARY_UNCAMELIZE[ str ] ) return uncamelized;
91                 uncamelized = '';
92                 for( i = 0, l = str.length; i < l; ++i ){
93                         chr = str.charAt( i );
94                         code = chr.charCodeAt( 0 );
95                         uncamelized += ( A <= code && code <= Z ) ? '-' + chr : chr;
96                 };
97                 return me._DICTIONARY_UNCAMELIZE[ str ] = uncamelized.toLowerCase();
98         },
99         
100         objToCssText : function( obj ){
101                 var css           = [],
102                         me            = X.Dom.Style,
103                         uncamelize    = me.uncamelize,
104                         VENDER_PREFIX = me.VENDER_PREFIX,
105                         FIX_PROP      = me.SPECIAL_FIX_PROP,
106                         SPECIAL_FIX   = me.SPECIAL_FIX,
107                         p, name, sp;
108                 for( p in obj ){
109                         name = uncamelize( p );
110                         if( FIX_PROP[ name ] ){
111                                 sp = 1;
112                         } else {
113                                 css[ css.length ] = [ VENDER_PREFIX[ name ] || name, obj[ p ] ].join( ':' );
114                         };
115                 };
116                 sp && ( css[ css.length ] = SPECIAL_FIX( obj ) );
117                 return css.join( ';' );
118         },
119         
120         _FONT_SIZE_RATIO : {},
121         
122         absoluteFontSizeToPx : function( fontsize ){
123                 return X.Dom.Style._FONT_SIZE_RATIO[ fontsize ] || 0;
124         }
125
126         //  https://developer.mozilla.org/en-US/docs/Web/CSS/transform
127         //  Firefox 3.5, ie9, Opera 10.5, Safari 3.1, Chrome
128         //  3D support Firefox 10, ie10, Safari 4.0, Chrome 12.0
129         // transform : void 0,
130         
131         //  https://developer.mozilla.org/ja/docs/Web/Guide/CSS/Using_CSS_transitions
132         //  Chrome 1.0, Firefox 4.0, ie10, Opera 10.5, Safari 3.2
133         //  Android 2.1, Firefox Android 4.0, Opera Mobile 10, Safari Mobile 3.2        
134         // transition : void 0
135 };
136
137 X.Dom.Style.Option = {
138         BORDER_STYLE      : 'none,hidden,dotted,dashed,solid,double,groove,ridge,inset,outset'.split(','),
139         POSITION_X        : 'left,center,right'.split(','),
140         POSITION_Y        : 'top,center,bottom'.split(','),
141         ALIGN             : 'left,center,right,justify'.split(','),
142         TEXT_DECORATION   : 'none,underline,overline,line-through,blink'.split(','),
143         TEXT_TRANSFORM    : 'none,capitalize,lowercase,uppercase'.split(','),
144         WIDTH_HEIGHT      : [ 'auto' ],
145         BOX_SIZING        : 'content-box,padding-box,border-box'.split(',') // ,margin-box
146 };
147 X.Dom.Style.Props = {
148         borderWidth       : [ X.Dom.Dirty.REFLOW,  0, X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH  ], // em [ top, right, bottom, left ]
149         borderColor       : [ X.Dom.Dirty.PAINT,   4, X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.COLOR   ], // color [ top, right, bottom, left ]
150         borderStyle       : [ X.Dom.Dirty.PAINT,   8, X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LIST, X.Dom.Style.Option.BORDER_STYLE ], // string [ top, right, bottom, left ]
151         cornerRadius      : [ X.Dom.Dirty.PAINT,  12, X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ], // em, px [ top, right, bottom, left ]
152         bgColor           : [ X.Dom.Dirty.PAINT,  16, X.Dom.Style.Type.COLOR     ], // color
153         bgAlpha           : [ X.Dom.Dirty.PAINT,  17, X.Dom.Style.Type.U_DECIMAL ], // 0 - 1
154         bgImgUrl          : [ X.Dom.Dirty.PAINT,  18, X.Dom.Style.Type.URL       ], // url
155         bgImgRepeatX      : [ X.Dom.Dirty.PAINT,  19, X.Dom.Style.Type.BOOLEAN   ], // true / false
156         bgImgRepeatY      : [ X.Dom.Dirty.PAINT,  20, X.Dom.Style.Type.BOOLEAN   ], // true / false
157         bgImgPositionX    : [ X.Dom.Dirty.PAINT,  21, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT | X.Dom.Style.Type.LIST, X.Dom.Style.Option.POSITION_X ], // em %, px, string
158         bgImgPositionY    : [ X.Dom.Dirty.PAINT,  22, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT | X.Dom.Style.Type.LIST, X.Dom.Style.Option.POSITION_Y ], // em %, px, string
159         shadowColor       : [ X.Dom.Dirty.PAINT,  23, X.Dom.Style.Type.COLOR     ], // color
160         shadowAlpha       : [ X.Dom.Dirty.PAINT,  24, X.Dom.Style.Type.U_DECIMAL ], // 0 - 1
161         shadowOffsetX     : [ X.Dom.Dirty.PAINT,  25, X.Dom.Style.Type.LENGTH    ], // em
162         shadowOffsetY     : [ X.Dom.Dirty.PAINT,  26, X.Dom.Style.Type.LENGTH    ], // em
163         shadowBlur        : [ X.Dom.Dirty.PAINT,  27, X.Dom.Style.Type.LENGTH    ], // em
164         shadowSpread      : [ X.Dom.Dirty.PAINT,  28, X.Dom.Style.Type.LENGTH    ], // em
165         shadowInset       : [ X.Dom.Dirty.PAINT,  29, X.Dom.Style.Type.BOOLEAN   ], // true / false
166         
167         color             : [ X.Dom.Dirty.PAINT,  30, X.Dom.Style.Type.COLOR     ], // color
168         fontFamily        : [ X.Dom.Dirty.FONT,   31, X.Dom.Style.Type.FONT_NAME ], // string
169         fontSize          : [ X.Dom.Dirty.FONT,   32, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ], // em, %
170         bold              : [ X.Dom.Dirty.FONT,   33, X.Dom.Style.Type.BOOLEAN   ], // true / false
171         italic            : [ X.Dom.Dirty.FONT,   34, X.Dom.Style.Type.BOOLEAN   ], // true / false
172         lineHeight        : [ X.Dom.Dirty.FONT,   35, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT | X.Dom.Style.Type.NUMERICAL ], // em, %, 
173         letterSpacing     : [ X.Dom.Dirty.FONT,   36, X.Dom.Style.Type.LENGTH    ], // em
174         wordSpacing       : [ X.Dom.Dirty.FONT,   37, X.Dom.Style.Type.LENGTH    ],
175         align             : [ X.Dom.Dirty.FONT,   38, X.Dom.Style.Type.LIST, X.Dom.Style.Type.ALIGN           ],
176         decoration        : [ X.Dom.Dirty.PAINT,  39, X.Dom.Style.Type.LIST, X.Dom.Style.Type.TEXT_DECORATION ],
177         transform         : [ X.Dom.Dirty.FONT,   40, X.Dom.Style.Type.LIST, X.Dom.Style.Type.TEXT_TRANSFORM  ],
178         textShadowColor   : [ X.Dom.Dirty.PAINT,  41, X.Dom.Style.Type.COLOR     ],
179         textShadowOffsetX : [ X.Dom.Dirty.PAINT,  42, X.Dom.Style.Type.LENGTH    ],
180         textShadowOffsetY : [ X.Dom.Dirty.PAINT,  43, X.Dom.Style.Type.LENGTH    ],
181         shadowBlur        : [ X.Dom.Dirty.PAINT,  44, X.Dom.Style.Type.LENGTH    ],
182         
183         width             : [ X.Dom.Dirty.REFLOW, 45, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT, X.Dom.Style.Option.WIDTH_HEIGHT ],
184         minWidth          : [ X.Dom.Dirty.REFLOW, 46, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
185         maxWidth          : [ X.Dom.Dirty.REFLOW, 47, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
186         height            : [ X.Dom.Dirty.REFLOW, 48, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT, X.Dom.Style.Option.WIDTH_HEIGHT ],
187         minHeight         : [ X.Dom.Dirty.REFLOW, 49, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
188         maxHeight         : [ X.Dom.Dirty.REFLOW, 50, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
189         padding           : [ X.Dom.Dirty.REFLOW, 51, X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
190         margin            : [ X.Dom.Dirty.REFLOW, 55, X.Dom.Style.Type.QUARTET | X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
191         sizing            : [ X.Dom.Dirty.REFLOW, 59, X.Dom.Style.Type.LIST, X.Dom.Style.Option.BOX_SIZING ],
192         pageBox           : [ X.Dom.Dirty.REFLOW, 60, X.Dom.Style.Type.BOOLEAN ], // true / false
193         left              : [ X.Dom.Dirty.REFLOW, 61, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
194         top               : [ X.Dom.Dirty.REFLOW, 62, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
195         bottom            : [ X.Dom.Dirty.REFLOW, 63, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ],
196         right             : [ X.Dom.Dirty.REFLOW, 64, X.Dom.Style.Type.LENGTH | X.Dom.Style.Type.PERCENT ]
197 };
198         
199 X.Dom.Style.SPECIAL_FIX =
200         // ~IE8
201         X.UA.IE && X.UA.IE < 9 ?
202                 (function( obj ){
203                         var test    = X.Dom.Style.SPECIAL_FIX_PROP,
204                                 filters = [], p, id, v;
205                         for( p in obj ){
206                                 if( !( id = test[ p ] ) ) continue;
207                                 v = obj[ p ];
208                                 switch( id ){
209                                         case 1 : //'filter' :
210                                                 filters[ filters.length ] = v;
211                                                 break;
212                                         case 2 : //'opacity' :
213                                                 filters[ filters.length ] = 'aplha(opacity=' + v +')';
214                                                 break;
215                                         case 3 : //'boxShadow' :
216                                                 // box-shadow: 10px 10px 10px 10px rgba(0,0,0,0.4) inset;
217                                                 // スペース区切りで、水平方向の距離 垂直方向の距離 ぼかし距離 広がり距離 影の色 insetキーワードを指定する。 ぼかし距離 広がり距離 影の色 insetキーワードは省略可
218                                                 // shadow(color=#cccccc, strength=10, direction=135);
219                                                 parseValue( 'boxShadow', v, 'px' );
220                                                 dir = Math.atan2( ary[1], ary[0] ) * 180 / Math.PI + 90;
221                                                 dir += dir < 0 ? 360 : 0;
222                                                 break;
223                                         case 4 : //'textShadow' :
224                                                 //text-shadow: 5px 5px 2px blue; 水平方向の距離 垂直方向の距離 影のぼかし半径 影の色 none
225                                                 //glow(Color=yellow,Strength=10);
226                                                 //どうやらCSSのbackgroundプロパティと同時に使えないようです。 
227                                                 break;
228                                         case 5 : //'backgroundImage' :
229                                                 //
230                                 };
231                         };
232                         if( filters ) return filters.join( ' ' );
233                 }) :
234         // IE9
235         X.UA.IE && 9 <= X.UA.IE && X.UA.IE < 10 ?
236                 (function( obj ){
237                         var test    = X.Dom.Style.SPECIAL_FIX_PROP,
238                                 filters = [], p, id, v;
239                         for( p in obj ){
240                                 if( !( id = test[ p ] ) ) continue;
241                                 v = obj[ p ];
242                                 switch( id ){
243                                         case 1 : //'filter' :
244                                                 filters[ filters.length ] = v;
245                                                 break;
246                                 };
247                         };
248                         if( filters ) return filters.join( ' ' );
249                 }) :
250                 (function( obj ){
251                         var test    = X.Dom.Style.SPECIAL_FIX_PROP,
252                                 ret = [], p, id, v;
253                         for( p in obj ){
254                                 if( !( id = test[ p ] ) ) continue;
255                                 v = obj[ p ];
256                                 switch( id ){
257                                         case 1 : //'backgroundPositionX' :
258                                                 bgpX = v;
259                                                 break;
260                                         case 2 : //'backgroundPositionY' :
261                                                 bgpY = v;
262                                                 break;
263                                         case 3 : //'backgroundPositionX' :
264                                                 clipT = v;
265                                                 break;
266                                         case 4 : //'backgroundPositionX' :
267                                                 clipB = v;
268                                                 break;
269                                         case 5 : //'backgroundPositionX' :
270                                                 clipL = v;
271                                                 break;
272                                         case 6 : //'backgroundPositionX' :
273                                                 clipR = v;
274                                                 break;
275                                 };
276                         };
277                         if( bgpX || bgpY ) ret[ ret.length ] = 'background-position:';
278                         if( clipT || clipB || clipL || clipR ){
279                                 ret[ ret.length ] = 'clip:rect(';
280                         };
281                         return ret.join( ';' );
282                 });
283
284
285
286
287 // export
288 // name getter
289 // unitID, name 単位指定のプロパティ取得 geter
290 // obj setter
291 // name, value setter
292 X.Dom.Node.prototype.css = function( nameOrObj /* orUnitID, valuOrUnitOrName */ ){
293         var XDomStyle = X.Dom.Style,
294                 args = arguments,
295                 css  = this._css,
296                 p, valOrUnit, name, v, node, camelize;
297         if( this._nodeType !== 1 ) return this;
298         // setter
299         if( X.Type.isObject( nameOrObj ) ){
300                 if( !css ) css = this._css = {};
301                 camelize = XDomStyle.camelize;
302                 for( p in nameOrObj ){
303                         css[ camelize( p ) ] = nameOrObj[ p ];
304                 };
305                 this._cssText = XDomStyle.objToCssText( this._css );
306                 if( node = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode ){
307                         if( this._cssText ){
308                                 node.style.cssText = this._cssText;
309                         } else {
310                                 node.removeAttribute( 'style' );
311                         };
312                 };
313                 return this;
314         } else
315         if( 1 < args.length && !XDomStyle.UNIT[ nameOrObj ] ){
316                 if( !css ) css = this._css = {};
317                 name = XDomStyle.camelize( nameOrObj );
318                 v    = args[ 1 ];
319                 if( css[ name ] === v ) return this;
320                 if( node = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode ){
321                         node.style[ name ] = v; // val
322                 };
323                 if( !css[ name ] ){
324                         this._cssText = [ this._cssText, this._cssText ? ';' : '', XDomStyle.uncamelize( nameOrObj ), ':', v ].join( '' );
325                         css[ name ] = v;
326                 } else {
327                         css[ name ] = v;
328                         // build _cssText
329                         this._cssText = XDomStyle.objToCssText( css );
330                 };
331                 node && !this._cssText && node.removeAttribute( 'style' );
332                 return this;
333         };
334         // getter
335         if( !css ) return;
336         if( 1 < args.length && XDomStyle.UNIT[ nameOrObj ] ){ // unit
337                 // To do
338                 return XDomStyle.getValue( this, args[ 1 ], name );
339         };
340         // 集計 border, padding, margin, backgroundPosition, clip
341         // border で正確なデータを返せない時は、null を返す
342         return css[ XDomStyle.camelize( nameOrObj ) ];
343 };
344
345 X.Dom.Node.prototype.cssText = function( v ){
346         var camelize, obj, i, l, attr, name;
347         if( X.Type.isString( v ) ){
348                 camelize = X.Dom.Style.camelize;
349                 obj = {};
350                 v   = v.split( ';' );
351                 delete this._css;
352                 for( i = 0, l = v.length; i < l; ++i ){
353                         attr = v[ i ].split( ':' );
354                         name = camelize( attr[ 0 ] );
355                         name && ( obj[ name ] = attr[ 1 ] || true );
356                 };
357                 return this.css( obj );
358         };
359         return this._cssText;
360 };
361
362 X.Dom.Node.prototype._getCharSize =
363         document.defaultView && document.defaultView.getComputedStyle ?
364                 (function(){
365                         document.defaultView.getComputedStyle( this._rawNode, null );
366                 }) :
367         X.UA.IE && 5 <= X.UA.IE ?
368                 (function(){
369                         //this._rawNode.currentStyle;
370                 }) :
371         document.removeChild ?
372                 (function(){
373                         
374                 }) :
375                 (function(){
376                         
377                 });
378
379 X.Dom.listenOnce( X.Dom.Event.DOM_PREINIT, function(){
380         
381         var testStyle = X.Dom._view;
382         
383         X.Dom.Style.VENDER_PREFIX = (function(){
384                 var ret       = {},
385                         vendors   = ',webkit,Webkit,Moz,moz,ms,Ms,O,o,khtml,Khtml'.split( ',' ),
386                         searches  =
387                                 'opacity,boxSizing,' +
388                                 'transform,transformOrigin,perspective,' +
389                                 'transisiton,transitionDelay,transitionProperty,transitionDuration,transitionTimingFunction,' +
390                                 'userSelect,touchAction,touchCallout,contentZooming,userDrag,tapHighlightColor'.split( ',' ),
391                         vendor, i, search, prop;
392                         
393                 function findVenderPrefix( prop ){
394                         var v, i = vendors.length;
395                         vendor = null;
396                         for( ; i; ){
397                                 v = vendors[ --i ];
398                                 if( testStyle[ v + prop ] !== undefined ){
399                                         vendor = v;
400                                         return v + prop;
401                                 };
402                         };      
403                 };
404                 
405                 for( i = searches.length; i; ){
406                         search = searches[ --i ];
407                         prop = findVenderPrefix( search );
408                         if( search === 'transform' ) ret.transVender = vendor;
409                         if( prop ) ret[ search ] = prop;
410                 };
411                 return ret;
412         })();
413                 
414         X.Dom.Style.SPECIAL_FIX_PROP =
415                 // ~IE8
416                 X.UA.IE && X.UA.IE < 9 ?
417                         {
418                                 filter          : 1,
419                                 opacity         : 2//, uinode ChromeNode で行う
420                                 //boxShadow       : 3,
421                                 //textShadow      : 4,
422                                 //backgroundImage : 5
423                         } :
424                 // IE9
425                 X.UA.IE && 9 <= X.UA.IE && X.UA.IE < 10 ?
426                         {
427                                 filter          : 1//,
428                                 //textShadow      : 1
429                         } :
430                 {
431                         backgroundPositionX : testStyle.backgroundPositionX === undefined ? 3 : 0,
432                         backgroundPosiitonY : testStyle.backgroundPositionX === undefined ? 3 : 0,
433                         clipTop             : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 3 : 0,
434                         clipBottom          : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 4 : 0,
435                         clipLeft            : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 5 : 0,
436                         clipRight           : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 6 : 0
437                 };
438 } );
439
440 X.Dom.listenOnce( X.Dom.Event.DOM_INIT, function(){
441         var xnode = Node._systemNode;
442
443         var ret = X.Dom.Style._UNIT_RATIO = {},
444                 unit,
445                 units = 'em,cm,mm,in,pt,pc'.split( ',' ),
446                 i     = units.length;
447         
448         for( ; i; ){
449                 unit = units[ --i ];
450                 xnode.css( 'width', 100 + unit );
451                 ret[ unit ] = xnode.width() / 100;
452                 console.log( unit + ':' + ret[ unit ] );
453         };
454         xnode.css( 'width', '' );
455
456         var ret = X.Dom.Style._FONT_SIZE_RATIO = {},
457                 size, base,
458                 list = 'xx-large,x-large,large,larger,medium,small,smaller,x-small,xx-small'.split( ',' ),
459                 i = list.length;
460         
461         base = xnode.css( 'lineHeight', 1 ).text( 'X' ).height();
462         for( ; i; ){
463                 size = list[ --i ];
464                 ret[ size ] = xnode.css( 'fontSize', size ).height() / base;
465                 console.log( size + ':' + ( ret[ size ] * 100 | 0 ) + '%' );
466         };
467         
468         xnode.empty().cssText( '' );
469 } );