|
import Position from './position'; |
|
|
|
|
|
|
|
|
|
|
|
export default class Overlay { |
|
|
|
|
|
|
|
|
|
|
|
constructor(options, window, document) { |
|
this.options = options; |
|
|
|
this.positionToHighlight = new Position({}); |
|
this.highlightedPosition = new Position({}); |
|
this.highlightedElement = null; |
|
this.lastHighlightedElement = null; |
|
|
|
this.draw = this.draw.bind(this); |
|
|
|
this.window = window; |
|
this.document = document; |
|
|
|
this.resetOverlay(); |
|
} |
|
|
|
|
|
|
|
|
|
resetOverlay() { |
|
|
|
|
|
this.pageOverlay = this.document.getElementById('driver-page-overlay'); |
|
this.highlightStage = this.document.getElementById('driver-highlighted-element-stage'); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
highlight(element, animate = true) { |
|
if (!element || !element.node) { |
|
console.warn('Invalid element to highlight. Must be an instance of `Element`'); |
|
return; |
|
} |
|
|
|
|
|
element.onHighlightStarted(); |
|
|
|
|
|
if (this.highlightedElement) { |
|
this.highlightedElement.onDeselected(); |
|
} |
|
|
|
|
|
const position = element.getCalculatedPosition(); |
|
if (!position.canHighlight()) { |
|
return; |
|
} |
|
|
|
this.lastHighlightedElement = this.highlightedElement; |
|
this.highlightedElement = element; |
|
this.positionToHighlight = position; |
|
|
|
|
|
|
|
if (!this.options.animate || !animate) { |
|
this.highlightedPosition = this.positionToHighlight; |
|
} |
|
|
|
this.draw(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
getHighlightedElement() { |
|
return this.highlightedElement; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
getLastHighlightedElement() { |
|
return this.lastHighlightedElement; |
|
} |
|
|
|
|
|
|
|
|
|
clear() { |
|
this.positionToHighlight = new Position(); |
|
if (this.highlightedElement) { |
|
this.highlightedElement.onDeselected(); |
|
} |
|
|
|
this.highlightedElement = null; |
|
this.lastHighlightedElement = null; |
|
|
|
this.pageOverlay.style.opacity = '0'; |
|
this.highlightStage.style.display = 'none'; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
draw() { |
|
if (!this.highlightedElement || !this.positionToHighlight.canHighlight()) { |
|
return; |
|
} |
|
|
|
|
|
const requiredPadding = this.options.padding * 2; |
|
|
|
|
|
this.pageOverlay.style.opacity = `${this.options.opacity}`; |
|
|
|
const width = (this.positionToHighlight.right - this.positionToHighlight.left) + (requiredPadding); |
|
const height = (this.positionToHighlight.bottom - this.positionToHighlight.top) + (requiredPadding); |
|
|
|
|
|
this.highlightStage.style.display = 'block'; |
|
this.highlightStage.style.position = 'absolute'; |
|
this.highlightStage.style.width = `${width}px`; |
|
this.highlightStage.style.height = `${height}px`; |
|
this.highlightStage.style.top = `${this.positionToHighlight.top - (requiredPadding / 2)}px`; |
|
this.highlightStage.style.left = `${this.positionToHighlight.left - (requiredPadding / 2)}px`; |
|
|
|
|
|
this.highlightedElement.onHighlighted(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
refresh(animate = true) { |
|
|
|
|
|
|
|
if (this.highlightedElement) { |
|
this.highlight(this.highlightedElement, animate); |
|
this.highlightedElement.onHighlighted(); |
|
} |
|
} |
|
} |
|
|