superdoc 1.0.0-beta.65 → 1.0.0-beta.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/chunks/{PdfViewer-CPtbSOs5.cjs → PdfViewer-DTK306FZ.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-CqHxrRM3.es.js → PdfViewer-P0cvxvjh.es.js} +1 -1
  3. package/dist/chunks/{index-DWJXw-IX.cjs → index-BNGG0zf5.cjs} +3 -3
  4. package/dist/chunks/{index-YSWS94Jr-BeHINTZ9.es.js → index-Cixgd5bX-39fIJYpL.es.js} +1 -1
  5. package/dist/chunks/{index-YSWS94Jr-C7xFStTB.cjs → index-Cixgd5bX-ByqITVZq.cjs} +1 -1
  6. package/dist/chunks/{index-BUvQNe-T.es.js → index-U-bzTPNb.es.js} +3 -3
  7. package/dist/chunks/{super-editor.es-DaC-R5gx.es.js → super-editor.es-CIPQg4rG.es.js} +386 -158
  8. package/dist/chunks/{super-editor.es-BHjskxiY.cjs → super-editor.es-DKbuo7ju.cjs} +386 -158
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-DIAStmht.js → converter-BLNx019v.js} +1 -1
  11. package/dist/super-editor/chunks/{docx-zipper-DK-wWQD9.js → docx-zipper-BfQBQQz_.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-CxKPNxhs.js → editor-5RSp-DNd.js} +536 -97
  13. package/dist/super-editor/chunks/{index-YSWS94Jr.js → index-Cixgd5bX.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-D7ZHiSKZ.js → toolbar-Db_-z4Fa.js} +2 -2
  15. package/dist/super-editor/converter.es.js +1 -1
  16. package/dist/super-editor/docx-zipper.es.js +2 -2
  17. package/dist/super-editor/editor.es.js +3 -3
  18. package/dist/super-editor/file-zipper.es.js +1 -1
  19. package/dist/super-editor/super-editor.es.js +6 -6
  20. package/dist/super-editor/toolbar.es.js +2 -2
  21. package/dist/super-editor.cjs +1 -1
  22. package/dist/super-editor.es.js +1 -1
  23. package/dist/superdoc.cjs +2 -2
  24. package/dist/superdoc.es.js +2 -2
  25. package/dist/superdoc.umd.js +388 -160
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -9,11 +9,11 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
9
9
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
10
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
11
11
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
12
- var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _selectionOverlay, _activeEditorHost, _activeDecorationContainer, _activeRegion, _borderLine, _dimmingOverlay, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, hideDimmingOverlay_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _dragHandlerCleanup, _layoutError, _layoutErrorState, _errorBanner, _errorBannerMessage, _telemetryEmitter, _renderScheduled, _pendingDocChange, _isRerendering, _selectionUpdateScheduled, _remoteCursorUpdateScheduled, _rafHandle, _editorListeners, _sectionMetadata, _documentMode, _inputBridge, _trackedChangesMode, _trackedChangesEnabled, _trackedChangesOverrides, _headerFooterManager, _headerFooterAdapter, _headerFooterIdentifier, _multiSectionIdentifier, _headerLayoutResults, _footerLayoutResults, _headerLayoutsByRId, _footerLayoutsByRId, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _overlayManager, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _dragAnchor, _isDragging, _dragExtensionMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, collectCommentPositions_fn, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupDragHandlers_fn, focusEditorAfterImageSelection_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, calculateExtendedSelection_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _handlePointerUp, _handleDragOver, _handleDrop, _handleDoubleClick, _handleKeyDown, focusHeaderFooterShortcut_fn, scheduleRerender_fn, flushRerenderQueue_fn, rerender_fn, ensurePainter_fn, scheduleSelectionUpdate_fn, updateSelection_fn, resolveLayoutOptions_fn, buildHeaderFooterInput_fn, computeHeaderFooterConstraints_fn, layoutPerRIdHeaderFooters_fn, updateDecorationProviders_fn, createDecorationProvider_fn, findHeaderFooterPageForPageNumber_fn, computeDecorationBox_fn, computeExpectedSectionType_fn, rebuildHeaderFooterRegions_fn, hitTestHeaderFooterRegion_fn, pointInRegion_fn, activateHeaderFooterRegion_fn, enterHeaderFooterMode_fn, exitHeaderFooterMode_fn, getActiveDomTarget_fn, emitHeaderFooterModeChanged_fn, emitHeaderFooterEditingContext_fn, updateAwarenessSession_fn, updateModeBanner_fn, announce_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, scrollPageIntoView_fn, computeAnchorMap_fn, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, parseColumns_fn, inchesToPx_fn, applyZoom_fn, createLayoutMetrics_fn, convertPageLocalToOverlayCoords_fn, normalizeClientPoint_fn, computeCaretLayoutRect_fn, computeCaretLayoutRectFromDOM_fn, computeTableCaretLayoutRect_fn, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _layoutSurfaces, _getTargetDom, _isEditable, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _VectorShapeView_instances, ensureParentPositioned_fn, _ShapeGroupView_instances, ensureParentPositioned_fn2;
12
+ var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _selectionOverlay, _activeEditorHost, _activeDecorationContainer, _activeRegion, _borderLine, _dimmingOverlay, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, hideDimmingOverlay_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _dragHandlerCleanup, _layoutError, _layoutErrorState, _errorBanner, _errorBannerMessage, _telemetryEmitter, _renderScheduled, _pendingDocChange, _isRerendering, _selectionUpdateScheduled, _remoteCursorUpdateScheduled, _rafHandle, _editorListeners, _sectionMetadata, _documentMode, _inputBridge, _trackedChangesMode, _trackedChangesEnabled, _trackedChangesOverrides, _headerFooterManager, _headerFooterAdapter, _headerFooterIdentifier, _multiSectionIdentifier, _headerLayoutResults, _footerLayoutResults, _headerLayoutsByRId, _footerLayoutsByRId, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _overlayManager, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _dragAnchor, _isDragging, _dragExtensionMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, collectCommentPositions_fn, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupDragHandlers_fn, focusEditorAfterImageSelection_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, calculateExtendedSelection_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _handlePointerUp, _handleDragOver, _handleDrop, _handleDoubleClick, _handleKeyDown, focusHeaderFooterShortcut_fn, scheduleRerender_fn, flushRerenderQueue_fn, rerender_fn, ensurePainter_fn, scheduleSelectionUpdate_fn, updateSelection_fn, resolveLayoutOptions_fn, buildHeaderFooterInput_fn, computeHeaderFooterConstraints_fn, layoutPerRIdHeaderFooters_fn, updateDecorationProviders_fn, createDecorationProvider_fn, findHeaderFooterPageForPageNumber_fn, computeDecorationBox_fn, computeExpectedSectionType_fn, rebuildHeaderFooterRegions_fn, hitTestHeaderFooterRegion_fn, pointInRegion_fn, activateHeaderFooterRegion_fn, enterHeaderFooterMode_fn, exitHeaderFooterMode_fn, getActiveDomTarget_fn, emitHeaderFooterModeChanged_fn, emitHeaderFooterEditingContext_fn, updateAwarenessSession_fn, updateModeBanner_fn, announce_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, scrollPageIntoView_fn, computeAnchorMap_fn, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, applyDomCorrectionToRects_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, parseColumns_fn, inchesToPx_fn, applyZoom_fn, createLayoutMetrics_fn, getPageOffsetX_fn, convertPageLocalToOverlayCoords_fn, computeDomCaretPageLocal_fn, normalizeClientPoint_fn, computeCaretLayoutRectGeometry_fn, computeCaretLayoutRect_fn, computeCaretLayoutRectFromDOM_fn, computeTableCaretLayoutRect_fn, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _layoutSurfaces, _getTargetDom, _isEditable, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _VectorShapeView_instances, ensureParentPositioned_fn, _ShapeGroupView_instances, ensureParentPositioned_fn2;
13
13
  import * as Y from "yjs";
14
14
  import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
15
- import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as htmlHandler, E as ReplaceStep, G as twipsToInches, H as inchesToTwips, I as ptToTwips, J as getResolvedParagraphProperties, K as linesToTwips, L as changeListLevel, O as findParentNode, Q as isList, U as updateNumberingProperties, V as ListHelpers, W as isMacOS, X as isIOS, Y as getSchemaTypeByName, Z as inputRulesPlugin, _ as TrackDeleteMarkName$1, $ as TrackInsertMarkName$1, a0 as v4, a1 as TrackFormatMarkName$1, a2 as comments_module_events, a3 as findMark, a4 as objectIncludes, a5 as AddMarkStep, a6 as RemoveMarkStep, a7 as twipsToLines, a8 as pixelsToTwips, a9 as helpers, aa as posToDOMRect, ab as CommandService, ac as SuperConverter, ad as createDocument, ae as createDocFromMarkdown, af as createDocFromHTML, ag as EditorState, ah as isActive, ai as unflattenListsInHtml, aj as resolveParagraphProperties, ak as _getReferencedTableStyles, al as parseSizeUnit, am as minMax, an as updateDOMAttributes, ao as findChildren$5, ap as generateRandomSigned32BitIntStrId, aq as decodeRPrFromMarks, ar as calculateResolvedParagraphProperties, as as resolveRunProperties, at as encodeCSSFromPPr, au as twipsToPixels$2, av as encodeCSSFromRPr, aw as generateOrderedListIndex, ax as docxNumberingHelpers, ay as InputRule, az as convertSizeToCSS, aA as SelectionRange, aB as Transform, aC as findParentNodeClosestToPos, aD as isInTable$1, aE as generateDocxRandomId, aF as insertNewRelationship, aG as inchesToPixels, aH as kebabCase, aI as getUnderlineCssString } from "./converter-DIAStmht.js";
16
- import { D as DocxZipper } from "./docx-zipper-DK-wWQD9.js";
15
+ import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as htmlHandler, E as ReplaceStep, G as twipsToInches, H as inchesToTwips, I as ptToTwips, J as getResolvedParagraphProperties, K as linesToTwips, L as changeListLevel, O as findParentNode, Q as isList, U as updateNumberingProperties, V as ListHelpers, W as isMacOS, X as isIOS, Y as getSchemaTypeByName, Z as inputRulesPlugin, _ as TrackDeleteMarkName$1, $ as TrackInsertMarkName$1, a0 as v4, a1 as TrackFormatMarkName$1, a2 as comments_module_events, a3 as findMark, a4 as objectIncludes, a5 as AddMarkStep, a6 as RemoveMarkStep, a7 as twipsToLines, a8 as pixelsToTwips, a9 as helpers, aa as posToDOMRect, ab as CommandService, ac as SuperConverter, ad as createDocument, ae as createDocFromMarkdown, af as createDocFromHTML, ag as EditorState, ah as isActive, ai as unflattenListsInHtml, aj as resolveParagraphProperties, ak as _getReferencedTableStyles, al as parseSizeUnit, am as minMax, an as updateDOMAttributes, ao as findChildren$5, ap as generateRandomSigned32BitIntStrId, aq as decodeRPrFromMarks, ar as calculateResolvedParagraphProperties, as as resolveRunProperties, at as encodeCSSFromPPr, au as twipsToPixels$2, av as encodeCSSFromRPr, aw as generateOrderedListIndex, ax as docxNumberingHelpers, ay as InputRule, az as convertSizeToCSS, aA as SelectionRange, aB as Transform, aC as findParentNodeClosestToPos, aD as isInTable$1, aE as generateDocxRandomId, aF as insertNewRelationship, aG as inchesToPixels, aH as kebabCase, aI as getUnderlineCssString } from "./converter-BLNx019v.js";
16
+ import { D as DocxZipper } from "./docx-zipper-BfQBQQz_.js";
17
17
  import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
18
18
  var GOOD_LEAF_SIZE = 200;
19
19
  var RopeSequence = function RopeSequence2() {
@@ -13923,7 +13923,7 @@ const isHeadless = (editor) => {
13923
13923
  const shouldSkipNodeView = (editor) => {
13924
13924
  return isHeadless(editor);
13925
13925
  };
13926
- const summaryVersion = "1.0.0-beta.65";
13926
+ const summaryVersion = "1.0.0-beta.67";
13927
13927
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
13928
13928
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
13929
13929
  function mapAttributes(attrs) {
@@ -14715,7 +14715,7 @@ const _Editor = class _Editor extends EventEmitter {
14715
14715
  { default: remarkStringify },
14716
14716
  { default: remarkGfm }
14717
14717
  ] = await Promise.all([
14718
- import("./index-YSWS94Jr.js"),
14718
+ import("./index-Cixgd5bX.js"),
14719
14719
  import("./index-DRCvimau.js"),
14720
14720
  import("./index-C_x_N6Uh.js"),
14721
14721
  import("./index-D_sWOSiG.js"),
@@ -14920,7 +14920,7 @@ const _Editor = class _Editor extends EventEmitter {
14920
14920
  * Process collaboration migrations
14921
14921
  */
14922
14922
  processCollaborationMigrations() {
14923
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.65");
14923
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.67");
14924
14924
  if (!this.options.ydoc) return;
14925
14925
  const metaMap = this.options.ydoc.getMap("meta");
14926
14926
  let docVersion = metaMap.get("version");
@@ -22513,6 +22513,7 @@ function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize
22513
22513
  let measurementCanvas = null;
22514
22514
  let measurementCtx = null;
22515
22515
  const TAB_CHAR_LENGTH = 1;
22516
+ const SPACE_CHARS = /* @__PURE__ */ new Set([" ", " "]);
22516
22517
  const isTabRun$1 = (run) => run?.kind === "tab";
22517
22518
  function getMeasurementContext() {
22518
22519
  if (measurementCtx) return measurementCtx;
@@ -22529,6 +22530,41 @@ function getMeasurementContext() {
22529
22530
  }
22530
22531
  return measurementCtx;
22531
22532
  }
22533
+ const countSpaces = (text) => {
22534
+ let spaces = 0;
22535
+ for (let i = 0; i < text.length; i += 1) {
22536
+ if (SPACE_CHARS.has(text[i])) {
22537
+ spaces += 1;
22538
+ }
22539
+ }
22540
+ return spaces;
22541
+ };
22542
+ const getJustifyAdjustment = (block, line, availableWidthOverride) => {
22543
+ if (block.kind !== "paragraph") {
22544
+ return { extraPerSpace: 0, totalSpaces: 0 };
22545
+ }
22546
+ const alignment = block.attrs?.alignment;
22547
+ const hasExplicitPositioning = line.segments?.some((seg) => seg.x !== void 0);
22548
+ const availableWidth = availableWidthOverride ?? line.maxWidth ?? line.width;
22549
+ const slack = Math.max(0, availableWidth - line.width);
22550
+ if (alignment !== "justify" || hasExplicitPositioning || slack <= 0) {
22551
+ return { extraPerSpace: 0, totalSpaces: 0 };
22552
+ }
22553
+ const runs = sliceRunsForLine$1(block, line);
22554
+ const totalSpaces = runs.reduce((sum, run) => {
22555
+ if (isTabRun$1(run) || "src" in run || run.kind === "lineBreak" || run.kind === "break" || run.kind === "fieldAnnotation") {
22556
+ return sum;
22557
+ }
22558
+ return sum + countSpaces(run.text ?? "");
22559
+ }, 0);
22560
+ if (totalSpaces <= 0) {
22561
+ return { extraPerSpace: 0, totalSpaces: 0 };
22562
+ }
22563
+ return {
22564
+ extraPerSpace: slack / totalSpaces,
22565
+ totalSpaces
22566
+ };
22567
+ };
22532
22568
  function getRunFontString(run) {
22533
22569
  if (run.kind === "tab" || run.kind === "lineBreak" || run.kind === "break" || run.kind === "fieldAnnotation" || "src" in run) {
22534
22570
  return "normal normal 16px Arial";
@@ -22586,9 +22622,15 @@ function sliceRunsForLine$1(block, line) {
22586
22622
  }
22587
22623
  return result;
22588
22624
  }
22589
- function measureCharacterX(block, line, charOffset) {
22625
+ function measureCharacterX(block, line, charOffset, availableWidthOverride) {
22590
22626
  const ctx2 = getMeasurementContext();
22627
+ const availableWidth = availableWidthOverride ?? line.maxWidth ?? // Fallback: if no maxWidth, approximate available width as line width (no slack)
22628
+ line.width;
22629
+ const justify = getJustifyAdjustment(block, line, availableWidth);
22630
+ const renderedLineWidth = line.width + Math.max(0, availableWidth - line.width);
22631
+ const alignment = block.kind === "paragraph" ? block.attrs?.alignment : void 0;
22591
22632
  const hasExplicitPositioning = line.segments?.some((seg) => seg.x !== void 0);
22633
+ const alignmentOffset = !hasExplicitPositioning && alignment === "center" ? Math.max(0, (availableWidth - renderedLineWidth) / 2) : !hasExplicitPositioning && alignment === "right" ? Math.max(0, availableWidth - renderedLineWidth) : 0;
22592
22634
  if (hasExplicitPositioning && line.segments && ctx2) {
22593
22635
  return measureCharacterXSegmentBased(block, line, charOffset, ctx2);
22594
22636
  }
@@ -22603,11 +22645,12 @@ function measureCharacterX(block, line, charOffset) {
22603
22645
  return sum + (run.text ?? "").length;
22604
22646
  }, 0)
22605
22647
  );
22606
- return charOffset / charsInLine * line.width;
22648
+ return charOffset / charsInLine * renderedLineWidth;
22607
22649
  }
22608
22650
  const runs = sliceRunsForLine$1(block, line);
22609
22651
  let currentX = 0;
22610
22652
  let currentCharOffset = 0;
22653
+ let spaceTally = 0;
22611
22654
  for (const run of runs) {
22612
22655
  if (isTabRun$1(run)) {
22613
22656
  const runLength2 = TAB_CHAR_LENGTH;
@@ -22628,14 +22671,18 @@ function measureCharacterX(block, line, charOffset) {
22628
22671
  const textUpToTarget = text.slice(0, offsetInRun);
22629
22672
  const measured2 = ctx2.measureText(textUpToTarget);
22630
22673
  const spacingWidth = computeLetterSpacingWidth(run, offsetInRun, runLength);
22631
- return currentX + measured2.width + spacingWidth;
22674
+ const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(textUpToTarget) : 0;
22675
+ return alignmentOffset + currentX + measured2.width + spacingWidth + justify.extraPerSpace * (spaceTally + spacesInPortion);
22632
22676
  }
22633
22677
  ctx2.font = getRunFontString(run);
22634
22678
  const measured = ctx2.measureText(text);
22635
- currentX += measured.width + computeLetterSpacingWidth(run, runLength, runLength);
22679
+ const runLetterSpacing = computeLetterSpacingWidth(run, runLength, runLength);
22680
+ const spacesInRun = justify.extraPerSpace > 0 ? countSpaces(text) : 0;
22681
+ currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
22682
+ spaceTally += spacesInRun;
22636
22683
  currentCharOffset += runLength;
22637
22684
  }
22638
- return currentX;
22685
+ return alignmentOffset + currentX;
22639
22686
  }
22640
22687
  function measureCharacterXSegmentBased(block, line, charOffset, ctx2) {
22641
22688
  if (block.kind !== "paragraph" || !line.segments) return 0;
@@ -22710,8 +22757,15 @@ function charOffsetToPm(block, line, charOffset, fallbackPmStart) {
22710
22757
  }
22711
22758
  return lastPm;
22712
22759
  }
22713
- function findCharacterAtX(block, line, x, pmStart) {
22760
+ function findCharacterAtX(block, line, x, pmStart, availableWidthOverride) {
22714
22761
  const ctx2 = getMeasurementContext();
22762
+ const availableWidth = availableWidthOverride ?? line.maxWidth ?? // Fallback: approximate with line width when no maxWidth is present
22763
+ line.width;
22764
+ const justify = getJustifyAdjustment(block, line, availableWidth);
22765
+ const renderedLineWidth = line.width + Math.max(0, availableWidth - line.width);
22766
+ const alignment = block.kind === "paragraph" ? block.attrs?.alignment : void 0;
22767
+ const hasExplicitPositioning = line.segments?.some((seg) => seg.x !== void 0);
22768
+ const alignmentOffset = !hasExplicitPositioning && alignment === "center" ? Math.max(0, (availableWidth - renderedLineWidth) / 2) : !hasExplicitPositioning && alignment === "right" ? Math.max(0, availableWidth - renderedLineWidth) : 0;
22715
22769
  if (!ctx2) {
22716
22770
  const runs2 = sliceRunsForLine$1(block, line);
22717
22771
  const charsInLine = Math.max(
@@ -22723,7 +22777,7 @@ function findCharacterAtX(block, line, x, pmStart) {
22723
22777
  return sum + (run.text ?? "").length;
22724
22778
  }, 0)
22725
22779
  );
22726
- const ratio = Math.max(0, Math.min(1, x / line.width));
22780
+ const ratio = Math.max(0, Math.min(1, (x - alignmentOffset) / renderedLineWidth));
22727
22781
  const charOffset = Math.round(ratio * charsInLine);
22728
22782
  const pmPosition2 = charOffsetToPm(block, line, charOffset, pmStart);
22729
22783
  return {
@@ -22732,9 +22786,10 @@ function findCharacterAtX(block, line, x, pmStart) {
22732
22786
  };
22733
22787
  }
22734
22788
  const runs = sliceRunsForLine$1(block, line);
22735
- const safeX = Math.max(0, Math.min(line.width, x));
22789
+ const safeX = Math.max(0, Math.min(renderedLineWidth, x - alignmentOffset));
22736
22790
  let currentX = 0;
22737
22791
  let currentCharOffset = 0;
22792
+ let spaceTally = 0;
22738
22793
  for (const run of runs) {
22739
22794
  if (isTabRun$1(run)) {
22740
22795
  const tabWidth = run.width ?? 0;
@@ -22761,7 +22816,8 @@ function findCharacterAtX(block, line, x, pmStart) {
22761
22816
  for (let i = 0; i <= runLength; i++) {
22762
22817
  const textUpToChar = text.slice(0, i);
22763
22818
  const measured2 = ctx2.measureText(textUpToChar);
22764
- const charX = currentX + measured2.width + computeLetterSpacingWidth(run, i, runLength);
22819
+ const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(textUpToChar) : 0;
22820
+ const charX = currentX + measured2.width + computeLetterSpacingWidth(run, i, runLength) + justify.extraPerSpace * (spaceTally + spacesInPortion);
22765
22821
  if (charX >= safeX) {
22766
22822
  if (i === 0) {
22767
22823
  const pmPosition3 = charOffsetToPm(block, line, currentCharOffset, pmStart);
@@ -22784,7 +22840,10 @@ function findCharacterAtX(block, line, x, pmStart) {
22784
22840
  }
22785
22841
  }
22786
22842
  const measured = ctx2.measureText(text);
22787
- currentX += measured.width + computeLetterSpacingWidth(run, runLength, runLength);
22843
+ const runLetterSpacing = computeLetterSpacingWidth(run, runLength, runLength);
22844
+ const spacesInRun = justify.extraPerSpace > 0 ? countSpaces(text) : 0;
22845
+ currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
22846
+ spaceTally += spacesInRun;
22788
22847
  currentCharOffset += runLength;
22789
22848
  }
22790
22849
  const pmPosition = charOffsetToPm(block, line, currentCharOffset, pmStart);
@@ -35401,7 +35460,18 @@ function clickToPosition(layout, blocks, measures, containerPoint, domContainer,
35401
35460
  }
35402
35461
  const line = measure.lines[lineIndex];
35403
35462
  const isRTL = isRtlBlock(block);
35404
- const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL);
35463
+ const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
35464
+ const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
35465
+ const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
35466
+ const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
35467
+ const totalIndent = paraIndentLeft + paraIndentRight;
35468
+ const availableWidth = Math.max(0, fragment.width - totalIndent);
35469
+ if (totalIndent > fragment.width) {
35470
+ console.warn(
35471
+ `[clickToPosition] Paragraph indents (${totalIndent}px) exceed fragment width (${fragment.width}px) for block ${fragment.blockId}. This may indicate a layout miscalculation. Available width clamped to 0.`
35472
+ );
35473
+ }
35474
+ const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth);
35405
35475
  if (pos == null) {
35406
35476
  logClickStage("warn", "no-position", {
35407
35477
  blockId: fragment.blockId
@@ -35432,7 +35502,18 @@ function clickToPosition(layout, blocks, measures, containerPoint, domContainer,
35432
35502
  if (lineIndex != null) {
35433
35503
  const line = cellMeasure.lines[lineIndex];
35434
35504
  const isRTL = isRtlBlock(cellBlock);
35435
- const pos = mapPointToPm(cellBlock, line, localX, isRTL);
35505
+ const indentLeft = typeof cellBlock.attrs?.indent?.left === "number" ? cellBlock.attrs.indent.left : 0;
35506
+ const indentRight = typeof cellBlock.attrs?.indent?.right === "number" ? cellBlock.attrs.indent.right : 0;
35507
+ const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
35508
+ const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
35509
+ const totalIndent = paraIndentLeft + paraIndentRight;
35510
+ const availableWidth = Math.max(0, tableHit.fragment.width - totalIndent);
35511
+ if (totalIndent > tableHit.fragment.width) {
35512
+ console.warn(
35513
+ `[clickToPosition:table] Paragraph indents (${totalIndent}px) exceed fragment width (${tableHit.fragment.width}px) for block ${tableHit.fragment.blockId}. This may indicate a layout miscalculation. Available width clamped to 0.`
35514
+ );
35515
+ }
35516
+ const pos = mapPointToPm(cellBlock, line, localX, isRTL, availableWidth);
35436
35517
  if (pos != null) {
35437
35518
  logClickStage("log", "success", {
35438
35519
  blockId: tableHit.fragment.blockId,
@@ -35591,7 +35672,15 @@ function selectionToRects(layout, blocks, measures, from2, to) {
35591
35672
  const startX = mapPmToX(block, line, charOffsetFrom, fragment.width);
35592
35673
  const endX = mapPmToX(block, line, charOffsetTo, fragment.width);
35593
35674
  const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
35594
- const rectX = fragment.x + markerWidth + Math.min(startX, endX);
35675
+ const paraIndentLeft = block.attrs?.indent?.left ?? 0;
35676
+ const firstLineOffset = (block.attrs?.indent?.firstLine ?? 0) - (block.attrs?.indent?.hanging ?? 0);
35677
+ const isFirstLine = index2 === fragment.fromLine;
35678
+ const isListFirstLine = isFirstLine && !fragment.continuesFromPrev && (fragment.markerWidth ?? 0) > 0;
35679
+ let indentAdjust = 0;
35680
+ if (!isListFirstLine) {
35681
+ indentAdjust = paraIndentLeft + (isFirstLine ? firstLineOffset : 0);
35682
+ }
35683
+ const rectX = fragment.x + markerWidth + indentAdjust + Math.min(startX, endX);
35595
35684
  const rectWidth = Math.max(1, Math.abs(endX - startX));
35596
35685
  const lineOffset = lineHeightBeforeIndex(measure, index2) - lineHeightBeforeIndex(measure, fragment.fromLine);
35597
35686
  const rectY = fragment.y + lineOffset;
@@ -35967,11 +36056,11 @@ const lineHeightBeforeIndex = (measure, absoluteLineIndex) => {
35967
36056
  }
35968
36057
  return height;
35969
36058
  };
35970
- const mapPointToPm = (block, line, x, isRTL) => {
36059
+ const mapPointToPm = (block, line, x, isRTL, availableWidthOverride) => {
35971
36060
  if (block.kind !== "paragraph") return null;
35972
36061
  const range = computeLinePmRange(block, line);
35973
36062
  if (range.pmStart == null || range.pmEnd == null) return null;
35974
- const result = findCharacterAtX(block, line, x, range.pmStart);
36063
+ const result = findCharacterAtX(block, line, x, range.pmStart, availableWidthOverride);
35975
36064
  if (isRTL) {
35976
36065
  const charOffset = result.charOffset;
35977
36066
  const charsInLine = Math.max(1, line.toChar - line.fromChar);
@@ -35982,7 +36071,22 @@ const mapPointToPm = (block, line, x, isRTL) => {
35982
36071
  };
35983
36072
  const mapPmToX = (block, line, offset2, fragmentWidth) => {
35984
36073
  if (fragmentWidth <= 0 || line.width <= 0) return 0;
35985
- return measureCharacterX(block, line, offset2);
36074
+ let paraIndentLeft = 0;
36075
+ let paraIndentRight = 0;
36076
+ if (block.kind === "paragraph") {
36077
+ const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
36078
+ const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
36079
+ paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
36080
+ paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
36081
+ }
36082
+ const totalIndent = paraIndentLeft + paraIndentRight;
36083
+ const availableWidth = Math.max(0, fragmentWidth - totalIndent);
36084
+ if (totalIndent > fragmentWidth) {
36085
+ console.warn(
36086
+ `[mapPmToX] Paragraph indents (${totalIndent}px) exceed fragment width (${fragmentWidth}px) for block ${block.id}. This may indicate a layout miscalculation. Available width clamped to 0.`
36087
+ );
36088
+ }
36089
+ return measureCharacterX(block, line, offset2, availableWidth);
35986
36090
  };
35987
36091
  const isRtlBlock = (block) => {
35988
36092
  if (block.kind !== "paragraph") return false;
@@ -38729,40 +38833,31 @@ ensureEditorHost_fn = function(pageElement, kind, decorationContainer) {
38729
38833
  return editorHost;
38730
38834
  };
38731
38835
  /**
38732
- * Positions the editor host for header/footer editing.
38836
+ * Positions the editor host for header/footer editing using pure layout coordinates.
38837
+ *
38838
+ * This method uses ONLY layout-based coordinates from the region data, never
38839
+ * getBoundingClientRect(). This ensures overlays stay aligned with content even
38840
+ * when the editor is embedded in containers with CSS transforms, filters, or
38841
+ * complex positioning contexts.
38733
38842
  *
38734
- * When a decoration container exists, positions are derived from its bounds.
38735
- * When no decoration container exists (empty header/footer), positions are
38736
- * derived directly from the region data.
38843
+ * The transform: scale() on #viewportHost handles zoom, so we don't multiply
38844
+ * by zoom here - we use the raw layout coordinates directly.
38737
38845
  *
38738
38846
  * @param editorHost - The editor host element to position
38739
- * @param region - The header/footer region with dimension data
38847
+ * @param region - The header/footer region with dimension data from layout engine
38740
38848
  * @param decorationContainer - The decoration container (optional, may not exist for empty regions)
38741
- * @param zoom - Current zoom level
38849
+ * @param _zoom - Current zoom level (unused - zoom is handled by transform: scale())
38742
38850
  */
38743
- positionEditorHost_fn = function(editorHost, region, decorationContainer, zoom) {
38851
+ positionEditorHost_fn = function(editorHost, region, decorationContainer, _zoom) {
38744
38852
  const pageElement = editorHost.parentElement;
38745
38853
  if (!pageElement) {
38746
38854
  console.error("[EditorOverlayManager] Editor host has no parent element");
38747
38855
  return;
38748
38856
  }
38749
- let top2;
38750
- let left2;
38751
- let width;
38752
- let height;
38753
- if (decorationContainer) {
38754
- const decorationRect = decorationContainer.getBoundingClientRect();
38755
- const pageRect = pageElement.getBoundingClientRect();
38756
- top2 = decorationRect.top - pageRect.top;
38757
- left2 = decorationRect.left - pageRect.left;
38758
- width = decorationRect.width;
38759
- height = decorationRect.height;
38760
- } else {
38761
- top2 = region.localY * zoom;
38762
- left2 = region.localX * zoom;
38763
- width = region.width * zoom;
38764
- height = region.height * zoom;
38765
- }
38857
+ const top2 = decorationContainer?.offsetTop ?? region.localY;
38858
+ const left2 = decorationContainer?.offsetLeft ?? region.localX;
38859
+ const width = decorationContainer?.offsetWidth ?? region.width;
38860
+ const height = decorationContainer?.offsetHeight ?? region.height;
38766
38861
  Object.assign(editorHost.style, {
38767
38862
  top: `${top2}px`,
38768
38863
  left: `${left2}px`,
@@ -38791,20 +38886,17 @@ hideDimmingOverlay_fn = function() {
38791
38886
  /**
38792
38887
  * Shows a full-width border line at the bottom of the header or top of the footer.
38793
38888
  * This creates the MS Word style visual indicator spanning edge-to-edge of the page.
38889
+ *
38890
+ * Uses pure layout coordinates from region data to avoid coordinate system mixing.
38794
38891
  */
38795
- showHeaderFooterBorder_fn = function(pageElement, region, decorationContainer, zoom) {
38892
+ showHeaderFooterBorder_fn = function(pageElement, region, decorationContainer, _zoom) {
38796
38893
  __privateMethod(this, _EditorOverlayManager_instances, hideHeaderFooterBorder_fn).call(this);
38797
38894
  __privateSet(this, _borderLine, document.createElement("div"));
38798
38895
  __privateGet(this, _borderLine).className = "superdoc-header-footer-border";
38799
- let topPosition;
38800
38896
  const isHeader = region.kind === "header";
38801
- if (decorationContainer) {
38802
- const decorationRect = decorationContainer.getBoundingClientRect();
38803
- const pageRect = pageElement.getBoundingClientRect();
38804
- topPosition = isHeader ? decorationRect.bottom - pageRect.top : decorationRect.top - pageRect.top;
38805
- } else {
38806
- topPosition = isHeader ? (region.localY + region.height) * zoom : region.localY * zoom;
38807
- }
38897
+ const decorationTop = decorationContainer?.offsetTop;
38898
+ const decorationHeight = decorationContainer?.offsetHeight;
38899
+ const topPosition = isHeader ? decorationTop != null && decorationHeight != null ? decorationTop + decorationHeight : region.localY + region.height : decorationTop ?? region.localY;
38808
38900
  Object.assign(__privateGet(this, _borderLine).style, {
38809
38901
  position: "absolute",
38810
38902
  left: "0",
@@ -39976,8 +40068,10 @@ const _PresentationEditor = class _PresentationEditor extends EventEmitter {
39976
40068
  const start2 = Math.min(from2, to);
39977
40069
  const end2 = Math.max(from2, to);
39978
40070
  const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
39979
- const overlayRect = __privateGet(this, _selectionOverlay2).getBoundingClientRect();
39980
40071
  const relativeRect = relativeTo?.getBoundingClientRect() ?? null;
40072
+ const containerRect = __privateGet(this, _visibleHost).getBoundingClientRect();
40073
+ const scrollLeft = __privateGet(this, _visibleHost).scrollLeft ?? 0;
40074
+ const scrollTop = __privateGet(this, _visibleHost).scrollTop ?? 0;
39981
40075
  const layoutRectSource = () => {
39982
40076
  if (__privateGet(this, _session).mode !== "body") {
39983
40077
  return __privateMethod(this, _PresentationEditor_instances, computeHeaderFooterSelectionRects_fn).call(this, start2, end2);
@@ -39988,14 +40082,46 @@ const _PresentationEditor = class _PresentationEditor extends EventEmitter {
39988
40082
  };
39989
40083
  const rawRects = layoutRectSource();
39990
40084
  if (!rawRects.length) return [];
40085
+ let domCaretStart = null;
40086
+ let domCaretEnd = null;
40087
+ try {
40088
+ domCaretStart = __privateMethod(this, _PresentationEditor_instances, computeDomCaretPageLocal_fn).call(this, start2);
40089
+ domCaretEnd = __privateMethod(this, _PresentationEditor_instances, computeDomCaretPageLocal_fn).call(this, end2);
40090
+ } catch (error) {
40091
+ if (process$1.env.NODE_ENV === "development") {
40092
+ console.warn("[PresentationEditor] DOM caret computation failed in getRectsForRange:", error);
40093
+ }
40094
+ }
40095
+ const layoutCaretStart = __privateMethod(this, _PresentationEditor_instances, computeCaretLayoutRectGeometry_fn).call(this, start2, false);
40096
+ __privateMethod(this, _PresentationEditor_instances, computeCaretLayoutRectGeometry_fn).call(this, end2, false);
40097
+ const pageDelta = {};
40098
+ if (domCaretStart && layoutCaretStart && domCaretStart.pageIndex === layoutCaretStart.pageIndex) {
40099
+ pageDelta[domCaretStart.pageIndex] = {
40100
+ dx: domCaretStart.x - layoutCaretStart.x,
40101
+ dy: domCaretStart.y - layoutCaretStart.y
40102
+ };
40103
+ }
39991
40104
  const pageHeight = __privateGet(this, _session).mode === "body" ? __privateMethod(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this) : __privateMethod(this, _PresentationEditor_instances, getHeaderFooterPageHeight_fn).call(this);
39992
40105
  const pageGap = __privateGet(this, _layoutState).layout?.pageGap ?? 0;
39993
- return rawRects.map((rect) => {
39994
- const pageLocalY = rect.y - rect.pageIndex * (pageHeight + pageGap);
39995
- const coords = __privateMethod(this, _PresentationEditor_instances, convertPageLocalToOverlayCoords_fn).call(this, rect.pageIndex, rect.x, pageLocalY);
40106
+ const finalRects = rawRects.map((rect, idx, allRects) => {
40107
+ const delta = pageDelta[rect.pageIndex];
40108
+ let adjustedX = delta ? rect.x + delta.dx : rect.x;
40109
+ const adjustedY = delta ? rect.y + delta.dy : rect.y;
40110
+ const isFirstRect = idx === 0;
40111
+ const isLastRect = idx === allRects.length - 1;
40112
+ if (isFirstRect && domCaretStart && rect.pageIndex === domCaretStart.pageIndex) {
40113
+ adjustedX = domCaretStart.x;
40114
+ }
40115
+ if (isLastRect && domCaretEnd && rect.pageIndex === domCaretEnd.pageIndex) {
40116
+ const endX = domCaretEnd.x;
40117
+ const newWidth = Math.max(1, endX - adjustedX);
40118
+ rect = { ...rect, width: newWidth };
40119
+ }
40120
+ const pageLocalY = adjustedY - rect.pageIndex * (pageHeight + pageGap);
40121
+ const coords = __privateMethod(this, _PresentationEditor_instances, convertPageLocalToOverlayCoords_fn).call(this, rect.pageIndex, adjustedX, pageLocalY);
39996
40122
  if (!coords) return null;
39997
- const absLeft = coords.x * zoom + overlayRect.left;
39998
- const absTop = coords.y * zoom + overlayRect.top;
40123
+ const absLeft = coords.x * zoom - scrollLeft + containerRect.left;
40124
+ const absTop = coords.y * zoom - scrollTop + containerRect.top;
39999
40125
  const left2 = relativeRect ? absLeft - relativeRect.left : absLeft;
40000
40126
  const top2 = relativeRect ? absTop - relativeRect.top : absTop;
40001
40127
  const width = Math.max(1, rect.width * zoom);
@@ -40010,6 +40136,7 @@ const _PresentationEditor = class _PresentationEditor extends EventEmitter {
40010
40136
  height
40011
40137
  };
40012
40138
  }).filter((rect) => Boolean(rect));
40139
+ return finalRects;
40013
40140
  }
40014
40141
  /**
40015
40142
  * Get selection bounds for a document range with aggregated bounding box.
@@ -40238,24 +40365,22 @@ const _PresentationEditor = class _PresentationEditor extends EventEmitter {
40238
40365
  return null;
40239
40366
  }
40240
40367
  const rect2 = rects2[0];
40241
- const overlayRect = __privateGet(this, _selectionOverlay2)?.getBoundingClientRect();
40242
- if (!overlayRect) {
40243
- return null;
40244
- }
40368
+ const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
40369
+ const containerRect = __privateGet(this, _visibleHost).getBoundingClientRect();
40370
+ const scrollLeft = __privateGet(this, _visibleHost).scrollLeft ?? 0;
40371
+ const scrollTop = __privateGet(this, _visibleHost).scrollTop ?? 0;
40245
40372
  const pageHeight = __privateMethod(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
40246
40373
  const pageGap = __privateGet(this, _layoutState).layout?.pageGap ?? 0;
40247
40374
  const pageLocalY = rect2.y - rect2.pageIndex * (pageHeight + pageGap);
40248
40375
  const coords = __privateMethod(this, _PresentationEditor_instances, convertPageLocalToOverlayCoords_fn).call(this, rect2.pageIndex, rect2.x, pageLocalY);
40249
- if (!coords) {
40250
- return null;
40251
- }
40376
+ if (!coords) return null;
40252
40377
  return {
40253
- top: coords.y + overlayRect.top,
40254
- bottom: coords.y + overlayRect.top + rect2.height,
40255
- left: coords.x + overlayRect.left,
40256
- right: coords.x + overlayRect.left + rect2.width,
40257
- width: rect2.width,
40258
- height: rect2.height
40378
+ top: coords.y * zoom - scrollTop + containerRect.top,
40379
+ bottom: coords.y * zoom - scrollTop + containerRect.top + rect2.height * zoom,
40380
+ left: coords.x * zoom - scrollLeft + containerRect.left,
40381
+ right: coords.x * zoom - scrollLeft + containerRect.left + rect2.width * zoom,
40382
+ width: rect2.width * zoom,
40383
+ height: rect2.height * zoom
40259
40384
  };
40260
40385
  }
40261
40386
  const rects = this.getRangeRects(pos, pos);
@@ -41747,6 +41872,19 @@ rerender_fn = async function() {
41747
41872
  __privateSet(this, _layoutState, { blocks, measures, layout, bookmarks, anchorMap });
41748
41873
  __privateSet(this, _headerLayoutResults, headerLayouts ?? null);
41749
41874
  __privateSet(this, _footerLayoutResults, footerLayouts ?? null);
41875
+ const pageWidth = layout.pageSize?.w ?? __privateGet(this, _layoutOptions).pageSize?.w ?? DEFAULT_PAGE_SIZE.w;
41876
+ if (__privateGet(this, _painterHost)) {
41877
+ __privateGet(this, _painterHost).style.width = `${pageWidth}px`;
41878
+ __privateGet(this, _painterHost).style.marginLeft = "0";
41879
+ __privateGet(this, _painterHost).style.marginRight = "0";
41880
+ }
41881
+ if (__privateGet(this, _selectionOverlay2)) {
41882
+ __privateGet(this, _selectionOverlay2).style.width = `${pageWidth}px`;
41883
+ __privateGet(this, _selectionOverlay2).style.left = "0";
41884
+ __privateGet(this, _selectionOverlay2).style.right = "";
41885
+ __privateGet(this, _selectionOverlay2).style.marginLeft = "0";
41886
+ __privateGet(this, _selectionOverlay2).style.marginRight = "0";
41887
+ }
41750
41888
  await __privateMethod(this, _PresentationEditor_instances, layoutPerRIdHeaderFooters_fn).call(this, headerFooterInput, layout, sectionMetadata);
41751
41889
  __privateMethod(this, _PresentationEditor_instances, updateDecorationProviders_fn).call(this, layout);
41752
41890
  const painter = __privateMethod(this, _PresentationEditor_instances, ensurePainter_fn).call(this, blocks, measures);
@@ -41963,9 +42101,20 @@ updateSelection_fn = function() {
41963
42101
  return;
41964
42102
  }
41965
42103
  const rects = selectionToRects(layout, __privateGet(this, _layoutState).blocks, __privateGet(this, _layoutState).measures, from2, to) ?? [];
42104
+ let domStart = null;
42105
+ let domEnd = null;
42106
+ try {
42107
+ domStart = __privateMethod(this, _PresentationEditor_instances, computeDomCaretPageLocal_fn).call(this, from2);
42108
+ domEnd = __privateMethod(this, _PresentationEditor_instances, computeDomCaretPageLocal_fn).call(this, to);
42109
+ } catch (error) {
42110
+ if (process$1.env.NODE_ENV === "development") {
42111
+ console.warn("[PresentationEditor] DOM caret computation failed in #renderLocalSelection:", error);
42112
+ }
42113
+ }
42114
+ const correctedRects = __privateMethod(this, _PresentationEditor_instances, applyDomCorrectionToRects_fn).call(this, rects, domStart, domEnd);
41966
42115
  try {
41967
42116
  __privateGet(this, _localSelectionLayer).innerHTML = "";
41968
- __privateMethod(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, rects);
42117
+ __privateMethod(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, correctedRects);
41969
42118
  } catch (error) {
41970
42119
  if (process$1.env.NODE_ENV === "development") {
41971
42120
  console.warn("[PresentationEditor] Failed to render selection rects:", error);
@@ -42810,6 +42959,67 @@ getHeaderFooterPageHeight_fn = function() {
42810
42959
  }
42811
42960
  return context.layout.pageSize?.h ?? context.region.height ?? 1;
42812
42961
  };
42962
+ /**
42963
+ * Applies DOM-based position correction to layout-computed selection rectangles.
42964
+ *
42965
+ * This method ensures selection highlights align with actual rendered text positions
42966
+ * by correcting for CSS effects (padding, text-indent, word-spacing) that the painter
42967
+ * applies but the layout engine doesn't account for. Without this correction, selection
42968
+ * highlights would be misaligned with the visible text.
42969
+ *
42970
+ * Algorithm:
42971
+ * 1. Calculate per-page delta between DOM and layout positions at selection start
42972
+ * 2. Apply horizontal and vertical deltas to all rectangles on the same page
42973
+ * 3. For the first rectangle, override with exact DOM start position
42974
+ * 4. For the last rectangle, compute width from DOM end position
42975
+ *
42976
+ * The correction is page-aware because multi-page selections may have different
42977
+ * rendering contexts on each page (e.g., different header/footer heights, column layouts).
42978
+ *
42979
+ * @param rects - Layout-computed selection rectangles to correct
42980
+ * @param domStart - DOM-measured start position {pageIndex, x, y} or null if unavailable
42981
+ * @param domEnd - DOM-measured end position {pageIndex, x, y} or null if unavailable
42982
+ * @returns Corrected selection rectangles with DOM-aligned positions
42983
+ *
42984
+ * @throws Never throws - gracefully handles null DOM positions by returning uncorrected rects
42985
+ */
42986
+ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
42987
+ if (rects.length === 0) return rects;
42988
+ const pageDelta = {};
42989
+ if (domStart && rects[0] && domStart.pageIndex === rects[0].pageIndex) {
42990
+ const pageHeight = __privateMethod(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
42991
+ const pageGap = __privateGet(this, _layoutState).layout?.pageGap ?? 0;
42992
+ const layoutY = rects[0].y - rects[0].pageIndex * (pageHeight + pageGap);
42993
+ pageDelta[domStart.pageIndex] = {
42994
+ dx: domStart.x - rects[0].x,
42995
+ dy: domStart.y - layoutY
42996
+ };
42997
+ }
42998
+ return rects.map((rect, idx) => {
42999
+ const delta = pageDelta[rect.pageIndex];
43000
+ let adjustedX = delta ? rect.x + delta.dx : rect.x;
43001
+ let adjustedY = delta ? rect.y + delta.dy : rect.y;
43002
+ let adjustedWidth = rect.width;
43003
+ const isFirstRect = idx === 0;
43004
+ const isLastRect = idx === rects.length - 1;
43005
+ if (isFirstRect && domStart && rect.pageIndex === domStart.pageIndex) {
43006
+ const pageHeight = __privateMethod(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
43007
+ const pageGap = __privateGet(this, _layoutState).layout?.pageGap ?? 0;
43008
+ adjustedX = domStart.x;
43009
+ adjustedY = domStart.y + rect.pageIndex * (pageHeight + pageGap);
43010
+ }
43011
+ if (isLastRect && domEnd && rect.pageIndex === domEnd.pageIndex) {
43012
+ const endX = domEnd.x;
43013
+ adjustedWidth = Math.max(1, endX - adjustedX);
43014
+ }
43015
+ return {
43016
+ ...rect,
43017
+ x: adjustedX,
43018
+ y: adjustedY,
43019
+ width: adjustedWidth
43020
+ };
43021
+ });
43022
+ };
42813
43023
  renderSelectionRects_fn = function(rects) {
42814
43024
  const localSelectionLayer = __privateGet(this, _localSelectionLayer);
42815
43025
  if (!localSelectionLayer) {
@@ -42817,7 +43027,7 @@ renderSelectionRects_fn = function(rects) {
42817
43027
  }
42818
43028
  const pageHeight = __privateMethod(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
42819
43029
  const pageGap = __privateGet(this, _layoutState).layout?.pageGap ?? 0;
42820
- rects.forEach((rect, _index) => {
43030
+ rects.forEach((rect) => {
42821
43031
  const pageLocalY = rect.y - rect.pageIndex * (pageHeight + pageGap);
42822
43032
  const coords = __privateMethod(this, _PresentationEditor_instances, convertPageLocalToOverlayCoords_fn).call(this, rect.pageIndex, rect.x, pageLocalY);
42823
43033
  if (!coords) {
@@ -43083,6 +43293,20 @@ createLayoutMetrics_fn = function(perf, startMark, layout, blocks) {
43083
43293
  *
43084
43294
  * @private
43085
43295
  */
43296
+ getPageOffsetX_fn = function(pageIndex) {
43297
+ if (!__privateGet(this, _painterHost) || !__privateGet(this, _viewportHost)) {
43298
+ return null;
43299
+ }
43300
+ const pageEl = __privateGet(this, _painterHost).querySelector(
43301
+ `.superdoc-page[data-page-index="${pageIndex}"]`
43302
+ );
43303
+ if (!pageEl) return null;
43304
+ const pageRect = pageEl.getBoundingClientRect();
43305
+ const viewportRect = __privateGet(this, _viewportHost).getBoundingClientRect();
43306
+ const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
43307
+ const offsetX = (pageRect.left - viewportRect.left) / zoom;
43308
+ return offsetX;
43309
+ };
43086
43310
  convertPageLocalToOverlayCoords_fn = function(pageIndex, pageLocalX, pageLocalY) {
43087
43311
  if (!Number.isFinite(pageIndex) || pageIndex < 0) {
43088
43312
  console.warn(
@@ -43104,10 +43328,95 @@ convertPageLocalToOverlayCoords_fn = function(pageIndex, pageLocalX, pageLocalY)
43104
43328
  }
43105
43329
  const pageHeight = __privateGet(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
43106
43330
  const pageGap = __privateGet(this, _layoutState).layout?.pageGap ?? 0;
43107
- return {
43108
- x: pageLocalX,
43331
+ const pageOffsetX = __privateMethod(this, _PresentationEditor_instances, getPageOffsetX_fn).call(this, pageIndex) ?? 0;
43332
+ const coords = {
43333
+ x: pageOffsetX + pageLocalX,
43109
43334
  y: pageIndex * (pageHeight + pageGap) + pageLocalY
43110
43335
  };
43336
+ return coords;
43337
+ };
43338
+ /**
43339
+ * Computes DOM-based caret position in page-local coordinates.
43340
+ *
43341
+ * This method queries the actual DOM to find the pixel-perfect caret position
43342
+ * for a given ProseMirror position. It's used as the source of truth for caret
43343
+ * rendering, as DOM measurements reflect the actual painted text (including CSS
43344
+ * effects like word-spacing, text-indent, and padding).
43345
+ *
43346
+ * Algorithm:
43347
+ * 1. Find all spans with data-pm-start and data-pm-end attributes
43348
+ * 2. Locate the span containing the target PM position
43349
+ * 3. Find the closest .superdoc-page ancestor to determine page context
43350
+ * 4. Create a DOM Range at the character index within the text node
43351
+ * 5. Measure the Range's bounding rect relative to the page
43352
+ * 6. Return page-local coordinates (adjusted for zoom)
43353
+ *
43354
+ * Fallback Behavior:
43355
+ * - If text node unavailable: Use span's bounding rect
43356
+ * - If no matching span found: Return null
43357
+ * - If page element not found: Return null
43358
+ *
43359
+ * Error Handling:
43360
+ * DOM operations can throw exceptions (invalid ranges, detached nodes, etc.).
43361
+ * Callers should wrap this method in try-catch to prevent crashes.
43362
+ *
43363
+ * @param pos - ProseMirror position to compute caret for
43364
+ * @returns Object with {pageIndex, x, y} in page-local coordinates, or null if DOM unavailable
43365
+ *
43366
+ * @throws May throw DOM exceptions (InvalidStateError, IndexSizeError) if DOM is in invalid state
43367
+ *
43368
+ * @example
43369
+ * ```typescript
43370
+ * try {
43371
+ * const caretPos = this.#computeDomCaretPageLocal(42);
43372
+ * if (caretPos) {
43373
+ * // Render caret at caretPos.x, caretPos.y on page caretPos.pageIndex
43374
+ * }
43375
+ * } catch (error) {
43376
+ * console.warn('DOM caret computation failed:', error);
43377
+ * // Fall back to geometry-based calculation
43378
+ * }
43379
+ * ```
43380
+ */
43381
+ computeDomCaretPageLocal_fn = function(pos) {
43382
+ __privateGet(this, _viewportHost).querySelector(`.superdoc-page span[data-pm-start][data-pm-end]`) ? __privateGet(this, _viewportHost).querySelector(`.superdoc-page`) : null;
43383
+ const spans = Array.from(__privateGet(this, _viewportHost).querySelectorAll("span[data-pm-start][data-pm-end]"));
43384
+ let targetSpan = null;
43385
+ for (const span of spans) {
43386
+ const pmStart2 = Number(span.dataset.pmStart ?? "NaN");
43387
+ const pmEnd = Number(span.dataset.pmEnd ?? "NaN");
43388
+ if (!Number.isFinite(pmStart2) || !Number.isFinite(pmEnd)) continue;
43389
+ if (pos < pmStart2 || pos > pmEnd) continue;
43390
+ targetSpan = span;
43391
+ break;
43392
+ }
43393
+ if (!targetSpan) return null;
43394
+ const page = targetSpan.closest(".superdoc-page");
43395
+ if (!page) return null;
43396
+ const pageRect = page.getBoundingClientRect();
43397
+ const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
43398
+ const textNode = targetSpan.firstChild;
43399
+ if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
43400
+ const spanRect = targetSpan.getBoundingClientRect();
43401
+ return {
43402
+ pageIndex: Number(page.dataset.pageIndex ?? "0"),
43403
+ x: (spanRect.left - pageRect.left) / zoom,
43404
+ y: (spanRect.top - pageRect.top) / zoom
43405
+ };
43406
+ }
43407
+ const pmStart = Number(targetSpan.dataset.pmStart ?? "NaN");
43408
+ const charIndex = Math.min(pos - pmStart, textNode.length);
43409
+ const range = document.createRange();
43410
+ range.setStart(textNode, Math.max(0, charIndex));
43411
+ range.setEnd(textNode, Math.max(0, charIndex));
43412
+ const rangeRect = range.getBoundingClientRect();
43413
+ const lineEl = targetSpan.closest(".superdoc-line");
43414
+ const lineRect = lineEl?.getBoundingClientRect() ?? rangeRect;
43415
+ return {
43416
+ pageIndex: Number(page.dataset.pageIndex ?? "0"),
43417
+ x: (rangeRect.left - pageRect.left) / zoom,
43418
+ y: (lineRect.top - pageRect.top) / zoom
43419
+ };
43111
43420
  };
43112
43421
  normalizeClientPoint_fn = function(clientX, clientY) {
43113
43422
  if (!Number.isFinite(clientX) || !Number.isFinite(clientY)) {
@@ -43117,18 +43426,68 @@ normalizeClientPoint_fn = function(clientX, clientY) {
43117
43426
  const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
43118
43427
  const scrollLeft = __privateGet(this, _visibleHost).scrollLeft ?? 0;
43119
43428
  const scrollTop = __privateGet(this, _visibleHost).scrollTop ?? 0;
43429
+ const baseX = (clientX - rect.left + scrollLeft) / zoom;
43430
+ const baseY = (clientY - rect.top + scrollTop) / zoom;
43431
+ let adjustedX = baseX;
43432
+ const doc2 = __privateGet(this, _visibleHost).ownerDocument ?? document;
43433
+ const hitChain = typeof doc2.elementsFromPoint === "function" ? doc2.elementsFromPoint(clientX, clientY) : [];
43434
+ const pageEl = Array.isArray(hitChain) ? hitChain.find((el) => el?.classList?.contains("superdoc-page")) : null;
43435
+ if (pageEl) {
43436
+ const pageIndex = Number(pageEl.dataset.pageIndex ?? "NaN");
43437
+ if (Number.isFinite(pageIndex)) {
43438
+ const pageOffsetX = __privateMethod(this, _PresentationEditor_instances, getPageOffsetX_fn).call(this, pageIndex);
43439
+ if (pageOffsetX != null) {
43440
+ adjustedX = baseX - pageOffsetX;
43441
+ }
43442
+ }
43443
+ }
43120
43444
  return {
43121
- x: (clientX - rect.left + scrollLeft) / zoom,
43122
- y: (clientY - rect.top + scrollTop) / zoom
43445
+ x: adjustedX,
43446
+ y: baseY
43123
43447
  };
43124
43448
  };
43125
- computeCaretLayoutRect_fn = function(pos) {
43449
+ /**
43450
+ * Computes caret layout rectangle using geometry-based calculations.
43451
+ *
43452
+ * This method calculates the caret position and height from layout engine data
43453
+ * (fragments, blocks, measures) without querying the DOM. It's used as a fallback
43454
+ * when DOM-based measurements are unavailable or as a primary source in non-interactive
43455
+ * scenarios (e.g., headless rendering, PDF export).
43456
+ *
43457
+ * The geometry-based calculation accounts for:
43458
+ * - List markers (offset caret by marker width)
43459
+ * - Paragraph indents (left, right, first-line, hanging)
43460
+ * - Justified text alignment (extra space distributed across spaces)
43461
+ * - Multi-column layouts
43462
+ * - Table cell content
43463
+ *
43464
+ * Algorithm:
43465
+ * 1. Find the fragment containing the PM position
43466
+ * 2. Handle table fragments separately (delegate to #computeTableCaretLayoutRect)
43467
+ * 3. For paragraph fragments:
43468
+ * a. Find the line containing the position
43469
+ * b. Convert PM position to character offset
43470
+ * c. Measure X coordinate using Canvas-based text measurement
43471
+ * d. Apply marker width and indent adjustments
43472
+ * e. Calculate Y offset from line heights
43473
+ * f. Return page-local coordinates with line height
43474
+ *
43475
+ * @param pos - ProseMirror position to compute caret for
43476
+ * @param includeDomFallback - Whether to compare with DOM measurements for debugging (default: true).
43477
+ * When true, logs geometry vs DOM deltas for analysis. Has no effect on return value.
43478
+ * @returns Object with {pageIndex, x, y, height} in page-local coordinates, or null if position not found
43479
+ *
43480
+ * @example
43481
+ * ```typescript
43482
+ * const caretGeometry = this.#computeCaretLayoutRectGeometry(42, false);
43483
+ * if (caretGeometry) {
43484
+ * // Render caret at caretGeometry.x, caretGeometry.y with height caretGeometry.height
43485
+ * }
43486
+ * ```
43487
+ */
43488
+ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
43126
43489
  const layout = __privateGet(this, _layoutState).layout;
43127
43490
  if (!layout) return null;
43128
- const domResult = __privateMethod(this, _PresentationEditor_instances, computeCaretLayoutRectFromDOM_fn).call(this, pos);
43129
- if (domResult) {
43130
- return domResult;
43131
- }
43132
43491
  const hit = getFragmentAtPosition(layout, __privateGet(this, _layoutState).blocks, __privateGet(this, _layoutState).measures, pos);
43133
43492
  if (!hit) {
43134
43493
  return null;
@@ -43150,27 +43509,100 @@ computeCaretLayoutRect_fn = function(pos) {
43150
43509
  const { line, index: index2 } = lineInfo;
43151
43510
  const range = computeLinePmRange(block, line);
43152
43511
  if (range.pmStart == null || range.pmEnd == null) return null;
43153
- const pmCharsInLine = Math.max(1, range.pmEnd - range.pmStart);
43154
- const pmOffset = Math.max(0, Math.min(pmCharsInLine, pos - range.pmStart));
43155
- const localX = fragment.x + measureCharacterX(block, line, pmOffset);
43512
+ const pmOffset = pmPosToCharOffset(block, line, pos);
43513
+ const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
43514
+ const paraIndentLeft = block.attrs?.indent?.left ?? 0;
43515
+ const paraIndentRight = block.attrs?.indent?.right ?? 0;
43516
+ const availableWidth = Math.max(0, fragment.width - (paraIndentLeft + paraIndentRight));
43517
+ const charX = measureCharacterX(block, line, pmOffset, availableWidth);
43518
+ const firstLineOffset = (block.attrs?.indent?.firstLine ?? 0) - (block.attrs?.indent?.hanging ?? 0);
43519
+ const isFirstLine = index2 === fragment.fromLine;
43520
+ const isListFirstLine = isFirstLine && !fragment.continuesFromPrev && (fragment.markerWidth ?? 0) > 0;
43521
+ let indentAdjust = 0;
43522
+ if (!isListFirstLine) {
43523
+ indentAdjust = paraIndentLeft + (isFirstLine ? firstLineOffset : 0);
43524
+ }
43525
+ const localX = fragment.x + markerWidth + indentAdjust + charX;
43156
43526
  const lineOffset = __privateMethod(this, _PresentationEditor_instances, lineHeightBeforeIndex_fn).call(this, measure.lines, fragment.fromLine, index2);
43157
43527
  const localY = fragment.y + lineOffset;
43158
- return {
43528
+ const result = {
43159
43529
  pageIndex: hit.pageIndex,
43160
43530
  x: localX,
43161
43531
  y: localY,
43162
43532
  height: line.lineHeight
43163
43533
  };
43534
+ const pageEl = __privateGet(this, _painterHost)?.querySelector(
43535
+ `.superdoc-page[data-page-index="${hit.pageIndex}"]`
43536
+ );
43537
+ const pageRect = pageEl?.getBoundingClientRect();
43538
+ const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
43539
+ let domCaretX = null;
43540
+ let domCaretY = null;
43541
+ const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
43542
+ for (const spanEl of spanEls) {
43543
+ const pmStart = Number(spanEl.dataset.pmStart);
43544
+ const pmEnd = Number(spanEl.dataset.pmEnd);
43545
+ if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
43546
+ const textNode = spanEl.firstChild;
43547
+ const charIndex = Math.min(pos - pmStart, textNode.length);
43548
+ const rangeObj = document.createRange();
43549
+ rangeObj.setStart(textNode, charIndex);
43550
+ rangeObj.setEnd(textNode, charIndex);
43551
+ const rangeRect = rangeObj.getBoundingClientRect();
43552
+ if (pageRect) {
43553
+ domCaretX = (rangeRect.left - pageRect.left) / zoom;
43554
+ domCaretY = (rangeRect.top - pageRect.top) / zoom;
43555
+ }
43556
+ break;
43557
+ }
43558
+ }
43559
+ if (includeDomFallback && domCaretX != null && domCaretY != null) {
43560
+ return {
43561
+ pageIndex: hit.pageIndex,
43562
+ x: domCaretX,
43563
+ y: domCaretY,
43564
+ height: line.lineHeight
43565
+ };
43566
+ }
43567
+ return result;
43568
+ };
43569
+ /**
43570
+ * Compute caret position, preferring DOM when available, falling back to geometry.
43571
+ */
43572
+ computeCaretLayoutRect_fn = function(pos) {
43573
+ const geometry = __privateMethod(this, _PresentationEditor_instances, computeCaretLayoutRectGeometry_fn).call(this, pos, true);
43574
+ let dom = null;
43575
+ try {
43576
+ dom = __privateMethod(this, _PresentationEditor_instances, computeDomCaretPageLocal_fn).call(this, pos);
43577
+ } catch (error) {
43578
+ if (process$1.env.NODE_ENV === "development") {
43579
+ console.warn("[PresentationEditor] DOM caret computation failed in #computeCaretLayoutRect:", error);
43580
+ }
43581
+ }
43582
+ if (dom && geometry) {
43583
+ return {
43584
+ pageIndex: dom.pageIndex,
43585
+ x: dom.x,
43586
+ y: dom.y,
43587
+ height: geometry.height
43588
+ };
43589
+ }
43590
+ return geometry;
43164
43591
  };
43165
43592
  /**
43166
- * Computes caret position using DOM-based positioning.
43167
- * This matches how click-to-position mapping works and correctly handles
43168
- * segment-based rendering with tab stops.
43593
+ * DEPRECATED: Computes caret position using DOM-based positioning.
43594
+ *
43595
+ * This method is NO LONGER USED as of the fix for overlay positioning with external transforms.
43596
+ * It uses getBoundingClientRect() which returns viewport coordinates affected by external
43597
+ * transforms, causing caret drift when SuperDoc is embedded in containers with CSS transforms.
43169
43598
  *
43170
- * Returns page-local coordinates (x, y relative to the page element).
43599
+ * Kept for reference only. Use layout engine geometry instead (see #computeCaretLayoutRect).
43600
+ *
43601
+ * @deprecated Use layout engine geometry directly - this method is incompatible with external transforms
43602
+ * @private
43171
43603
  */
43604
+ // eslint-disable-next-line no-unused-private-class-members
43172
43605
  computeCaretLayoutRectFromDOM_fn = function(pos) {
43173
- const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
43174
43606
  let targetPageEl = null;
43175
43607
  if (__privateGet(this, _layoutState).layout && __privateGet(this, _layoutState).blocks && __privateGet(this, _layoutState).measures) {
43176
43608
  const fragmentHit = getFragmentAtPosition(
@@ -43202,6 +43634,7 @@ computeCaretLayoutRectFromDOM_fn = function(pos) {
43202
43634
  if (!pageEl) continue;
43203
43635
  const pageIndex = Number(pageEl.dataset.pageIndex ?? "0");
43204
43636
  const pageRect = pageEl.getBoundingClientRect();
43637
+ const zoom = __privateGet(this, _layoutOptions).zoom ?? 1;
43205
43638
  const textNode = spanEl.firstChild;
43206
43639
  if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
43207
43640
  const spanRect2 = spanEl.getBoundingClientRect();
@@ -43254,9 +43687,15 @@ computeCaretLayoutRectFromDOM_fn = function(pos) {
43254
43687
  return null;
43255
43688
  };
43256
43689
  /**
43257
- * Computes caret position within a table cell using DOM-based positioning.
43258
- * This uses the actual rendered DOM elements to get accurate positions,
43259
- * matching how click-to-position mapping works.
43690
+ * DEPRECATED: Computes caret position within a table cell using DOM-based positioning.
43691
+ *
43692
+ * This method is NO LONGER USED as the parent #computeCaretLayoutRect now uses layout
43693
+ * engine geometry exclusively to avoid issues with external transforms.
43694
+ *
43695
+ * Kept for reference only.
43696
+ *
43697
+ * @deprecated Use layout engine geometry - this method is incompatible with external transforms
43698
+ * @private
43260
43699
  */
43261
43700
  computeTableCaretLayoutRect_fn = function(pos, _fragment, _tableBlock, _tableMeasure, pageIndex) {
43262
43701
  const lineEls = Array.from(__privateGet(this, _viewportHost).querySelectorAll(".superdoc-line"));