@fullcalendar/web-component
Version:
Custom Element for FullCalendar
141 lines (138 loc) • 5.03 kB
JavaScript
function pointInsideRect(point, rect) {
return point.left >= rect.left &&
point.left < rect.right &&
point.top >= rect.top &&
point.top < rect.bottom;
}
// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
function intersectRects(rect1, rect2) {
let res = {
left: Math.max(rect1.left, rect2.left),
right: Math.min(rect1.right, rect2.right),
top: Math.max(rect1.top, rect2.top),
bottom: Math.min(rect1.bottom, rect2.bottom),
};
if (res.left < res.right && res.top < res.bottom) {
return res;
}
return false;
}
// Returns a new point that will have been moved to reside within the given rectangle
function constrainPoint(point, rect) {
return {
left: Math.min(Math.max(point.left, rect.left), rect.right),
top: Math.min(Math.max(point.top, rect.top), rect.bottom),
};
}
// Returns a point that is the center of the given rectangle
function getRectCenter(rect) {
return {
left: (rect.left + rect.right) / 2,
top: (rect.top + rect.bottom) / 2,
};
}
// Subtracts point2's coordinates from point1's coordinates, returning a delta
function diffPoints(point1, point2) {
return {
left: point1.left - point2.left,
top: point1.top - point2.top,
};
}
function computeEdges(el, getPadding = false) {
let computedStyle = window.getComputedStyle(el);
let borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
let borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
let borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
let borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
let badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border!
let scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;
let scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;
let res = {
borderLeft,
borderRight,
borderTop,
borderBottom,
scrollbarBottom,
scrollbarLeft: 0,
scrollbarRight: 0,
};
if (computedStyle.direction === 'rtl') {
res.scrollbarLeft = scrollbarLeftRight;
}
else {
res.scrollbarRight = scrollbarLeftRight;
}
if (getPadding) {
res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
}
return res;
}
function computeInnerRect(el, goWithinPadding = false, doFromWindowViewport) {
let outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);
let edges = computeEdges(el, goWithinPadding);
let res = {
left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
right: outerRect.right - edges.borderRight - edges.scrollbarRight,
top: outerRect.top + edges.borderTop,
bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom,
};
if (goWithinPadding) {
res.left += edges.paddingLeft;
res.right -= edges.paddingRight;
res.top += edges.paddingTop;
res.bottom -= edges.paddingBottom;
}
return res;
}
function computeRect(el) {
let rect = el.getBoundingClientRect();
return {
left: rect.left + window.scrollX,
top: rect.top + window.scrollY,
right: rect.right + window.scrollX,
bottom: rect.bottom + window.scrollY,
};
}
/*
Returns relative to viewport origin
*/
function computeClippedClientRect(el) {
let clippingParents = getClippingParents(el);
let rect = el.getBoundingClientRect();
for (let clippingParent of clippingParents) {
let intersection = intersectRects(rect, clippingParent.getBoundingClientRect());
if (intersection) {
rect = intersection;
}
else {
return null;
}
}
return rect;
}
// does not return window
function getClippingParents(el) {
let parents = [];
while (el instanceof HTMLElement) { // will stop when gets to document or null
let computedStyle = window.getComputedStyle(el);
if (computedStyle.position === 'fixed') {
break;
}
if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
parents.push(el);
}
el = el.parentNode;
}
return parents;
}
// WARNING: will include border
function computeScrollbarWidthsForEl(el) {
return {
x: el.offsetHeight - el.clientHeight,
y: el.offsetWidth - el.clientWidth,
};
}
export { constrainPoint as a, computeInnerRect as b, computeRect as c, diffPoints as d, getClippingParents as e, computeClippedClientRect as f, getRectCenter as g, intersectRects as i, pointInsideRect as p };