diff options
Diffstat (limited to 'popperjs/package/lib/dom-utils/getOffsetParent.js')
-rw-r--r-- | popperjs/package/lib/dom-utils/getOffsetParent.js | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/popperjs/package/lib/dom-utils/getOffsetParent.js b/popperjs/package/lib/dom-utils/getOffsetParent.js new file mode 100644 index 0000000..5300b0f --- /dev/null +++ b/popperjs/package/lib/dom-utils/getOffsetParent.js @@ -0,0 +1,64 @@ +import getWindow from "./getWindow.js"; +import getNodeName from "./getNodeName.js"; +import getComputedStyle from "./getComputedStyle.js"; +import { isHTMLElement } from "./instanceOf.js"; +import isTableElement from "./isTableElement.js"; +import getParentNode from "./getParentNode.js"; + +function getTrueOffsetParent(element) { + if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 + getComputedStyle(element).position === 'fixed') { + return null; + } + + return element.offsetParent; +} // `.offsetParent` reports `null` for fixed elements, while absolute elements +// return the containing block + + +function getContainingBlock(element) { + var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') !== -1; + var isIE = navigator.userAgent.indexOf('Trident') !== -1; + + if (isIE && isHTMLElement(element)) { + // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport + var elementCss = getComputedStyle(element); + + if (elementCss.position === 'fixed') { + return null; + } + } + + var currentNode = getParentNode(element); + + while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { + var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that + // create a containing block. + // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block + + if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') { + return currentNode; + } else { + currentNode = currentNode.parentNode; + } + } + + return null; +} // Gets the closest ancestor positioned element. Handles some edge cases, +// such as table ancestors and cross browser bugs. + + +export default function getOffsetParent(element) { + var window = getWindow(element); + var offsetParent = getTrueOffsetParent(element); + + while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') { + offsetParent = getTrueOffsetParent(offsetParent); + } + + if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) { + return window; + } + + return offsetParent || getContainingBlock(element) || window; +}
\ No newline at end of file |