X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/ff3fb2ebb91ccbe186dc82d69b6351bbf82eacb7..refs/pull/3908/head:/resources/js/components/pointer.js diff --git a/resources/js/components/pointer.js b/resources/js/components/pointer.js index a74422ce4..d884dc721 100644 --- a/resources/js/components/pointer.js +++ b/resources/js/components/pointer.js @@ -1,10 +1,9 @@ import * as DOM from "../services/dom"; import Clipboard from "clipboard/dist/clipboard.min"; +import {Component} from "./component"; -/** - * @extends Component - */ -class Pointer { + +export class Pointer extends Component { setup() { this.container = this.$el; @@ -16,13 +15,7 @@ class Pointer { this.pointerModeLink = true; this.pointerSectionId = ''; - this.init(); this.setupListeners(); - } - - init() { - // Set up pointer by removing it - this.container.parentNode.removeChild(this.container); // Set up clipboard new Clipboard(this.container.querySelector('button')); @@ -52,8 +45,7 @@ class Pointer { // Hide pointer when clicking away DOM.onEvents(document.body, ['click', 'focus'], event => { if (!this.showing || this.isSelection) return; - this.container.parentElement.removeChild(this.container); - this.showing = false; + this.hidePointer(); }); // Show pointer when selecting a single block of tagged content @@ -67,6 +59,11 @@ class Pointer { }); } + hidePointer() { + this.container.style.display = null; + this.showing = false; + } + /** * Move and display the pointer at the given element, targeting the given screen x-position if possible. * @param {Element} element @@ -80,23 +77,29 @@ class Pointer { this.pointerSectionId = element.id; this.updateForTarget(element); - element.parentNode.insertBefore(this.container, element); this.container.style.display = 'block'; + const targetBounds = element.getBoundingClientRect(); + const pointerBounds = this.container.getBoundingClientRect(); + + const xTarget = Math.min(Math.max(xPosition, targetBounds.left), targetBounds.right); + const xOffset = xTarget - (pointerBounds.width / 2); + const yOffset = (targetBounds.top - pointerBounds.height) - 16; + + this.container.style.left = `${xOffset}px`; + this.container.style.top = `${yOffset}px`; + this.showing = true; this.isSelection = true; - // Set pointer to sit near mouse-up position - requestAnimationFrame(() => { - const bookMarkBounds = element.getBoundingClientRect(); - const pointerLeftOffset = Math.max((xPosition - bookMarkBounds.left - 164), 0); - const pointerLeftOffsetPercent = (pointerLeftOffset / bookMarkBounds.width) * 100; + setTimeout(() => { + this.isSelection = false; + }, 100); - this.container.children[0].style.left = pointerLeftOffsetPercent + '%'; - - setTimeout(() => { - this.isSelection = false; - }, 100); - }); + const scrollListener = () => { + this.hidePointer(); + window.removeEventListener('scroll', scrollListener, {passive: true}); + }; + window.addEventListener('scroll', scrollListener, {passive: true}); } /** @@ -122,6 +125,4 @@ class Pointer { editAnchor.href = `${editHref}?content-id=${elementId}&content-text=${encodeURIComponent(queryContent)}`; } } -} - -export default Pointer; \ No newline at end of file +} \ No newline at end of file