[76] | 1 | /*! |
---|
| 2 | * Ext JS Library 3.4.0 |
---|
| 3 | * Copyright(c) 2006-2011 Sencha Inc. |
---|
| 4 | * licensing@sencha.com |
---|
| 5 | * http://www.sencha.com/license |
---|
| 6 | */ |
---|
| 7 | /** |
---|
| 8 | * @class Ext.Element |
---|
| 9 | */ |
---|
| 10 | |
---|
| 11 | // special markup used throughout Ext when box wrapping elements |
---|
| 12 | Ext.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>'; |
---|
| 13 | |
---|
| 14 | Ext.Element.addMethods(function(){ |
---|
| 15 | var INTERNAL = "_internal", |
---|
| 16 | pxMatch = /(\d+\.?\d+)px/; |
---|
| 17 | return { |
---|
| 18 | /** |
---|
| 19 | * More flexible version of {@link #setStyle} for setting style properties. |
---|
| 20 | * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or |
---|
| 21 | * a function which returns such a specification. |
---|
| 22 | * @return {Ext.Element} this |
---|
| 23 | */ |
---|
| 24 | applyStyles : function(style){ |
---|
| 25 | Ext.DomHelper.applyStyles(this.dom, style); |
---|
| 26 | return this; |
---|
| 27 | }, |
---|
| 28 | |
---|
| 29 | /** |
---|
| 30 | * Returns an object with properties matching the styles requested. |
---|
| 31 | * For example, el.getStyles('color', 'font-size', 'width') might return |
---|
| 32 | * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}. |
---|
| 33 | * @param {String} style1 A style name |
---|
| 34 | * @param {String} style2 A style name |
---|
| 35 | * @param {String} etc. |
---|
| 36 | * @return {Object} The style object |
---|
| 37 | */ |
---|
| 38 | getStyles : function(){ |
---|
| 39 | var ret = {}; |
---|
| 40 | Ext.each(arguments, function(v) { |
---|
| 41 | ret[v] = this.getStyle(v); |
---|
| 42 | }, |
---|
| 43 | this); |
---|
| 44 | return ret; |
---|
| 45 | }, |
---|
| 46 | |
---|
| 47 | // private ==> used by ext full |
---|
| 48 | setOverflow : function(v){ |
---|
| 49 | var dom = this.dom; |
---|
| 50 | if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug |
---|
| 51 | dom.style.overflow = 'hidden'; |
---|
| 52 | (function(){dom.style.overflow = 'auto';}).defer(1); |
---|
| 53 | }else{ |
---|
| 54 | dom.style.overflow = v; |
---|
| 55 | } |
---|
| 56 | }, |
---|
| 57 | |
---|
| 58 | /** |
---|
| 59 | * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as |
---|
| 60 | * a gray container with a gradient background, rounded corners and a 4-way shadow.</p> |
---|
| 61 | * <p>This special markup is used throughout Ext when box wrapping elements ({@link Ext.Button}, |
---|
| 62 | * {@link Ext.Panel} when <tt>{@link Ext.Panel#frame frame=true}</tt>, {@link Ext.Window}). The markup |
---|
| 63 | * is of this form:</p> |
---|
| 64 | * <pre><code> |
---|
| 65 | Ext.Element.boxMarkup = |
---|
| 66 | '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div> |
---|
| 67 | <div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div> |
---|
| 68 | <div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>'; |
---|
| 69 | * </code></pre> |
---|
| 70 | * <p>Example usage:</p> |
---|
| 71 | * <pre><code> |
---|
| 72 | // Basic box wrap |
---|
| 73 | Ext.get("foo").boxWrap(); |
---|
| 74 | |
---|
| 75 | // You can also add a custom class and use CSS inheritance rules to customize the box look. |
---|
| 76 | // 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example |
---|
| 77 | // for how to create a custom box wrap style. |
---|
| 78 | Ext.get("foo").boxWrap().addClass("x-box-blue"); |
---|
| 79 | * </code></pre> |
---|
| 80 | * @param {String} class (optional) A base CSS class to apply to the containing wrapper element |
---|
| 81 | * (defaults to <tt>'x-box'</tt>). Note that there are a number of CSS rules that are dependent on |
---|
| 82 | * this name to make the overall effect work, so if you supply an alternate base class, make sure you |
---|
| 83 | * also supply all of the necessary rules. |
---|
| 84 | * @return {Ext.Element} The outermost wrapping element of the created box structure. |
---|
| 85 | */ |
---|
| 86 | boxWrap : function(cls){ |
---|
| 87 | cls = cls || 'x-box'; |
---|
| 88 | var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>")); //String.format('<div class="{0}">'+Ext.Element.boxMarkup+'</div>', cls))); |
---|
| 89 | Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom); |
---|
| 90 | return el; |
---|
| 91 | }, |
---|
| 92 | |
---|
| 93 | /** |
---|
| 94 | * Set the size of this Element. If animation is true, both width and height will be animated concurrently. |
---|
| 95 | * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul> |
---|
| 96 | * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li> |
---|
| 97 | * <li>A String used to set the CSS width style. Animation may <b>not</b> be used. |
---|
| 98 | * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li> |
---|
| 99 | * </ul></div> |
---|
| 100 | * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul> |
---|
| 101 | * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).</li> |
---|
| 102 | * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li> |
---|
| 103 | * </ul></div> |
---|
| 104 | * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object |
---|
| 105 | * @return {Ext.Element} this |
---|
| 106 | */ |
---|
| 107 | setSize : function(width, height, animate){ |
---|
| 108 | var me = this; |
---|
| 109 | if(typeof width == 'object'){ // in case of object from getSize() |
---|
| 110 | height = width.height; |
---|
| 111 | width = width.width; |
---|
| 112 | } |
---|
| 113 | width = me.adjustWidth(width); |
---|
| 114 | height = me.adjustHeight(height); |
---|
| 115 | if(!animate || !me.anim){ |
---|
| 116 | me.dom.style.width = me.addUnits(width); |
---|
| 117 | me.dom.style.height = me.addUnits(height); |
---|
| 118 | }else{ |
---|
| 119 | me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2)); |
---|
| 120 | } |
---|
| 121 | return me; |
---|
| 122 | }, |
---|
| 123 | |
---|
| 124 | /** |
---|
| 125 | * Returns either the offsetHeight or the height of this element based on CSS height adjusted by padding or borders |
---|
| 126 | * when needed to simulate offsetHeight when offsets aren't available. This may not work on display:none elements |
---|
| 127 | * if a height has not been set using CSS. |
---|
| 128 | * @return {Number} |
---|
| 129 | */ |
---|
| 130 | getComputedHeight : function(){ |
---|
| 131 | var me = this, |
---|
| 132 | h = Math.max(me.dom.offsetHeight, me.dom.clientHeight); |
---|
| 133 | if(!h){ |
---|
| 134 | h = parseFloat(me.getStyle('height')) || 0; |
---|
| 135 | if(!me.isBorderBox()){ |
---|
| 136 | h += me.getFrameWidth('tb'); |
---|
| 137 | } |
---|
| 138 | } |
---|
| 139 | return h; |
---|
| 140 | }, |
---|
| 141 | |
---|
| 142 | /** |
---|
| 143 | * Returns either the offsetWidth or the width of this element based on CSS width adjusted by padding or borders |
---|
| 144 | * when needed to simulate offsetWidth when offsets aren't available. This may not work on display:none elements |
---|
| 145 | * if a width has not been set using CSS. |
---|
| 146 | * @return {Number} |
---|
| 147 | */ |
---|
| 148 | getComputedWidth : function(){ |
---|
| 149 | var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth); |
---|
| 150 | if(!w){ |
---|
| 151 | w = parseFloat(this.getStyle('width')) || 0; |
---|
| 152 | if(!this.isBorderBox()){ |
---|
| 153 | w += this.getFrameWidth('lr'); |
---|
| 154 | } |
---|
| 155 | } |
---|
| 156 | return w; |
---|
| 157 | }, |
---|
| 158 | |
---|
| 159 | /** |
---|
| 160 | * Returns the sum width of the padding and borders for the passed "sides". See getBorderWidth() |
---|
| 161 | for more information about the sides. |
---|
| 162 | * @param {String} sides |
---|
| 163 | * @return {Number} |
---|
| 164 | */ |
---|
| 165 | getFrameWidth : function(sides, onlyContentBox){ |
---|
| 166 | return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides)); |
---|
| 167 | }, |
---|
| 168 | |
---|
| 169 | /** |
---|
| 170 | * Sets up event handlers to add and remove a css class when the mouse is over this element |
---|
| 171 | * @param {String} className |
---|
| 172 | * @return {Ext.Element} this |
---|
| 173 | */ |
---|
| 174 | addClassOnOver : function(className){ |
---|
| 175 | this.hover( |
---|
| 176 | function(){ |
---|
| 177 | Ext.fly(this, INTERNAL).addClass(className); |
---|
| 178 | }, |
---|
| 179 | function(){ |
---|
| 180 | Ext.fly(this, INTERNAL).removeClass(className); |
---|
| 181 | } |
---|
| 182 | ); |
---|
| 183 | return this; |
---|
| 184 | }, |
---|
| 185 | |
---|
| 186 | /** |
---|
| 187 | * Sets up event handlers to add and remove a css class when this element has the focus |
---|
| 188 | * @param {String} className |
---|
| 189 | * @return {Ext.Element} this |
---|
| 190 | */ |
---|
| 191 | addClassOnFocus : function(className){ |
---|
| 192 | this.on("focus", function(){ |
---|
| 193 | Ext.fly(this, INTERNAL).addClass(className); |
---|
| 194 | }, this.dom); |
---|
| 195 | this.on("blur", function(){ |
---|
| 196 | Ext.fly(this, INTERNAL).removeClass(className); |
---|
| 197 | }, this.dom); |
---|
| 198 | return this; |
---|
| 199 | }, |
---|
| 200 | |
---|
| 201 | /** |
---|
| 202 | * 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) |
---|
| 203 | * @param {String} className |
---|
| 204 | * @return {Ext.Element} this |
---|
| 205 | */ |
---|
| 206 | addClassOnClick : function(className){ |
---|
| 207 | var dom = this.dom; |
---|
| 208 | this.on("mousedown", function(){ |
---|
| 209 | Ext.fly(dom, INTERNAL).addClass(className); |
---|
| 210 | var d = Ext.getDoc(), |
---|
| 211 | fn = function(){ |
---|
| 212 | Ext.fly(dom, INTERNAL).removeClass(className); |
---|
| 213 | d.removeListener("mouseup", fn); |
---|
| 214 | }; |
---|
| 215 | d.on("mouseup", fn); |
---|
| 216 | }); |
---|
| 217 | return this; |
---|
| 218 | }, |
---|
| 219 | |
---|
| 220 | /** |
---|
| 221 | * <p>Returns the dimensions of the element available to lay content out in.<p> |
---|
| 222 | * <p>If the element (or any ancestor element) has CSS style <code>display : none</code>, the dimensions will be zero.</p> |
---|
| 223 | * example:<pre><code> |
---|
| 224 | var vpSize = Ext.getBody().getViewSize(); |
---|
| 225 | |
---|
| 226 | // all Windows created afterwards will have a default value of 90% height and 95% width |
---|
| 227 | Ext.Window.override({ |
---|
| 228 | width: vpSize.width * 0.9, |
---|
| 229 | height: vpSize.height * 0.95 |
---|
| 230 | }); |
---|
| 231 | // To handle window resizing you would have to hook onto onWindowResize. |
---|
| 232 | * </code></pre> |
---|
| 233 | * |
---|
| 234 | * getViewSize utilizes clientHeight/clientWidth which excludes sizing of scrollbars. |
---|
| 235 | * To obtain the size including scrollbars, use getStyleSize |
---|
| 236 | * |
---|
| 237 | * Sizing of the document body is handled at the adapter level which handles special cases for IE and strict modes, etc. |
---|
| 238 | */ |
---|
| 239 | |
---|
| 240 | getViewSize : function(){ |
---|
| 241 | var doc = document, |
---|
| 242 | d = this.dom, |
---|
| 243 | isDoc = (d == doc || d == doc.body); |
---|
| 244 | |
---|
| 245 | // If the body, use Ext.lib.Dom |
---|
| 246 | if (isDoc) { |
---|
| 247 | var extdom = Ext.lib.Dom; |
---|
| 248 | return { |
---|
| 249 | width : extdom.getViewWidth(), |
---|
| 250 | height : extdom.getViewHeight() |
---|
| 251 | }; |
---|
| 252 | |
---|
| 253 | // Else use clientHeight/clientWidth |
---|
| 254 | } else { |
---|
| 255 | return { |
---|
| 256 | width : d.clientWidth, |
---|
| 257 | height : d.clientHeight |
---|
| 258 | }; |
---|
| 259 | } |
---|
| 260 | }, |
---|
| 261 | |
---|
| 262 | /** |
---|
| 263 | * <p>Returns the dimensions of the element available to lay content out in.<p> |
---|
| 264 | * |
---|
| 265 | * getStyleSize utilizes prefers style sizing if present, otherwise it chooses the larger of offsetHeight/clientHeight and offsetWidth/clientWidth. |
---|
| 266 | * To obtain the size excluding scrollbars, use getViewSize |
---|
| 267 | * |
---|
| 268 | * Sizing of the document body is handled at the adapter level which handles special cases for IE and strict modes, etc. |
---|
| 269 | */ |
---|
| 270 | |
---|
| 271 | getStyleSize : function(){ |
---|
| 272 | var me = this, |
---|
| 273 | w, h, |
---|
| 274 | doc = document, |
---|
| 275 | d = this.dom, |
---|
| 276 | isDoc = (d == doc || d == doc.body), |
---|
| 277 | s = d.style; |
---|
| 278 | |
---|
| 279 | // If the body, use Ext.lib.Dom |
---|
| 280 | if (isDoc) { |
---|
| 281 | var extdom = Ext.lib.Dom; |
---|
| 282 | return { |
---|
| 283 | width : extdom.getViewWidth(), |
---|
| 284 | height : extdom.getViewHeight() |
---|
| 285 | }; |
---|
| 286 | } |
---|
| 287 | // Use Styles if they are set |
---|
| 288 | if(s.width && s.width != 'auto'){ |
---|
| 289 | w = parseFloat(s.width); |
---|
| 290 | if(me.isBorderBox()){ |
---|
| 291 | w -= me.getFrameWidth('lr'); |
---|
| 292 | } |
---|
| 293 | } |
---|
| 294 | // Use Styles if they are set |
---|
| 295 | if(s.height && s.height != 'auto'){ |
---|
| 296 | h = parseFloat(s.height); |
---|
| 297 | if(me.isBorderBox()){ |
---|
| 298 | h -= me.getFrameWidth('tb'); |
---|
| 299 | } |
---|
| 300 | } |
---|
| 301 | // Use getWidth/getHeight if style not set. |
---|
| 302 | return {width: w || me.getWidth(true), height: h || me.getHeight(true)}; |
---|
| 303 | }, |
---|
| 304 | |
---|
| 305 | /** |
---|
| 306 | * Returns the size of the element. |
---|
| 307 | * @param {Boolean} contentSize (optional) true to get the width/size minus borders and padding |
---|
| 308 | * @return {Object} An object containing the element's size {width: (element width), height: (element height)} |
---|
| 309 | */ |
---|
| 310 | getSize : function(contentSize){ |
---|
| 311 | return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)}; |
---|
| 312 | }, |
---|
| 313 | |
---|
| 314 | /** |
---|
| 315 | * Forces the browser to repaint this element |
---|
| 316 | * @return {Ext.Element} this |
---|
| 317 | */ |
---|
| 318 | repaint : function(){ |
---|
| 319 | var dom = this.dom; |
---|
| 320 | this.addClass("x-repaint"); |
---|
| 321 | setTimeout(function(){ |
---|
| 322 | Ext.fly(dom).removeClass("x-repaint"); |
---|
| 323 | }, 1); |
---|
| 324 | return this; |
---|
| 325 | }, |
---|
| 326 | |
---|
| 327 | /** |
---|
| 328 | * Disables text selection for this element (normalized across browsers) |
---|
| 329 | * @return {Ext.Element} this |
---|
| 330 | */ |
---|
| 331 | unselectable : function(){ |
---|
| 332 | this.dom.unselectable = "on"; |
---|
| 333 | return this.swallowEvent("selectstart", true). |
---|
| 334 | applyStyles("-moz-user-select:none;-khtml-user-select:none;"). |
---|
| 335 | addClass("x-unselectable"); |
---|
| 336 | }, |
---|
| 337 | |
---|
| 338 | /** |
---|
| 339 | * Returns an object with properties top, left, right and bottom representing the margins of this element unless sides is passed, |
---|
| 340 | * then it returns the calculated width of the sides (see getPadding) |
---|
| 341 | * @param {String} sides (optional) Any combination of l, r, t, b to get the sum of those sides |
---|
| 342 | * @return {Object/Number} |
---|
| 343 | */ |
---|
| 344 | getMargins : function(side){ |
---|
| 345 | var me = this, |
---|
| 346 | key, |
---|
| 347 | hash = {t:"top", l:"left", r:"right", b: "bottom"}, |
---|
| 348 | o = {}; |
---|
| 349 | |
---|
| 350 | if (!side) { |
---|
| 351 | for (key in me.margins){ |
---|
| 352 | o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0; |
---|
| 353 | } |
---|
| 354 | return o; |
---|
| 355 | } else { |
---|
| 356 | return me.addStyles.call(me, side, me.margins); |
---|
| 357 | } |
---|
| 358 | } |
---|
| 359 | }; |
---|
| 360 | }()); |
---|