@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
124 lines • 4.89 kB
JavaScript
export function isBody(elem) {
return elem === document.body;
}
export function isTextNode(elem) {
return elem && elem.nodeType === 3;
}
/**
* Decides if given fitHeight fits below or above the target taking boundaries into account.
*/
export function getVerticalPlacement(target, boundariesElement, fitHeight, alignY) {
if (alignY) {
return alignY;
}
if (!fitHeight) {
return 'bottom';
}
if (isTextNode(target)) {
target = target.parentElement;
}
var boundariesClientRect = boundariesElement.getBoundingClientRect();
var boundriesHeight = boundariesClientRect.height;
var boundriesTop = isBody(boundariesElement) ? 0 : boundariesClientRect.top;
var _a = target.getBoundingClientRect(), targetTop = _a.top, targetHeight = _a.height;
var spaceAbove = targetTop - (boundriesTop - boundariesElement.scrollTop);
var spaceBelow = (boundriesTop + boundriesHeight) - (targetTop + targetHeight);
if (spaceBelow >= fitHeight || spaceBelow >= spaceAbove) {
return 'bottom';
}
return 'top';
}
/**
* Decides if given fitWidth fits to the left or to the right of the target taking boundaries into account.
*/
export function getHorizontalPlacement(target, boundariesElement, fitWidth, alignX) {
if (alignX) {
return alignX;
}
if (!fitWidth) {
return 'left';
}
if (isTextNode(target)) {
target = target.parentElement;
}
var _a = target.getBoundingClientRect(), targetLeft = _a.left, targetWidth = _a.width;
var _b = boundariesElement.getBoundingClientRect(), boundriesLeft = _b.left, boundriesWidth = _b.width;
var spaceLeft = targetLeft - boundriesLeft + targetWidth;
var spaceRight = (boundriesLeft + boundriesWidth) - targetLeft;
if (spaceRight >= fitWidth || spaceRight >= spaceLeft) {
return 'left';
}
return 'right';
}
export function calculatePlacement(target, boundariesElement, fitWidth, fitHeight, alignX, alignY) {
return [
getVerticalPlacement(target, boundariesElement, fitHeight, alignY),
getHorizontalPlacement(target, boundariesElement, fitWidth, alignX),
];
}
/**
* Calculates relative coordinates for placing popup along with the target.
* Uses placement from calculatePlacement.
*/
export function calculatePosition(_a) {
var placement = _a.placement, target = _a.target, popup = _a.popup, offset = _a.offset;
var position = {};
if (!target || !popup || !popup.offsetParent) {
return position;
}
if (isTextNode(target)) {
target = target.parentElement;
}
var popupOffsetParent = popup.offsetParent;
var offsetParentStyle = popupOffsetParent.style;
var borderBottomWidth = 0;
if (offsetParentStyle && offsetParentStyle.borderBottomWidth) {
borderBottomWidth = parseInt(offsetParentStyle.borderBottomWidth, 10);
}
var verticalPlacement = placement[0], horizontalPlacement = placement[1];
var _b = popupOffsetParent.getBoundingClientRect(), popupOffsetParentTop = _b.top, popupOffsetParentLeft = _b.left, popupOffsetParentRight = _b.right, popupOffsetParentHeight = _b.height;
var _c = target.getBoundingClientRect(), targetTop = _c.top, targetLeft = _c.left, targetRight = _c.right, targetHeight = _c.height;
if (verticalPlacement === 'top') {
position.bottom = Math.ceil(popupOffsetParentHeight
- (targetTop - popupOffsetParentTop)
- (isBody(popupOffsetParent) ? 0 : popupOffsetParent.scrollTop)
- borderBottomWidth
+ offset[1]);
}
else {
position.top = Math.ceil((targetTop - popupOffsetParentTop)
+ targetHeight
+ (isBody(popupOffsetParent) ? 0 : popupOffsetParent.scrollTop)
- borderBottomWidth
+ offset[1]);
}
if (horizontalPlacement === 'left') {
position.left = Math.ceil(targetLeft - popupOffsetParentLeft
+ (isBody(popupOffsetParent) ? 0 : popupOffsetParent.scrollLeft)
+ offset[0]);
}
else {
position.right = Math.ceil(popupOffsetParentRight - targetRight
- (isBody(popupOffsetParent) ? 0 : popupOffsetParent.scrollLeft)
+ offset[0]);
}
return position;
}
/**
* Traverse DOM Tree upwards looking for popup parents with "overflow: scroll".
*/
export function findOverflowScrollParent(popup) {
var parent = popup;
if (!parent) {
return false;
}
while (parent = parent.parentElement) {
// IE11 on Window 8 doesn't show styles from CSS when accessing through element.style property.
var style = window.getComputedStyle(parent);
if (style.overflow === 'scroll' || style.overflowX === 'scroll' || style.overflowY === 'scroll') {
return parent;
}
}
return false;
}
//# sourceMappingURL=utils.js.map