@harbour-enterprises/superdoc 1.0.0-beta.21 → 1.0.0-beta.23

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 (28) hide show
  1. package/dist/chunks/{PdfViewer-CqAQvFv3.cjs → PdfViewer-C9mryfp4.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-CEwbF85g.es.js → PdfViewer-umOKwA1g.es.js} +1 -1
  3. package/dist/chunks/{index-DSuc12CK-Dpg5Hd9W.cjs → index-DYBG7Xab-CoI6fike.cjs} +1 -1
  4. package/dist/chunks/{index-DSuc12CK-DH_DeF0B.es.js → index-DYBG7Xab-mIeLdlWI.es.js} +1 -1
  5. package/dist/chunks/{index-BFobqgP4.es.js → index-DyY842H4.es.js} +7 -5
  6. package/dist/chunks/{index-Dy-eAVHL.cjs → index-Q-l_lwcU.cjs} +7 -5
  7. package/dist/chunks/{super-editor.es-C2UuUFg3.cjs → super-editor.es-49DW4_-r.cjs} +445 -135
  8. package/dist/chunks/{super-editor.es-B5YJmpPg.es.js → super-editor.es-Cj9Sb-Qv.es.js} +445 -135
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  10. package/dist/super-editor/ai-writer.es.js +2 -2
  11. package/dist/super-editor/chunks/{converter-Cw0V00On.js → converter-DJyfDFNm.js} +38 -34
  12. package/dist/super-editor/chunks/{docx-zipper-D7k6lS5l.js → docx-zipper-C-9Tqy8I.js} +1 -1
  13. package/dist/super-editor/chunks/{editor-CDWzRc4H.js → editor-f37DOCIX.js} +415 -108
  14. package/dist/super-editor/chunks/{index-DSuc12CK.js → index-DYBG7Xab.js} +1 -1
  15. package/dist/super-editor/chunks/{toolbar-CHJspeuY.js → toolbar-Devgq8w3.js} +2 -2
  16. package/dist/super-editor/converter.es.js +1 -1
  17. package/dist/super-editor/docx-zipper.es.js +2 -2
  18. package/dist/super-editor/editor.es.js +3 -3
  19. package/dist/super-editor/file-zipper.es.js +1 -1
  20. package/dist/super-editor/super-editor.es.js +6 -6
  21. package/dist/super-editor/toolbar.es.js +2 -2
  22. package/dist/super-editor.cjs +1 -1
  23. package/dist/super-editor.es.js +1 -1
  24. package/dist/superdoc.cjs +2 -2
  25. package/dist/superdoc.es.js +2 -2
  26. package/dist/superdoc.umd.js +451 -139
  27. package/dist/superdoc.umd.js.map +1 -1
  28. package/package.json +1 -1
@@ -24978,24 +24978,32 @@ function extractGradientFill(gradFill) {
24978
24978
  const DRAWING_XML_TAG = "w:drawing";
24979
24979
  const SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
24980
24980
  const GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
24981
+ const normalizeTargetPath = (targetPath = "") => {
24982
+ if (!targetPath) return targetPath;
24983
+ const trimmed = targetPath.replace(/^\/+/, "");
24984
+ if (trimmed.startsWith("word/")) return trimmed;
24985
+ if (trimmed.startsWith("media/")) return `word/${trimmed}`;
24986
+ return `word/${trimmed}`;
24987
+ };
24981
24988
  const DEFAULT_SHAPE_WIDTH = 100;
24982
24989
  const DEFAULT_SHAPE_HEIGHT = 100;
24983
24990
  function handleImageNode$1(node, params2, isAnchor) {
24991
+ if (!node) return null;
24984
24992
  const { docx, filename } = params2;
24985
- const { attributes } = node;
24993
+ const attributes = node?.attributes || {};
24986
24994
  const padding = {
24987
- top: emuToPixels(attributes["distT"]),
24988
- bottom: emuToPixels(attributes["distB"]),
24989
- left: emuToPixels(attributes["distL"]),
24990
- right: emuToPixels(attributes["distR"])
24995
+ top: emuToPixels(attributes?.["distT"]),
24996
+ bottom: emuToPixels(attributes?.["distB"]),
24997
+ left: emuToPixels(attributes?.["distL"]),
24998
+ right: emuToPixels(attributes?.["distR"])
24991
24999
  };
24992
- const extent = node.elements.find((el) => el.name === "wp:extent");
25000
+ const extent = node?.elements?.find((el) => el.name === "wp:extent");
24993
25001
  const size2 = {
24994
25002
  width: emuToPixels(extent?.attributes?.cx),
24995
25003
  height: emuToPixels(extent?.attributes?.cy)
24996
25004
  };
24997
25005
  let transformData = {};
24998
- const effectExtent = node.elements.find((el) => el.name === "wp:effectExtent");
25006
+ const effectExtent = node?.elements?.find((el) => el.name === "wp:effectExtent");
24999
25007
  if (effectExtent) {
25000
25008
  const sanitizeEmuValue = (value) => {
25001
25009
  if (value === null || value === void 0) return 0;
@@ -25009,12 +25017,12 @@ function handleImageNode$1(node, params2, isAnchor) {
25009
25017
  bottom: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["b"]))
25010
25018
  };
25011
25019
  }
25012
- const positionHTag = node.elements.find((el) => el.name === "wp:positionH");
25013
- const positionH = positionHTag?.elements.find((el) => el.name === "wp:posOffset");
25020
+ const positionHTag = node?.elements?.find((el) => el.name === "wp:positionH");
25021
+ const positionH = positionHTag?.elements?.find((el) => el.name === "wp:posOffset");
25014
25022
  const positionHValue = emuToPixels(positionH?.elements[0]?.text);
25015
25023
  const hRelativeFrom = positionHTag?.attributes?.relativeFrom;
25016
- const alignH = positionHTag?.elements.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
25017
- const positionVTag = node.elements.find((el) => el.name === "wp:positionV");
25024
+ const alignH = positionHTag?.elements?.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
25025
+ const positionVTag = node?.elements?.find((el) => el.name === "wp:positionV");
25018
25026
  const positionV = positionVTag?.elements?.find((el) => el.name === "wp:posOffset");
25019
25027
  const positionVValue = emuToPixels(positionV?.elements[0]?.text);
25020
25028
  const vRelativeFrom = positionVTag?.attributes?.relativeFrom;
@@ -25024,8 +25032,8 @@ function handleImageNode$1(node, params2, isAnchor) {
25024
25032
  top: positionVValue
25025
25033
  };
25026
25034
  const useSimplePos = attributes["simplePos"] === "1" || attributes["simplePos"] === 1 || attributes["simplePos"] === true;
25027
- const simplePosNode = node.elements.find((el) => el.name === "wp:simplePos");
25028
- const wrapNode = isAnchor ? node.elements.find(
25035
+ const simplePosNode = node?.elements?.find((el) => el.name === "wp:simplePos");
25036
+ const wrapNode = isAnchor ? node?.elements?.find(
25029
25037
  (el) => ["wp:wrapNone", "wp:wrapSquare", "wp:wrapThrough", "wp:wrapTight", "wp:wrapTopAndBottom"].includes(el.name)
25030
25038
  ) : null;
25031
25039
  const wrap2 = isAnchor ? { type: wrapNode?.name.slice(7) || "None", attrs: {} } : { type: "Inline" };
@@ -25146,9 +25154,8 @@ function handleImageNode$1(node, params2, isAnchor) {
25146
25154
  if (!rel) return null;
25147
25155
  const { attributes: relAttributes } = rel;
25148
25156
  const targetPath = relAttributes["Target"];
25149
- let path = `word/${targetPath}`;
25150
- if (targetPath.startsWith("/word") || targetPath.startsWith("/media")) path = targetPath.substring(1);
25151
- const extension = targetPath.substring(targetPath.lastIndexOf(".") + 1);
25157
+ const path = normalizeTargetPath(targetPath);
25158
+ const extension = path.substring(path.lastIndexOf(".") + 1);
25152
25159
  return {
25153
25160
  type: "image",
25154
25161
  attrs: {
@@ -25166,8 +25173,8 @@ function handleImageNode$1(node, params2, isAnchor) {
25166
25173
  transformData,
25167
25174
  ...useSimplePos && {
25168
25175
  simplePos: {
25169
- x: simplePosNode.attributes?.x,
25170
- y: simplePosNode.attributes?.y
25176
+ x: simplePosNode?.attributes?.x,
25177
+ y: simplePosNode?.attributes?.y
25171
25178
  }
25172
25179
  },
25173
25180
  wrap: wrap2,
@@ -25177,12 +25184,12 @@ function handleImageNode$1(node, params2, isAnchor) {
25177
25184
  wrapTopAndBottom: wrap2.type === "TopAndBottom",
25178
25185
  shouldStretch,
25179
25186
  originalPadding: {
25180
- distT: attributes["distT"],
25181
- distB: attributes["distB"],
25182
- distL: attributes["distL"],
25183
- distR: attributes["distR"]
25187
+ distT: attributes?.["distT"],
25188
+ distB: attributes?.["distB"],
25189
+ distL: attributes?.["distL"],
25190
+ distR: attributes?.["distR"]
25184
25191
  },
25185
- originalAttributes: node.attributes,
25192
+ originalAttributes: node?.attributes || {},
25186
25193
  rId: relAttributes["Id"]
25187
25194
  }
25188
25195
  };
@@ -25346,11 +25353,8 @@ const handleShapeGroup = (params2, node, graphicData, size2, padding, marginOffs
25346
25353
  const { elements } = relationships || [];
25347
25354
  const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
25348
25355
  if (!rel) return null;
25349
- const targetPath = rel.attributes?.["Target"];
25350
- let path = `word/${targetPath}`;
25351
- if (targetPath.startsWith("/word") || targetPath.startsWith("/media")) {
25352
- path = targetPath.substring(1);
25353
- }
25356
+ const targetPath = normalizeTargetPath(rel.attributes?.["Target"]);
25357
+ const path = targetPath;
25354
25358
  const nvPicPr = pic.elements?.find((el) => el.name === "pic:nvPicPr");
25355
25359
  const cNvPr = nvPicPr?.elements?.find((el) => el.name === "pic:cNvPr");
25356
25360
  const picId = cNvPr?.attributes?.["id"];
@@ -36371,7 +36375,7 @@ const _SuperConverter = class _SuperConverter2 {
36371
36375
  static getStoredSuperdocVersion(docx) {
36372
36376
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
36373
36377
  }
36374
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.21") {
36378
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.23") {
36375
36379
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
36376
36380
  }
36377
36381
  /**
@@ -39677,7 +39681,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
39677
39681
  var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
39678
39682
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
39679
39683
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
39680
- 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, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _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, _remoteCursorState, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _remoteCursorRafHandle, _scrollTimeout, _PresentationEditor_instances, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _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, 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, 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, _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;
39684
+ 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, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _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, _remoteCursorState, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _remoteCursorRafHandle, _scrollTimeout, _PresentationEditor_instances, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _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, 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, 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;
39681
39685
  var GOOD_LEAF_SIZE = 200;
39682
39686
  var RopeSequence = function RopeSequence2() {
39683
39687
  };
@@ -49579,6 +49583,59 @@ function skipTab(dir) {
49579
49583
  return true;
49580
49584
  };
49581
49585
  }
49586
+ const decreaseListIndent = () => ({ editor, tr, dispatch }) => {
49587
+ const handled = changeListLevel(-1, editor, tr);
49588
+ if (handled && dispatch) {
49589
+ dispatch(tr);
49590
+ }
49591
+ return handled;
49592
+ };
49593
+ const removeNumberingProperties = ({ checkType = "startParagraph" } = {}) => (props) => {
49594
+ const { tr, state: state2, editor, dispatch } = props;
49595
+ const { node: paragraph, pos } = findParentNode(isList)(state2.selection) || {};
49596
+ if (!paragraph) return false;
49597
+ if (checkType === "empty" && !isVisuallyEmptyParagraph(paragraph)) return false;
49598
+ if (checkType === "startParagraph") {
49599
+ const { $from, empty: empty2 } = state2.selection;
49600
+ if ((!empty2 || $from.parentOffset !== 0) && !isVisuallyEmptyParagraph(paragraph)) return false;
49601
+ }
49602
+ const ilvl = getResolvedParagraphProperties(paragraph).numberingProperties.ilvl;
49603
+ if (ilvl > 0) {
49604
+ const outdented = decreaseListIndent()(props);
49605
+ if (outdented) {
49606
+ tr.scrollIntoView();
49607
+ }
49608
+ return outdented;
49609
+ } else {
49610
+ updateNumberingProperties(null, paragraph, pos, editor, tr);
49611
+ }
49612
+ if (dispatch) dispatch(tr);
49613
+ return true;
49614
+ };
49615
+ function isVisuallyEmptyParagraph(node) {
49616
+ if (!node || node.type.name !== "paragraph") return false;
49617
+ let hasHardBreak = false;
49618
+ node.descendants((n) => {
49619
+ if (n.type && n.type.name === "hardBreak") {
49620
+ hasHardBreak = true;
49621
+ return false;
49622
+ }
49623
+ return true;
49624
+ });
49625
+ if (hasHardBreak) return false;
49626
+ const text = (node.textContent || "").replace(/\u200b/g, "").trim();
49627
+ if (text.length > 0) return false;
49628
+ let hasInlineLeaf = false;
49629
+ node.descendants((n) => {
49630
+ if (n.isInline && n.isLeaf && n.type?.name !== "hardBreak" && n.type?.name !== "run") {
49631
+ hasInlineLeaf = true;
49632
+ return false;
49633
+ }
49634
+ return true;
49635
+ });
49636
+ if (hasInlineLeaf) return false;
49637
+ return true;
49638
+ }
49582
49639
  const toggleList = (listType) => ({ editor, state: state2, tr, dispatch }) => {
49583
49640
  let predicate;
49584
49641
  if (listType === "orderedList") {
@@ -49598,19 +49655,22 @@ const toggleList = (listType) => ({ editor, state: state2, tr, dispatch }) => {
49598
49655
  const { from: from2, to } = selection;
49599
49656
  let firstListNode = null;
49600
49657
  let hasNonListParagraphs = false;
49601
- let paragraphsInSelection = [];
49658
+ let allParagraphsInSelection = [];
49602
49659
  state2.doc.nodesBetween(from2, to, (node, pos) => {
49603
49660
  if (node.type.name === "paragraph") {
49604
- paragraphsInSelection.push({ node, pos });
49605
- if (!firstListNode && predicate(node)) {
49606
- firstListNode = node;
49607
- } else if (!predicate(node)) {
49608
- hasNonListParagraphs = true;
49609
- }
49661
+ allParagraphsInSelection.push({ node, pos });
49610
49662
  return false;
49611
49663
  }
49612
49664
  return true;
49613
49665
  });
49666
+ let paragraphsInSelection = allParagraphsInSelection.length === 1 ? allParagraphsInSelection : allParagraphsInSelection.filter(({ node }) => !isVisuallyEmptyParagraph(node));
49667
+ for (const { node } of paragraphsInSelection) {
49668
+ if (!firstListNode && predicate(node)) {
49669
+ firstListNode = node;
49670
+ } else if (!predicate(node)) {
49671
+ hasNonListParagraphs = true;
49672
+ }
49673
+ }
49614
49674
  if (!firstListNode && from2 > 0) {
49615
49675
  const $from = state2.doc.resolve(from2);
49616
49676
  const parentIndex = $from.index(-1);
@@ -49654,11 +49714,30 @@ const toggleList = (listType) => ({ editor, state: state2, tr, dispatch }) => {
49654
49714
  }
49655
49715
  updateNumberingProperties(sharedNumberingProperties, node, pos, editor, tr);
49656
49716
  }
49657
- const newTo = tr.mapping.map(to);
49658
- if (newTo >= 0 && newTo <= tr.doc.content.size) {
49659
- try {
49660
- tr.setSelection(state2.selection.constructor.near(tr.doc.resolve(newTo)));
49661
- } catch {
49717
+ if (paragraphsInSelection.length > 0) {
49718
+ const firstPara = paragraphsInSelection[0];
49719
+ const lastPara = paragraphsInSelection[paragraphsInSelection.length - 1];
49720
+ const mappedFirstPos = tr.mapping.map(firstPara.pos);
49721
+ const mappedLastPos = tr.mapping.map(lastPara.pos);
49722
+ const $firstPos = tr.doc.resolve(mappedFirstPos);
49723
+ const $lastPos = tr.doc.resolve(mappedLastPos);
49724
+ const firstNode = $firstPos.nodeAfter;
49725
+ const lastNode = $lastPos.nodeAfter;
49726
+ if (firstNode && lastNode) {
49727
+ let selFrom = mappedFirstPos + 1;
49728
+ let selTo = mappedLastPos + lastNode.nodeSize - 1;
49729
+ if (firstNode.firstChild && firstNode.firstChild.type.name === "run") {
49730
+ selFrom = mappedFirstPos + 2;
49731
+ }
49732
+ if (lastNode.lastChild && lastNode.lastChild.type.name === "run") {
49733
+ selTo = mappedLastPos + lastNode.nodeSize - 2;
49734
+ }
49735
+ if (selFrom >= 0 && selTo <= tr.doc.content.size && selFrom <= selTo) {
49736
+ try {
49737
+ tr.setSelection(TextSelection$1.create(tr.doc, selFrom, selTo));
49738
+ } catch {
49739
+ }
49740
+ }
49662
49741
  }
49663
49742
  }
49664
49743
  if (dispatch) dispatch(tr);
@@ -49671,59 +49750,6 @@ const increaseListIndent = () => ({ editor, tr, dispatch }) => {
49671
49750
  }
49672
49751
  return handled;
49673
49752
  };
49674
- const decreaseListIndent = () => ({ editor, tr, dispatch }) => {
49675
- const handled = changeListLevel(-1, editor, tr);
49676
- if (handled && dispatch) {
49677
- dispatch(tr);
49678
- }
49679
- return handled;
49680
- };
49681
- const removeNumberingProperties = ({ checkType = "startParagraph" } = {}) => (props) => {
49682
- const { tr, state: state2, editor, dispatch } = props;
49683
- const { node: paragraph, pos } = findParentNode(isList)(state2.selection) || {};
49684
- if (!paragraph) return false;
49685
- if (checkType === "empty" && !isVisuallyEmptyParagraph(paragraph)) return false;
49686
- if (checkType === "startParagraph") {
49687
- const { $from, empty: empty2 } = state2.selection;
49688
- if ((!empty2 || $from.parentOffset !== 0) && !isVisuallyEmptyParagraph(paragraph)) return false;
49689
- }
49690
- const ilvl = getResolvedParagraphProperties(paragraph).numberingProperties.ilvl;
49691
- if (ilvl > 0) {
49692
- const outdented = decreaseListIndent()(props);
49693
- if (outdented) {
49694
- tr.scrollIntoView();
49695
- }
49696
- return outdented;
49697
- } else {
49698
- updateNumberingProperties(null, paragraph, pos, editor, tr);
49699
- }
49700
- if (dispatch) dispatch(tr);
49701
- return true;
49702
- };
49703
- function isVisuallyEmptyParagraph(node) {
49704
- if (!node || node.type.name !== "paragraph") return false;
49705
- let hasHardBreak = false;
49706
- node.descendants((n) => {
49707
- if (n.type && n.type.name === "hardBreak") {
49708
- hasHardBreak = true;
49709
- return false;
49710
- }
49711
- return true;
49712
- });
49713
- if (hasHardBreak) return false;
49714
- const text = (node.textContent || "").replace(/\u200b/g, "").trim();
49715
- if (text.length > 0) return false;
49716
- let hasInlineLeaf = false;
49717
- node.descendants((n) => {
49718
- if (n.isInline && n.isLeaf && n.type?.name !== "hardBreak" && n.type?.name !== "run") {
49719
- hasInlineLeaf = true;
49720
- return false;
49721
- }
49722
- return true;
49723
- });
49724
- if (hasInlineLeaf) return false;
49725
- return true;
49726
- }
49727
49753
  const restoreSelection = () => ({ editor, state: state2, tr }) => {
49728
49754
  if (editor.options.lastSelection) {
49729
49755
  const selectionTr = tr.setSelection(
@@ -49806,6 +49832,7 @@ const commands$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
49806
49832
  insertTabCharacter,
49807
49833
  insertTabNode,
49808
49834
  isStyleTokenEnabled,
49835
+ isVisuallyEmptyParagraph,
49809
49836
  joinBackward,
49810
49837
  joinDown,
49811
49838
  joinForward,
@@ -49924,12 +49951,38 @@ const Keymap = Extension.create({
49924
49951
  const Editable = Extension.create({
49925
49952
  name: "editable",
49926
49953
  addPmPlugins() {
49954
+ const editor = this.editor;
49927
49955
  const editablePlugin = new Plugin({
49928
49956
  key: new PluginKey("editable"),
49929
49957
  props: {
49930
- editable: () => {
49931
- return this.editor.options.editable;
49932
- }
49958
+ editable: () => editor.options.editable,
49959
+ handleDOMEvents: {
49960
+ beforeinput: (_view, event) => {
49961
+ if (!editor.options.editable) {
49962
+ event.preventDefault();
49963
+ return true;
49964
+ }
49965
+ return false;
49966
+ },
49967
+ mousedown: (_view, event) => {
49968
+ if (!editor.options.editable) {
49969
+ event.preventDefault();
49970
+ return true;
49971
+ }
49972
+ return false;
49973
+ },
49974
+ focus: (view, event) => {
49975
+ if (!editor.options.editable) {
49976
+ event.preventDefault();
49977
+ view.dom.blur();
49978
+ return true;
49979
+ }
49980
+ return false;
49981
+ }
49982
+ },
49983
+ handleClick: () => !editor.options.editable,
49984
+ handleDoubleClick: () => !editor.options.editable,
49985
+ handleTripleClick: () => !editor.options.editable
49933
49986
  }
49934
49987
  });
49935
49988
  return [editablePlugin];
@@ -53487,7 +53540,7 @@ const isHeadless = (editor) => {
53487
53540
  const shouldSkipNodeView = (editor) => {
53488
53541
  return isHeadless(editor);
53489
53542
  };
53490
- const summaryVersion = "1.0.0-beta.21";
53543
+ const summaryVersion = "1.0.0-beta.23";
53491
53544
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
53492
53545
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
53493
53546
  function mapAttributes(attrs) {
@@ -53892,10 +53945,23 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53892
53945
  this.view.updateState(this.state);
53893
53946
  }
53894
53947
  /**
53895
- * Set whether the editor is editable
53948
+ * Set whether the editor is editable.
53949
+ *
53950
+ * When setting to non-editable, this method:
53951
+ * - Forces ProseMirror to re-evaluate the editable prop from the Editable plugin
53952
+ * - Blurs the editor to remove the cursor
53953
+ *
53954
+ * @param editable - Whether the editor should accept user input (default: true)
53955
+ * @param emitUpdate - Whether to emit an update event after changing editability (default: true)
53896
53956
  */
53897
53957
  setEditable(editable = true, emitUpdate = true) {
53898
53958
  this.setOptions({ editable });
53959
+ if (this.view) {
53960
+ this.view.setProps({});
53961
+ if (!editable && this.view.dom) {
53962
+ this.view.dom.blur();
53963
+ }
53964
+ }
53899
53965
  if (emitUpdate) {
53900
53966
  this.emit("update", { editor: this, transaction: this.state.tr });
53901
53967
  }
@@ -54263,7 +54329,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
54263
54329
  { default: remarkStringify },
54264
54330
  { default: remarkGfm }
54265
54331
  ] = await Promise.all([
54266
- import("./index-DSuc12CK-DH_DeF0B.es.js"),
54332
+ import("./index-DYBG7Xab-mIeLdlWI.es.js"),
54267
54333
  import("./index-DRCvimau-Cw339678.es.js"),
54268
54334
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
54269
54335
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -54468,7 +54534,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
54468
54534
  * Process collaboration migrations
54469
54535
  */
54470
54536
  processCollaborationMigrations() {
54471
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.21");
54537
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.23");
54472
54538
  if (!this.options.ydoc) return;
54473
54539
  const metaMap = this.options.ydoc.getMap("meta");
54474
54540
  let docVersion = metaMap.get("version");
@@ -56920,6 +56986,11 @@ const normalizeAlignment = (value) => {
56920
56986
  case "right":
56921
56987
  case "justify":
56922
56988
  return value;
56989
+ case "both":
56990
+ case "distribute":
56991
+ case "numTab":
56992
+ case "thaiDistribute":
56993
+ return "justify";
56923
56994
  case "end":
56924
56995
  return "right";
56925
56996
  case "start":
@@ -59134,6 +59205,11 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
59134
59205
  } else if (computed2.paragraph.alignment) {
59135
59206
  paragraphAttrs.alignment = computed2.paragraph.alignment;
59136
59207
  }
59208
+ const isJustified = paragraphAttrs.alignment === "justify" || paragraphAttrs.alignment === "both";
59209
+ const hasFirstLineIndent = normalizedIndent?.firstLine && normalizedIndent.firstLine > 0;
59210
+ if (isJustified && hasFirstLineIndent) {
59211
+ paragraphAttrs.suppressFirstLineIndent = true;
59212
+ }
59137
59213
  const spacingPx = spacingPtToPx(spacing, normalizedSpacing);
59138
59214
  if (spacingPx) paragraphAttrs.spacing = spacingPx;
59139
59215
  if (normalizedSpacing?.beforeAutospacing != null || normalizedSpacing?.afterAutospacing != null) {
@@ -59351,7 +59427,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
59351
59427
  }
59352
59428
  }
59353
59429
  paragraphAttrs.wordLayout = wordLayout;
59354
- if (enrichedNumberingProps.resolvedLevelIndent) {
59430
+ if (enrichedNumberingProps.resolvedLevelIndent && !hasExplicitIndent) {
59355
59431
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
59356
59432
  paragraphAttrs.indent = {
59357
59433
  ...paragraphAttrs.indent,
@@ -62717,8 +62793,14 @@ function computeNextSectionPropsAtBreak(blocks) {
62717
62793
  });
62718
62794
  return nextSectionPropsAtBreak;
62719
62795
  }
62720
- function scheduleSectionBreak(block, state2, baseMargins) {
62796
+ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0) {
62721
62797
  const next = { ...state2 };
62798
+ const calcRequiredTopMargin = (headerDistance, baseTop) => {
62799
+ if (maxHeaderContentHeight > 0) {
62800
+ return Math.max(baseTop, headerDistance + maxHeaderContentHeight);
62801
+ }
62802
+ return Math.max(baseTop, headerDistance);
62803
+ };
62722
62804
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
62723
62805
  if (block.pageSize) {
62724
62806
  next.activePageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -62732,7 +62814,7 @@ function scheduleSectionBreak(block, state2, baseMargins) {
62732
62814
  const headerDistance = Math.max(0, block.margins.header);
62733
62815
  next.activeHeaderDistance = headerDistance;
62734
62816
  next.pendingHeaderDistance = headerDistance;
62735
- next.activeTopMargin = Math.max(baseMargins.top, headerDistance);
62817
+ next.activeTopMargin = calcRequiredTopMargin(headerDistance, baseMargins.top);
62736
62818
  next.pendingTopMargin = next.activeTopMargin;
62737
62819
  }
62738
62820
  if (block.margins?.footer !== void 0) {
@@ -62754,9 +62836,15 @@ function scheduleSectionBreak(block, state2, baseMargins) {
62754
62836
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
62755
62837
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
62756
62838
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
62757
- next.pendingTopMargin = typeof headerPx === "number" ? Math.max(baseMargins.top, headerPx) : nextTop;
62839
+ if (typeof headerPx === "number") {
62840
+ const newHeaderDist = Math.max(0, headerPx);
62841
+ next.pendingHeaderDistance = newHeaderDist;
62842
+ next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, baseMargins.top);
62843
+ } else {
62844
+ next.pendingTopMargin = nextTop;
62845
+ next.pendingHeaderDistance = nextHeader;
62846
+ }
62758
62847
  next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
62759
- next.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
62760
62848
  next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
62761
62849
  if (block.pageSize) {
62762
62850
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -64221,7 +64309,22 @@ function layoutDocument(blocks, measures, options = {}) {
64221
64309
  if (contentWidth <= 0) {
64222
64310
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
64223
64311
  }
64224
- let activeTopMargin = margins.top;
64312
+ const validateHeaderHeight = (height) => {
64313
+ if (height === void 0) return 0;
64314
+ if (!Number.isFinite(height) || height < 0) return 0;
64315
+ return height;
64316
+ };
64317
+ const headerContentHeights = options.headerContentHeights;
64318
+ const maxHeaderContentHeight = headerContentHeights ? Math.max(
64319
+ 0,
64320
+ validateHeaderHeight(headerContentHeights.default),
64321
+ validateHeaderHeight(headerContentHeights.first),
64322
+ validateHeaderHeight(headerContentHeights.even),
64323
+ validateHeaderHeight(headerContentHeights.odd)
64324
+ ) : 0;
64325
+ const headerDistance = margins.header ?? margins.top;
64326
+ const effectiveTopMargin = maxHeaderContentHeight > 0 ? Math.max(margins.top, headerDistance + maxHeaderContentHeight) : margins.top;
64327
+ let activeTopMargin = effectiveTopMargin;
64225
64328
  let activeBottomMargin = margins.bottom;
64226
64329
  let pendingTopMargin = null;
64227
64330
  let pendingBottomMargin = null;
@@ -64245,7 +64348,7 @@ function layoutDocument(blocks, measures, options = {}) {
64245
64348
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
64246
64349
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
64247
64350
  if (typeof scheduleSectionBreak === "function") {
64248
- return scheduleSectionBreak(block, state2, baseMargins);
64351
+ return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight);
64249
64352
  }
64250
64353
  const next = { ...state2 };
64251
64354
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
@@ -64258,10 +64361,11 @@ function layoutDocument(blocks, measures, options = {}) {
64258
64361
  next.pendingOrientation = null;
64259
64362
  }
64260
64363
  if (block.margins?.header !== void 0) {
64261
- const headerDistance = Math.max(0, block.margins.header);
64262
- next.activeHeaderDistance = headerDistance;
64263
- next.pendingHeaderDistance = headerDistance;
64264
- next.activeTopMargin = Math.max(baseMargins.top, headerDistance);
64364
+ const headerDist = Math.max(0, block.margins.header);
64365
+ next.activeHeaderDistance = headerDist;
64366
+ next.pendingHeaderDistance = headerDist;
64367
+ const requiredTop = maxHeaderContentHeight > 0 ? headerDist + maxHeaderContentHeight : headerDist;
64368
+ next.activeTopMargin = Math.max(baseMargins.top, requiredTop);
64265
64369
  next.pendingTopMargin = next.activeTopMargin;
64266
64370
  }
64267
64371
  if (block.margins?.footer !== void 0) {
@@ -64298,14 +64402,22 @@ function layoutDocument(blocks, measures, options = {}) {
64298
64402
  }
64299
64403
  const headerPx = block.margins?.header;
64300
64404
  const footerPx = block.margins?.footer;
64405
+ const topPx = block.margins?.top;
64301
64406
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
64302
64407
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
64303
64408
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
64304
64409
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
64305
- next.pendingTopMargin = typeof headerPx === "number" ? Math.max(baseMargins.top, headerPx) : nextTop;
64306
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
64307
64410
  next.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
64308
64411
  next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
64412
+ if (typeof headerPx === "number" || typeof topPx === "number") {
64413
+ const sectionTop = topPx ?? baseMargins.top;
64414
+ const sectionHeader = next.pendingHeaderDistance;
64415
+ const requiredTop = maxHeaderContentHeight > 0 ? sectionHeader + maxHeaderContentHeight : sectionHeader;
64416
+ next.pendingTopMargin = Math.max(sectionTop, requiredTop);
64417
+ } else {
64418
+ next.pendingTopMargin = nextTop;
64419
+ }
64420
+ next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
64309
64421
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
64310
64422
  if (block.orientation) next.pendingOrientation = block.orientation;
64311
64423
  const sectionType = block.type ?? "continuous";
@@ -65056,7 +65168,7 @@ const resolveTrackedChangesEnabled = (attrs, defaultEnabled = true) => {
65056
65168
  }
65057
65169
  return attrs.trackedChangesEnabled !== false;
65058
65170
  };
65059
- const MAX_CACHE_SIZE = 1e4;
65171
+ const MAX_CACHE_SIZE$1 = 1e4;
65060
65172
  const BYTES_PER_ENTRY_ESTIMATE = 5e3;
65061
65173
  const NORMALIZED_WHITESPACE = /\s+/g;
65062
65174
  const normalizeText = (text) => text.replace(NORMALIZED_WHITESPACE, " ");
@@ -65156,7 +65268,7 @@ class MeasureCache {
65156
65268
  if (this.cache.has(key2)) {
65157
65269
  this.cache.delete(key2);
65158
65270
  }
65159
- if (this.cache.size >= MAX_CACHE_SIZE) {
65271
+ if (this.cache.size >= MAX_CACHE_SIZE$1) {
65160
65272
  const oldestKey = this.cache.keys().next().value;
65161
65273
  if (oldestKey !== void 0) {
65162
65274
  this.cache.delete(oldestKey);
@@ -65230,13 +65342,13 @@ class MeasureCache {
65230
65342
  * Get maximum cache size
65231
65343
  */
65232
65344
  getMaxSize() {
65233
- return MAX_CACHE_SIZE;
65345
+ return MAX_CACHE_SIZE$1;
65234
65346
  }
65235
65347
  /**
65236
65348
  * Check if cache is near capacity
65237
65349
  */
65238
65350
  isNearCapacity(threshold = 0.9) {
65239
- return this.cache.size >= MAX_CACHE_SIZE * threshold;
65351
+ return this.cache.size >= MAX_CACHE_SIZE$1 * threshold;
65240
65352
  }
65241
65353
  /**
65242
65354
  * Update size statistics
@@ -66248,9 +66360,46 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
66248
66360
  perfLog(
66249
66361
  `[Perf] 4.1 Measure all blocks: ${(measureEnd - measureStart).toFixed(2)}ms (${cacheMisses} measured, ${cacheHits} cached)`
66250
66362
  );
66363
+ let headerContentHeights;
66364
+ if (headerFooter?.constraints && headerFooter.headerBlocks) {
66365
+ const hfPreStart = performance.now();
66366
+ const measureFn = headerFooter.measure ?? measureBlock2;
66367
+ invalidateHeaderFooterCache(
66368
+ headerMeasureCache,
66369
+ headerFooterCacheState,
66370
+ headerFooter.headerBlocks,
66371
+ headerFooter.footerBlocks,
66372
+ headerFooter.constraints,
66373
+ options.sectionMetadata
66374
+ );
66375
+ const HEADER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT = 1;
66376
+ const preHeaderLayouts = await layoutHeaderFooterWithCache(
66377
+ headerFooter.headerBlocks,
66378
+ headerFooter.constraints,
66379
+ measureFn,
66380
+ headerMeasureCache,
66381
+ HEADER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT,
66382
+ void 0
66383
+ // No page resolver needed for height calculation
66384
+ );
66385
+ const isValidHeaderType = (key2) => {
66386
+ return ["default", "first", "even", "odd"].includes(key2);
66387
+ };
66388
+ headerContentHeights = {};
66389
+ for (const [type2, value] of Object.entries(preHeaderLayouts)) {
66390
+ if (!isValidHeaderType(type2)) continue;
66391
+ if (value?.layout && typeof value.layout.height === "number") {
66392
+ headerContentHeights[type2] = value.layout.height;
66393
+ }
66394
+ }
66395
+ const hfPreEnd = performance.now();
66396
+ perfLog(`[Perf] 4.1.5 Pre-layout headers for height: ${(hfPreEnd - hfPreStart).toFixed(2)}ms`);
66397
+ }
66251
66398
  const layoutStart = performance.now();
66252
66399
  let layout = layoutDocument(nextBlocks, measures, {
66253
66400
  ...options,
66401
+ headerContentHeights,
66402
+ // Pass header heights to prevent overlap
66254
66403
  remeasureParagraph: (block, maxWidth) => remeasureParagraph(block, maxWidth)
66255
66404
  });
66256
66405
  const layoutEnd = performance.now();
@@ -66297,6 +66446,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
66297
66446
  const relayoutStart = performance.now();
66298
66447
  layout = layoutDocument(currentBlocks, currentMeasures, {
66299
66448
  ...options,
66449
+ headerContentHeights,
66450
+ // Pass header heights to prevent overlap
66300
66451
  remeasureParagraph: (block, maxWidth) => remeasureParagraph(block, maxWidth)
66301
66452
  });
66302
66453
  const relayoutEnd = performance.now();
@@ -69346,7 +69497,12 @@ const lineStyles = (lineHeight2) => ({
69346
69497
  height: `${lineHeight2}px`,
69347
69498
  position: "relative",
69348
69499
  display: "block",
69349
- whiteSpace: "pre"
69500
+ whiteSpace: "pre",
69501
+ // Allow text to overflow the line container as a safety net.
69502
+ // The primary fix uses accurate font metrics from Canvas API, but this
69503
+ // provides defense-in-depth against any remaining sub-pixel rendering
69504
+ // differences between measurement and display.
69505
+ overflow: "visible"
69350
69506
  });
69351
69507
  const PRINT_STYLES = `
69352
69508
  @media print {
@@ -70912,7 +71068,8 @@ const _DomPainter = class _DomPainter2 {
70912
71068
  const paraIndent = block.attrs?.indent;
70913
71069
  const paraIndentLeft = paraIndent?.left ?? 0;
70914
71070
  const paraIndentRight = paraIndent?.right ?? 0;
70915
- const firstLineOffset = (paraIndent?.firstLine ?? 0) - (paraIndent?.hanging ?? 0);
71071
+ const suppressFirstLineIndent = block.attrs?.suppressFirstLineIndent === true;
71072
+ const firstLineOffset = suppressFirstLineIndent ? 0 : (paraIndent?.firstLine ?? 0) - (paraIndent?.hanging ?? 0);
70916
71073
  lines.forEach((line, index2) => {
70917
71074
  const lineEl = this.renderLine(block, line, context);
70918
71075
  const isListFirstLine = index2 === 0 && !fragment.continuesFromPrev && fragment.markerWidth && wordLayout?.marker;
@@ -72539,9 +72696,36 @@ const fragmentSignature = (fragment, lookup2) => {
72539
72696
  }
72540
72697
  return base2;
72541
72698
  };
72699
+ const hasListMarkerProperties = (attrs) => {
72700
+ if (!attrs || typeof attrs !== "object") return false;
72701
+ const obj = attrs;
72702
+ if (!obj.numberingProperties || typeof obj.numberingProperties !== "object") return false;
72703
+ const numProps = obj.numberingProperties;
72704
+ if ("numId" in numProps) {
72705
+ const numId = numProps.numId;
72706
+ if (typeof numId !== "number" && typeof numId !== "string") return false;
72707
+ }
72708
+ if ("ilvl" in numProps) {
72709
+ const ilvl = numProps.ilvl;
72710
+ if (typeof ilvl !== "number") return false;
72711
+ }
72712
+ if ("wordLayout" in obj && obj.wordLayout !== void 0) {
72713
+ if (typeof obj.wordLayout !== "object" || obj.wordLayout === null) return false;
72714
+ const wordLayout = obj.wordLayout;
72715
+ if ("marker" in wordLayout && wordLayout.marker !== void 0) {
72716
+ if (typeof wordLayout.marker !== "object" || wordLayout.marker === null) return false;
72717
+ const marker = wordLayout.marker;
72718
+ if ("markerText" in marker && marker.markerText !== void 0) {
72719
+ if (typeof marker.markerText !== "string") return false;
72720
+ }
72721
+ }
72722
+ }
72723
+ return true;
72724
+ };
72542
72725
  const deriveBlockVersion = (block) => {
72543
72726
  if (block.kind === "paragraph") {
72544
- return block.runs.map((run2) => {
72727
+ const markerVersion = hasListMarkerProperties(block.attrs) ? `marker:${block.attrs.numberingProperties.numId ?? ""}:${block.attrs.numberingProperties.ilvl ?? 0}:${block.attrs.wordLayout?.marker?.markerText ?? ""}` : "";
72728
+ const runsVersion = block.runs.map((run2) => {
72545
72729
  if (run2.kind === "image") {
72546
72730
  const imgRun = run2;
72547
72731
  return [
@@ -72584,6 +72768,7 @@ const deriveBlockVersion = (block) => {
72584
72768
  textRun.token ?? ""
72585
72769
  ].join(",");
72586
72770
  }).join("|");
72771
+ return markerVersion ? `${markerVersion}|${runsVersion}` : runsVersion;
72587
72772
  }
72588
72773
  if (block.kind === "list") {
72589
72774
  return block.items.map((item) => `${item.id}:${item.marker.text}:${deriveBlockVersion(item.paragraph)}`).join("|");
@@ -73073,6 +73258,61 @@ function evictIfNeeded() {
73073
73258
  cache$1.delete(oldestKey);
73074
73259
  }
73075
73260
  }
73261
+ const fontMetricsCache = /* @__PURE__ */ new Map();
73262
+ const MAX_CACHE_SIZE = 1e3;
73263
+ const METRICS_TEST_STRING = "MHgypbdlÁÉÍ";
73264
+ function getFontKey(fontInfo) {
73265
+ return `${fontInfo.fontFamily}|${fontInfo.fontSize}|${fontInfo.bold ?? false}|${fontInfo.italic ?? false}`;
73266
+ }
73267
+ function buildFontStringForMetrics(fontInfo, mode, fonts) {
73268
+ const parts = [];
73269
+ if (fontInfo.italic) parts.push("italic");
73270
+ if (fontInfo.bold) parts.push("bold");
73271
+ parts.push(`${fontInfo.fontSize}px`);
73272
+ {
73273
+ parts.push(fontInfo.fontFamily);
73274
+ }
73275
+ return parts.join(" ");
73276
+ }
73277
+ function getFontMetrics(ctx2, fontInfo, mode, fonts) {
73278
+ if (!ctx2 || typeof ctx2 !== "object") {
73279
+ throw new TypeError("Canvas context must be a valid CanvasRenderingContext2D object");
73280
+ }
73281
+ if (typeof fontInfo.fontSize !== "number" || !Number.isFinite(fontInfo.fontSize) || fontInfo.fontSize <= 0) {
73282
+ throw new TypeError(
73283
+ `Font size must be a positive finite number, got: ${typeof fontInfo.fontSize === "number" ? fontInfo.fontSize : typeof fontInfo.fontSize}`
73284
+ );
73285
+ }
73286
+ if (typeof fontInfo.fontFamily !== "string" || fontInfo.fontFamily.trim().length === 0) {
73287
+ throw new TypeError("Font family must be a non-empty string");
73288
+ }
73289
+ const key2 = getFontKey(fontInfo);
73290
+ const cached = fontMetricsCache.get(key2);
73291
+ if (cached) {
73292
+ return cached;
73293
+ }
73294
+ const font = buildFontStringForMetrics(fontInfo);
73295
+ ctx2.font = font;
73296
+ const textMetrics = ctx2.measureText(METRICS_TEST_STRING);
73297
+ let ascent;
73298
+ let descent;
73299
+ if (typeof textMetrics.actualBoundingBoxAscent === "number" && typeof textMetrics.actualBoundingBoxDescent === "number" && textMetrics.actualBoundingBoxAscent > 0) {
73300
+ ascent = textMetrics.actualBoundingBoxAscent;
73301
+ descent = textMetrics.actualBoundingBoxDescent;
73302
+ } else {
73303
+ ascent = fontInfo.fontSize * 0.8;
73304
+ descent = fontInfo.fontSize * 0.2;
73305
+ }
73306
+ const result = { ascent, descent };
73307
+ if (fontMetricsCache.size >= MAX_CACHE_SIZE) {
73308
+ const firstKey = fontMetricsCache.keys().next().value;
73309
+ if (firstKey) {
73310
+ fontMetricsCache.delete(firstKey);
73311
+ }
73312
+ }
73313
+ fontMetricsCache.set(key2, result);
73314
+ return result;
73315
+ }
73076
73316
  const { computeTabStops } = Engines;
73077
73317
  let canvasContext = null;
73078
73318
  const DEFAULT_TAB_INTERVAL_TWIPS = 720;
@@ -73120,10 +73360,20 @@ function measureText(text, font, ctx2, _fontFamily, _letterSpacing) {
73120
73360
  return Math.max(advanceWidth, paintedWidth);
73121
73361
  }
73122
73362
  const MIN_SINGLE_LINE_PX = 12 * 96 / 72;
73123
- function calculateTypographyMetrics(fontSize2, spacing) {
73124
- const ascent = roundValue(fontSize2 * 0.8);
73125
- const descent = roundValue(fontSize2 * 0.2);
73126
- const baseLineHeight = Math.max(fontSize2, MIN_SINGLE_LINE_PX);
73363
+ const LINE_HEIGHT_SAFETY_MARGIN_PX = 1;
73364
+ function calculateTypographyMetrics(fontSize2, spacing, fontInfo) {
73365
+ let ascent;
73366
+ let descent;
73367
+ if (fontInfo) {
73368
+ const ctx2 = getCanvasContext();
73369
+ const metrics = getFontMetrics(ctx2, fontInfo);
73370
+ ascent = roundValue(metrics.ascent);
73371
+ descent = roundValue(metrics.descent);
73372
+ } else {
73373
+ ascent = roundValue(fontSize2 * 0.8);
73374
+ descent = roundValue(fontSize2 * 0.2);
73375
+ }
73376
+ const baseLineHeight = Math.max(ascent + descent + LINE_HEIGHT_SAFETY_MARGIN_PX, MIN_SINGLE_LINE_PX);
73127
73377
  const lineHeight2 = roundValue(resolveLineHeight(spacing, baseLineHeight));
73128
73378
  return {
73129
73379
  ascent,
@@ -73131,6 +73381,20 @@ function calculateTypographyMetrics(fontSize2, spacing) {
73131
73381
  lineHeight: lineHeight2
73132
73382
  };
73133
73383
  }
73384
+ function getFontInfoFromRun(run2) {
73385
+ return {
73386
+ fontFamily: run2.fontFamily,
73387
+ fontSize: run2.fontSize,
73388
+ bold: run2.bold,
73389
+ italic: run2.italic
73390
+ };
73391
+ }
73392
+ function updateMaxFontInfo(currentMaxSize, currentMaxInfo, newRun) {
73393
+ if (newRun.fontSize >= currentMaxSize) {
73394
+ return getFontInfoFromRun(newRun);
73395
+ }
73396
+ return currentMaxInfo;
73397
+ }
73134
73398
  function isTabRun(run2) {
73135
73399
  return run2.kind === "tab";
73136
73400
  }
@@ -73176,7 +73440,8 @@ async function measureParagraphBlock(block, maxWidth) {
73176
73440
  const indentRight = sanitizePositive(indent?.right);
73177
73441
  const firstLine = indent?.firstLine ?? 0;
73178
73442
  const hanging = indent?.hanging ?? 0;
73179
- const firstLineOffset = firstLine - hanging;
73443
+ const suppressFirstLine = block.attrs?.suppressFirstLineIndent === true;
73444
+ const firstLineOffset = suppressFirstLine ? 0 : firstLine - hanging;
73180
73445
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
73181
73446
  const initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset);
73182
73447
  const tabStops = buildTabStopsPx(
@@ -73312,7 +73577,7 @@ async function measureParagraphBlock(block, maxWidth) {
73312
73577
  const run2 = runsToProcess[runIndex];
73313
73578
  if (run2.kind === "break") {
73314
73579
  if (currentLine) {
73315
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
73580
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
73316
73581
  const completedLine = { ...currentLine, ...metrics };
73317
73582
  addBarTabsToLine(completedLine);
73318
73583
  lines.push(completedLine);
@@ -73342,7 +73607,7 @@ async function measureParagraphBlock(block, maxWidth) {
73342
73607
  }
73343
73608
  if (isLineBreakRun(run2)) {
73344
73609
  if (currentLine) {
73345
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
73610
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
73346
73611
  const completedLine = {
73347
73612
  ...currentLine,
73348
73613
  ...metrics
@@ -73455,7 +73720,7 @@ async function measureParagraphBlock(block, maxWidth) {
73455
73720
  }
73456
73721
  const appliedTabAlign = lastAppliedTabAlign;
73457
73722
  if (currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
73458
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
73723
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
73459
73724
  const completedLine = {
73460
73725
  ...currentLine,
73461
73726
  ...metrics
@@ -73543,6 +73808,7 @@ async function measureParagraphBlock(block, maxWidth) {
73543
73808
  toChar: wordEndNoSpace,
73544
73809
  width: wordOnlyWidth,
73545
73810
  maxFontSize: run2.fontSize,
73811
+ maxFontInfo: getFontInfoFromRun(run2),
73546
73812
  maxWidth: getEffectiveWidth(initialAvailableWidth),
73547
73813
  segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }]
73548
73814
  };
@@ -73559,7 +73825,7 @@ async function measureParagraphBlock(block, maxWidth) {
73559
73825
  const isTocEntry = block.attrs?.isTocEntry;
73560
73826
  const boundarySpacing = currentLine.width > 0 ? run2.letterSpacing ?? 0 : 0;
73561
73827
  if (currentLine.width + boundarySpacing + wordOnlyWidth > currentLine.maxWidth - WIDTH_FUDGE_PX && currentLine.width > 0 && !isTocEntry) {
73562
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
73828
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
73563
73829
  const completedLine = {
73564
73830
  ...currentLine,
73565
73831
  ...metrics
@@ -73575,6 +73841,7 @@ async function measureParagraphBlock(block, maxWidth) {
73575
73841
  toChar: wordEndNoSpace,
73576
73842
  width: wordOnlyWidth,
73577
73843
  maxFontSize: run2.fontSize,
73844
+ maxFontInfo: getFontInfoFromRun(run2),
73578
73845
  maxWidth: getEffectiveWidth(contentWidth),
73579
73846
  segments: [{ runIndex, fromChar: wordStartChar, toChar: wordEndNoSpace, width: wordOnlyWidth }]
73580
73847
  };
@@ -73590,9 +73857,10 @@ async function measureParagraphBlock(block, maxWidth) {
73590
73857
  if (!isLastWord && currentLine.width + boundarySpacing + wordOnlyWidth + spaceWidth > currentLine.maxWidth - WIDTH_FUDGE_PX) {
73591
73858
  currentLine.toChar = wordEndNoSpace;
73592
73859
  currentLine.width = roundValue(currentLine.width + boundarySpacing + wordOnlyWidth);
73860
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
73593
73861
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
73594
73862
  appendSegment(currentLine.segments, runIndex, wordStartChar, wordEndNoSpace, wordOnlyWidth, segmentStartX);
73595
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
73863
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
73596
73864
  const completedLine = { ...currentLine, ...metrics };
73597
73865
  addBarTabsToLine(completedLine);
73598
73866
  lines.push(completedLine);
@@ -73609,6 +73877,7 @@ async function measureParagraphBlock(block, maxWidth) {
73609
73877
  currentLine.width = roundValue(
73610
73878
  currentLine.width + boundarySpacing + wordCommitWidth + (isLastWord ? 0 : run2.letterSpacing ?? 0)
73611
73879
  );
73880
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
73612
73881
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
73613
73882
  appendSegment(currentLine.segments, runIndex, wordStartChar, newToChar, wordCommitWidth, explicitX);
73614
73883
  }
@@ -73631,6 +73900,7 @@ async function measureParagraphBlock(block, maxWidth) {
73631
73900
  toChar: charPosInRun,
73632
73901
  width: 0,
73633
73902
  maxFontSize: run2.fontSize,
73903
+ maxFontInfo: getFontInfoFromRun(run2),
73634
73904
  maxWidth: getEffectiveWidth(initialAvailableWidth),
73635
73905
  segments: []
73636
73906
  };
@@ -73640,6 +73910,7 @@ async function measureParagraphBlock(block, maxWidth) {
73640
73910
  tabStopCursor = nextIndex;
73641
73911
  const tabAdvance = Math.max(0, target - currentLine.width);
73642
73912
  currentLine.width = roundValue(currentLine.width + tabAdvance);
73913
+ currentLine.maxFontInfo = updateMaxFontInfo(currentLine.maxFontSize, currentLine.maxFontInfo, run2);
73643
73914
  currentLine.maxFontSize = Math.max(currentLine.maxFontSize, run2.fontSize);
73644
73915
  currentLine.toRun = runIndex;
73645
73916
  currentLine.toChar = charPosInRun;
@@ -73676,7 +73947,7 @@ async function measureParagraphBlock(block, maxWidth) {
73676
73947
  lines.push(fallbackLine);
73677
73948
  }
73678
73949
  if (currentLine) {
73679
- const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
73950
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
73680
73951
  const finalLine = {
73681
73952
  ...currentLine,
73682
73953
  ...metrics
@@ -77087,7 +77358,12 @@ setupPointerHandlers_fn = function() {
77087
77358
  setupInputBridge_fn = function() {
77088
77359
  __privateGet$1(this, _inputBridge)?.destroy();
77089
77360
  const win = __privateGet$1(this, _visibleHost).ownerDocument?.defaultView ?? window;
77090
- __privateSet(this, _inputBridge, new PresentationInputBridge(win, __privateGet$1(this, _visibleHost), () => __privateMethod$1(this, _PresentationEditor_instances, getActiveDomTarget_fn).call(this)));
77361
+ __privateSet(this, _inputBridge, new PresentationInputBridge(
77362
+ win,
77363
+ __privateGet$1(this, _visibleHost),
77364
+ () => __privateMethod$1(this, _PresentationEditor_instances, getActiveDomTarget_fn).call(this),
77365
+ () => __privateGet$1(this, _documentMode) !== "viewing"
77366
+ ));
77091
77367
  __privateGet$1(this, _inputBridge).bind();
77092
77368
  };
77093
77369
  initHeaderFooterRegistry_fn = function() {
@@ -77475,6 +77751,10 @@ updateSelection_fn = function() {
77475
77751
  if (!__privateGet$1(this, _localSelectionLayer)) {
77476
77752
  return;
77477
77753
  }
77754
+ if (__privateGet$1(this, _documentMode) === "viewing") {
77755
+ __privateGet$1(this, _localSelectionLayer).innerHTML = "";
77756
+ return;
77757
+ }
77478
77758
  const layout = __privateGet$1(this, _layoutState).layout;
77479
77759
  const selection = this.getActiveEditor().state?.selection;
77480
77760
  __privateGet$1(this, _localSelectionLayer).innerHTML = "";
@@ -78780,11 +79060,27 @@ _PresentationEditor.CURSOR_STYLES = {
78780
79060
  };
78781
79061
  let PresentationEditor = _PresentationEditor;
78782
79062
  class PresentationInputBridge {
78783
- constructor(windowRoot, layoutSurface, getTargetDom, onTargetChanged, options) {
79063
+ /**
79064
+ * Creates a new PresentationInputBridge that forwards user input events from the visible layout
79065
+ * surface to the hidden editor DOM. This enables input handling when the actual editor is not
79066
+ * directly visible to the user.
79067
+ *
79068
+ * @param windowRoot - The window object containing the layout surface and editor target
79069
+ * @param layoutSurface - The visible HTML element that receives user input events (e.g., keyboard, mouse)
79070
+ * @param getTargetDom - Callback that returns the hidden editor's DOM element where events should be forwarded
79071
+ * @param isEditable - Callback that returns whether the editor is in an editable mode (editing/suggesting).
79072
+ * When this returns false (e.g., in viewing mode), keyboard, text, and composition
79073
+ * events will not be forwarded to prevent document modification.
79074
+ * @param onTargetChanged - Optional callback invoked when the target editor DOM element changes
79075
+ * @param options - Optional configuration including:
79076
+ * - useWindowFallback: Whether to attach window-level event listeners as fallback
79077
+ */
79078
+ constructor(windowRoot, layoutSurface, getTargetDom, isEditable, onTargetChanged, options) {
78784
79079
  __privateAdd$1(this, _PresentationInputBridge_instances);
78785
79080
  __privateAdd$1(this, _windowRoot);
78786
79081
  __privateAdd$1(this, _layoutSurfaces);
78787
79082
  __privateAdd$1(this, _getTargetDom);
79083
+ __privateAdd$1(this, _isEditable);
78788
79084
  __privateAdd$1(this, _onTargetChanged);
78789
79085
  __privateAdd$1(this, _listeners);
78790
79086
  __privateAdd$1(this, _currentTarget, null);
@@ -78793,6 +79089,7 @@ class PresentationInputBridge {
78793
79089
  __privateSet(this, _windowRoot, windowRoot);
78794
79090
  __privateSet(this, _layoutSurfaces, /* @__PURE__ */ new Set([layoutSurface]));
78795
79091
  __privateSet(this, _getTargetDom, getTargetDom);
79092
+ __privateSet(this, _isEditable, isEditable);
78796
79093
  __privateSet(this, _onTargetChanged, onTargetChanged);
78797
79094
  __privateSet(this, _listeners, []);
78798
79095
  __privateSet(this, _useWindowFallback, options?.useWindowFallback ?? false);
@@ -78859,6 +79156,7 @@ class PresentationInputBridge {
78859
79156
  _windowRoot = /* @__PURE__ */ new WeakMap();
78860
79157
  _layoutSurfaces = /* @__PURE__ */ new WeakMap();
78861
79158
  _getTargetDom = /* @__PURE__ */ new WeakMap();
79159
+ _isEditable = /* @__PURE__ */ new WeakMap();
78862
79160
  _onTargetChanged = /* @__PURE__ */ new WeakMap();
78863
79161
  _listeners = /* @__PURE__ */ new WeakMap();
78864
79162
  _currentTarget = /* @__PURE__ */ new WeakMap();
@@ -78889,6 +79187,9 @@ dispatchToTarget_fn = function(originalEvent, synthetic) {
78889
79187
  }
78890
79188
  };
78891
79189
  forwardKeyboardEvent_fn = function(event) {
79190
+ if (!__privateGet$1(this, _isEditable).call(this)) {
79191
+ return;
79192
+ }
78892
79193
  if (__privateMethod$1(this, _PresentationInputBridge_instances, shouldSkipSurface_fn).call(this, event)) {
78893
79194
  return;
78894
79195
  }
@@ -78916,6 +79217,9 @@ forwardKeyboardEvent_fn = function(event) {
78916
79217
  __privateMethod$1(this, _PresentationInputBridge_instances, dispatchToTarget_fn).call(this, event, synthetic);
78917
79218
  };
78918
79219
  forwardTextEvent_fn = function(event) {
79220
+ if (!__privateGet$1(this, _isEditable).call(this)) {
79221
+ return;
79222
+ }
78919
79223
  if (__privateMethod$1(this, _PresentationInputBridge_instances, shouldSkipSurface_fn).call(this, event)) {
78920
79224
  return;
78921
79225
  }
@@ -78946,6 +79250,9 @@ forwardTextEvent_fn = function(event) {
78946
79250
  });
78947
79251
  };
78948
79252
  forwardCompositionEvent_fn = function(event) {
79253
+ if (!__privateGet$1(this, _isEditable).call(this)) {
79254
+ return;
79255
+ }
78949
79256
  if (__privateMethod$1(this, _PresentationInputBridge_instances, shouldSkipSurface_fn).call(this, event)) {
78950
79257
  return;
78951
79258
  }
@@ -78965,6 +79272,9 @@ forwardCompositionEvent_fn = function(event) {
78965
79272
  __privateMethod$1(this, _PresentationInputBridge_instances, dispatchToTarget_fn).call(this, event, synthetic);
78966
79273
  };
78967
79274
  forwardContextMenu_fn = function(event) {
79275
+ if (!__privateGet$1(this, _isEditable).call(this)) {
79276
+ return;
79277
+ }
78968
79278
  if (__privateMethod$1(this, _PresentationInputBridge_instances, shouldSkipSurface_fn).call(this, event)) {
78969
79279
  return;
78970
79280
  }