Upgrade to ExtJS 3.1.0 - Released 12/16/2009
[extjs.git] / docs / source / Element.style.html
1 <html>\r
2 <head>\r
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    \r
4   <title>The source code</title>\r
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
7 </head>\r
8 <body  onload="prettyPrint();">\r
9     <pre class="prettyprint lang-js">/**
10  * @class Ext.Element
11  */
12 Ext.Element.addMethods(function(){
13     // local style camelizing for speed
14     var propCache = {},
15         camelRe = /(-[a-z])/gi,
16         classReCache = {},
17         view = document.defaultView,
18         propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
19         opacityRe = /alpha\(opacity=(.*)\)/i,
20         trimRe = /^\s+|\s+$/g,
21         EL = Ext.Element,
22         PADDING = "padding",
23         MARGIN = "margin",
24         BORDER = "border",
25         LEFT = "-left",
26         RIGHT = "-right",
27         TOP = "-top",
28         BOTTOM = "-bottom",
29         WIDTH = "-width",
30         MATH = Math,
31         HIDDEN = 'hidden',
32         ISCLIPPED = 'isClipped',
33         OVERFLOW = 'overflow',
34         OVERFLOWX = 'overflow-x',
35         OVERFLOWY = 'overflow-y',
36         ORIGINALCLIP = 'originalClip',
37         // special markup used throughout Ext when box wrapping elements
38         borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
39         paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
40         margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
41         data = Ext.Element.data;
42
43
44     // private
45     function camelFn(m, a) {
46         return a.charAt(1).toUpperCase();
47     }
48
49     function chkCache(prop) {
50         return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
51     }
52
53     return {
54         // private  ==> used by Fx
55         adjustWidth : function(width) {
56             var me = this;
57             var isNum = Ext.isNumber(width);
58             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
59                width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
60             }
61             return (isNum && width < 0) ? 0 : width;
62         },
63
64         // private   ==> used by Fx
65         adjustHeight : function(height) {
66             var me = this;
67             var isNum = Ext.isNumber(height);
68             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
69                height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
70             }
71             return (isNum && height < 0) ? 0 : height;
72         },
73
74
75         <div id="method-Ext.Element-addClass"></div>/**
76          * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.
77          * @param {String/Array} className The CSS class to add, or an array of classes
78          * @return {Ext.Element} this
79          */
80         addClass : function(className){
81             var me = this, i, len, v;
82             className = Ext.isArray(className) ? className : [className];
83             for (i=0, len = className.length; i < len; i++) {
84                 v = className[i];
85                 if (v) {
86                     me.dom.className += (!me.hasClass(v) && v ? " " + v : "");
87                 };
88             };
89             return me;
90         },
91
92         <div id="method-Ext.Element-radioClass"></div>/**
93          * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.
94          * @param {String/Array} className The CSS class to add, or an array of classes
95          * @return {Ext.Element} this
96          */
97         radioClass : function(className){
98             var cn = this.dom.parentNode.childNodes, v;
99             className = Ext.isArray(className) ? className : [className];
100             for (var i=0, len = cn.length; i < len; i++) {
101                 v = cn[i];
102                 if(v && v.nodeType == 1) {
103                     Ext.fly(v, '_internal').removeClass(className);
104                 }
105             };
106             return this.addClass(className);
107         },
108
109         <div id="method-Ext.Element-removeClass"></div>/**
110          * Removes one or more CSS classes from the element.
111          * @param {String/Array} className The CSS class to remove, or an array of classes
112          * @return {Ext.Element} this
113          */
114         removeClass : function(className){
115             var me = this, v;
116             className = Ext.isArray(className) ? className : [className];
117             if (me.dom && me.dom.className) {
118                 for (var i=0, len=className.length; i < len; i++) {
119                     v = className[i];
120                     if(v) {
121                         me.dom.className = me.dom.className.replace(
122                             classReCache[v] = classReCache[v] || new RegExp('(?:^|\\s+)' + v + '(?:\\s+|$)', "g"), " "
123                         );
124                     }
125                 };
126             }
127             return me;
128         },
129
130         <div id="method-Ext.Element-toggleClass"></div>/**
131          * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).
132          * @param {String} className The CSS class to toggle
133          * @return {Ext.Element} this
134          */
135         toggleClass : function(className){
136             return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
137         },
138
139         <div id="method-Ext.Element-hasClass"></div>/**
140          * Checks if the specified CSS class exists on this element's DOM node.
141          * @param {String} className The CSS class to check for
142          * @return {Boolean} True if the class exists, else false
143          */
144         hasClass : function(className){
145             return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
146         },
147
148         <div id="method-Ext.Element-replaceClass"></div>/**
149          * Replaces a CSS class on the element with another.  If the old name does not exist, the new name will simply be added.
150          * @param {String} oldClassName The CSS class to replace
151          * @param {String} newClassName The replacement CSS class
152          * @return {Ext.Element} this
153          */
154         replaceClass : function(oldClassName, newClassName){
155             return this.removeClass(oldClassName).addClass(newClassName);
156         },
157
158         isStyle : function(style, val) {
159             return this.getStyle(style) == val;
160         },
161
162         <div id="method-Ext.Element-getStyle"></div>/**
163          * Normalizes currentStyle and computedStyle.
164          * @param {String} property The style property whose value is returned.
165          * @return {String} The current value of the style property for this element.
166          */
167         getStyle : function(){
168             return view && view.getComputedStyle ?
169                 function(prop){
170                     var el = this.dom,
171                         v,
172                         cs,
173                         out,
174                         display,
175                         wk = Ext.isWebKit,
176                         display;
177                         
178                     if(el == document){
179                         return null;
180                     }
181                     prop = chkCache(prop);
182                     // Fix bug caused by this: https://bugs.webkit.org/show_bug.cgi?id=13343
183                     if(wk && /marginRight/.test(prop)){
184                         display = this.getStyle('display');
185                         el.style.display = 'inline-block';
186                     }
187                     out = (v = el.style[prop]) ? v :
188                            (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
189
190                     // Webkit returns rgb values for transparent.
191                     if(wk){
192                         if(out == 'rgba(0, 0, 0, 0)'){
193                             out = 'transparent';
194                         }else if(display){
195                             el.style.display = display;
196                         }
197                     }
198                     return out;
199                 } :
200                 function(prop){
201                     var el = this.dom,
202                         m,
203                         cs;
204
205                     if(el == document) return null;
206                     if (prop == 'opacity') {
207                         if (el.style.filter.match) {
208                             if(m = el.style.filter.match(opacityRe)){
209                                 var fv = parseFloat(m[1]);
210                                 if(!isNaN(fv)){
211                                     return fv ? fv / 100 : 0;
212                                 }
213                             }
214                         }
215                         return 1;
216                     }
217                     prop = chkCache(prop);
218                     return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
219                 };
220         }(),
221
222         <div id="method-Ext.Element-getColor"></div>/**
223          * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values
224          * are convert to standard 6 digit hex color.
225          * @param {String} attr The css attribute
226          * @param {String} defaultValue The default value to use when a valid color isn't found
227          * @param {String} prefix (optional) defaults to #. Use an empty string when working with
228          * color anims.
229          */
230         getColor : function(attr, defaultValue, prefix){
231             var v = this.getStyle(attr),
232                 color = Ext.isDefined(prefix) ? prefix : '#',
233                 h;
234
235             if(!v || /transparent|inherit/.test(v)){
236                 return defaultValue;
237             }
238             if(/^r/.test(v)){
239                 Ext.each(v.slice(4, v.length -1).split(','), function(s){
240                     h = parseInt(s, 10);
241                     color += (h < 16 ? '0' : '') + h.toString(16);
242                 });
243             }else{
244                 v = v.replace('#', '');
245                 color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
246             }
247             return(color.length > 5 ? color.toLowerCase() : defaultValue);
248         },
249
250         <div id="method-Ext.Element-setStyle"></div>/**
251          * Wrapper for setting style properties, also takes single object parameter of multiple styles.
252          * @param {String/Object} property The style property to be set, or an object of multiple styles.
253          * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
254          * @return {Ext.Element} this
255          */
256         setStyle : function(prop, value){
257             var tmp,
258                 style,
259                 camel;
260             if (!Ext.isObject(prop)) {
261                 tmp = {};
262                 tmp[prop] = value;
263                 prop = tmp;
264             }
265             for (style in prop) {
266                 value = prop[style];
267                 style == 'opacity' ?
268                     this.setOpacity(value) :
269                     this.dom.style[chkCache(style)] = value;
270             }
271             return this;
272         },
273
274         <div id="method-Ext.Element-setOpacity"></div>/**
275          * Set the opacity of the element
276          * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc
277          * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for
278          * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)
279          * @return {Ext.Element} this
280          */
281          setOpacity : function(opacity, animate){
282             var me = this,
283                 s = me.dom.style;
284
285             if(!animate || !me.anim){
286                 if(Ext.isIE){
287                     var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
288                     val = s.filter.replace(opacityRe, '').replace(trimRe, '');
289
290                     s.zoom = 1;
291                     s.filter = val + (val.length > 0 ? ' ' : '') + opac;
292                 }else{
293                     s.opacity = opacity;
294                 }
295             }else{
296                 me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
297             }
298             return me;
299         },
300
301         <div id="method-Ext.Element-clearOpacity"></div>/**
302          * Clears any opacity settings from this element. Required in some cases for IE.
303          * @return {Ext.Element} this
304          */
305         clearOpacity : function(){
306             var style = this.dom.style;
307             if(Ext.isIE){
308                 if(!Ext.isEmpty(style.filter)){
309                     style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
310                 }
311             }else{
312                 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
313             }
314             return this;
315         },
316
317         <div id="method-Ext.Element-getHeight"></div>/**
318          * Returns the offset height of the element
319          * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding
320          * @return {Number} The element's height
321          */
322         getHeight : function(contentHeight){
323             var me = this,
324                 dom = me.dom,
325                 hidden = Ext.isIE && me.isStyle('display', 'none'),
326                 h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
327
328             h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
329             return h < 0 ? 0 : h;
330         },
331
332         <div id="method-Ext.Element-getWidth"></div>/**
333          * Returns the offset width of the element
334          * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding
335          * @return {Number} The element's width
336          */
337         getWidth : function(contentWidth){
338             var me = this,
339                 dom = me.dom,
340                 hidden = Ext.isIE && me.isStyle('display', 'none'),
341                 w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
342             w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
343             return w < 0 ? 0 : w;
344         },
345
346         <div id="method-Ext.Element-setWidth"></div>/**
347          * Set the width of this Element.
348          * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
349          * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
350          * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
351          * </ul></div>
352          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
353          * @return {Ext.Element} this
354          */
355         setWidth : function(width, animate){
356             var me = this;
357             width = me.adjustWidth(width);
358             !animate || !me.anim ?
359                 me.dom.style.width = me.addUnits(width) :
360                 me.anim({width : {to : width}}, me.preanim(arguments, 1));
361             return me;
362         },
363
364         <div id="method-Ext.Element-setHeight"></div>/**
365          * Set the height of this Element.
366          * <pre><code>
367 // change the height to 200px and animate with default configuration
368 Ext.fly('elementId').setHeight(200, true);
369
370 // change the height to 150px and animate with a custom configuration
371 Ext.fly('elId').setHeight(150, {
372     duration : .5, // animation will have a duration of .5 seconds
373     // will change the content to "finished"
374     callback: function(){ this.{@link #update}("finished"); }
375 });
376          * </code></pre>
377          * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
378          * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>
379          * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
380          * </ul></div>
381          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
382          * @return {Ext.Element} this
383          */
384          setHeight : function(height, animate){
385             var me = this;
386             height = me.adjustHeight(height);
387             !animate || !me.anim ?
388                 me.dom.style.height = me.addUnits(height) :
389                 me.anim({height : {to : height}}, me.preanim(arguments, 1));
390             return me;
391         },
392
393         <div id="method-Ext.Element-getBorderWidth"></div>/**
394          * Gets the width of the border(s) for the specified side(s)
395          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
396          * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.
397          * @return {Number} The width of the sides passed added together
398          */
399         getBorderWidth : function(side){
400             return this.addStyles(side, borders);
401         },
402
403         <div id="method-Ext.Element-getPadding"></div>/**
404          * Gets the width of the padding(s) for the specified side(s)
405          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
406          * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.
407          * @return {Number} The padding of the sides passed added together
408          */
409         getPadding : function(side){
410             return this.addStyles(side, paddings);
411         },
412
413         <div id="method-Ext.Element-clip"></div>/**
414          *  Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove
415          * @return {Ext.Element} this
416          */
417         clip : function(){
418             var me = this,
419                 dom = me.dom;
420
421             if(!data(dom, ISCLIPPED)){
422                 data(dom, ISCLIPPED, true);
423                 data(dom, ORIGINALCLIP, {
424                     o: me.getStyle(OVERFLOW),
425                     x: me.getStyle(OVERFLOWX),
426                     y: me.getStyle(OVERFLOWY)
427                 });
428                 me.setStyle(OVERFLOW, HIDDEN);
429                 me.setStyle(OVERFLOWX, HIDDEN);
430                 me.setStyle(OVERFLOWY, HIDDEN);
431             }
432             return me;
433         },
434
435         <div id="method-Ext.Element-unclip"></div>/**
436          *  Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called
437          * @return {Ext.Element} this
438          */
439         unclip : function(){
440             var me = this,
441                 dom = me.dom;
442
443             if(data(dom, ISCLIPPED)){
444                 data(dom, ISCLIPPED, false);
445                 var o = data(dom, ORIGINALCLIP);
446                 if(o.o){
447                     me.setStyle(OVERFLOW, o.o);
448                 }
449                 if(o.x){
450                     me.setStyle(OVERFLOWX, o.x);
451                 }
452                 if(o.y){
453                     me.setStyle(OVERFLOWY, o.y);
454                 }
455             }
456             return me;
457         },
458
459         // private
460         addStyles : function(sides, styles){
461             var val = 0,
462                 m = sides.match(/\w/g),
463                 s;
464             for (var i=0, len=m.length; i<len; i++) {
465                 s = m[i] && parseInt(this.getStyle(styles[m[i]]), 10);
466                 if (s) {
467                     val += MATH.abs(s);
468                 }
469             }
470             return val;
471         },
472
473         margins : margins
474     }
475 }()
476 );
477 </pre>    \r
478 </body>\r
479 </html>