From de9b9ed80c0ecfad3901ee187446219ac337b59d Mon Sep 17 00:00:00 2001 From: Bo26fhmC5M <88071760+Bo26fhmC5M@users.noreply.github.com> Date: Tue, 28 Jan 2025 09:45:33 +0900 Subject: [PATCH] fix: ensure scrollToSelection works cross-browser in HypaV3 modal --- src/lib/Others/HypaV3Modal.svelte | 44 ++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/lib/Others/HypaV3Modal.svelte b/src/lib/Others/HypaV3Modal.svelte index 579de3a6..cef64c67 100644 --- a/src/lib/Others/HypaV3Modal.svelte +++ b/src/lib/Others/HypaV3Modal.svelte @@ -235,9 +235,13 @@ result.summaryPosition.end ); - textarea.scrollTop = textarea.scrollHeight; // Scroll to the bottom - textarea.blur(); // Collapse selection - textarea.focus(); // This scrolls the textarea + textarea.focus(); + scrollToSelection(textarea); + + // This only works on firefox + //textarea.scrollTop = textarea.scrollHeight; // Scroll to the bottom + //textarea.blur(); // Collapse selection + //textarea.focus(); // This scrolls the textarea // Highlight textarea window.setTimeout(() => { @@ -248,6 +252,40 @@ } } + function scrollToSelection(textarea: HTMLTextAreaElement) { + const { selectionStart, selectionEnd } = textarea; + + if ( + selectionStart === null || + selectionEnd === null || + selectionStart === selectionEnd + ) { + return; // Exit if there is no selected text + } + + // Calculate the text before the selected position based on the textarea's text + const textBeforeSelection = textarea.value.substring(0, selectionStart); + + // Use a temporary DOM element to calculate the exact position of the selected text + const tempDiv = document.createElement("div"); + tempDiv.style.position = "absolute"; + tempDiv.style.whiteSpace = "pre-wrap"; + tempDiv.style.overflowWrap = "break-word"; + tempDiv.style.font = window.getComputedStyle(textarea).font; + tempDiv.style.width = `${textarea.offsetWidth}px`; + tempDiv.style.visibility = "hidden"; // Set it to be invisible + + tempDiv.textContent = textBeforeSelection; + document.body.appendChild(tempDiv); + + // Calculate the position of the selected text within the textarea + const selectionTop = tempDiv.offsetHeight; + document.body.removeChild(tempDiv); + + // Adjust the scroll so that the selected text is centered on the screen + textarea.scrollTop = selectionTop - textarea.clientHeight / 2; + } + function isGuidLike(str: string): boolean { const strTrimed = str.trim();