Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo-mod-jslibs-dist.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'popperjs/package/lib/dom-utils/getClippingRect.js.flow')
-rw-r--r--popperjs/package/lib/dom-utils/getClippingRect.js.flow104
1 files changed, 104 insertions, 0 deletions
diff --git a/popperjs/package/lib/dom-utils/getClippingRect.js.flow b/popperjs/package/lib/dom-utils/getClippingRect.js.flow
new file mode 100644
index 0000000..7efd8d0
--- /dev/null
+++ b/popperjs/package/lib/dom-utils/getClippingRect.js.flow
@@ -0,0 +1,104 @@
+// @flow
+import type { ClientRectObject } from '../types';
+import type { Boundary, RootBoundary } from '../enums';
+import { viewport } from '../enums';
+import getViewportRect from './getViewportRect';
+import getDocumentRect from './getDocumentRect';
+import listScrollParents from './listScrollParents';
+import getOffsetParent from './getOffsetParent';
+import getDocumentElement from './getDocumentElement';
+import getComputedStyle from './getComputedStyle';
+import { isElement, isHTMLElement } from './instanceOf';
+import getBoundingClientRect from './getBoundingClientRect';
+import getParentNode from './getParentNode';
+import contains from './contains';
+import getNodeName from './getNodeName';
+import rectToClientRect from '../utils/rectToClientRect';
+import { max, min } from '../utils/math';
+
+function getInnerBoundingClientRect(element: Element) {
+ const rect = getBoundingClientRect(element);
+
+ rect.top = rect.top + element.clientTop;
+ rect.left = rect.left + element.clientLeft;
+ rect.bottom = rect.top + element.clientHeight;
+ rect.right = rect.left + element.clientWidth;
+ rect.width = element.clientWidth;
+ rect.height = element.clientHeight;
+ rect.x = rect.left;
+ rect.y = rect.top;
+
+ return rect;
+}
+
+function getClientRectFromMixedType(
+ element: Element,
+ clippingParent: Element | RootBoundary
+): ClientRectObject {
+ return clippingParent === viewport
+ ? rectToClientRect(getViewportRect(element))
+ : isElement(clippingParent)
+ ? getInnerBoundingClientRect(clippingParent)
+ : rectToClientRect(getDocumentRect(getDocumentElement(element)));
+}
+
+// A "clipping parent" is an overflowable container with the characteristic of
+// clipping (or hiding) overflowing elements with a position different from
+// `initial`
+function getClippingParents(element: Element): Array<Element> {
+ const clippingParents = listScrollParents(getParentNode(element));
+ const canEscapeClipping =
+ ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;
+ const clipperElement =
+ canEscapeClipping && isHTMLElement(element)
+ ? getOffsetParent(element)
+ : element;
+
+ if (!isElement(clipperElement)) {
+ return [];
+ }
+
+ // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414
+ return clippingParents.filter(
+ (clippingParent) =>
+ isElement(clippingParent) &&
+ contains(clippingParent, clipperElement) &&
+ getNodeName(clippingParent) !== 'body' &&
+ (canEscapeClipping
+ ? getComputedStyle(clippingParent).position !== 'static'
+ : true)
+ );
+}
+
+// Gets the maximum area that the element is visible in due to any number of
+// clipping parents
+export default function getClippingRect(
+ element: Element,
+ boundary: Boundary,
+ rootBoundary: RootBoundary
+): ClientRectObject {
+ const mainClippingParents =
+ boundary === 'clippingParents'
+ ? getClippingParents(element)
+ : [].concat(boundary);
+ const clippingParents = [...mainClippingParents, rootBoundary];
+ const firstClippingParent = clippingParents[0];
+
+ const clippingRect = clippingParents.reduce((accRect, clippingParent) => {
+ const rect = getClientRectFromMixedType(element, clippingParent);
+
+ 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;
+ }, getClientRectFromMixedType(element, firstClippingParent));
+
+ clippingRect.width = clippingRect.right - clippingRect.left;
+ clippingRect.height = clippingRect.bottom - clippingRect.top;
+ clippingRect.x = clippingRect.left;
+ clippingRect.y = clippingRect.top;
+
+ return clippingRect;
+}