From 72a4e0f6d3a59b51978b558750dbb204118fd3de Mon Sep 17 00:00:00 2001 From: Lukas <38840142+lukasstorck@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:13:42 +0200 Subject: [PATCH 1/2] refactor: use global tooltip element, that is updated based on mouse position --- .../src/main/resources/static/js/navbar.js | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/app/core/src/main/resources/static/js/navbar.js b/app/core/src/main/resources/static/js/navbar.js index a95ff1639..9787f09fe 100644 --- a/app/core/src/main/resources/static/js/navbar.js +++ b/app/core/src/main/resources/static/js/navbar.js @@ -75,39 +75,46 @@ function setupDropdowns() { }); } -window.tooltipSetup = () => { - const tooltipElements = document.querySelectorAll('[title]'); +function tooltipSetup() { + // initialize global tooltip element or get reference + let customTooltip = document.getElementById("customTooltip"); + if (!customTooltip) { + customTooltip = document.createElement("div"); + customTooltip.id = "customTooltip"; + customTooltip.className = "btn-tooltip"; + document.body.appendChild(customTooltip); + } + + function updateTooltipPosition(event, text) { + if (window.innerWidth >= 1200) { + customTooltip.textContent = text; + customTooltip.style.display = "block"; + customTooltip.style.left = `${event.pageX + 10}px`; + customTooltip.style.top = `${event.pageY + 10}px`; + } + } + + function hideTooltip() { + customTooltip.style.display = "none"; + } + + // find uninitialized tooltips and set up event listeners + const tooltipElements = document.querySelectorAll("[title]"); tooltipElements.forEach((element) => { - const tooltipText = element.getAttribute('title'); - element.removeAttribute('title'); - element.setAttribute('data-title', tooltipText); - const customTooltip = document.createElement('div'); - customTooltip.className = 'btn-tooltip'; - customTooltip.textContent = tooltipText; + const tooltipText = element.getAttribute("title"); + element.removeAttribute("title"); + element.setAttribute("data-title", tooltipText); // no UI effect, just for reference - document.body.appendChild(customTooltip); + element.addEventListener("mouseenter", (event) => updateTooltipPosition(event, tooltipText)); + element.addEventListener("mousemove", (event) => updateTooltipPosition(event, tooltipText)); + element.addEventListener("mouseleave", hideTooltip); - element.addEventListener('mouseenter', (event) => { - if (window.innerWidth >= 1200) { - customTooltip.style.display = 'block'; - customTooltip.style.left = `${event.pageX + 10}px`; - customTooltip.style.top = `${event.pageY + 10}px`; - } - }); - - element.addEventListener('mousemove', (event) => { - if (window.innerWidth >= 1200) { - customTooltip.style.left = `${event.pageX + 10}px`; - customTooltip.style.top = `${event.pageY + 10}px`; - } - }); - - element.addEventListener('mouseleave', () => { - customTooltip.style.display = 'none'; - }); + // in case UI moves and mouseleave is not triggered, tooltip is readded when mouse is moved over the element + element.addEventListener("click", hideTooltip); }); }; +window.tooltipSetup = tooltipSetup; // Override the bootstrap dropdown styles for mobile function fixNavbarDropdownStyles() { From 8d943313a060fb8cf75ea6cced226b25e2f1d666 Mon Sep 17 00:00:00 2001 From: Lukas <38840142+lukasstorck@users.noreply.github.com> Date: Thu, 7 Aug 2025 14:15:20 +0200 Subject: [PATCH 2/2] refactor: also use custom stirling-pdf tooltips in bookmark editor --- .../static/js/pages/edit-table-of-contents.js | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/app/core/src/main/resources/static/js/pages/edit-table-of-contents.js b/app/core/src/main/resources/static/js/pages/edit-table-of-contents.js index 82c92a50e..9b8cb5cdd 100644 --- a/app/core/src/main/resources/static/js/pages/edit-table-of-contents.js +++ b/app/core/src/main/resources/static/js/pages/edit-table-of-contents.js @@ -316,9 +316,7 @@ document.addEventListener("DOMContentLoaded", function () { updateBookmarkData(); // Initialize tooltips for dynamically added elements - if (typeof $ !== "undefined") { - $('[data-bs-toggle="tooltip"]').tooltip(); - } + window.tooltipSetup(); } // Create the main bookmark element with collapsible interface @@ -390,8 +388,6 @@ document.addEventListener("DOMContentLoaded", function () { childCount.style.fontSize = "0.7rem"; childCount.style.padding = "0.2em 0.5em"; childCount.textContent = bookmark.children.length; - childCount.setAttribute("data-bs-toggle", "tooltip"); - childCount.setAttribute("data-bs-placement", "top"); childCount.title = `${bookmark.children.length} child bookmark${bookmark.children.length > 1 ? "s" : ""}`; toggleContainer.appendChild(childCount); } else { @@ -577,10 +573,6 @@ document.addEventListener("DOMContentLoaded", function () { button.type = "button"; button.className = `btn ${className} btn-bookmark-action`; button.innerHTML = `${icon}`; - - // Use Bootstrap tooltips - button.setAttribute("data-bs-toggle", "tooltip"); - button.setAttribute("data-bs-placement", "top"); button.title = title; button.addEventListener("click", clickHandler); @@ -601,10 +593,6 @@ document.addEventListener("DOMContentLoaded", function () { // Update the add bookmark button appearance with clear visual cue addBookmarkBtn.innerHTML = 'add Add Top-level Bookmark'; addBookmarkBtn.className = "btn btn-primary btn-add-bookmark top-level"; - - // Use Bootstrap tooltips - addBookmarkBtn.setAttribute("data-bs-toggle", "tooltip"); - addBookmarkBtn.setAttribute("data-bs-placement", "top"); addBookmarkBtn.title = "Add a new top-level bookmark"; // Add icon to empty state button as well @@ -612,14 +600,10 @@ document.addEventListener("DOMContentLoaded", function () { const emptyStateBtn = document.querySelector(".btn-add-first-bookmark"); if (emptyStateBtn) { emptyStateBtn.innerHTML = 'add Add First Bookmark'; - emptyStateBtn.setAttribute("data-bs-toggle", "tooltip"); - emptyStateBtn.setAttribute("data-bs-placement", "top"); emptyStateBtn.title = "Add first bookmark"; // Initialize tooltips for the empty state button - if (typeof $ !== "undefined") { - $('[data-bs-toggle="tooltip"]').tooltip(); - } + window.tooltipSetup(); } };