Skip to content

Commit

Permalink
[#66628] call smooth scroll multiple times for distant lines
Browse files Browse the repository at this point in the history
  • Loading branch information
Trzcin authored and MaciejWas committed Oct 7, 2024
1 parent cef96ee commit 0703f45
Showing 1 changed file with 38 additions and 12 deletions.
50 changes: 38 additions & 12 deletions src/extensions/syncDualPane.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,39 @@ export function handlePreviewClickToScroll(/** @type {{ target: HTMLElement }} *

const lineNumber = getLineById(lineMap.current, id);
const line = window.myst_editor.main_editor.state.doc.line(lineNumber);
const visible = window.myst_editor.main_editor.visibleRanges[0];
function setCursor() {
window.myst_editor.main_editor.dispatch({
selection: EditorSelection.create([EditorSelection.range(line.to, line.to)]),
});
window.myst_editor.main_editor.focus();
}
function keepScrolling() {
const { canScroll, editor } = scrollEditorToLine(elem, preview, line);
if (canScroll) {
editor.addEventListener("scrollend", keepScrolling, { once: true });
} else {
setCursor();
}
}

if (line.from >= visible.from && line.to <= visible.to) {
// if visible -> scroll just once
const { canScroll, editor } = scrollEditorToLine(elem, preview, line);
if (canScroll) {
editor.addEventListener("scrollend", setCursor, { once: true });
} else {
setCursor();
}
} else {
// When the section of the document is not rendered by CodeMirror, we do not have an accurate position of the line.
// This is because there is line wrapping, which means some lines will end up with a bigger height
// We keep smooth scrolling util we end up with some threshold of the desired position.
keepScrolling();
}
}

function scrollEditorToLine(elem, preview, line) {
const lineBlock = window.myst_editor.main_editor.lineBlockAt(line.from);
const targetRect = elem.getBoundingClientRect();
const previewRect = preview.current.getBoundingClientRect();
Expand All @@ -76,24 +109,17 @@ export function handlePreviewClickToScroll(/** @type {{ target: HTMLElement }} *
const editorScrollOffset = targetRect.top;
const top = lineBlock.top - editorScrollOffset + previewRect.top + previewTopPadding;
const direction = Math.sign(editor.scrollTop - top);
const threshhold = 5;
const canScroll =
!(direction === 1 && editor.scrollTop === 0) && !(direction === -1 && editor.scrollTop + editor.clientHeight >= editor.scrollHeight);
!(direction === 1 && editor.scrollTop === 0) &&
!(direction === -1 && editor.scrollTop + editor.clientHeight >= editor.scrollHeight) &&
Math.abs(editor.scrollTop - top) > threshhold;
editor.scrollTo({
top,
behavior: "smooth",
});

function setCursor() {
window.myst_editor.main_editor.dispatch({
selection: EditorSelection.create([EditorSelection.range(line.to, line.to)]),
});
window.myst_editor.main_editor.focus();
}
if (canScroll) {
editor.addEventListener("scrollend", setCursor, { once: true });
} else {
setCursor();
}
return { canScroll, editor };
}

function findSoruceMappedPreviousElement(startingElem) {
Expand Down

0 comments on commit 0703f45

Please sign in to comment.