Updated page pointer to use a fixed positioning system

Avoids interferance with elements that have their own overflow behaviour
such as table cells.
Related to #3774
This commit is contained in:
Dan Brown 2022-10-18 22:40:13 +01:00
parent ff3fb2ebb9
commit d084f225a0
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
3 changed files with 26 additions and 25 deletions

View File

@ -16,13 +16,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 +46,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 +60,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 +78,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});
}
/**

View File

@ -182,7 +182,7 @@ body.tox-fullscreen, body.markdown-fullscreen {
// Page content pointers
.pointer-container {
position: relative;
position: fixed;
display: none;
left: 0;
z-index: 10;
@ -196,11 +196,8 @@ body.tox-fullscreen, body.markdown-fullscreen {
padding: $-s $-s;
border-radius: 4px;
box-shadow: 0 0 12px 1px rgba(0, 0, 0, 0.1);
position: absolute;
top: -60px;
@include lightDark(background-color, #fff, #333);
width: 275px;
z-index: 55;
&.is-page-editable {
width: 328px;

View File

@ -18,9 +18,9 @@
<main class="content-wrap card">
<div class="page-content clearfix" page-display="{{ $page->id }}">
@include('pages.parts.pointer', ['page' => $page])
@include('pages.parts.page-display')
</div>
@include('pages.parts.pointer', ['page' => $page])
</main>
@include('entities.sibling-navigation', ['next' => $next, 'previous' => $previous])