3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.core.Element
19 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>';
20 // local style camelizing for speed
21 var supports = Ext.supports,
22 view = document.defaultView,
23 opacityRe = /alpha\(opacity=(.*)\)/i,
24 trimRe = /^\s+|\s+$/g,
27 adjustDirect2DTableRe = /table-row|table-.*-group/,
28 INTERNAL = '_internal',
39 ISCLIPPED = 'isClipped',
40 OVERFLOW = 'overflow',
41 OVERFLOWX = 'overflow-x',
42 OVERFLOWY = 'overflow-y',
43 ORIGINALCLIP = 'originalClip',
44 // special markup used throughout Ext when box wrapping elements
45 borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
46 paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
47 margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
48 data = Ext.core.Element.data;
50 Ext.override(Ext.core.Element, {
55 // private ==> used by Fx
56 adjustWidth : function(width) {
58 isNum = (typeof width == 'number');
60 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
61 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
63 return (isNum && width < 0) ? 0 : width;
66 // private ==> used by Fx
67 adjustHeight : function(height) {
69 isNum = (typeof height == "number");
71 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
72 height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
74 return (isNum && height < 0) ? 0 : height;
79 * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.
80 * @param {String/Array} className The CSS classes to add separated by space, or an array of classes
81 * @return {Ext.core.Element} this
83 addCls : function(className){
86 space = ((me.dom.className.replace(trimRe, '') == '') ? "" : " "),
88 if (className === undefined) {
91 // Separate case is for speed
92 if (Object.prototype.toString.call(className) !== '[object Array]') {
93 if (typeof className === 'string') {
94 className = className.replace(trimRe, '').split(spacesRe);
95 if (className.length === 1) {
96 className = className[0];
97 if (!me.hasCls(className)) {
98 me.dom.className += space + className;
101 this.addCls(className);
105 for (i = 0, len = className.length; i < len; i++) {
107 if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
112 me.dom.className += space + cls.join(" ");
119 * Removes one or more CSS classes from the element.
120 * @param {String/Array} className The CSS classes to remove separated by space, or an array of classes
121 * @return {Ext.core.Element} this
123 removeCls : function(className){
125 i, idx, len, cls, elClasses;
126 if (className === undefined) {
129 if (Object.prototype.toString.call(className) !== '[object Array]') {
130 className = className.replace(trimRe, '').split(spacesRe);
132 if (me.dom && me.dom.className) {
133 elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
134 for (i = 0, len = className.length; i < len; i++) {
136 if (typeof cls == 'string') {
137 cls = cls.replace(trimRe, '');
138 idx = Ext.Array.indexOf(elClasses, cls);
140 Ext.Array.erase(elClasses, idx, 1);
144 me.dom.className = elClasses.join(" ");
150 * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.
151 * @param {String/Array} className The CSS class to add, or an array of classes
152 * @return {Ext.core.Element} this
154 radioCls : function(className){
155 var cn = this.dom.parentNode.childNodes,
157 className = Ext.isArray(className) ? className : [className];
158 for (i = 0, len = cn.length; i < len; i++) {
160 if (v && v.nodeType == 1) {
161 Ext.fly(v, '_internal').removeCls(className);
164 return this.addCls(className);
168 * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).
169 * @param {String} className The CSS class to toggle
170 * @return {Ext.core.Element} this
173 toggleCls : Ext.supports.ClassList ?
174 function(className) {
175 this.dom.classList.toggle(Ext.String.trim(className));
178 function(className) {
179 return this.hasCls(className) ? this.removeCls(className) : this.addCls(className);
183 * Checks if the specified CSS class exists on this element's DOM node.
184 * @param {String} className The CSS class to check for
185 * @return {Boolean} True if the class exists, else false
188 hasCls : Ext.supports.ClassList ?
189 function(className) {
193 className = className.split(spacesRe);
194 var ln = className.length,
196 for (; i < ln; i++) {
197 if (className[i] && this.dom.classList.contains(className[i])) {
204 return className && (' ' + this.dom.className + ' ').indexOf(' ' + className + ' ') != -1;
208 * Replaces a CSS class on the element with another. If the old name does not exist, the new name will simply be added.
209 * @param {String} oldClassName The CSS class to replace
210 * @param {String} newClassName The replacement CSS class
211 * @return {Ext.core.Element} this
213 replaceCls : function(oldClassName, newClassName){
214 return this.removeCls(oldClassName).addCls(newClassName);
217 isStyle : function(style, val) {
218 return this.getStyle(style) == val;
222 * Normalizes currentStyle and computedStyle.
223 * @param {String} property The style property whose value is returned.
224 * @return {String} The current value of the style property for this element.
227 getStyle : function(){
228 return view && view.getComputedStyle ?
231 v, cs, out, display, cleaner;
236 prop = Ext.core.Element.normalize(prop);
237 out = (v = el.style[prop]) ? v :
238 (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
240 // Ignore cases when the margin is correctly reported as 0, the bug only shows
242 if(prop == 'marginRight' && out != '0px' && !supports.RightMargin){
243 cleaner = Ext.core.Element.getRightMarginFixCleaner(el);
244 display = this.getStyle('display');
245 el.style.display = 'inline-block';
246 out = view.getComputedStyle(el, '').marginRight;
247 el.style.display = display;
251 if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.TransparentColor){
260 if (el == document) {
264 if (prop == 'opacity') {
265 if (el.style.filter.match) {
266 m = el.style.filter.match(opacityRe);
268 var fv = parseFloat(m[1]);
270 return fv ? fv / 100 : 0;
276 prop = Ext.core.Element.normalize(prop);
277 return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
282 * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values
283 * are convert to standard 6 digit hex color.
284 * @param {String} attr The css attribute
285 * @param {String} defaultValue The default value to use when a valid color isn't found
286 * @param {String} prefix (optional) defaults to #. Use an empty string when working with
289 getColor : function(attr, defaultValue, prefix){
290 var v = this.getStyle(attr),
291 color = prefix || prefix === '' ? prefix : '#',
294 if(!v || (/transparent|inherit/.test(v))) {
298 Ext.each(v.slice(4, v.length -1).split(','), function(s){
300 color += (h < 16 ? '0' : '') + h.toString(16);
303 v = v.replace('#', '');
304 color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
306 return(color.length > 5 ? color.toLowerCase() : defaultValue);
310 * Wrapper for setting style properties, also takes single object parameter of multiple styles.
311 * @param {String/Object} property The style property to be set, or an object of multiple styles.
312 * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
313 * @return {Ext.core.Element} this
315 setStyle : function(prop, value){
322 if (typeof prop === 'string') {
327 for (style in prop) {
328 if (prop.hasOwnProperty(style)) {
329 value = Ext.value(prop[style], '');
330 if (style == 'opacity') {
331 me.setOpacity(value);
334 me.dom.style[Ext.core.Element.normalize(style)] = value;
342 * Set the opacity of the element
343 * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc
344 * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for
345 * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)
346 * @return {Ext.core.Element} this
348 setOpacity: function(opacity, animate) {
358 style = me.dom.style;
360 if (!animate || !me.anim) {
361 if (!Ext.supports.Opacity) {
362 opacity = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')': '';
363 val = style.filter.replace(opacityRe, '').replace(trimRe, '');
366 style.filter = val + (val.length > 0 ? ' ': '') + opacity;
369 style.opacity = opacity;
373 if (!Ext.isObject(animate)) {
379 me.animate(Ext.applyIf({
391 * Clears any opacity settings from this element. Required in some cases for IE.
392 * @return {Ext.core.Element} this
394 clearOpacity : function(){
395 var style = this.dom.style;
396 if(!Ext.supports.Opacity){
397 if(!Ext.isEmpty(style.filter)){
398 style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
401 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
408 * Returns 1 if the browser returns the subpixel dimension rounded to the lowest pixel.
409 * @return {Number} 0 or 1
411 adjustDirect2DDimension: function(dimension) {
414 display = me.getStyle('display'),
415 inlineDisplay = dom.style['display'],
416 inlinePosition = dom.style['position'],
417 originIndex = dimension === 'width' ? 0 : 1,
420 if (display === 'inline') {
421 dom.style['display'] = 'inline-block';
424 dom.style['position'] = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static';
426 // floating will contain digits that appears after the decimal point
427 // if height or width are set to auto we fallback to msTransformOrigin calculation
428 floating = (parseFloat(me.getStyle(dimension)) || parseFloat(dom.currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1;
430 dom.style['position'] = inlinePosition;
432 if (display === 'inline') {
433 dom.style['display'] = inlineDisplay;
440 * Returns the offset height of the element
441 * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding
442 * @return {Number} The element's height
444 getHeight: function(contentHeight, preciseHeight) {
447 hidden = Ext.isIE && me.isStyle('display', 'none'),
448 height, overflow, style, floating;
450 // IE Quirks mode acts more like a max-size measurement unless overflow is hidden during measurement.
451 // We will put the overflow back to it's original value when we are done measuring.
452 if (Ext.isIEQuirks) {
454 overflow = style.overflow;
455 me.setStyle({ overflow: 'hidden'});
458 height = dom.offsetHeight;
460 height = MATH.max(height, hidden ? 0 : dom.clientHeight) || 0;
462 // IE9 Direct2D dimension rounding bug
463 if (!hidden && Ext.supports.Direct2DBug) {
464 floating = me.adjustDirect2DDimension('height');
468 else if (floating > 0 && floating < 0.5) {
474 height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
477 if (Ext.isIEQuirks) {
478 me.setStyle({ overflow: overflow});
488 * Returns the offset width of the element
489 * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding
490 * @return {Number} The element's width
492 getWidth: function(contentWidth, preciseWidth) {
495 hidden = Ext.isIE && me.isStyle('display', 'none'),
496 rect, width, overflow, style, floating, parentPosition;
498 // IE Quirks mode acts more like a max-size measurement unless overflow is hidden during measurement.
499 // We will put the overflow back to it's original value when we are done measuring.
500 if (Ext.isIEQuirks) {
502 overflow = style.overflow;
503 me.setStyle({overflow: 'hidden'});
506 // Fix Opera 10.5x width calculation issues
507 if (Ext.isOpera10_5) {
508 if (dom.parentNode.currentStyle.position === 'relative') {
509 parentPosition = dom.parentNode.style.position;
510 dom.parentNode.style.position = 'static';
511 width = dom.offsetWidth;
512 dom.parentNode.style.position = parentPosition;
514 width = Math.max(width || 0, dom.offsetWidth);
516 // Gecko will in some cases report an offsetWidth that is actually less than the width of the
517 // text contents, because it measures fonts with sub-pixel precision but rounds the calculated
518 // value down. Using getBoundingClientRect instead of offsetWidth allows us to get the precise
519 // subpixel measurements so we can force them to always be rounded up. See
520 // https://bugzilla.mozilla.org/show_bug.cgi?id=458617
521 } else if (Ext.supports.BoundingClientRect) {
522 rect = dom.getBoundingClientRect();
523 width = rect.right - rect.left;
524 width = preciseWidth ? width : Math.ceil(width);
526 width = dom.offsetWidth;
529 width = MATH.max(width, hidden ? 0 : dom.clientWidth) || 0;
531 // IE9 Direct2D dimension rounding bug
532 if (!hidden && Ext.supports.Direct2DBug) {
533 floating = me.adjustDirect2DDimension('width');
537 else if (floating > 0 && floating < 0.5) {
543 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
546 if (Ext.isIEQuirks) {
547 me.setStyle({ overflow: overflow});
557 * Set the width of this Element.
558 * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
559 * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
560 * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
562 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
563 * @return {Ext.core.Element} this
565 setWidth : function(width, animate){
567 width = me.adjustWidth(width);
568 if (!animate || !me.anim) {
569 me.dom.style.width = me.addUnits(width);
572 if (!Ext.isObject(animate)) {
575 me.animate(Ext.applyIf({
585 * Set the height of this Element.
587 // change the height to 200px and animate with default configuration
588 Ext.fly('elementId').setHeight(200, true);
590 // change the height to 150px and animate with a custom configuration
591 Ext.fly('elId').setHeight(150, {
592 duration : .5, // animation will have a duration of .5 seconds
593 // will change the content to "finished"
594 callback: function(){ this.{@link #update}("finished"); }
597 * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
598 * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>
599 * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
601 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
602 * @return {Ext.core.Element} this
604 setHeight : function(height, animate){
606 height = me.adjustHeight(height);
607 if (!animate || !me.anim) {
608 me.dom.style.height = me.addUnits(height);
611 if (!Ext.isObject(animate)) {
614 me.animate(Ext.applyIf({
624 * Gets the width of the border(s) for the specified side(s)
625 * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
626 * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.
627 * @return {Number} The width of the sides passed added together
629 getBorderWidth : function(side){
630 return this.addStyles(side, borders);
634 * Gets the width of the padding(s) for the specified side(s)
635 * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
636 * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.
637 * @return {Number} The padding of the sides passed added together
639 getPadding : function(side){
640 return this.addStyles(side, paddings);
644 * Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove
645 * @return {Ext.core.Element} this
651 if(!data(dom, ISCLIPPED)){
652 data(dom, ISCLIPPED, true);
653 data(dom, ORIGINALCLIP, {
654 o: me.getStyle(OVERFLOW),
655 x: me.getStyle(OVERFLOWX),
656 y: me.getStyle(OVERFLOWY)
658 me.setStyle(OVERFLOW, HIDDEN);
659 me.setStyle(OVERFLOWX, HIDDEN);
660 me.setStyle(OVERFLOWY, HIDDEN);
666 * Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called
667 * @return {Ext.core.Element} this
674 if(data(dom, ISCLIPPED)){
675 data(dom, ISCLIPPED, false);
676 clip = data(dom, ORIGINALCLIP);
678 me.setStyle(OVERFLOW, o.o);
681 me.setStyle(OVERFLOWX, o.x);
684 me.setStyle(OVERFLOWY, o.y);
691 addStyles : function(sides, styles){
693 sidesArr = sides.match(wordsRe),
695 len = sidesArr.length,
697 for (; i < len; i++) {
699 size = side && parseInt(this.getStyle(styles[side]), 10);
701 totalSize += MATH.abs(size);
710 * More flexible version of {@link #setStyle} for setting style properties.
711 * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or
712 * a function which returns such a specification.
713 * @return {Ext.core.Element} this
715 applyStyles : function(style){
716 Ext.core.DomHelper.applyStyles(this.dom, style);
721 * Returns an object with properties matching the styles requested.
722 * For example, el.getStyles('color', 'font-size', 'width') might return
723 * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.
724 * @param {String} style1 A style name
725 * @param {String} style2 A style name
726 * @param {String} etc.
727 * @return {Object} The style object
729 getStyles : function(){
731 len = arguments.length,
734 for(; i < len; ++i) {
735 style = arguments[i];
736 styles[style] = this.getStyle(style);
742 * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as
743 * a gray container with a gradient background, rounded corners and a 4-way shadow.</p>
744 * <p>This special markup is used throughout Ext when box wrapping elements ({@link Ext.button.Button},
745 * {@link Ext.panel.Panel} when <tt>{@link Ext.panel.Panel#frame frame=true}</tt>, {@link Ext.window.Window}). The markup
746 * is of this form:</p>
748 Ext.core.Element.boxMarkup =
749 '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div>
750 <div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div>
751 <div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
753 * <p>Example usage:</p>
756 Ext.get("foo").boxWrap();
758 // You can also add a custom class and use CSS inheritance rules to customize the box look.
759 // 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example
760 // for how to create a custom box wrap style.
761 Ext.get("foo").boxWrap().addCls("x-box-blue");
763 * @param {String} class (optional) A base CSS class to apply to the containing wrapper element
764 * (defaults to <tt>'x-box'</tt>). Note that there are a number of CSS rules that are dependent on
765 * this name to make the overall effect work, so if you supply an alternate base class, make sure you
766 * also supply all of the necessary rules.
767 * @return {Ext.core.Element} The outermost wrapping element of the created box structure.
769 boxWrap : function(cls){
770 cls = cls || Ext.baseCSSPrefix + 'box';
771 var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + Ext.String.format(Ext.core.Element.boxMarkup, cls) + "</div>"));
772 Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
777 * Set the size of this Element. If animation is true, both width and height will be animated concurrently.
778 * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
779 * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
780 * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
781 * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>
783 * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
784 * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).</li>
785 * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
787 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
788 * @return {Ext.core.Element} this
790 setSize : function(width, height, animate){
792 if (Ext.isObject(width)) { // in case of object from getSize()
794 height = width.height;
797 width = me.adjustWidth(width);
798 height = me.adjustHeight(height);
799 if(!animate || !me.anim){
800 me.dom.style.width = me.addUnits(width);
801 me.dom.style.height = me.addUnits(height);
804 if (animate === true) {
807 me.animate(Ext.applyIf({
818 * Returns either the offsetHeight or the height of this element based on CSS height adjusted by padding or borders
819 * when needed to simulate offsetHeight when offsets aren't available. This may not work on display:none elements
820 * if a height has not been set using CSS.
823 getComputedHeight : function(){
825 h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
827 h = parseFloat(me.getStyle('height')) || 0;
828 if(!me.isBorderBox()){
829 h += me.getFrameWidth('tb');
836 * Returns either the offsetWidth or the width of this element based on CSS width adjusted by padding or borders
837 * when needed to simulate offsetWidth when offsets aren't available. This may not work on display:none elements
838 * if a width has not been set using CSS.
841 getComputedWidth : function(){
843 w = Math.max(me.dom.offsetWidth, me.dom.clientWidth);
846 w = parseFloat(me.getStyle('width')) || 0;
847 if(!me.isBorderBox()){
848 w += me.getFrameWidth('lr');
855 * Returns the sum width of the padding and borders for the passed "sides". See getBorderWidth()
856 for more information about the sides.
857 * @param {String} sides
860 getFrameWidth : function(sides, onlyContentBox){
861 return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
865 * Sets up event handlers to add and remove a css class when the mouse is over this element
866 * @param {String} className
867 * @return {Ext.core.Element} this
869 addClsOnOver : function(className){
873 Ext.fly(dom, INTERNAL).addCls(className);
876 Ext.fly(dom, INTERNAL).removeCls(className);
883 * Sets up event handlers to add and remove a css class when this element has the focus
884 * @param {String} className
885 * @return {Ext.core.Element} this
887 addClsOnFocus : function(className){
890 me.on("focus", function(){
891 Ext.fly(dom, INTERNAL).addCls(className);
893 me.on("blur", function(){
894 Ext.fly(dom, INTERNAL).removeCls(className);
900 * 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)
901 * @param {String} className
902 * @return {Ext.core.Element} this
904 addClsOnClick : function(className){
906 this.on("mousedown", function(){
907 Ext.fly(dom, INTERNAL).addCls(className);
908 var d = Ext.getDoc(),
910 Ext.fly(dom, INTERNAL).removeCls(className);
911 d.removeListener("mouseup", fn);
919 * <p>Returns the dimensions of the element available to lay content out in.<p>
920 * <p>If the element (or any ancestor element) has CSS style <code>display : none</code>, the dimensions will be zero.</p>
921 * example:<pre><code>
922 var vpSize = Ext.getBody().getViewSize();
924 // all Windows created afterwards will have a default value of 90% height and 95% width
925 Ext.Window.override({
926 width: vpSize.width * 0.9,
927 height: vpSize.height * 0.95
929 // To handle window resizing you would have to hook onto onWindowResize.
932 * getViewSize utilizes clientHeight/clientWidth which excludes sizing of scrollbars.
933 * To obtain the size including scrollbars, use getStyleSize
935 * Sizing of the document body is handled at the adapter level which handles special cases for IE and strict modes, etc.
938 getViewSize : function(){
941 isDoc = (dom == Ext.getDoc().dom || dom == Ext.getBody().dom),
942 style, overflow, ret;
944 // If the body, use static methods
947 width : Ext.core.Element.getViewWidth(),
948 height : Ext.core.Element.getViewHeight()
951 // Else use clientHeight/clientWidth
954 // IE 6 & IE Quirks mode acts more like a max-size measurement unless overflow is hidden during measurement.
955 // We will put the overflow back to it's original value when we are done measuring.
956 if (Ext.isIE6 || Ext.isIEQuirks) {
958 overflow = style.overflow;
959 me.setStyle({ overflow: 'hidden'});
962 width : dom.clientWidth,
963 height : dom.clientHeight
965 if (Ext.isIE6 || Ext.isIEQuirks) {
966 me.setStyle({ overflow: overflow });
973 * <p>Returns the dimensions of the element available to lay content out in.<p>
975 * getStyleSize utilizes prefers style sizing if present, otherwise it chooses the larger of offsetHeight/clientHeight and offsetWidth/clientWidth.
976 * To obtain the size excluding scrollbars, use getViewSize
978 * Sizing of the document body is handled at the adapter level which handles special cases for IE and strict modes, etc.
981 getStyleSize : function(){
985 isDoc = (d == doc || d == doc.body),
989 // If the body, use static methods
992 width : Ext.core.Element.getViewWidth(),
993 height : Ext.core.Element.getViewHeight()
996 // Use Styles if they are set
997 if(s.width && s.width != 'auto'){
998 w = parseFloat(s.width);
999 if(me.isBorderBox()){
1000 w -= me.getFrameWidth('lr');
1003 // Use Styles if they are set
1004 if(s.height && s.height != 'auto'){
1005 h = parseFloat(s.height);
1006 if(me.isBorderBox()){
1007 h -= me.getFrameWidth('tb');
1010 // Use getWidth/getHeight if style not set.
1011 return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
1015 * Returns the size of the element.
1016 * @param {Boolean} contentSize (optional) true to get the width/size minus borders and padding
1017 * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
1019 getSize : function(contentSize){
1020 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
1024 * Forces the browser to repaint this element
1025 * @return {Ext.core.Element} this
1027 repaint : function(){
1029 this.addCls(Ext.baseCSSPrefix + 'repaint');
1030 setTimeout(function(){
1031 Ext.fly(dom).removeCls(Ext.baseCSSPrefix + 'repaint');
1037 * Disables text selection for this element (normalized across browsers)
1038 * @return {Ext.core.Element} this
1040 unselectable : function(){
1042 me.dom.unselectable = "on";
1044 me.swallowEvent("selectstart", true);
1045 me.applyStyles("-moz-user-select:none;-khtml-user-select:none;");
1046 me.addCls(Ext.baseCSSPrefix + 'unselectable');
1052 * Returns an object with properties top, left, right and bottom representing the margins of this element unless sides is passed,
1053 * then it returns the calculated width of the sides (see getPadding)
1054 * @param {String} sides (optional) Any combination of l, r, t, b to get the sum of those sides
1055 * @return {Object/Number}
1057 getMargin : function(side){
1059 hash = {t:"top", l:"left", r:"right", b: "bottom"},
1064 for (key in me.margins){
1065 o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
1069 return me.addStyles.call(me, side, me.margins);