@discoveryjs/discovery
Version:
Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards
82 lines (81 loc) • 2.53 kB
JavaScript
const { documentElement, compatMode } = document;
const standardsMode = compatMode === "CSS1Compat";
export function getOffsetParent(node) {
let offsetParent = node.offsetParent;
while (offsetParent !== null && offsetParent !== documentElement && getComputedStyle(offsetParent).position === "static") {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || documentElement;
}
export function getOverflowParent(node) {
let overflowParent = node.parentNode;
while (overflowParent !== null && overflowParent !== documentElement && getComputedStyle(overflowParent).overflow === "visible") {
overflowParent = overflowParent.parentNode;
}
return overflowParent || documentElement;
}
export function getPageOffset(element = null) {
let top = 0;
let left = 0;
if (typeof element?.getBoundingClientRect === "function") {
const rect = element.getBoundingClientRect();
top = -rect.top;
left = -rect.left;
} else {
if (standardsMode) {
top = window.pageYOffset || documentElement.scrollTop;
left = window.pageXOffset || documentElement.scrollLeft;
} else {
const { body } = document;
if (element !== body) {
top = body.scrollTop - body.clientTop;
left = body.scrollLeft - body.clientLeft;
}
}
}
return {
left,
top
};
}
export function getBoundingRect(element, relElement = null) {
const offset = getPageOffset(relElement);
let top = 0;
let left = 0;
let right = 0;
let bottom = 0;
if (element instanceof HTMLElement && typeof element?.getBoundingClientRect === "function") {
({ top, left, right, bottom } = element.getBoundingClientRect());
}
return {
top: top + offset.top,
left: left + offset.left,
right: right + offset.left,
bottom: bottom + offset.top,
width: right - left,
height: bottom - top
};
}
export function getViewportRect(element, relElement = null) {
const topViewport = standardsMode ? documentElement : document.body;
let { top, left } = element === topViewport && !relElement ? getPageOffset() : getBoundingRect(element, relElement);
let width = 0;
let height = 0;
if (!element || element instanceof Window) {
width = window.innerWidth || 0;
height = window.innerHeight || 0;
} else {
top += element.clientTop;
left += element.clientLeft;
width = element.clientWidth;
height = element.clientHeight;
}
return {
top,
left,
right: left + width,
bottom: top + height,
width,
height
};
}