'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var getWindow = require('./getWindow.js');
var getNodeName = require('./getNodeName.js');
var getComputedStyle = require('./getComputedStyle.js');
var instanceOf = require('./instanceOf.js');
var isTableElement = require('./isTableElement.js');
var getParentNode = require('./getParentNode.js');
var userAgent = require('../utils/userAgent.js');

function getTrueOffsetParent(element) {
  if (!instanceOf.isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
  getComputedStyle.default(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 = /firefox/i.test(userAgent.default());
  var isIE = /Trident/i.test(userAgent.default());

  if (isIE && instanceOf.isHTMLElement(element)) {
    // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
    var elementCss = getComputedStyle.default(element);

    if (elementCss.position === 'fixed') {
      return null;
    }
  }

  var currentNode = getParentNode.default(element);

  if (instanceOf.isShadowRoot(currentNode)) {
    currentNode = currentNode.host;
  }

  while (instanceOf.isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName.default(currentNode)) < 0) {
    var css = getComputedStyle.default(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.


function getOffsetParent(element) {
  var window = getWindow.default(element);
  var offsetParent = getTrueOffsetParent(element);

  while (offsetParent && isTableElement.default(offsetParent) && getComputedStyle.default(offsetParent).position === 'static') {
    offsetParent = getTrueOffsetParent(offsetParent);
  }

  if (offsetParent && (getNodeName.default(offsetParent) === 'html' || getNodeName.default(offsetParent) === 'body' && getComputedStyle.default(offsetParent).position === 'static')) {
    return window;
  }

  return offsetParent || getContainingBlock(element) || window;
}

exports.default = getOffsetParent;
//# sourceMappingURL=getOffsetParent.js.map
