2 * @class Ext.core.Element
5 Ext.core.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
6 // local style camelizing for speed
7 var supports = Ext.supports,
8 view = document.defaultView,
9 opacityRe = /alpha\(opacity=(.*)\)/i,
10 trimRe = /^\s+|\s+$/g,
13 adjustDirect2DTableRe = /table-row|table-.*-group/,
14 INTERNAL = '_internal',
25 ISCLIPPED = 'isClipped',
26 OVERFLOW = 'overflow',
27 OVERFLOWX = 'overflow-x',
28 OVERFLOWY = 'overflow-y',
29 ORIGINALCLIP = 'originalClip',
30 // special markup used throughout Ext when box wrapping elements
31 borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
32 paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
33 margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
34 data = Ext.core.Element.data;
36 Ext.override(Ext.core.Element, {
41 // private ==> used by Fx
42 adjustWidth : function(width) {
44 isNum = (typeof width == 'number');
46 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
47 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
49 return (isNum && width < 0) ? 0 : width;
52 // private ==> used by Fx
53 adjustHeight : function(height) {
55 isNum = (typeof height == "number");
57 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
58 height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
60 return (isNum && height < 0) ? 0 : height;
65 * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.
66 * @param {String/Array} className The CSS classes to add separated by space, or an array of classes
67 * @return {Ext.core.Element} this
69 addCls : function(className){
72 space = ((me.dom.className.replace(trimRe, '') == '') ? "" : " "),
74 if (!Ext.isDefined(className)) {
77 // Separate case is for speed
78 if (!Ext.isArray(className)) {
79 if (typeof className === 'string') {
80 className = className.replace(trimRe, '').split(spacesRe);
81 if (className.length === 1) {
82 className = className[0];
83 if (!me.hasCls(className)) {
84 me.dom.className += space + className;
87 this.addCls(className);
91 for (i = 0, len = className.length; i < len; i++) {
93 if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
98 me.dom.className += space + cls.join(" ");
105 * Removes one or more CSS classes from the element.
106 * @param {String/Array} className The CSS classes to remove separated by space, or an array of classes
107 * @return {Ext.core.Element} this
109 removeCls : function(className){
111 i, idx, len, cls, elClasses;
112 if (!Ext.isDefined(className)) {
115 if (!Ext.isArray(className)){
116 className = className.replace(trimRe, '').split(spacesRe);
118 if (me.dom && me.dom.className) {
119 elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
120 for (i = 0, len = className.length; i < len; i++) {
122 if (typeof cls == 'string') {
123 cls = cls.replace(trimRe, '');
124 idx = Ext.Array.indexOf(elClasses, cls);
126 elClasses.splice(idx, 1);
130 me.dom.className = elClasses.join(" ");
136 * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.
137 * @param {String/Array} className The CSS class to add, or an array of classes
138 * @return {Ext.core.Element} this
140 radioCls : function(className){
141 var cn = this.dom.parentNode.childNodes,
143 className = Ext.isArray(className) ? className : [className];
144 for (i = 0, len = cn.length; i < len; i++) {
146 if (v && v.nodeType == 1) {
147 Ext.fly(v, '_internal').removeCls(className);
150 return this.addCls(className);
154 * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).
155 * @param {String} className The CSS class to toggle
156 * @return {Ext.core.Element} this
158 toggleCls : Ext.supports.ClassList ?
159 function(className) {
160 this.dom.classList.toggle(Ext.String.trim(className));
163 function(className) {
164 return this.hasCls(className) ? this.removeCls(className) : this.addCls(className);
168 * Checks if the specified CSS class exists on this element's DOM node.
169 * @param {String} className The CSS class to check for
170 * @return {Boolean} True if the class exists, else false
172 hasCls : Ext.supports.ClassList ?
173 function(className) {
177 className = className.split(spacesRe);
178 var ln = className.length,
180 for (; i < ln; i++) {
181 if (className[i] && this.dom.classList.contains(className[i])) {
188 return className && (' ' + this.dom.className + ' ').indexOf(' ' + className + ' ') != -1;
192 * Replaces a CSS class on the element with another. If the old name does not exist, the new name will simply be added.
193 * @param {String} oldClassName The CSS class to replace
194 * @param {String} newClassName The replacement CSS class
195 * @return {Ext.core.Element} this
197 replaceCls : function(oldClassName, newClassName){
198 return this.removeCls(oldClassName).addCls(newClassName);
201 isStyle : function(style, val) {
202 return this.getStyle(style) == val;
206 * Normalizes currentStyle and computedStyle.
207 * @param {String} property The style property whose value is returned.
208 * @return {String} The current value of the style property for this element.
210 getStyle : function(){
211 return view && view.getComputedStyle ?
219 prop = Ext.core.Element.normalize(prop);
220 out = (v = el.style[prop]) ? v :
221 (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
223 // Ignore cases when the margin is correctly reported as 0, the bug only shows
225 if(prop == 'marginRight' && out != '0px' && !supports.RightMargin){
226 display = this.getStyle('display');
227 el.style.display = 'inline-block';
228 out = view.getComputedStyle(el, '').marginRight;
229 el.style.display = display;
232 if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.TransparentColor){
241 if (el == document) {
245 if (prop == 'opacity') {
246 if (el.style.filter.match) {
247 m = el.style.filter.match(opacityRe);
249 var fv = parseFloat(m[1]);
251 return fv ? fv / 100 : 0;
257 prop = Ext.core.Element.normalize(prop);
258 return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
263 * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values
264 * are convert to standard 6 digit hex color.
265 * @param {String} attr The css attribute
266 * @param {String} defaultValue The default value to use when a valid color isn't found
267 * @param {String} prefix (optional) defaults to #. Use an empty string when working with
270 getColor : function(attr, defaultValue, prefix){
271 var v = this.getStyle(attr),
272 color = prefix || prefix === '' ? prefix : '#',
275 if(!v || (/transparent|inherit/.test(v))) {
279 Ext.each(v.slice(4, v.length -1).split(','), function(s){
281 color += (h < 16 ? '0' : '') + h.toString(16);
284 v = v.replace('#', '');
285 color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
287 return(color.length > 5 ? color.toLowerCase() : defaultValue);
291 * Wrapper for setting style properties, also takes single object parameter of multiple styles.
292 * @param {String/Object} property The style property to be set, or an object of multiple styles.
293 * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
294 * @return {Ext.core.Element} this
296 setStyle : function(prop, value){
304 if (!Ext.isObject(prop)) {
309 for (style in prop) {
310 if (prop.hasOwnProperty(style)) {
311 value = Ext.value(prop[style], '');
312 if (style == 'opacity') {
313 me.setOpacity(value);
316 me.dom.style[Ext.core.Element.normalize(style)] = value;
324 * Set the opacity of the element
325 * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc
326 * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for
327 * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)
328 * @return {Ext.core.Element} this
330 setOpacity: function(opacity, animate) {
340 style = me.dom.style;
342 if (!animate || !me.anim) {
343 if (!Ext.supports.Opacity) {
344 opacity = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')': '';
345 val = style.filter.replace(opacityRe, '').replace(trimRe, '');
348 style.filter = val + (val.length > 0 ? ' ': '') + opacity;
351 style.opacity = opacity;
355 if (!Ext.isObject(animate)) {
361 me.animate(Ext.applyIf({
373 * Clears any opacity settings from this element. Required in some cases for IE.
374 * @return {Ext.core.Element} this
376 clearOpacity : function(){
377 var style = this.dom.style;
378 if(!Ext.supports.Opacity){
379 if(!Ext.isEmpty(style.filter)){
380 style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
383 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
390 * Returns 1 if the browser returns the subpixel dimension rounded to the lowest pixel.
391 * @return {Number} 0 or 1
393 adjustDirect2DDimension: function(dimension) {
396 display = me.getStyle('display'),
397 inlineDisplay = dom.style['display'],
398 inlinePosition = dom.style['position'],
399 originIndex = dimension === 'width' ? 0 : 1,
402 if (display === 'inline') {
403 dom.style['display'] = 'inline-block';
406 dom.style['position'] = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static';
408 // floating will contain digits that appears after the decimal point
409 // if height or width are set to auto we fallback to msTransformOrigin calculation
410 floating = (parseFloat(me.getStyle(dimension)) || parseFloat(dom.currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1;
412 dom.style['position'] = inlinePosition;
414 if (display === 'inline') {
415 dom.style['display'] = inlineDisplay;
422 * Returns the offset height of the element
423 * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding
424 * @return {Number} The element's height
426 getHeight: function(contentHeight, preciseHeight) {
429 hidden = Ext.isIE && me.isStyle('display', 'none'),
430 height, overflow, style, floating;
432 // IE Quirks mode acts more like a max-size measurement unless overflow is hidden during measurement.
433 // We will put the overflow back to it's original value when we are done measuring.
434 if (Ext.isIEQuirks) {
436 overflow = style.overflow;
437 me.setStyle({ overflow: 'hidden'});
440 height = dom.offsetHeight;
442 height = MATH.max(height, hidden ? 0 : dom.clientHeight) || 0;
444 // IE9 Direct2D dimension rounding bug
445 if (!hidden && Ext.supports.Direct2DBug) {
446 floating = me.adjustDirect2DDimension('height');
450 else if (floating > 0 && floating < 0.5) {
456 height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
459 if (Ext.isIEQuirks) {
460 me.setStyle({ overflow: overflow});
470 * Returns the offset width of the element
471 * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding
472 * @return {Number} The element's width
474 getWidth: function(contentWidth, preciseWidth) {
477 hidden = Ext.isIE && me.isStyle('display', 'none'),
478 rect, width, overflow, style, floating, parentPosition;
480 // IE Quirks mode acts more like a max-size measurement unless overflow is hidden during measurement.
481 // We will put the overflow back to it's original value when we are done measuring.
482 if (Ext.isIEQuirks) {
484 overflow = style.overflow;
485 me.setStyle({overflow: 'hidden'});
488 // Fix Opera 10.5x width calculation issues
489 if (Ext.isOpera10_5) {
490 if (dom.parentNode.currentStyle.position === 'relative') {
491 parentPosition = dom.parentNode.style.position;
492 dom.parentNode.style.position = 'static';
493 width = dom.offsetWidth;
494 dom.parentNode.style.position = parentPosition;
496 width = Math.max(width || 0, dom.offsetWidth);
498 // Gecko will in some cases report an offsetWidth that is actually less than the width of the
499 // text contents, because it measures fonts with sub-pixel precision but rounds the calculated
500 // value down. Using getBoundingClientRect instead of offsetWidth allows us to get the precise
501 // subpixel measurements so we can force them to always be rounded up. See
502 // https://bugzilla.mozilla.org/show_bug.cgi?id=458617
503 } else if (Ext.supports.BoundingClientRect) {
504 rect = dom.getBoundingClientRect();
505 width = rect.right - rect.left;
506 width = preciseWidth ? width : Math.ceil(width);
508 width = dom.offsetWidth;
511 width = MATH.max(width, hidden ? 0 : dom.clientWidth) || 0;
513 // IE9 Direct2D dimension rounding bug
514 if (!hidden && Ext.supports.Direct2DBug) {
515 floating = me.adjustDirect2DDimension('width');
519 else if (floating > 0 && floating < 0.5) {
525 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
528 if (Ext.isIEQuirks) {
529 me.setStyle({ overflow: overflow});
539 * Set the width of this Element.
540 * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
541 * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
542 * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
544 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
545 * @return {Ext.core.Element} this
547 setWidth : function(width, animate){
549 width = me.adjustWidth(width);
550 if (!animate || !me.anim) {
551 me.dom.style.width = me.addUnits(width);
554 if (!Ext.isObject(animate)) {
557 me.animate(Ext.applyIf({
567 * Set the height of this Element.
569 // change the height to 200px and animate with default configuration
570 Ext.fly('elementId').setHeight(200, true);
572 // change the height to 150px and animate with a custom configuration
573 Ext.fly('elId').setHeight(150, {
574 duration : .5, // animation will have a duration of .5 seconds
575 // will change the content to "finished"
576 callback: function(){ this.{@link #update}("finished"); }
579 * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
580 * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>
581 * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
583 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
584 * @return {Ext.core.Element} this
586 setHeight : function(height, animate){
588 height = me.adjustHeight(height);
589 if (!animate || !me.anim) {
590 me.dom.style.height = me.addUnits(height);
593 if (!Ext.isObject(animate)) {
596 me.animate(Ext.applyIf({
606 * Gets the width of the border(s) for the specified side(s)
607 * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
608 * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.
609 * @return {Number} The width of the sides passed added together
611 getBorderWidth : function(side){
612 return this.addStyles(side, borders);
616 * Gets the width of the padding(s) for the specified side(s)
617 * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
618 * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.
619 * @return {Number} The padding of the sides passed added together
621 getPadding : function(side){
622 return this.addStyles(side, paddings);
626 * Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove
627 * @return {Ext.core.Element} this
633 if(!data(dom, ISCLIPPED)){
634 data(dom, ISCLIPPED, true);
635 data(dom, ORIGINALCLIP, {
636 o: me.getStyle(OVERFLOW),
637 x: me.getStyle(OVERFLOWX),
638 y: me.getStyle(OVERFLOWY)
640 me.setStyle(OVERFLOW, HIDDEN);
641 me.setStyle(OVERFLOWX, HIDDEN);
642 me.setStyle(OVERFLOWY, HIDDEN);
648 * Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called
649 * @return {Ext.core.Element} this
656 if(data(dom, ISCLIPPED)){
657 data(dom, ISCLIPPED, false);
658 clip = data(dom, ORIGINALCLIP);
660 me.setStyle(OVERFLOW, o.o);
663 me.setStyle(OVERFLOWX, o.x);
666 me.setStyle(OVERFLOWY, o.y);
673 addStyles : function(sides, styles){
675 sidesArr = sides.match(wordsRe),
677 len = sidesArr.length,
679 for (; i < len; i++) {
681 size = side && parseInt(this.getStyle(styles[side]), 10);
683 totalSize += MATH.abs(size);
692 * More flexible version of {@link #setStyle} for setting style properties.
693 * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or
694 * a function which returns such a specification.
695 * @return {Ext.core.Element} this
697 applyStyles : function(style){
698 Ext.core.DomHelper.applyStyles(this.dom, style);
703 * Returns an object with properties matching the styles requested.
704 * For example, el.getStyles('color', 'font-size', 'width') might return
705 * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.
706 * @param {String} style1 A style name
707 * @param {String} style2 A style name
708 * @param {String} etc.
709 * @return {Object} The style object
711 getStyles : function(){
713 len = arguments.length,
716 for(; i < len; ++i) {
717 style = arguments[i];
718 styles[style] = this.getStyle(style);
724 * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as
725 * a gray container with a gradient background, rounded corners and a 4-way shadow.</p>
726 * <p>This special markup is used throughout Ext when box wrapping elements ({@link Ext.button.Button},
727 * {@link Ext.panel.Panel} when <tt>{@link Ext.panel.Panel#frame frame=true}</tt>, {@link Ext.window.Window}). The markup
728 * is of this form:</p>
730 Ext.core.Element.boxMarkup =
731 '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div>
732 <div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div>
733 <div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
735 * <p>Example usage:</p>
738 Ext.get("foo").boxWrap();
740 // You can also add a custom class and use CSS inheritance rules to customize the box look.
741 // 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example
742 // for how to create a custom box wrap style.
743 Ext.get("foo").boxWrap().addCls("x-box-blue");
745 * @param {String} class (optional) A base CSS class to apply to the containing wrapper element
746 * (defaults to <tt>'x-box'</tt>). Note that there are a number of CSS rules that are dependent on
747 * this name to make the overall effect work, so if you supply an alternate base class, make sure you
748 * also supply all of the necessary rules.
749 * @return {Ext.core.Element} The outermost wrapping element of the created box structure.
751 boxWrap : function(cls){
752 cls = cls || Ext.baseCSSPrefix + 'box';
753 var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + Ext.String.format(Ext.core.Element.boxMarkup, cls) + "</div>"));
754 Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
759 * Set the size of this Element. If animation is true, both width and height will be animated concurrently.
760 * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
761 * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
762 * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
763 * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>
765 * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
766 * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).</li>
767 * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
769 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
770 * @return {Ext.core.Element} this
772 setSize : function(width, height, animate){
774 if (Ext.isObject(width)){ // in case of object from getSize()
775 height = width.height;
778 width = me.adjustWidth(width);
779 height = me.adjustHeight(height);
780 if(!animate || !me.anim){
781 me.dom.style.width = me.addUnits(width);
782 me.dom.style.height = me.addUnits(height);
785 if (!Ext.isObject(animate)) {
788 me.animate(Ext.applyIf({
799 * Returns either the offsetHeight or the height of this element based on CSS height adjusted by padding or borders
800 * when needed to simulate offsetHeight when offsets aren't available. This may not work on display:none elements
801 * if a height has not been set using CSS.
804 getComputedHeight : function(){
806 h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
808 h = parseFloat(me.getStyle('height')) || 0;
809 if(!me.isBorderBox()){
810 h += me.getFrameWidth('tb');
817 * Returns either the offsetWidth or the width of this element based on CSS width adjusted by padding or borders
818 * when needed to simulate offsetWidth when offsets aren't available. This may not work on display:none elements
819 * if a width has not been set using CSS.
822 getComputedWidth : function(){
824 w = Math.max(me.dom.offsetWidth, me.dom.clientWidth);
827 w = parseFloat(me.getStyle('width')) || 0;
828 if(!me.isBorderBox()){
829 w += me.getFrameWidth('lr');
836 * Returns the sum width of the padding and borders for the passed "sides". See getBorderWidth()
837 for more information about the sides.
838 * @param {String} sides
841 getFrameWidth : function(sides, onlyContentBox){
842 return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
846 * Sets up event handlers to add and remove a css class when the mouse is over this element
847 * @param {String} className
848 * @return {Ext.core.Element} this
850 addClsOnOver : function(className){
854 Ext.fly(dom, INTERNAL).addCls(className);
857 Ext.fly(dom, INTERNAL).removeCls(className);
864 * Sets up event handlers to add and remove a css class when this element has the focus
865 * @param {String} className
866 * @return {Ext.core.Element} this
868 addClsOnFocus : function(className){
871 me.on("focus", function(){
872 Ext.fly(dom, INTERNAL).addCls(className);
874 me.on("blur", function(){
875 Ext.fly(dom, INTERNAL).removeCls(className);
881 * Sets up event handlers to add and remove a css class when the mouse is down and then up on this element (a click effect)
882 * @param {String} className
883 * @return {Ext.core.Element} this
885 addClsOnClick : function(className){
887 this.on("mousedown", function(){
888 Ext.fly(dom, INTERNAL).addCls(className);
889 var d = Ext.getDoc(),
891 Ext.fly(dom, INTERNAL).removeCls(className);
892 d.removeListener("mouseup", fn);
900 * <p>Returns the dimensions of the element available to lay content out in.<p>
901 * <p>If the element (or any ancestor element) has CSS style <code>display : none</code>, the dimensions will be zero.</p>
902 * example:<pre><code>
903 var vpSize = Ext.getBody().getViewSize();
905 // all Windows created afterwards will have a default value of 90% height and 95% width
906 Ext.Window.override({
907 width: vpSize.width * 0.9,
908 height: vpSize.height * 0.95
910 // To handle window resizing you would have to hook onto onWindowResize.
913 * getViewSize utilizes clientHeight/clientWidth which excludes sizing of scrollbars.
914 * To obtain the size including scrollbars, use getStyleSize
916 * Sizing of the document body is handled at the adapter level which handles special cases for IE and strict modes, etc.
919 getViewSize : function(){
922 isDoc = (dom == Ext.getDoc().dom || dom == Ext.getBody().dom),
923 style, overflow, ret;
925 // If the body, use static methods
928 width : Ext.core.Element.getViewWidth(),
929 height : Ext.core.Element.getViewHeight()
932 // Else use clientHeight/clientWidth
935 // IE 6 & IE Quirks mode acts more like a max-size measurement unless overflow is hidden during measurement.
936 // We will put the overflow back to it's original value when we are done measuring.
937 if (Ext.isIE6 || Ext.isIEQuirks) {
939 overflow = style.overflow;
940 me.setStyle({ overflow: 'hidden'});
943 width : dom.clientWidth,
944 height : dom.clientHeight
946 if (Ext.isIE6 || Ext.isIEQuirks) {
947 me.setStyle({ overflow: overflow });
954 * <p>Returns the dimensions of the element available to lay content out in.<p>
956 * getStyleSize utilizes prefers style sizing if present, otherwise it chooses the larger of offsetHeight/clientHeight and offsetWidth/clientWidth.
957 * To obtain the size excluding scrollbars, use getViewSize
959 * Sizing of the document body is handled at the adapter level which handles special cases for IE and strict modes, etc.
962 getStyleSize : function(){
966 isDoc = (d == doc || d == doc.body),
970 // If the body, use static methods
973 width : Ext.core.Element.getViewWidth(),
974 height : Ext.core.Element.getViewHeight()
977 // Use Styles if they are set
978 if(s.width && s.width != 'auto'){
979 w = parseFloat(s.width);
980 if(me.isBorderBox()){
981 w -= me.getFrameWidth('lr');
984 // Use Styles if they are set
985 if(s.height && s.height != 'auto'){
986 h = parseFloat(s.height);
987 if(me.isBorderBox()){
988 h -= me.getFrameWidth('tb');
991 // Use getWidth/getHeight if style not set.
992 return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
996 * Returns the size of the element.
997 * @param {Boolean} contentSize (optional) true to get the width/size minus borders and padding
998 * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
1000 getSize : function(contentSize){
1001 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
1005 * Forces the browser to repaint this element
1006 * @return {Ext.core.Element} this
1008 repaint : function(){
1010 this.addCls(Ext.baseCSSPrefix + 'repaint');
1011 setTimeout(function(){
1012 Ext.fly(dom).removeCls(Ext.baseCSSPrefix + 'repaint');
1018 * Disables text selection for this element (normalized across browsers)
1019 * @return {Ext.core.Element} this
1021 unselectable : function(){
1023 me.dom.unselectable = "on";
1025 me.swallowEvent("selectstart", true);
1026 me.applyStyles("-moz-user-select:none;-khtml-user-select:none;");
1027 me.addCls(Ext.baseCSSPrefix + 'unselectable');
1033 * Returns an object with properties top, left, right and bottom representing the margins of this element unless sides is passed,
1034 * then it returns the calculated width of the sides (see getPadding)
1035 * @param {String} sides (optional) Any combination of l, r, t, b to get the sum of those sides
1036 * @return {Object/Number}
1038 getMargin : function(side){
1040 hash = {t:"top", l:"left", r:"right", b: "bottom"},
1045 for (key in me.margins){
1046 o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
1050 return me.addStyles.call(me, side, me.margins);