'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.tether = exports.removeChildElements = exports.moveElements = exports.isRectInsideWindowViewport = exports.isFocusable = exports.getScrollParents = exports.getParentElements = exports.getWindowViewport = undefined;

var _isNan = require('babel-runtime/core-js/number/is-nan');

var _isNan2 = _interopRequireDefault(_isNan);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Remove child element(s)
 * element.innerHTNL = '' has a performance penality!
 * @see http://jsperf.com/empty-an-element/16
 * @see http://jsperf.com/force-reflow
 * @param element
 * @param forceReflow
 */
var removeChildElements = function removeChildElements(element) {
  var forceReflow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;


  // See: http://jsperf.com/empty-an-element/16
  while (element.lastChild) {
    element.removeChild(element.lastChild);
  }
  if (forceReflow) {
    // See: http://jsperf.com/force-reflow
    var d = element.style.display;

    element.style.display = 'none';
    element.style.display = d;
  }
};

/**
 * Moves child elements from a DOM node to another dom node.
 * @param source {HTMLElement}
 * @param target {HTMLElement} If the target parameter is ommited, a document fragment is created
 * @return {HTMLElement} The target node
 *
 * @example
 * // Moves child elements from a DOM node to another dom node.
 * moveElements(source, destination);
 *
 * @example
 * // If the second parameter is ommited, a document fragment is created:
 * let fragment = moveElements(source);
 *
 * @See: https://github.com/webmodules/dom-move
 */
var moveElements = function moveElements(source, target) {
  if (!target) {
    target = source.ownerDocument.createDocumentFragment();
  }
  while (source.firstChild) {
    target.appendChild(source.firstChild);
  }
  return target;
};

/**
 * Get the browser viewport dimensions
 * @see http://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript
 * @return {{windowWidth: number, windowHeight: number}}
 */
var getWindowViewport = function getWindowViewport() {
  return {
    viewportWidth: Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0),
    viewportHeight: Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
  };
};

/**
 * Check whether an element is in the window viewport
 * @see http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/
 * @param top
 * @param left
 * @param bottom
 * @param right
 * @return {boolean} true if rectangle is inside window viewport, otherwise false
 */
var isRectInsideWindowViewport = function isRectInsideWindowViewport(_ref) {
  var top = _ref.top,
      left = _ref.left,
      bottom = _ref.bottom,
      right = _ref.right;

  var _getWindowViewport = getWindowViewport(),
      viewportWidth = _getWindowViewport.viewportWidth,
      viewportHeight = _getWindowViewport.viewportHeight;

  return top >= 0 && left >= 0 && bottom <= viewportHeight && right <= viewportWidth;
};

/**
 * Get a list of parent elements that can possibly scroll
 * @param el the element to get parents for
 * @returns {Array}
 */
var getScrollParents = function getScrollParents(el) {
  var elements = [];

  /*
  for (el = el.parentNode; el; el = el.parentNode) {
    const cs = window.getComputedStyle(el);
    if(!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
      elements.unshift(el);
    }
    if(el === document.body) {
      break;
    }
  }
  */

  var element = el.parentNode;
  while (element) {
    var cs = window.getComputedStyle(element);
    if (!(cs.overflowY === 'hidden' && cs.overflowX === 'hidden')) {
      elements.unshift(element);
    }
    if (element === document.body) {
      break;
    }
    element = element.parentNode;
  }

  return elements;
};

/**
 * Get a list of parent elements, from a given element to a given element
 * @param {HTMLElement} from
 * @param {HTMLElement} to
 * @return {Array<HTMLElement>} the parent elements, not including from and to
 */
var getParentElements = function getParentElements(from, to) {
  var result = [];
  var element = from.parentNode;
  while (element) {
    if (element === to) {
      break;
    }
    result.unshift(element);
    element = element.parentNode;
  }
  return result;
};

/**
 * Position element next to button
 *
 * Positioning strategy
 *  1. element.height > viewport.height
 *     let element.height = viewport.heigt
 *     let element.overflow-y = auto
 *  2. element.width > viewport.width
 *     let element.width = viewport.width
 *  3. position element below button, align left edge of element with button left
 *       done if element inside viewport
 *  4. position element below button, align right edge of element with button right
 *       done if element inside viewport
 *  5. positions element above button, aligns left edge of element with button left
 *       done if element inside viewport
 *  6. position element above the control element, aligned to its right.
 *       done if element inside viewport
 *  7. position element at button right hand side, aligns element top with button top
 *       done if element inside viewport
 *  8. position element at button left hand side, aligns element top with button top
 *       done if element inside viewport
 *  9. position element inside viewport
 *     1. position element at viewport bottom
 *     2. position element at button right hand side
 *        done if element inside viewport
 *     3. position element at button left hand side
 *       done if element inside viewport
 *     4. position element at viewport right
 * 10. done
 *
 */
var tether = function tether(controlledBy, element) {
  var controlRect = controlledBy.getBoundingClientRect();

  // 1. will element height fit inside window viewport?

  var _getWindowViewport2 = getWindowViewport(),
      viewportWidth = _getWindowViewport2.viewportWidth,
      viewportHeight = _getWindowViewport2.viewportHeight;

  element.style.height = 'auto';
  //element.style.overflowY = 'hidden';
  if (element.offsetHeight > viewportHeight) {
    element.style.height = viewportHeight + 'px';
    element.style.overflowY = 'auto';
  }

  // 2. will element width fit inside window viewport?
  element.style.width = 'auto';
  if (element.offsetWidth > viewportWidth) {
    element.style.width = viewportWidth + 'px';
  }

  var elementRect = element.getBoundingClientRect();

  // element to control distance
  var dy = controlRect.top - elementRect.top;
  var dx = controlRect.left - elementRect.left;

  // element rect, window coordinates relative to top,left of control
  var top = elementRect.top + dy;
  var left = elementRect.left + dx;
  var bottom = top + elementRect.height;
  var right = left + elementRect.width;

  // Position relative to control
  var ddy = dy;
  var ddx = dx;

  if (isRectInsideWindowViewport({
    top: top + controlRect.height,
    left: left,
    bottom: bottom + controlRect.height,
    right: right
  })) {
    // 3 position element below the control element, aligned to its left
    ddy = controlRect.height + dy;
    //console.log('***** 3');
  } else if (isRectInsideWindowViewport({
    top: top + controlRect.height,
    left: left + controlRect.width - elementRect.width,
    bottom: bottom + controlRect.height,
    right: left + controlRect.width
  })) {
    // 4 position element below the control element, aligned to its right
    ddy = controlRect.height + dy;
    ddx = dx + controlRect.width - elementRect.width;
    //console.log('***** 4');
  } else if (isRectInsideWindowViewport({
    top: top - elementRect.height,
    left: left,
    bottom: bottom - elementRect.height,
    right: right
  })) {
    // 5. position element above the control element, aligned to its left.
    ddy = dy - elementRect.height;
    //console.log('***** 5');
  } else if (isRectInsideWindowViewport({
    top: top - elementRect.height,
    left: left + controlRect.width - elementRect.width,
    bottom: bottom - elementRect.height,
    right: left + controlRect.width
  })) {
    // 6. position element above the control element, aligned to its right.
    ddy = dy - elementRect.height;
    ddx = dx + controlRect.width - elementRect.width;
    //console.log('***** 6');
  } else if (isRectInsideWindowViewport({
    top: top,
    left: left + controlRect.width,
    bottom: bottom,
    right: right + controlRect.width
  })) {
    // 7. position element at button right hand side
    ddx = controlRect.width + dx;
    //console.log('***** 7');
  } else if (isRectInsideWindowViewport({
    top: top,
    left: left - controlRect.width,
    bottom: bottom,
    right: right - controlRect.width
  })) {
    // 8. position element at button left hand side
    ddx = dx - elementRect.width;
    //console.log('***** 8');
  } else {
    // 9. position element inside viewport, near controlrect if possible
    //console.log('***** 9');

    // 9.1 position element near controlrect bottom
    ddy = dy - bottom + viewportHeight;
    if (top + controlRect.height >= 0 && bottom + controlRect.height <= viewportHeight) {
      ddy = controlRect.height + dy;
    } else if (top - elementRect.height >= 0 && bottom - elementRect.height <= viewportHeight) {
      ddy = dy - elementRect.height;
    }

    if (left + elementRect.width + controlRect.width <= viewportWidth) {
      // 9.2 Position element at button right hand side
      ddx = controlRect.width + dx;
      //console.log('***** 9.2');
    } else if (left - elementRect.width >= 0) {
      // 9.3 Position element at button left hand side
      ddx = dx - elementRect.width;
      //console.log('***** 9.3');
    } else {
      // 9.4 position element at (near) viewport right
      var r = left + elementRect.width - viewportWidth;
      ddx = dx - r;
      //console.log('***** 9.4');
    }
  }

  // 10. done
  element.style.top = element.offsetTop + ddy + 'px';
  element.style.left = element.offsetLeft + ddx + 'px';
  //console.log('***** 10. done');
};

/**
 * Check if the given element can receive focus
 * @param {HTMLElement} element the element to check
 * @return {boolean} true if the element is focusable, otherwise false
 */
var isFocusable = function isFocusable(element) {
  // https://github.com/stephenmathieson/is-focusable/blob/master/index.js
  // http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus

  if (element.hasAttribute('tabindex')) {
    var tabindex = element.getAttribute('tabindex');
    if (!(0, _isNan2.default)(tabindex)) {
      return parseInt(tabindex) > -1;
    }
  }

  if (element.hasAttribute('contenteditable') && element.getAttribute('contenteditable') !== 'false') {
    // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#attr-contenteditable
    return true;
  }

  // natively focusable, but only when enabled
  var selector = /input|select|textarea|button|details/i;
  var name = element.nodeName;
  if (selector.test(name)) {
    return element.type.toLowerCase() !== 'hidden' && !element.disabled;
  }

  // anchors and area must have an href
  if (name === 'A' || name === 'AREA') {
    return !!element.href;
  }

  if (name === 'IFRAME') {
    // Check visible iframe
    var cs = window.getComputedStyle(element);
    return cs.getPropertyValue('display').toLowerCase() !== 'none';
  }

  return false;
};

/**
 * Get a list of offset parents for given element
 * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
 * @param el the element
 * @return {Array} a list of offset parents
 */
/*
const offsetParents = (el) => {
  const elements = [];
  for (; el; el = el.offsetParent) {
    elements.unshift(el);
  }
  if(!elements.find(e => e === document.body)) {
    elements.unshift(document.body);
  }
  return elements;
};
*/

/**
 * Finds the common offset ancestor of two DOM nodes
 * @see https://www.benpickles.com/articles/51-finding-a-dom-nodes-common-ancestor-using-javascript
 * @see https://gist.github.com/benpickles/4059636
 * @param a
 * @param b
 * @return {Element} The common offset ancestor of a and b
 */
/*
const commonOffsetAncestor = (a, b) => {
  const parentsA = offsetParents(a);
  const parentsB = offsetParents(b);

  for (let i = 0; i < parentsA.length; i++) {
    if (parentsA[i] !== parentsB[i]) return parentsA[i-1];
  }
};
*/

/**
 * Calculate position relative to a target element
 * @see http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
 * @param target
 * @param el
 * @return {{top: number, left: number}}
 */
/*
const calcPositionRelativeToTarget = (target, el) => {
  let top = 0;
  let left = 0;

  while(el) {
    top += (el.offsetTop - el.scrollTop + el.clientTop) || 0;
    left += (el.offsetLeft - el.scrollLeft + el.clientLeft) || 0;
    el = el.offsetParent;

    if(el === target) {
      break;
    }
  }
  return { top: top, left: left };
};
*/

exports.getWindowViewport = getWindowViewport;
exports.getParentElements = getParentElements;
exports.getScrollParents = getScrollParents;
exports.isFocusable = isFocusable;
exports.isRectInsideWindowViewport = isRectInsideWindowViewport;
exports.moveElements = moveElements;
exports.removeChildElements = removeChildElements;
exports.tether = tether;