@qooxdoo/framework
Version:
The JS Framework for Coders
283 lines (251 loc) • 9.19 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2004-2009 1&1 Internet AG, Germany, http://www.1und1.de
License:
MIT: https://opensource.org/licenses/MIT
See the LICENSE file in the project's top-level directory for details.
Authors:
* Sebastian Werner (wpbasti)
* Fabian Jakobs (fjakobs)
************************************************************************ */
/**
* Contains support for calculating dimensions of HTML elements.
*
* We differ between the box (or border) size which is available via
* {@link #getWidth} and {@link #getHeight} and the content or scroll
* sizes which are available via {@link #getContentWidth} and
* {@link #getContentHeight}.
*/
qx.Bootstrap.define("qx.bom.element.Dimension", {
/*
*****************************************************************************
STATICS
*****************************************************************************
*/
statics: {
/**
* Returns the rendered width of the given element.
*
* This is the visible width of the object, which need not to be identical
* to the width configured via CSS. This highly depends on the current
* box-sizing for the document and maybe even for the element.
*
* @signature function(element)
* @param element {Element} element to query
* @return {Integer} width of the element
*/
getWidth(element) {
var rect = element.getBoundingClientRect();
return Math.round(rect.right - rect.left);
},
/**
* Returns the rendered height of the given element.
*
* This is the visible height of the object, which need not to be identical
* to the height configured via CSS. This highly depends on the current
* box-sizing for the document and maybe even for the element.
*
* @signature function(element)
* @param element {Element} element to query
* @return {Integer} height of the element
*/
getHeight(element) {
var rect = element.getBoundingClientRect();
return Math.round(rect.bottom - rect.top);
},
/**
* Returns the rendered size of the given element.
*
* @param element {Element} element to query
* @return {Map} map containing the width and height of the element
*/
getSize(element) {
return {
width: this.getWidth(element),
height: this.getHeight(element)
};
},
/**
* Returns the outer height of the given element, including height, vertical padding, and vertical borders
*
* @param element {Element} element to query
* @param includeMargins {Boolean?} whether to include margins in teh
* @return {Integer} the height of the element
*/
getOuterHeight(element, includeMargins) {
if (includeMargins) {
let marginTop = parseInt(
document.defaultView
.getComputedStyle(element, "")
.getPropertyValue("margin-top"),
10
);
let marginBottom = parseInt(
document.defaultView
.getComputedStyle(element, "")
.getPropertyValue("margin-bottom"),
10
);
return element.offsetHeight + marginTop + marginBottom;
}
return element.offsetHeight;
},
/**
* Returns the outer width of the given element, including height, vertical padding, and vertical borders
*
* @param element {Element} element to query
* @param includeMargins {Boolean?} whether to include margins in teh
* @return {Integer} the width of the element
*/
getOuterWidth(element, includeMargins) {
if (includeMargins) {
let marginLeft = parseInt(
document.defaultView
.getComputedStyle(element, "")
.getPropertyValue("margin-left"),
10
);
let marginRight = parseInt(
document.defaultView
.getComputedStyle(element, "")
.getPropertyValue("margin-right"),
10
);
return element.offsetWidth + marginLeft + marginRight;
}
return element.offsetWidth;
},
/**
* Returns the outer size of the given element, including height, vertical padding, and vertical borders
*
* @param element {Element} element to query
* @param includeMargins {Boolean?} whether to include margins in teh
* @return {Map} map containing the width and height of the element
*/
getOuterSize(element, includeMargins) {
return {
width: this.getOuterWidth(element, includeMargins),
height: this.getOuterHeight(element, includeMargins)
};
},
/** @type {Map} Contains all overflow values where scrollbars are invisible */
__hiddenScrollbars: {
visible: true,
hidden: true
},
/**
* Returns the content width.
*
* The content width is basically the maximum
* width used or the maximum width which can be used by the content. This
* excludes all kind of styles of the element like borders, paddings, margins,
* and even scrollbars.
*
* Please note that with visible scrollbars the content width returned
* may be larger than the box width returned via {@link #getWidth}.
*
* @param element {Element} element to query
* @return {Integer} Computed content width
*/
getContentWidth(element) {
var Style = qx.bom.element.Style;
var overflowX = qx.bom.element.Style.get(element, "overflowX");
var paddingLeft = parseInt(
Style.get(element, "paddingLeft") || "0px",
10
);
var paddingRight = parseInt(
Style.get(element, "paddingRight") || "0px",
10
);
if (this.__hiddenScrollbars[overflowX]) {
var contentWidth = element.clientWidth;
if (
qx.core.Environment.get("engine.name") == "opera" ||
qx.dom.Node.isBlockNode(element)
) {
contentWidth = contentWidth - paddingLeft - paddingRight;
}
// IE seems to return 0 on clientWidth if the element is 0px
// in height so we use the offsetWidth instead
if (qx.core.Environment.get("engine.name") == "mshtml") {
if (contentWidth === 0 && element.offsetHeight === 0) {
return element.offsetWidth;
}
}
return contentWidth;
} else {
if (element.clientWidth >= element.scrollWidth) {
// Scrollbars visible, but not needed? We need to substract both paddings
return (
Math.max(element.clientWidth, element.scrollWidth) -
paddingLeft -
paddingRight
);
} else {
// Scrollbars visible and needed. We just remove the left padding,
// as the right padding is not respected in rendering.
var width = element.scrollWidth - paddingLeft;
// IE renders the paddingRight as well with scrollbars on
if (qx.core.Environment.get("engine.name") == "mshtml") {
width -= paddingRight;
}
return width;
}
}
},
/**
* Returns the content height.
*
* The content height is basically the maximum
* height used or the maximum height which can be used by the content. This
* excludes all kind of styles of the element like borders, paddings, margins,
* and even scrollbars.
*
* Please note that with visible scrollbars the content height returned
* may be larger than the box height returned via {@link #getHeight}.
*
* @param element {Element} element to query
* @return {Integer} Computed content height
*/
getContentHeight(element) {
var Style = qx.bom.element.Style;
var overflowY = qx.bom.element.Style.get(element, "overflowY");
var paddingTop = parseInt(Style.get(element, "paddingTop") || "0px", 10);
var paddingBottom = parseInt(
Style.get(element, "paddingBottom") || "0px",
10
);
if (this.__hiddenScrollbars[overflowY]) {
return element.clientHeight - paddingTop - paddingBottom;
} else {
if (element.clientHeight >= element.scrollHeight) {
// Scrollbars visible, but not needed? We need to substract both paddings
return (
Math.max(element.clientHeight, element.scrollHeight) -
paddingTop -
paddingBottom
);
} else {
// Scrollbars visible and needed. We just remove the top padding,
// as the bottom padding is not respected in rendering.
return element.scrollHeight - paddingTop;
}
}
},
/**
* Returns the rendered content size of the given element.
*
* @param element {Element} element to query
* @return {Map} map containing the content width and height of the element
*/
getContentSize(element) {
return {
width: this.getContentWidth(element),
height: this.getContentHeight(element)
};
}
}
});