UNPKG

3.3 kBJavaScriptView Raw
1import { viewport } from "../enums.js";
2import getViewportRect from "./getViewportRect.js";
3import getDocumentRect from "./getDocumentRect.js";
4import listScrollParents from "./listScrollParents.js";
5import getOffsetParent from "./getOffsetParent.js";
6import getDocumentElement from "./getDocumentElement.js";
7import getComputedStyle from "./getComputedStyle.js";
8import { isElement, isHTMLElement } from "./instanceOf.js";
9import getBoundingClientRect from "./getBoundingClientRect.js";
10import getParentNode from "./getParentNode.js";
11import contains from "./contains.js";
12import getNodeName from "./getNodeName.js";
13import rectToClientRect from "../utils/rectToClientRect.js";
14import { max, min } from "../utils/math.js";
15
16function getInnerBoundingClientRect(element) {
17 var rect = getBoundingClientRect(element);
18 rect.top = rect.top + element.clientTop;
19 rect.left = rect.left + element.clientLeft;
20 rect.bottom = rect.top + element.clientHeight;
21 rect.right = rect.left + element.clientWidth;
22 rect.width = element.clientWidth;
23 rect.height = element.clientHeight;
24 rect.x = rect.left;
25 rect.y = rect.top;
26 return rect;
27}
28
29function getClientRectFromMixedType(element, clippingParent) {
30 return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
31} // A "clipping parent" is an overflowable container with the characteristic of
32// clipping (or hiding) overflowing elements with a position different from
33// `initial`
34
35
36function getClippingParents(element) {
37 var clippingParents = listScrollParents(getParentNode(element));
38 var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;
39 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
40
41 if (!isElement(clipperElement)) {
42 return [];
43 } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414
44
45
46 return clippingParents.filter(function (clippingParent) {
47 return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';
48 });
49} // Gets the maximum area that the element is visible in due to any number of
50// clipping parents
51
52
53export default function getClippingRect(element, boundary, rootBoundary) {
54 var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
55 var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
56 var firstClippingParent = clippingParents[0];
57 var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
58 var rect = getClientRectFromMixedType(element, clippingParent);
59 accRect.top = max(rect.top, accRect.top);
60 accRect.right = min(rect.right, accRect.right);
61 accRect.bottom = min(rect.bottom, accRect.bottom);
62 accRect.left = max(rect.left, accRect.left);
63 return accRect;
64 }, getClientRectFromMixedType(element, firstClippingParent));
65 clippingRect.width = clippingRect.right - clippingRect.left;
66 clippingRect.height = clippingRect.bottom - clippingRect.top;
67 clippingRect.x = clippingRect.left;
68 clippingRect.y = clippingRect.top;
69 return clippingRect;
70}
\No newline at end of file