mirror of
https://github.com/chmouel/liseur.git
synced 2026-10-14 03:39:09 +00:00
fix: Stop text selection jumping near page tops
Some checks are pending
Build / build (push) Waiting to run
Some checks are pending
Build / build (push) Waiting to run
When you held a finger on the text and dragged a selection handle near the top of a page in a paginated book, the page could slide sideways and the highlighted words kept flashing between different spots. The phone's built-in web view tried to scroll the page to follow the finger, the reader refused that scroll, and the two kept fighting over where the page should sit. This change made the reader remember where the page was when the selection started and put it back whenever the web view tried to move it sideways, until the selection was cleared. Books read in scrolling mode and books with vertical text were left alone, because following the finger is the expected behaviour there.
This commit is contained in:
parent
9f98d75ab9
commit
5aa45ee299
1 changed files with 33 additions and 1 deletions
|
|
@ -5,7 +5,14 @@ import org.readium.r2.shared.ExperimentalReadiumApi
|
|||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
/**
|
||||
* Keeps the start handle of a selection on the word that was selected.
|
||||
* Keeps selection handles on the passage being selected.
|
||||
*
|
||||
* Near the top of a paginated column, Chromium tries to auto-scroll the
|
||||
* document horizontally while a handle is dragged. Readium refuses native
|
||||
* scrolling during selection, so the browser and the view repeatedly
|
||||
* disagree about the offset and the range flashes between different words.
|
||||
* Keep the document on its selected page too, until the selection clears.
|
||||
* Scrolled and vertical-text books retain their normal selection scrolling.
|
||||
*
|
||||
* Long-pressing the *first* word of a paragraph selects it correctly, but
|
||||
* the WebView paints the start handle on the paragraph's last automatic
|
||||
|
|
@ -85,6 +92,31 @@ internal object SelectionHandleFix {
|
|||
const val SCRIPT: String = """
|
||||
(function () {
|
||||
var state = window.__liseurLead || (window.__liseurLead = {});
|
||||
if (!state.scrollGuardInstalled) {
|
||||
state.scrollGuardInstalled = true;
|
||||
state.selectionX = null;
|
||||
document.addEventListener("selectionchange", function () {
|
||||
var selection = window.getSelection();
|
||||
if (!selection || selection.isCollapsed) {
|
||||
state.selectionX = null;
|
||||
return;
|
||||
}
|
||||
var root = document.documentElement;
|
||||
var view = root.style.getPropertyValue("--USER__view").trim();
|
||||
var scroll = root.style.getPropertyValue("--USER__scroll").trim();
|
||||
if (view === "readium-scroll-on" || scroll === "readium-scroll-on" ||
|
||||
getComputedStyle(root).writingMode.indexOf("vertical") === 0) {
|
||||
state.selectionX = null;
|
||||
return;
|
||||
}
|
||||
if (state.selectionX === null) state.selectionX = window.scrollX;
|
||||
}, true);
|
||||
window.addEventListener("scroll", function () {
|
||||
if (state.selectionX !== null && window.scrollX !== state.selectionX) {
|
||||
document.scrollingElement.scrollLeft = state.selectionX;
|
||||
}
|
||||
});
|
||||
}
|
||||
var installed = false;
|
||||
var tok = state.token ||
|
||||
(state.token = "l" + Math.random().toString(36).slice(2, 10));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue