Merge pull request #3944 from SiriusXT/toc

toc scrolls smoothly
This commit is contained in:
zadam 2023-05-17 23:13:41 +02:00 committed by GitHub
commit bd8429a0ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 44 deletions

View File

@ -6,6 +6,7 @@ export default class ScrollingContainer extends Container {
this.class("scrolling-container"); this.class("scrolling-container");
this.css('overflow', 'auto'); this.css('overflow', 'auto');
this.css('scroll-behavior', 'smooth');
this.css('position', 'relative'); this.css('position', 'relative');
} }

View File

@ -176,7 +176,9 @@ export default class TocWidget extends RightPanelWidget {
const headingElement = $container.find(":header")[headingIndex]; const headingElement = $container.find(":header")[headingIndex];
if (headingElement != null) { if (headingElement != null) {
headingElement.scrollIntoView(); headingElement.scrollIntoView({
behavior: 'smooth'
});
} }
} else { } else {
const textEditor = await this.noteContext.getTextEditor(); const textEditor = await this.noteContext.getTextEditor();
@ -192,50 +194,9 @@ export default class TocWidget extends RightPanelWidget {
// navigate (note that the TOC rendering and other TOC // navigate (note that the TOC rendering and other TOC
// entries' navigation could be wrong too) // entries' navigation could be wrong too)
if (headingNode != null) { if (headingNode != null) {
// Setting the selection alone doesn't scroll to the $(textEditor.editing.view.domRoots.values().next().value).find(':header')[headingIndex].scrollIntoView({
// caret, needs to be done explicitly and outside of behavior: 'smooth'
// the writer change callback so the scroll is
// guaranteed to happen after the selection is
// updated.
// In addition, scrolling to a caret later in the
// document (ie "forward scrolls"), only scrolls
// barely enough to place the caret at the bottom of
// the screen, which is a usability issue, you would
// like the caret to be placed at the top or center
// of the screen.
// To work around that issue, first scroll to the
// end of the document, then scroll to the desired
// point. This causes all the scrolls to be
// "backward scrolls" no matter the current caret
// position, which places the caret at the top of
// the screen.
// XXX This could be fixed in another way by using
// the underlying CKEditor5
// scrollViewportToShowTarget, which allows to
// provide a larger "viewportOffset", but that
// has coding complications (requires calling an
// internal CKEditor utils funcion and passing
// an HTML element, not a CKEditor node, and
// CKEditor5 doesn't seem to have a
// straightforward way to convert a node to an
// HTML element? (in CKEditor4 this was done
// with $(node.$) )
// Scroll to the end of the note to guarantee the
// next scroll is a backwards scroll that places the
// caret at the top of the screen
model.change(writer => {
writer.setSelection(root.getChild(root.childCount - 1), 0);
}); });
textEditor.editing.view.scrollToTheSelection();
// Backwards scroll to the heading
model.change(writer => {
writer.setSelection(headingNode, 0);
});
textEditor.editing.view.scrollToTheSelection();
} }
} }
} }