1 | import { viewport } from "../enums.js";
|
---|
2 | import getViewportRect from "./getViewportRect.js";
|
---|
3 | import getDocumentRect from "./getDocumentRect.js";
|
---|
4 | import listScrollParents from "./listScrollParents.js";
|
---|
5 | import getOffsetParent from "./getOffsetParent.js";
|
---|
6 | import getDocumentElement from "./getDocumentElement.js";
|
---|
7 | import getComputedStyle from "./getComputedStyle.js";
|
---|
8 | import { isElement, isHTMLElement } from "./instanceOf.js";
|
---|
9 | import getBoundingClientRect from "./getBoundingClientRect.js";
|
---|
10 | import getParentNode from "./getParentNode.js";
|
---|
11 | import contains from "./contains.js";
|
---|
12 | import getNodeName from "./getNodeName.js";
|
---|
13 | import rectToClientRect from "../utils/rectToClientRect.js";
|
---|
14 | import { max, min } from "../utils/math.js";
|
---|
15 |
|
---|
16 | function getInnerBoundingClientRect(element, strategy) {
|
---|
17 | var rect = getBoundingClientRect(element, false, strategy === 'fixed');
|
---|
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 |
|
---|
29 | function getClientRectFromMixedType(element, clippingParent, strategy) {
|
---|
30 | return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : 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 |
|
---|
36 | function 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 |
|
---|
53 | export default function getClippingRect(element, boundary, rootBoundary, strategy) {
|
---|
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, strategy);
|
---|
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, strategy));
|
---|
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 | } |
---|