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
@@ -35580,7 +35580,7 @@ const _SuperConverter = class _SuperConverter2 {
35580
35580
  static getStoredSuperdocVersion(docx) {
35581
35581
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
35582
35582
  }
35583
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.2") {
35583
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.3") {
35584
35584
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
35585
35585
  }
35586
35586
  /**
@@ -38780,7 +38780,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
38780
38780
  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);
38781
38781
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
38782
38782
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
38783
- 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;
38783
+ 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;
38784
38784
  var GOOD_LEAF_SIZE = 200;
38785
38785
  var RopeSequence = function RopeSequence2() {
38786
38786
  };
@@ -52287,7 +52287,7 @@ const isHeadless = (editor) => {
52287
52287
  const shouldSkipNodeView = (editor) => {
52288
52288
  return isHeadless(editor);
52289
52289
  };
52290
- const summaryVersion = "1.0.0-beta.2";
52290
+ const summaryVersion = "1.0.0-beta.3";
52291
52291
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
52292
52292
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
52293
52293
  function mapAttributes(attrs) {
@@ -53066,7 +53066,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53066
53066
  { default: remarkStringify },
53067
53067
  { default: remarkGfm }
53068
53068
  ] = await Promise.all([
53069
- Promise.resolve().then(() => require("./index-Sn-JVHIg-BxOp3gSx.cjs")),
53069
+ Promise.resolve().then(() => require("./index-CJUy3fVi-BGLfCP5B.cjs")),
53070
53070
  Promise.resolve().then(() => require("./index-DRCvimau-H4Ck3S9a.cjs")),
53071
53071
  Promise.resolve().then(() => require("./index-C_x_N6Uh-Db3CUJMX.cjs")),
53072
53072
  Promise.resolve().then(() => require("./index-D_sWOSiG-BtDZzJ6I.cjs")),
@@ -53271,7 +53271,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
53271
53271
  * Process collaboration migrations
53272
53272
  */
53273
53273
  processCollaborationMigrations() {
53274
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.2");
53274
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.3");
53275
53275
  if (!this.options.ydoc) return;
53276
53276
  const metaMap = this.options.ydoc.getMap("meta");
53277
53277
  let docVersion = metaMap.get("version");
@@ -54890,6 +54890,50 @@ const resolveColorFromAttributes = (attrs, themeColors) => {
54890
54890
  }
54891
54891
  return void 0;
54892
54892
  };
54893
+ const MAX_DATA_ATTR_COUNT = 50;
54894
+ const MAX_DATA_ATTR_VALUE_LENGTH = 1e3;
54895
+ const MAX_DATA_ATTR_NAME_LENGTH = 100;
54896
+ const extractDataAttributes = (attrs) => {
54897
+ if (!attrs) return void 0;
54898
+ const result = {};
54899
+ let attrCount = 0;
54900
+ for (const [key2, value] of Object.entries(attrs)) {
54901
+ if (typeof key2 !== "string" || !key2.toLowerCase().startsWith("data-")) {
54902
+ continue;
54903
+ }
54904
+ if (attrCount >= MAX_DATA_ATTR_COUNT) {
54905
+ if (process$1$1.env.NODE_ENV === "development") {
54906
+ console.warn(`[PM-Adapter] Rejecting data attributes exceeding ${MAX_DATA_ATTR_COUNT} limit`);
54907
+ }
54908
+ break;
54909
+ }
54910
+ if (key2.length > MAX_DATA_ATTR_NAME_LENGTH) {
54911
+ if (process$1$1.env.NODE_ENV === "development") {
54912
+ console.warn(
54913
+ `[PM-Adapter] Rejecting data attribute name exceeding ${MAX_DATA_ATTR_NAME_LENGTH} chars: ${key2.substring(0, 50)}...`
54914
+ );
54915
+ }
54916
+ continue;
54917
+ }
54918
+ if (value == null) {
54919
+ continue;
54920
+ }
54921
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
54922
+ const stringValue = String(value);
54923
+ if (stringValue.length > MAX_DATA_ATTR_VALUE_LENGTH) {
54924
+ if (process$1$1.env.NODE_ENV === "development") {
54925
+ console.warn(
54926
+ `[PM-Adapter] Rejecting data attribute value exceeding ${MAX_DATA_ATTR_VALUE_LENGTH} chars for key: ${key2}`
54927
+ );
54928
+ }
54929
+ continue;
54930
+ }
54931
+ result[key2] = stringValue;
54932
+ attrCount++;
54933
+ }
54934
+ }
54935
+ return Object.keys(result).length > 0 ? result : void 0;
54936
+ };
54893
54937
  const normalizeRunMarkList = (value) => {
54894
54938
  if (!value) return void 0;
54895
54939
  let entries = value;
@@ -55069,11 +55113,9 @@ const applyTextStyleMark = (run2, attrs, themeColors) => {
55069
55113
  run2.fontFamily = sanitized;
55070
55114
  }
55071
55115
  }
55072
- if (isFiniteNumber(attrs.fontSize)) {
55073
- const size2 = Number(attrs.fontSize);
55074
- if (size2 >= 1 && size2 <= 1e3) {
55075
- run2.fontSize = size2;
55076
- }
55116
+ const fontSizeValue = pickNumber(attrs.fontSize);
55117
+ if (fontSizeValue !== void 0 && fontSizeValue >= 1 && fontSizeValue <= 1e3) {
55118
+ run2.fontSize = fontSizeValue;
55077
55119
  }
55078
55120
  if (isFiniteNumber(attrs.letterSpacing)) {
55079
55121
  const spacing = Number(attrs.letterSpacing);
@@ -55087,6 +55129,7 @@ const DEFAULT_HYPERLINK_CONFIG = {
55087
55129
  };
55088
55130
  const applyMarksToRun = (run2, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG, themeColors) => {
55089
55131
  marks.forEach((mark) => {
55132
+ const forwardedDataAttrs = extractDataAttributes(mark.attrs);
55090
55133
  try {
55091
55134
  switch (mark.type) {
55092
55135
  case TRACK_INSERT_MARK:
@@ -55181,6 +55224,9 @@ const applyMarksToRun = (run2, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG
55181
55224
  console.warn(`[PM-Adapter] Failed to apply mark ${mark.type}:`, error);
55182
55225
  }
55183
55226
  }
55227
+ if (forwardedDataAttrs) {
55228
+ run2.dataAttrs = { ...run2.dataAttrs ?? {}, ...forwardedDataAttrs };
55229
+ }
55184
55230
  });
55185
55231
  };
55186
55232
  function textNodeToRun(textNode, positions, defaultFont, defaultSize, inheritedMarks = [], sdtMetadata, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors) {
@@ -55204,8 +55250,9 @@ function tabNodeToRun(node, positions, tabIndex, paragraph) {
55204
55250
  const pos = positions.get(node);
55205
55251
  if (!pos) return null;
55206
55252
  const paragraphAttrs = paragraph.attrs ?? {};
55207
- const tabStops = Array.isArray(paragraphAttrs.tabStops) ? paragraphAttrs.tabStops : void 0;
55208
- const indent = paragraphAttrs.indent;
55253
+ const paragraphProps = typeof paragraphAttrs.paragraphProperties === "object" && paragraphAttrs.paragraphProperties !== null ? paragraphAttrs.paragraphProperties : {};
55254
+ const tabStops = Array.isArray(paragraphAttrs.tabStops) && paragraphAttrs.tabStops.length ? paragraphAttrs.tabStops : Array.isArray(paragraphProps.tabStops) ? paragraphProps.tabStops : void 0;
55255
+ const indent = paragraphAttrs.indent ?? paragraphProps.indent ?? void 0;
55209
55256
  return {
55210
55257
  kind: "tab",
55211
55258
  text: " ",
@@ -55519,6 +55566,9 @@ const normalizeParagraphSpacing = (value) => {
55519
55566
  const afterRaw = pickNumber(source.after);
55520
55567
  const lineRaw = pickNumber(source.line);
55521
55568
  const lineRule = normalizeLineRule(source.lineRule);
55569
+ const beforeAutospacing = toBooleanFlag(source.beforeAutospacing ?? source.beforeAutoSpacing);
55570
+ const afterAutospacing = toBooleanFlag(source.afterAutospacing ?? source.afterAutoSpacing);
55571
+ const contextualSpacing = toBooleanFlag(source.contextualSpacing);
55522
55572
  const before = beforeRaw != null ? twipsToPx$1(beforeRaw) : pickNumber(source.lineSpaceBefore);
55523
55573
  const after = afterRaw != null ? twipsToPx$1(afterRaw) : pickNumber(source.lineSpaceAfter);
55524
55574
  const line = normalizeLineValue(lineRaw, lineRule);
@@ -55526,8 +55576,24 @@ const normalizeParagraphSpacing = (value) => {
55526
55576
  if (after != null) spacing.after = after;
55527
55577
  if (line != null) spacing.line = line;
55528
55578
  if (lineRule) spacing.lineRule = lineRule;
55579
+ if (beforeAutospacing != null) spacing.beforeAutospacing = beforeAutospacing;
55580
+ if (afterAutospacing != null) spacing.afterAutospacing = afterAutospacing;
55581
+ if (contextualSpacing != null) spacing.contextualSpacing = contextualSpacing;
55529
55582
  return Object.keys(spacing).length > 0 ? spacing : void 0;
55530
55583
  };
55584
+ const toBooleanFlag = (value) => {
55585
+ if (value === true || value === false) return value;
55586
+ if (typeof value === "string") {
55587
+ const normalized = value.trim().toLowerCase();
55588
+ if (["true", "1", "on", "yes"].includes(normalized)) return true;
55589
+ if (["false", "0", "off", "no"].includes(normalized)) return false;
55590
+ }
55591
+ if (typeof value === "number") {
55592
+ if (value === 1) return true;
55593
+ if (value === 0) return false;
55594
+ }
55595
+ return void 0;
55596
+ };
55531
55597
  const normalizeLineValue = (value, lineRule) => {
55532
55598
  if (value == null) return void 0;
55533
55599
  if (lineRule === "auto") {
@@ -56900,15 +56966,17 @@ const hydrateParagraphStyleAttrs = (para, context, preResolved) => {
56900
56966
  return null;
56901
56967
  }
56902
56968
  const attrs = para.attrs ?? {};
56903
- const styleId = typeof attrs.styleId === "string" && attrs.styleId.trim() ? attrs.styleId : null;
56969
+ const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
56970
+ const styleIdSource = attrs.styleId ?? paragraphProps.styleId;
56971
+ const styleId = typeof styleIdSource === "string" && styleIdSource.trim() ? styleIdSource : null;
56904
56972
  if (!styleId) {
56905
56973
  return null;
56906
56974
  }
56907
56975
  const inlineProps = {
56908
56976
  styleId,
56909
- numberingProperties: cloneIfObject(attrs.numberingProperties),
56910
- indent: cloneIfObject(attrs.indent),
56911
- spacing: cloneIfObject(attrs.spacing)
56977
+ numberingProperties: cloneIfObject(attrs.numberingProperties ?? paragraphProps.numberingProperties),
56978
+ indent: cloneIfObject(attrs.indent ?? paragraphProps.indent),
56979
+ spacing: cloneIfObject(attrs.spacing ?? paragraphProps.spacing)
56912
56980
  };
56913
56981
  const resolverParams = {
56914
56982
  docx: context.docx,
@@ -57186,13 +57254,17 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
57186
57254
  };
57187
57255
  const computeParagraphAttrs = (para, styleContext, listCounterContext, converterContext, hydrationOverride) => {
57188
57256
  const attrs = para.attrs ?? {};
57257
+ const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
57189
57258
  const hydrated = hydrationOverride ?? hydrateParagraphStyleAttrs(para, converterContext);
57190
- const spacingSource = attrs.spacing !== void 0 ? attrs.spacing : hydrated?.spacing;
57259
+ const spacingSource = attrs.spacing !== void 0 ? attrs.spacing : paragraphProps.spacing !== void 0 ? paragraphProps.spacing : hydrated?.spacing;
57191
57260
  const normalizedSpacing = normalizeParagraphSpacing(spacingSource);
57192
- const indentSource = attrs.indent ?? hydrated?.indent;
57261
+ const indentSource = attrs.indent ?? paragraphProps.indent ?? hydrated?.indent;
57193
57262
  const normalizedIndent = normalizePxIndent(indentSource) ?? normalizeParagraphIndent(indentSource ?? attrs.textIndent);
57194
- const styleNodeAttrs = hydrated?.tabStops && !attrs.tabStops && !attrs.tabs ? { ...attrs, tabStops: hydrated.tabStops } : attrs;
57263
+ const styleNodeAttrs = hydrated?.tabStops && !attrs.tabStops && !attrs.tabs ? { ...attrs, tabStops: hydrated.tabStops } : !attrs.tabStops && paragraphProps.tabStops ? { ...attrs, tabStops: paragraphProps.tabStops } : attrs;
57195
57264
  const styleNode = buildStyleNodeFromAttrs(styleNodeAttrs, normalizedSpacing, normalizedIndent);
57265
+ if (styleNodeAttrs.styleId == null && paragraphProps.styleId) {
57266
+ styleNode.styleId = paragraphProps.styleId;
57267
+ }
57196
57268
  const computed2 = resolveStyle(styleNode, styleContext);
57197
57269
  const { spacing, indent } = resolveSpacingIndent(computed2.paragraph, computed2.numbering);
57198
57270
  const paragraphAttrs = {};
@@ -57217,6 +57289,18 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
57217
57289
  }
57218
57290
  const spacingPx = spacingPtToPx(spacing, normalizedSpacing);
57219
57291
  if (spacingPx) paragraphAttrs.spacing = spacingPx;
57292
+ if (normalizedSpacing?.beforeAutospacing != null || normalizedSpacing?.afterAutospacing != null) {
57293
+ paragraphAttrs.spacing = paragraphAttrs.spacing ?? {};
57294
+ if (normalizedSpacing?.beforeAutospacing != null) {
57295
+ paragraphAttrs.spacing.beforeAutospacing = normalizedSpacing.beforeAutospacing;
57296
+ }
57297
+ if (normalizedSpacing?.afterAutospacing != null) {
57298
+ paragraphAttrs.spacing.afterAutospacing = normalizedSpacing.afterAutospacing;
57299
+ }
57300
+ }
57301
+ if (normalizedSpacing?.contextualSpacing != null) {
57302
+ paragraphAttrs.contextualSpacing = normalizedSpacing.contextualSpacing;
57303
+ }
57220
57304
  const hasExplicitIndent = Boolean(normalizedIndent);
57221
57305
  const hasNumberingIndent = Boolean(computed2.numbering?.indent?.left || computed2.numbering?.indent?.hanging);
57222
57306
  if (hasExplicitIndent || hasNumberingIndent || bidi && adjustRightInd) {
@@ -57235,10 +57319,20 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
57235
57319
  if (borders) paragraphAttrs.borders = borders;
57236
57320
  const shading = normalizeParagraphShading(attrs.shading ?? hydrated?.shading);
57237
57321
  if (shading) paragraphAttrs.shading = shading;
57322
+ const keepNext = paragraphProps.keepNext ?? hydrated?.keepNext ?? attrs.keepNext;
57323
+ if (keepNext === true) paragraphAttrs.keepNext = true;
57324
+ const keepLines = paragraphProps.keepLines ?? hydrated?.keepLines ?? attrs.keepLines;
57325
+ if (keepLines === true) paragraphAttrs.keepLines = true;
57238
57326
  const paragraphDecimalSeparator = styleContext.defaults?.decimalSeparator ?? DEFAULT_DECIMAL_SEPARATOR$2;
57239
57327
  if (paragraphDecimalSeparator !== DEFAULT_DECIMAL_SEPARATOR$2) {
57240
57328
  paragraphAttrs.decimalSeparator = paragraphDecimalSeparator;
57241
57329
  }
57330
+ const styleIdAttr = typeof attrs.styleId === "string" ? attrs.styleId : void 0;
57331
+ if (styleIdAttr) {
57332
+ paragraphAttrs.styleId = styleIdAttr;
57333
+ } else if (paragraphProps.styleId) {
57334
+ paragraphAttrs.styleId = paragraphProps.styleId;
57335
+ }
57242
57336
  const paraIntervalTwips = pickNumber(attrs.tabIntervalTwips) ?? (() => {
57243
57337
  const px = pickNumber(attrs.tabIntervalPx);
57244
57338
  return px != null ? Math.round(px * 15) : void 0;
@@ -57275,7 +57369,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
57275
57369
  paragraphAttrs.floatAlignment = xAlign;
57276
57370
  }
57277
57371
  }
57278
- const numberingSource = attrs.numberingProperties ?? hydrated?.numberingProperties;
57372
+ const numberingSource = attrs.numberingProperties ?? paragraphProps.numberingProperties ?? hydrated?.numberingProperties;
57279
57373
  const rawNumberingProps = toAdapterNumberingProps(numberingSource);
57280
57374
  if (rawNumberingProps) {
57281
57375
  const numberingProps = rawNumberingProps;
@@ -57928,13 +58022,29 @@ const extractRunStyleId = (runProperties) => {
57928
58022
  return null;
57929
58023
  };
57930
58024
  const isTextRun$1 = (run2) => run2.kind !== "tab";
58025
+ const dataAttrsCompatible = (a, b2) => {
58026
+ const aAttrs = a.dataAttrs;
58027
+ const bAttrs = b2.dataAttrs;
58028
+ if (!aAttrs && !bAttrs) return true;
58029
+ if (!aAttrs || !bAttrs) return false;
58030
+ const aKeys = Object.keys(aAttrs).sort();
58031
+ const bKeys = Object.keys(bAttrs).sort();
58032
+ if (aKeys.length !== bKeys.length) return false;
58033
+ for (let i = 0; i < aKeys.length; i++) {
58034
+ const key2 = aKeys[i];
58035
+ if (key2 !== bKeys[i] || aAttrs[key2] !== bAttrs[key2]) {
58036
+ return false;
58037
+ }
58038
+ }
58039
+ return true;
58040
+ };
57931
58041
  function mergeAdjacentRuns(runs) {
57932
58042
  if (runs.length <= 1) return runs;
57933
58043
  const merged = [];
57934
58044
  let current = runs[0];
57935
58045
  for (let i = 1; i < runs.length; i++) {
57936
58046
  const next = runs[i];
57937
- 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);
58047
+ 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);
57938
58048
  if (canMerge) {
57939
58049
  const currText = current.text ?? "";
57940
58050
  const nextText = next.text ?? "";
@@ -57951,10 +58061,62 @@ function mergeAdjacentRuns(runs) {
57951
58061
  merged.push(current);
57952
58062
  return merged;
57953
58063
  }
58064
+ const applyBaseRunDefaults = (run2, defaults, fallbackFont, fallbackSize) => {
58065
+ if (!run2) return;
58066
+ if (defaults.fontFamily && run2.fontFamily === fallbackFont) {
58067
+ run2.fontFamily = defaults.fontFamily;
58068
+ }
58069
+ if (defaults.fontSizePx != null && run2.fontSize === fallbackSize) {
58070
+ run2.fontSize = defaults.fontSizePx;
58071
+ }
58072
+ if (defaults.color && !run2.color) {
58073
+ run2.color = defaults.color;
58074
+ }
58075
+ if (defaults.letterSpacing != null && run2.letterSpacing == null) {
58076
+ run2.letterSpacing = defaults.letterSpacing;
58077
+ }
58078
+ if (defaults.bold && run2.bold === void 0) {
58079
+ run2.bold = true;
58080
+ }
58081
+ if (defaults.italic && run2.italic === void 0) {
58082
+ run2.italic = true;
58083
+ }
58084
+ if (defaults.underline && !run2.underline) {
58085
+ run2.underline = defaults.underline;
58086
+ }
58087
+ };
57954
58088
  function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converters, converterContext) {
57955
58089
  const baseBlockId = nextBlockId("paragraph");
57956
- const paragraphStyleId = typeof para.attrs?.styleId === "string" ? para.attrs.styleId : null;
58090
+ const paragraphProps = typeof para.attrs?.paragraphProperties === "object" && para.attrs.paragraphProperties !== null ? para.attrs.paragraphProperties : {};
58091
+ const paragraphStyleId = typeof para.attrs?.styleId === "string" && para.attrs.styleId.trim() ? para.attrs.styleId : typeof paragraphProps.styleId === "string" && paragraphProps.styleId.trim() ? paragraphProps.styleId : null;
57957
58092
  const paragraphHydration = converterContext ? hydrateParagraphStyleAttrs(para, converterContext) : null;
58093
+ let baseRunDefaults = {};
58094
+ try {
58095
+ const spacingSource = para.attrs?.spacing !== void 0 ? para.attrs.spacing : paragraphProps.spacing !== void 0 ? paragraphProps.spacing : paragraphHydration?.spacing;
58096
+ const indentSource = para.attrs?.indent ?? paragraphProps.indent ?? paragraphHydration?.indent;
58097
+ const normalizedSpacing = normalizeParagraphSpacing(spacingSource);
58098
+ const normalizedIndent = normalizePxIndent(indentSource) ?? normalizeParagraphIndent(indentSource ?? para.attrs?.textIndent);
58099
+ const styleNodeAttrs = paragraphHydration?.tabStops && !para.attrs?.tabStops && !para.attrs?.tabs ? { ...para.attrs ?? {}, tabStops: paragraphHydration.tabStops } : para.attrs ?? {};
58100
+ const styleNode = buildStyleNodeFromAttrs(styleNodeAttrs, normalizedSpacing, normalizedIndent);
58101
+ if (styleNodeAttrs.styleId == null && paragraphProps.styleId) {
58102
+ styleNode.styleId = paragraphProps.styleId;
58103
+ }
58104
+ const resolved = resolveStyle(styleNode, styleContext);
58105
+ baseRunDefaults = {
58106
+ fontFamily: resolved.character.font?.family,
58107
+ fontSizePx: ptToPx(resolved.character.font?.size),
58108
+ color: resolved.character.color,
58109
+ bold: resolved.character.font?.weight != null ? resolved.character.font.weight >= 600 : void 0,
58110
+ italic: resolved.character.font?.italic,
58111
+ underline: resolved.character.underline ? {
58112
+ style: resolved.character.underline.style,
58113
+ color: resolved.character.underline.color
58114
+ } : void 0,
58115
+ letterSpacing: ptToPx(resolved.character.letterSpacing)
58116
+ };
58117
+ } catch {
58118
+ baseRunDefaults = {};
58119
+ }
57958
58120
  const paragraphAttrs = computeParagraphAttrs(
57959
58121
  para,
57960
58122
  styleContext,
@@ -57962,6 +58124,18 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
57962
58124
  converterContext,
57963
58125
  paragraphHydration
57964
58126
  );
58127
+ if (paragraphAttrs?.spacing) {
58128
+ const spacing = { ...paragraphAttrs.spacing };
58129
+ const effectiveFontSize = baseRunDefaults.fontSizePx ?? defaultSize;
58130
+ const isList2 = Boolean(paragraphAttrs.numberingProperties);
58131
+ if (spacing.beforeAutospacing) {
58132
+ spacing.before = isList2 ? 0 : Math.max(0, Number(spacing.before ?? 0) + effectiveFontSize * 0.5);
58133
+ }
58134
+ if (spacing.afterAutospacing) {
58135
+ spacing.after = isList2 ? 0 : Math.max(0, Number(spacing.after ?? 0) + effectiveFontSize * 0.5);
58136
+ }
58137
+ paragraphAttrs.spacing = spacing;
58138
+ }
57965
58139
  const linkedStyleResolver = createLinkedStyleResolver(converterContext?.linkedStyles);
57966
58140
  const blocks = [];
57967
58141
  if (hasPageBreakBefore(para)) {
@@ -58039,6 +58213,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58039
58213
  );
58040
58214
  const inlineStyleId = getInlineStyleId(inheritedMarks);
58041
58215
  applyRunStyles2(run2, inlineStyleId, activeRunStyleId);
58216
+ applyBaseRunDefaults(run2, baseRunDefaults, defaultFont, defaultSize);
58042
58217
  currentRuns.push(run2);
58043
58218
  return;
58044
58219
  }
@@ -58074,6 +58249,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58074
58249
  );
58075
58250
  const inlineStyleId = getInlineStyleId(inheritedMarks);
58076
58251
  applyRunStyles2(run2, inlineStyleId, activeRunStyleId);
58252
+ applyBaseRunDefaults(run2, baseRunDefaults, defaultFont, defaultSize);
58077
58253
  currentRuns.push(run2);
58078
58254
  }
58079
58255
  }
@@ -58111,6 +58287,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58111
58287
  );
58112
58288
  const inlineStyleId = getInlineStyleId(mergedMarks);
58113
58289
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
58290
+ applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
58114
58291
  if (pageRefPos) {
58115
58292
  tokenRun.pmStart = pageRefPos.start;
58116
58293
  tokenRun.pmEnd = pageRefPos.end;
@@ -58169,6 +58346,7 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
58169
58346
  }
58170
58347
  const inlineStyleId = getInlineStyleId(inheritedMarks);
58171
58348
  applyRunStyles2(tokenRun, inlineStyleId, activeRunStyleId);
58349
+ applyBaseRunDefaults(tokenRun, baseRunDefaults, defaultFont, defaultSize);
58172
58350
  currentRuns.push(tokenRun);
58173
58351
  }
58174
58352
  return;
@@ -60197,7 +60375,9 @@ function layoutParagraphBlock(ctx2, anchors) {
60197
60375
  let lines = normalizeLines(measure);
60198
60376
  let fromLine = 0;
60199
60377
  const spacing = block.attrs?.spacing ?? {};
60200
- const spacingBefore = Math.max(0, Number(spacing.before ?? spacing.lineSpaceBefore ?? 0));
60378
+ const styleId = block.attrs?.styleId;
60379
+ const contextualSpacing = Boolean(block.attrs?.contextualSpacing);
60380
+ let spacingBefore = Math.max(0, Number(spacing.before ?? spacing.lineSpaceBefore ?? 0));
60201
60381
  const spacingAfter = Math.max(0, Number(spacing.after ?? spacing.lineSpaceAfter ?? 0));
60202
60382
  let appliedSpacingBefore = spacingBefore === 0;
60203
60383
  let lastState = null;
@@ -60213,6 +60393,15 @@ function layoutParagraphBlock(ctx2, anchors) {
60213
60393
  while (fromLine < lines.length) {
60214
60394
  let state2 = ensurePage();
60215
60395
  if (state2.trailingSpacing == null) state2.trailingSpacing = 0;
60396
+ if (contextualSpacing) {
60397
+ const prevStyle = state2.lastParagraphStyleId;
60398
+ if (styleId && prevStyle && prevStyle === styleId) {
60399
+ spacingBefore = 0;
60400
+ }
60401
+ }
60402
+ if (contextualSpacing && state2.lastParagraphStyleId && styleId && state2.lastParagraphStyleId === styleId) {
60403
+ spacingBefore = 0;
60404
+ }
60216
60405
  if (!appliedSpacingBefore && spacingBefore > 0) {
60217
60406
  while (!appliedSpacingBefore) {
60218
60407
  const prevTrailing = state2.trailingSpacing ?? 0;
@@ -60381,6 +60570,7 @@ function layoutParagraphBlock(ctx2, anchors) {
60381
60570
  } else {
60382
60571
  lastState.trailingSpacing = 0;
60383
60572
  }
60573
+ lastState.lastParagraphStyleId = styleId;
60384
60574
  }
60385
60575
  }
60386
60576
  function layoutImageBlock({
@@ -60619,7 +60809,8 @@ function createPaginator(opts) {
60619
60809
  contentBottom,
60620
60810
  constraintBoundaries: [],
60621
60811
  activeConstraintIndex: -1,
60622
- trailingSpacing: 0
60812
+ trailingSpacing: 0,
60813
+ lastParagraphStyleId: void 0
60623
60814
  };
60624
60815
  states.push(state2);
60625
60816
  pages.push(state2.page);
@@ -60641,6 +60832,7 @@ function createPaginator(opts) {
60641
60832
  state2.cursorY = state2.topMargin;
60642
60833
  }
60643
60834
  state2.trailingSpacing = 0;
60835
+ state2.lastParagraphStyleId = void 0;
60644
60836
  return state2;
60645
60837
  }
60646
60838
  return startNewPage();
@@ -65792,147 +65984,162 @@ const _DomPainter = class _DomPainter2 {
65792
65984
  return el;
65793
65985
  }
65794
65986
  renderListItemFragment(fragment, context) {
65795
- const lookup2 = this.blockLookup.get(fragment.blockId);
65796
- if (!lookup2 || lookup2.block.kind !== "list" || lookup2.measure.kind !== "list") {
65797
- throw new Error(`DomPainter: missing list data for fragment ${fragment.blockId}`);
65798
- }
65799
- if (!this.doc) {
65800
- throw new Error("DomPainter: document is not available");
65987
+ try {
65988
+ const lookup2 = this.blockLookup.get(fragment.blockId);
65989
+ if (!lookup2 || lookup2.block.kind !== "list" || lookup2.measure.kind !== "list") {
65990
+ throw new Error(`DomPainter: missing list data for fragment ${fragment.blockId}`);
65991
+ }
65992
+ if (!this.doc) {
65993
+ throw new Error("DomPainter: document is not available");
65994
+ }
65995
+ const block = lookup2.block;
65996
+ const measure = lookup2.measure;
65997
+ const item = block.items.find((entry) => entry.id === fragment.itemId);
65998
+ const itemMeasure = measure.items.find((entry) => entry.itemId === fragment.itemId);
65999
+ if (!item || !itemMeasure) {
66000
+ throw new Error(`DomPainter: missing list item ${fragment.itemId}`);
66001
+ }
66002
+ const fragmentEl = this.doc.createElement("div");
66003
+ fragmentEl.classList.add(CLASS_NAMES.fragment, `${CLASS_NAMES.fragment}-list-item`);
66004
+ applyStyles$2(fragmentEl, fragmentStyles);
66005
+ fragmentEl.style.left = `${fragment.x - fragment.markerWidth}px`;
66006
+ fragmentEl.style.top = `${fragment.y}px`;
66007
+ fragmentEl.style.width = `${fragment.markerWidth + fragment.width}px`;
66008
+ fragmentEl.dataset.blockId = fragment.blockId;
66009
+ fragmentEl.dataset.itemId = fragment.itemId;
66010
+ const paragraphMetadata = item.paragraph.attrs?.sdt;
66011
+ this.applySdtDataset(fragmentEl, paragraphMetadata);
66012
+ if (fragment.continuesFromPrev) {
66013
+ fragmentEl.dataset.continuesFromPrev = "true";
66014
+ }
66015
+ if (fragment.continuesOnNext) {
66016
+ fragmentEl.dataset.continuesOnNext = "true";
66017
+ }
66018
+ const markerEl = this.doc.createElement("span");
66019
+ markerEl.classList.add("superdoc-list-marker");
66020
+ const wordLayout = item.paragraph.attrs?.wordLayout;
66021
+ if (wordLayout?.marker) {
66022
+ const marker = wordLayout.marker;
66023
+ markerEl.textContent = marker.markerText;
66024
+ markerEl.style.display = "inline-block";
66025
+ markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
66026
+ markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
66027
+ markerEl.style.textAlign = marker.justification;
66028
+ markerEl.style.fontFamily = marker.run.fontFamily;
66029
+ markerEl.style.fontSize = `${marker.run.fontSize}px`;
66030
+ if (marker.run.bold) markerEl.style.fontWeight = "bold";
66031
+ if (marker.run.italic) markerEl.style.fontStyle = "italic";
66032
+ if (marker.run.color) markerEl.style.color = marker.run.color;
66033
+ if (marker.run.letterSpacing) markerEl.style.letterSpacing = `${marker.run.letterSpacing}px`;
66034
+ } else {
66035
+ markerEl.textContent = item.marker.text;
66036
+ markerEl.style.display = "inline-block";
66037
+ markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
66038
+ markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
66039
+ if (item.marker.align) {
66040
+ markerEl.style.textAlign = item.marker.align;
66041
+ }
66042
+ }
66043
+ fragmentEl.appendChild(markerEl);
66044
+ const contentEl = this.doc.createElement("div");
66045
+ contentEl.classList.add("superdoc-list-content");
66046
+ this.applySdtDataset(contentEl, paragraphMetadata);
66047
+ contentEl.style.display = "inline-block";
66048
+ contentEl.style.width = `${fragment.width}px`;
66049
+ const lines = itemMeasure.paragraph.lines.slice(fragment.fromLine, fragment.toLine);
66050
+ const contentAttrs = wordLayout ? item.paragraph.attrs : stripListIndent(item.paragraph.attrs);
66051
+ applyParagraphBlockStyles(contentEl, contentAttrs);
66052
+ lines.forEach((line) => {
66053
+ const lineEl = this.renderLine(item.paragraph, line, context);
66054
+ contentEl.appendChild(lineEl);
66055
+ });
66056
+ fragmentEl.appendChild(contentEl);
66057
+ return fragmentEl;
66058
+ } catch (error) {
66059
+ console.error("[DomPainter] List item fragment rendering failed:", { fragment, error });
66060
+ return this.createErrorPlaceholder(fragment.blockId, error);
65801
66061
  }
65802
- const block = lookup2.block;
65803
- const measure = lookup2.measure;
65804
- const item = block.items.find((entry) => entry.id === fragment.itemId);
65805
- const itemMeasure = measure.items.find((entry) => entry.itemId === fragment.itemId);
65806
- if (!item || !itemMeasure) {
65807
- throw new Error(`DomPainter: missing list item ${fragment.itemId}`);
65808
- }
65809
- const fragmentEl = this.doc.createElement("div");
65810
- fragmentEl.classList.add(CLASS_NAMES.fragment, `${CLASS_NAMES.fragment}-list-item`);
65811
- applyStyles$2(fragmentEl, fragmentStyles);
65812
- fragmentEl.style.left = `${fragment.x - fragment.markerWidth}px`;
65813
- fragmentEl.style.top = `${fragment.y}px`;
65814
- fragmentEl.style.width = `${fragment.markerWidth + fragment.width}px`;
65815
- fragmentEl.dataset.blockId = fragment.blockId;
65816
- fragmentEl.dataset.itemId = fragment.itemId;
65817
- const paragraphMetadata = item.paragraph.attrs?.sdt;
65818
- this.applySdtDataset(fragmentEl, paragraphMetadata);
65819
- if (fragment.continuesFromPrev) {
65820
- fragmentEl.dataset.continuesFromPrev = "true";
65821
- }
65822
- if (fragment.continuesOnNext) {
65823
- fragmentEl.dataset.continuesOnNext = "true";
65824
- }
65825
- const markerEl = this.doc.createElement("span");
65826
- markerEl.classList.add("superdoc-list-marker");
65827
- const wordLayout = item.paragraph.attrs?.wordLayout;
65828
- if (wordLayout?.marker) {
65829
- const marker = wordLayout.marker;
65830
- markerEl.textContent = marker.markerText;
65831
- markerEl.style.display = "inline-block";
65832
- markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
65833
- markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
65834
- markerEl.style.textAlign = marker.justification;
65835
- markerEl.style.fontFamily = marker.run.fontFamily;
65836
- markerEl.style.fontSize = `${marker.run.fontSize}px`;
65837
- if (marker.run.bold) markerEl.style.fontWeight = "bold";
65838
- if (marker.run.italic) markerEl.style.fontStyle = "italic";
65839
- if (marker.run.color) markerEl.style.color = marker.run.color;
65840
- if (marker.run.letterSpacing) markerEl.style.letterSpacing = `${marker.run.letterSpacing}px`;
65841
- } else {
65842
- markerEl.textContent = item.marker.text;
65843
- markerEl.style.display = "inline-block";
65844
- markerEl.style.width = `${Math.max(0, fragment.markerWidth - LIST_MARKER_GAP$1)}px`;
65845
- markerEl.style.paddingRight = `${LIST_MARKER_GAP$1}px`;
65846
- if (item.marker.align) {
65847
- markerEl.style.textAlign = item.marker.align;
65848
- }
65849
- }
65850
- fragmentEl.appendChild(markerEl);
65851
- const contentEl = this.doc.createElement("div");
65852
- contentEl.classList.add("superdoc-list-content");
65853
- this.applySdtDataset(contentEl, paragraphMetadata);
65854
- contentEl.style.display = "inline-block";
65855
- contentEl.style.width = `${fragment.width}px`;
65856
- const lines = itemMeasure.paragraph.lines.slice(fragment.fromLine, fragment.toLine);
65857
- const contentAttrs = wordLayout ? item.paragraph.attrs : stripListIndent(item.paragraph.attrs);
65858
- applyParagraphBlockStyles(contentEl, contentAttrs);
65859
- lines.forEach((line) => {
65860
- const lineEl = this.renderLine(item.paragraph, line, context);
65861
- contentEl.appendChild(lineEl);
65862
- });
65863
- fragmentEl.appendChild(contentEl);
65864
- return fragmentEl;
65865
66062
  }
65866
66063
  renderImageFragment(fragment) {
65867
- const lookup2 = this.blockLookup.get(fragment.blockId);
65868
- if (!lookup2 || lookup2.block.kind !== "image" || lookup2.measure.kind !== "image") {
65869
- throw new Error(`DomPainter: missing image block for fragment ${fragment.blockId}`);
65870
- }
65871
- if (!this.doc) {
65872
- throw new Error("DomPainter: document is not available");
65873
- }
65874
- const block = lookup2.block;
65875
- const fragmentEl = this.doc.createElement("div");
65876
- fragmentEl.classList.add(CLASS_NAMES.fragment);
65877
- applyStyles$2(fragmentEl, fragmentStyles);
65878
- this.applyFragmentFrame(fragmentEl, fragment);
65879
- fragmentEl.style.height = `${fragment.height}px`;
65880
- this.applySdtDataset(fragmentEl, block.attrs?.sdt);
65881
- this.applyContainerSdtDataset(fragmentEl, block.attrs?.containerSdt);
65882
- if (fragment.isAnchored && fragment.zIndex != null) {
65883
- fragmentEl.style.zIndex = String(fragment.zIndex);
65884
- }
65885
- const img = this.doc.createElement("img");
65886
- if (block.src) {
65887
- img.src = block.src;
66064
+ try {
66065
+ const lookup2 = this.blockLookup.get(fragment.blockId);
66066
+ if (!lookup2 || lookup2.block.kind !== "image" || lookup2.measure.kind !== "image") {
66067
+ throw new Error(`DomPainter: missing image block for fragment ${fragment.blockId}`);
66068
+ }
66069
+ if (!this.doc) {
66070
+ throw new Error("DomPainter: document is not available");
66071
+ }
66072
+ const block = lookup2.block;
66073
+ const fragmentEl = this.doc.createElement("div");
66074
+ fragmentEl.classList.add(CLASS_NAMES.fragment);
66075
+ applyStyles$2(fragmentEl, fragmentStyles);
66076
+ this.applyFragmentFrame(fragmentEl, fragment);
66077
+ fragmentEl.style.height = `${fragment.height}px`;
66078
+ this.applySdtDataset(fragmentEl, block.attrs?.sdt);
66079
+ this.applyContainerSdtDataset(fragmentEl, block.attrs?.containerSdt);
66080
+ if (fragment.isAnchored && fragment.zIndex != null) {
66081
+ fragmentEl.style.zIndex = String(fragment.zIndex);
66082
+ }
66083
+ const img = this.doc.createElement("img");
66084
+ if (block.src) {
66085
+ img.src = block.src;
66086
+ }
66087
+ img.alt = block.alt ?? "";
66088
+ img.style.width = "100%";
66089
+ img.style.height = "100%";
66090
+ img.style.objectFit = block.objectFit ?? "contain";
66091
+ img.style.display = block.display === "inline" ? "inline-block" : "block";
66092
+ fragmentEl.appendChild(img);
66093
+ return fragmentEl;
66094
+ } catch (error) {
66095
+ console.error("[DomPainter] Image fragment rendering failed:", { fragment, error });
66096
+ return this.createErrorPlaceholder(fragment.blockId, error);
65888
66097
  }
65889
- img.alt = block.alt ?? "";
65890
- img.style.width = "100%";
65891
- img.style.height = "100%";
65892
- img.style.objectFit = block.objectFit ?? "contain";
65893
- img.style.display = block.display === "inline" ? "inline-block" : "block";
65894
- fragmentEl.appendChild(img);
65895
- return fragmentEl;
65896
66098
  }
65897
66099
  renderDrawingFragment(fragment) {
65898
- const lookup2 = this.blockLookup.get(fragment.blockId);
65899
- if (!lookup2 || lookup2.block.kind !== "drawing" || lookup2.measure.kind !== "drawing") {
65900
- throw new Error(`DomPainter: missing drawing block for fragment ${fragment.blockId}`);
65901
- }
65902
- if (!this.doc) {
65903
- throw new Error("DomPainter: document is not available");
66100
+ try {
66101
+ const lookup2 = this.blockLookup.get(fragment.blockId);
66102
+ if (!lookup2 || lookup2.block.kind !== "drawing" || lookup2.measure.kind !== "drawing") {
66103
+ throw new Error(`DomPainter: missing drawing block for fragment ${fragment.blockId}`);
66104
+ }
66105
+ if (!this.doc) {
66106
+ throw new Error("DomPainter: document is not available");
66107
+ }
66108
+ const block = lookup2.block;
66109
+ const isVectorShapeBlock = block.kind === "drawing" && block.drawingKind === "vectorShape";
66110
+ const fragmentEl = this.doc.createElement("div");
66111
+ fragmentEl.classList.add(CLASS_NAMES.fragment, "superdoc-drawing-fragment");
66112
+ applyStyles$2(fragmentEl, fragmentStyles);
66113
+ this.applyFragmentFrame(fragmentEl, fragment);
66114
+ fragmentEl.style.height = `${fragment.height}px`;
66115
+ fragmentEl.style.position = "absolute";
66116
+ if (fragment.isAnchored && fragment.zIndex != null) {
66117
+ fragmentEl.style.zIndex = String(fragment.zIndex);
66118
+ }
66119
+ const innerWrapper = this.doc.createElement("div");
66120
+ innerWrapper.classList.add("superdoc-drawing-inner");
66121
+ innerWrapper.style.position = "absolute";
66122
+ innerWrapper.style.left = "50%";
66123
+ innerWrapper.style.top = "50%";
66124
+ innerWrapper.style.width = `${fragment.geometry.width}px`;
66125
+ innerWrapper.style.height = `${fragment.geometry.height}px`;
66126
+ innerWrapper.style.transformOrigin = "center";
66127
+ const scale = fragment.scale ?? 1;
66128
+ const transforms = ["translate(-50%, -50%)"];
66129
+ if (!isVectorShapeBlock) {
66130
+ transforms.push(`rotate(${fragment.geometry.rotation ?? 0}deg)`);
66131
+ transforms.push(`scaleX(${fragment.geometry.flipH ? -1 : 1})`);
66132
+ transforms.push(`scaleY(${fragment.geometry.flipV ? -1 : 1})`);
66133
+ }
66134
+ transforms.push(`scale(${scale})`);
66135
+ innerWrapper.style.transform = transforms.join(" ");
66136
+ innerWrapper.appendChild(this.renderDrawingContent(block, fragment));
66137
+ fragmentEl.appendChild(innerWrapper);
66138
+ return fragmentEl;
66139
+ } catch (error) {
66140
+ console.error("[DomPainter] Drawing fragment rendering failed:", { fragment, error });
66141
+ return this.createErrorPlaceholder(fragment.blockId, error);
65904
66142
  }
65905
- const block = lookup2.block;
65906
- const isVectorShapeBlock = block.kind === "drawing" && block.drawingKind === "vectorShape";
65907
- const fragmentEl = this.doc.createElement("div");
65908
- fragmentEl.classList.add(CLASS_NAMES.fragment, "superdoc-drawing-fragment");
65909
- applyStyles$2(fragmentEl, fragmentStyles);
65910
- this.applyFragmentFrame(fragmentEl, fragment);
65911
- fragmentEl.style.height = `${fragment.height}px`;
65912
- fragmentEl.style.position = "absolute";
65913
- if (fragment.isAnchored && fragment.zIndex != null) {
65914
- fragmentEl.style.zIndex = String(fragment.zIndex);
65915
- }
65916
- const innerWrapper = this.doc.createElement("div");
65917
- innerWrapper.classList.add("superdoc-drawing-inner");
65918
- innerWrapper.style.position = "absolute";
65919
- innerWrapper.style.left = "50%";
65920
- innerWrapper.style.top = "50%";
65921
- innerWrapper.style.width = `${fragment.geometry.width}px`;
65922
- innerWrapper.style.height = `${fragment.geometry.height}px`;
65923
- innerWrapper.style.transformOrigin = "center";
65924
- const scale = fragment.scale ?? 1;
65925
- const transforms = ["translate(-50%, -50%)"];
65926
- if (!isVectorShapeBlock) {
65927
- transforms.push(`rotate(${fragment.geometry.rotation ?? 0}deg)`);
65928
- transforms.push(`scaleX(${fragment.geometry.flipH ? -1 : 1})`);
65929
- transforms.push(`scaleY(${fragment.geometry.flipV ? -1 : 1})`);
65930
- }
65931
- transforms.push(`scale(${scale})`);
65932
- innerWrapper.style.transform = transforms.join(" ");
65933
- innerWrapper.appendChild(this.renderDrawingContent(block, fragment));
65934
- fragmentEl.appendChild(innerWrapper);
65935
- return fragmentEl;
65936
66143
  }
65937
66144
  renderDrawingContent(block, fragment) {
65938
66145
  if (!this.doc) {
@@ -66367,6 +66574,7 @@ const _DomPainter = class _DomPainter2 {
66367
66574
  }
66368
66575
  applyRunStyles(elem, run2, isActiveLink);
66369
66576
  elem.style.zIndex = "1";
66577
+ applyRunDataAttributes(elem, run2.dataAttrs);
66370
66578
  if (run2.pmStart != null) elem.dataset.pmStart = String(run2.pmStart);
66371
66579
  if (run2.pmEnd != null) elem.dataset.pmEnd = String(run2.pmEnd);
66372
66580
  if (trackedConfig) {
@@ -66747,6 +66955,12 @@ const deriveBlockVersion = (block) => {
66747
66955
  run2.kind !== "tab" && run2.bold ? 1 : 0,
66748
66956
  run2.kind !== "tab" && run2.italic ? 1 : 0,
66749
66957
  run2.kind !== "tab" ? run2.color ?? "" : "",
66958
+ // Text decorations - ensures DOM updates when decoration properties change.
66959
+ run2.kind !== "tab" ? run2.underline?.style ?? "" : "",
66960
+ run2.kind !== "tab" ? run2.underline?.color ?? "" : "",
66961
+ run2.kind !== "tab" && run2.strike ? 1 : 0,
66962
+ run2.kind !== "tab" ? run2.highlight ?? "" : "",
66963
+ run2.kind !== "tab" && run2.letterSpacing != null ? run2.letterSpacing : "",
66750
66964
  run2.pmStart ?? "",
66751
66965
  run2.pmEnd ?? "",
66752
66966
  run2.kind !== "tab" ? run2.token ?? "" : ""
@@ -66841,6 +67055,20 @@ const applyRunStyles = (element, run2, isLink = false) => {
66841
67055
  element.style.textDecorationLine = decorations.join(" ");
66842
67056
  }
66843
67057
  };
67058
+ const applyRunDataAttributes = (element, dataAttrs) => {
67059
+ if (!dataAttrs) return;
67060
+ Object.entries(dataAttrs).forEach(([key2, value]) => {
67061
+ if (typeof key2 !== "string" || !key2.toLowerCase().startsWith("data-")) return;
67062
+ if (typeof value !== "string") return;
67063
+ try {
67064
+ element.setAttribute(key2, value);
67065
+ } catch (error) {
67066
+ if (process$1$1.env.NODE_ENV === "development") {
67067
+ console.warn(`[DomPainter] Failed to set data attribute "${key2}":`, error);
67068
+ }
67069
+ }
67070
+ });
67071
+ };
66844
67072
  const applyParagraphBlockStyles = (element, attrs) => {
66845
67073
  if (!attrs) return;
66846
67074
  if (attrs.alignment) {
@@ -70828,7 +71056,8 @@ getHeaderFooterPageHeight_fn = function() {
70828
71056
  return context.layout.pageSize?.h ?? context.region.height ?? 1;
70829
71057
  };
70830
71058
  renderSelectionRects_fn = function(rects) {
70831
- if (!__privateGet$1(this, _selectionOverlay)) {
71059
+ const localSelectionLayer = __privateGet$1(this, _localSelectionLayer);
71060
+ if (!localSelectionLayer) {
70832
71061
  return;
70833
71062
  }
70834
71063
  const pageHeight = __privateMethod$1(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
@@ -70839,7 +71068,7 @@ renderSelectionRects_fn = function(rects) {
70839
71068
  if (!coords) {
70840
71069
  return;
70841
71070
  }
70842
- const highlight = __privateGet$1(this, _selectionOverlay).ownerDocument?.createElement("div");
71071
+ const highlight = localSelectionLayer.ownerDocument?.createElement("div");
70843
71072
  if (!highlight) {
70844
71073
  return;
70845
71074
  }
@@ -70852,7 +71081,7 @@ renderSelectionRects_fn = function(rects) {
70852
71081
  highlight.style.backgroundColor = "rgba(51, 132, 255, 0.35)";
70853
71082
  highlight.style.borderRadius = "2px";
70854
71083
  highlight.style.pointerEvents = "none";
70855
- __privateGet$1(this, _selectionOverlay).appendChild(highlight);
71084
+ localSelectionLayer.appendChild(highlight);
70856
71085
  });
70857
71086
  };
70858
71087
  renderHoverRegion_fn = function(region) {
@@ -71302,6 +71531,7 @@ class PresentationInputBridge {
71302
71531
  __privateAdd$1(this, _onTargetChanged);
71303
71532
  __privateAdd$1(this, _listeners);
71304
71533
  __privateAdd$1(this, _currentTarget, null);
71534
+ __privateAdd$1(this, _destroyed, false);
71305
71535
  __privateSet(this, _windowRoot, windowRoot);
71306
71536
  __privateSet(this, _visibleHost2, visibleHost);
71307
71537
  __privateSet(this, _getTargetDom, getTargetDom);
@@ -71329,9 +71559,13 @@ class PresentationInputBridge {
71329
71559
  });
71330
71560
  __privateSet(this, _listeners, []);
71331
71561
  __privateSet(this, _currentTarget, null);
71562
+ __privateSet(this, _destroyed, true);
71332
71563
  }
71333
71564
  notifyTargetChanged() {
71334
71565
  var _a2;
71566
+ if (__privateGet$1(this, _destroyed)) {
71567
+ return;
71568
+ }
71335
71569
  const nextTarget = __privateGet$1(this, _getTargetDom).call(this);
71336
71570
  if (nextTarget === __privateGet$1(this, _currentTarget)) {
71337
71571
  return;
@@ -71361,6 +71595,7 @@ _getTargetDom = /* @__PURE__ */ new WeakMap();
71361
71595
  _onTargetChanged = /* @__PURE__ */ new WeakMap();
71362
71596
  _listeners = /* @__PURE__ */ new WeakMap();
71363
71597
  _currentTarget = /* @__PURE__ */ new WeakMap();
71598
+ _destroyed = /* @__PURE__ */ new WeakMap();
71364
71599
  _PresentationInputBridge_instances = /* @__PURE__ */ new WeakSet();
71365
71600
  addListener_fn = function(type2, handler2, target) {
71366
71601
  const bound = handler2.bind(this);
@@ -71368,12 +71603,21 @@ addListener_fn = function(type2, handler2, target) {
71368
71603
  target.addEventListener(type2, bound, true);
71369
71604
  };
71370
71605
  dispatchToTarget_fn = function(originalEvent, synthetic) {
71606
+ if (__privateGet$1(this, _destroyed)) return;
71371
71607
  const target = __privateGet$1(this, _getTargetDom).call(this);
71372
71608
  __privateSet(this, _currentTarget, target);
71373
71609
  if (!target) return;
71374
- const canceled = !target.dispatchEvent(synthetic) || synthetic.defaultPrevented;
71375
- if (canceled) {
71376
- originalEvent.preventDefault();
71610
+ const isConnected = target.isConnected;
71611
+ if (isConnected === false) return;
71612
+ try {
71613
+ const canceled = !target.dispatchEvent(synthetic) || synthetic.defaultPrevented;
71614
+ if (canceled) {
71615
+ originalEvent.preventDefault();
71616
+ }
71617
+ } catch (error) {
71618
+ if (process$1$1.env.NODE_ENV === "development") {
71619
+ console.warn("[PresentationEditor] Failed to dispatch event to target:", error);
71620
+ }
71377
71621
  }
71378
71622
  };
71379
71623
  forwardKeyboardEvent_fn = function(event) {
@@ -100263,7 +100507,7 @@ var __accessCheck = (obj, member, msg2) => member.has(obj) || __typeError("Canno
100263
100507
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
100264
100508
  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);
100265
100509
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
100266
- var _SuperToolbar_instances, initToolbarGroups_fn, _interceptedCommands, makeToolbarItems_fn, initDefaultFonts_fn, updateHighlightColors_fn, deactivateAll_fn, updateToolbarHistory_fn, enrichTrackedChanges_fn, runCommandWithArgumentOnly_fn;
100510
+ 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;
100267
100511
  var eventemitter3 = { exports: {} };
100268
100512
  var hasRequiredEventemitter3;
100269
100513
  function requireEventemitter3() {
@@ -100482,7 +100726,7 @@ const useToolbarItem = (options) => {
100482
100726
  if (!Array.isArray(options.options)) throw new Error("Invalid toolbar item options - " + options.options);
100483
100727
  nestedOptions.value?.push(...options.options);
100484
100728
  }
100485
- const activate = (attrs, ...args) => {
100729
+ const activate = (attrs = {}, ...args) => {
100486
100730
  onActivate(attrs, ...args);
100487
100731
  if (suppressActiveHighlight.value) return;
100488
100732
  active.value = true;
@@ -102754,7 +102998,7 @@ const isNegatedMark = (name, attrs = {}) => {
102754
102998
  if (typeof checker !== "function") return false;
102755
102999
  return Boolean(checker(attrs));
102756
103000
  };
102757
- class SuperToolbar extends EventEmitter2 {
103001
+ const _SuperToolbar = class _SuperToolbar2 extends EventEmitter2 {
102758
103002
  /**
102759
103003
  * Creates a new SuperToolbar instance
102760
103004
  * @param {ToolbarConfig} config - The configuration for the toolbar
@@ -102798,11 +103042,11 @@ class SuperToolbar extends EventEmitter2 {
102798
103042
  const isSmallScreen = window.matchMedia("(max-width: 834px)").matches;
102799
103043
  if (isMobileDevice && isSmallScreen) {
102800
103044
  layers.style.transformOrigin = "0 0";
102801
- layers.style.transform = `scale(${parseInt(argument) / 100})`;
103045
+ layers.style.transform = `scale(${parseInt(argument, 10) / 100})`;
102802
103046
  } else {
102803
- layers.style.zoom = parseInt(argument) / 100;
103047
+ layers.style.zoom = parseInt(argument, 10) / 100;
102804
103048
  }
102805
- this.superdoc.superdocStore.activeZoom = parseInt(argument);
103049
+ this.superdoc.superdocStore.activeZoom = parseInt(argument, 10);
102806
103050
  },
102807
103051
  /**
102808
103052
  * Sets the document mode
@@ -102884,31 +103128,37 @@ class SuperToolbar extends EventEmitter2 {
102884
103128
  * @returns {Promise<void>}
102885
103129
  */
102886
103130
  startImageUpload: async () => {
102887
- let open = getFileOpener();
102888
- let result = await open();
102889
- if (!result?.file) {
102890
- return;
102891
- }
102892
- const { size: size2, file } = await checkAndProcessImage({
102893
- file: result.file,
102894
- getMaxContentSize: () => this.activeEditor.getMaxContentSize()
102895
- });
102896
- if (!file) {
102897
- return;
103131
+ try {
103132
+ let open = getFileOpener();
103133
+ let result = await open();
103134
+ if (!result?.file) {
103135
+ return;
103136
+ }
103137
+ const { size: size2, file } = await checkAndProcessImage({
103138
+ file: result.file,
103139
+ getMaxContentSize: () => this.activeEditor.getMaxContentSize()
103140
+ });
103141
+ if (!file) {
103142
+ return;
103143
+ }
103144
+ const id = {};
103145
+ replaceSelectionWithImagePlaceholder({
103146
+ view: this.activeEditor.view,
103147
+ editorOptions: this.activeEditor.options,
103148
+ id
103149
+ });
103150
+ await uploadAndInsertImage({
103151
+ editor: this.activeEditor,
103152
+ view: this.activeEditor.view,
103153
+ file,
103154
+ size: size2,
103155
+ id
103156
+ });
103157
+ } catch (error) {
103158
+ const err = new Error("[super-toolbar 🎨] Image upload failed");
103159
+ this.emit("exception", { error: err, editor: this.activeEditor, originalError: error });
103160
+ console.error(err, error);
102898
103161
  }
102899
- const id = {};
102900
- replaceSelectionWithImagePlaceholder({
102901
- view: this.activeEditor.view,
102902
- editorOptions: this.activeEditor.options,
102903
- id
102904
- });
102905
- await uploadAndInsertImage({
102906
- editor: this.activeEditor,
102907
- view: this.activeEditor.view,
102908
- file,
102909
- size: size2,
102910
- id
102911
- });
102912
103162
  },
102913
103163
  /**
102914
103164
  * Increases text indentation or list level
@@ -103077,6 +103327,13 @@ class SuperToolbar extends EventEmitter2 {
103077
103327
  };
103078
103328
  this.config.hideButtons = config2.hideButtons ?? true;
103079
103329
  this.config.responsiveToContainer = config2.responsiveToContainer ?? false;
103330
+ this.pendingMarkCommands = [];
103331
+ this.stickyStoredMarks = null;
103332
+ this._boundEditorHandlers = {
103333
+ transaction: null,
103334
+ selectionUpdate: null,
103335
+ focus: null
103336
+ };
103080
103337
  if (!this.config.selector && this.config.element) {
103081
103338
  this.config.selector = this.config.element;
103082
103339
  }
@@ -103136,12 +103393,28 @@ class SuperToolbar extends EventEmitter2 {
103136
103393
  }
103137
103394
  /**
103138
103395
  * The toolbar expects an active Super Editor instance.
103139
- * @param {Object} editor - The editor instance to attach to the toolbar
103396
+ * Removes listeners from the previous editor (if any) before attaching to the new one.
103397
+ * @param {Object|null} editor - The editor instance to attach to the toolbar, or null to detach
103140
103398
  * @returns {void}
103141
103399
  */
103142
103400
  setActiveEditor(editor) {
103401
+ if (this.activeEditor && this._boundEditorHandlers.transaction) {
103402
+ this.activeEditor.off("transaction", this._boundEditorHandlers.transaction);
103403
+ this.activeEditor.off("selectionUpdate", this._boundEditorHandlers.selectionUpdate);
103404
+ this.activeEditor.off("focus", this._boundEditorHandlers.focus);
103405
+ this._boundEditorHandlers.transaction = null;
103406
+ this._boundEditorHandlers.selectionUpdate = null;
103407
+ this._boundEditorHandlers.focus = null;
103408
+ }
103143
103409
  this.activeEditor = editor;
103144
- this.activeEditor.on("transaction", this.onEditorTransaction.bind(this));
103410
+ if (editor) {
103411
+ this._boundEditorHandlers.transaction = this.onEditorTransaction.bind(this);
103412
+ this._boundEditorHandlers.selectionUpdate = this.onEditorSelectionUpdate.bind(this);
103413
+ this._boundEditorHandlers.focus = this.onEditorFocus.bind(this);
103414
+ this.activeEditor.on("transaction", this._boundEditorHandlers.transaction);
103415
+ this.activeEditor.on("selectionUpdate", this._boundEditorHandlers.selectionUpdate);
103416
+ this.activeEditor.on("focus", this._boundEditorHandlers.focus);
103417
+ }
103145
103418
  }
103146
103419
  /**
103147
103420
  * Get toolbar items by group name
@@ -103289,15 +103562,28 @@ class SuperToolbar extends EventEmitter2 {
103289
103562
  * @returns {*} The result of the executed command, undefined if no result is returned
103290
103563
  */
103291
103564
  emitCommand({ item, argument, option }) {
103565
+ const hasFocusFn = this.activeEditor?.view?.hasFocus;
103566
+ const wasFocused = Boolean(typeof hasFocusFn === "function" && hasFocusFn.call(this.activeEditor.view));
103567
+ const { command: command2 } = item;
103568
+ const isMarkToggle = this.isMarkToggle(item);
103569
+ if (!wasFocused && isMarkToggle) {
103570
+ this.pendingMarkCommands.push({ command: command2, argument, item });
103571
+ item?.activate?.();
103572
+ if (this.activeEditor && !this.activeEditor.options.isHeaderOrFooter) {
103573
+ this.activeEditor.focus();
103574
+ }
103575
+ return;
103576
+ }
103292
103577
  if (this.activeEditor && !this.activeEditor.options.isHeaderOrFooter) {
103293
103578
  this.activeEditor.focus();
103294
103579
  }
103295
- const { command: command2 } = item;
103296
103580
  if (!command2) {
103297
103581
  return;
103298
103582
  }
103299
103583
  if (command2 in __privateGet(this, _interceptedCommands)) {
103300
- return __privateGet(this, _interceptedCommands)[command2]({ item, argument });
103584
+ const result = __privateGet(this, _interceptedCommands)[command2]({ item, argument });
103585
+ if (isMarkToggle) __privateMethod(this, _SuperToolbar_instances, syncStickyMarksFromState_fn).call(this);
103586
+ return result;
103301
103587
  }
103302
103588
  if (this.activeEditor && this.activeEditor.commands && command2 in this.activeEditor.commands) {
103303
103589
  this.activeEditor.commands[command2](argument);
@@ -103308,9 +103594,67 @@ class SuperToolbar extends EventEmitter2 {
103308
103594
  this.emit("exception", { error, editor: this.activeEditor });
103309
103595
  throw error;
103310
103596
  }
103597
+ if (isMarkToggle) __privateMethod(this, _SuperToolbar_instances, syncStickyMarksFromState_fn).call(this);
103311
103598
  this.updateToolbarState();
103312
103599
  }
103313
- }
103600
+ /**
103601
+ * Processes and executes pending mark commands when editor selection updates.
103602
+ * This is triggered by the editor's 'selectionUpdate' event after focus is restored.
103603
+ * Clears the pending queue after execution.
103604
+ * @returns {void}
103605
+ */
103606
+ onEditorSelectionUpdate() {
103607
+ if (!this.activeEditor) return;
103608
+ if (this.pendingMarkCommands.length) {
103609
+ const pending = this.pendingMarkCommands;
103610
+ this.pendingMarkCommands = [];
103611
+ pending.forEach(({ command: command2, argument, item }) => {
103612
+ if (!command2) return;
103613
+ try {
103614
+ if (command2 in __privateGet(this, _interceptedCommands)) {
103615
+ __privateGet(this, _interceptedCommands)[command2]({ item, argument });
103616
+ } else if (this.activeEditor.commands && command2 in this.activeEditor.commands) {
103617
+ this.activeEditor.commands[command2](argument);
103618
+ }
103619
+ __privateMethod(this, _SuperToolbar_instances, ensureStoredMarksForMarkToggle_fn).call(this, { command: command2, argument });
103620
+ } catch (error) {
103621
+ const err = new Error(`[super-toolbar 🎨] Failed to execute pending command: ${command2}`);
103622
+ this.emit("exception", { error: err, editor: this.activeEditor, originalError: error });
103623
+ console.error(err, error);
103624
+ }
103625
+ });
103626
+ __privateMethod(this, _SuperToolbar_instances, syncStickyMarksFromState_fn).call(this);
103627
+ this.updateToolbarState();
103628
+ return;
103629
+ }
103630
+ const restored = __privateMethod(this, _SuperToolbar_instances, restoreStickyMarksIfNeeded_fn).call(this);
103631
+ if (restored) this.updateToolbarState();
103632
+ }
103633
+ /**
103634
+ * Handles editor focus events by flushing any pending mark commands.
103635
+ * This is triggered by the editor's 'focus' event.
103636
+ * @returns {void}
103637
+ */
103638
+ onEditorFocus() {
103639
+ if (this.pendingMarkCommands.length) {
103640
+ this.onEditorSelectionUpdate();
103641
+ return;
103642
+ }
103643
+ const restored = __privateMethod(this, _SuperToolbar_instances, restoreStickyMarksIfNeeded_fn).call(this);
103644
+ if (restored) this.updateToolbarState();
103645
+ }
103646
+ /**
103647
+ * Determines if a toolbar item represents a mark toggle command.
103648
+ * Mark toggles include text formatting commands like bold, italic, underline, etc.
103649
+ * @param {ToolbarItem} item - The toolbar item to check
103650
+ * @returns {boolean} True if the item is a mark toggle, false otherwise
103651
+ */
103652
+ isMarkToggle(item) {
103653
+ const name = item?.name?.value;
103654
+ return __privateGet(_SuperToolbar2, _MARK_TOGGLE_NAMES).has(name);
103655
+ }
103656
+ };
103657
+ _MARK_TOGGLE_NAMES = /* @__PURE__ */ new WeakMap();
103314
103658
  _SuperToolbar_instances = /* @__PURE__ */ new WeakSet();
103315
103659
  initToolbarGroups_fn = function() {
103316
103660
  if (this.config.groups && !Array.isArray(this.config.groups) && Object.keys(this.config.groups).length) {
@@ -103423,6 +103767,55 @@ runCommandWithArgumentOnly_fn = function({ item, argument, noArgumentCallback =
103423
103767
  this.updateToolbarState();
103424
103768
  }
103425
103769
  };
103770
+ syncStickyMarksFromState_fn = function() {
103771
+ if (!this.activeEditor) return;
103772
+ const { selection, storedMarks } = this.activeEditor.state || {};
103773
+ if (!selection?.empty) return;
103774
+ this.stickyStoredMarks = storedMarks?.length ? [...storedMarks] : null;
103775
+ };
103776
+ restoreStickyMarksIfNeeded_fn = function() {
103777
+ if (!this.activeEditor) return false;
103778
+ if (!this.stickyStoredMarks?.length) return false;
103779
+ const { state: state2, view } = this.activeEditor;
103780
+ const { selection, storedMarks } = state2 || {};
103781
+ if (!selection?.empty) return false;
103782
+ if (storedMarks?.length) return false;
103783
+ if (!view?.dispatch || !state2?.tr) return false;
103784
+ const hasActiveMarkToggle = getActiveFormatting(this.activeEditor).some(
103785
+ (mark) => __privateGet(_SuperToolbar, _MARK_TOGGLE_NAMES).has(mark.name)
103786
+ );
103787
+ if (hasActiveMarkToggle) return false;
103788
+ const tr = state2.tr.setStoredMarks(this.stickyStoredMarks);
103789
+ view.dispatch(tr);
103790
+ return true;
103791
+ };
103792
+ ensureStoredMarksForMarkToggle_fn = function({ command: command2, argument }) {
103793
+ if (!this.activeEditor) return;
103794
+ if (!this.activeEditor.state?.selection?.empty) return;
103795
+ if (this.activeEditor.state?.storedMarks?.length) return;
103796
+ if (command2 !== "setFontSize") return;
103797
+ const { state: state2, view } = this.activeEditor;
103798
+ const textStyleMark = state2.schema?.marks?.textStyle;
103799
+ if (!textStyleMark || !view?.dispatch || !state2?.tr) return;
103800
+ const [value, unit] = parseSizeUnit(argument ?? "");
103801
+ if (Number.isNaN(value)) return;
103802
+ const clamped = Math.min(96, Math.max(8, Number(value)));
103803
+ const resolvedUnit = unit || "pt";
103804
+ const mark = textStyleMark.create({ fontSize: `${clamped}${resolvedUnit}` });
103805
+ const tr = state2.tr.setStoredMarks([mark]);
103806
+ view.dispatch(tr);
103807
+ };
103808
+ __privateAdd(_SuperToolbar, _MARK_TOGGLE_NAMES, /* @__PURE__ */ new Set([
103809
+ "bold",
103810
+ "italic",
103811
+ "underline",
103812
+ "strike",
103813
+ "highlight",
103814
+ "color",
103815
+ "fontSize",
103816
+ "fontFamily"
103817
+ ]));
103818
+ let SuperToolbar = _SuperToolbar;
103426
103819
  const onMarginClickCursorChange = (event, editor) => {
103427
103820
  const y2 = event.clientY;
103428
103821
  const x2 = event.clientX;