superdoc 1.0.0-beta.2 → 1.0.0-beta.3

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 (34) hide show
  1. package/dist/chunks/{PdfViewer-saAhozRR.es.js → PdfViewer-CKzs9Ct5.es.js} +2 -2
  2. package/dist/chunks/{PdfViewer-CeuX3gOe.cjs → PdfViewer-CxHbcDGx.cjs} +1 -1
  3. package/dist/chunks/{eventemitter3-BZXKb7j7.es.js → eventemitter3-ByBH0NYV.es.js} +1 -1
  4. package/dist/chunks/{index-Sn-JVHIg-BxOp3gSx.cjs → index-CJUy3fVi-BGLfCP5B.cjs} +1 -1
  5. package/dist/chunks/{index-Sn-JVHIg-BCItIT88.es.js → index-CJUy3fVi-D8zt9F3Z.es.js} +1 -1
  6. package/dist/chunks/{index-Dh5oVJua.cjs → index-Dp3rVMnX.cjs} +3 -3
  7. package/dist/chunks/{index-C0OeGje6.es.js → index-DukSDI8_.es.js} +6 -6
  8. package/dist/chunks/{jszip-Duxs2YMV.es.js → jszip-BwsONqK5.es.js} +1 -1
  9. package/dist/chunks/{super-editor.es-Dcz39nKY.es.js → super-editor.es-BRKZG90h.es.js} +593 -200
  10. package/dist/chunks/{super-editor.es-BKljkYUU.cjs → super-editor.es-CDiTp9Fe.cjs} +592 -199
  11. package/dist/chunks/{vue-B5QAf5pA.es.js → vue-CztqUvm1.es.js} +17 -17
  12. package/dist/chunks/xml-js-BZPSMmVo.es.js +2 -0
  13. package/dist/packages/superdoc/src/core/SuperDoc.d.ts +35 -2
  14. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  15. package/dist/super-editor/ai-writer.es.js +2 -2
  16. package/dist/super-editor/chunks/{converter-BFGB7hqj.js → converter-B9YfBdcc.js} +1 -1
  17. package/dist/super-editor/chunks/{docx-zipper-OPbzIk16.js → docx-zipper-V16OzZ7a.js} +1 -1
  18. package/dist/super-editor/chunks/{editor-CtI4XnMw.js → editor-DlvlVSbc.js} +409 -165
  19. package/dist/super-editor/chunks/{index-Sn-JVHIg.js → index-CJUy3fVi.js} +1 -1
  20. package/dist/super-editor/chunks/{toolbar-BydALv4o.js → toolbar-cNDvtryE.js} +2 -2
  21. package/dist/super-editor/converter.es.js +1 -1
  22. package/dist/super-editor/docx-zipper.es.js +2 -2
  23. package/dist/super-editor/editor.es.js +3 -3
  24. package/dist/super-editor/file-zipper.es.js +1 -1
  25. package/dist/super-editor/super-editor.es.js +217 -41
  26. package/dist/super-editor/toolbar.es.js +2 -2
  27. package/dist/super-editor.cjs +1 -1
  28. package/dist/super-editor.es.js +2 -2
  29. package/dist/superdoc.cjs +2 -2
  30. package/dist/superdoc.es.js +2 -2
  31. package/dist/superdoc.umd.js +594 -201
  32. package/dist/superdoc.umd.js.map +1 -1
  33. package/package.json +1 -1
  34. package/dist/chunks/xml-js-CVyfrKaV.es.js +0 -2
@@ -1,4 +1,4 @@
1
- import { g as global$2, r as ref$1, c as createApp, a as computed, b as createElementBlock, o as openBlock, F as Fragment$1, d as renderList, n as normalizeClass, w as withModifiers, e as createCommentVNode, t as toDisplayString, f as createBaseVNode, i as inject, h as onBeforeMount, j as onMounted, k as onBeforeUnmount, l as watch, m as defineComponent, p as getCurrentInstance, q as onDeactivated, s as nextTick, u as createBlock, v as createVNode, x as unref, y as h, z as mergeProps, A as shallowRef, B as withCtx, C as createTextVNode, D as normalizeStyle, E as toRef, G as provide, H as cloneVNode, T as Text$2, I as withDirectives, J as watchEffect, K as vModelText, L as withKeys, M as reactive, N as readonly, O as Transition, P as vShow, Q as Comment, R as renderSlot, S as onActivated, U as Teleport, V as isVNode, W as onUnmounted, X as resolveDynamicComponent, Y as normalizeProps, Z as guardReactiveProps, _ as markRaw } from "./vue-B5QAf5pA.es.js";
1
+ import { g as global$2, r as ref$1, c as createApp, a as computed, b as createElementBlock, o as openBlock, F as Fragment$1, d as renderList, n as normalizeClass, w as withModifiers, e as createCommentVNode, t as toDisplayString, f as createBaseVNode, i as inject, h as onBeforeMount, j as onMounted, k as onBeforeUnmount, l as watch, m as getCurrentInstance, p as onDeactivated, q as nextTick, s as createBlock, u as createVNode, v as unref, x as normalizeStyle, y as defineComponent, z as h, A as mergeProps, B as shallowRef, C as withCtx, D as createTextVNode, E as toRef, G as provide, H as cloneVNode, T as Text$2, I as withDirectives, J as watchEffect, K as vModelText, L as withKeys, M as reactive, N as readonly, O as Transition, P as vShow, Q as Comment, R as renderSlot, S as onActivated, U as Teleport, V as isVNode, W as onUnmounted, X as markRaw, Y as resolveDynamicComponent, Z as normalizeProps, _ as guardReactiveProps } from "./vue-CztqUvm1.es.js";
2
2
  import * as Y from "yjs";
3
3
  import { UndoManager, Item as Item$2, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
4
4
  var __defProp$2 = Object.defineProperty;
@@ -35563,7 +35563,7 @@ const _SuperConverter = class _SuperConverter2 {
35563
35563
  static getStoredSuperdocVersion(docx) {
35564
35564
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
35565
35565
  }
35566
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.2") {
35566
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.3") {
35567
35567
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
35568
35568
  }
35569
35569
  /**
@@ -38763,7 +38763,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
38763
38763
  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);
38764
38764
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
38765
38765
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
38766
- 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, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay, _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, _headerLayoutResults, _footerLayoutResults, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _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, updateDecorationProviders_fn, createDecorationProvider_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, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, computeHeaderFooterCaretRect_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, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _visibleHost2, _getTargetDom, _onTargetChanged, _listeners, _currentTarget, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, updateHTMLAttributes_fn, updateDOMStyles_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;
38766
+ 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, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay, _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, _headerLayoutResults, _footerLayoutResults, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _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, updateDecorationProviders_fn, createDecorationProvider_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, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, computeHeaderFooterCaretRect_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, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _visibleHost2, _getTargetDom, _onTargetChanged, _listeners, _currentTarget, _destroyed, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, updateHTMLAttributes_fn, updateDOMStyles_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;
38767
38767
  var GOOD_LEAF_SIZE = 200;
38768
38768
  var RopeSequence = function RopeSequence2() {
38769
38769
  };
@@ -52270,7 +52270,7 @@ const isHeadless = (editor) => {
52270
52270
  const shouldSkipNodeView = (editor) => {
52271
52271
  return isHeadless(editor);
52272
52272
  };
52273
- const summaryVersion = "1.0.0-beta.2";
52273
+ const summaryVersion = "1.0.0-beta.3";
52274
52274
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
52275
52275
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
52276
52276
  function mapAttributes(attrs) {
@@ -53049,7 +53049,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53049
53049
  { default: remarkStringify },
53050
53050
  { default: remarkGfm }
53051
53051
  ] = await Promise.all([
53052
- import("./index-Sn-JVHIg-BCItIT88.es.js"),
53052
+ import("./index-CJUy3fVi-D8zt9F3Z.es.js"),
53053
53053
  import("./index-DRCvimau-Cw339678.es.js"),
53054
53054
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
53055
53055
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -53254,7 +53254,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53254
53254
  * Process collaboration migrations
53255
53255
  */
53256
53256
  processCollaborationMigrations() {
53257
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.2");
53257
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.3");
53258
53258
  if (!this.options.ydoc) return;
53259
53259
  const metaMap = this.options.ydoc.getMap("meta");
53260
53260
  let docVersion = metaMap.get("version");
@@ -54873,6 +54873,50 @@ const resolveColorFromAttributes = (attrs, themeColors) => {
54873
54873
  }
54874
54874
  return void 0;
54875
54875
  };
54876
+ const MAX_DATA_ATTR_COUNT = 50;
54877
+ const MAX_DATA_ATTR_VALUE_LENGTH = 1e3;
54878
+ const MAX_DATA_ATTR_NAME_LENGTH = 100;
54879
+ const extractDataAttributes = (attrs) => {
54880
+ if (!attrs) return void 0;
54881
+ const result = {};
54882
+ let attrCount = 0;
54883
+ for (const [key2, value] of Object.entries(attrs)) {
54884
+ if (typeof key2 !== "string" || !key2.toLowerCase().startsWith("data-")) {
54885
+ continue;
54886
+ }
54887
+ if (attrCount >= MAX_DATA_ATTR_COUNT) {
54888
+ if (process$1$1.env.NODE_ENV === "development") {
54889
+ console.warn(`[PM-Adapter] Rejecting data attributes exceeding ${MAX_DATA_ATTR_COUNT} limit`);
54890
+ }
54891
+ break;
54892
+ }
54893
+ if (key2.length > MAX_DATA_ATTR_NAME_LENGTH) {
54894
+ if (process$1$1.env.NODE_ENV === "development") {
54895
+ console.warn(
54896
+ `[PM-Adapter] Rejecting data attribute name exceeding ${MAX_DATA_ATTR_NAME_LENGTH} chars: ${key2.substring(0, 50)}...`
54897
+ );
54898
+ }
54899
+ continue;
54900
+ }
54901
+ if (value == null) {
54902
+ continue;
54903
+ }
54904
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
54905
+ const stringValue = String(value);
54906
+ if (stringValue.length > MAX_DATA_ATTR_VALUE_LENGTH) {
54907
+ if (process$1$1.env.NODE_ENV === "development") {
54908
+ console.warn(
54909
+ `[PM-Adapter] Rejecting data attribute value exceeding ${MAX_DATA_ATTR_VALUE_LENGTH} chars for key: ${key2}`
54910
+ );
54911
+ }
54912
+ continue;
54913
+ }
54914
+ result[key2] = stringValue;
54915
+ attrCount++;
54916
+ }
54917
+ }
54918
+ return Object.keys(result).length > 0 ? result : void 0;
54919
+ };
54876
54920
  const normalizeRunMarkList = (value) => {
54877
54921
  if (!value) return void 0;
54878
54922
  let entries = value;
@@ -55052,11 +55096,9 @@ const applyTextStyleMark = (run2, attrs, themeColors) => {
55052
55096
  run2.fontFamily = sanitized;
55053
55097
  }
55054
55098
  }
55055
- if (isFiniteNumber(attrs.fontSize)) {
55056
- const size2 = Number(attrs.fontSize);
55057
- if (size2 >= 1 && size2 <= 1e3) {
55058
- run2.fontSize = size2;
55059
- }
55099
+ const fontSizeValue = pickNumber(attrs.fontSize);
55100
+ if (fontSizeValue !== void 0 && fontSizeValue >= 1 && fontSizeValue <= 1e3) {
55101
+ run2.fontSize = fontSizeValue;
55060
55102
  }
55061
55103
  if (isFiniteNumber(attrs.letterSpacing)) {
55062
55104
  const spacing = Number(attrs.letterSpacing);
@@ -55070,6 +55112,7 @@ const DEFAULT_HYPERLINK_CONFIG = {
55070
55112
  };
55071
55113
  const applyMarksToRun = (run2, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors) => {
55072
55114
  marks.forEach((mark) => {
55115
+ const forwardedDataAttrs = extractDataAttributes(mark.attrs);
55073
55116
  try {
55074
55117
  switch (mark.type) {
55075
55118
  case TRACK_INSERT_MARK:
@@ -55164,6 +55207,9 @@ const applyMarksToRun = (run2, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG
55164
55207
  console.warn(`[PM-Adapter] Failed to apply mark ${mark.type}:`, error);
55165
55208
  }
55166
55209
  }
55210
+ if (forwardedDataAttrs) {
55211
+ run2.dataAttrs = { ...run2.dataAttrs ?? {}, ...forwardedDataAttrs };
55212
+ }
55167
55213
  });
55168
55214
  };
55169
55215
  function textNodeToRun(textNode, positions, defaultFont, defaultSize, inheritedMarks = [], sdtMetadata, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors) {
@@ -55187,8 +55233,9 @@ function tabNodeToRun(node, positions, tabIndex, paragraph) {
55187
55233
  const pos = positions.get(node);
55188
55234
  if (!pos) return null;
55189
55235
  const paragraphAttrs = paragraph.attrs ?? {};
55190
- const tabStops = Array.isArray(paragraphAttrs.tabStops) ? paragraphAttrs.tabStops : void 0;
55191
- const indent = paragraphAttrs.indent;
55236
+ const paragraphProps = typeof paragraphAttrs.paragraphProperties === "object" && paragraphAttrs.paragraphProperties !== null ? paragraphAttrs.paragraphProperties : {};
55237
+ const tabStops = Array.isArray(paragraphAttrs.tabStops) && paragraphAttrs.tabStops.length ? paragraphAttrs.tabStops : Array.isArray(paragraphProps.tabStops) ? paragraphProps.tabStops : void 0;
55238
+ const indent = paragraphAttrs.indent ?? paragraphProps.indent ?? void 0;
55192
55239
  return {
55193
55240
  kind: "tab",
55194
55241
  text: " ",
@@ -55502,6 +55549,9 @@ const normalizeParagraphSpacing = (value) => {
55502
55549
  const afterRaw = pickNumber(source.after);
55503
55550
  const lineRaw = pickNumber(source.line);
55504
55551
  const lineRule = normalizeLineRule(source.lineRule);
55552
+ const beforeAutospacing = toBooleanFlag(source.beforeAutospacing ?? source.beforeAutoSpacing);
55553
+ const afterAutospacing = toBooleanFlag(source.afterAutospacing ?? source.afterAutoSpacing);
55554
+ const contextualSpacing = toBooleanFlag(source.contextualSpacing);
55505
55555
  const before = beforeRaw != null ? twipsToPx$1(beforeRaw) : pickNumber(source.lineSpaceBefore);
55506
55556
  const after = afterRaw != null ? twipsToPx$1(afterRaw) : pickNumber(source.lineSpaceAfter);
55507
55557
  const line = normalizeLineValue(lineRaw, lineRule);
@@ -55509,8 +55559,24 @@ const normalizeParagraphSpacing = (value) => {
55509
55559
  if (after != null) spacing.after = after;
55510
55560
  if (line != null) spacing.line = line;
55511
55561
  if (lineRule) spacing.lineRule = lineRule;
55562
+ if (beforeAutospacing != null) spacing.beforeAutospacing = beforeAutospacing;
55563
+ if (afterAutospacing != null) spacing.afterAutospacing = afterAutospacing;
55564
+ if (contextualSpacing != null) spacing.contextualSpacing = contextualSpacing;
55512
55565
  return Object.keys(spacing).length > 0 ? spacing : void 0;
55513
55566
  };
55567
+ const toBooleanFlag = (value) => {
55568
+ if (value === true || value === false) return value;
55569
+ if (typeof value === "string") {
55570
+ const normalized = value.trim().toLowerCase();
55571
+ if (["true", "1", "on", "yes"].includes(normalized)) return true;
55572
+ if (["false", "0", "off", "no"].includes(normalized)) return false;
55573
+ }
55574
+ if (typeof value === "number") {
55575
+ if (value === 1) return true;
55576
+ if (value === 0) return false;
55577
+ }
55578
+ return void 0;
55579
+ };
55514
55580
  const normalizeLineValue = (value, lineRule) => {
55515
55581
  if (value == null) return void 0;
55516
55582
  if (lineRule === "auto") {
@@ -56883,15 +56949,17 @@ const hydrateParagraphStyleAttrs = (para, context, preResolved) => {
56883
56949
  return null;
56884
56950
  }
56885
56951
  const attrs = para.attrs ?? {};
56886
- const styleId = typeof attrs.styleId === "string" && attrs.styleId.trim() ? attrs.styleId : null;
56952
+ const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
56953
+ const styleIdSource = attrs.styleId ?? paragraphProps.styleId;
56954
+ const styleId = typeof styleIdSource === "string" && styleIdSource.trim() ? styleIdSource : null;
56887
56955
  if (!styleId) {
56888
56956
  return null;
56889
56957
  }
56890
56958
  const inlineProps = {
56891
56959
  styleId,
56892
- numberingProperties: cloneIfObject(attrs.numberingProperties),
56893
- indent: cloneIfObject(attrs.indent),
56894
- spacing: cloneIfObject(attrs.spacing)
56960
+ numberingProperties: cloneIfObject(attrs.numberingProperties ?? paragraphProps.numberingProperties),
56961
+ indent: cloneIfObject(attrs.indent ?? paragraphProps.indent),
56962
+ spacing: cloneIfObject(attrs.spacing ?? paragraphProps.spacing)
56895
56963
  };
56896
56964
  const resolverParams = {
56897
56965
  docx: context.docx,
@@ -57169,13 +57237,17 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
57169
57237
  };
57170
57238
  const computeParagraphAttrs = (para, styleContext, listCounterContext, converterContext, hydrationOverride) => {
57171
57239
  const attrs = para.attrs ?? {};
57240
+ const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
57172
57241
  const hydrated = hydrationOverride ?? hydrateParagraphStyleAttrs(para, converterContext);
57173
- const spacingSource = attrs.spacing !== void 0 ? attrs.spacing : hydrated?.spacing;
57242
+ const spacingSource = attrs.spacing !== void 0 ? attrs.spacing : paragraphProps.spacing !== void 0 ? paragraphProps.spacing : hydrated?.spacing;
57174
57243
  const normalizedSpacing = normalizeParagraphSpacing(spacingSource);
57175
- const indentSource = attrs.indent ?? hydrated?.indent;
57244
+ const indentSource = attrs.indent ?? paragraphProps.indent ?? hydrated?.indent;
57176
57245
  const normalizedIndent = normalizePxIndent(indentSource) ?? normalizeParagraphIndent(indentSource ?? attrs.textIndent);
57177
- const styleNodeAttrs = hydrated?.tabStops && !attrs.tabStops && !attrs.tabs ? { ...attrs, tabStops: hydrated.tabStops } : attrs;
57246
+ const styleNodeAttrs = hydrated?.tabStops && !attrs.tabStops && !attrs.tabs ? { ...attrs, tabStops: hydrated.tabStops } : !attrs.tabStops && paragraphProps.tabStops ? { ...attrs, tabStops: paragraphProps.tabStops } : attrs;
57178
57247
  const styleNode = buildStyleNodeFromAttrs(styleNodeAttrs, normalizedSpacing, normalizedIndent);
57248
+ if (styleNodeAttrs.styleId == null && paragraphProps.styleId) {
57249
+ styleNode.styleId = paragraphProps.styleId;
57250
+ }
57179
57251
  const computed2 = resolveStyle(styleNode, styleContext);
57180
57252
  const { spacing, indent } = resolveSpacingIndent(computed2.paragraph, computed2.numbering);
57181
57253
  const paragraphAttrs = {};
@@ -57200,6 +57272,18 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
57200
57272
  }
57201
57273
  const spacingPx = spacingPtToPx(spacing, normalizedSpacing);
57202
57274
  if (spacingPx) paragraphAttrs.spacing = spacingPx;
57275
+ if (normalizedSpacing?.beforeAutospacing != null || normalizedSpacing?.afterAutospacing != null) {
57276
+ paragraphAttrs.spacing = paragraphAttrs.spacing ?? {};
57277
+ if (normalizedSpacing?.beforeAutospacing != null) {
57278
+ paragraphAttrs.spacing.beforeAutospacing = normalizedSpacing.beforeAutospacing;
57279
+ }
57280
+ if (normalizedSpacing?.afterAutospacing != null) {
57281
+ paragraphAttrs.spacing.afterAutospacing = normalizedSpacing.afterAutospacing;
57282
+ }
57283
+ }
57284
+ if (normalizedSpacing?.contextualSpacing != null) {
57285
+ paragraphAttrs.contextualSpacing = normalizedSpacing.contextualSpacing;
57286
+ }
57203
57287
  const hasExplicitIndent = Boolean(normalizedIndent);
57204
57288
  const hasNumberingIndent = Boolean(computed2.numbering?.indent?.left || computed2.numbering?.indent?.hanging);
57205
57289
  if (hasExplicitIndent || hasNumberingIndent || bidi && adjustRightInd) {
@@ -57218,10 +57302,20 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
57218
57302
  if (borders) paragraphAttrs.borders = borders;
57219
57303
  const shading = normalizeParagraphShading(attrs.shading ?? hydrated?.shading);
57220
57304
  if (shading) paragraphAttrs.shading = shading;
57305
+ const keepNext = paragraphProps.keepNext ?? hydrated?.keepNext ?? attrs.keepNext;
57306
+ if (keepNext === true) paragraphAttrs.keepNext = true;
57307
+ const keepLines = paragraphProps.keepLines ?? hydrated?.keepLines ?? attrs.keepLines;
57308
+ if (keepLines === true) paragraphAttrs.keepLines = true;
57221
57309
  const paragraphDecimalSeparator = styleContext.defaults?.decimalSeparator ?? DEFAULT_DECIMAL_SEPARATOR$2;
57222
57310
  if (paragraphDecimalSeparator !== DEFAULT_DECIMAL_SEPARATOR$2) {
57223
57311
  paragraphAttrs.decimalSeparator = paragraphDecimalSeparator;
57224
57312
  }
57313
+ const styleIdAttr = typeof attrs.styleId === "string" ? attrs.styleId : void 0;
57314
+ if (styleIdAttr) {
57315
+ paragraphAttrs.styleId = styleIdAttr;
57316
+ } else if (paragraphProps.styleId) {
57317
+ paragraphAttrs.styleId = paragraphProps.styleId;
57318
+ }
57225
57319
  const paraIntervalTwips = pickNumber(attrs.tabIntervalTwips) ?? (() => {
57226
57320
  const px = pickNumber(attrs.tabIntervalPx);
57227
57321
  return px != null ? Math.round(px * 15) : void 0;
@@ -57258,7 +57352,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
57258
57352
  paragraphAttrs.floatAlignment = xAlign;
57259
57353
  }
57260
57354
  }
57261
- const numberingSource = attrs.numberingProperties ?? hydrated?.numberingProperties;
57355
+ const numberingSource = attrs.numberingProperties ?? paragraphProps.numberingProperties ?? hydrated?.numberingProperties;
57262
57356
  const rawNumberingProps = toAdapterNumberingProps(numberingSource);
57263
57357
  if (rawNumberingProps) {
57264
57358
  const numberingProps = rawNumberingProps;
@@ -57911,13 +58005,29 @@ const extractRunStyleId = (runProperties) => {
57911
58005
  return null;
57912
58006
  };
57913
58007
  const isTextRun$1 = (run2) => run2.kind !== "tab";
58008
+ const dataAttrsCompatible = (a, b2) => {
58009
+ const aAttrs = a.dataAttrs;
58010
+ const bAttrs = b2.dataAttrs;
58011
+ if (!aAttrs && !bAttrs) return true;
58012
+ if (!aAttrs || !bAttrs) return false;
58013
+ const aKeys = Object.keys(aAttrs).sort();
58014
+ const bKeys = Object.keys(bAttrs).sort();
58015
+ if (aKeys.length !== bKeys.length) return false;
58016
+ for (let i = 0; i < aKeys.length; i++) {
58017
+ const key2 = aKeys[i];
58018
+ if (key2 !== bKeys[i] || aAttrs[key2] !== bAttrs[key2]) {
58019
+ return false;
58020
+ }
58021
+ }
58022
+ return true;
58023
+ };
57914
58024
  function mergeAdjacentRuns(runs) {
57915
58025
  if (runs.length <= 1) return runs;
57916
58026
  const merged = [];
57917
58027
  let current = runs[0];
57918
58028
  for (let i = 1; i < runs.length; i++) {
57919
58029
  const next = runs[i];
57920
- const canMerge = isTextRun$1(current) && isTextRun$1(next) && !current.token && !next.token && current.pmStart != null && current.pmEnd != null && next.pmStart != null && next.pmEnd != null && current.pmEnd === next.pmStart && current.fontFamily === next.fontFamily && current.fontSize === next.fontSize && current.bold === next.bold && current.italic === next.italic && current.underline === next.underline && current.strike === next.strike && current.color === next.color && current.highlight === next.highlight && (current.letterSpacing ?? 0) === (next.letterSpacing ?? 0) && trackedChangesCompatible(current, next);
58030
+ const canMerge = isTextRun$1(current) && isTextRun$1(next) && !current.token && !next.token && current.pmStart != null && current.pmEnd != null && next.pmStart != null && next.pmEnd != null && current.pmEnd === next.pmStart && current.fontFamily === next.fontFamily && current.fontSize === next.fontSize && current.bold === next.bold && current.italic === next.italic && current.underline === next.underline && current.strike === next.strike && current.color === next.color && current.highlight === next.highlight && (current.letterSpacing ?? 0) === (next.letterSpacing ?? 0) && trackedChangesCompatible(current, next) && dataAttrsCompatible(current, next);
57921
58031
  if (canMerge) {
57922
58032
  const currText = current.text ?? "";
57923
58033
  const nextText = next.text ?? "";
@@ -57934,10 +58044,62 @@ function mergeAdjacentRuns(runs) {
57934
58044
  merged.push(current);
57935
58045
  return merged;
57936
58046
  }
58047
+ const applyBaseRunDefaults = (run2, defaults, fallbackFont, fallbackSize) => {
58048
+ if (!run2) return;
58049
+ if (defaults.fontFamily && run2.fontFamily === fallbackFont) {
58050
+ run2.fontFamily = defaults.fontFamily;
58051
+ }
58052
+ if (defaults.fontSizePx != null && run2.fontSize === fallbackSize) {
58053
+ run2.fontSize = defaults.fontSizePx;
58054
+ }
58055
+ if (defaults.color && !run2.color) {
58056
+ run2.color = defaults.color;
58057
+ }
58058
+ if (defaults.letterSpacing != null && run2.letterSpacing == null) {
58059
+ run2.letterSpacing = defaults.letterSpacing;
58060
+ }
58061
+ if (defaults.bold && run2.bold === void 0) {
58062
+ run2.bold = true;
58063
+ }
58064
+ if (defaults.italic && run2.italic === void 0) {
58065
+ run2.italic = true;
58066
+ }
58067
+ if (defaults.underline && !run2.underline) {
58068
+ run2.underline = defaults.underline;
58069
+ }
58070
+ };
57937
58071
  function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converters, converterContext) {
57938
58072
  const baseBlockId = nextBlockId("paragraph");
57939
- const paragraphStyleId = typeof para.attrs?.styleId === "string" ? para.attrs.styleId : null;
58073
+ const paragraphProps = typeof para.attrs?.paragraphProperties === "object" && para.attrs.paragraphProperties !== null ? para.attrs.paragraphProperties : {};
58074
+ const paragraphStyleId = typeof para.attrs?.styleId === "string" && para.attrs.styleId.trim() ? para.attrs.styleId : typeof paragraphProps.styleId === "string" && paragraphProps.styleId.trim() ? paragraphProps.styleId : null;
57940
58075
  const paragraphHydration = converterContext ? hydrateParagraphStyleAttrs(para, converterContext) : null;
58076
+ let baseRunDefaults = {};
58077
+ try {
58078
+ const spacingSource = para.attrs?.spacing !== void 0 ? para.attrs.spacing : paragraphProps.spacing !== void 0 ? paragraphProps.spacing : paragraphHydration?.spacing;
58079
+ const indentSource = para.attrs?.indent ?? paragraphProps.indent ?? paragraphHydration?.indent;
58080
+ const normalizedSpacing = normalizeParagraphSpacing(spacingSource);
58081
+ const normalizedIndent = normalizePxIndent(indentSource) ?? normalizeParagraphIndent(indentSource ?? para.attrs?.textIndent);
58082
+ const styleNodeAttrs = paragraphHydration?.tabStops && !para.attrs?.tabStops && !para.attrs?.tabs ? { ...para.attrs ?? {}, tabStops: paragraphHydration.tabStops } : para.attrs ?? {};
58083
+ const styleNode = buildStyleNodeFromAttrs(styleNodeAttrs, normalizedSpacing, normalizedIndent);
58084
+ if (styleNodeAttrs.styleId == null && paragraphProps.styleId) {
58085
+ styleNode.styleId = paragraphProps.styleId;
58086
+ }
58087
+ const resolved = resolveStyle(styleNode, styleContext);
58088
+ baseRunDefaults = {
58089
+ fontFamily: resolved.character.font?.family,
58090
+ fontSizePx: ptToPx(resolved.character.font?.size),
58091
+ color: resolved.character.color,
58092
+ bold: resolved.character.font?.weight != null ? resolved.character.font.weight >= 600 : void 0,
58093
+ italic: resolved.character.font?.italic,
58094
+ underline: resolved.character.underline ? {
58095
+ style: resolved.character.underline.style,
58096
+ color: resolved.character.underline.color
58097
+ } : void 0,
58098
+ letterSpacing: ptToPx(resolved.character.letterSpacing)
58099
+ };
58100
+ } catch {
58101
+ baseRunDefaults = {};
58102
+ }
57941
58103
  const paragraphAttrs = computeParagraphAttrs(
57942
58104
  para,
57943
58105
  styleContext,
@@ -57945,6 +58107,18 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
57945
58107
  converterContext,
57946
58108
  paragraphHydration
57947
58109
  );
58110
+ if (paragraphAttrs?.spacing) {
58111
+ const spacing = { ...paragraphAttrs.spacing };
58112
+ const effectiveFontSize = baseRunDefaults.fontSizePx ?? defaultSize;
58113
+ const isList2 = Boolean(paragraphAttrs.numberingProperties);
58114
+ if (spacing.beforeAutospacing) {
58115
+ spacing.before = isList2 ? 0 : Math.max(0, Number(spacing.before ?? 0) + effectiveFontSize * 0.5);
58116
+ }
58117
+ if (spacing.afterAutospacing) {
58118
+ spacing.after = isList2 ? 0 : Math.max(0, Number(spacing.after ?? 0) + effectiveFontSize * 0.5);
58119
+ }
58120
+ paragraphAttrs.spacing = spacing;
58121
+ }
57948
58122
  const linkedStyleResolver = createLinkedStyleResolver(converterContext?.linkedStyles);
57949
58123
  const blocks = [];
57950
58124
  if (hasPageBreakBefore(para)) {
@@ -58022,6 +58196,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58022
58196
  );
58023
58197
  const inlineStyleId = getInlineStyleId(inheritedMarks);
58024
58198
  applyRunStyles2(run2, inlineStyleId, activeRunStyleId);
58199
+ applyBaseRunDefaults(run2, baseRunDefaults, defaultFont, defaultSize);
58025
58200
  currentRuns.push(run2);
58026
58201
  return;
58027
58202
  }
@@ -58057,6 +58232,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58057
58232
  );
58058
58233
  const inlineStyleId = getInlineStyleId(inheritedMarks);
58059
58234
  applyRunStyles2(run2, inlineStyleId, activeRunStyleId);
58235
+ applyBaseRunDefaults(run2, baseRunDefaults, defaultFont, defaultSize);
58060
58236
  currentRuns.push(run2);
58061
58237
  }
58062
58238
  }
@@ -58094,6 +58270,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58094
58270
  );
58095
58271
  const inlineStyleId = getInlineStyleId(mergedMarks);
58096
58272
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
58273
+ applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
58097
58274
  if (pageRefPos) {
58098
58275
  tokenRun.pmStart = pageRefPos.start;
58099
58276
  tokenRun.pmEnd = pageRefPos.end;
@@ -58152,6 +58329,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58152
58329
  }
58153
58330
  const inlineStyleId = getInlineStyleId(inheritedMarks);
58154
58331
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
58332
+ applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
58155
58333
  currentRuns.push(tokenRun);
58156
58334
  }
58157
58335
  return;
@@ -60180,7 +60358,9 @@ function layoutParagraphBlock(ctx2, anchors) {
60180
60358
  let lines = normalizeLines(measure);
60181
60359
  let fromLine = 0;
60182
60360
  const spacing = block.attrs?.spacing ?? {};
60183
- const spacingBefore = Math.max(0, Number(spacing.before ?? spacing.lineSpaceBefore ?? 0));
60361
+ const styleId = block.attrs?.styleId;
60362
+ const contextualSpacing = Boolean(block.attrs?.contextualSpacing);
60363
+ let spacingBefore = Math.max(0, Number(spacing.before ?? spacing.lineSpaceBefore ?? 0));
60184
60364
  const spacingAfter = Math.max(0, Number(spacing.after ?? spacing.lineSpaceAfter ?? 0));
60185
60365
  let appliedSpacingBefore = spacingBefore === 0;
60186
60366
  let lastState = null;
@@ -60196,6 +60376,15 @@ function layoutParagraphBlock(ctx2, anchors) {
60196
60376
  while (fromLine < lines.length) {
60197
60377
  let state2 = ensurePage();
60198
60378
  if (state2.trailingSpacing == null) state2.trailingSpacing = 0;
60379
+ if (contextualSpacing) {
60380
+ const prevStyle = state2.lastParagraphStyleId;
60381
+ if (styleId && prevStyle && prevStyle === styleId) {
60382
+ spacingBefore = 0;
60383
+ }
60384
+ }
60385
+ if (contextualSpacing && state2.lastParagraphStyleId && styleId && state2.lastParagraphStyleId === styleId) {
60386
+ spacingBefore = 0;
60387
+ }
60199
60388
  if (!appliedSpacingBefore && spacingBefore > 0) {
60200
60389
  while (!appliedSpacingBefore) {
60201
60390
  const prevTrailing = state2.trailingSpacing ?? 0;
@@ -60364,6 +60553,7 @@ function layoutParagraphBlock(ctx2, anchors) {
60364
60553
  } else {
60365
60554
  lastState.trailingSpacing = 0;
60366
60555
  }
60556
+ lastState.lastParagraphStyleId = styleId;
60367
60557
  }
60368
60558
  }
60369
60559
  function layoutImageBlock({
@@ -60602,7 +60792,8 @@ function createPaginator(opts) {
60602
60792
  contentBottom,
60603
60793
  constraintBoundaries: [],
60604
60794
  activeConstraintIndex: -1,
60605
- trailingSpacing: 0
60795
+ trailingSpacing: 0,
60796
+ lastParagraphStyleId: void 0
60606
60797
  };
60607
60798
  states.push(state2);
60608
60799
  pages.push(state2.page);
@@ -60624,6 +60815,7 @@ function createPaginator(opts) {
60624
60815
  state2.cursorY = state2.topMargin;
60625
60816
  }
60626
60817
  state2.trailingSpacing = 0;
60818
+ state2.lastParagraphStyleId = void 0;
60627
60819
  return state2;
60628
60820
  }
60629
60821
  return startNewPage();
@@ -65775,147 +65967,162 @@ const _DomPainter = class _DomPainter2 {
65775
65967
  return el;
65776
65968
  }
65777
65969
  renderListItemFragment(fragment, context) {
65778
- const lookup2 = this.blockLookup.get(fragment.blockId);
65779
- if (!lookup2 || lookup2.block.kind !== "list" || lookup2.measure.kind !== "list") {
65780
- throw new Error(`DomPainter: missing list data for fragment ${fragment.blockId}`);
65781
- }
65782
- if (!this.doc) {
65783
- throw new Error("DomPainter: document is not available");
65970
+ try {
65971
+ const lookup2 = this.blockLookup.get(fragment.blockId);
65972
+ if (!lookup2 || lookup2.block.kind !== "list" || lookup2.measure.kind !== "list") {
65973
+ throw new Error(`DomPainter: missing list data for fragment ${fragment.blockId}`);
65974
+ }
65975
+ if (!this.doc) {
65976
+ throw new Error("DomPainter: document is not available");
65977
+ }
65978
+ const block = lookup2.block;
65979
+ const measure = lookup2.measure;
65980
+ const item = block.items.find((entry) => entry.id === fragment.itemId);
65981
+ const itemMeasure = measure.items.find((entry) => entry.itemId === fragment.itemId);
65982
+ if (!item || !itemMeasure) {
65983
+ throw new Error(`DomPainter: missing list item ${fragment.itemId}`);
65984
+ }
65985
+ const fragmentEl = this.doc.createElement("div");
65986
+ fragmentEl.classList.add(CLASS_NAMES.fragment, `${CLASS_NAMES.fragment}-list-item`);
65987
+ applyStyles$2(fragmentEl, fragmentStyles);
65988
+ fragmentEl.style.left = `${fragment.x - fragment.markerWidth}px`;
65989
+ fragmentEl.style.top = `${fragment.y}px`;
65990
+ fragmentEl.style.width = `${fragment.markerWidth + fragment.width}px`;
65991
+ fragmentEl.dataset.blockId = fragment.blockId;
65992
+ fragmentEl.dataset.itemId = fragment.itemId;
65993
+ const paragraphMetadata = item.paragraph.attrs?.sdt;
65994
+ this.applySdtDataset(fragmentEl, paragraphMetadata);
65995
+ if (fragment.continuesFromPrev) {
65996
+ fragmentEl.dataset.continuesFromPrev = "true";
65997
+ }
65998
+ if (fragment.continuesOnNext) {
65999
+ fragmentEl.dataset.continuesOnNext = "true";
66000
+ }
66001
+ const markerEl = this.doc.createElement("span");
66002
+ markerEl.classList.add("superdoc-list-marker");
66003
+ const wordLayout = item.paragraph.attrs?.wordLayout;
66004
+ if (wordLayout?.marker) {
66005
+ const marker = wordLayout.marker;
66006
+ markerEl.textContent = marker.markerText;
66007
+ markerEl.style.display = "inline-block";
66008
+ markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
66009
+ markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
66010
+ markerEl.style.textAlign = marker.justification;
66011
+ markerEl.style.fontFamily = marker.run.fontFamily;
66012
+ markerEl.style.fontSize = `${marker.run.fontSize}px`;
66013
+ if (marker.run.bold) markerEl.style.fontWeight = "bold";
66014
+ if (marker.run.italic) markerEl.style.fontStyle = "italic";
66015
+ if (marker.run.color) markerEl.style.color = marker.run.color;
66016
+ if (marker.run.letterSpacing) markerEl.style.letterSpacing = `${marker.run.letterSpacing}px`;
66017
+ } else {
66018
+ markerEl.textContent = item.marker.text;
66019
+ markerEl.style.display = "inline-block";
66020
+ markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
66021
+ markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
66022
+ if (item.marker.align) {
66023
+ markerEl.style.textAlign = item.marker.align;
66024
+ }
66025
+ }
66026
+ fragmentEl.appendChild(markerEl);
66027
+ const contentEl = this.doc.createElement("div");
66028
+ contentEl.classList.add("superdoc-list-content");
66029
+ this.applySdtDataset(contentEl, paragraphMetadata);
66030
+ contentEl.style.display = "inline-block";
66031
+ contentEl.style.width = `${fragment.width}px`;
66032
+ const lines = itemMeasure.paragraph.lines.slice(fragment.fromLine, fragment.toLine);
66033
+ const contentAttrs = wordLayout ? item.paragraph.attrs : stripListIndent(item.paragraph.attrs);
66034
+ applyParagraphBlockStyles(contentEl, contentAttrs);
66035
+ lines.forEach((line) => {
66036
+ const lineEl = this.renderLine(item.paragraph, line, context);
66037
+ contentEl.appendChild(lineEl);
66038
+ });
66039
+ fragmentEl.appendChild(contentEl);
66040
+ return fragmentEl;
66041
+ } catch (error) {
66042
+ console.error("[DomPainter] List item fragment rendering failed:", { fragment, error });
66043
+ return this.createErrorPlaceholder(fragment.blockId, error);
65784
66044
  }
65785
- const block = lookup2.block;
65786
- const measure = lookup2.measure;
65787
- const item = block.items.find((entry) => entry.id === fragment.itemId);
65788
- const itemMeasure = measure.items.find((entry) => entry.itemId === fragment.itemId);
65789
- if (!item || !itemMeasure) {
65790
- throw new Error(`DomPainter: missing list item ${fragment.itemId}`);
65791
- }
65792
- const fragmentEl = this.doc.createElement("div");
65793
- fragmentEl.classList.add(CLASS_NAMES.fragment, `${CLASS_NAMES.fragment}-list-item`);
65794
- applyStyles$2(fragmentEl, fragmentStyles);
65795
- fragmentEl.style.left = `${fragment.x - fragment.markerWidth}px`;
65796
- fragmentEl.style.top = `${fragment.y}px`;
65797
- fragmentEl.style.width = `${fragment.markerWidth + fragment.width}px`;
65798
- fragmentEl.dataset.blockId = fragment.blockId;
65799
- fragmentEl.dataset.itemId = fragment.itemId;
65800
- const paragraphMetadata = item.paragraph.attrs?.sdt;
65801
- this.applySdtDataset(fragmentEl, paragraphMetadata);
65802
- if (fragment.continuesFromPrev) {
65803
- fragmentEl.dataset.continuesFromPrev = "true";
65804
- }
65805
- if (fragment.continuesOnNext) {
65806
- fragmentEl.dataset.continuesOnNext = "true";
65807
- }
65808
- const markerEl = this.doc.createElement("span");
65809
- markerEl.classList.add("superdoc-list-marker");
65810
- const wordLayout = item.paragraph.attrs?.wordLayout;
65811
- if (wordLayout?.marker) {
65812
- const marker = wordLayout.marker;
65813
- markerEl.textContent = marker.markerText;
65814
- markerEl.style.display = "inline-block";
65815
- markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
65816
- markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
65817
- markerEl.style.textAlign = marker.justification;
65818
- markerEl.style.fontFamily = marker.run.fontFamily;
65819
- markerEl.style.fontSize = `${marker.run.fontSize}px`;
65820
- if (marker.run.bold) markerEl.style.fontWeight = "bold";
65821
- if (marker.run.italic) markerEl.style.fontStyle = "italic";
65822
- if (marker.run.color) markerEl.style.color = marker.run.color;
65823
- if (marker.run.letterSpacing) markerEl.style.letterSpacing = `${marker.run.letterSpacing}px`;
65824
- } else {
65825
- markerEl.textContent = item.marker.text;
65826
- markerEl.style.display = "inline-block";
65827
- markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
65828
- markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
65829
- if (item.marker.align) {
65830
- markerEl.style.textAlign = item.marker.align;
65831
- }
65832
- }
65833
- fragmentEl.appendChild(markerEl);
65834
- const contentEl = this.doc.createElement("div");
65835
- contentEl.classList.add("superdoc-list-content");
65836
- this.applySdtDataset(contentEl, paragraphMetadata);
65837
- contentEl.style.display = "inline-block";
65838
- contentEl.style.width = `${fragment.width}px`;
65839
- const lines = itemMeasure.paragraph.lines.slice(fragment.fromLine, fragment.toLine);
65840
- const contentAttrs = wordLayout ? item.paragraph.attrs : stripListIndent(item.paragraph.attrs);
65841
- applyParagraphBlockStyles(contentEl, contentAttrs);
65842
- lines.forEach((line) => {
65843
- const lineEl = this.renderLine(item.paragraph, line, context);
65844
- contentEl.appendChild(lineEl);
65845
- });
65846
- fragmentEl.appendChild(contentEl);
65847
- return fragmentEl;
65848
66045
  }
65849
66046
  renderImageFragment(fragment) {
65850
- const lookup2 = this.blockLookup.get(fragment.blockId);
65851
- if (!lookup2 || lookup2.block.kind !== "image" || lookup2.measure.kind !== "image") {
65852
- throw new Error(`DomPainter: missing image block for fragment ${fragment.blockId}`);
65853
- }
65854
- if (!this.doc) {
65855
- throw new Error("DomPainter: document is not available");
65856
- }
65857
- const block = lookup2.block;
65858
- const fragmentEl = this.doc.createElement("div");
65859
- fragmentEl.classList.add(CLASS_NAMES.fragment);
65860
- applyStyles$2(fragmentEl, fragmentStyles);
65861
- this.applyFragmentFrame(fragmentEl, fragment);
65862
- fragmentEl.style.height = `${fragment.height}px`;
65863
- this.applySdtDataset(fragmentEl, block.attrs?.sdt);
65864
- this.applyContainerSdtDataset(fragmentEl, block.attrs?.containerSdt);
65865
- if (fragment.isAnchored && fragment.zIndex != null) {
65866
- fragmentEl.style.zIndex = String(fragment.zIndex);
65867
- }
65868
- const img = this.doc.createElement("img");
65869
- if (block.src) {
65870
- img.src = block.src;
66047
+ try {
66048
+ const lookup2 = this.blockLookup.get(fragment.blockId);
66049
+ if (!lookup2 || lookup2.block.kind !== "image" || lookup2.measure.kind !== "image") {
66050
+ throw new Error(`DomPainter: missing image block for fragment ${fragment.blockId}`);
66051
+ }
66052
+ if (!this.doc) {
66053
+ throw new Error("DomPainter: document is not available");
66054
+ }
66055
+ const block = lookup2.block;
66056
+ const fragmentEl = this.doc.createElement("div");
66057
+ fragmentEl.classList.add(CLASS_NAMES.fragment);
66058
+ applyStyles$2(fragmentEl, fragmentStyles);
66059
+ this.applyFragmentFrame(fragmentEl, fragment);
66060
+ fragmentEl.style.height = `${fragment.height}px`;
66061
+ this.applySdtDataset(fragmentEl, block.attrs?.sdt);
66062
+ this.applyContainerSdtDataset(fragmentEl, block.attrs?.containerSdt);
66063
+ if (fragment.isAnchored && fragment.zIndex != null) {
66064
+ fragmentEl.style.zIndex = String(fragment.zIndex);
66065
+ }
66066
+ const img = this.doc.createElement("img");
66067
+ if (block.src) {
66068
+ img.src = block.src;
66069
+ }
66070
+ img.alt = block.alt ?? "";
66071
+ img.style.width = "100%";
66072
+ img.style.height = "100%";
66073
+ img.style.objectFit = block.objectFit ?? "contain";
66074
+ img.style.display = block.display === "inline" ? "inline-block" : "block";
66075
+ fragmentEl.appendChild(img);
66076
+ return fragmentEl;
66077
+ } catch (error) {
66078
+ console.error("[DomPainter] Image fragment rendering failed:", { fragment, error });
66079
+ return this.createErrorPlaceholder(fragment.blockId, error);
65871
66080
  }
65872
- img.alt = block.alt ?? "";
65873
- img.style.width = "100%";
65874
- img.style.height = "100%";
65875
- img.style.objectFit = block.objectFit ?? "contain";
65876
- img.style.display = block.display === "inline" ? "inline-block" : "block";
65877
- fragmentEl.appendChild(img);
65878
- return fragmentEl;
65879
66081
  }
65880
66082
  renderDrawingFragment(fragment) {
65881
- const lookup2 = this.blockLookup.get(fragment.blockId);
65882
- if (!lookup2 || lookup2.block.kind !== "drawing" || lookup2.measure.kind !== "drawing") {
65883
- throw new Error(`DomPainter: missing drawing block for fragment ${fragment.blockId}`);
65884
- }
65885
- if (!this.doc) {
65886
- throw new Error("DomPainter: document is not available");
66083
+ try {
66084
+ const lookup2 = this.blockLookup.get(fragment.blockId);
66085
+ if (!lookup2 || lookup2.block.kind !== "drawing" || lookup2.measure.kind !== "drawing") {
66086
+ throw new Error(`DomPainter: missing drawing block for fragment ${fragment.blockId}`);
66087
+ }
66088
+ if (!this.doc) {
66089
+ throw new Error("DomPainter: document is not available");
66090
+ }
66091
+ const block = lookup2.block;
66092
+ const isVectorShapeBlock = block.kind === "drawing" && block.drawingKind === "vectorShape";
66093
+ const fragmentEl = this.doc.createElement("div");
66094
+ fragmentEl.classList.add(CLASS_NAMES.fragment, "superdoc-drawing-fragment");
66095
+ applyStyles$2(fragmentEl, fragmentStyles);
66096
+ this.applyFragmentFrame(fragmentEl, fragment);
66097
+ fragmentEl.style.height = `${fragment.height}px`;
66098
+ fragmentEl.style.position = "absolute";
66099
+ if (fragment.isAnchored && fragment.zIndex != null) {
66100
+ fragmentEl.style.zIndex = String(fragment.zIndex);
66101
+ }
66102
+ const innerWrapper = this.doc.createElement("div");
66103
+ innerWrapper.classList.add("superdoc-drawing-inner");
66104
+ innerWrapper.style.position = "absolute";
66105
+ innerWrapper.style.left = "50%";
66106
+ innerWrapper.style.top = "50%";
66107
+ innerWrapper.style.width = `${fragment.geometry.width}px`;
66108
+ innerWrapper.style.height = `${fragment.geometry.height}px`;
66109
+ innerWrapper.style.transformOrigin = "center";
66110
+ const scale = fragment.scale ?? 1;
66111
+ const transforms = ["translate(-50%, -50%)"];
66112
+ if (!isVectorShapeBlock) {
66113
+ transforms.push(`rotate(${fragment.geometry.rotation ?? 0}deg)`);
66114
+ transforms.push(`scaleX(${fragment.geometry.flipH ? -1 : 1})`);
66115
+ transforms.push(`scaleY(${fragment.geometry.flipV ? -1 : 1})`);
66116
+ }
66117
+ transforms.push(`scale(${scale})`);
66118
+ innerWrapper.style.transform = transforms.join(" ");
66119
+ innerWrapper.appendChild(this.renderDrawingContent(block, fragment));
66120
+ fragmentEl.appendChild(innerWrapper);
66121
+ return fragmentEl;
66122
+ } catch (error) {
66123
+ console.error("[DomPainter] Drawing fragment rendering failed:", { fragment, error });
66124
+ return this.createErrorPlaceholder(fragment.blockId, error);
65887
66125
  }
65888
- const block = lookup2.block;
65889
- const isVectorShapeBlock = block.kind === "drawing" && block.drawingKind === "vectorShape";
65890
- const fragmentEl = this.doc.createElement("div");
65891
- fragmentEl.classList.add(CLASS_NAMES.fragment, "superdoc-drawing-fragment");
65892
- applyStyles$2(fragmentEl, fragmentStyles);
65893
- this.applyFragmentFrame(fragmentEl, fragment);
65894
- fragmentEl.style.height = `${fragment.height}px`;
65895
- fragmentEl.style.position = "absolute";
65896
- if (fragment.isAnchored && fragment.zIndex != null) {
65897
- fragmentEl.style.zIndex = String(fragment.zIndex);
65898
- }
65899
- const innerWrapper = this.doc.createElement("div");
65900
- innerWrapper.classList.add("superdoc-drawing-inner");
65901
- innerWrapper.style.position = "absolute";
65902
- innerWrapper.style.left = "50%";
65903
- innerWrapper.style.top = "50%";
65904
- innerWrapper.style.width = `${fragment.geometry.width}px`;
65905
- innerWrapper.style.height = `${fragment.geometry.height}px`;
65906
- innerWrapper.style.transformOrigin = "center";
65907
- const scale = fragment.scale ?? 1;
65908
- const transforms = ["translate(-50%, -50%)"];
65909
- if (!isVectorShapeBlock) {
65910
- transforms.push(`rotate(${fragment.geometry.rotation ?? 0}deg)`);
65911
- transforms.push(`scaleX(${fragment.geometry.flipH ? -1 : 1})`);
65912
- transforms.push(`scaleY(${fragment.geometry.flipV ? -1 : 1})`);
65913
- }
65914
- transforms.push(`scale(${scale})`);
65915
- innerWrapper.style.transform = transforms.join(" ");
65916
- innerWrapper.appendChild(this.renderDrawingContent(block, fragment));
65917
- fragmentEl.appendChild(innerWrapper);
65918
- return fragmentEl;
65919
66126
  }
65920
66127
  renderDrawingContent(block, fragment) {
65921
66128
  if (!this.doc) {
@@ -66350,6 +66557,7 @@ const _DomPainter = class _DomPainter2 {
66350
66557
  }
66351
66558
  applyRunStyles(elem, run2, isActiveLink);
66352
66559
  elem.style.zIndex = "1";
66560
+ applyRunDataAttributes(elem, run2.dataAttrs);
66353
66561
  if (run2.pmStart != null) elem.dataset.pmStart = String(run2.pmStart);
66354
66562
  if (run2.pmEnd != null) elem.dataset.pmEnd = String(run2.pmEnd);
66355
66563
  if (trackedConfig) {
@@ -66730,6 +66938,12 @@ const deriveBlockVersion = (block) => {
66730
66938
  run2.kind !== "tab" && run2.bold ? 1 : 0,
66731
66939
  run2.kind !== "tab" && run2.italic ? 1 : 0,
66732
66940
  run2.kind !== "tab" ? run2.color ?? "" : "",
66941
+ // Text decorations - ensures DOM updates when decoration properties change.
66942
+ run2.kind !== "tab" ? run2.underline?.style ?? "" : "",
66943
+ run2.kind !== "tab" ? run2.underline?.color ?? "" : "",
66944
+ run2.kind !== "tab" && run2.strike ? 1 : 0,
66945
+ run2.kind !== "tab" ? run2.highlight ?? "" : "",
66946
+ run2.kind !== "tab" && run2.letterSpacing != null ? run2.letterSpacing : "",
66733
66947
  run2.pmStart ?? "",
66734
66948
  run2.pmEnd ?? "",
66735
66949
  run2.kind !== "tab" ? run2.token ?? "" : ""
@@ -66824,6 +67038,20 @@ const applyRunStyles = (element, run2, isLink = false) => {
66824
67038
  element.style.textDecorationLine = decorations.join(" ");
66825
67039
  }
66826
67040
  };
67041
+ const applyRunDataAttributes = (element, dataAttrs) => {
67042
+ if (!dataAttrs) return;
67043
+ Object.entries(dataAttrs).forEach(([key2, value]) => {
67044
+ if (typeof key2 !== "string" || !key2.toLowerCase().startsWith("data-")) return;
67045
+ if (typeof value !== "string") return;
67046
+ try {
67047
+ element.setAttribute(key2, value);
67048
+ } catch (error) {
67049
+ if (process$1$1.env.NODE_ENV === "development") {
67050
+ console.warn(`[DomPainter] Failed to set data attribute "${key2}":`, error);
67051
+ }
67052
+ }
67053
+ });
67054
+ };
66827
67055
  const applyParagraphBlockStyles = (element, attrs) => {
66828
67056
  if (!attrs) return;
66829
67057
  if (attrs.alignment) {
@@ -70811,7 +71039,8 @@ getHeaderFooterPageHeight_fn = function() {
70811
71039
  return context.layout.pageSize?.h ?? context.region.height ?? 1;
70812
71040
  };
70813
71041
  renderSelectionRects_fn = function(rects) {
70814
- if (!__privateGet$1(this, _selectionOverlay)) {
71042
+ const localSelectionLayer = __privateGet$1(this, _localSelectionLayer);
71043
+ if (!localSelectionLayer) {
70815
71044
  return;
70816
71045
  }
70817
71046
  const pageHeight = __privateMethod$1(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
@@ -70822,7 +71051,7 @@ renderSelectionRects_fn = function(rects) {
70822
71051
  if (!coords) {
70823
71052
  return;
70824
71053
  }
70825
- const highlight = __privateGet$1(this, _selectionOverlay).ownerDocument?.createElement("div");
71054
+ const highlight = localSelectionLayer.ownerDocument?.createElement("div");
70826
71055
  if (!highlight) {
70827
71056
  return;
70828
71057
  }
@@ -70835,7 +71064,7 @@ renderSelectionRects_fn = function(rects) {
70835
71064
  highlight.style.backgroundColor = "rgba(51, 132, 255, 0.35)";
70836
71065
  highlight.style.borderRadius = "2px";
70837
71066
  highlight.style.pointerEvents = "none";
70838
- __privateGet$1(this, _selectionOverlay).appendChild(highlight);
71067
+ localSelectionLayer.appendChild(highlight);
70839
71068
  });
70840
71069
  };
70841
71070
  renderHoverRegion_fn = function(region) {
@@ -71285,6 +71514,7 @@ class PresentationInputBridge {
71285
71514
  __privateAdd$1(this, _onTargetChanged);
71286
71515
  __privateAdd$1(this, _listeners);
71287
71516
  __privateAdd$1(this, _currentTarget, null);
71517
+ __privateAdd$1(this, _destroyed, false);
71288
71518
  __privateSet(this, _windowRoot, windowRoot);
71289
71519
  __privateSet(this, _visibleHost2, visibleHost);
71290
71520
  __privateSet(this, _getTargetDom, getTargetDom);
@@ -71312,9 +71542,13 @@ class PresentationInputBridge {
71312
71542
  });
71313
71543
  __privateSet(this, _listeners, []);
71314
71544
  __privateSet(this, _currentTarget, null);
71545
+ __privateSet(this, _destroyed, true);
71315
71546
  }
71316
71547
  notifyTargetChanged() {
71317
71548
  var _a2;
71549
+ if (__privateGet$1(this, _destroyed)) {
71550
+ return;
71551
+ }
71318
71552
  const nextTarget = __privateGet$1(this, _getTargetDom).call(this);
71319
71553
  if (nextTarget === __privateGet$1(this, _currentTarget)) {
71320
71554
  return;
@@ -71344,6 +71578,7 @@ _getTargetDom = /* @__PURE__ */ new WeakMap();
71344
71578
  _onTargetChanged = /* @__PURE__ */ new WeakMap();
71345
71579
  _listeners = /* @__PURE__ */ new WeakMap();
71346
71580
  _currentTarget = /* @__PURE__ */ new WeakMap();
71581
+ _destroyed = /* @__PURE__ */ new WeakMap();
71347
71582
  _PresentationInputBridge_instances = /* @__PURE__ */ new WeakSet();
71348
71583
  addListener_fn = function(type2, handler2, target) {
71349
71584
  const bound = handler2.bind(this);
@@ -71351,12 +71586,21 @@ addListener_fn = function(type2, handler2, target) {
71351
71586
  target.addEventListener(type2, bound, true);
71352
71587
  };
71353
71588
  dispatchToTarget_fn = function(originalEvent, synthetic) {
71589
+ if (__privateGet$1(this, _destroyed)) return;
71354
71590
  const target = __privateGet$1(this, _getTargetDom).call(this);
71355
71591
  __privateSet(this, _currentTarget, target);
71356
71592
  if (!target) return;
71357
- const canceled = !target.dispatchEvent(synthetic) || synthetic.defaultPrevented;
71358
- if (canceled) {
71359
- originalEvent.preventDefault();
71593
+ const isConnected = target.isConnected;
71594
+ if (isConnected === false) return;
71595
+ try {
71596
+ const canceled = !target.dispatchEvent(synthetic) || synthetic.defaultPrevented;
71597
+ if (canceled) {
71598
+ originalEvent.preventDefault();
71599
+ }
71600
+ } catch (error) {
71601
+ if (process$1$1.env.NODE_ENV === "development") {
71602
+ console.warn("[PresentationEditor] Failed to dispatch event to target:", error);
71603
+ }
71360
71604
  }
71361
71605
  };
71362
71606
  forwardKeyboardEvent_fn = function(event) {
@@ -100246,7 +100490,7 @@ var __accessCheck = (obj, member, msg2) => member.has(obj) || __typeError("Canno
100246
100490
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
100247
100491
  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);
100248
100492
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
100249
- var _SuperToolbar_instances, initToolbarGroups_fn, _interceptedCommands, makeToolbarItems_fn, initDefaultFonts_fn, updateHighlightColors_fn, deactivateAll_fn, updateToolbarHistory_fn, enrichTrackedChanges_fn, runCommandWithArgumentOnly_fn;
100493
+ var _MARK_TOGGLE_NAMES, _SuperToolbar_instances, initToolbarGroups_fn, _interceptedCommands, makeToolbarItems_fn, initDefaultFonts_fn, updateHighlightColors_fn, deactivateAll_fn, updateToolbarHistory_fn, enrichTrackedChanges_fn, runCommandWithArgumentOnly_fn, syncStickyMarksFromState_fn, restoreStickyMarksIfNeeded_fn, ensureStoredMarksForMarkToggle_fn;
100250
100494
  var eventemitter3 = { exports: {} };
100251
100495
  var hasRequiredEventemitter3;
100252
100496
  function requireEventemitter3() {
@@ -100465,7 +100709,7 @@ const useToolbarItem = (options) => {
100465
100709
  if (!Array.isArray(options.options)) throw new Error("Invalid toolbar item options - " + options.options);
100466
100710
  nestedOptions.value?.push(...options.options);
100467
100711
  }
100468
- const activate = (attrs, ...args) => {
100712
+ const activate = (attrs = {}, ...args) => {
100469
100713
  onActivate(attrs, ...args);
100470
100714
  if (suppressActiveHighlight.value) return;
100471
100715
  active.value = true;
@@ -102737,7 +102981,7 @@ const isNegatedMark = (name, attrs = {}) => {
102737
102981
  if (typeof checker !== "function") return false;
102738
102982
  return Boolean(checker(attrs));
102739
102983
  };
102740
- class SuperToolbar extends EventEmitter2 {
102984
+ const _SuperToolbar = class _SuperToolbar2 extends EventEmitter2 {
102741
102985
  /**
102742
102986
  * Creates a new SuperToolbar instance
102743
102987
  * @param {ToolbarConfig} config - The configuration for the toolbar
@@ -102781,11 +103025,11 @@ class SuperToolbar extends EventEmitter2 {
102781
103025
  const isSmallScreen = window.matchMedia("(max-width: 834px)").matches;
102782
103026
  if (isMobileDevice && isSmallScreen) {
102783
103027
  layers.style.transformOrigin = "0 0";
102784
- layers.style.transform = `scale(${parseInt(argument) / 100})`;
103028
+ layers.style.transform = `scale(${parseInt(argument, 10) / 100})`;
102785
103029
  } else {
102786
- layers.style.zoom = parseInt(argument) / 100;
103030
+ layers.style.zoom = parseInt(argument, 10) / 100;
102787
103031
  }
102788
- this.superdoc.superdocStore.activeZoom = parseInt(argument);
103032
+ this.superdoc.superdocStore.activeZoom = parseInt(argument, 10);
102789
103033
  },
102790
103034
  /**
102791
103035
  * Sets the document mode
@@ -102867,31 +103111,37 @@ class SuperToolbar extends EventEmitter2 {
102867
103111
  * @returns {Promise<void>}
102868
103112
  */
102869
103113
  startImageUpload: async () => {
102870
- let open = getFileOpener();
102871
- let result = await open();
102872
- if (!result?.file) {
102873
- return;
102874
- }
102875
- const { size: size2, file } = await checkAndProcessImage({
102876
- file: result.file,
102877
- getMaxContentSize: () => this.activeEditor.getMaxContentSize()
102878
- });
102879
- if (!file) {
102880
- return;
103114
+ try {
103115
+ let open = getFileOpener();
103116
+ let result = await open();
103117
+ if (!result?.file) {
103118
+ return;
103119
+ }
103120
+ const { size: size2, file } = await checkAndProcessImage({
103121
+ file: result.file,
103122
+ getMaxContentSize: () => this.activeEditor.getMaxContentSize()
103123
+ });
103124
+ if (!file) {
103125
+ return;
103126
+ }
103127
+ const id = {};
103128
+ replaceSelectionWithImagePlaceholder({
103129
+ view: this.activeEditor.view,
103130
+ editorOptions: this.activeEditor.options,
103131
+ id
103132
+ });
103133
+ await uploadAndInsertImage({
103134
+ editor: this.activeEditor,
103135
+ view: this.activeEditor.view,
103136
+ file,
103137
+ size: size2,
103138
+ id
103139
+ });
103140
+ } catch (error) {
103141
+ const err = new Error("[super-toolbar 🎨] Image upload failed");
103142
+ this.emit("exception", { error: err, editor: this.activeEditor, originalError: error });
103143
+ console.error(err, error);
102881
103144
  }
102882
- const id = {};
102883
- replaceSelectionWithImagePlaceholder({
102884
- view: this.activeEditor.view,
102885
- editorOptions: this.activeEditor.options,
102886
- id
102887
- });
102888
- await uploadAndInsertImage({
102889
- editor: this.activeEditor,
102890
- view: this.activeEditor.view,
102891
- file,
102892
- size: size2,
102893
- id
102894
- });
102895
103145
  },
102896
103146
  /**
102897
103147
  * Increases text indentation or list level
@@ -103060,6 +103310,13 @@ class SuperToolbar extends EventEmitter2 {
103060
103310
  };
103061
103311
  this.config.hideButtons = config2.hideButtons ?? true;
103062
103312
  this.config.responsiveToContainer = config2.responsiveToContainer ?? false;
103313
+ this.pendingMarkCommands = [];
103314
+ this.stickyStoredMarks = null;
103315
+ this._boundEditorHandlers = {
103316
+ transaction: null,
103317
+ selectionUpdate: null,
103318
+ focus: null
103319
+ };
103063
103320
  if (!this.config.selector && this.config.element) {
103064
103321
  this.config.selector = this.config.element;
103065
103322
  }
@@ -103119,12 +103376,28 @@ class SuperToolbar extends EventEmitter2 {
103119
103376
  }
103120
103377
  /**
103121
103378
  * The toolbar expects an active Super Editor instance.
103122
- * @param {Object} editor - The editor instance to attach to the toolbar
103379
+ * Removes listeners from the previous editor (if any) before attaching to the new one.
103380
+ * @param {Object|null} editor - The editor instance to attach to the toolbar, or null to detach
103123
103381
  * @returns {void}
103124
103382
  */
103125
103383
  setActiveEditor(editor) {
103384
+ if (this.activeEditor && this._boundEditorHandlers.transaction) {
103385
+ this.activeEditor.off("transaction", this._boundEditorHandlers.transaction);
103386
+ this.activeEditor.off("selectionUpdate", this._boundEditorHandlers.selectionUpdate);
103387
+ this.activeEditor.off("focus", this._boundEditorHandlers.focus);
103388
+ this._boundEditorHandlers.transaction = null;
103389
+ this._boundEditorHandlers.selectionUpdate = null;
103390
+ this._boundEditorHandlers.focus = null;
103391
+ }
103126
103392
  this.activeEditor = editor;
103127
- this.activeEditor.on("transaction", this.onEditorTransaction.bind(this));
103393
+ if (editor) {
103394
+ this._boundEditorHandlers.transaction = this.onEditorTransaction.bind(this);
103395
+ this._boundEditorHandlers.selectionUpdate = this.onEditorSelectionUpdate.bind(this);
103396
+ this._boundEditorHandlers.focus = this.onEditorFocus.bind(this);
103397
+ this.activeEditor.on("transaction", this._boundEditorHandlers.transaction);
103398
+ this.activeEditor.on("selectionUpdate", this._boundEditorHandlers.selectionUpdate);
103399
+ this.activeEditor.on("focus", this._boundEditorHandlers.focus);
103400
+ }
103128
103401
  }
103129
103402
  /**
103130
103403
  * Get toolbar items by group name
@@ -103272,15 +103545,28 @@ class SuperToolbar extends EventEmitter2 {
103272
103545
  * @returns {*} The result of the executed command, undefined if no result is returned
103273
103546
  */
103274
103547
  emitCommand({ item, argument, option }) {
103548
+ const hasFocusFn = this.activeEditor?.view?.hasFocus;
103549
+ const wasFocused = Boolean(typeof hasFocusFn === "function" && hasFocusFn.call(this.activeEditor.view));
103550
+ const { command: command2 } = item;
103551
+ const isMarkToggle = this.isMarkToggle(item);
103552
+ if (!wasFocused && isMarkToggle) {
103553
+ this.pendingMarkCommands.push({ command: command2, argument, item });
103554
+ item?.activate?.();
103555
+ if (this.activeEditor && !this.activeEditor.options.isHeaderOrFooter) {
103556
+ this.activeEditor.focus();
103557
+ }
103558
+ return;
103559
+ }
103275
103560
  if (this.activeEditor && !this.activeEditor.options.isHeaderOrFooter) {
103276
103561
  this.activeEditor.focus();
103277
103562
  }
103278
- const { command: command2 } = item;
103279
103563
  if (!command2) {
103280
103564
  return;
103281
103565
  }
103282
103566
  if (command2 in __privateGet(this, _interceptedCommands)) {
103283
- return __privateGet(this, _interceptedCommands)[command2]({ item, argument });
103567
+ const result = __privateGet(this, _interceptedCommands)[command2]({ item, argument });
103568
+ if (isMarkToggle) __privateMethod(this, _SuperToolbar_instances, syncStickyMarksFromState_fn).call(this);
103569
+ return result;
103284
103570
  }
103285
103571
  if (this.activeEditor && this.activeEditor.commands && command2 in this.activeEditor.commands) {
103286
103572
  this.activeEditor.commands[command2](argument);
@@ -103291,9 +103577,67 @@ class SuperToolbar extends EventEmitter2 {
103291
103577
  this.emit("exception", { error, editor: this.activeEditor });
103292
103578
  throw error;
103293
103579
  }
103580
+ if (isMarkToggle) __privateMethod(this, _SuperToolbar_instances, syncStickyMarksFromState_fn).call(this);
103294
103581
  this.updateToolbarState();
103295
103582
  }
103296
- }
103583
+ /**
103584
+ * Processes and executes pending mark commands when editor selection updates.
103585
+ * This is triggered by the editor's 'selectionUpdate' event after focus is restored.
103586
+ * Clears the pending queue after execution.
103587
+ * @returns {void}
103588
+ */
103589
+ onEditorSelectionUpdate() {
103590
+ if (!this.activeEditor) return;
103591
+ if (this.pendingMarkCommands.length) {
103592
+ const pending = this.pendingMarkCommands;
103593
+ this.pendingMarkCommands = [];
103594
+ pending.forEach(({ command: command2, argument, item }) => {
103595
+ if (!command2) return;
103596
+ try {
103597
+ if (command2 in __privateGet(this, _interceptedCommands)) {
103598
+ __privateGet(this, _interceptedCommands)[command2]({ item, argument });
103599
+ } else if (this.activeEditor.commands && command2 in this.activeEditor.commands) {
103600
+ this.activeEditor.commands[command2](argument);
103601
+ }
103602
+ __privateMethod(this, _SuperToolbar_instances, ensureStoredMarksForMarkToggle_fn).call(this, { command: command2, argument });
103603
+ } catch (error) {
103604
+ const err = new Error(`[super-toolbar 🎨] Failed to execute pending command: ${command2}`);
103605
+ this.emit("exception", { error: err, editor: this.activeEditor, originalError: error });
103606
+ console.error(err, error);
103607
+ }
103608
+ });
103609
+ __privateMethod(this, _SuperToolbar_instances, syncStickyMarksFromState_fn).call(this);
103610
+ this.updateToolbarState();
103611
+ return;
103612
+ }
103613
+ const restored = __privateMethod(this, _SuperToolbar_instances, restoreStickyMarksIfNeeded_fn).call(this);
103614
+ if (restored) this.updateToolbarState();
103615
+ }
103616
+ /**
103617
+ * Handles editor focus events by flushing any pending mark commands.
103618
+ * This is triggered by the editor's 'focus' event.
103619
+ * @returns {void}
103620
+ */
103621
+ onEditorFocus() {
103622
+ if (this.pendingMarkCommands.length) {
103623
+ this.onEditorSelectionUpdate();
103624
+ return;
103625
+ }
103626
+ const restored = __privateMethod(this, _SuperToolbar_instances, restoreStickyMarksIfNeeded_fn).call(this);
103627
+ if (restored) this.updateToolbarState();
103628
+ }
103629
+ /**
103630
+ * Determines if a toolbar item represents a mark toggle command.
103631
+ * Mark toggles include text formatting commands like bold, italic, underline, etc.
103632
+ * @param {ToolbarItem} item - The toolbar item to check
103633
+ * @returns {boolean} True if the item is a mark toggle, false otherwise
103634
+ */
103635
+ isMarkToggle(item) {
103636
+ const name = item?.name?.value;
103637
+ return __privateGet(_SuperToolbar2, _MARK_TOGGLE_NAMES).has(name);
103638
+ }
103639
+ };
103640
+ _MARK_TOGGLE_NAMES = /* @__PURE__ */ new WeakMap();
103297
103641
  _SuperToolbar_instances = /* @__PURE__ */ new WeakSet();
103298
103642
  initToolbarGroups_fn = function() {
103299
103643
  if (this.config.groups && !Array.isArray(this.config.groups) && Object.keys(this.config.groups).length) {
@@ -103406,6 +103750,55 @@ runCommandWithArgumentOnly_fn = function({ item, argument, noArgumentCallback =
103406
103750
  this.updateToolbarState();
103407
103751
  }
103408
103752
  };
103753
+ syncStickyMarksFromState_fn = function() {
103754
+ if (!this.activeEditor) return;
103755
+ const { selection, storedMarks } = this.activeEditor.state || {};
103756
+ if (!selection?.empty) return;
103757
+ this.stickyStoredMarks = storedMarks?.length ? [...storedMarks] : null;
103758
+ };
103759
+ restoreStickyMarksIfNeeded_fn = function() {
103760
+ if (!this.activeEditor) return false;
103761
+ if (!this.stickyStoredMarks?.length) return false;
103762
+ const { state: state2, view } = this.activeEditor;
103763
+ const { selection, storedMarks } = state2 || {};
103764
+ if (!selection?.empty) return false;
103765
+ if (storedMarks?.length) return false;
103766
+ if (!view?.dispatch || !state2?.tr) return false;
103767
+ const hasActiveMarkToggle = getActiveFormatting(this.activeEditor).some(
103768
+ (mark) => __privateGet(_SuperToolbar, _MARK_TOGGLE_NAMES).has(mark.name)
103769
+ );
103770
+ if (hasActiveMarkToggle) return false;
103771
+ const tr = state2.tr.setStoredMarks(this.stickyStoredMarks);
103772
+ view.dispatch(tr);
103773
+ return true;
103774
+ };
103775
+ ensureStoredMarksForMarkToggle_fn = function({ command: command2, argument }) {
103776
+ if (!this.activeEditor) return;
103777
+ if (!this.activeEditor.state?.selection?.empty) return;
103778
+ if (this.activeEditor.state?.storedMarks?.length) return;
103779
+ if (command2 !== "setFontSize") return;
103780
+ const { state: state2, view } = this.activeEditor;
103781
+ const textStyleMark = state2.schema?.marks?.textStyle;
103782
+ if (!textStyleMark || !view?.dispatch || !state2?.tr) return;
103783
+ const [value, unit] = parseSizeUnit(argument ?? "");
103784
+ if (Number.isNaN(value)) return;
103785
+ const clamped = Math.min(96, Math.max(8, Number(value)));
103786
+ const resolvedUnit = unit || "pt";
103787
+ const mark = textStyleMark.create({ fontSize: `${clamped}${resolvedUnit}` });
103788
+ const tr = state2.tr.setStoredMarks([mark]);
103789
+ view.dispatch(tr);
103790
+ };
103791
+ __privateAdd(_SuperToolbar, _MARK_TOGGLE_NAMES, /* @__PURE__ */ new Set([
103792
+ "bold",
103793
+ "italic",
103794
+ "underline",
103795
+ "strike",
103796
+ "highlight",
103797
+ "color",
103798
+ "fontSize",
103799
+ "fontFamily"
103800
+ ]));
103801
+ let SuperToolbar = _SuperToolbar;
103409
103802
  const onMarginClickCursorChange = (event, editor) => {
103410
103803
  const y2 = event.clientY;
103411
103804
  const x2 = event.clientX;