element.js 2.5 KB
Newer Older
K
Kamran Ahmed 已提交
1 2 3
import Position from './position';

export default class Element {
K
Kamran Ahmed 已提交
4 5 6
  /**
   * DOM element object
   * @param node
K
Kamran Ahmed 已提交
7
   * @param options
K
Kamran Ahmed 已提交
8
   */
K
Kamran Ahmed 已提交
9 10
  constructor(node, options) {
    this.node = node;
K
Kamran Ahmed 已提交
11
    this.document = document;
K
Kamran Ahmed 已提交
12 13
    this.window = window;
    this.options = options;
K
Kamran Ahmed 已提交
14
    this.popover = this.getPopover();
K
Kamran Ahmed 已提交
15 16
  }

K
Kamran Ahmed 已提交
17 18 19 20
  /**
   * Gets the screen co-ordinates (x,y) for the current dom element
   * @returns {{x: number, y: number}}
   */
K
Kamran Ahmed 已提交
21
  getScreenCoordinates() {
K
Kamran Ahmed 已提交
22
    let tempNode = this.node;
K
Kamran Ahmed 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36

    let x = this.document.documentElement.offsetLeft;
    let y = this.document.documentElement.offsetTop;

    if (tempNode.offsetParent) {
      do {
        x += tempNode.offsetLeft;
        y += tempNode.offsetTop;
      } while (tempNode = tempNode.offsetParent);
    }

    return { x, y };
  }

K
Kamran Ahmed 已提交
37 38 39 40 41
  /**
   * Gets the calculated position on screen, around which
   * we need to draw
   */
  getCalculatedPosition() {
K
Kamran Ahmed 已提交
42 43 44 45 46 47 48 49 50 51
    const coordinates = this.getScreenCoordinates();
    const position = new Position({
      left: Number.MAX_VALUE,
      top: Number.MAX_VALUE,
      right: 0,
      bottom: 0,
    });

    // If we have the position for this element
    // and the element is visible on screen (has some height)
K
Kamran Ahmed 已提交
52
    if (typeof coordinates.x === 'number' && typeof coordinates.y === 'number' && (this.node.offsetWidth > 0 || this.node.offsetHeight > 0)) {
K
Kamran Ahmed 已提交
53 54
      position.left = Math.min(position.left, coordinates.x);
      position.top = Math.min(position.top, coordinates.y);
K
Kamran Ahmed 已提交
55 56
      position.right = Math.max(position.right, coordinates.x + this.node.offsetWidth);
      position.bottom = Math.max(position.bottom, coordinates.y + this.node.offsetHeight);
K
Kamran Ahmed 已提交
57 58 59 60
    }

    return position;
  }
61

K
Kamran Ahmed 已提交
62 63 64 65 66 67 68 69 70 71 72
  onDeselected() {
    // Will be called when element is about to be deselected
    this.hidePopover();
  }

  onHighlightStarted() {
    // Will be triggered when the element is about to be highlighted
    // i.e. overlay has started transitioning towards this element
    this.showPopover();
  }

73
  onHighlighted() {
K
Kamran Ahmed 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    this.showPopover();
  }

  showPopover() {
    const position = this.getCalculatedPosition();

    this.popover.style.left = `${position.left}px`;
    this.popover.style.top = `${position.bottom + 10}px`;
    this.popover.style.display = 'block';
  }

  getPopover() {
    // @todo: Create if not there
    const popover = this.document.getElementById('sholo-popover-item');
    popover.style.position = 'absolute';

    return popover;
  }

  hidePopover() {
    this.popover.style.display = 'none';
95
  }
K
Kamran Ahmed 已提交
96
}