web-apps/vendor/touch/src/dom/Element.position.js
2016-09-14 15:04:28 +03:00

301 lines
9.6 KiB
JavaScript

//@tag dom,core
//@define Ext.Element-all
//@define Ext.Element-position
//@require Ext.Element-insertion
/**
* @class Ext.dom.Element
*/
Ext.dom.Element.override({
/**
* 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`).
* @return {Number} The X position of the element
*/
getX: function() {
return this.getXY()[0];
},
/**
* 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`).
* @return {Number} The Y position of the element
*/
getY: function() {
return this.getXY()[1];
},
/**
* 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`).
* @return {Array} The XY position of the element
*/
getXY: function() {
var rect = this.dom.getBoundingClientRect(),
round = Math.round;
return [round(rect.left + window.pageXOffset), round(rect.top + window.pageYOffset)];
},
/**
* 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.
* @param {Mixed} element The element to get the offsets from.
* @return {Array} The XY page offsets (e.g. [100, -200])
*/
getOffsetsTo: function(el) {
var o = this.getXY(),
e = Ext.fly(el, '_internal').getXY();
return [o[0] - e[0], o[1] - e[1]];
},
/**
* 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`).
* @param {Number} x The X position of the element
* @return {Ext.dom.Element} this
*/
setX: function(x) {
return this.setXY([x, this.getY()]);
},
/**
* 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`).
* @param {Number} y The Y position of the element.
* @return {Ext.dom.Element} this
*/
setY: function(y) {
return this.setXY([this.getX(), y]);
},
/**
* Sets the position of the element in page coordinates, regardless of how the element is positioned.
* The element must be part of the DOM tree to have page coordinates (`display:none` or elements not appended return `false`).
* @param {Number[]} pos Contains X & Y [x, y] values for new position (coordinates are page-based).
* @return {Ext.dom.Element} this
*/
setXY: function(pos) {
var me = this;
if (arguments.length > 1) {
pos = [pos, arguments[1]];
}
// me.position();
var pts = me.translatePoints(pos),
style = me.dom.style;
for (pos in pts) {
if (!pts.hasOwnProperty(pos)) {
continue;
}
if (!isNaN(pts[pos])) style[pos] = pts[pos] + "px";
}
return me;
},
/**
* Gets the left X coordinate.
* @return {Number}
*/
getLeft: function() {
return parseInt(this.getStyle('left'), 10) || 0;
},
/**
* Gets the right X coordinate of the element (element X position + element width).
* @return {Number}
*/
getRight: function() {
return parseInt(this.getStyle('right'), 10) || 0;
},
/**
* Gets the top Y coordinate.
* @return {Number}
*/
getTop: function() {
return parseInt(this.getStyle('top'), 10) || 0;
},
/**
* Gets the bottom Y coordinate of the element (element Y position + element height).
* @return {Number}
*/
getBottom: function() {
return parseInt(this.getStyle('bottom'), 10) || 0;
},
/**
* Translates the passed page coordinates into left/top CSS values for this element.
* @param {Number/Array} x The page `x` or an array containing [x, y].
* @param {Number} y (optional) The page `y`, required if `x` is not an array.
* @return {Object} An object with `left` and `top` properties. e.g. `{left: (value), top: (value)}`.
*/
translatePoints: function(x, y) {
y = isNaN(x[1]) ? y : x[1];
x = isNaN(x[0]) ? x : x[0];
var me = this,
relative = me.isStyle('position', 'relative'),
o = me.getXY(),
l = parseInt(me.getStyle('left'), 10),
t = parseInt(me.getStyle('top'), 10);
l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);
return {left: (x - o[0] + l), top: (y - o[1] + t)};
},
/**
* Sets the element's box. Use {@link #getBox} on another element to get a box object.
* @param {Object} box The box to fill, for example:
*
* {
* left: ...,
* top: ...,
* width: ...,
* height: ...
* }
*
* @return {Ext.dom.Element} this
*/
setBox: function(box) {
var me = this,
width = box.width,
height = box.height,
top = box.top,
left = box.left;
if (left !== undefined) {
me.setLeft(left);
}
if (top !== undefined) {
me.setTop(top);
}
if (width !== undefined) {
me.setWidth(width);
}
if (height !== undefined) {
me.setHeight(height);
}
return this;
},
/**
* Return an object defining the area of this Element which can be passed to {@link #setBox} to
* set another Element's size/location to match this element.
*
* The returned object may also be addressed as an Array where index 0 contains the X position
* and index 1 contains the Y position. So the result may also be used for {@link #setXY}.
*
* @param {Boolean} contentBox (optional) If `true` a box for the content of the element is returned.
* @param {Boolean} local (optional) If `true` the element's left and top are returned instead of page x/y.
* @return {Object} An object in the format
* @return {Number} return.x The element's X position.
* @return {Number} return.y The element's Y position.
* @return {Number} return.width The element's width.
* @return {Number} return.height The element's height.
* @return {Number} return.bottom The element's lower bound.
* @return {Number} return.right The element's rightmost bound.
*/
getBox: function(contentBox, local) {
var me = this,
dom = me.dom,
width = dom.offsetWidth,
height = dom.offsetHeight,
xy, box, l, r, t, b;
if (!local) {
xy = me.getXY();
}
else if (contentBox) {
xy = [0, 0];
}
else {
xy = [parseInt(me.getStyle("left"), 10) || 0, parseInt(me.getStyle("top"), 10) || 0];
}
if (!contentBox) {
box = {
x: xy[0],
y: xy[1],
0: xy[0],
1: xy[1],
width: width,
height: height
};
}
else {
l = me.getBorderWidth.call(me, "l") + me.getPadding.call(me, "l");
r = me.getBorderWidth.call(me, "r") + me.getPadding.call(me, "r");
t = me.getBorderWidth.call(me, "t") + me.getPadding.call(me, "t");
b = me.getBorderWidth.call(me, "b") + me.getPadding.call(me, "b");
box = {
x: xy[0] + l,
y: xy[1] + t,
0: xy[0] + l,
1: xy[1] + t,
width: width - (l + r),
height: height - (t + b)
};
}
box.left = box.x;
box.top = box.y;
box.right = box.x + box.width;
box.bottom = box.y + box.height;
return box;
},
/**
* Return an object defining the area of this Element which can be passed to {@link #setBox} to
* set another Element's size/location to match this element.
* @param {Boolean} asRegion (optional) If `true` an {@link Ext.util.Region} will be returned.
* @return {Object} box An object in the format:
*
* {
* x: <Element's X position>,
* y: <Element's Y position>,
* width: <Element's width>,
* height: <Element's height>,
* bottom: <Element's lower bound>,
* right: <Element's rightmost bound>
* }
*
* The returned object may also be addressed as an Array where index 0 contains the X position
* and index 1 contains the Y position. So the result may also be used for {@link #setXY}.
*/
getPageBox: function(getRegion) {
var me = this,
el = me.dom;
if (!el) {
return new Ext.util.Region();
}
var w = el.offsetWidth,
h = el.offsetHeight,
xy = me.getXY(),
t = xy[1],
r = xy[0] + w,
b = xy[1] + h,
l = xy[0];
if (getRegion) {
return new Ext.util.Region(t, r, b, l);
}
else {
return {
left: l,
top: t,
width: w,
height: h,
right: r,
bottom: b
};
}
}
});