visually-overlaps.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /**
  2. * Checks whether a parent element visually overlaps a rectangle, either directly or via scrolling.
  3. * @method visuallyOverlaps
  4. * @memberof axe.commons.dom
  5. * @instance
  6. * @param {DOMRect} rect
  7. * @param {Element} parent
  8. * @return {boolean} True if rect is visually contained within parent
  9. */
  10. function visuallyOverlaps(rect, parent) {
  11. var parentRect = parent.getBoundingClientRect();
  12. var parentTop = parentRect.top;
  13. var parentLeft = parentRect.left;
  14. var parentScrollArea = {
  15. top: parentTop - parent.scrollTop,
  16. bottom: parentTop - parent.scrollTop + parent.scrollHeight,
  17. left: parentLeft - parent.scrollLeft,
  18. right: parentLeft - parent.scrollLeft + parent.scrollWidth
  19. };
  20. //In theory, we should just be able to look at the scroll area as a superset of the parentRect,
  21. //but that's not true in Firefox
  22. if (
  23. (rect.left > parentScrollArea.right && rect.left > parentRect.right) ||
  24. (rect.top > parentScrollArea.bottom && rect.top > parentRect.bottom) ||
  25. (rect.right < parentScrollArea.left && rect.right < parentRect.left) ||
  26. (rect.bottom < parentScrollArea.top && rect.bottom < parentRect.top)
  27. ) {
  28. return false;
  29. }
  30. var style = window.getComputedStyle(parent);
  31. if (rect.left > parentRect.right || rect.top > parentRect.bottom) {
  32. return (
  33. style.overflow === 'scroll' ||
  34. style.overflow === 'auto' ||
  35. parent instanceof window.HTMLBodyElement ||
  36. parent instanceof window.HTMLHtmlElement
  37. );
  38. }
  39. return true;
  40. }
  41. export default visuallyOverlaps;