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.
20 var ELEMENT = Ext.Element,
25 POSITION = "position",
27 RELATIVE = "relative",
31 Ext.override(Ext.Element, {
33 * Gets the current X position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
34 * @return {Number} The X position of the element
37 return ELEMENT.getX(this.dom);
41 * Gets the current Y position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
42 * @return {Number} The Y position of the element
45 return ELEMENT.getY(this.dom);
49 * Gets the current position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
50 * @return {Number[]} The XY position of the element
53 return ELEMENT.getXY(this.dom);
57 * Returns the offsets of this element from the passed element. Both element must be part of the DOM tree and not have display:none to have page coordinates.
58 * @param {String/HTMLElement/Ext.Element} element The element to get the offsets from.
59 * @return {Number[]} The XY page offsets (e.g. [100, -200])
61 getOffsetsTo : function(el){
63 e = Ext.fly(el, '_internal').getXY();
64 return [o[0]-e[0],o[1]-e[1]];
68 * Sets the X position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
69 * @param {Number} The X position of the element
70 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
71 * @return {Ext.Element} this
73 setX : function(x, animate){
74 return this.setXY([x, this.getY()], animate);
78 * Sets the Y position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
79 * @param {Number} The Y position of the element
80 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
81 * @return {Ext.Element} this
83 setY : function(y, animate){
84 return this.setXY([this.getX(), y], animate);
88 * Sets the element's left position directly using CSS style (instead of {@link #setX}).
89 * @param {String} left The left CSS property value
90 * @return {Ext.Element} this
92 setLeft : function(left){
93 this.setStyle(LEFT, this.addUnits(left));
98 * Sets the element's top position directly using CSS style (instead of {@link #setY}).
99 * @param {String} top The top CSS property value
100 * @return {Ext.Element} this
102 setTop : function(top){
103 this.setStyle(TOP, this.addUnits(top));
108 * Sets the element's CSS right style.
109 * @param {String} right The right CSS property value
110 * @return {Ext.Element} this
112 setRight : function(right){
113 this.setStyle(RIGHT, this.addUnits(right));
118 * Sets the element's CSS bottom style.
119 * @param {String} bottom The bottom CSS property value
120 * @return {Ext.Element} this
122 setBottom : function(bottom){
123 this.setStyle(BOTTOM, this.addUnits(bottom));
128 * Sets the position of the element in page coordinates, regardless of how the element is positioned.
129 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
130 * @param {Number[]} pos Contains X & Y [x, y] values for new position (coordinates are page-based)
131 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
132 * @return {Ext.Element} this
134 setXY: function(pos, animate) {
136 if (!animate || !me.anim) {
137 ELEMENT.setXY(me.dom, pos);
140 if (!Ext.isObject(animate)) {
143 me.animate(Ext.applyIf({ to: { x: pos[0], y: pos[1] } }, animate));
149 * Sets the position of the element in page coordinates, regardless of how the element is positioned.
150 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
151 * @param {Number} x X value for new position (coordinates are page-based)
152 * @param {Number} y Y value for new position (coordinates are page-based)
153 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
154 * @return {Ext.Element} this
156 setLocation : function(x, y, animate){
157 return this.setXY([x, y], animate);
161 * Sets the position of the element in page coordinates, regardless of how the element is positioned.
162 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
163 * @param {Number} x X value for new position (coordinates are page-based)
164 * @param {Number} y Y value for new position (coordinates are page-based)
165 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
166 * @return {Ext.Element} this
168 moveTo : function(x, y, animate){
169 return this.setXY([x, y], animate);
173 * Gets the left X coordinate
174 * @param {Boolean} local True to get the local css position instead of page coordinate
177 getLeft : function(local){
178 return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
182 * Gets the right X coordinate of the element (element X position + element width)
183 * @param {Boolean} local True to get the local css position instead of page coordinate
186 getRight : function(local){
188 return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
192 * Gets the top Y coordinate
193 * @param {Boolean} local True to get the local css position instead of page coordinate
196 getTop : function(local) {
197 return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
201 * Gets the bottom Y coordinate of the element (element Y position + element height)
202 * @param {Boolean} local True to get the local css position instead of page coordinate
205 getBottom : function(local){
207 return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
211 * Initializes positioning on this element. If a desired position is not passed, it will make the
212 * the element positioned relative IF it is not already positioned.
213 * @param {String} pos (optional) Positioning to use "relative", "absolute" or "fixed"
214 * @param {Number} zIndex (optional) The zIndex to apply
215 * @param {Number} x (optional) Set the page X position
216 * @param {Number} y (optional) Set the page Y position
218 position : function(pos, zIndex, x, y) {
221 if (!pos && me.isStyle(POSITION, STATIC)){
222 me.setStyle(POSITION, RELATIVE);
224 me.setStyle(POSITION, pos);
227 me.setStyle(ZINDEX, zIndex);
230 me.setXY([x || false, y || false]);
235 * Clear positioning back to the default when the document was loaded
236 * @param {String} value (optional) The value to use for the left,right,top,bottom, defaults to '' (empty string). You could use 'auto'.
237 * @return {Ext.Element} this
239 clearPositioning : function(value){
253 * Gets an object with all CSS positioning properties. Useful along with setPostioning to get
254 * snapshot before performing an update and then restoring the element.
257 getPositioning : function(){
258 var l = this.getStyle(LEFT);
259 var t = this.getStyle(TOP);
261 "position" : this.getStyle(POSITION),
263 "right" : l ? "" : this.getStyle(RIGHT),
265 "bottom" : t ? "" : this.getStyle(BOTTOM),
266 "z-index" : this.getStyle(ZINDEX)
271 * Set positioning with an object returned by getPositioning().
272 * @param {Object} posCfg
273 * @return {Ext.Element} this
275 setPositioning : function(pc){
277 style = me.dom.style;
281 if(pc.right == AUTO){
284 if(pc.bottom == AUTO){
292 * Translates the passed page coordinates into left/top css values for this element
293 * @param {Number/Number[]} x The page x or an array containing [x, y]
294 * @param {Number} y (optional) The page y, required if x is not an array
295 * @return {Object} An object with left and top properties. e.g. {left: (value), top: (value)}
297 translatePoints: function(x, y) {
298 if (Ext.isArray(x)) {
303 relative = me.isStyle(POSITION, RELATIVE),
305 left = parseInt(me.getStyle(LEFT), 10),
306 top = parseInt(me.getStyle(TOP), 10);
308 if (!Ext.isNumber(left)) {
309 left = relative ? 0 : me.dom.offsetLeft;
311 if (!Ext.isNumber(top)) {
312 top = relative ? 0 : me.dom.offsetTop;
314 left = (Ext.isNumber(x)) ? x - o[0] + left : undefined;
315 top = (Ext.isNumber(y)) ? y - o[1] + top : undefined;
323 * Sets the element's box. Use getBox() on another element to get a box obj. If animate is true then width, height, x and y will be animated concurrently.
324 * @param {Object} box The box to fill {x, y, width, height}
325 * @param {Boolean} adjust (optional) Whether to adjust for box-model issues automatically
326 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
327 * @return {Ext.Element} this
329 setBox: function(box, adjust, animate) {
333 if ((adjust && !me.autoBoxAdjust) && !me.isBorderBox()) {
334 w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
335 h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
337 me.setBounds(box.x, box.y, w, h, animate);
342 * Return an object defining the area of this Element which can be passed to {@link #setBox} to
343 * set another Element's size/location to match this element.
344 * @param {Boolean} contentBox (optional) If true a box for the content of the element is returned.
345 * @param {Boolean} local (optional) If true the element's left and top are returned instead of page x/y.
346 * @return {Object} box An object in the format<pre><code>
348 x: <Element's X position>,
349 y: <Element's Y position>,
350 width: <Element's width>,
351 height: <Element's height>,
352 bottom: <Element's lower bound>,
353 right: <Element's rightmost bound>
356 * The returned object may also be addressed as an Array where index 0 contains the X position
357 * and index 1 contains the Y position. So the result may also be used for {@link #setXY}
359 getBox: function(contentBox, local) {
364 getBorderWidth = me.getBorderWidth,
365 getPadding = me.getPadding,
366 l, r, t, b, w, h, bx;
370 left = parseInt(me.getStyle("left"), 10) || 0;
371 top = parseInt(me.getStyle("top"), 10) || 0;
386 l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
387 r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
388 t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
389 b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
399 bx.right = bx.x + bx.width;
400 bx.bottom = bx.y + bx.height;
405 * Move this element relative to its current position.
406 * @param {String} direction Possible values are: "l" (or "left"), "r" (or "right"), "t" (or "top", or "up"), "b" (or "bottom", or "down").
407 * @param {Number} distance How far to move the element in pixels
408 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
410 move: function(direction, distance, animate) {
415 left = [x - distance, y],
416 right = [x + distance, y],
417 top = [x, y - distance],
418 bottom = [x, y + distance],
432 direction = direction.toLowerCase();
433 me.moveTo(hash[direction][0], hash[direction][1], animate);
437 * Quick set left and top adding default units
438 * @param {String} left The left CSS property value
439 * @param {String} top The top CSS property value
440 * @return {Ext.Element} this
442 setLeftTop: function(left, top) {
444 style = me.dom.style;
445 style.left = me.addUnits(left);
446 style.top = me.addUnits(top);
451 * Returns the region of this element.
452 * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
453 * @return {Ext.util.Region} A Region containing "top, left, bottom, right" member data.
455 getRegion: function() {
456 return this.getPageBox(true);
460 * Returns the <b>content</b> region of this element. That is the region within the borders and padding.
461 * @return {Ext.util.Region} A Region containing "top, left, bottom, right" member data.
463 getViewRegion: function() {
465 isBody = me.dom === document.body,
466 scroll, pos, top, left, width, height;
468 // For the body we want to do some special logic
470 scroll = me.getScroll();
473 width = Ext.Element.getViewportWidth();
474 height = Ext.Element.getViewportHeight();
478 left = pos[0] + me.getBorderWidth('l') + me.getPadding('l');
479 top = pos[1] + me.getBorderWidth('t') + me.getPadding('t');
480 width = me.getWidth(true);
481 height = me.getHeight(true);
484 return Ext.create('Ext.util.Region', top, left + width, top + height, left);
488 * Return an object defining the area of this Element which can be passed to {@link #setBox} to
489 * set another Element's size/location to match this element.
490 * @param {Boolean} asRegion(optional) If true an Ext.util.Region will be returned
491 * @return {Object} box An object in the format<pre><code>
493 x: <Element's X position>,
494 y: <Element's Y position>,
495 width: <Element's width>,
496 height: <Element's height>,
497 bottom: <Element's lower bound>,
498 right: <Element's rightmost bound>
501 * The returned object may also be addressed as an Array where index 0 contains the X position
502 * and index 1 contains the Y position. So the result may also be used for {@link #setXY}
504 getPageBox : function(getRegion) {
507 isDoc = el === document.body,
508 w = isDoc ? Ext.Element.getViewWidth() : el.offsetWidth,
509 h = isDoc ? Ext.Element.getViewHeight() : el.offsetHeight,
517 return Ext.create('Ext.util.Region', t, r, b, l);
532 * Sets the element's position and size in one shot. If animation is true then width, height, x and y will be animated concurrently.
533 * @param {Number} x X value for new position (coordinates are page-based)
534 * @param {Number} y Y value for new position (coordinates are page-based)
535 * @param {Number/String} width The new width. This may be one of:<div class="mdetail-params"><ul>
536 * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels)</li>
537 * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
539 * @param {Number/String} height The new height. This may be one of:<div class="mdetail-params"><ul>
540 * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels)</li>
541 * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
543 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
544 * @return {Ext.Element} this
546 setBounds: function(x, y, width, height, animate) {
548 if (!animate || !me.anim) {
549 me.setSize(width, height);
550 me.setLocation(x, y);
552 if (!Ext.isObject(animate)) {
555 me.animate(Ext.applyIf({
559 width: me.adjustWidth(width),
560 height: me.adjustHeight(height)
568 * Sets the element's position and size the specified region. If animation is true then width, height, x and y will be animated concurrently.
569 * @param {Ext.util.Region} region The region to fill
570 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
571 * @return {Ext.Element} this
573 setRegion: function(region, animate) {
574 return this.setBounds(region.left, region.top, region.right - region.left, region.bottom - region.top, animate);