UNPKG

@vuesax-alpha/nightly

Version:
116 lines (113 loc) 4.87 kB
import { concat } from 'lodash-unified'; import { createCoords, rectToClientRect, max, min } from '../../utils/index.mjs'; import { isHTMLElement, getDocumentElement, getParentNode, isLastTraversableNode, getComputedStyle, getOverflowAncestors, getNodeName, isContainingBlock, isOverflowElement } from '../../utils/dom.mjs'; import { getBoundingClientRect } from '../utils/get-bounding-client-rect.mjs'; import { getDocumentRect } from '../utils/get-document-rect.mjs'; import { getViewportRect } from '../utils/get-viewport-rect.mjs'; import { getVisualOffsets } from '../utils/get-visual-offsets.mjs'; import { getScale } from './get-scale.mjs'; import { isElement } from './is-element.mjs'; function getInnerBoundingClientRect(element, strategy) { const clientRect = getBoundingClientRect(element, true, strategy === "fixed"); const top = clientRect.top + element.clientTop; const left = clientRect.left + element.clientLeft; const scale = isHTMLElement(element) ? getScale(element) : createCoords(1); const width = element.clientWidth * scale.x; const height = element.clientHeight * scale.y; const x = left * scale.x; const y = top * scale.y; return { width, height, x, y }; } function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) { let rect; if (clippingAncestor === "viewport") { rect = getViewportRect(element, strategy); } else if (clippingAncestor === "document") { rect = getDocumentRect(getDocumentElement(element)); } else if (isElement(clippingAncestor)) { rect = getInnerBoundingClientRect(clippingAncestor, strategy); } else { const visualOffsets = getVisualOffsets(element); rect = { ...clippingAncestor, x: clippingAncestor.x - visualOffsets.x, y: clippingAncestor.y - visualOffsets.y }; } return rectToClientRect(rect); } function hasFixedPositionAncestor(element, stopNode) { const parentNode = getParentNode(element); if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) { return false; } return getComputedStyle(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode); } function getClippingElementAncestors(element, cache) { const cachedResult = cache == null ? void 0 : cache.get(element); if (cachedResult) { return cachedResult; } let result = getOverflowAncestors(element, [], false).filter( (el) => isElement(el) && getNodeName(el) !== "body" ); let currentContainingBlockComputedStyle = null; const elementIsFixed = getComputedStyle(element).position === "fixed"; let currentNode = elementIsFixed ? getParentNode(element) : element; while (isElement(currentNode) && !isLastTraversableNode(currentNode)) { const computedStyle = getComputedStyle(currentNode); const currentNodeIsContaining = isContainingBlock(currentNode); if (!currentNodeIsContaining && computedStyle.position === "fixed") { currentContainingBlockComputedStyle = null; } const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && ["absolute", "fixed"].includes( currentContainingBlockComputedStyle.position ) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode); if (shouldDropCurrentNode) { result = result.filter((ancestor) => ancestor !== currentNode); } else { currentContainingBlockComputedStyle = computedStyle; } currentNode = getParentNode(currentNode); } cache == null ? void 0 : cache.set(element, result); return result; } function getClippingRect({ element, boundary, rootBoundary, strategy }) { const elementClippingAncestors = boundary === "clippingAncestors" ? getClippingElementAncestors(element, this._c) : concat([], boundary); const clippingAncestors = [...elementClippingAncestors, rootBoundary]; const firstClippingAncestor = clippingAncestors[0]; const clippingRect = clippingAncestors.reduce( (accRect, clippingAncestor) => { const rect = getClientRectFromClippingAncestor( element, clippingAncestor, strategy ); accRect.top = max(rect.top, accRect.top); accRect.right = min(rect.right, accRect.right); accRect.bottom = min(rect.bottom, accRect.bottom); accRect.left = max(rect.left, accRect.left); return accRect; }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy) ); return { width: clippingRect.right - clippingRect.left, height: clippingRect.bottom - clippingRect.top, x: clippingRect.left, y: clippingRect.top }; } export { getClippingRect }; //# sourceMappingURL=get-clipping-rect.mjs.map