import getScrollParent from './getScrollParent'; import getParentNode from './getParentNode'; import findCommonOffsetParent from './findCommonOffsetParent'; import getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode'; import getViewportOffsetRectRelativeToArtbitraryNode from './getViewportOffsetRectRelativeToArtbitraryNode'; import getWindowSizes from './getWindowSizes'; import isFixed from './isFixed'; /** * Computed the boundaries limits and return them * @method * @memberof Popper.Utils * @param {HTMLElement} popper * @param {HTMLElement} reference * @param {number} padding * @param {HTMLElement} boundariesElement - Element used to define the boundaries * @returns {Object} Coordinates of the boundaries */ export default function getBoundaries( popper, reference, padding, boundariesElement ) { // NOTE: 1 DOM access here let boundaries = { top: 0, left: 0 }; const offsetParent = findCommonOffsetParent(popper, reference); // Handle viewport case if (boundariesElement === 'viewport') { boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent); } else { // Handle other cases based on DOM element used as boundaries let boundariesNode; if (boundariesElement === 'scrollParent') { boundariesNode = getScrollParent(getParentNode(popper)); if (boundariesNode.nodeName === 'BODY') { boundariesNode = popper.ownerDocument.documentElement; } } else if (boundariesElement === 'window') { boundariesNode = popper.ownerDocument.documentElement; } else { boundariesNode = boundariesElement; } const offsets = getOffsetRectRelativeToArbitraryNode( boundariesNode, offsetParent ); // In case of HTML, we need a different computation if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { const { height, width } = getWindowSizes(); boundaries.top += offsets.top - offsets.marginTop; boundaries.bottom = height + offsets.top; boundaries.left += offsets.left - offsets.marginLeft; boundaries.right = width + offsets.left; } else { // for all the other DOM elements, this one is good boundaries = offsets; } } // Add paddings boundaries.left += padding; boundaries.top += padding; boundaries.right -= padding; boundaries.bottom -= padding; return boundaries; }