UNPKG

@atlaskit/editor-plugin-show-diff

Version:

ShowDiff plugin for @atlaskit/editor-core

72 lines (68 loc) 2.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.scrollToActiveDecoration = void 0; /** * Extra space above the scrolled-to element so it does not sit flush under the * viewport edge (helps with sticky table headers, toolbars, etc.). * * Implemented with `scroll-margin-top` so we still use the browser’s native * `scrollIntoView`, which scrolls every relevant scrollport (nested containers * and the window). A single manual `scrollTop` on one ancestor often misses * outer scroll or mis-identifies the active scroll container. */ var SCROLL_TOP_MARGIN_PX = 100; /** * Scrolls to the current position/selection of the document. It does the same as scrollIntoView() * but without requiring the focus on the editor, thus it can be called at any time. */ function scrollToSelection(node) { var element = node instanceof Element ? node : (node === null || node === void 0 ? void 0 : node.parentElement) instanceof Element ? node.parentElement : null; if (!(element instanceof HTMLElement)) { return; } // scroll-margin is included in scroll-into-view math; it does not change layout. var previousScrollMarginTop = element.style.scrollMarginTop; element.style.scrollMarginTop = "".concat(SCROLL_TOP_MARGIN_PX, "px"); try { element.scrollIntoView({ behavior: 'smooth', block: 'start' }); } finally { element.style.scrollMarginTop = previousScrollMarginTop; } } /** * Schedules scrolling to the decoration at the given index after the next frame. * * @returns A function that cancels the scheduled `requestAnimationFrame` if it has not run yet. */ var scrollToActiveDecoration = exports.scrollToActiveDecoration = function scrollToActiveDecoration(view, decorations, activeIndex) { var decoration = decorations[activeIndex]; if (!decoration) { return function () {}; } var rafId = requestAnimationFrame(function () { var _decoration$spec; rafId = null; if (((_decoration$spec = decoration.spec) === null || _decoration$spec === void 0 ? void 0 : _decoration$spec.key) === 'diff-widget-active') { var _decoration$type; // @ts-expect-error - decoration.type is not typed public API var widgetDom = decoration === null || decoration === void 0 || (_decoration$type = decoration.type) === null || _decoration$type === void 0 ? void 0 : _decoration$type.toDOM; scrollToSelection(widgetDom); } else { var _view$domAtPos; var targetNode = view.nodeDOM(decoration === null || decoration === void 0 ? void 0 : decoration.from); var node = targetNode instanceof Element ? targetNode : (_view$domAtPos = view.domAtPos(decoration === null || decoration === void 0 ? void 0 : decoration.from)) === null || _view$domAtPos === void 0 ? void 0 : _view$domAtPos.node; scrollToSelection(node); } }); return function () { if (rafId !== null) { cancelAnimationFrame(rafId); rafId = null; } }; };