* Scrolls the cursor into view if it is not currently visible.
(options = {})
| 2406 | * Scrolls the cursor into view if it is not currently visible. |
| 2407 | */ |
| 2408 | function scrollCursorIntoView(options = {}) { |
| 2409 | const view = editor; |
| 2410 | const scroller = view?.scrollDOM; |
| 2411 | if (!view || !scroller) return; |
| 2412 | |
| 2413 | const { behavior = "smooth" } = options; |
| 2414 | const { head } = view.state.selection.main; |
| 2415 | const caret = safeCoordsAtPos(view, head); |
| 2416 | if (!caret) return; |
| 2417 | |
| 2418 | const scrollerRect = scroller.getBoundingClientRect(); |
| 2419 | const relativeTop = caret.top - scrollerRect.top + scroller.scrollTop; |
| 2420 | const relativeBottom = caret.bottom - scrollerRect.top + scroller.scrollTop; |
| 2421 | const topMargin = 16; |
| 2422 | const bottomMargin = 24; |
| 2423 | |
| 2424 | const scrollTop = scroller.scrollTop; |
| 2425 | const visibleTop = scrollTop + topMargin; |
| 2426 | const visibleBottom = scrollTop + scroller.clientHeight - bottomMargin; |
| 2427 | |
| 2428 | if (relativeTop < visibleTop) { |
| 2429 | const nextTop = Math.max(relativeTop - topMargin, 0); |
| 2430 | scroller.scrollTo({ top: nextTop, behavior }); |
| 2431 | } else if (relativeBottom > visibleBottom) { |
| 2432 | const delta = relativeBottom - visibleBottom; |
| 2433 | scroller.scrollTo({ top: scrollTop + delta, behavior }); |
| 2434 | } |
| 2435 | } |
| 2436 | |
| 2437 | function suppressCursorReveal(duration = 500) { |
| 2438 | suppressCursorRevealUntil = Date.now() + duration; |
no test coverage detected