superdoc 1.0.0-beta.13 → 1.0.0-beta.14
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.
- package/dist/chunks/{PdfViewer-D_E86Mtr.cjs → PdfViewer-Cdc_EOZ9.cjs} +2 -2
- package/dist/chunks/{PdfViewer-D0cPi5hG.es.js → PdfViewer-DrsLL5TV.es.js} +2 -2
- package/dist/chunks/{eventemitter3-ByBH0NYV.es.js → eventemitter3-CcXAdeql.es.js} +1 -1
- package/dist/chunks/{eventemitter3-CFCpOk3d.cjs → eventemitter3-DQmQUge-.cjs} +1 -1
- package/dist/chunks/{index-CL4VptDO.cjs → index-9ZvcPlCg.cjs} +6 -6
- package/dist/chunks/{index-BHmLKAul.es.js → index-DB1DyDmZ.es.js} +6 -6
- package/dist/chunks/{index-BMAfbNel-CvPc3jnD.es.js → index-I4Ew0HDV-Bht7-IGi.es.js} +1 -1
- package/dist/chunks/{index-BMAfbNel-DBZCkkMj.cjs → index-I4Ew0HDV-EPhjcu7T.cjs} +1 -1
- package/dist/chunks/{jszip-BwsONqK5.es.js → jszip-5vvIqAEE.es.js} +1 -1
- package/dist/chunks/{jszip-B99MTu59.cjs → jszip-BdEez1WM.cjs} +1 -1
- package/dist/chunks/{super-editor.es-riuOlaxm.cjs → super-editor.es-DuS77THX.cjs} +3958 -531
- package/dist/chunks/{super-editor.es-5gtBhP8I.es.js → super-editor.es-DxAG4BVh.es.js} +3959 -532
- package/dist/chunks/{vue-CztqUvm1.es.js → vue-Dysv_7z5.es.js} +101 -12
- package/dist/chunks/{vue-ARQSyfaw.cjs → vue-jWLMl8Ts.cjs} +89 -0
- package/dist/chunks/xml-js-ClO_jHnq.es.js +2 -0
- package/dist/chunks/xml-js-Dz51sEbr.cjs +3 -0
- package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
- package/dist/style.css +50 -11
- package/dist/super-editor/ai-writer.es.js +2 -2
- package/dist/super-editor/chunks/{converter-D9KiDgXx.js → converter-CfmIU--8.js} +511 -95
- package/dist/super-editor/chunks/{docx-zipper-DQmUj-ef.js → docx-zipper-B-CXiNSb.js} +1 -1
- package/dist/super-editor/chunks/{editor-ByPqJ2k8.js → editor-wC_gs8Bl.js} +2898 -347
- package/dist/super-editor/chunks/{index-BMAfbNel.js → index-I4Ew0HDV.js} +1 -1
- package/dist/super-editor/chunks/{toolbar-Da2cOhJ-.js → toolbar-BR1GYvwW.js} +36 -22
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor/docx-zipper.es.js +2 -2
- package/dist/super-editor/editor.es.js +3 -3
- package/dist/super-editor/file-zipper.es.js +1 -1
- package/dist/super-editor/style.css +50 -11
- package/dist/super-editor/super-editor.es.js +559 -67
- package/dist/super-editor/toolbar.es.js +2 -2
- package/dist/super-editor.cjs +4 -4
- package/dist/super-editor.es.js +2 -2
- package/dist/superdoc.cjs +2 -2
- package/dist/superdoc.es.js +2 -2
- package/dist/superdoc.umd.js +4023 -520
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/xml-js-BZPSMmVo.es.js +0 -2
- package/dist/chunks/xml-js-DQa4Ye5C.cjs +0 -3
|
@@ -9,11 +9,11 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
9
9
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
10
10
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
11
11
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
12
|
-
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _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, _layoutSurfaces, _getTargetDom, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn;
|
|
12
|
+
var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _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, _lastSelectedImageBlockId, _remoteCursorState, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _remoteCursorRafHandle, _scrollTimeout, _PresentationEditor_instances, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _handleDoubleClick, _handleKeyDown, focusHeaderFooterShortcut_fn, scheduleRerender_fn, flushRerenderQueue_fn, rerender_fn, ensurePainter_fn, scheduleSelectionUpdate_fn, updateSelection_fn, resolveLayoutOptions_fn, buildHeaderFooterInput_fn, computeHeaderFooterConstraints_fn, updateDecorationProviders_fn, createDecorationProvider_fn, findHeaderFooterPageForPageNumber_fn, computeDecorationBox_fn, rebuildHeaderFooterRegions_fn, hitTestHeaderFooterRegion_fn, pointInRegion_fn, activateHeaderFooterRegion_fn, enterHeaderFooterMode_fn, exitHeaderFooterMode_fn, getActiveDomTarget_fn, emitHeaderFooterModeChanged_fn, emitHeaderFooterEditingContext_fn, updateAwarenessSession_fn, updateModeBanner_fn, announce_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, 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, _layoutSurfaces, _getTargetDom, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _VectorShapeView_instances, ensureParentPositioned_fn, _ShapeGroupView_instances, ensureParentPositioned_fn2;
|
|
13
13
|
import * as Y from "yjs";
|
|
14
14
|
import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
|
|
15
|
-
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as htmlHandler, E as ReplaceStep, G as twipsToInches, H as inchesToTwips, I as ptToTwips, J as getResolvedParagraphProperties, K as linesToTwips, L as ListHelpers, O as updateNumberingProperties, Q as changeListLevel, U as findParentNode, V as isList, W as isMacOS, X as isIOS, Y as getSchemaTypeByName, Z as inputRulesPlugin, _ as TrackDeleteMarkName, $ as TrackInsertMarkName, a0 as v4, a1 as TrackFormatMarkName, a2 as comments_module_events, a3 as findMark, a4 as objectIncludes, a5 as AddMarkStep, a6 as RemoveMarkStep, a7 as twipsToLines, a8 as pixelsToTwips, a9 as helpers, aa as posToDOMRect, ab as CommandService, ac as SuperConverter, ad as createDocument, ae as createDocFromMarkdown, af as createDocFromHTML, ag as EditorState, ah as isActive, ai as unflattenListsInHtml, aj as resolveParagraphProperties, ak as _getReferencedTableStyles, al as parseSizeUnit, am as minMax, an as updateDOMAttributes, ao as findChildren$5, ap as generateRandomSigned32BitIntStrId, aq as calculateResolvedParagraphProperties, ar as encodeCSSFromPPr, as as twipsToPixels$2, at as resolveRunProperties, au as encodeCSSFromRPr, av as generateOrderedListIndex, aw as docxNumberingHelpers, ax as InputRule, ay as convertSizeToCSS, az as SelectionRange, aA as Transform, aB as findParentNodeClosestToPos, aC as isInTable$1, aD as generateDocxRandomId, aE as insertNewRelationship, aF as inchesToPixels, aG as kebabCase, aH as getUnderlineCssString } from "./converter-
|
|
16
|
-
import { D as DocxZipper } from "./docx-zipper-
|
|
15
|
+
import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$1, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as htmlHandler, E as ReplaceStep, G as twipsToInches, H as inchesToTwips, I as ptToTwips, J as getResolvedParagraphProperties, K as linesToTwips, L as ListHelpers, O as updateNumberingProperties, Q as changeListLevel, U as findParentNode, V as isList, W as isMacOS, X as isIOS, Y as getSchemaTypeByName, Z as inputRulesPlugin, _ as TrackDeleteMarkName, $ as TrackInsertMarkName, a0 as v4, a1 as TrackFormatMarkName, a2 as comments_module_events, a3 as findMark, a4 as objectIncludes, a5 as AddMarkStep, a6 as RemoveMarkStep, a7 as twipsToLines, a8 as pixelsToTwips, a9 as helpers, aa as posToDOMRect, ab as CommandService, ac as SuperConverter, ad as createDocument, ae as createDocFromMarkdown, af as createDocFromHTML, ag as EditorState, ah as isActive, ai as unflattenListsInHtml, aj as resolveParagraphProperties, ak as _getReferencedTableStyles, al as parseSizeUnit, am as minMax, an as updateDOMAttributes, ao as findChildren$5, ap as generateRandomSigned32BitIntStrId, aq as calculateResolvedParagraphProperties, ar as encodeCSSFromPPr, as as twipsToPixels$2, at as resolveRunProperties, au as encodeCSSFromRPr, av as generateOrderedListIndex, aw as docxNumberingHelpers, ax as InputRule, ay as convertSizeToCSS, az as SelectionRange, aA as Transform, aB as findParentNodeClosestToPos, aC as isInTable$1, aD as generateDocxRandomId, aE as insertNewRelationship, aF as inchesToPixels, aG as kebabCase, aH as getUnderlineCssString } from "./converter-CfmIU--8.js";
|
|
16
|
+
import { D as DocxZipper } from "./docx-zipper-B-CXiNSb.js";
|
|
17
17
|
import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
|
|
18
18
|
var GOOD_LEAF_SIZE = 200;
|
|
19
19
|
var RopeSequence = function RopeSequence2() {
|
|
@@ -13553,7 +13553,7 @@ const isHeadless = (editor) => {
|
|
|
13553
13553
|
const shouldSkipNodeView = (editor) => {
|
|
13554
13554
|
return isHeadless(editor);
|
|
13555
13555
|
};
|
|
13556
|
-
const summaryVersion = "1.0.0-beta.
|
|
13556
|
+
const summaryVersion = "1.0.0-beta.14";
|
|
13557
13557
|
const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
|
|
13558
13558
|
const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
|
|
13559
13559
|
function mapAttributes(attrs) {
|
|
@@ -14335,7 +14335,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
14335
14335
|
{ default: remarkStringify },
|
|
14336
14336
|
{ default: remarkGfm }
|
|
14337
14337
|
] = await Promise.all([
|
|
14338
|
-
import("./index-
|
|
14338
|
+
import("./index-I4Ew0HDV.js"),
|
|
14339
14339
|
import("./index-DRCvimau.js"),
|
|
14340
14340
|
import("./index-C_x_N6Uh.js"),
|
|
14341
14341
|
import("./index-D_sWOSiG.js"),
|
|
@@ -14540,7 +14540,7 @@ const _Editor = class _Editor extends EventEmitter {
|
|
|
14540
14540
|
* Process collaboration migrations
|
|
14541
14541
|
*/
|
|
14542
14542
|
processCollaborationMigrations() {
|
|
14543
|
-
console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.
|
|
14543
|
+
console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.14");
|
|
14544
14544
|
if (!this.options.ydoc) return;
|
|
14545
14545
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
14546
14546
|
let docVersion = metaMap.get("version");
|
|
@@ -15872,22 +15872,15 @@ function hydrateImageBlocks(blocks, mediaFiles) {
|
|
|
15872
15872
|
if (normalizedMedia.size === 0) {
|
|
15873
15873
|
return blocks;
|
|
15874
15874
|
}
|
|
15875
|
-
|
|
15876
|
-
if (
|
|
15877
|
-
return
|
|
15878
|
-
}
|
|
15879
|
-
if (!block.src || block.src.startsWith("data:")) {
|
|
15880
|
-
return block;
|
|
15875
|
+
const resolveImageSrc = (src, relId, attrSrc, extension) => {
|
|
15876
|
+
if (!src || src.startsWith("data:")) {
|
|
15877
|
+
return void 0;
|
|
15881
15878
|
}
|
|
15882
|
-
const attrs = block.attrs ?? {};
|
|
15883
|
-
const relId = typeof attrs.rId === "string" ? attrs.rId : void 0;
|
|
15884
|
-
const attrSrc = typeof attrs.src === "string" ? attrs.src : void 0;
|
|
15885
|
-
const extension = typeof attrs.extension === "string" ? attrs.extension.toLowerCase() : void 0;
|
|
15886
15879
|
const candidates = /* @__PURE__ */ new Set();
|
|
15887
|
-
candidates.add(
|
|
15880
|
+
candidates.add(src);
|
|
15888
15881
|
if (attrSrc) candidates.add(attrSrc);
|
|
15889
15882
|
if (relId) {
|
|
15890
|
-
const inferredExt = extension ?? inferExtensionFromPath(
|
|
15883
|
+
const inferredExt = extension ?? inferExtensionFromPath(src) ?? "jpeg";
|
|
15891
15884
|
candidates.add(`word/media/${relId}.${inferredExt}`);
|
|
15892
15885
|
candidates.add(`media/${relId}.${inferredExt}`);
|
|
15893
15886
|
}
|
|
@@ -15897,14 +15890,128 @@ function hydrateImageBlocks(blocks, mediaFiles) {
|
|
|
15897
15890
|
const base64 = normalizedMedia.get(normalized);
|
|
15898
15891
|
if (!base64) continue;
|
|
15899
15892
|
const finalExt = extension ?? inferExtensionFromPath(normalized) ?? "jpeg";
|
|
15900
|
-
return {
|
|
15901
|
-
|
|
15902
|
-
|
|
15903
|
-
|
|
15893
|
+
return base64.startsWith("data:") ? base64 : `data:image/${finalExt};base64,${base64}`;
|
|
15894
|
+
}
|
|
15895
|
+
return void 0;
|
|
15896
|
+
};
|
|
15897
|
+
const hydrateRuns = (runs) => {
|
|
15898
|
+
let hasChanges = false;
|
|
15899
|
+
const hydratedRuns = runs.map((run) => {
|
|
15900
|
+
if (run.kind !== "image") {
|
|
15901
|
+
return run;
|
|
15902
|
+
}
|
|
15903
|
+
const imageRun = run;
|
|
15904
|
+
if (!imageRun.src || imageRun.src.startsWith("data:")) {
|
|
15905
|
+
return run;
|
|
15906
|
+
}
|
|
15907
|
+
const resolvedSrc = resolveImageSrc(imageRun.src);
|
|
15908
|
+
if (resolvedSrc) {
|
|
15909
|
+
hasChanges = true;
|
|
15910
|
+
return { ...imageRun, src: resolvedSrc };
|
|
15911
|
+
}
|
|
15912
|
+
return run;
|
|
15913
|
+
});
|
|
15914
|
+
return hasChanges ? hydratedRuns : runs;
|
|
15915
|
+
};
|
|
15916
|
+
return blocks.map((block) => {
|
|
15917
|
+
if (block.kind === "image") {
|
|
15918
|
+
if (!block.src || block.src.startsWith("data:")) {
|
|
15919
|
+
return block;
|
|
15920
|
+
}
|
|
15921
|
+
const attrs = block.attrs ?? {};
|
|
15922
|
+
const relId = typeof attrs.rId === "string" ? attrs.rId : void 0;
|
|
15923
|
+
const attrSrc = typeof attrs.src === "string" ? attrs.src : void 0;
|
|
15924
|
+
const extension = typeof attrs.extension === "string" ? attrs.extension.toLowerCase() : void 0;
|
|
15925
|
+
const resolvedSrc = resolveImageSrc(block.src, relId, attrSrc, extension);
|
|
15926
|
+
if (resolvedSrc) {
|
|
15927
|
+
return { ...block, src: resolvedSrc };
|
|
15928
|
+
}
|
|
15929
|
+
return block;
|
|
15930
|
+
}
|
|
15931
|
+
if (block.kind === "paragraph") {
|
|
15932
|
+
const paragraphBlock = block;
|
|
15933
|
+
if (!paragraphBlock.runs || paragraphBlock.runs.length === 0) {
|
|
15934
|
+
return block;
|
|
15935
|
+
}
|
|
15936
|
+
const hydratedRuns = hydrateRuns(paragraphBlock.runs);
|
|
15937
|
+
if (hydratedRuns !== paragraphBlock.runs) {
|
|
15938
|
+
return { ...paragraphBlock, runs: hydratedRuns };
|
|
15939
|
+
}
|
|
15940
|
+
return block;
|
|
15904
15941
|
}
|
|
15905
15942
|
return block;
|
|
15906
15943
|
});
|
|
15907
15944
|
}
|
|
15945
|
+
function isGradientFill(value) {
|
|
15946
|
+
if (!isPlainObject$2(value)) return false;
|
|
15947
|
+
if (value.type !== "gradient") return false;
|
|
15948
|
+
const gradientType = value.gradientType;
|
|
15949
|
+
if (gradientType !== "linear" && gradientType !== "radial") return false;
|
|
15950
|
+
if (gradientType === "linear") {
|
|
15951
|
+
if (typeof value.angle !== "number" || !Number.isFinite(value.angle)) {
|
|
15952
|
+
return false;
|
|
15953
|
+
}
|
|
15954
|
+
}
|
|
15955
|
+
if (!Array.isArray(value.stops) || value.stops.length === 0) return false;
|
|
15956
|
+
return value.stops.every((stop) => {
|
|
15957
|
+
if (!isPlainObject$2(stop)) return false;
|
|
15958
|
+
return typeof stop.position === "number" && Number.isFinite(stop.position) && typeof stop.color === "string" && (stop.alpha === void 0 || typeof stop.alpha === "number" && Number.isFinite(stop.alpha));
|
|
15959
|
+
});
|
|
15960
|
+
}
|
|
15961
|
+
function isSolidFillWithAlpha(value) {
|
|
15962
|
+
return isPlainObject$2(value) && value.type === "solidWithAlpha" && typeof value.color === "string" && typeof value.alpha === "number";
|
|
15963
|
+
}
|
|
15964
|
+
function normalizeFillColor(value) {
|
|
15965
|
+
if (value === null) return null;
|
|
15966
|
+
if (typeof value === "string") return value;
|
|
15967
|
+
if (isGradientFill(value)) return value;
|
|
15968
|
+
if (isSolidFillWithAlpha(value)) return value;
|
|
15969
|
+
return void 0;
|
|
15970
|
+
}
|
|
15971
|
+
function normalizeStrokeColor(value) {
|
|
15972
|
+
if (value === null) return null;
|
|
15973
|
+
if (typeof value === "string") return value;
|
|
15974
|
+
return void 0;
|
|
15975
|
+
}
|
|
15976
|
+
function normalizeTextContent(value) {
|
|
15977
|
+
if (!isPlainObject$2(value)) return void 0;
|
|
15978
|
+
if (!Array.isArray(value.parts)) return void 0;
|
|
15979
|
+
if (value.parts.length === 0) return void 0;
|
|
15980
|
+
const validParts = value.parts.filter((p) => isPlainObject$2(p) && typeof p.text === "string");
|
|
15981
|
+
if (validParts.length === 0) return void 0;
|
|
15982
|
+
const result = {
|
|
15983
|
+
parts: validParts
|
|
15984
|
+
};
|
|
15985
|
+
if (["left", "center", "right"].includes(value.horizontalAlign)) {
|
|
15986
|
+
result.horizontalAlign = value.horizontalAlign;
|
|
15987
|
+
}
|
|
15988
|
+
return result;
|
|
15989
|
+
}
|
|
15990
|
+
function normalizeTextVerticalAlign(value) {
|
|
15991
|
+
if (typeof value !== "string") return void 0;
|
|
15992
|
+
if (value === "top" || value === "center" || value === "bottom") {
|
|
15993
|
+
return value;
|
|
15994
|
+
}
|
|
15995
|
+
return void 0;
|
|
15996
|
+
}
|
|
15997
|
+
function normalizeTextInsets(value) {
|
|
15998
|
+
if (!isPlainObject$2(value)) return void 0;
|
|
15999
|
+
const top2 = pickNumber(value.top);
|
|
16000
|
+
const right2 = pickNumber(value.right);
|
|
16001
|
+
const bottom2 = pickNumber(value.bottom);
|
|
16002
|
+
const left2 = pickNumber(value.left);
|
|
16003
|
+
if (top2 == null || right2 == null || bottom2 == null || left2 == null) {
|
|
16004
|
+
return void 0;
|
|
16005
|
+
}
|
|
16006
|
+
return { top: top2, right: right2, bottom: bottom2, left: left2 };
|
|
16007
|
+
}
|
|
16008
|
+
const OOXML_Z_INDEX_BASE = 251658240;
|
|
16009
|
+
function normalizeZIndex(originalAttributes) {
|
|
16010
|
+
if (!isPlainObject$2(originalAttributes)) return void 0;
|
|
16011
|
+
const relativeHeight = originalAttributes.relativeHeight;
|
|
16012
|
+
if (typeof relativeHeight !== "number") return void 0;
|
|
16013
|
+
return Math.max(0, relativeHeight - OOXML_Z_INDEX_BASE);
|
|
16014
|
+
}
|
|
15908
16015
|
const DEFAULT_ALLOWED_PROTOCOLS = ["http", "https", "mailto", "tel", "sms"];
|
|
15909
16016
|
const OPTIONAL_PROTOCOLS = ["ftp", "sftp", "irc"];
|
|
15910
16017
|
const BLOCKED_PROTOCOLS = ["javascript", "data", "vbscript", "file", "ssh", "ws", "wss"];
|
|
@@ -16798,6 +16905,7 @@ const normalizeBorderSide = (value) => {
|
|
|
16798
16905
|
if (!value || typeof value !== "object") return void 0;
|
|
16799
16906
|
const raw = value;
|
|
16800
16907
|
const style = mapBorderStyle(raw.val);
|
|
16908
|
+
if (style === "none") return void 0;
|
|
16801
16909
|
const width = pickNumber(raw.size);
|
|
16802
16910
|
const widthPx = borderSizeToPx(width);
|
|
16803
16911
|
const color = normalizeColor(raw.color);
|
|
@@ -16806,7 +16914,9 @@ const normalizeBorderSide = (value) => {
|
|
|
16806
16914
|
return void 0;
|
|
16807
16915
|
}
|
|
16808
16916
|
const border = {};
|
|
16809
|
-
if (style
|
|
16917
|
+
if (style) {
|
|
16918
|
+
border.style = style;
|
|
16919
|
+
}
|
|
16810
16920
|
if (widthPx != null) border.width = Math.max(0, widthPx);
|
|
16811
16921
|
if (color) border.color = color;
|
|
16812
16922
|
if (space != null) border.space = Math.max(0, space);
|
|
@@ -17917,7 +18027,13 @@ function resolveMarkerRunProperties(input) {
|
|
|
17917
18027
|
return input.cached;
|
|
17918
18028
|
}
|
|
17919
18029
|
const numberingResolved = input.numbering?.resolvedMarkerRpr || input.resolvedParagraphProps.numberingProperties?.resolvedMarkerRpr;
|
|
17920
|
-
|
|
18030
|
+
const result = mergeRunProperties(
|
|
18031
|
+
DEFAULT_MARKER_RUN,
|
|
18032
|
+
input.docDefaults.run,
|
|
18033
|
+
numberingResolved,
|
|
18034
|
+
input.inlineMarkerRpr
|
|
18035
|
+
);
|
|
18036
|
+
return result;
|
|
17921
18037
|
}
|
|
17922
18038
|
const DEFAULT_MARKER_RUN = {
|
|
17923
18039
|
fontFamily: "Times New Roman",
|
|
@@ -18661,7 +18777,7 @@ const normalizeResolvedTabAlignment = (value) => {
|
|
|
18661
18777
|
return void 0;
|
|
18662
18778
|
}
|
|
18663
18779
|
};
|
|
18664
|
-
const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleContext) => {
|
|
18780
|
+
const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleContext, _paragraphNode) => {
|
|
18665
18781
|
if (numberingProps === null) {
|
|
18666
18782
|
return null;
|
|
18667
18783
|
}
|
|
@@ -18684,12 +18800,14 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
|
|
|
18684
18800
|
decimalSeparator: paragraphAttrs.decimalSeparator,
|
|
18685
18801
|
numberingProperties: numberingProps
|
|
18686
18802
|
};
|
|
18803
|
+
const defaultFontFamily = styleContext.defaults?.paragraphFont ?? styleContext.defaults?.paragraphFontFamily ?? "Times New Roman";
|
|
18804
|
+
const defaultFontSize = styleContext.defaults?.fontSize ?? 12;
|
|
18687
18805
|
const docDefaults = {
|
|
18688
18806
|
defaultTabIntervalTwips: styleContext.defaults?.defaultTabIntervalTwips ?? 720,
|
|
18689
18807
|
decimalSeparator: styleContext.defaults?.decimalSeparator ?? ".",
|
|
18690
18808
|
run: {
|
|
18691
|
-
fontFamily:
|
|
18692
|
-
fontSize:
|
|
18809
|
+
fontFamily: defaultFontFamily,
|
|
18810
|
+
fontSize: defaultFontSize
|
|
18693
18811
|
},
|
|
18694
18812
|
paragraph: {
|
|
18695
18813
|
indent: {},
|
|
@@ -18710,12 +18828,26 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
|
|
|
18710
18828
|
};
|
|
18711
18829
|
}
|
|
18712
18830
|
}
|
|
18713
|
-
|
|
18831
|
+
if (!markerRun) {
|
|
18832
|
+
markerRun = {
|
|
18833
|
+
fontFamily: "Times New Roman",
|
|
18834
|
+
fontSize: 12,
|
|
18835
|
+
color: "#000000"
|
|
18836
|
+
};
|
|
18837
|
+
}
|
|
18838
|
+
if (markerRun.fontSize != null) {
|
|
18839
|
+
const fontSizePx = ptToPx(markerRun.fontSize);
|
|
18840
|
+
if (fontSizePx != null) {
|
|
18841
|
+
markerRun = { ...markerRun, fontSize: fontSizePx };
|
|
18842
|
+
}
|
|
18843
|
+
}
|
|
18844
|
+
const layout = computeWordParagraphLayout({
|
|
18714
18845
|
paragraph: resolvedParagraph,
|
|
18715
18846
|
numbering: numberingProps,
|
|
18716
18847
|
markerRun,
|
|
18717
18848
|
docDefaults
|
|
18718
18849
|
});
|
|
18850
|
+
return layout;
|
|
18719
18851
|
} catch {
|
|
18720
18852
|
return null;
|
|
18721
18853
|
}
|
|
@@ -18879,26 +19011,58 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
|
|
|
18879
19011
|
paragraphAttrs.tabs = normalizedTabs;
|
|
18880
19012
|
}
|
|
18881
19013
|
}
|
|
18882
|
-
|
|
18883
|
-
|
|
18884
|
-
|
|
18885
|
-
|
|
18886
|
-
|
|
18887
|
-
|
|
18888
|
-
|
|
18889
|
-
|
|
18890
|
-
dropCap: framePrElement.attributes["w:dropCap"]
|
|
18891
|
-
};
|
|
18892
|
-
}
|
|
19014
|
+
const asString = (value) => {
|
|
19015
|
+
return typeof value === "string" ? value : void 0;
|
|
19016
|
+
};
|
|
19017
|
+
const normalizeFramePr = (value) => {
|
|
19018
|
+
if (!value || typeof value !== "object") return void 0;
|
|
19019
|
+
const record = value;
|
|
19020
|
+
if (record.attributes && typeof record.attributes === "object") {
|
|
19021
|
+
return record.attributes;
|
|
18893
19022
|
}
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
|
|
19023
|
+
return record;
|
|
19024
|
+
};
|
|
19025
|
+
const extractFramePrFromElements = (paragraphProperties) => {
|
|
19026
|
+
if (!paragraphProperties || typeof paragraphProperties !== "object") return void 0;
|
|
19027
|
+
const pPr = paragraphProperties;
|
|
19028
|
+
if (!Array.isArray(pPr.elements)) return void 0;
|
|
19029
|
+
const framePrElement = pPr.elements.find((el) => el.name === "w:framePr");
|
|
19030
|
+
if (framePrElement?.attributes && typeof framePrElement.attributes === "object") {
|
|
19031
|
+
return framePrElement.attributes;
|
|
19032
|
+
}
|
|
19033
|
+
return void 0;
|
|
19034
|
+
};
|
|
19035
|
+
const framePr = normalizeFramePr(attrs.framePr) ?? normalizeFramePr(attrs.paragraphProperties?.framePr) ?? extractFramePrFromElements(attrs.paragraphProperties);
|
|
19036
|
+
if (framePr) {
|
|
19037
|
+
const rawXAlign = asString(framePr["w:xAlign"] ?? framePr.xAlign);
|
|
19038
|
+
const xAlign = typeof rawXAlign === "string" ? rawXAlign.toLowerCase() : void 0;
|
|
18897
19039
|
if (xAlign === "left" || xAlign === "right" || xAlign === "center") {
|
|
18898
19040
|
paragraphAttrs.floatAlignment = xAlign;
|
|
18899
19041
|
}
|
|
18900
|
-
|
|
18901
|
-
|
|
19042
|
+
const dropCap = framePr["w:dropCap"] ?? framePr.dropCap;
|
|
19043
|
+
if (dropCap != null && (typeof dropCap === "string" || typeof dropCap === "number" || typeof dropCap === "boolean")) {
|
|
19044
|
+
paragraphAttrs.dropCap = dropCap;
|
|
19045
|
+
}
|
|
19046
|
+
const frame = {};
|
|
19047
|
+
const wrap = asString(framePr["w:wrap"] ?? framePr.wrap);
|
|
19048
|
+
if (wrap) frame.wrap = wrap;
|
|
19049
|
+
if (xAlign) {
|
|
19050
|
+
frame.xAlign = xAlign;
|
|
19051
|
+
}
|
|
19052
|
+
const rawYAlign = asString(framePr["w:yAlign"] ?? framePr.yAlign);
|
|
19053
|
+
if (rawYAlign) {
|
|
19054
|
+
frame.yAlign = rawYAlign;
|
|
19055
|
+
}
|
|
19056
|
+
const hAnchor = asString(framePr["w:hAnchor"] ?? framePr.hAnchor);
|
|
19057
|
+
if (hAnchor) frame.hAnchor = hAnchor;
|
|
19058
|
+
const vAnchor = asString(framePr["w:vAnchor"] ?? framePr.vAnchor);
|
|
19059
|
+
if (vAnchor) frame.vAnchor = vAnchor;
|
|
19060
|
+
const xTwips = pickNumber(framePr["w:x"] ?? framePr.x);
|
|
19061
|
+
if (xTwips != null) frame.x = twipsToPx$1(xTwips);
|
|
19062
|
+
const yTwips = pickNumber(framePr["w:y"] ?? framePr.y);
|
|
19063
|
+
if (yTwips != null) frame.y = twipsToPx$1(yTwips);
|
|
19064
|
+
if (Object.keys(frame).length > 0) {
|
|
19065
|
+
paragraphAttrs.frame = frame;
|
|
18902
19066
|
}
|
|
18903
19067
|
}
|
|
18904
19068
|
const numberingSource = attrs.numberingProperties ?? paragraphProps.numberingProperties ?? hydrated?.numberingProperties;
|
|
@@ -18943,13 +19107,6 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
|
|
|
18943
19107
|
enrichedNumberingProps.resolvedMarkerRpr = marker.run;
|
|
18944
19108
|
}
|
|
18945
19109
|
}
|
|
18946
|
-
if (!enrichedNumberingProps.resolvedMarkerRpr) {
|
|
18947
|
-
enrichedNumberingProps.resolvedMarkerRpr = {
|
|
18948
|
-
fontFamily: "Times New Roman",
|
|
18949
|
-
fontSize: 12,
|
|
18950
|
-
color: "#000000"
|
|
18951
|
-
};
|
|
18952
|
-
}
|
|
18953
19110
|
}
|
|
18954
19111
|
const wordLayout = computeWordLayoutForParagraph(paragraphAttrs, enrichedNumberingProps, styleContext);
|
|
18955
19112
|
if (wordLayout) {
|
|
@@ -19386,7 +19543,9 @@ function handleDocumentPartObjectNode(node, context) {
|
|
|
19386
19543
|
styleContext,
|
|
19387
19544
|
bookmarks,
|
|
19388
19545
|
hyperlinkConfig,
|
|
19389
|
-
converters
|
|
19546
|
+
converters,
|
|
19547
|
+
listCounterContext,
|
|
19548
|
+
trackedChangesConfig
|
|
19390
19549
|
} = context;
|
|
19391
19550
|
const docPartGallery = getDocPartGallery(node);
|
|
19392
19551
|
const docPartObjectId = getDocPartObjectId(node);
|
|
@@ -19409,6 +19568,27 @@ function handleDocumentPartObjectNode(node, context) {
|
|
|
19409
19568
|
{ blocks, recordBlockKind },
|
|
19410
19569
|
paragraphToFlowBlocks2
|
|
19411
19570
|
);
|
|
19571
|
+
} else if (paragraphToFlowBlocks2) {
|
|
19572
|
+
for (const child of node.content) {
|
|
19573
|
+
if (child.type === "paragraph") {
|
|
19574
|
+
const childBlocks = paragraphToFlowBlocks2(
|
|
19575
|
+
child,
|
|
19576
|
+
nextBlockId,
|
|
19577
|
+
positions,
|
|
19578
|
+
defaultFont,
|
|
19579
|
+
defaultSize,
|
|
19580
|
+
styleContext,
|
|
19581
|
+
listCounterContext,
|
|
19582
|
+
trackedChangesConfig,
|
|
19583
|
+
bookmarks,
|
|
19584
|
+
hyperlinkConfig
|
|
19585
|
+
);
|
|
19586
|
+
for (const block of childBlocks) {
|
|
19587
|
+
blocks.push(block);
|
|
19588
|
+
recordBlockKind(block.kind);
|
|
19589
|
+
}
|
|
19590
|
+
}
|
|
19591
|
+
}
|
|
19412
19592
|
}
|
|
19413
19593
|
}
|
|
19414
19594
|
const extractValue = (value) => {
|
|
@@ -19569,6 +19749,55 @@ const extractRunStyleId = (runProperties) => {
|
|
|
19569
19749
|
}
|
|
19570
19750
|
return null;
|
|
19571
19751
|
};
|
|
19752
|
+
const DEFAULT_IMAGE_DIMENSION_PX = 100;
|
|
19753
|
+
function isInlineImage(node) {
|
|
19754
|
+
const attrs = node.attrs ?? {};
|
|
19755
|
+
const wrap = attrs.wrap;
|
|
19756
|
+
const rawWrapType = wrap?.type;
|
|
19757
|
+
if (rawWrapType === "Inline") return true;
|
|
19758
|
+
if (rawWrapType && rawWrapType !== "Inline") return false;
|
|
19759
|
+
if (attrs.inline === true) return true;
|
|
19760
|
+
if (attrs.display === "inline") return true;
|
|
19761
|
+
return false;
|
|
19762
|
+
}
|
|
19763
|
+
function imageNodeToRun(node, positions, activeSdt) {
|
|
19764
|
+
const attrs = node.attrs ?? {};
|
|
19765
|
+
const src = typeof attrs.src === "string" ? attrs.src : "";
|
|
19766
|
+
if (!src) {
|
|
19767
|
+
return null;
|
|
19768
|
+
}
|
|
19769
|
+
const size = attrs.size ?? {};
|
|
19770
|
+
const width = typeof size.width === "number" && Number.isFinite(size.width) && size.width > 0 ? size.width : DEFAULT_IMAGE_DIMENSION_PX;
|
|
19771
|
+
const height = typeof size.height === "number" && Number.isFinite(size.height) && size.height > 0 ? size.height : DEFAULT_IMAGE_DIMENSION_PX;
|
|
19772
|
+
const wrap = isPlainObject$2(attrs.wrap) ? attrs.wrap : {};
|
|
19773
|
+
const wrapAttrs = isPlainObject$2(wrap.attrs) ? wrap.attrs : {};
|
|
19774
|
+
const run = {
|
|
19775
|
+
kind: "image",
|
|
19776
|
+
src,
|
|
19777
|
+
width,
|
|
19778
|
+
height
|
|
19779
|
+
};
|
|
19780
|
+
if (typeof attrs.alt === "string") run.alt = attrs.alt;
|
|
19781
|
+
if (typeof attrs.title === "string") run.title = attrs.title;
|
|
19782
|
+
const distTop = pickNumber(wrapAttrs.distTop ?? wrapAttrs.distT);
|
|
19783
|
+
if (distTop != null) run.distTop = distTop;
|
|
19784
|
+
const distBottom = pickNumber(wrapAttrs.distBottom ?? wrapAttrs.distB);
|
|
19785
|
+
if (distBottom != null) run.distBottom = distBottom;
|
|
19786
|
+
const distLeft = pickNumber(wrapAttrs.distLeft ?? wrapAttrs.distL);
|
|
19787
|
+
if (distLeft != null) run.distLeft = distLeft;
|
|
19788
|
+
const distRight = pickNumber(wrapAttrs.distRight ?? wrapAttrs.distR);
|
|
19789
|
+
if (distRight != null) run.distRight = distRight;
|
|
19790
|
+
run.verticalAlign = "bottom";
|
|
19791
|
+
const pos = positions.get(node);
|
|
19792
|
+
if (pos) {
|
|
19793
|
+
run.pmStart = pos.start;
|
|
19794
|
+
run.pmEnd = pos.end;
|
|
19795
|
+
}
|
|
19796
|
+
if (activeSdt) {
|
|
19797
|
+
run.sdt = activeSdt;
|
|
19798
|
+
}
|
|
19799
|
+
return run;
|
|
19800
|
+
}
|
|
19572
19801
|
const isTextRun$1 = (run) => run.kind !== "tab";
|
|
19573
19802
|
const dataAttrsCompatible = (a, b) => {
|
|
19574
19803
|
const aAttrs = a.dataAttrs;
|
|
@@ -19609,6 +19838,62 @@ function mergeAdjacentRuns(runs) {
|
|
|
19609
19838
|
merged.push(current);
|
|
19610
19839
|
return merged;
|
|
19611
19840
|
}
|
|
19841
|
+
const extractFirstTextRunFont = (para) => {
|
|
19842
|
+
if (!para.content || !Array.isArray(para.content) || para.content.length === 0) {
|
|
19843
|
+
return void 0;
|
|
19844
|
+
}
|
|
19845
|
+
const extractFontFromMarks = (marks) => {
|
|
19846
|
+
if (!marks || !Array.isArray(marks)) return void 0;
|
|
19847
|
+
const result = {};
|
|
19848
|
+
for (const mark of marks) {
|
|
19849
|
+
if (!mark || typeof mark !== "object") continue;
|
|
19850
|
+
if (mark.type === "textStyle" && mark.attrs) {
|
|
19851
|
+
const attrs = mark.attrs;
|
|
19852
|
+
if (attrs.fontSize != null) {
|
|
19853
|
+
const fontSizeStr = String(attrs.fontSize);
|
|
19854
|
+
const size = parseFloat(fontSizeStr);
|
|
19855
|
+
if (Number.isFinite(size)) {
|
|
19856
|
+
if (fontSizeStr.endsWith("pt")) {
|
|
19857
|
+
result.fontSizePx = ptToPx(size);
|
|
19858
|
+
} else {
|
|
19859
|
+
result.fontSizePx = size;
|
|
19860
|
+
}
|
|
19861
|
+
}
|
|
19862
|
+
}
|
|
19863
|
+
if (typeof attrs.fontFamily === "string") {
|
|
19864
|
+
result.fontFamily = attrs.fontFamily;
|
|
19865
|
+
}
|
|
19866
|
+
}
|
|
19867
|
+
}
|
|
19868
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
19869
|
+
};
|
|
19870
|
+
const findFirstTextFont = (nodes) => {
|
|
19871
|
+
for (const node of nodes) {
|
|
19872
|
+
if (!node) continue;
|
|
19873
|
+
if (node.type === "text") {
|
|
19874
|
+
const font2 = extractFontFromMarks(node.marks);
|
|
19875
|
+
if (font2) return font2;
|
|
19876
|
+
}
|
|
19877
|
+
if (node.type === "run" && Array.isArray(node.content)) {
|
|
19878
|
+
const runFont = extractFontFromMarks(node.marks);
|
|
19879
|
+
const childFont = findFirstTextFont(node.content);
|
|
19880
|
+
if (runFont || childFont) {
|
|
19881
|
+
return {
|
|
19882
|
+
fontSizePx: childFont?.fontSizePx ?? runFont?.fontSizePx,
|
|
19883
|
+
fontFamily: childFont?.fontFamily ?? runFont?.fontFamily
|
|
19884
|
+
};
|
|
19885
|
+
}
|
|
19886
|
+
}
|
|
19887
|
+
if (Array.isArray(node.content)) {
|
|
19888
|
+
const font2 = findFirstTextFont(node.content);
|
|
19889
|
+
if (font2) return font2;
|
|
19890
|
+
}
|
|
19891
|
+
}
|
|
19892
|
+
return void 0;
|
|
19893
|
+
};
|
|
19894
|
+
const font = findFirstTextFont(para.content);
|
|
19895
|
+
return font;
|
|
19896
|
+
};
|
|
19612
19897
|
const applyBaseRunDefaults = (run, defaults, fallbackFont, fallbackSize) => {
|
|
19613
19898
|
if (!run) return;
|
|
19614
19899
|
if (defaults.fontFamily && run.fontFamily === fallbackFont) {
|
|
@@ -19684,6 +19969,22 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
|
|
|
19684
19969
|
}
|
|
19685
19970
|
paragraphAttrs.spacing = spacing;
|
|
19686
19971
|
}
|
|
19972
|
+
if (paragraphAttrs?.numberingProperties && paragraphAttrs?.wordLayout) {
|
|
19973
|
+
const firstRunFont = extractFirstTextRunFont(para);
|
|
19974
|
+
if (firstRunFont) {
|
|
19975
|
+
const wordLayout = paragraphAttrs.wordLayout;
|
|
19976
|
+
const marker = wordLayout.marker;
|
|
19977
|
+
if (marker?.run) {
|
|
19978
|
+
const markerRun = marker.run;
|
|
19979
|
+
if (firstRunFont.fontSizePx != null && Number.isFinite(firstRunFont.fontSizePx)) {
|
|
19980
|
+
markerRun.fontSize = firstRunFont.fontSizePx;
|
|
19981
|
+
}
|
|
19982
|
+
if (firstRunFont.fontFamily) {
|
|
19983
|
+
markerRun.fontFamily = firstRunFont.fontFamily;
|
|
19984
|
+
}
|
|
19985
|
+
}
|
|
19986
|
+
}
|
|
19987
|
+
}
|
|
19687
19988
|
const linkedStyleResolver = createLinkedStyleResolver(converterContext?.linkedStyles);
|
|
19688
19989
|
const blocks = [];
|
|
19689
19990
|
if (hasPageBreakBefore(para)) {
|
|
@@ -19900,6 +20201,13 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
|
|
|
19900
20201
|
return;
|
|
19901
20202
|
}
|
|
19902
20203
|
if (node.type === "image") {
|
|
20204
|
+
if (isInlineImage(node)) {
|
|
20205
|
+
const imageRun = imageNodeToRun(node, positions, activeSdt);
|
|
20206
|
+
if (imageRun) {
|
|
20207
|
+
currentRuns.push(imageRun);
|
|
20208
|
+
}
|
|
20209
|
+
return;
|
|
20210
|
+
}
|
|
19903
20211
|
flushParagraph();
|
|
19904
20212
|
const mergedMarks = [...node.marks ?? [], ...inheritedMarks ?? []];
|
|
19905
20213
|
const trackedMeta = trackedChanges?.enabled ? collectTrackedChangeFromMarks(mergedMarks) : void 0;
|
|
@@ -19999,7 +20307,9 @@ function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defa
|
|
|
19999
20307
|
return;
|
|
20000
20308
|
}
|
|
20001
20309
|
};
|
|
20002
|
-
para.content.forEach((child) =>
|
|
20310
|
+
para.content.forEach((child) => {
|
|
20311
|
+
visitNode(child, [], void 0, null);
|
|
20312
|
+
});
|
|
20003
20313
|
flushParagraph();
|
|
20004
20314
|
const hasParagraphBlock = blocks.some((block) => block.kind === "paragraph");
|
|
20005
20315
|
if (!hasParagraphBlock) {
|
|
@@ -20167,7 +20477,7 @@ const normalizeWrap$2 = (value) => {
|
|
|
20167
20477
|
return void 0;
|
|
20168
20478
|
}
|
|
20169
20479
|
const type = normalizeWrapType$1(value.type);
|
|
20170
|
-
if (!type
|
|
20480
|
+
if (!type) {
|
|
20171
20481
|
return void 0;
|
|
20172
20482
|
}
|
|
20173
20483
|
const wrap = { type };
|
|
@@ -20392,6 +20702,8 @@ const buildDrawingBlock = (rawAttrs, nextBlockId, positions, node, geometry, dra
|
|
|
20392
20702
|
attrsWithPm.pmStart = pos.start;
|
|
20393
20703
|
attrsWithPm.pmEnd = pos.end;
|
|
20394
20704
|
}
|
|
20705
|
+
const zIndexFromRelativeHeight = normalizeZIndex(rawAttrs.originalAttributes);
|
|
20706
|
+
const finalZIndex = zIndexFromRelativeHeight ?? coerceNumber(rawAttrs.zIndex);
|
|
20395
20707
|
return {
|
|
20396
20708
|
kind: "drawing",
|
|
20397
20709
|
id: nextBlockId("drawing"),
|
|
@@ -20400,15 +20712,19 @@ const buildDrawingBlock = (rawAttrs, nextBlockId, positions, node, geometry, dra
|
|
|
20400
20712
|
margin: toBoxSpacing$1(rawAttrs.marginOffset) ?? toBoxSpacing$1(rawAttrs.margin),
|
|
20401
20713
|
anchor: baseAnchor,
|
|
20402
20714
|
wrap: normalizedWrap,
|
|
20403
|
-
zIndex:
|
|
20715
|
+
zIndex: finalZIndex,
|
|
20404
20716
|
drawingContentId: typeof rawAttrs.drawingContentId === "string" ? rawAttrs.drawingContentId : void 0,
|
|
20405
20717
|
drawingContent: toDrawingContentSnapshot(rawAttrs.drawingContent),
|
|
20406
20718
|
attrs: attrsWithPm,
|
|
20407
20719
|
geometry,
|
|
20408
20720
|
shapeKind: typeof rawAttrs.kind === "string" ? rawAttrs.kind : void 0,
|
|
20409
|
-
fillColor:
|
|
20410
|
-
strokeColor:
|
|
20721
|
+
fillColor: normalizeFillColor(rawAttrs.fillColor),
|
|
20722
|
+
strokeColor: normalizeStrokeColor(rawAttrs.strokeColor),
|
|
20411
20723
|
strokeWidth: coerceNumber(rawAttrs.strokeWidth),
|
|
20724
|
+
textContent: normalizeTextContent(rawAttrs.textContent),
|
|
20725
|
+
textAlign: typeof rawAttrs.textAlign === "string" ? rawAttrs.textAlign : void 0,
|
|
20726
|
+
textVerticalAlign: normalizeTextVerticalAlign(rawAttrs.textVerticalAlign),
|
|
20727
|
+
textInsets: normalizeTextInsets(rawAttrs.textInsets),
|
|
20412
20728
|
...extraProps
|
|
20413
20729
|
};
|
|
20414
20730
|
};
|
|
@@ -20585,26 +20901,32 @@ const parseTableCell = (args) => {
|
|
|
20585
20901
|
if (!isTableCellNode(cellNode) || !Array.isArray(cellNode.content)) {
|
|
20586
20902
|
return null;
|
|
20587
20903
|
}
|
|
20588
|
-
const
|
|
20589
|
-
|
|
20904
|
+
const blocks = [];
|
|
20905
|
+
for (const childNode of cellNode.content) {
|
|
20906
|
+
if (childNode.type === "paragraph") {
|
|
20907
|
+
const paragraphBlocks = context.paragraphToFlowBlocks(
|
|
20908
|
+
childNode,
|
|
20909
|
+
context.nextBlockId,
|
|
20910
|
+
context.positions,
|
|
20911
|
+
context.defaultFont,
|
|
20912
|
+
context.defaultSize,
|
|
20913
|
+
context.styleContext,
|
|
20914
|
+
void 0,
|
|
20915
|
+
context.trackedChanges,
|
|
20916
|
+
context.bookmarks,
|
|
20917
|
+
context.hyperlinkConfig,
|
|
20918
|
+
context.themeColors,
|
|
20919
|
+
context.converterContext
|
|
20920
|
+
);
|
|
20921
|
+
const paragraph = paragraphBlocks.find((b) => b.kind === "paragraph");
|
|
20922
|
+
if (paragraph) {
|
|
20923
|
+
blocks.push(paragraph);
|
|
20924
|
+
}
|
|
20925
|
+
}
|
|
20926
|
+
}
|
|
20927
|
+
if (blocks.length === 0) {
|
|
20590
20928
|
return null;
|
|
20591
20929
|
}
|
|
20592
|
-
const paragraphBlocks = context.paragraphToFlowBlocks(
|
|
20593
|
-
paraNode,
|
|
20594
|
-
context.nextBlockId,
|
|
20595
|
-
context.positions,
|
|
20596
|
-
context.defaultFont,
|
|
20597
|
-
context.defaultSize,
|
|
20598
|
-
context.styleContext,
|
|
20599
|
-
void 0,
|
|
20600
|
-
context.trackedChanges,
|
|
20601
|
-
context.bookmarks,
|
|
20602
|
-
context.hyperlinkConfig,
|
|
20603
|
-
context.themeColors,
|
|
20604
|
-
context.converterContext
|
|
20605
|
-
);
|
|
20606
|
-
const paragraph = paragraphBlocks.find((b) => b.kind === "paragraph");
|
|
20607
|
-
if (!paragraph) return null;
|
|
20608
20930
|
const cellAttrs = {};
|
|
20609
20931
|
const borders = extractCellBorders(cellNode.attrs ?? {});
|
|
20610
20932
|
if (borders) cellAttrs.borders = borders;
|
|
@@ -20627,7 +20949,9 @@ const parseTableCell = (args) => {
|
|
|
20627
20949
|
const colSpan = pickNumber(cellNode.attrs?.colspan);
|
|
20628
20950
|
return {
|
|
20629
20951
|
id: context.nextBlockId(`cell-${rowIndex}-${cellIndex}`),
|
|
20630
|
-
|
|
20952
|
+
blocks,
|
|
20953
|
+
// Backward compatibility: set paragraph to first block if it's a paragraph
|
|
20954
|
+
paragraph: blocks[0]?.kind === "paragraph" ? blocks[0] : void 0,
|
|
20631
20955
|
rowSpan: rowSpan ?? void 0,
|
|
20632
20956
|
colSpan: colSpan ?? void 0,
|
|
20633
20957
|
attrs: Object.keys(cellAttrs).length > 0 ? cellAttrs : void 0
|
|
@@ -20722,6 +21046,10 @@ function tableNodeToBlock$1(node, nextBlockId, positions, defaultFont, defaultSi
|
|
|
20722
21046
|
} else if (hydratedTableStyle?.tableWidth) {
|
|
20723
21047
|
tableAttrs.tableWidth = hydratedTableStyle.tableWidth;
|
|
20724
21048
|
}
|
|
21049
|
+
const tableLayout = node.attrs?.tableLayout;
|
|
21050
|
+
if (tableLayout) {
|
|
21051
|
+
tableAttrs.tableLayout = tableLayout;
|
|
21052
|
+
}
|
|
20725
21053
|
let columnWidths = void 0;
|
|
20726
21054
|
const twipsToPixels2 = (twips) => {
|
|
20727
21055
|
const PIXELS_PER_INCH2 = 96;
|
|
@@ -21074,7 +21402,7 @@ function getMeasurementContext() {
|
|
|
21074
21402
|
return measurementCtx;
|
|
21075
21403
|
}
|
|
21076
21404
|
function getRunFontString(run) {
|
|
21077
|
-
if (run.kind === "tab") {
|
|
21405
|
+
if (run.kind === "tab" || run.kind === "image") {
|
|
21078
21406
|
return "normal normal 16px Arial";
|
|
21079
21407
|
}
|
|
21080
21408
|
const style = run.italic ? "italic" : "normal";
|
|
@@ -21093,6 +21421,10 @@ function sliceRunsForLine$1(block, line) {
|
|
|
21093
21421
|
result.push(run);
|
|
21094
21422
|
continue;
|
|
21095
21423
|
}
|
|
21424
|
+
if (run.kind === "image") {
|
|
21425
|
+
result.push(run);
|
|
21426
|
+
continue;
|
|
21427
|
+
}
|
|
21096
21428
|
const text = run.text ?? "";
|
|
21097
21429
|
const isFirstRun = runIndex === line.fromRun;
|
|
21098
21430
|
const isLastRun = runIndex === line.toRun;
|
|
@@ -21120,7 +21452,11 @@ function measureCharacterX(block, line, charOffset) {
|
|
|
21120
21452
|
const runs2 = sliceRunsForLine$1(block, line);
|
|
21121
21453
|
const charsInLine = Math.max(
|
|
21122
21454
|
1,
|
|
21123
|
-
runs2.reduce((sum, run) =>
|
|
21455
|
+
runs2.reduce((sum, run) => {
|
|
21456
|
+
if (isTabRun$1(run)) return sum + TAB_CHAR_LENGTH;
|
|
21457
|
+
if (run.kind === "image") return sum;
|
|
21458
|
+
return sum + (run.text ?? "").length;
|
|
21459
|
+
}, 0)
|
|
21124
21460
|
);
|
|
21125
21461
|
return charOffset / charsInLine * line.width;
|
|
21126
21462
|
}
|
|
@@ -21139,7 +21475,7 @@ function measureCharacterX(block, line, charOffset) {
|
|
|
21139
21475
|
currentCharOffset += runLength2;
|
|
21140
21476
|
continue;
|
|
21141
21477
|
}
|
|
21142
|
-
const text = run.text ?? "";
|
|
21478
|
+
const text = run.kind === "image" ? "" : run.text ?? "";
|
|
21143
21479
|
const runLength = text.length;
|
|
21144
21480
|
if (currentCharOffset + runLength >= charOffset) {
|
|
21145
21481
|
const offsetInRun = charOffset - currentCharOffset;
|
|
@@ -21162,7 +21498,11 @@ function findCharacterAtX(block, line, x, pmStart) {
|
|
|
21162
21498
|
const runs2 = sliceRunsForLine$1(block, line);
|
|
21163
21499
|
const charsInLine = Math.max(
|
|
21164
21500
|
1,
|
|
21165
|
-
runs2.reduce((sum, run) =>
|
|
21501
|
+
runs2.reduce((sum, run) => {
|
|
21502
|
+
if (isTabRun$1(run)) return sum + TAB_CHAR_LENGTH;
|
|
21503
|
+
if (run.kind === "image") return sum;
|
|
21504
|
+
return sum + (run.text ?? "").length;
|
|
21505
|
+
}, 0)
|
|
21166
21506
|
);
|
|
21167
21507
|
const ratio = Math.max(0, Math.min(1, x / line.width));
|
|
21168
21508
|
const charOffset = Math.round(ratio * charsInLine);
|
|
@@ -21195,7 +21535,7 @@ function findCharacterAtX(block, line, x, pmStart) {
|
|
|
21195
21535
|
currentCharOffset += TAB_CHAR_LENGTH;
|
|
21196
21536
|
continue;
|
|
21197
21537
|
}
|
|
21198
|
-
const text = run.text ?? "";
|
|
21538
|
+
const text = run.kind === "image" ? "" : run.text ?? "";
|
|
21199
21539
|
const runLength = text.length;
|
|
21200
21540
|
if (runLength === 0) continue;
|
|
21201
21541
|
ctx2.font = getRunFontString(run);
|
|
@@ -21232,7 +21572,7 @@ function findCharacterAtX(block, line, x, pmStart) {
|
|
|
21232
21572
|
};
|
|
21233
21573
|
}
|
|
21234
21574
|
const computeLetterSpacingWidth = (run, precedingChars, runLength) => {
|
|
21235
|
-
if (run.kind === "
|
|
21575
|
+
if (isTabRun$1(run) || run.kind === "image" || !run.letterSpacing) {
|
|
21236
21576
|
return 0;
|
|
21237
21577
|
}
|
|
21238
21578
|
const maxGaps = Math.max(runLength - 1, 0);
|
|
@@ -21598,14 +21938,8 @@ function computeAnchorX(anchor, columnIndex, columns, imageWidth, margins, pageW
|
|
|
21598
21938
|
baseX = columnLeft;
|
|
21599
21939
|
availableWidth = columns.width;
|
|
21600
21940
|
}
|
|
21601
|
-
|
|
21602
|
-
|
|
21603
|
-
} else if (alignH === "right") {
|
|
21604
|
-
return baseX + availableWidth - imageWidth - offsetH;
|
|
21605
|
-
} else if (alignH === "center") {
|
|
21606
|
-
return baseX + (availableWidth - imageWidth) / 2 + offsetH;
|
|
21607
|
-
}
|
|
21608
|
-
return baseX;
|
|
21941
|
+
const result = alignH === "left" ? baseX + offsetH : alignH === "right" ? baseX + availableWidth - imageWidth - offsetH : alignH === "center" ? baseX + (availableWidth - imageWidth) / 2 + offsetH : baseX;
|
|
21942
|
+
return result;
|
|
21609
21943
|
}
|
|
21610
21944
|
function computeWrapMode(wrap, _anchor) {
|
|
21611
21945
|
if (!wrap) return "none";
|
|
@@ -21834,6 +22168,18 @@ const computeLinePmRange$2 = (block, line) => {
|
|
|
21834
22168
|
for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
|
|
21835
22169
|
const run = block.runs[runIndex];
|
|
21836
22170
|
if (!run) continue;
|
|
22171
|
+
if (run.kind === "image") {
|
|
22172
|
+
const runPmStart2 = run.pmStart ?? void 0;
|
|
22173
|
+
const runPmEnd = run.pmEnd ?? void 0;
|
|
22174
|
+
if (runPmStart2 == null || runPmEnd == null) {
|
|
22175
|
+
continue;
|
|
22176
|
+
}
|
|
22177
|
+
if (pmStart == null) {
|
|
22178
|
+
pmStart = runPmStart2;
|
|
22179
|
+
}
|
|
22180
|
+
pmEnd = runPmEnd;
|
|
22181
|
+
continue;
|
|
22182
|
+
}
|
|
21837
22183
|
const runWithPm = run;
|
|
21838
22184
|
const text = runWithPm.text ?? "";
|
|
21839
22185
|
const runLength = text.length;
|
|
@@ -21867,16 +22213,34 @@ const extractBlockPmRange = (block) => {
|
|
|
21867
22213
|
pmEnd: end2 ?? (start2 != null ? start2 + 1 : void 0)
|
|
21868
22214
|
};
|
|
21869
22215
|
};
|
|
21870
|
-
const
|
|
22216
|
+
const anchorDebugLog = (...args) => {
|
|
22217
|
+
return;
|
|
21871
22218
|
};
|
|
21872
22219
|
function layoutParagraphBlock(ctx2, anchors) {
|
|
21873
22220
|
const { block, measure, columnWidth, ensurePage, advanceColumn, columnX, floatManager } = ctx2;
|
|
21874
22221
|
const remeasureParagraph2 = ctx2.remeasureParagraph;
|
|
22222
|
+
const frame = block.attrs?.frame;
|
|
21875
22223
|
if (anchors?.anchoredDrawings?.length) {
|
|
21876
22224
|
for (const entry of anchors.anchoredDrawings) {
|
|
21877
22225
|
if (anchors.placedAnchoredIds.has(entry.block.id)) continue;
|
|
21878
22226
|
const state = ensurePage();
|
|
21879
|
-
const
|
|
22227
|
+
const baseAnchorY = state.cursorY;
|
|
22228
|
+
const firstLineHeight = measure.lines?.[0]?.lineHeight ?? 0;
|
|
22229
|
+
const vRelativeFrom = entry.block.anchor?.vRelativeFrom;
|
|
22230
|
+
const paragraphAdjustment = vRelativeFrom === "paragraph" ? firstLineHeight / 2 : 0;
|
|
22231
|
+
const anchorY = baseAnchorY + paragraphAdjustment;
|
|
22232
|
+
anchorDebugLog("Positioning anchored image:", {
|
|
22233
|
+
blockId: entry.block.id,
|
|
22234
|
+
baseAnchorY,
|
|
22235
|
+
paragraphAdjustment,
|
|
22236
|
+
anchorY,
|
|
22237
|
+
offsetV: entry.block.anchor?.offsetV,
|
|
22238
|
+
finalY: anchorY + (entry.block.anchor?.offsetV ?? 0),
|
|
22239
|
+
measureHeight: entry.measure.height,
|
|
22240
|
+
measureWidth: entry.measure.width,
|
|
22241
|
+
pageNumber: state.page.number,
|
|
22242
|
+
vRelativeFrom
|
|
22243
|
+
});
|
|
21880
22244
|
floatManager.registerDrawing(entry.block, entry.measure, anchorY, state.columnIndex, state.page.number);
|
|
21881
22245
|
const anchorX = entry.block.anchor ? computeAnchorX(
|
|
21882
22246
|
entry.block.anchor,
|
|
@@ -21888,6 +22252,30 @@ function layoutParagraphBlock(ctx2, anchors) {
|
|
|
21888
22252
|
) : columnX(state.columnIndex);
|
|
21889
22253
|
const pmRange = extractBlockPmRange(entry.block);
|
|
21890
22254
|
if (entry.block.kind === "image" && entry.measure.kind === "image") {
|
|
22255
|
+
const pageContentHeight = Math.max(0, state.contentBottom - state.topMargin);
|
|
22256
|
+
const relativeFrom = entry.block.anchor?.hRelativeFrom ?? "column";
|
|
22257
|
+
const marginLeft = anchors.pageMargins.left ?? 0;
|
|
22258
|
+
const marginRight = anchors.pageMargins.right ?? 0;
|
|
22259
|
+
let maxWidth;
|
|
22260
|
+
if (relativeFrom === "page") {
|
|
22261
|
+
maxWidth = anchors.columns.count === 1 ? anchors.pageWidth - marginLeft - marginRight : anchors.pageWidth;
|
|
22262
|
+
} else if (relativeFrom === "margin") {
|
|
22263
|
+
maxWidth = anchors.pageWidth - marginLeft - marginRight;
|
|
22264
|
+
} else {
|
|
22265
|
+
maxWidth = anchors.columns.width;
|
|
22266
|
+
}
|
|
22267
|
+
const aspectRatio = entry.measure.width > 0 && entry.measure.height > 0 ? entry.measure.width / entry.measure.height : 1;
|
|
22268
|
+
const minWidth = 20;
|
|
22269
|
+
const minHeight = minWidth / aspectRatio;
|
|
22270
|
+
const metadata = {
|
|
22271
|
+
originalWidth: entry.measure.width,
|
|
22272
|
+
originalHeight: entry.measure.height,
|
|
22273
|
+
maxWidth,
|
|
22274
|
+
maxHeight: pageContentHeight,
|
|
22275
|
+
aspectRatio,
|
|
22276
|
+
minWidth,
|
|
22277
|
+
minHeight
|
|
22278
|
+
};
|
|
21891
22279
|
const fragment = {
|
|
21892
22280
|
kind: "image",
|
|
21893
22281
|
blockId: entry.block.id,
|
|
@@ -21896,7 +22284,8 @@ function layoutParagraphBlock(ctx2, anchors) {
|
|
|
21896
22284
|
width: entry.measure.width,
|
|
21897
22285
|
height: entry.measure.height,
|
|
21898
22286
|
isAnchored: true,
|
|
21899
|
-
zIndex: entry.block.anchor?.behindDoc ? 0 : 1
|
|
22287
|
+
zIndex: entry.block.anchor?.behindDoc ? 0 : 1,
|
|
22288
|
+
metadata
|
|
21900
22289
|
};
|
|
21901
22290
|
if (pmRange.pmStart != null) fragment.pmStart = pmRange.pmStart;
|
|
21902
22291
|
if (pmRange.pmEnd != null) fragment.pmEnd = pmRange.pmEnd;
|
|
@@ -21932,13 +22321,41 @@ function layoutParagraphBlock(ctx2, anchors) {
|
|
|
21932
22321
|
const spacingAfter = Math.max(0, Number(spacing.after ?? spacing.lineSpaceAfter ?? 0));
|
|
21933
22322
|
let appliedSpacingBefore = spacingBefore === 0;
|
|
21934
22323
|
let lastState = null;
|
|
21935
|
-
|
|
21936
|
-
|
|
22324
|
+
const isPositionedFrame = frame?.wrap === "none";
|
|
22325
|
+
if (isPositionedFrame) {
|
|
22326
|
+
let state = ensurePage();
|
|
22327
|
+
if (state.cursorY >= state.contentBottom) {
|
|
22328
|
+
state = advanceColumn(state);
|
|
22329
|
+
}
|
|
22330
|
+
const maxLineWidth = lines.reduce((max2, line) => Math.max(max2, line.width ?? 0), 0);
|
|
22331
|
+
const fragmentWidth = maxLineWidth || columnWidth;
|
|
22332
|
+
let x = columnX(state.columnIndex);
|
|
22333
|
+
if (frame.xAlign === "right") {
|
|
22334
|
+
x += columnWidth - fragmentWidth;
|
|
22335
|
+
} else if (frame.xAlign === "center") {
|
|
22336
|
+
x += (columnWidth - fragmentWidth) / 2;
|
|
22337
|
+
}
|
|
22338
|
+
if (typeof frame.x === "number" && Number.isFinite(frame.x)) {
|
|
22339
|
+
x += frame.x;
|
|
22340
|
+
}
|
|
22341
|
+
const yOffset = typeof frame.y === "number" && Number.isFinite(frame.y) ? frame.y : 0;
|
|
22342
|
+
const fragment = {
|
|
22343
|
+
kind: "para",
|
|
21937
22344
|
blockId: block.id,
|
|
21938
|
-
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
22345
|
+
fromLine: 0,
|
|
22346
|
+
toLine: lines.length,
|
|
22347
|
+
x,
|
|
22348
|
+
y: state.cursorY + yOffset,
|
|
22349
|
+
width: fragmentWidth,
|
|
22350
|
+
...computeFragmentPmRange(block, lines, 0, lines.length)
|
|
22351
|
+
};
|
|
22352
|
+
if (measure.marker) {
|
|
22353
|
+
fragment.markerWidth = measure.marker.markerWidth;
|
|
22354
|
+
}
|
|
22355
|
+
state.page.fragments.push(fragment);
|
|
22356
|
+
state.trailingSpacing = 0;
|
|
22357
|
+
state.lastParagraphStyleId = styleId;
|
|
22358
|
+
return;
|
|
21942
22359
|
}
|
|
21943
22360
|
let didRemeasureForFloats = false;
|
|
21944
22361
|
while (fromLine < lines.length) {
|
|
@@ -21957,54 +22374,13 @@ function layoutParagraphBlock(ctx2, anchors) {
|
|
|
21957
22374
|
while (!appliedSpacingBefore) {
|
|
21958
22375
|
const prevTrailing = state.trailingSpacing ?? 0;
|
|
21959
22376
|
const neededSpacingBefore = Math.max(spacingBefore - prevTrailing, 0);
|
|
21960
|
-
{
|
|
21961
|
-
spacingDebugLog("spacingBefore pending", {
|
|
21962
|
-
blockId: block.id,
|
|
21963
|
-
cursorY: state.cursorY,
|
|
21964
|
-
contentBottom: state.contentBottom,
|
|
21965
|
-
spacingBefore,
|
|
21966
|
-
prevTrailing,
|
|
21967
|
-
neededSpacingBefore,
|
|
21968
|
-
column: state.columnIndex,
|
|
21969
|
-
page: state.page.number
|
|
21970
|
-
});
|
|
21971
|
-
}
|
|
21972
22377
|
if (state.cursorY + neededSpacingBefore > state.contentBottom) {
|
|
21973
|
-
{
|
|
21974
|
-
spacingDebugLog("spacingBefore triggers column advance", {
|
|
21975
|
-
blockId: block.id,
|
|
21976
|
-
cursorY: state.cursorY,
|
|
21977
|
-
spacingBefore,
|
|
21978
|
-
neededSpacingBefore,
|
|
21979
|
-
prevTrailing,
|
|
21980
|
-
column: state.columnIndex,
|
|
21981
|
-
page: state.page.number
|
|
21982
|
-
});
|
|
21983
|
-
}
|
|
21984
22378
|
state = advanceColumn(state);
|
|
21985
22379
|
if (state.trailingSpacing == null) state.trailingSpacing = 0;
|
|
21986
22380
|
continue;
|
|
21987
22381
|
}
|
|
21988
22382
|
if (neededSpacingBefore > 0) {
|
|
21989
22383
|
state.cursorY += neededSpacingBefore;
|
|
21990
|
-
{
|
|
21991
|
-
spacingDebugLog("spacingBefore applied", {
|
|
21992
|
-
blockId: block.id,
|
|
21993
|
-
added: neededSpacingBefore,
|
|
21994
|
-
prevTrailing,
|
|
21995
|
-
newCursorY: state.cursorY,
|
|
21996
|
-
column: state.columnIndex,
|
|
21997
|
-
page: state.page.number
|
|
21998
|
-
});
|
|
21999
|
-
}
|
|
22000
|
-
} else if (prevTrailing > 0) {
|
|
22001
|
-
spacingDebugLog("spacingBefore collapsed by trailing spacing", {
|
|
22002
|
-
blockId: block.id,
|
|
22003
|
-
prevTrailing,
|
|
22004
|
-
spacingBefore,
|
|
22005
|
-
column: state.columnIndex,
|
|
22006
|
-
page: state.page.number
|
|
22007
|
-
});
|
|
22008
22384
|
}
|
|
22009
22385
|
state.trailingSpacing = 0;
|
|
22010
22386
|
appliedSpacingBefore = true;
|
|
@@ -22056,18 +22432,18 @@ function layoutParagraphBlock(ctx2, anchors) {
|
|
|
22056
22432
|
width: effectiveColumnWidth,
|
|
22057
22433
|
...computeFragmentPmRange(block, lines, fromLine, slice2.toLine)
|
|
22058
22434
|
};
|
|
22435
|
+
anchorDebugLog("Positioning paragraph fragment:", {
|
|
22436
|
+
blockId: block.id,
|
|
22437
|
+
fragmentY: state.cursorY,
|
|
22438
|
+
fragmentHeight,
|
|
22439
|
+
firstLineHeight: lines[fromLine]?.lineHeight,
|
|
22440
|
+
firstLineAscent: lines[fromLine]?.ascent,
|
|
22441
|
+
firstLineDescent: lines[fromLine]?.descent,
|
|
22442
|
+
pageNumber: state.page.number
|
|
22443
|
+
});
|
|
22059
22444
|
if (measure.marker && fromLine === 0) {
|
|
22060
22445
|
fragment.markerWidth = measure.marker.markerWidth;
|
|
22061
22446
|
}
|
|
22062
|
-
if (process$1.env.NODE_ENV !== "production" && measure.marker && fromLine === 0) {
|
|
22063
|
-
console.log("[layoutParagraphBlock] fragment marker info", {
|
|
22064
|
-
blockId: block.id,
|
|
22065
|
-
indent: block.attrs?.indent,
|
|
22066
|
-
markerWidth: fragment.markerWidth,
|
|
22067
|
-
textWidth: fragment.width,
|
|
22068
|
-
marker: measure.marker
|
|
22069
|
-
});
|
|
22070
|
-
}
|
|
22071
22447
|
if (fromLine > 0) fragment.continuesFromPrev = true;
|
|
22072
22448
|
if (slice2.toLine < lines.length) fragment.continuesOnNext = true;
|
|
22073
22449
|
const floatAlignment = block.attrs?.floatAlignment;
|
|
@@ -22094,30 +22470,12 @@ function layoutParagraphBlock(ctx2, anchors) {
|
|
|
22094
22470
|
let targetState = lastState;
|
|
22095
22471
|
let appliedSpacingAfter = spacingAfter;
|
|
22096
22472
|
if (targetState.cursorY + spacingAfter > targetState.contentBottom) {
|
|
22097
|
-
{
|
|
22098
|
-
spacingDebugLog("spacingAfter triggers column advance", {
|
|
22099
|
-
blockId: block.id,
|
|
22100
|
-
cursorY: targetState.cursorY,
|
|
22101
|
-
spacingAfter,
|
|
22102
|
-
column: targetState.columnIndex,
|
|
22103
|
-
page: targetState.page.number
|
|
22104
|
-
});
|
|
22105
|
-
}
|
|
22106
22473
|
targetState = advanceColumn(targetState);
|
|
22107
22474
|
appliedSpacingAfter = 0;
|
|
22108
22475
|
} else {
|
|
22109
22476
|
targetState.cursorY += spacingAfter;
|
|
22110
22477
|
}
|
|
22111
22478
|
targetState.trailingSpacing = appliedSpacingAfter;
|
|
22112
|
-
{
|
|
22113
|
-
spacingDebugLog("spacingAfter applied", {
|
|
22114
|
-
blockId: block.id,
|
|
22115
|
-
appliedSpacingAfter,
|
|
22116
|
-
newCursorY: targetState.cursorY,
|
|
22117
|
-
column: targetState.columnIndex,
|
|
22118
|
-
page: targetState.page.number
|
|
22119
|
-
});
|
|
22120
|
-
}
|
|
22121
22479
|
} else {
|
|
22122
22480
|
lastState.trailingSpacing = 0;
|
|
22123
22481
|
}
|
|
@@ -22159,6 +22517,18 @@ function layoutImageBlock({
|
|
|
22159
22517
|
state = advanceColumn(state);
|
|
22160
22518
|
}
|
|
22161
22519
|
const pmRange = extractBlockPmRange(block);
|
|
22520
|
+
const aspectRatio = measure.width > 0 && measure.height > 0 ? measure.width / measure.height : 1;
|
|
22521
|
+
const minWidth = 20;
|
|
22522
|
+
const minHeight = minWidth / aspectRatio;
|
|
22523
|
+
const metadata = {
|
|
22524
|
+
originalWidth: measure.width,
|
|
22525
|
+
originalHeight: measure.height,
|
|
22526
|
+
maxWidth,
|
|
22527
|
+
maxHeight: pageContentHeight,
|
|
22528
|
+
aspectRatio,
|
|
22529
|
+
minWidth,
|
|
22530
|
+
minHeight
|
|
22531
|
+
};
|
|
22162
22532
|
const fragment = {
|
|
22163
22533
|
kind: "image",
|
|
22164
22534
|
blockId: block.id,
|
|
@@ -22167,7 +22537,8 @@ function layoutImageBlock({
|
|
|
22167
22537
|
width,
|
|
22168
22538
|
height,
|
|
22169
22539
|
pmStart: pmRange.pmStart,
|
|
22170
|
-
pmEnd: pmRange.pmEnd
|
|
22540
|
+
pmEnd: pmRange.pmEnd,
|
|
22541
|
+
metadata
|
|
22171
22542
|
};
|
|
22172
22543
|
state.page.fragments.push(fragment);
|
|
22173
22544
|
state.cursorY += requiredHeight;
|
|
@@ -22398,6 +22769,175 @@ function createPaginator(opts) {
|
|
|
22398
22769
|
getActiveColumnsForState
|
|
22399
22770
|
};
|
|
22400
22771
|
}
|
|
22772
|
+
function toUpperRoman(num) {
|
|
22773
|
+
if (num < 1 || num > 3999) {
|
|
22774
|
+
return String(num);
|
|
22775
|
+
}
|
|
22776
|
+
const values = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
|
|
22777
|
+
const numerals = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
|
|
22778
|
+
let result = "";
|
|
22779
|
+
let remaining = num;
|
|
22780
|
+
for (let i = 0; i < values.length; i++) {
|
|
22781
|
+
while (remaining >= values[i]) {
|
|
22782
|
+
result += numerals[i];
|
|
22783
|
+
remaining -= values[i];
|
|
22784
|
+
}
|
|
22785
|
+
}
|
|
22786
|
+
return result;
|
|
22787
|
+
}
|
|
22788
|
+
function toLowerRoman(num) {
|
|
22789
|
+
return toUpperRoman(num).toLowerCase();
|
|
22790
|
+
}
|
|
22791
|
+
function toUpperLetter(num) {
|
|
22792
|
+
if (num < 1) {
|
|
22793
|
+
return "A";
|
|
22794
|
+
}
|
|
22795
|
+
let result = "";
|
|
22796
|
+
let n = num;
|
|
22797
|
+
while (n > 0) {
|
|
22798
|
+
const remainder = (n - 1) % 26;
|
|
22799
|
+
result = String.fromCharCode(65 + remainder) + result;
|
|
22800
|
+
n = Math.floor((n - 1) / 26);
|
|
22801
|
+
}
|
|
22802
|
+
return result;
|
|
22803
|
+
}
|
|
22804
|
+
function toLowerLetter(num) {
|
|
22805
|
+
return toUpperLetter(num).toLowerCase();
|
|
22806
|
+
}
|
|
22807
|
+
function formatPageNumber$1(pageNumber, format) {
|
|
22808
|
+
const num = Math.max(1, pageNumber);
|
|
22809
|
+
switch (format) {
|
|
22810
|
+
case "decimal":
|
|
22811
|
+
return String(num);
|
|
22812
|
+
case "upperRoman":
|
|
22813
|
+
return toUpperRoman(num);
|
|
22814
|
+
case "lowerRoman":
|
|
22815
|
+
return toLowerRoman(num);
|
|
22816
|
+
case "upperLetter":
|
|
22817
|
+
return toUpperLetter(num);
|
|
22818
|
+
case "lowerLetter":
|
|
22819
|
+
return toLowerLetter(num);
|
|
22820
|
+
default:
|
|
22821
|
+
return String(num);
|
|
22822
|
+
}
|
|
22823
|
+
}
|
|
22824
|
+
function computeDisplayPageNumber(pages, sections) {
|
|
22825
|
+
const result = [];
|
|
22826
|
+
if (pages.length === 0) {
|
|
22827
|
+
return result;
|
|
22828
|
+
}
|
|
22829
|
+
const sectionMap = /* @__PURE__ */ new Map();
|
|
22830
|
+
for (const section of sections) {
|
|
22831
|
+
sectionMap.set(section.sectionIndex, section);
|
|
22832
|
+
}
|
|
22833
|
+
let runningCounter = 1;
|
|
22834
|
+
let currentSectionIndex = -1;
|
|
22835
|
+
for (let i = 0; i < pages.length; i++) {
|
|
22836
|
+
const page = pages[i];
|
|
22837
|
+
const pageSectionIndex = 0;
|
|
22838
|
+
if (pageSectionIndex !== currentSectionIndex) {
|
|
22839
|
+
const sectionMetadata2 = sectionMap.get(pageSectionIndex);
|
|
22840
|
+
if (sectionMetadata2?.numbering?.start !== void 0) {
|
|
22841
|
+
runningCounter = sectionMetadata2.numbering.start;
|
|
22842
|
+
}
|
|
22843
|
+
currentSectionIndex = pageSectionIndex;
|
|
22844
|
+
}
|
|
22845
|
+
const sectionMetadata = sectionMap.get(pageSectionIndex);
|
|
22846
|
+
const format = sectionMetadata?.numbering?.format ?? "decimal";
|
|
22847
|
+
const displayNumber = runningCounter;
|
|
22848
|
+
const displayText = formatPageNumber$1(displayNumber, format);
|
|
22849
|
+
result.push({
|
|
22850
|
+
physicalPage: page.number,
|
|
22851
|
+
displayNumber,
|
|
22852
|
+
displayText,
|
|
22853
|
+
sectionIndex: pageSectionIndex
|
|
22854
|
+
});
|
|
22855
|
+
runningCounter++;
|
|
22856
|
+
}
|
|
22857
|
+
return result;
|
|
22858
|
+
}
|
|
22859
|
+
function resolvePageNumberTokens(layout, blocks, measures, numberingCtx) {
|
|
22860
|
+
const affectedBlockIds = /* @__PURE__ */ new Set();
|
|
22861
|
+
const updatedBlocks = /* @__PURE__ */ new Map();
|
|
22862
|
+
if (!layout?.pages || layout.pages.length === 0) {
|
|
22863
|
+
return { affectedBlockIds, updatedBlocks };
|
|
22864
|
+
}
|
|
22865
|
+
if (!numberingCtx || !numberingCtx.displayPages || numberingCtx.totalPages < 1) {
|
|
22866
|
+
console.warn("[resolvePageTokens] Invalid numbering context - skipping resolution");
|
|
22867
|
+
return { affectedBlockIds, updatedBlocks };
|
|
22868
|
+
}
|
|
22869
|
+
const blockMap = /* @__PURE__ */ new Map();
|
|
22870
|
+
const blockHasTokensFlags = /* @__PURE__ */ new Map();
|
|
22871
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
22872
|
+
const block = blocks[i];
|
|
22873
|
+
blockMap.set(block.id, block);
|
|
22874
|
+
if (block.kind === "paragraph" && block.attrs && "hasPageTokens" in block.attrs) {
|
|
22875
|
+
blockHasTokensFlags.set(block.id, Boolean(block.attrs.hasPageTokens));
|
|
22876
|
+
}
|
|
22877
|
+
}
|
|
22878
|
+
const totalPagesStr = String(numberingCtx.totalPages);
|
|
22879
|
+
const processedBlocks = /* @__PURE__ */ new Set();
|
|
22880
|
+
for (const page of layout.pages) {
|
|
22881
|
+
const pageIndex = page.number - 1;
|
|
22882
|
+
const displayPageInfo = numberingCtx.displayPages[pageIndex];
|
|
22883
|
+
if (!displayPageInfo) {
|
|
22884
|
+
console.warn(`[resolvePageTokens] No display page info for page ${page.number} - skipping`);
|
|
22885
|
+
continue;
|
|
22886
|
+
}
|
|
22887
|
+
const displayPageText = displayPageInfo.displayText;
|
|
22888
|
+
for (const fragment of page.fragments) {
|
|
22889
|
+
if (fragment.kind !== "para") continue;
|
|
22890
|
+
const blockId = fragment.blockId;
|
|
22891
|
+
if (processedBlocks.has(blockId)) continue;
|
|
22892
|
+
const hasTokensFlag = blockHasTokensFlags.get(blockId);
|
|
22893
|
+
if (hasTokensFlag === false) continue;
|
|
22894
|
+
const block = blockMap.get(blockId);
|
|
22895
|
+
if (!block || block.kind !== "paragraph") continue;
|
|
22896
|
+
const wasModified = hasPageTokens$1(block);
|
|
22897
|
+
if (!wasModified) {
|
|
22898
|
+
processedBlocks.add(blockId);
|
|
22899
|
+
continue;
|
|
22900
|
+
}
|
|
22901
|
+
const clonedBlock = cloneBlockWithResolvedTokens(block, displayPageText, totalPagesStr);
|
|
22902
|
+
updatedBlocks.set(blockId, clonedBlock);
|
|
22903
|
+
affectedBlockIds.add(blockId);
|
|
22904
|
+
processedBlocks.add(blockId);
|
|
22905
|
+
}
|
|
22906
|
+
}
|
|
22907
|
+
return { affectedBlockIds, updatedBlocks };
|
|
22908
|
+
}
|
|
22909
|
+
function hasPageTokens$1(block) {
|
|
22910
|
+
for (const run of block.runs) {
|
|
22911
|
+
if ("token" in run && (run.token === "pageNumber" || run.token === "totalPageCount")) {
|
|
22912
|
+
return true;
|
|
22913
|
+
}
|
|
22914
|
+
}
|
|
22915
|
+
return false;
|
|
22916
|
+
}
|
|
22917
|
+
function cloneBlockWithResolvedTokens(block, displayPageText, totalPagesStr) {
|
|
22918
|
+
const clonedRuns = block.runs.map((run) => {
|
|
22919
|
+
if ("token" in run && run.token) {
|
|
22920
|
+
if (run.token === "pageNumber") {
|
|
22921
|
+
const { token: _token, ...runWithoutToken } = run;
|
|
22922
|
+
return {
|
|
22923
|
+
...runWithoutToken,
|
|
22924
|
+
text: displayPageText
|
|
22925
|
+
};
|
|
22926
|
+
} else if (run.token === "totalPageCount") {
|
|
22927
|
+
const { token: _token, ...runWithoutToken } = run;
|
|
22928
|
+
return {
|
|
22929
|
+
...runWithoutToken,
|
|
22930
|
+
text: totalPagesStr
|
|
22931
|
+
};
|
|
22932
|
+
}
|
|
22933
|
+
}
|
|
22934
|
+
return run;
|
|
22935
|
+
});
|
|
22936
|
+
return {
|
|
22937
|
+
...block,
|
|
22938
|
+
runs: clonedRuns
|
|
22939
|
+
};
|
|
22940
|
+
}
|
|
22401
22941
|
const DEFAULT_PAGE_SIZE$2 = { w: 612, h: 792 };
|
|
22402
22942
|
const DEFAULT_MARGINS$2 = { top: 72, right: 72, bottom: 72, left: 72 };
|
|
22403
22943
|
const COLUMN_EPSILON = 1e-4;
|
|
@@ -22854,7 +23394,7 @@ function layoutDocument(blocks, measures, options = {}) {
|
|
|
22854
23394
|
throw new Error(`layoutDocument: expected paragraph measure for block ${block.id}`);
|
|
22855
23395
|
}
|
|
22856
23396
|
const paraBlock = block;
|
|
22857
|
-
const isEmpty2 = !paraBlock.runs || paraBlock.runs.length === 0 || paraBlock.runs.length === 1 && (!paraBlock.runs[0].text || paraBlock.runs[0].text === "");
|
|
23397
|
+
const isEmpty2 = !paraBlock.runs || paraBlock.runs.length === 0 || paraBlock.runs.length === 1 && (!paraBlock.runs[0].kind || paraBlock.runs[0].kind === "text") && (!paraBlock.runs[0].text || paraBlock.runs[0].text === "");
|
|
22858
23398
|
if (isEmpty2) {
|
|
22859
23399
|
const prevBlock = index2 > 0 ? blocks[index2 - 1] : null;
|
|
22860
23400
|
const nextBlock = index2 < blocks.length - 1 ? blocks[index2 + 1] : null;
|
|
@@ -22980,7 +23520,21 @@ function layoutHeaderFooter(blocks, measures, constraints) {
|
|
|
22980
23520
|
if (!Number.isFinite(height) || height <= 0) {
|
|
22981
23521
|
throw new Error("layoutHeaderFooter: height must be positive");
|
|
22982
23522
|
}
|
|
22983
|
-
const
|
|
23523
|
+
const marginLeft = constraints.margins?.left ?? 0;
|
|
23524
|
+
const transformedBlocks = marginLeft > 0 ? blocks.map((block) => {
|
|
23525
|
+
const hasPageRelativeAnchor = (block.kind === "image" || block.kind === "drawing") && block.anchor?.hRelativeFrom === "page" && block.anchor.offsetH != null;
|
|
23526
|
+
if (hasPageRelativeAnchor) {
|
|
23527
|
+
return {
|
|
23528
|
+
...block,
|
|
23529
|
+
anchor: {
|
|
23530
|
+
...block.anchor,
|
|
23531
|
+
offsetH: block.anchor.offsetH - marginLeft
|
|
23532
|
+
}
|
|
23533
|
+
};
|
|
23534
|
+
}
|
|
23535
|
+
return block;
|
|
23536
|
+
}) : blocks;
|
|
23537
|
+
const layout = layoutDocument(transformedBlocks, measures, {
|
|
22984
23538
|
pageSize: { w: width, h: height },
|
|
22985
23539
|
margins: { top: 0, right: 0, bottom: 0, left: 0 }
|
|
22986
23540
|
});
|
|
@@ -23074,7 +23628,7 @@ const hashRuns = (block) => {
|
|
|
23074
23628
|
const trackedMode = block.attrs && "trackedChangesMode" in block.attrs && block.attrs.trackedChangesMode || "review";
|
|
23075
23629
|
const trackedEnabled = resolveTrackedChangesEnabled(block.attrs, true);
|
|
23076
23630
|
const runsHash = block.runs.map((run) => {
|
|
23077
|
-
const text = normalizeText(run.text ?? "");
|
|
23631
|
+
const text = normalizeText(run.kind === "image" ? "" : run.text ?? "");
|
|
23078
23632
|
const bold = "bold" in run ? run.bold : false;
|
|
23079
23633
|
const italic = "italic" in run ? run.italic : false;
|
|
23080
23634
|
const color = "color" in run ? run.color : void 0;
|
|
@@ -23253,6 +23807,358 @@ class MeasureCache {
|
|
|
23253
23807
|
return `${block.id}@${safeWidth}x${safeHeight}:${hash2}`;
|
|
23254
23808
|
}
|
|
23255
23809
|
}
|
|
23810
|
+
function resolveHeaderFooterTokens(blocks, pageNumber, totalPages) {
|
|
23811
|
+
if (!blocks || blocks.length === 0) {
|
|
23812
|
+
return;
|
|
23813
|
+
}
|
|
23814
|
+
if (!Number.isFinite(pageNumber) || pageNumber < 1) {
|
|
23815
|
+
console.warn("[resolveHeaderFooterTokens] Invalid pageNumber:", pageNumber, "- using 1 as fallback");
|
|
23816
|
+
pageNumber = 1;
|
|
23817
|
+
}
|
|
23818
|
+
if (!Number.isFinite(totalPages) || totalPages < 1) {
|
|
23819
|
+
console.warn("[resolveHeaderFooterTokens] Invalid totalPages:", totalPages, "- using 1 as fallback");
|
|
23820
|
+
totalPages = 1;
|
|
23821
|
+
}
|
|
23822
|
+
const pageNumberStr = String(pageNumber);
|
|
23823
|
+
const totalPagesStr = String(totalPages);
|
|
23824
|
+
for (const block of blocks) {
|
|
23825
|
+
if (block.kind !== "paragraph") continue;
|
|
23826
|
+
const paraBlock = block;
|
|
23827
|
+
for (const run of paraBlock.runs) {
|
|
23828
|
+
if ("token" in run && run.token) {
|
|
23829
|
+
if (run.token === "pageNumber") {
|
|
23830
|
+
run.text = pageNumberStr;
|
|
23831
|
+
} else if (run.token === "totalPageCount") {
|
|
23832
|
+
run.text = totalPagesStr;
|
|
23833
|
+
}
|
|
23834
|
+
}
|
|
23835
|
+
}
|
|
23836
|
+
}
|
|
23837
|
+
}
|
|
23838
|
+
function cloneHeaderFooterBlocks(blocks) {
|
|
23839
|
+
if (!blocks || blocks.length === 0) {
|
|
23840
|
+
return [];
|
|
23841
|
+
}
|
|
23842
|
+
return blocks.map((block) => {
|
|
23843
|
+
if (block.kind === "paragraph") {
|
|
23844
|
+
const paraBlock = block;
|
|
23845
|
+
return {
|
|
23846
|
+
...paraBlock,
|
|
23847
|
+
runs: paraBlock.runs.map((run) => ({ ...run })),
|
|
23848
|
+
attrs: paraBlock.attrs ? { ...paraBlock.attrs } : void 0
|
|
23849
|
+
};
|
|
23850
|
+
}
|
|
23851
|
+
return { ...block };
|
|
23852
|
+
});
|
|
23853
|
+
}
|
|
23854
|
+
function isEnabled(envVar, defaultValue) {
|
|
23855
|
+
if (typeof process$1 === "undefined" || typeof process$1.env === "undefined") {
|
|
23856
|
+
return defaultValue;
|
|
23857
|
+
}
|
|
23858
|
+
const value = process$1.env[envVar];
|
|
23859
|
+
if (value === "true" || value === "1") {
|
|
23860
|
+
return true;
|
|
23861
|
+
}
|
|
23862
|
+
if (value === "false" || value === "0") {
|
|
23863
|
+
return false;
|
|
23864
|
+
}
|
|
23865
|
+
return defaultValue;
|
|
23866
|
+
}
|
|
23867
|
+
const FeatureFlags = {
|
|
23868
|
+
/**
|
|
23869
|
+
* Enable section-aware numbering with restarts and format changes.
|
|
23870
|
+
* When disabled, falls back to simple 1-N sequential numbering.
|
|
23871
|
+
*/
|
|
23872
|
+
NUMBERING_SECTION_AWARE: isEnabled("SD_NUMBERING_SECTION_AWARE", true),
|
|
23873
|
+
/**
|
|
23874
|
+
* Enable body page token resolution (PAGE/NUMPAGES in document content).
|
|
23875
|
+
* When disabled, tokens remain as placeholders in body content.
|
|
23876
|
+
*/
|
|
23877
|
+
BODY_PAGE_TOKENS: isEnabled("SD_BODY_PAGE_TOKENS", true),
|
|
23878
|
+
/**
|
|
23879
|
+
* Enable header/footer page token resolution.
|
|
23880
|
+
* When disabled, headers/footers use painter-time token rendering fallback.
|
|
23881
|
+
*/
|
|
23882
|
+
HEADER_FOOTER_PAGE_TOKENS: isEnabled("SD_HEADER_FOOTER_PAGE_TOKENS", true),
|
|
23883
|
+
/**
|
|
23884
|
+
* Enable digit bucketing for header/footer caching in large documents.
|
|
23885
|
+
* When disabled, creates per-page layouts for all documents (no bucketing).
|
|
23886
|
+
* Recommended to keep enabled for documents with 100+ pages.
|
|
23887
|
+
*/
|
|
23888
|
+
HF_DIGIT_BUCKETING: isEnabled("SD_HF_DIGIT_BUCKETING", true),
|
|
23889
|
+
/**
|
|
23890
|
+
* Enable debug logging for page token resolution.
|
|
23891
|
+
* Logs token resolution details, affected blocks, and convergence iteration info.
|
|
23892
|
+
* Should be disabled in production (only enabled for debugging).
|
|
23893
|
+
*/
|
|
23894
|
+
DEBUG_PAGE_TOKENS: isEnabled("SD_DEBUG_PAGE_TOKENS", false),
|
|
23895
|
+
/**
|
|
23896
|
+
* Enable debug logging for header/footer cache operations.
|
|
23897
|
+
* Logs cache hits, misses, invalidations, and bucket selection.
|
|
23898
|
+
* Should be disabled in production (only enabled for debugging).
|
|
23899
|
+
*/
|
|
23900
|
+
DEBUG_HF_CACHE: isEnabled("SD_DEBUG_HF_CACHE", false)
|
|
23901
|
+
};
|
|
23902
|
+
const PageTokenLogger = {
|
|
23903
|
+
/**
|
|
23904
|
+
* Logs the start of token resolution.
|
|
23905
|
+
*
|
|
23906
|
+
* @param iteration - Current iteration number (0-based)
|
|
23907
|
+
* @param totalPages - Total number of pages in the document
|
|
23908
|
+
*/
|
|
23909
|
+
logIterationStart(iteration, totalPages) {
|
|
23910
|
+
if (!FeatureFlags.DEBUG_PAGE_TOKENS) return;
|
|
23911
|
+
console.log(`[PageTokens] Iteration ${iteration}: Resolving tokens for ${totalPages} pages`);
|
|
23912
|
+
},
|
|
23913
|
+
/**
|
|
23914
|
+
* Logs affected blocks during token resolution.
|
|
23915
|
+
*
|
|
23916
|
+
* @param iteration - Current iteration number (0-based)
|
|
23917
|
+
* @param affectedBlockIds - Set of affected block IDs
|
|
23918
|
+
* @param blockSamples - Sample block IDs for debugging (first 5)
|
|
23919
|
+
*/
|
|
23920
|
+
logAffectedBlocks(iteration, affectedBlockIds, blockSamples = []) {
|
|
23921
|
+
if (!FeatureFlags.DEBUG_PAGE_TOKENS) return;
|
|
23922
|
+
const count = affectedBlockIds.size;
|
|
23923
|
+
const samples = blockSamples.slice(0, 5).join(", ");
|
|
23924
|
+
console.log(
|
|
23925
|
+
`[PageTokens] Iteration ${iteration}: ${count} blocks affected`,
|
|
23926
|
+
samples ? `(samples: ${samples})` : ""
|
|
23927
|
+
);
|
|
23928
|
+
},
|
|
23929
|
+
/**
|
|
23930
|
+
* Logs convergence status.
|
|
23931
|
+
*
|
|
23932
|
+
* @param iteration - Final iteration number
|
|
23933
|
+
* @param converged - Whether convergence was achieved
|
|
23934
|
+
* @param totalTimeMs - Total time spent in token resolution
|
|
23935
|
+
*/
|
|
23936
|
+
logConvergence(iteration, converged, totalTimeMs) {
|
|
23937
|
+
if (!FeatureFlags.DEBUG_PAGE_TOKENS) return;
|
|
23938
|
+
if (converged) {
|
|
23939
|
+
console.log(`[PageTokens] Converged after ${iteration} iterations in ${totalTimeMs.toFixed(2)}ms`);
|
|
23940
|
+
} else {
|
|
23941
|
+
console.warn(`[PageTokens] Did NOT converge after ${iteration} iterations (${totalTimeMs.toFixed(2)}ms)`);
|
|
23942
|
+
}
|
|
23943
|
+
},
|
|
23944
|
+
/**
|
|
23945
|
+
* Logs token resolution error.
|
|
23946
|
+
*
|
|
23947
|
+
* @param blockId - Block ID where error occurred
|
|
23948
|
+
* @param error - Error object
|
|
23949
|
+
*/
|
|
23950
|
+
logError(blockId, error) {
|
|
23951
|
+
if (!FeatureFlags.DEBUG_PAGE_TOKENS) return;
|
|
23952
|
+
console.error(`[PageTokens] Error resolving tokens in block ${blockId}:`, error);
|
|
23953
|
+
},
|
|
23954
|
+
/**
|
|
23955
|
+
* Logs re-measurement details.
|
|
23956
|
+
*
|
|
23957
|
+
* @param blockCount - Number of blocks being re-measured
|
|
23958
|
+
* @param timeMs - Time spent re-measuring
|
|
23959
|
+
*/
|
|
23960
|
+
logRemeasure(blockCount, timeMs) {
|
|
23961
|
+
if (!FeatureFlags.DEBUG_PAGE_TOKENS) return;
|
|
23962
|
+
console.log(`[PageTokens] Re-measured ${blockCount} blocks in ${timeMs.toFixed(2)}ms`);
|
|
23963
|
+
}
|
|
23964
|
+
};
|
|
23965
|
+
const HeaderFooterCacheLogger = {
|
|
23966
|
+
/**
|
|
23967
|
+
* Logs cache hit for a header/footer variant.
|
|
23968
|
+
*
|
|
23969
|
+
* @param variantType - Variant type (default, first, even, odd)
|
|
23970
|
+
* @param pageNumber - Page number being cached
|
|
23971
|
+
* @param bucket - Digit bucket (d1, d2, d3, d4) or 'exact'
|
|
23972
|
+
*/
|
|
23973
|
+
logCacheHit(variantType, pageNumber, bucket) {
|
|
23974
|
+
if (!FeatureFlags.DEBUG_HF_CACHE) return;
|
|
23975
|
+
console.log(`[HF Cache] HIT: variant=${variantType}, page=${pageNumber}, bucket=${bucket}`);
|
|
23976
|
+
},
|
|
23977
|
+
/**
|
|
23978
|
+
* Logs cache miss for a header/footer variant.
|
|
23979
|
+
*
|
|
23980
|
+
* @param variantType - Variant type (default, first, even, odd)
|
|
23981
|
+
* @param pageNumber - Page number being cached
|
|
23982
|
+
* @param bucket - Digit bucket (d1, d2, d3, d4) or 'exact'
|
|
23983
|
+
*/
|
|
23984
|
+
logCacheMiss(variantType, pageNumber, bucket) {
|
|
23985
|
+
if (!FeatureFlags.DEBUG_HF_CACHE) return;
|
|
23986
|
+
console.log(`[HF Cache] MISS: variant=${variantType}, page=${pageNumber}, bucket=${bucket}`);
|
|
23987
|
+
},
|
|
23988
|
+
/**
|
|
23989
|
+
* Logs cache invalidation.
|
|
23990
|
+
*
|
|
23991
|
+
* @param reason - Reason for invalidation
|
|
23992
|
+
* @param affectedBlockIds - Block IDs being invalidated
|
|
23993
|
+
*/
|
|
23994
|
+
logInvalidation(reason, affectedBlockIds) {
|
|
23995
|
+
if (!FeatureFlags.DEBUG_HF_CACHE) return;
|
|
23996
|
+
console.log(`[HF Cache] INVALIDATE: reason=${reason}, blocks=${affectedBlockIds.length}`);
|
|
23997
|
+
},
|
|
23998
|
+
/**
|
|
23999
|
+
* Logs cache statistics.
|
|
24000
|
+
*
|
|
24001
|
+
* @param stats - Cache statistics object
|
|
24002
|
+
*/
|
|
24003
|
+
logStats(stats) {
|
|
24004
|
+
if (!FeatureFlags.DEBUG_HF_CACHE) return;
|
|
24005
|
+
const hitRate = stats.hits + stats.misses > 0 ? (stats.hits / (stats.hits + stats.misses) * 100).toFixed(1) : "0.0";
|
|
24006
|
+
console.log(
|
|
24007
|
+
`[HF Cache] Stats: hits=${stats.hits}, misses=${stats.misses}, hitRate=${hitRate}%, size=${stats.size}, evictions=${stats.evictions}`
|
|
24008
|
+
);
|
|
24009
|
+
},
|
|
24010
|
+
/**
|
|
24011
|
+
* Logs bucketing decision for large documents.
|
|
24012
|
+
*
|
|
24013
|
+
* @param totalPages - Total number of pages
|
|
24014
|
+
* @param useBucketing - Whether bucketing is being used
|
|
24015
|
+
* @param buckets - Buckets needed (if bucketing enabled)
|
|
24016
|
+
*/
|
|
24017
|
+
logBucketingDecision(totalPages, useBucketing, buckets) {
|
|
24018
|
+
if (!FeatureFlags.DEBUG_HF_CACHE) return;
|
|
24019
|
+
if (useBucketing && buckets) {
|
|
24020
|
+
console.log(`[HF Cache] Bucketing enabled: ${totalPages} pages, buckets=${buckets.join(", ")}`);
|
|
24021
|
+
} else {
|
|
24022
|
+
console.log(`[HF Cache] Bucketing disabled: ${totalPages} pages (per-page layouts)`);
|
|
24023
|
+
}
|
|
24024
|
+
}
|
|
24025
|
+
};
|
|
24026
|
+
class MetricsCollector {
|
|
24027
|
+
constructor() {
|
|
24028
|
+
this.pageTokenMetrics = null;
|
|
24029
|
+
this.headerFooterCacheMetrics = null;
|
|
24030
|
+
this.layoutMetrics = null;
|
|
24031
|
+
}
|
|
24032
|
+
/**
|
|
24033
|
+
* Records page token resolution metrics.
|
|
24034
|
+
*
|
|
24035
|
+
* @param metrics - Page token metrics
|
|
24036
|
+
*/
|
|
24037
|
+
recordPageTokenMetrics(metrics) {
|
|
24038
|
+
this.pageTokenMetrics = { ...metrics };
|
|
24039
|
+
this.checkPageTokenRollbackTriggers(metrics);
|
|
24040
|
+
}
|
|
24041
|
+
/**
|
|
24042
|
+
* Records header/footer cache metrics.
|
|
24043
|
+
*
|
|
24044
|
+
* @param stats - Cache statistics
|
|
24045
|
+
*/
|
|
24046
|
+
recordHeaderFooterCacheMetrics(stats) {
|
|
24047
|
+
const hitRate = stats.hits + stats.misses > 0 ? stats.hits / (stats.hits + stats.misses) * 100 : 0;
|
|
24048
|
+
this.headerFooterCacheMetrics = {
|
|
24049
|
+
hits: stats.hits,
|
|
24050
|
+
misses: stats.misses,
|
|
24051
|
+
hitRate,
|
|
24052
|
+
cacheSize: stats.size,
|
|
24053
|
+
memoryEstimate: stats.memorySizeEstimate,
|
|
24054
|
+
evictions: stats.evictions
|
|
24055
|
+
};
|
|
24056
|
+
this.checkCacheRollbackTriggers(this.headerFooterCacheMetrics);
|
|
24057
|
+
}
|
|
24058
|
+
/**
|
|
24059
|
+
* Records overall layout metrics.
|
|
24060
|
+
*
|
|
24061
|
+
* @param metrics - Layout metrics
|
|
24062
|
+
*/
|
|
24063
|
+
recordLayoutMetrics(metrics) {
|
|
24064
|
+
this.layoutMetrics = { ...metrics };
|
|
24065
|
+
}
|
|
24066
|
+
/**
|
|
24067
|
+
* Gets all collected metrics.
|
|
24068
|
+
*
|
|
24069
|
+
* @returns Object with all metrics or null if not collected
|
|
24070
|
+
*/
|
|
24071
|
+
getMetrics() {
|
|
24072
|
+
return {
|
|
24073
|
+
pageTokens: this.pageTokenMetrics,
|
|
24074
|
+
headerFooterCache: this.headerFooterCacheMetrics,
|
|
24075
|
+
layout: this.layoutMetrics
|
|
24076
|
+
};
|
|
24077
|
+
}
|
|
24078
|
+
/**
|
|
24079
|
+
* Resets all collected metrics.
|
|
24080
|
+
*/
|
|
24081
|
+
reset() {
|
|
24082
|
+
this.pageTokenMetrics = null;
|
|
24083
|
+
this.headerFooterCacheMetrics = null;
|
|
24084
|
+
this.layoutMetrics = null;
|
|
24085
|
+
}
|
|
24086
|
+
/**
|
|
24087
|
+
* Checks for page token rollback triggers and logs warnings.
|
|
24088
|
+
*
|
|
24089
|
+
* Rollback triggers (from plan):
|
|
24090
|
+
* - Convergence > 2 iterations
|
|
24091
|
+
* - Token resolution time > 100ms per layout run
|
|
24092
|
+
*
|
|
24093
|
+
* @param metrics - Page token metrics
|
|
24094
|
+
*/
|
|
24095
|
+
checkPageTokenRollbackTriggers(metrics) {
|
|
24096
|
+
if (metrics.iterations > 2 && !metrics.converged) {
|
|
24097
|
+
console.warn(
|
|
24098
|
+
`[Rollback Trigger] Page token resolution did not converge after ${metrics.iterations} iterations. Consider disabling SD_BODY_PAGE_TOKENS if this persists.`
|
|
24099
|
+
);
|
|
24100
|
+
}
|
|
24101
|
+
if (metrics.totalTimeMs > 100 && metrics.iterations > 0) {
|
|
24102
|
+
console.warn(
|
|
24103
|
+
`[Rollback Trigger] Page token resolution took ${metrics.totalTimeMs.toFixed(2)}ms (>100ms threshold). Consider disabling SD_BODY_PAGE_TOKENS if performance is unacceptable.`
|
|
24104
|
+
);
|
|
24105
|
+
}
|
|
24106
|
+
}
|
|
24107
|
+
/**
|
|
24108
|
+
* Checks for cache rollback triggers and logs warnings.
|
|
24109
|
+
*
|
|
24110
|
+
* Rollback triggers (from plan):
|
|
24111
|
+
* - Cache thrash (hit rate below 30%)
|
|
24112
|
+
* - Excessive memory usage (>1MB per 100 pages)
|
|
24113
|
+
*
|
|
24114
|
+
* @param metrics - Header/footer cache metrics
|
|
24115
|
+
*/
|
|
24116
|
+
checkCacheRollbackTriggers(metrics) {
|
|
24117
|
+
const MIN_HIT_RATE = 30;
|
|
24118
|
+
const MAX_MEMORY_PER_100_PAGES = 1e6;
|
|
24119
|
+
if (metrics.hits + metrics.misses > 10 && metrics.hitRate < MIN_HIT_RATE) {
|
|
24120
|
+
console.warn(
|
|
24121
|
+
`[Rollback Trigger] Header/footer cache hit rate is low (${metrics.hitRate.toFixed(1)}% < ${MIN_HIT_RATE}%). Consider disabling SD_HF_DIGIT_BUCKETING if cache thrashing persists.`
|
|
24122
|
+
);
|
|
24123
|
+
}
|
|
24124
|
+
if (metrics.memoryEstimate > MAX_MEMORY_PER_100_PAGES) {
|
|
24125
|
+
console.warn(
|
|
24126
|
+
`[Rollback Trigger] Header/footer cache memory usage is high (${(metrics.memoryEstimate / 1e6).toFixed(2)}MB). Monitor for excessive growth.`
|
|
24127
|
+
);
|
|
24128
|
+
}
|
|
24129
|
+
}
|
|
24130
|
+
}
|
|
24131
|
+
const globalMetrics = new MetricsCollector();
|
|
24132
|
+
const MIN_PAGES_FOR_BUCKETING = 100;
|
|
24133
|
+
function getBucketForPageNumber(pageNumber) {
|
|
24134
|
+
if (pageNumber < 10) return "d1";
|
|
24135
|
+
if (pageNumber < 100) return "d2";
|
|
24136
|
+
if (pageNumber < 1e3) return "d3";
|
|
24137
|
+
return "d4";
|
|
24138
|
+
}
|
|
24139
|
+
function getBucketRepresentative(bucket) {
|
|
24140
|
+
switch (bucket) {
|
|
24141
|
+
case "d1":
|
|
24142
|
+
return 5;
|
|
24143
|
+
case "d2":
|
|
24144
|
+
return 50;
|
|
24145
|
+
case "d3":
|
|
24146
|
+
return 500;
|
|
24147
|
+
case "d4":
|
|
24148
|
+
return 5e3;
|
|
24149
|
+
}
|
|
24150
|
+
}
|
|
24151
|
+
function hasPageTokens(blocks) {
|
|
24152
|
+
for (const block of blocks) {
|
|
24153
|
+
if (block.kind !== "paragraph") continue;
|
|
24154
|
+
for (const run of block.runs) {
|
|
24155
|
+
if ("token" in run && (run.token === "pageNumber" || run.token === "totalPageCount")) {
|
|
24156
|
+
return true;
|
|
24157
|
+
}
|
|
24158
|
+
}
|
|
24159
|
+
}
|
|
24160
|
+
return false;
|
|
24161
|
+
}
|
|
23256
24162
|
class HeaderFooterLayoutCache {
|
|
23257
24163
|
constructor() {
|
|
23258
24164
|
this.cache = new MeasureCache();
|
|
@@ -23277,15 +24183,81 @@ class HeaderFooterLayoutCache {
|
|
|
23277
24183
|
invalidate(blockIds) {
|
|
23278
24184
|
this.cache.invalidate(blockIds);
|
|
23279
24185
|
}
|
|
24186
|
+
/**
|
|
24187
|
+
* Gets cache statistics for monitoring and debugging.
|
|
24188
|
+
*
|
|
24189
|
+
* @returns Cache statistics object
|
|
24190
|
+
*/
|
|
24191
|
+
getStats() {
|
|
24192
|
+
return this.cache.getStats();
|
|
24193
|
+
}
|
|
23280
24194
|
}
|
|
23281
24195
|
const sharedHeaderFooterCache = new HeaderFooterLayoutCache();
|
|
23282
|
-
async function layoutHeaderFooterWithCache(sections, constraints, measureBlock2, cache2 = sharedHeaderFooterCache) {
|
|
24196
|
+
async function layoutHeaderFooterWithCache(sections, constraints, measureBlock2, cache2 = sharedHeaderFooterCache, totalPages, pageResolver) {
|
|
23283
24197
|
const result = {};
|
|
24198
|
+
if (!pageResolver) {
|
|
24199
|
+
const numPages = totalPages ?? 1;
|
|
24200
|
+
for (const [type, blocks] of Object.entries(sections)) {
|
|
24201
|
+
if (!blocks || blocks.length === 0) continue;
|
|
24202
|
+
const clonedBlocks = cloneHeaderFooterBlocks(blocks);
|
|
24203
|
+
resolveHeaderFooterTokens(clonedBlocks, 1, numPages);
|
|
24204
|
+
const measures = await cache2.measureBlocks(clonedBlocks, constraints, measureBlock2);
|
|
24205
|
+
const layout = layoutHeaderFooter(clonedBlocks, measures, constraints);
|
|
24206
|
+
result[type] = { blocks: clonedBlocks, measures, layout };
|
|
24207
|
+
}
|
|
24208
|
+
return result;
|
|
24209
|
+
}
|
|
24210
|
+
const { totalPages: docTotalPages } = pageResolver(1);
|
|
24211
|
+
const useBucketing = FeatureFlags.HF_DIGIT_BUCKETING && docTotalPages >= MIN_PAGES_FOR_BUCKETING;
|
|
23284
24212
|
for (const [type, blocks] of Object.entries(sections)) {
|
|
23285
24213
|
if (!blocks || blocks.length === 0) continue;
|
|
23286
|
-
|
|
23287
|
-
|
|
23288
|
-
|
|
24214
|
+
if (!hasPageTokens(blocks)) {
|
|
24215
|
+
const measures = await cache2.measureBlocks(blocks, constraints, measureBlock2);
|
|
24216
|
+
const layout = layoutHeaderFooter(blocks, measures, constraints);
|
|
24217
|
+
result[type] = { blocks, measures, layout };
|
|
24218
|
+
continue;
|
|
24219
|
+
}
|
|
24220
|
+
let pagesToLayout;
|
|
24221
|
+
if (!useBucketing) {
|
|
24222
|
+
pagesToLayout = Array.from({ length: docTotalPages }, (_, i) => i + 1);
|
|
24223
|
+
HeaderFooterCacheLogger.logBucketingDecision(docTotalPages, false);
|
|
24224
|
+
} else {
|
|
24225
|
+
const bucketsNeeded = /* @__PURE__ */ new Set();
|
|
24226
|
+
for (let p = 1; p <= docTotalPages; p++) {
|
|
24227
|
+
bucketsNeeded.add(getBucketForPageNumber(p));
|
|
24228
|
+
}
|
|
24229
|
+
pagesToLayout = Array.from(bucketsNeeded).map((bucket) => getBucketRepresentative(bucket));
|
|
24230
|
+
HeaderFooterCacheLogger.logBucketingDecision(docTotalPages, true, Array.from(bucketsNeeded));
|
|
24231
|
+
}
|
|
24232
|
+
const pages = [];
|
|
24233
|
+
for (const pageNum of pagesToLayout) {
|
|
24234
|
+
const clonedBlocks = cloneHeaderFooterBlocks(blocks);
|
|
24235
|
+
const { displayText, totalPages: totalPagesForPage } = pageResolver(pageNum);
|
|
24236
|
+
resolveHeaderFooterTokens(clonedBlocks, parseInt(displayText, 10) || pageNum, totalPagesForPage);
|
|
24237
|
+
const measures = await cache2.measureBlocks(clonedBlocks, constraints, measureBlock2);
|
|
24238
|
+
const pageLayout = layoutHeaderFooter(clonedBlocks, measures, constraints);
|
|
24239
|
+
pages.push({
|
|
24240
|
+
number: pageNum,
|
|
24241
|
+
blocks: clonedBlocks,
|
|
24242
|
+
measures,
|
|
24243
|
+
fragments: pageLayout.pages[0]?.fragments ?? []
|
|
24244
|
+
});
|
|
24245
|
+
}
|
|
24246
|
+
const firstPageLayout = pages[0] ? layoutHeaderFooter(pages[0].blocks, pages[0].measures, constraints) : { height: 0 };
|
|
24247
|
+
const finalLayout = {
|
|
24248
|
+
height: firstPageLayout.height,
|
|
24249
|
+
minY: firstPageLayout.minY,
|
|
24250
|
+
maxY: firstPageLayout.maxY,
|
|
24251
|
+
pages: pages.map((p) => ({
|
|
24252
|
+
number: p.number,
|
|
24253
|
+
fragments: p.fragments
|
|
24254
|
+
}))
|
|
24255
|
+
};
|
|
24256
|
+
result[type] = {
|
|
24257
|
+
blocks: pages[0]?.blocks ?? blocks,
|
|
24258
|
+
measures: pages[0]?.measures ?? [],
|
|
24259
|
+
layout: finalLayout
|
|
24260
|
+
};
|
|
23289
24261
|
}
|
|
23290
24262
|
return result;
|
|
23291
24263
|
}
|
|
@@ -23310,7 +24282,7 @@ function fontString(run) {
|
|
|
23310
24282
|
return `${italic}${bold}${size}px ${family}`.trim();
|
|
23311
24283
|
}
|
|
23312
24284
|
function runText(run) {
|
|
23313
|
-
return run.text ?? "";
|
|
24285
|
+
return run.kind === "image" ? "" : run.text ?? "";
|
|
23314
24286
|
}
|
|
23315
24287
|
function measureRunSliceWidth(run, fromChar, toChar) {
|
|
23316
24288
|
const context = getCtx();
|
|
@@ -23472,7 +24444,7 @@ const paragraphBlocksEqual = (a, b) => {
|
|
|
23472
24444
|
for (let i = 0; i < a.runs.length; i += 1) {
|
|
23473
24445
|
const runA = a.runs[i];
|
|
23474
24446
|
const runB = b.runs[i];
|
|
23475
|
-
if (runA.text !== runB.text || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
|
|
24447
|
+
if ((runA.kind === "image" ? "" : runA.text) !== (runB.kind === "image" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
|
|
23476
24448
|
return false;
|
|
23477
24449
|
}
|
|
23478
24450
|
}
|
|
@@ -23583,8 +24555,195 @@ const jsonEqual = (a, b) => {
|
|
|
23583
24555
|
return false;
|
|
23584
24556
|
}
|
|
23585
24557
|
};
|
|
24558
|
+
function computeHeaderFooterContentHash(blocks) {
|
|
24559
|
+
if (!blocks || blocks.length === 0) {
|
|
24560
|
+
return "";
|
|
24561
|
+
}
|
|
24562
|
+
const parts = [];
|
|
24563
|
+
for (const block of blocks) {
|
|
24564
|
+
parts.push(block.id);
|
|
24565
|
+
if (block.kind === "paragraph") {
|
|
24566
|
+
for (const run of block.runs) {
|
|
24567
|
+
if (run.kind !== "image") {
|
|
24568
|
+
parts.push(run.text ?? "");
|
|
24569
|
+
}
|
|
24570
|
+
if ("bold" in run && run.bold) parts.push("b");
|
|
24571
|
+
if ("italic" in run && run.italic) parts.push("i");
|
|
24572
|
+
if ("token" in run && run.token) parts.push(`token:${run.token}`);
|
|
24573
|
+
}
|
|
24574
|
+
}
|
|
24575
|
+
}
|
|
24576
|
+
return parts.join("|");
|
|
24577
|
+
}
|
|
24578
|
+
function computeSectionMetadataHash(sections) {
|
|
24579
|
+
if (!sections || sections.length === 0) {
|
|
24580
|
+
return "";
|
|
24581
|
+
}
|
|
24582
|
+
const parts = [];
|
|
24583
|
+
for (const section of sections) {
|
|
24584
|
+
parts.push(`section:${section.sectionIndex}`);
|
|
24585
|
+
if (section.numbering) {
|
|
24586
|
+
const num = section.numbering;
|
|
24587
|
+
parts.push(`num:${num.format ?? "decimal"}:${num.start ?? 1}`);
|
|
24588
|
+
}
|
|
24589
|
+
if (section.headerRefs) {
|
|
24590
|
+
const refs = section.headerRefs;
|
|
24591
|
+
if (refs.default) parts.push(`hdr-def:${refs.default}`);
|
|
24592
|
+
if (refs.first) parts.push(`hdr-first:${refs.first}`);
|
|
24593
|
+
if (refs.even) parts.push(`hdr-even:${refs.even}`);
|
|
24594
|
+
if (refs.odd) parts.push(`hdr-odd:${refs.odd}`);
|
|
24595
|
+
}
|
|
24596
|
+
if (section.footerRefs) {
|
|
24597
|
+
const refs = section.footerRefs;
|
|
24598
|
+
if (refs.default) parts.push(`ftr-def:${refs.default}`);
|
|
24599
|
+
if (refs.first) parts.push(`ftr-first:${refs.first}`);
|
|
24600
|
+
if (refs.even) parts.push(`ftr-even:${refs.even}`);
|
|
24601
|
+
if (refs.odd) parts.push(`ftr-odd:${refs.odd}`);
|
|
24602
|
+
}
|
|
24603
|
+
}
|
|
24604
|
+
return parts.join("|");
|
|
24605
|
+
}
|
|
24606
|
+
function computeConstraintsHash(constraints) {
|
|
24607
|
+
const { width, height, pageWidth, margins } = constraints;
|
|
24608
|
+
const parts = [`w:${width}`, `h:${height}`];
|
|
24609
|
+
if (pageWidth !== void 0) {
|
|
24610
|
+
parts.push(`pw:${pageWidth}`);
|
|
24611
|
+
}
|
|
24612
|
+
if (margins) {
|
|
24613
|
+
parts.push(`ml:${margins.left}`, `mr:${margins.right}`);
|
|
24614
|
+
}
|
|
24615
|
+
return parts.join("|");
|
|
24616
|
+
}
|
|
24617
|
+
class HeaderFooterCacheState {
|
|
24618
|
+
constructor() {
|
|
24619
|
+
this.contentHashes = /* @__PURE__ */ new Map();
|
|
24620
|
+
this.constraintsHash = "";
|
|
24621
|
+
this.sectionMetadataHash = "";
|
|
24622
|
+
}
|
|
24623
|
+
/**
|
|
24624
|
+
* Checks if header/footer content has changed for a variant.
|
|
24625
|
+
*
|
|
24626
|
+
* @param variantKey - Unique key for the variant (e.g., 'header-default')
|
|
24627
|
+
* @param blocks - Current blocks for the variant
|
|
24628
|
+
* @returns True if content has changed
|
|
24629
|
+
*/
|
|
24630
|
+
hasContentChanged(variantKey, blocks) {
|
|
24631
|
+
const currentHash = computeHeaderFooterContentHash(blocks);
|
|
24632
|
+
const previousHash = this.contentHashes.get(variantKey);
|
|
24633
|
+
if (previousHash === void 0) {
|
|
24634
|
+
this.contentHashes.set(variantKey, currentHash);
|
|
24635
|
+
return false;
|
|
24636
|
+
}
|
|
24637
|
+
const changed = currentHash !== previousHash;
|
|
24638
|
+
if (changed) {
|
|
24639
|
+
this.contentHashes.set(variantKey, currentHash);
|
|
24640
|
+
}
|
|
24641
|
+
return changed;
|
|
24642
|
+
}
|
|
24643
|
+
/**
|
|
24644
|
+
* Checks if constraints have changed.
|
|
24645
|
+
*
|
|
24646
|
+
* @param constraints - Current constraints
|
|
24647
|
+
* @returns True if constraints have changed
|
|
24648
|
+
*/
|
|
24649
|
+
hasConstraintsChanged(constraints) {
|
|
24650
|
+
const currentHash = computeConstraintsHash(constraints);
|
|
24651
|
+
if (this.constraintsHash === "") {
|
|
24652
|
+
this.constraintsHash = currentHash;
|
|
24653
|
+
return false;
|
|
24654
|
+
}
|
|
24655
|
+
const changed = currentHash !== this.constraintsHash;
|
|
24656
|
+
if (changed) {
|
|
24657
|
+
this.constraintsHash = currentHash;
|
|
24658
|
+
}
|
|
24659
|
+
return changed;
|
|
24660
|
+
}
|
|
24661
|
+
/**
|
|
24662
|
+
* Checks if section metadata has changed.
|
|
24663
|
+
*
|
|
24664
|
+
* @param sections - Current section metadata
|
|
24665
|
+
* @returns True if metadata has changed
|
|
24666
|
+
*/
|
|
24667
|
+
hasSectionMetadataChanged(sections) {
|
|
24668
|
+
const currentHash = computeSectionMetadataHash(sections);
|
|
24669
|
+
if (this.sectionMetadataHash === "") {
|
|
24670
|
+
this.sectionMetadataHash = currentHash;
|
|
24671
|
+
return false;
|
|
24672
|
+
}
|
|
24673
|
+
const changed = currentHash !== this.sectionMetadataHash;
|
|
24674
|
+
if (changed) {
|
|
24675
|
+
this.sectionMetadataHash = currentHash;
|
|
24676
|
+
}
|
|
24677
|
+
return changed;
|
|
24678
|
+
}
|
|
24679
|
+
/**
|
|
24680
|
+
* Resets all cached state.
|
|
24681
|
+
* Called when performing a full cache clear.
|
|
24682
|
+
*/
|
|
24683
|
+
reset() {
|
|
24684
|
+
this.contentHashes.clear();
|
|
24685
|
+
this.constraintsHash = "";
|
|
24686
|
+
this.sectionMetadataHash = "";
|
|
24687
|
+
}
|
|
24688
|
+
}
|
|
24689
|
+
function invalidateHeaderFooterCache(cache2, cacheState, headerBlocks, footerBlocks, constraints, sections) {
|
|
24690
|
+
const invalidationReasons = [];
|
|
24691
|
+
const affectedBlockIds = [];
|
|
24692
|
+
if (constraints && cacheState.hasConstraintsChanged(constraints)) {
|
|
24693
|
+
invalidationReasons.push("constraints changed");
|
|
24694
|
+
if (headerBlocks) {
|
|
24695
|
+
Object.values(headerBlocks).forEach((blocks) => {
|
|
24696
|
+
if (blocks) affectedBlockIds.push(...blocks.map((b) => b.id));
|
|
24697
|
+
});
|
|
24698
|
+
}
|
|
24699
|
+
if (footerBlocks) {
|
|
24700
|
+
Object.values(footerBlocks).forEach((blocks) => {
|
|
24701
|
+
if (blocks) affectedBlockIds.push(...blocks.map((b) => b.id));
|
|
24702
|
+
});
|
|
24703
|
+
}
|
|
24704
|
+
}
|
|
24705
|
+
if (sections && cacheState.hasSectionMetadataChanged(sections)) {
|
|
24706
|
+
invalidationReasons.push("section metadata changed");
|
|
24707
|
+
if (headerBlocks) {
|
|
24708
|
+
Object.values(headerBlocks).forEach((blocks) => {
|
|
24709
|
+
if (blocks) affectedBlockIds.push(...blocks.map((b) => b.id));
|
|
24710
|
+
});
|
|
24711
|
+
}
|
|
24712
|
+
if (footerBlocks) {
|
|
24713
|
+
Object.values(footerBlocks).forEach((blocks) => {
|
|
24714
|
+
if (blocks) affectedBlockIds.push(...blocks.map((b) => b.id));
|
|
24715
|
+
});
|
|
24716
|
+
}
|
|
24717
|
+
}
|
|
24718
|
+
if (headerBlocks) {
|
|
24719
|
+
for (const [variant, blocks] of Object.entries(headerBlocks)) {
|
|
24720
|
+
if (!blocks) continue;
|
|
24721
|
+
const variantKey = `header-${variant}`;
|
|
24722
|
+
if (cacheState.hasContentChanged(variantKey, blocks)) {
|
|
24723
|
+
invalidationReasons.push(`header ${variant} content changed`);
|
|
24724
|
+
affectedBlockIds.push(...blocks.map((b) => b.id));
|
|
24725
|
+
}
|
|
24726
|
+
}
|
|
24727
|
+
}
|
|
24728
|
+
if (footerBlocks) {
|
|
24729
|
+
for (const [variant, blocks] of Object.entries(footerBlocks)) {
|
|
24730
|
+
if (!blocks) continue;
|
|
24731
|
+
const variantKey = `footer-${variant}`;
|
|
24732
|
+
if (cacheState.hasContentChanged(variantKey, blocks)) {
|
|
24733
|
+
invalidationReasons.push(`footer ${variant} content changed`);
|
|
24734
|
+
affectedBlockIds.push(...blocks.map((b) => b.id));
|
|
24735
|
+
}
|
|
24736
|
+
}
|
|
24737
|
+
}
|
|
24738
|
+
if (affectedBlockIds.length > 0) {
|
|
24739
|
+
const uniqueBlockIds = Array.from(new Set(affectedBlockIds));
|
|
24740
|
+
cache2.invalidate(uniqueBlockIds);
|
|
24741
|
+
HeaderFooterCacheLogger.logInvalidation(invalidationReasons.join(", "), uniqueBlockIds);
|
|
24742
|
+
}
|
|
24743
|
+
}
|
|
23586
24744
|
const measureCache = new MeasureCache();
|
|
23587
24745
|
const headerMeasureCache = new HeaderFooterLayoutCache();
|
|
24746
|
+
const headerFooterCacheState = new HeaderFooterCacheState();
|
|
23588
24747
|
const layoutDebugEnabled = typeof process$1 !== "undefined" && typeof process$1.env !== "undefined" && Boolean(process$1.env.SD_DEBUG_LAYOUT);
|
|
23589
24748
|
const perfLog = (...args) => {
|
|
23590
24749
|
if (!layoutDebugEnabled) return;
|
|
@@ -23626,22 +24785,121 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
|
|
|
23626
24785
|
`[Perf] 4.1 Measure all blocks: ${(measureEnd - measureStart).toFixed(2)}ms (${cacheMisses} measured, ${cacheHits} cached)`
|
|
23627
24786
|
);
|
|
23628
24787
|
const layoutStart = performance.now();
|
|
23629
|
-
|
|
24788
|
+
let layout = layoutDocument(nextBlocks, measures, {
|
|
23630
24789
|
...options,
|
|
23631
24790
|
remeasureParagraph: (block, maxWidth) => remeasureParagraph(block, maxWidth)
|
|
23632
24791
|
});
|
|
23633
24792
|
const layoutEnd = performance.now();
|
|
23634
24793
|
perfLog(`[Perf] 4.2 Layout document (pagination): ${(layoutEnd - layoutStart).toFixed(2)}ms`);
|
|
24794
|
+
const maxIterations = 3;
|
|
24795
|
+
let currentBlocks = nextBlocks;
|
|
24796
|
+
let currentMeasures = measures;
|
|
24797
|
+
let iteration = 0;
|
|
24798
|
+
const pageTokenStart = performance.now();
|
|
24799
|
+
let totalAffectedBlocks = 0;
|
|
24800
|
+
let totalRemeasureTime = 0;
|
|
24801
|
+
let totalRelayoutTime = 0;
|
|
24802
|
+
let converged = true;
|
|
24803
|
+
if (FeatureFlags.BODY_PAGE_TOKENS) {
|
|
24804
|
+
while (iteration < maxIterations) {
|
|
24805
|
+
const sections = options.sectionMetadata ?? [];
|
|
24806
|
+
const numberingCtx = buildNumberingContext(layout, sections);
|
|
24807
|
+
PageTokenLogger.logIterationStart(iteration, layout.pages.length);
|
|
24808
|
+
const tokenResult = resolvePageNumberTokens(layout, currentBlocks, currentMeasures, numberingCtx);
|
|
24809
|
+
if (tokenResult.affectedBlockIds.size === 0) {
|
|
24810
|
+
perfLog(`[Perf] 4.3 Page token resolution converged after ${iteration} iterations`);
|
|
24811
|
+
break;
|
|
24812
|
+
}
|
|
24813
|
+
perfLog(`[Perf] 4.3.${iteration + 1} Page tokens resolved: ${tokenResult.affectedBlockIds.size} blocks affected`);
|
|
24814
|
+
const blockSamples = Array.from(tokenResult.affectedBlockIds).slice(0, 5);
|
|
24815
|
+
PageTokenLogger.logAffectedBlocks(iteration, tokenResult.affectedBlockIds, blockSamples);
|
|
24816
|
+
totalAffectedBlocks += tokenResult.affectedBlockIds.size;
|
|
24817
|
+
currentBlocks = currentBlocks.map((block) => tokenResult.updatedBlocks.get(block.id) ?? block);
|
|
24818
|
+
measureCache.invalidate(Array.from(tokenResult.affectedBlockIds));
|
|
24819
|
+
const remeasureStart = performance.now();
|
|
24820
|
+
currentMeasures = await remeasureAffectedBlocks(
|
|
24821
|
+
currentBlocks,
|
|
24822
|
+
currentMeasures,
|
|
24823
|
+
tokenResult.affectedBlockIds,
|
|
24824
|
+
constraints,
|
|
24825
|
+
measureBlock2
|
|
24826
|
+
);
|
|
24827
|
+
const remeasureEnd = performance.now();
|
|
24828
|
+
const remeasureTime = remeasureEnd - remeasureStart;
|
|
24829
|
+
totalRemeasureTime += remeasureTime;
|
|
24830
|
+
perfLog(`[Perf] 4.3.${iteration + 1}.1 Re-measure: ${remeasureTime.toFixed(2)}ms`);
|
|
24831
|
+
PageTokenLogger.logRemeasure(tokenResult.affectedBlockIds.size, remeasureTime);
|
|
24832
|
+
const oldPageCount = layout.pages.length;
|
|
24833
|
+
const relayoutStart = performance.now();
|
|
24834
|
+
layout = layoutDocument(currentBlocks, currentMeasures, {
|
|
24835
|
+
...options,
|
|
24836
|
+
remeasureParagraph: (block, maxWidth) => remeasureParagraph(block, maxWidth)
|
|
24837
|
+
});
|
|
24838
|
+
const relayoutEnd = performance.now();
|
|
24839
|
+
const relayoutTime = relayoutEnd - relayoutStart;
|
|
24840
|
+
totalRelayoutTime += relayoutTime;
|
|
24841
|
+
perfLog(`[Perf] 4.3.${iteration + 1}.2 Re-layout: ${relayoutTime.toFixed(2)}ms`);
|
|
24842
|
+
const newPageCount = layout.pages.length;
|
|
24843
|
+
if (newPageCount === oldPageCount && iteration > 0) {
|
|
24844
|
+
perfLog(`[Perf] 4.3 Page count stable at ${newPageCount} - breaking convergence loop`);
|
|
24845
|
+
break;
|
|
24846
|
+
}
|
|
24847
|
+
iteration++;
|
|
24848
|
+
}
|
|
24849
|
+
if (iteration >= maxIterations) {
|
|
24850
|
+
converged = false;
|
|
24851
|
+
console.warn(
|
|
24852
|
+
`[incrementalLayout] Page token resolution did not converge after ${maxIterations} iterations - stopping`
|
|
24853
|
+
);
|
|
24854
|
+
}
|
|
24855
|
+
}
|
|
24856
|
+
const pageTokenEnd = performance.now();
|
|
24857
|
+
const totalTokenTime = pageTokenEnd - pageTokenStart;
|
|
24858
|
+
if (iteration > 0) {
|
|
24859
|
+
perfLog(`[Perf] 4.3 Total page token resolution time: ${totalTokenTime.toFixed(2)}ms`);
|
|
24860
|
+
PageTokenLogger.logConvergence(iteration, converged, totalTokenTime);
|
|
24861
|
+
globalMetrics.recordPageTokenMetrics({
|
|
24862
|
+
totalTimeMs: totalTokenTime,
|
|
24863
|
+
iterations: iteration,
|
|
24864
|
+
affectedBlocks: totalAffectedBlocks,
|
|
24865
|
+
remeasureTimeMs: totalRemeasureTime,
|
|
24866
|
+
relayoutTimeMs: totalRelayoutTime,
|
|
24867
|
+
converged
|
|
24868
|
+
});
|
|
24869
|
+
}
|
|
23635
24870
|
let headers;
|
|
23636
24871
|
let footers;
|
|
23637
24872
|
if (headerFooter?.constraints && (headerFooter.headerBlocks || headerFooter.footerBlocks)) {
|
|
24873
|
+
const hfStart = performance.now();
|
|
23638
24874
|
const measureFn = headerFooter.measure ?? measureBlock2;
|
|
24875
|
+
invalidateHeaderFooterCache(
|
|
24876
|
+
headerMeasureCache,
|
|
24877
|
+
headerFooterCacheState,
|
|
24878
|
+
headerFooter.headerBlocks,
|
|
24879
|
+
headerFooter.footerBlocks,
|
|
24880
|
+
headerFooter.constraints,
|
|
24881
|
+
options.sectionMetadata
|
|
24882
|
+
);
|
|
24883
|
+
const sections = options.sectionMetadata ?? [];
|
|
24884
|
+
const numberingCtx = buildNumberingContext(layout, sections);
|
|
24885
|
+
const pageResolver = FeatureFlags.HEADER_FOOTER_PAGE_TOKENS ? (pageNumber) => {
|
|
24886
|
+
const pageIndex = pageNumber - 1;
|
|
24887
|
+
const displayInfo = numberingCtx.displayPages[pageIndex];
|
|
24888
|
+
return {
|
|
24889
|
+
displayText: displayInfo?.displayText ?? String(pageNumber),
|
|
24890
|
+
totalPages: numberingCtx.totalPages
|
|
24891
|
+
};
|
|
24892
|
+
} : void 0;
|
|
23639
24893
|
if (headerFooter.headerBlocks) {
|
|
23640
24894
|
const headerLayouts = await layoutHeaderFooterWithCache(
|
|
23641
24895
|
headerFooter.headerBlocks,
|
|
23642
24896
|
headerFooter.constraints,
|
|
23643
24897
|
measureFn,
|
|
23644
|
-
headerMeasureCache
|
|
24898
|
+
headerMeasureCache,
|
|
24899
|
+
FeatureFlags.HEADER_FOOTER_PAGE_TOKENS ? void 0 : numberingCtx.totalPages,
|
|
24900
|
+
// Fallback for backward compat
|
|
24901
|
+
pageResolver
|
|
24902
|
+
// Use page resolver for section-aware numbering
|
|
23645
24903
|
);
|
|
23646
24904
|
headers = serializeHeaderFooterResults("header", headerLayouts);
|
|
23647
24905
|
}
|
|
@@ -23650,14 +24908,23 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
|
|
|
23650
24908
|
headerFooter.footerBlocks,
|
|
23651
24909
|
headerFooter.constraints,
|
|
23652
24910
|
measureFn,
|
|
23653
|
-
headerMeasureCache
|
|
24911
|
+
headerMeasureCache,
|
|
24912
|
+
FeatureFlags.HEADER_FOOTER_PAGE_TOKENS ? void 0 : numberingCtx.totalPages,
|
|
24913
|
+
// Fallback for backward compat
|
|
24914
|
+
pageResolver
|
|
24915
|
+
// Use page resolver for section-aware numbering
|
|
23654
24916
|
);
|
|
23655
24917
|
footers = serializeHeaderFooterResults("footer", footerLayouts);
|
|
23656
24918
|
}
|
|
24919
|
+
const hfEnd = performance.now();
|
|
24920
|
+
perfLog(`[Perf] 4.4 Header/footer layout: ${(hfEnd - hfStart).toFixed(2)}ms`);
|
|
24921
|
+
const cacheStats = headerMeasureCache.getStats();
|
|
24922
|
+
globalMetrics.recordHeaderFooterCacheMetrics(cacheStats);
|
|
24923
|
+
HeaderFooterCacheLogger.logStats(cacheStats);
|
|
23657
24924
|
}
|
|
23658
24925
|
return {
|
|
23659
24926
|
layout,
|
|
23660
|
-
measures,
|
|
24927
|
+
measures: currentMeasures,
|
|
23661
24928
|
dirty,
|
|
23662
24929
|
headers,
|
|
23663
24930
|
footers
|
|
@@ -23701,6 +24968,31 @@ const serializeHeaderFooterResults = (kind, batch) => {
|
|
|
23701
24968
|
});
|
|
23702
24969
|
return results;
|
|
23703
24970
|
};
|
|
24971
|
+
function buildNumberingContext(layout, sections) {
|
|
24972
|
+
const totalPages = layout.pages.length;
|
|
24973
|
+
const displayPages = computeDisplayPageNumber(layout.pages, sections);
|
|
24974
|
+
return {
|
|
24975
|
+
totalPages,
|
|
24976
|
+
displayPages
|
|
24977
|
+
};
|
|
24978
|
+
}
|
|
24979
|
+
async function remeasureAffectedBlocks(blocks, measures, affectedBlockIds, constraints, measureBlock2) {
|
|
24980
|
+
const updatedMeasures = [...measures];
|
|
24981
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
24982
|
+
const block = blocks[i];
|
|
24983
|
+
if (!affectedBlockIds.has(block.id)) {
|
|
24984
|
+
continue;
|
|
24985
|
+
}
|
|
24986
|
+
try {
|
|
24987
|
+
const newMeasure = await measureBlock2(block, constraints);
|
|
24988
|
+
updatedMeasures[i] = newMeasure;
|
|
24989
|
+
measureCache.set(block, constraints.maxWidth, constraints.maxHeight, newMeasure);
|
|
24990
|
+
} catch (error) {
|
|
24991
|
+
console.warn(`[incrementalLayout] Failed to re-measure block ${block.id} after token resolution:`, error);
|
|
24992
|
+
}
|
|
24993
|
+
}
|
|
24994
|
+
return updatedMeasures;
|
|
24995
|
+
}
|
|
23704
24996
|
const isAtomicFragment = (fragment) => {
|
|
23705
24997
|
return fragment.kind === "drawing" || fragment.kind === "image";
|
|
23706
24998
|
};
|
|
@@ -24040,7 +25332,7 @@ function computeLinePmRange$1(block, line) {
|
|
|
24040
25332
|
for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
|
|
24041
25333
|
const run = block.runs[runIndex];
|
|
24042
25334
|
if (!run) continue;
|
|
24043
|
-
const text = run.text ?? "";
|
|
25335
|
+
const text = run.kind === "image" ? "" : run.text ?? "";
|
|
24044
25336
|
const runLength = text.length;
|
|
24045
25337
|
const runPmStart = run.pmStart ?? null;
|
|
24046
25338
|
const runPmEnd = run.pmEnd ?? (runPmStart != null ? runPmStart + runLength : null);
|
|
@@ -26221,6 +27513,104 @@ function k(t) {
|
|
|
26221
27513
|
${l}
|
|
26222
27514
|
</svg>`;
|
|
26223
27515
|
}
|
|
27516
|
+
function validateHexColor(color) {
|
|
27517
|
+
if (typeof color !== "string") return void 0;
|
|
27518
|
+
const trimmed = color.trim();
|
|
27519
|
+
if (!trimmed) return void 0;
|
|
27520
|
+
const withoutHash = trimmed.startsWith("#") ? trimmed.slice(1) : trimmed;
|
|
27521
|
+
const hexPattern = /^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/;
|
|
27522
|
+
if (!hexPattern.test(withoutHash)) {
|
|
27523
|
+
return void 0;
|
|
27524
|
+
}
|
|
27525
|
+
return `#${withoutHash}`;
|
|
27526
|
+
}
|
|
27527
|
+
function addValidatedGradientStops(gradient, stops) {
|
|
27528
|
+
stops.forEach((stop) => {
|
|
27529
|
+
const position = typeof stop.position === "number" && Number.isFinite(stop.position) ? Math.max(0, Math.min(1, stop.position)) : 0;
|
|
27530
|
+
const validatedColor = validateHexColor(stop.color);
|
|
27531
|
+
if (!validatedColor) {
|
|
27532
|
+
return;
|
|
27533
|
+
}
|
|
27534
|
+
const alpha = typeof stop.alpha === "number" && Number.isFinite(stop.alpha) ? Math.max(0, Math.min(1, stop.alpha)) : 1;
|
|
27535
|
+
const stopElement = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
|
27536
|
+
stopElement.setAttribute("offset", `${position * 100}%`);
|
|
27537
|
+
stopElement.setAttribute("stop-color", validatedColor);
|
|
27538
|
+
if (alpha < 1) {
|
|
27539
|
+
stopElement.setAttribute("stop-opacity", alpha.toString());
|
|
27540
|
+
}
|
|
27541
|
+
gradient.appendChild(stopElement);
|
|
27542
|
+
});
|
|
27543
|
+
}
|
|
27544
|
+
function createGradient$1(gradientData, gradientId) {
|
|
27545
|
+
const { gradientType, stops, angle } = gradientData;
|
|
27546
|
+
if (!stops || stops.length === 0) {
|
|
27547
|
+
return null;
|
|
27548
|
+
}
|
|
27549
|
+
let gradient;
|
|
27550
|
+
if (gradientType === "linear") {
|
|
27551
|
+
gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
|
|
27552
|
+
gradient.setAttribute("id", gradientId);
|
|
27553
|
+
const radians = angle * Math.PI / 180;
|
|
27554
|
+
const x1 = 50 - 50 * Math.cos(radians);
|
|
27555
|
+
const y1 = 50 + 50 * Math.sin(radians);
|
|
27556
|
+
const x2 = 50 + 50 * Math.cos(radians);
|
|
27557
|
+
const y2 = 50 - 50 * Math.sin(radians);
|
|
27558
|
+
gradient.setAttribute("x1", `${x1}%`);
|
|
27559
|
+
gradient.setAttribute("y1", `${y1}%`);
|
|
27560
|
+
gradient.setAttribute("x2", `${x2}%`);
|
|
27561
|
+
gradient.setAttribute("y2", `${y2}%`);
|
|
27562
|
+
} else {
|
|
27563
|
+
gradient = document.createElementNS("http://www.w3.org/2000/svg", "radialGradient");
|
|
27564
|
+
gradient.setAttribute("id", gradientId);
|
|
27565
|
+
gradient.setAttribute("cx", "50%");
|
|
27566
|
+
gradient.setAttribute("cy", "50%");
|
|
27567
|
+
gradient.setAttribute("r", "50%");
|
|
27568
|
+
}
|
|
27569
|
+
addValidatedGradientStops(gradient, stops);
|
|
27570
|
+
return gradient;
|
|
27571
|
+
}
|
|
27572
|
+
function applyGradientToSVG$1(svg, gradientData) {
|
|
27573
|
+
try {
|
|
27574
|
+
const gradientId = generateGradientId("gradient");
|
|
27575
|
+
const gradient = createGradient$1(gradientData, gradientId);
|
|
27576
|
+
if (!gradient) {
|
|
27577
|
+
return;
|
|
27578
|
+
}
|
|
27579
|
+
let defs = svg.querySelector("defs");
|
|
27580
|
+
if (!defs) {
|
|
27581
|
+
defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
27582
|
+
svg.insertBefore(defs, svg.firstChild);
|
|
27583
|
+
}
|
|
27584
|
+
defs.appendChild(gradient);
|
|
27585
|
+
const filledElements = svg.querySelectorAll('[fill]:not([fill="none"])');
|
|
27586
|
+
filledElements.forEach((el) => {
|
|
27587
|
+
el.setAttribute("fill", `url(#${gradientId})`);
|
|
27588
|
+
});
|
|
27589
|
+
} catch (error) {
|
|
27590
|
+
console.error("Failed to apply gradient to SVG:", error);
|
|
27591
|
+
}
|
|
27592
|
+
}
|
|
27593
|
+
function applyAlphaToSVG$1(svg, alphaData) {
|
|
27594
|
+
try {
|
|
27595
|
+
const { color, alpha } = alphaData;
|
|
27596
|
+
const validatedColor = validateHexColor(color);
|
|
27597
|
+
if (!validatedColor) {
|
|
27598
|
+
return;
|
|
27599
|
+
}
|
|
27600
|
+
const clampedAlpha = typeof alpha === "number" && Number.isFinite(alpha) ? Math.max(0, Math.min(1, alpha)) : 1;
|
|
27601
|
+
const filledElements = svg.querySelectorAll('[fill]:not([fill="none"])');
|
|
27602
|
+
filledElements.forEach((el) => {
|
|
27603
|
+
el.setAttribute("fill", validatedColor);
|
|
27604
|
+
el.setAttribute("fill-opacity", clampedAlpha.toString());
|
|
27605
|
+
});
|
|
27606
|
+
} catch (error) {
|
|
27607
|
+
console.error("Failed to apply alpha to SVG:", error);
|
|
27608
|
+
}
|
|
27609
|
+
}
|
|
27610
|
+
let gradientIdCounter = 0;
|
|
27611
|
+
function generateGradientId(prefix = "gradient") {
|
|
27612
|
+
return `${prefix}-${Date.now()}-${gradientIdCounter++}-${Math.random().toString(36).substring(2, 11)}`;
|
|
27613
|
+
}
|
|
26224
27614
|
const CLASS_NAMES = {
|
|
26225
27615
|
container: "superdoc-layout",
|
|
26226
27616
|
page: "superdoc-page",
|
|
@@ -26555,47 +27945,20 @@ const borderValueToSpec = (value) => {
|
|
|
26555
27945
|
}
|
|
26556
27946
|
return void 0;
|
|
26557
27947
|
};
|
|
26558
|
-
const resolveTableBorderValue = (explicit, fallback) => {
|
|
26559
|
-
const explicitSpec = borderValueToSpec(explicit);
|
|
26560
|
-
if (explicitSpec) {
|
|
26561
|
-
return explicitSpec;
|
|
26562
|
-
}
|
|
26563
|
-
return borderValueToSpec(fallback);
|
|
26564
|
-
};
|
|
26565
|
-
const createTableBorderOverlay = (doc2, fragment, tableBorders) => {
|
|
26566
|
-
const top2 = borderValueToSpec(tableBorders.top ?? null);
|
|
26567
|
-
const right2 = borderValueToSpec(tableBorders.right ?? null);
|
|
26568
|
-
const bottom2 = borderValueToSpec(tableBorders.bottom ?? null);
|
|
26569
|
-
const left2 = borderValueToSpec(tableBorders.left ?? null);
|
|
26570
|
-
if (!top2 && !right2 && !bottom2 && !left2) {
|
|
26571
|
-
return null;
|
|
26572
|
-
}
|
|
26573
|
-
const overlay = doc2.createElement("div");
|
|
26574
|
-
overlay.classList.add("superdoc-table-border");
|
|
26575
|
-
overlay.style.position = "absolute";
|
|
26576
|
-
overlay.style.left = "0";
|
|
26577
|
-
overlay.style.top = "0";
|
|
26578
|
-
overlay.style.width = `${fragment.width}px`;
|
|
26579
|
-
overlay.style.height = `${fragment.height}px`;
|
|
26580
|
-
overlay.style.boxSizing = "border-box";
|
|
26581
|
-
overlay.style.pointerEvents = "none";
|
|
26582
|
-
overlay.style.zIndex = "1";
|
|
26583
|
-
applyBorder(overlay, "Top", top2);
|
|
26584
|
-
applyBorder(overlay, "Right", right2);
|
|
26585
|
-
applyBorder(overlay, "Bottom", bottom2);
|
|
26586
|
-
applyBorder(overlay, "Left", left2);
|
|
26587
|
-
return overlay;
|
|
26588
|
-
};
|
|
26589
27948
|
const resolveTableCellBorders = (tableBorders, rowIndex, colIndex, totalRows, totalCols) => {
|
|
26590
27949
|
const isFirstRow = rowIndex === 0;
|
|
26591
27950
|
const isLastRow = rowIndex === totalRows - 1;
|
|
26592
27951
|
const isFirstCol = colIndex === 0;
|
|
26593
27952
|
const isLastCol = colIndex === totalCols - 1;
|
|
26594
27953
|
return {
|
|
26595
|
-
|
|
26596
|
-
|
|
26597
|
-
|
|
26598
|
-
|
|
27954
|
+
// Top: first row gets table.top, interior rows get insideH
|
|
27955
|
+
top: borderValueToSpec(isFirstRow ? tableBorders?.top : tableBorders?.insideH),
|
|
27956
|
+
// Bottom: ONLY last row gets table.bottom (interior cells don't render bottom - it comes from cell below's top)
|
|
27957
|
+
bottom: borderValueToSpec(isLastRow ? tableBorders?.bottom : null),
|
|
27958
|
+
// Left: first col gets table.left, interior cols get insideV
|
|
27959
|
+
left: borderValueToSpec(isFirstCol ? tableBorders?.left : tableBorders?.insideV),
|
|
27960
|
+
// Right: ONLY last col gets table.right (interior cells don't render right - it comes from cell to right's left)
|
|
27961
|
+
right: borderValueToSpec(isLastCol ? tableBorders?.right : null)
|
|
26599
27962
|
};
|
|
26600
27963
|
};
|
|
26601
27964
|
const renderTableCell = (deps) => {
|
|
@@ -26621,21 +27984,37 @@ const renderTableCell = (deps) => {
|
|
|
26621
27984
|
let contentElement;
|
|
26622
27985
|
const attrs = cell?.attrs;
|
|
26623
27986
|
const padding = attrs?.padding || { top: 2, left: 4, right: 4 };
|
|
26624
|
-
|
|
26625
|
-
|
|
27987
|
+
const paddingLeft = padding.left ?? 4;
|
|
27988
|
+
const paddingTop = padding.top ?? 2;
|
|
27989
|
+
const paddingRight = padding.right ?? 4;
|
|
27990
|
+
const cellBlocks = cell?.blocks ?? (cell?.paragraph ? [cell.paragraph] : []);
|
|
27991
|
+
const blockMeasures = cellMeasure.blocks ?? (cellMeasure.paragraph ? [cellMeasure.paragraph] : []);
|
|
27992
|
+
if (cellBlocks.length > 0 && blockMeasures.length > 0) {
|
|
26626
27993
|
const content = doc2.createElement("div");
|
|
26627
27994
|
content.style.position = "absolute";
|
|
26628
|
-
applySdtDataset(content, cell.paragraph.attrs?.sdt);
|
|
26629
|
-
const paddingLeft = padding.left ?? 4;
|
|
26630
|
-
const paddingTop = padding.top ?? 2;
|
|
26631
|
-
const paddingRight = padding.right ?? 4;
|
|
26632
27995
|
content.style.left = `${x + paddingLeft}px`;
|
|
26633
27996
|
content.style.top = `${y + paddingTop}px`;
|
|
26634
27997
|
content.style.width = `${Math.max(0, cellMeasure.width - paddingLeft - paddingRight)}px`;
|
|
26635
|
-
|
|
26636
|
-
|
|
26637
|
-
|
|
26638
|
-
|
|
27998
|
+
let blockY = 0;
|
|
27999
|
+
for (let i = 0; i < Math.min(blockMeasures.length, cellBlocks.length); i++) {
|
|
28000
|
+
const blockMeasure = blockMeasures[i];
|
|
28001
|
+
const block = cellBlocks[i];
|
|
28002
|
+
if (blockMeasure.kind === "paragraph" && block?.kind === "paragraph") {
|
|
28003
|
+
const paraWrapper = doc2.createElement("div");
|
|
28004
|
+
paraWrapper.style.position = "absolute";
|
|
28005
|
+
paraWrapper.style.top = `${blockY}px`;
|
|
28006
|
+
paraWrapper.style.left = "0";
|
|
28007
|
+
paraWrapper.style.width = "100%";
|
|
28008
|
+
applySdtDataset(paraWrapper, block.attrs?.sdt);
|
|
28009
|
+
const lines = blockMeasure.lines;
|
|
28010
|
+
lines.forEach((line) => {
|
|
28011
|
+
const lineEl = renderLine(block, line, { ...context, section: "body" });
|
|
28012
|
+
paraWrapper.appendChild(lineEl);
|
|
28013
|
+
});
|
|
28014
|
+
content.appendChild(paraWrapper);
|
|
28015
|
+
blockY += blockMeasure.totalHeight;
|
|
28016
|
+
}
|
|
28017
|
+
}
|
|
26639
28018
|
contentElement = content;
|
|
26640
28019
|
}
|
|
26641
28020
|
return { cellElement: cellEl, contentElement };
|
|
@@ -26680,10 +28059,25 @@ const renderTableRow = (deps) => {
|
|
|
26680
28059
|
const gridColIndex = cellMeasure.gridColumnStart ?? cellIndex;
|
|
26681
28060
|
const totalCols = columnWidths.length;
|
|
26682
28061
|
let resolvedBorders;
|
|
26683
|
-
if (hasExplicitBorders) {
|
|
26684
|
-
resolvedBorders = cellBordersAttr;
|
|
26685
|
-
} else if (hasBordersAttribute) {
|
|
28062
|
+
if (hasBordersAttribute && !hasExplicitBorders) {
|
|
26686
28063
|
resolvedBorders = void 0;
|
|
28064
|
+
} else if (hasExplicitBorders && tableBorders) {
|
|
28065
|
+
const isFirstRow = rowIndex === 0;
|
|
28066
|
+
const isLastRow = rowIndex === totalRows - 1;
|
|
28067
|
+
const isFirstCol = gridColIndex === 0;
|
|
28068
|
+
const isLastCol = gridColIndex === totalCols - 1;
|
|
28069
|
+
resolvedBorders = {
|
|
28070
|
+
// For top: use cell's if defined, otherwise use table's top for first row
|
|
28071
|
+
top: cellBordersAttr.top ?? borderValueToSpec(isFirstRow ? tableBorders.top : tableBorders.insideH),
|
|
28072
|
+
// For bottom: use cell's if defined, otherwise use table's bottom for last row only
|
|
28073
|
+
bottom: cellBordersAttr.bottom ?? borderValueToSpec(isLastRow ? tableBorders.bottom : void 0),
|
|
28074
|
+
// For left: use cell's if defined, otherwise use table's left for first col
|
|
28075
|
+
left: cellBordersAttr.left ?? borderValueToSpec(isFirstCol ? tableBorders.left : tableBorders.insideV),
|
|
28076
|
+
// For right: use cell's if defined, otherwise use table's right for last col only
|
|
28077
|
+
right: cellBordersAttr.right ?? borderValueToSpec(isLastCol ? tableBorders.right : void 0)
|
|
28078
|
+
};
|
|
28079
|
+
} else if (hasExplicitBorders) {
|
|
28080
|
+
resolvedBorders = cellBordersAttr;
|
|
26687
28081
|
} else if (tableBorders) {
|
|
26688
28082
|
resolvedBorders = resolveTableCellBorders(tableBorders, rowIndex, gridColIndex, totalRows, totalCols);
|
|
26689
28083
|
} else {
|
|
@@ -26739,7 +28133,6 @@ const renderTableFragment = (deps) => {
|
|
|
26739
28133
|
const block = lookup.block;
|
|
26740
28134
|
const measure = lookup.measure;
|
|
26741
28135
|
const tableBorders = block.attrs?.borders;
|
|
26742
|
-
const borderOverlay = tableBorders ? createTableBorderOverlay(doc2, fragment, tableBorders) : null;
|
|
26743
28136
|
const container = doc2.createElement("div");
|
|
26744
28137
|
container.classList.add(CLASS_NAMES.fragment);
|
|
26745
28138
|
applyStyles2(container, fragmentStyles);
|
|
@@ -26838,9 +28231,6 @@ const renderTableFragment = (deps) => {
|
|
|
26838
28231
|
});
|
|
26839
28232
|
y += rowMeasure.height;
|
|
26840
28233
|
}
|
|
26841
|
-
if (borderOverlay) {
|
|
26842
|
-
container.appendChild(borderOverlay);
|
|
26843
|
-
}
|
|
26844
28234
|
return container;
|
|
26845
28235
|
};
|
|
26846
28236
|
const LIST_MARKER_GAP$1 = 8;
|
|
@@ -26853,6 +28243,8 @@ const LINK_DATASET_KEYS = {
|
|
|
26853
28243
|
};
|
|
26854
28244
|
const MAX_HREF_LENGTH = 2048;
|
|
26855
28245
|
const SAFE_ANCHOR_PATTERN = /^[A-Za-z0-9._-]+$/;
|
|
28246
|
+
const MAX_DATA_URL_LENGTH = 10 * 1024 * 1024;
|
|
28247
|
+
const VALID_IMAGE_DATA_URL = /^data:image\/(png|jpeg|jpg|gif|svg\+xml|webp|bmp|ico|tiff?);base64,/i;
|
|
26856
28248
|
const AMBIGUOUS_LINK_PATTERNS = /^(click here|read more|more|link|here|this|download|view)$/i;
|
|
26857
28249
|
const TRACK_CHANGE_BASE_CLASS = {
|
|
26858
28250
|
insert: "track-insert-dec",
|
|
@@ -26879,6 +28271,11 @@ const TRACK_CHANGE_MODIFIER_CLASS = {
|
|
|
26879
28271
|
off: void 0
|
|
26880
28272
|
}
|
|
26881
28273
|
};
|
|
28274
|
+
function sanitizeUrl(href) {
|
|
28275
|
+
if (typeof href !== "string") return null;
|
|
28276
|
+
const sanitized = sanitizeHref(href);
|
|
28277
|
+
return sanitized?.href ?? null;
|
|
28278
|
+
}
|
|
26882
28279
|
const LINK_TARGET_SET = /* @__PURE__ */ new Set(["_blank", "_self", "_parent", "_top"]);
|
|
26883
28280
|
const normalizeAnchor = (value) => {
|
|
26884
28281
|
if (typeof value !== "string") return null;
|
|
@@ -27773,7 +29170,7 @@ const _DomPainter = class _DomPainter {
|
|
|
27773
29170
|
}
|
|
27774
29171
|
const block = lookup.block;
|
|
27775
29172
|
const fragmentEl = this.doc.createElement("div");
|
|
27776
|
-
fragmentEl.classList.add(CLASS_NAMES.fragment);
|
|
29173
|
+
fragmentEl.classList.add(CLASS_NAMES.fragment, "superdoc-image-fragment");
|
|
27777
29174
|
applyStyles$2(fragmentEl, fragmentStyles);
|
|
27778
29175
|
this.applyFragmentFrame(fragmentEl, fragment);
|
|
27779
29176
|
fragmentEl.style.height = `${fragment.height}px`;
|
|
@@ -27782,6 +29179,18 @@ const _DomPainter = class _DomPainter {
|
|
|
27782
29179
|
if (fragment.isAnchored && fragment.zIndex != null) {
|
|
27783
29180
|
fragmentEl.style.zIndex = String(fragment.zIndex);
|
|
27784
29181
|
}
|
|
29182
|
+
if (block.id) {
|
|
29183
|
+
fragmentEl.setAttribute("data-sd-block-id", block.id);
|
|
29184
|
+
}
|
|
29185
|
+
if (fragment.pmStart != null) {
|
|
29186
|
+
fragmentEl.dataset.pmStart = String(fragment.pmStart);
|
|
29187
|
+
}
|
|
29188
|
+
if (fragment.pmEnd != null) {
|
|
29189
|
+
fragmentEl.dataset.pmEnd = String(fragment.pmEnd);
|
|
29190
|
+
}
|
|
29191
|
+
if (fragment.metadata) {
|
|
29192
|
+
fragmentEl.setAttribute("data-image-metadata", JSON.stringify(fragment.metadata));
|
|
29193
|
+
}
|
|
27785
29194
|
const img = this.doc.createElement("img");
|
|
27786
29195
|
if (block.src) {
|
|
27787
29196
|
img.src = block.src;
|
|
@@ -27815,6 +29224,7 @@ const _DomPainter = class _DomPainter {
|
|
|
27815
29224
|
this.applyFragmentFrame(fragmentEl, fragment);
|
|
27816
29225
|
fragmentEl.style.height = `${fragment.height}px`;
|
|
27817
29226
|
fragmentEl.style.position = "absolute";
|
|
29227
|
+
fragmentEl.style.overflow = "hidden";
|
|
27818
29228
|
if (fragment.isAnchored && fragment.zIndex != null) {
|
|
27819
29229
|
fragmentEl.style.zIndex = String(fragment.zIndex);
|
|
27820
29230
|
}
|
|
@@ -27872,12 +29282,13 @@ const _DomPainter = class _DomPainter {
|
|
|
27872
29282
|
img.style.display = "block";
|
|
27873
29283
|
return img;
|
|
27874
29284
|
}
|
|
27875
|
-
createVectorShapeElement(block, geometry, applyTransforms = false) {
|
|
29285
|
+
createVectorShapeElement(block, geometry, applyTransforms = false, groupScaleX = 1, groupScaleY = 1) {
|
|
27876
29286
|
const container = this.doc.createElement("div");
|
|
27877
29287
|
container.classList.add("superdoc-vector-shape");
|
|
27878
29288
|
container.style.width = "100%";
|
|
27879
29289
|
container.style.height = "100%";
|
|
27880
29290
|
container.style.position = "relative";
|
|
29291
|
+
container.style.overflow = "hidden";
|
|
27881
29292
|
const svgMarkup = block.shapeKind ? this.tryCreatePresetSvg(block) : null;
|
|
27882
29293
|
if (svgMarkup) {
|
|
27883
29294
|
const svgElement = this.parseSafeSvg(svgMarkup);
|
|
@@ -27885,27 +29296,193 @@ const _DomPainter = class _DomPainter {
|
|
|
27885
29296
|
svgElement.setAttribute("width", "100%");
|
|
27886
29297
|
svgElement.setAttribute("height", "100%");
|
|
27887
29298
|
svgElement.style.display = "block";
|
|
29299
|
+
if (block.fillColor && typeof block.fillColor === "object") {
|
|
29300
|
+
if ("type" in block.fillColor && block.fillColor.type === "gradient") {
|
|
29301
|
+
applyGradientToSVG$1(svgElement, block.fillColor);
|
|
29302
|
+
} else if ("type" in block.fillColor && block.fillColor.type === "solidWithAlpha") {
|
|
29303
|
+
applyAlphaToSVG$1(svgElement, block.fillColor);
|
|
29304
|
+
}
|
|
29305
|
+
}
|
|
27888
29306
|
if (applyTransforms && geometry) {
|
|
27889
29307
|
this.applyVectorShapeTransforms(svgElement, geometry);
|
|
27890
29308
|
}
|
|
27891
29309
|
container.appendChild(svgElement);
|
|
29310
|
+
if (block.textContent && block.textContent.parts.length > 0) {
|
|
29311
|
+
const textDiv = this.createFallbackTextElement(
|
|
29312
|
+
block.textContent,
|
|
29313
|
+
block.textAlign ?? "center",
|
|
29314
|
+
block.textVerticalAlign,
|
|
29315
|
+
block.textInsets,
|
|
29316
|
+
groupScaleX,
|
|
29317
|
+
groupScaleY
|
|
29318
|
+
);
|
|
29319
|
+
container.appendChild(textDiv);
|
|
29320
|
+
}
|
|
27892
29321
|
return container;
|
|
27893
29322
|
}
|
|
27894
29323
|
}
|
|
27895
|
-
|
|
27896
|
-
|
|
29324
|
+
this.applyFallbackShapeStyle(container, block);
|
|
29325
|
+
if (block.textContent && block.textContent.parts.length > 0) {
|
|
29326
|
+
const textDiv = this.createFallbackTextElement(
|
|
29327
|
+
block.textContent,
|
|
29328
|
+
block.textAlign ?? "center",
|
|
29329
|
+
block.textVerticalAlign,
|
|
29330
|
+
block.textInsets,
|
|
29331
|
+
groupScaleX,
|
|
29332
|
+
groupScaleY
|
|
29333
|
+
);
|
|
29334
|
+
container.appendChild(textDiv);
|
|
29335
|
+
}
|
|
27897
29336
|
if (applyTransforms && geometry) {
|
|
27898
29337
|
this.applyVectorShapeTransforms(container, geometry);
|
|
27899
29338
|
}
|
|
27900
29339
|
return container;
|
|
27901
29340
|
}
|
|
29341
|
+
/**
|
|
29342
|
+
* Apply fill and stroke styles to a fallback shape container
|
|
29343
|
+
*/
|
|
29344
|
+
applyFallbackShapeStyle(container, block) {
|
|
29345
|
+
if (block.fillColor === null) {
|
|
29346
|
+
container.style.background = "none";
|
|
29347
|
+
} else if (typeof block.fillColor === "string") {
|
|
29348
|
+
container.style.background = block.fillColor;
|
|
29349
|
+
} else if (typeof block.fillColor === "object" && "type" in block.fillColor) {
|
|
29350
|
+
if (block.fillColor.type === "solidWithAlpha") {
|
|
29351
|
+
const alpha = block.fillColor.alpha;
|
|
29352
|
+
const color = block.fillColor.color;
|
|
29353
|
+
container.style.background = color;
|
|
29354
|
+
container.style.opacity = alpha.toString();
|
|
29355
|
+
} else if (block.fillColor.type === "gradient") {
|
|
29356
|
+
container.style.background = "rgba(15, 23, 42, 0.1)";
|
|
29357
|
+
}
|
|
29358
|
+
} else {
|
|
29359
|
+
container.style.background = "rgba(15, 23, 42, 0.1)";
|
|
29360
|
+
}
|
|
29361
|
+
if (block.strokeColor === null) {
|
|
29362
|
+
container.style.border = "none";
|
|
29363
|
+
} else if (typeof block.strokeColor === "string") {
|
|
29364
|
+
const strokeWidth = block.strokeWidth ?? 1;
|
|
29365
|
+
container.style.border = `${strokeWidth}px solid ${block.strokeColor}`;
|
|
29366
|
+
} else {
|
|
29367
|
+
container.style.border = "1px solid rgba(15, 23, 42, 0.3)";
|
|
29368
|
+
}
|
|
29369
|
+
}
|
|
29370
|
+
/**
|
|
29371
|
+
* Create a fallback text element for shapes without SVG
|
|
29372
|
+
* @param textContent - Text content with formatting
|
|
29373
|
+
* @param textAlign - Horizontal text alignment
|
|
29374
|
+
* @param textVerticalAlign - Vertical text alignment (top, center, bottom)
|
|
29375
|
+
* @param textInsets - Text insets in pixels (top, right, bottom, left)
|
|
29376
|
+
* @param groupScaleX - Scale factor applied by parent group (for counter-scaling)
|
|
29377
|
+
* @param groupScaleY - Scale factor applied by parent group (for counter-scaling)
|
|
29378
|
+
*/
|
|
29379
|
+
createFallbackTextElement(textContent2, textAlign, textVerticalAlign, textInsets, groupScaleX = 1, groupScaleY = 1) {
|
|
29380
|
+
const textDiv = this.doc.createElement("div");
|
|
29381
|
+
textDiv.style.position = "absolute";
|
|
29382
|
+
textDiv.style.top = "0";
|
|
29383
|
+
textDiv.style.left = "0";
|
|
29384
|
+
textDiv.style.width = "100%";
|
|
29385
|
+
textDiv.style.height = "100%";
|
|
29386
|
+
textDiv.style.display = "flex";
|
|
29387
|
+
textDiv.style.flexDirection = "column";
|
|
29388
|
+
const verticalAlign = textVerticalAlign ?? "center";
|
|
29389
|
+
if (verticalAlign === "top") {
|
|
29390
|
+
textDiv.style.justifyContent = "flex-start";
|
|
29391
|
+
} else if (verticalAlign === "bottom") {
|
|
29392
|
+
textDiv.style.justifyContent = "flex-end";
|
|
29393
|
+
} else {
|
|
29394
|
+
textDiv.style.justifyContent = "center";
|
|
29395
|
+
}
|
|
29396
|
+
if (textInsets) {
|
|
29397
|
+
textDiv.style.padding = `${textInsets.top}px ${textInsets.right}px ${textInsets.bottom}px ${textInsets.left}px`;
|
|
29398
|
+
} else {
|
|
29399
|
+
textDiv.style.padding = "10px";
|
|
29400
|
+
}
|
|
29401
|
+
textDiv.style.boxSizing = "border-box";
|
|
29402
|
+
textDiv.style.wordWrap = "break-word";
|
|
29403
|
+
textDiv.style.overflowWrap = "break-word";
|
|
29404
|
+
textDiv.style.overflow = "hidden";
|
|
29405
|
+
textDiv.style.minWidth = "0";
|
|
29406
|
+
textDiv.style.fontSize = "12px";
|
|
29407
|
+
textDiv.style.lineHeight = "1.2";
|
|
29408
|
+
if (groupScaleX !== 1 || groupScaleY !== 1) {
|
|
29409
|
+
const counterScaleX = 1 / groupScaleX;
|
|
29410
|
+
const counterScaleY = 1 / groupScaleY;
|
|
29411
|
+
textDiv.style.transform = `scale(${counterScaleX}, ${counterScaleY})`;
|
|
29412
|
+
textDiv.style.transformOrigin = "top left";
|
|
29413
|
+
textDiv.style.width = `${100 * groupScaleX}%`;
|
|
29414
|
+
textDiv.style.height = `${100 * groupScaleY}%`;
|
|
29415
|
+
}
|
|
29416
|
+
if (textAlign === "center") {
|
|
29417
|
+
textDiv.style.textAlign = "center";
|
|
29418
|
+
} else if (textAlign === "right" || textAlign === "r") {
|
|
29419
|
+
textDiv.style.textAlign = "right";
|
|
29420
|
+
} else {
|
|
29421
|
+
textDiv.style.textAlign = "left";
|
|
29422
|
+
}
|
|
29423
|
+
let currentParagraph = this.doc.createElement("div");
|
|
29424
|
+
currentParagraph.style.width = "100%";
|
|
29425
|
+
currentParagraph.style.minWidth = "0";
|
|
29426
|
+
currentParagraph.style.whiteSpace = "normal";
|
|
29427
|
+
textContent2.parts.forEach((part) => {
|
|
29428
|
+
if (part.isLineBreak) {
|
|
29429
|
+
textDiv.appendChild(currentParagraph);
|
|
29430
|
+
currentParagraph = this.doc.createElement("div");
|
|
29431
|
+
currentParagraph.style.width = "100%";
|
|
29432
|
+
currentParagraph.style.minWidth = "0";
|
|
29433
|
+
currentParagraph.style.whiteSpace = "normal";
|
|
29434
|
+
if (part.isEmptyParagraph) {
|
|
29435
|
+
currentParagraph.style.minHeight = "1em";
|
|
29436
|
+
}
|
|
29437
|
+
} else {
|
|
29438
|
+
const span = this.doc.createElement("span");
|
|
29439
|
+
span.textContent = part.text;
|
|
29440
|
+
if (part.formatting) {
|
|
29441
|
+
if (part.formatting.bold) {
|
|
29442
|
+
span.style.fontWeight = "bold";
|
|
29443
|
+
}
|
|
29444
|
+
if (part.formatting.italic) {
|
|
29445
|
+
span.style.fontStyle = "italic";
|
|
29446
|
+
}
|
|
29447
|
+
if (part.formatting.color) {
|
|
29448
|
+
const validatedColor = validateHexColor(part.formatting.color);
|
|
29449
|
+
if (validatedColor) {
|
|
29450
|
+
span.style.color = validatedColor;
|
|
29451
|
+
}
|
|
29452
|
+
}
|
|
29453
|
+
if (part.formatting.fontSize) {
|
|
29454
|
+
span.style.fontSize = `${part.formatting.fontSize}px`;
|
|
29455
|
+
}
|
|
29456
|
+
}
|
|
29457
|
+
currentParagraph.appendChild(span);
|
|
29458
|
+
}
|
|
29459
|
+
});
|
|
29460
|
+
textDiv.appendChild(currentParagraph);
|
|
29461
|
+
return textDiv;
|
|
29462
|
+
}
|
|
27902
29463
|
tryCreatePresetSvg(block) {
|
|
27903
29464
|
try {
|
|
29465
|
+
let fillColor;
|
|
29466
|
+
if (block.fillColor === null) {
|
|
29467
|
+
fillColor = "none";
|
|
29468
|
+
} else if (typeof block.fillColor === "string") {
|
|
29469
|
+
fillColor = block.fillColor;
|
|
29470
|
+
}
|
|
29471
|
+
const strokeColor = block.strokeColor === null ? "none" : typeof block.strokeColor === "string" ? block.strokeColor : void 0;
|
|
29472
|
+
if (block.shapeKind === "line") {
|
|
29473
|
+
const width = block.geometry.width;
|
|
29474
|
+
const height = block.geometry.height;
|
|
29475
|
+
const stroke = strokeColor ?? "#000000";
|
|
29476
|
+
const strokeWidth = block.strokeWidth ?? 1;
|
|
29477
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
|
|
29478
|
+
<line x1="0" y1="0" x2="${width}" y2="${height}" stroke="${stroke}" stroke-width="${strokeWidth}" />
|
|
29479
|
+
</svg>`;
|
|
29480
|
+
}
|
|
27904
29481
|
return k({
|
|
27905
29482
|
preset: block.shapeKind ?? "",
|
|
27906
29483
|
styleOverrides: () => ({
|
|
27907
|
-
fill:
|
|
27908
|
-
stroke:
|
|
29484
|
+
fill: fillColor,
|
|
29485
|
+
stroke: strokeColor,
|
|
27909
29486
|
strokeWidth: block.strokeWidth ?? void 0
|
|
27910
29487
|
})
|
|
27911
29488
|
});
|
|
@@ -27971,6 +29548,8 @@ const _DomPainter = class _DomPainter {
|
|
|
27971
29548
|
groupEl.style.height = "100%";
|
|
27972
29549
|
const groupTransform = block.groupTransform;
|
|
27973
29550
|
let contentContainer = groupEl;
|
|
29551
|
+
let groupScaleX = 1;
|
|
29552
|
+
let groupScaleY = 1;
|
|
27974
29553
|
if (groupTransform) {
|
|
27975
29554
|
const inner = this.doc.createElement("div");
|
|
27976
29555
|
inner.style.position = "absolute";
|
|
@@ -27988,10 +29567,10 @@ const _DomPainter = class _DomPainter {
|
|
|
27988
29567
|
}
|
|
27989
29568
|
const targetWidth = groupTransform.width ?? block.geometry.width ?? childWidth;
|
|
27990
29569
|
const targetHeight = groupTransform.height ?? block.geometry.height ?? childHeight;
|
|
27991
|
-
|
|
27992
|
-
|
|
27993
|
-
if (
|
|
27994
|
-
transforms.push(`scale(${
|
|
29570
|
+
groupScaleX = childWidth ? targetWidth / childWidth : 1;
|
|
29571
|
+
groupScaleY = childHeight ? targetHeight / childHeight : 1;
|
|
29572
|
+
if (groupScaleX !== 1 || groupScaleY !== 1) {
|
|
29573
|
+
transforms.push(`scale(${groupScaleX}, ${groupScaleY})`);
|
|
27995
29574
|
}
|
|
27996
29575
|
if (transforms.length > 0) {
|
|
27997
29576
|
inner.style.transformOrigin = "top left";
|
|
@@ -28001,7 +29580,7 @@ const _DomPainter = class _DomPainter {
|
|
|
28001
29580
|
contentContainer = inner;
|
|
28002
29581
|
}
|
|
28003
29582
|
block.shapes.forEach((child) => {
|
|
28004
|
-
const childContent = this.createGroupChildContent(child);
|
|
29583
|
+
const childContent = this.createGroupChildContent(child, groupScaleX, groupScaleY);
|
|
28005
29584
|
if (!childContent) return;
|
|
28006
29585
|
const attrs = child.attrs ?? {};
|
|
28007
29586
|
const wrapper = this.doc.createElement("div");
|
|
@@ -28034,20 +29613,21 @@ const _DomPainter = class _DomPainter {
|
|
|
28034
29613
|
});
|
|
28035
29614
|
return groupEl;
|
|
28036
29615
|
}
|
|
28037
|
-
createGroupChildContent(child) {
|
|
29616
|
+
createGroupChildContent(child, groupScaleX = 1, groupScaleY = 1) {
|
|
28038
29617
|
if (child.shapeType === "vectorShape" && "fillColor" in child.attrs) {
|
|
28039
29618
|
const attrs = child.attrs;
|
|
29619
|
+
const childGeometry = {
|
|
29620
|
+
width: attrs.width ?? 0,
|
|
29621
|
+
height: attrs.height ?? 0,
|
|
29622
|
+
rotation: attrs.rotation ?? 0,
|
|
29623
|
+
flipH: attrs.flipH ?? false,
|
|
29624
|
+
flipV: attrs.flipV ?? false
|
|
29625
|
+
};
|
|
28040
29626
|
const vectorChild = {
|
|
28041
29627
|
drawingKind: "vectorShape",
|
|
28042
29628
|
kind: "drawing",
|
|
28043
29629
|
id: `${attrs.shapeId ?? child.shapeType}`,
|
|
28044
|
-
geometry:
|
|
28045
|
-
width: attrs.width ?? 0,
|
|
28046
|
-
height: attrs.height ?? 0,
|
|
28047
|
-
rotation: attrs.rotation ?? 0,
|
|
28048
|
-
flipH: attrs.flipH ?? false,
|
|
28049
|
-
flipV: attrs.flipV ?? false
|
|
28050
|
-
},
|
|
29630
|
+
geometry: childGeometry,
|
|
28051
29631
|
padding: void 0,
|
|
28052
29632
|
margin: void 0,
|
|
28053
29633
|
anchor: void 0,
|
|
@@ -28058,9 +29638,11 @@ const _DomPainter = class _DomPainter {
|
|
|
28058
29638
|
shapeKind: attrs.kind,
|
|
28059
29639
|
fillColor: attrs.fillColor,
|
|
28060
29640
|
strokeColor: attrs.strokeColor,
|
|
28061
|
-
strokeWidth: attrs.strokeWidth
|
|
29641
|
+
strokeWidth: attrs.strokeWidth,
|
|
29642
|
+
textContent: attrs.textContent,
|
|
29643
|
+
textAlign: attrs.textAlign
|
|
28062
29644
|
};
|
|
28063
|
-
return this.createVectorShapeElement(vectorChild);
|
|
29645
|
+
return this.createVectorShapeElement(vectorChild, childGeometry, false, groupScaleX, groupScaleY);
|
|
28064
29646
|
}
|
|
28065
29647
|
if (child.shapeType === "image" && "src" in child.attrs) {
|
|
28066
29648
|
const attrs = child.attrs;
|
|
@@ -28250,7 +29832,16 @@ const _DomPainter = class _DomPainter {
|
|
|
28250
29832
|
/**
|
|
28251
29833
|
* Render a single run as an HTML element (span or anchor).
|
|
28252
29834
|
*/
|
|
29835
|
+
/**
|
|
29836
|
+
* Type guard to check if a run is an image run.
|
|
29837
|
+
*/
|
|
29838
|
+
isImageRun(run) {
|
|
29839
|
+
return run.kind === "image";
|
|
29840
|
+
}
|
|
28253
29841
|
renderRun(run, context, trackedConfig) {
|
|
29842
|
+
if (this.isImageRun(run)) {
|
|
29843
|
+
return this.renderImageRun(run);
|
|
29844
|
+
}
|
|
28254
29845
|
if (!run.text || !this.doc) {
|
|
28255
29846
|
return null;
|
|
28256
29847
|
}
|
|
@@ -28285,6 +29876,88 @@ const _DomPainter = class _DomPainter {
|
|
|
28285
29876
|
this.applySdtDataset(elem, run.sdt);
|
|
28286
29877
|
return elem;
|
|
28287
29878
|
}
|
|
29879
|
+
/**
|
|
29880
|
+
* Renders an ImageRun as an inline <img> element.
|
|
29881
|
+
*
|
|
29882
|
+
* SECURITY NOTES:
|
|
29883
|
+
* - Data URLs are validated against VALID_IMAGE_DATA_URL regex to ensure proper format
|
|
29884
|
+
* - Size limit (MAX_DATA_URL_LENGTH) prevents DoS attacks from extremely large images
|
|
29885
|
+
* - Only allows safe image MIME types (png, jpeg, gif, etc.) with base64 encoding
|
|
29886
|
+
* - Non-data URLs are sanitized through sanitizeUrl to prevent XSS
|
|
29887
|
+
*
|
|
29888
|
+
* @param run - The ImageRun to render containing image source, dimensions, and spacing
|
|
29889
|
+
* @returns HTMLElement (img) or null if src is missing or invalid
|
|
29890
|
+
*
|
|
29891
|
+
* @example
|
|
29892
|
+
* ```typescript
|
|
29893
|
+
* // Valid data URL
|
|
29894
|
+
* renderImageRun({ kind: 'image', src: 'data:image/png;base64,iVBORw...', width: 100, height: 100 })
|
|
29895
|
+
* // Returns: <img> element
|
|
29896
|
+
*
|
|
29897
|
+
* // Invalid MIME type
|
|
29898
|
+
* renderImageRun({ kind: 'image', src: 'data:text/html;base64,PHNjcmlwdD4...', width: 100, height: 100 })
|
|
29899
|
+
* // Returns: null (blocked)
|
|
29900
|
+
*
|
|
29901
|
+
* // HTTP URL
|
|
29902
|
+
* renderImageRun({ kind: 'image', src: 'https://example.com/image.png', width: 100, height: 100 })
|
|
29903
|
+
* // Returns: <img> element (after sanitization)
|
|
29904
|
+
* ```
|
|
29905
|
+
*/
|
|
29906
|
+
renderImageRun(run) {
|
|
29907
|
+
if (!this.doc || !run.src) {
|
|
29908
|
+
return null;
|
|
29909
|
+
}
|
|
29910
|
+
const img = this.doc.createElement("img");
|
|
29911
|
+
const isDataUrl = typeof run.src === "string" && run.src.startsWith("data:");
|
|
29912
|
+
if (isDataUrl) {
|
|
29913
|
+
if (run.src.length > MAX_DATA_URL_LENGTH) {
|
|
29914
|
+
return null;
|
|
29915
|
+
}
|
|
29916
|
+
if (!VALID_IMAGE_DATA_URL.test(run.src)) {
|
|
29917
|
+
return null;
|
|
29918
|
+
}
|
|
29919
|
+
img.src = run.src;
|
|
29920
|
+
} else {
|
|
29921
|
+
const sanitized = sanitizeUrl(run.src);
|
|
29922
|
+
if (sanitized) {
|
|
29923
|
+
img.src = sanitized;
|
|
29924
|
+
} else {
|
|
29925
|
+
return null;
|
|
29926
|
+
}
|
|
29927
|
+
}
|
|
29928
|
+
img.width = run.width;
|
|
29929
|
+
img.height = run.height;
|
|
29930
|
+
img.alt = run.alt ?? "";
|
|
29931
|
+
if (run.title) {
|
|
29932
|
+
img.title = run.title;
|
|
29933
|
+
}
|
|
29934
|
+
img.style.display = "inline-block";
|
|
29935
|
+
img.style.verticalAlign = run.verticalAlign ?? "bottom";
|
|
29936
|
+
if (run.distTop) {
|
|
29937
|
+
img.style.marginTop = `${run.distTop}px`;
|
|
29938
|
+
}
|
|
29939
|
+
if (run.distBottom) {
|
|
29940
|
+
img.style.marginBottom = `${run.distBottom}px`;
|
|
29941
|
+
}
|
|
29942
|
+
if (run.distLeft) {
|
|
29943
|
+
img.style.marginLeft = `${run.distLeft}px`;
|
|
29944
|
+
}
|
|
29945
|
+
if (run.distRight) {
|
|
29946
|
+
img.style.marginRight = `${run.distRight}px`;
|
|
29947
|
+
}
|
|
29948
|
+
img.style.zIndex = "1";
|
|
29949
|
+
if (run.pmStart != null) {
|
|
29950
|
+
img.dataset.pmStart = String(run.pmStart);
|
|
29951
|
+
}
|
|
29952
|
+
if (run.pmEnd != null) {
|
|
29953
|
+
img.dataset.pmEnd = String(run.pmEnd);
|
|
29954
|
+
}
|
|
29955
|
+
this.applySdtDataset(img, run.sdt);
|
|
29956
|
+
if (run.dataAttrs) {
|
|
29957
|
+
applyRunDataAttributes(img, run.dataAttrs);
|
|
29958
|
+
}
|
|
29959
|
+
return img;
|
|
29960
|
+
}
|
|
28288
29961
|
renderLine(block, line, context) {
|
|
28289
29962
|
if (!this.doc) {
|
|
28290
29963
|
throw new Error("DomPainter: document is not available");
|
|
@@ -28356,6 +30029,16 @@ const _DomPainter = class _DomPainter {
|
|
|
28356
30029
|
line.segments.forEach((segment, _segIdx) => {
|
|
28357
30030
|
const baseRun = runs[segment.runIndex];
|
|
28358
30031
|
if (!baseRun || baseRun.kind === "tab") return;
|
|
30032
|
+
if (this.isImageRun(baseRun)) {
|
|
30033
|
+
const elem2 = this.renderRun(baseRun, context, trackedConfig);
|
|
30034
|
+
if (elem2) {
|
|
30035
|
+
if (styleId) {
|
|
30036
|
+
elem2.setAttribute("styleid", styleId);
|
|
30037
|
+
}
|
|
30038
|
+
el.appendChild(elem2);
|
|
30039
|
+
}
|
|
30040
|
+
return;
|
|
30041
|
+
}
|
|
28359
30042
|
const segmentText = baseRun.text.slice(segment.fromChar, segment.toChar);
|
|
28360
30043
|
const segmentRun = { ...baseRun, text: segmentText };
|
|
28361
30044
|
const elem = this.renderRun(segmentRun, context, trackedConfig);
|
|
@@ -28686,8 +30369,25 @@ const fragmentSignature = (fragment, lookup) => {
|
|
|
28686
30369
|
};
|
|
28687
30370
|
const deriveBlockVersion = (block) => {
|
|
28688
30371
|
if (block.kind === "paragraph") {
|
|
28689
|
-
return block.runs.map(
|
|
28690
|
-
(run)
|
|
30372
|
+
return block.runs.map((run) => {
|
|
30373
|
+
if (run.kind === "image") {
|
|
30374
|
+
const imgRun = run;
|
|
30375
|
+
return [
|
|
30376
|
+
"img",
|
|
30377
|
+
imgRun.src,
|
|
30378
|
+
imgRun.width,
|
|
30379
|
+
imgRun.height,
|
|
30380
|
+
imgRun.alt ?? "",
|
|
30381
|
+
imgRun.title ?? "",
|
|
30382
|
+
imgRun.distTop ?? "",
|
|
30383
|
+
imgRun.distBottom ?? "",
|
|
30384
|
+
imgRun.distLeft ?? "",
|
|
30385
|
+
imgRun.distRight ?? "",
|
|
30386
|
+
imgRun.pmStart ?? "",
|
|
30387
|
+
imgRun.pmEnd ?? ""
|
|
30388
|
+
].join(",");
|
|
30389
|
+
}
|
|
30390
|
+
return [
|
|
28691
30391
|
run.text ?? "",
|
|
28692
30392
|
run.kind !== "tab" ? run.fontFamily : "",
|
|
28693
30393
|
run.kind !== "tab" ? run.fontSize : "",
|
|
@@ -28703,8 +30403,8 @@ const deriveBlockVersion = (block) => {
|
|
|
28703
30403
|
run.pmStart ?? "",
|
|
28704
30404
|
run.pmEnd ?? "",
|
|
28705
30405
|
run.kind !== "tab" ? run.token ?? "" : ""
|
|
28706
|
-
].join(",")
|
|
28707
|
-
).join("|");
|
|
30406
|
+
].join(",");
|
|
30407
|
+
}).join("|");
|
|
28708
30408
|
}
|
|
28709
30409
|
if (block.kind === "list") {
|
|
28710
30410
|
return block.items.map((item) => `${item.id}:${item.marker.text}:${deriveBlockVersion(item.paragraph)}`).join("|");
|
|
@@ -28762,7 +30462,7 @@ const deriveBlockVersion = (block) => {
|
|
|
28762
30462
|
return block.id;
|
|
28763
30463
|
};
|
|
28764
30464
|
const applyRunStyles = (element, run, isLink = false) => {
|
|
28765
|
-
if (run.kind === "tab") {
|
|
30465
|
+
if (run.kind === "tab" || run.kind === "image") {
|
|
28766
30466
|
return;
|
|
28767
30467
|
}
|
|
28768
30468
|
element.style.fontFamily = run.fontFamily;
|
|
@@ -28881,6 +30581,10 @@ const sliceRunsForLine = (block, line) => {
|
|
|
28881
30581
|
for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
|
|
28882
30582
|
const run = block.runs[runIndex];
|
|
28883
30583
|
if (!run) continue;
|
|
30584
|
+
if (run.kind === "image") {
|
|
30585
|
+
result.push(run);
|
|
30586
|
+
continue;
|
|
30587
|
+
}
|
|
28884
30588
|
const text = run.text ?? "";
|
|
28885
30589
|
const isFirstRun = runIndex === line.fromRun;
|
|
28886
30590
|
const isLastRun = runIndex === line.toRun;
|
|
@@ -28919,6 +30623,21 @@ const computeLinePmRange = (block, line) => {
|
|
|
28919
30623
|
for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
|
|
28920
30624
|
const run = block.runs[runIndex];
|
|
28921
30625
|
if (!run) continue;
|
|
30626
|
+
if (run.kind === "image") {
|
|
30627
|
+
const runPmStart2 = run.pmStart ?? null;
|
|
30628
|
+
const runPmEnd = run.pmEnd ?? null;
|
|
30629
|
+
if (runPmStart2 == null || runPmEnd == null) {
|
|
30630
|
+
continue;
|
|
30631
|
+
}
|
|
30632
|
+
if (pmStart == null) {
|
|
30633
|
+
pmStart = runPmStart2;
|
|
30634
|
+
}
|
|
30635
|
+
pmEnd = runPmEnd;
|
|
30636
|
+
if (runIndex === line.toRun) {
|
|
30637
|
+
break;
|
|
30638
|
+
}
|
|
30639
|
+
continue;
|
|
30640
|
+
}
|
|
28922
30641
|
const text = run.text ?? "";
|
|
28923
30642
|
const runLength = text.length;
|
|
28924
30643
|
const runPmStart = run.pmStart ?? null;
|
|
@@ -28950,27 +30669,21 @@ const applyStyles$2 = (el, styles) => {
|
|
|
28950
30669
|
});
|
|
28951
30670
|
};
|
|
28952
30671
|
const resolveRunText = (run, context) => {
|
|
30672
|
+
const runToken = "token" in run ? run.token : void 0;
|
|
28953
30673
|
if (run.kind === "tab") {
|
|
28954
30674
|
return run.text;
|
|
28955
30675
|
}
|
|
28956
|
-
if (
|
|
30676
|
+
if (run.kind === "image") {
|
|
30677
|
+
return "";
|
|
30678
|
+
}
|
|
30679
|
+
if (!runToken) {
|
|
28957
30680
|
return run.text ?? "";
|
|
28958
30681
|
}
|
|
28959
|
-
if (
|
|
28960
|
-
|
|
28961
|
-
if (typeof process$1 !== "undefined" && process$1.env?.NODE_ENV === "development" && context.section) {
|
|
28962
|
-
console.debug(
|
|
28963
|
-
`[Page Number] ${context.section}: page ${context.pageNumber} of ${context.totalPages} → "${resolved}"`
|
|
28964
|
-
);
|
|
28965
|
-
}
|
|
28966
|
-
return resolved;
|
|
30682
|
+
if (runToken === "pageNumber") {
|
|
30683
|
+
return context.pageNumberText ?? String(context.pageNumber);
|
|
28967
30684
|
}
|
|
28968
|
-
if (
|
|
28969
|
-
|
|
28970
|
-
if (typeof process$1 !== "undefined" && process$1.env?.NODE_ENV === "development" && context.section) {
|
|
28971
|
-
console.debug(`[Total Pages] ${context.section}: ${resolved}`);
|
|
28972
|
-
}
|
|
28973
|
-
return resolved;
|
|
30685
|
+
if (runToken === "totalPageCount") {
|
|
30686
|
+
return context.totalPages ? String(context.totalPages) : run.text ?? "";
|
|
28974
30687
|
}
|
|
28975
30688
|
return run.text ?? "";
|
|
28976
30689
|
};
|
|
@@ -29126,6 +30839,9 @@ function calculateTypographyMetrics(fontSize, spacing) {
|
|
|
29126
30839
|
function isTabRun(run) {
|
|
29127
30840
|
return run.kind === "tab";
|
|
29128
30841
|
}
|
|
30842
|
+
function isImageRun(run) {
|
|
30843
|
+
return run.kind === "image";
|
|
30844
|
+
}
|
|
29129
30845
|
async function measureBlock(block, constraints) {
|
|
29130
30846
|
const normalized = normalizeConstraints(constraints);
|
|
29131
30847
|
if (block.kind === "drawing") {
|
|
@@ -29269,6 +30985,79 @@ async function measureParagraphBlock(block, maxWidth) {
|
|
|
29269
30985
|
}
|
|
29270
30986
|
continue;
|
|
29271
30987
|
}
|
|
30988
|
+
if (isImageRun(run)) {
|
|
30989
|
+
const leftSpace = run.distLeft ?? 0;
|
|
30990
|
+
const rightSpace = run.distRight ?? 0;
|
|
30991
|
+
const imageWidth = run.width + leftSpace + rightSpace;
|
|
30992
|
+
const topSpace = run.distTop ?? 0;
|
|
30993
|
+
const bottomSpace = run.distBottom ?? 0;
|
|
30994
|
+
const imageHeight = run.height + topSpace + bottomSpace;
|
|
30995
|
+
if (!currentLine) {
|
|
30996
|
+
currentLine = {
|
|
30997
|
+
fromRun: runIndex,
|
|
30998
|
+
fromChar: 0,
|
|
30999
|
+
toRun: runIndex,
|
|
31000
|
+
toChar: 1,
|
|
31001
|
+
// Images are treated as single atomic units
|
|
31002
|
+
width: imageWidth,
|
|
31003
|
+
maxFontSize: imageHeight,
|
|
31004
|
+
// Use image height for line height calculation
|
|
31005
|
+
maxWidth: availableWidth,
|
|
31006
|
+
segments: [
|
|
31007
|
+
{
|
|
31008
|
+
runIndex,
|
|
31009
|
+
fromChar: 0,
|
|
31010
|
+
toChar: 1,
|
|
31011
|
+
width: imageWidth
|
|
31012
|
+
}
|
|
31013
|
+
]
|
|
31014
|
+
};
|
|
31015
|
+
availableWidth = contentWidth;
|
|
31016
|
+
continue;
|
|
31017
|
+
}
|
|
31018
|
+
if (currentLine.width + imageWidth > currentLine.maxWidth && currentLine.width > 0) {
|
|
31019
|
+
const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing);
|
|
31020
|
+
const completedLine = {
|
|
31021
|
+
...currentLine,
|
|
31022
|
+
...metrics
|
|
31023
|
+
};
|
|
31024
|
+
addBarTabsToLine(completedLine);
|
|
31025
|
+
lines.push(completedLine);
|
|
31026
|
+
tabStopCursor = 0;
|
|
31027
|
+
pendingTabAlignment = null;
|
|
31028
|
+
currentLine = {
|
|
31029
|
+
fromRun: runIndex,
|
|
31030
|
+
fromChar: 0,
|
|
31031
|
+
toRun: runIndex,
|
|
31032
|
+
toChar: 1,
|
|
31033
|
+
width: imageWidth,
|
|
31034
|
+
maxFontSize: imageHeight,
|
|
31035
|
+
maxWidth: contentWidth,
|
|
31036
|
+
segments: [
|
|
31037
|
+
{
|
|
31038
|
+
runIndex,
|
|
31039
|
+
fromChar: 0,
|
|
31040
|
+
toChar: 1,
|
|
31041
|
+
width: imageWidth
|
|
31042
|
+
}
|
|
31043
|
+
]
|
|
31044
|
+
};
|
|
31045
|
+
availableWidth = contentWidth;
|
|
31046
|
+
} else {
|
|
31047
|
+
currentLine.toRun = runIndex;
|
|
31048
|
+
currentLine.toChar = 1;
|
|
31049
|
+
currentLine.width = roundValue(currentLine.width + imageWidth);
|
|
31050
|
+
currentLine.maxFontSize = Math.max(currentLine.maxFontSize, imageHeight);
|
|
31051
|
+
if (!currentLine.segments) currentLine.segments = [];
|
|
31052
|
+
currentLine.segments.push({
|
|
31053
|
+
runIndex,
|
|
31054
|
+
fromChar: 0,
|
|
31055
|
+
toChar: 1,
|
|
31056
|
+
width: imageWidth
|
|
31057
|
+
});
|
|
31058
|
+
}
|
|
31059
|
+
continue;
|
|
31060
|
+
}
|
|
29272
31061
|
const { font } = buildFontString(run);
|
|
29273
31062
|
const tabSegments = run.text.split(" ");
|
|
29274
31063
|
let charPosInRun = 0;
|
|
@@ -29423,7 +31212,7 @@ async function measureParagraphBlock(block, maxWidth) {
|
|
|
29423
31212
|
}
|
|
29424
31213
|
}
|
|
29425
31214
|
if (!currentLine && lines.length === 0) {
|
|
29426
|
-
const fallbackFontSize = (block.runs[0]?.kind
|
|
31215
|
+
const fallbackFontSize = (block.runs[0]?.kind === "text" ? block.runs[0].fontSize : void 0) ?? 12;
|
|
29427
31216
|
const metrics = calculateTypographyMetrics(fallbackFontSize, spacing);
|
|
29428
31217
|
const fallbackLine = {
|
|
29429
31218
|
fromRun: 0,
|
|
@@ -29474,16 +31263,34 @@ async function measureParagraphBlock(block, maxWidth) {
|
|
|
29474
31263
|
async function measureTableBlock(block, constraints) {
|
|
29475
31264
|
const maxWidth = typeof constraints === "number" ? constraints : constraints.maxWidth;
|
|
29476
31265
|
let columnWidths;
|
|
31266
|
+
const maxCellCount = Math.max(1, Math.max(...block.rows.map((r2) => r2.cells.length)));
|
|
29477
31267
|
if (block.columnWidths && block.columnWidths.length > 0) {
|
|
29478
31268
|
columnWidths = [...block.columnWidths];
|
|
29479
|
-
const totalWidth2 = columnWidths.reduce((a, b) => a + b, 0);
|
|
29480
31269
|
const hasExplicitWidth = block.attrs?.tableWidth != null;
|
|
29481
|
-
|
|
29482
|
-
|
|
29483
|
-
|
|
31270
|
+
const hasFixedLayout = block.attrs?.tableLayout === "fixed";
|
|
31271
|
+
if (hasExplicitWidth || hasFixedLayout) {
|
|
31272
|
+
const totalWidth2 = columnWidths.reduce((a, b) => a + b, 0);
|
|
31273
|
+
if (totalWidth2 > maxWidth) {
|
|
31274
|
+
const scale = maxWidth / totalWidth2;
|
|
31275
|
+
columnWidths = columnWidths.map((w) => Math.max(1, Math.floor(w * scale)));
|
|
31276
|
+
}
|
|
31277
|
+
} else {
|
|
31278
|
+
if (columnWidths.length < maxCellCount) {
|
|
31279
|
+
const usedWidth = columnWidths.reduce((a, b) => a + b, 0);
|
|
31280
|
+
const remainingWidth = Math.max(0, maxWidth - usedWidth);
|
|
31281
|
+
const missingColumns = maxCellCount - columnWidths.length;
|
|
31282
|
+
const paddingWidth = Math.max(1, Math.floor(remainingWidth / missingColumns));
|
|
31283
|
+
columnWidths.push(...Array.from({ length: missingColumns }, () => paddingWidth));
|
|
31284
|
+
} else if (columnWidths.length > maxCellCount) {
|
|
31285
|
+
columnWidths = columnWidths.slice(0, maxCellCount);
|
|
31286
|
+
}
|
|
31287
|
+
const totalWidth2 = columnWidths.reduce((a, b) => a + b, 0);
|
|
31288
|
+
if (totalWidth2 > maxWidth) {
|
|
31289
|
+
const scale = maxWidth / totalWidth2;
|
|
31290
|
+
columnWidths = columnWidths.map((w) => Math.max(1, Math.floor(w * scale)));
|
|
31291
|
+
}
|
|
29484
31292
|
}
|
|
29485
31293
|
} else {
|
|
29486
|
-
const maxCellCount = Math.max(1, Math.max(...block.rows.map((r2) => r2.cells.length)));
|
|
29487
31294
|
const columnWidth = Math.max(1, Math.floor(maxWidth / maxCellCount));
|
|
29488
31295
|
columnWidths = Array.from({ length: maxCellCount }, () => columnWidth);
|
|
29489
31296
|
}
|
|
@@ -29517,12 +31324,28 @@ async function measureTableBlock(block, constraints) {
|
|
|
29517
31324
|
rowspanTracker[gridColIndex + c] = rowspan - 1;
|
|
29518
31325
|
}
|
|
29519
31326
|
}
|
|
29520
|
-
const
|
|
29521
|
-
const
|
|
31327
|
+
const cellPadding = cell.attrs?.padding ?? { top: 2, left: 4, right: 4, bottom: 2 };
|
|
31328
|
+
const paddingTop = cellPadding.top ?? 2;
|
|
31329
|
+
const paddingBottom = cellPadding.bottom ?? 2;
|
|
31330
|
+
const paddingLeft = cellPadding.left ?? 4;
|
|
31331
|
+
const paddingRight = cellPadding.right ?? 4;
|
|
31332
|
+
const contentWidth = Math.max(1, cellWidth - paddingLeft - paddingRight);
|
|
31333
|
+
const blockMeasures = [];
|
|
31334
|
+
let contentHeight = 0;
|
|
31335
|
+
const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
|
|
31336
|
+
for (const block2 of cellBlocks) {
|
|
31337
|
+
const measure = await measureBlock(block2, { maxWidth: contentWidth, maxHeight: Infinity });
|
|
31338
|
+
blockMeasures.push(measure);
|
|
31339
|
+
const blockHeight = "totalHeight" in measure ? measure.totalHeight : "height" in measure ? measure.height : 0;
|
|
31340
|
+
contentHeight += blockHeight;
|
|
31341
|
+
}
|
|
31342
|
+
const totalCellHeight = contentHeight + paddingTop + paddingBottom;
|
|
29522
31343
|
cellMeasures.push({
|
|
29523
|
-
|
|
31344
|
+
blocks: blockMeasures,
|
|
31345
|
+
// Backward compatibility
|
|
31346
|
+
paragraph: blockMeasures[0]?.kind === "paragraph" ? blockMeasures[0] : void 0,
|
|
29524
31347
|
width: cellWidth,
|
|
29525
|
-
height,
|
|
31348
|
+
height: totalCellHeight,
|
|
29526
31349
|
gridColumnStart: gridColIndex,
|
|
29527
31350
|
colSpan: colspan,
|
|
29528
31351
|
rowSpan: rowspan
|
|
@@ -29550,7 +31373,8 @@ async function measureTableBlock(block, constraints) {
|
|
|
29550
31373
|
async function measureImageBlock(block, constraints) {
|
|
29551
31374
|
const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
|
|
29552
31375
|
const maxWidth = constraints.maxWidth > 0 ? constraints.maxWidth : intrinsic.width;
|
|
29553
|
-
const
|
|
31376
|
+
const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
|
|
31377
|
+
const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
|
|
29554
31378
|
const widthScale = maxWidth / intrinsic.width;
|
|
29555
31379
|
const heightScale = maxHeight / intrinsic.height;
|
|
29556
31380
|
const scale = Math.min(1, widthScale, heightScale);
|
|
@@ -29594,7 +31418,8 @@ async function measureDrawingBlock(block, constraints) {
|
|
|
29594
31418
|
const naturalWidth = Math.max(1, rotatedBounds.width);
|
|
29595
31419
|
const naturalHeight = Math.max(1, rotatedBounds.height);
|
|
29596
31420
|
const maxWidth = constraints.maxWidth > 0 ? constraints.maxWidth : naturalWidth;
|
|
29597
|
-
const
|
|
31421
|
+
const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
|
|
31422
|
+
const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
|
|
29598
31423
|
const widthScale = maxWidth / naturalWidth;
|
|
29599
31424
|
const heightScale = maxHeight / naturalHeight;
|
|
29600
31425
|
const normalizedScale = Math.min(1, widthScale, heightScale);
|
|
@@ -29705,14 +31530,14 @@ async function measureListBlock(block, constraints) {
|
|
|
29705
31530
|
};
|
|
29706
31531
|
}
|
|
29707
31532
|
const getPrimaryRun = (paragraph) => {
|
|
29708
|
-
return paragraph.runs.find((run) => run.kind
|
|
31533
|
+
return paragraph.runs.find((run) => run.kind === "text" && Boolean(run.fontFamily && run.fontSize)) || {
|
|
29709
31534
|
text: "",
|
|
29710
31535
|
fontFamily: "Arial",
|
|
29711
31536
|
fontSize: 16
|
|
29712
31537
|
};
|
|
29713
31538
|
};
|
|
29714
31539
|
const measureRunWidth = (text, font, ctx2, run) => {
|
|
29715
|
-
const letterSpacing = run.kind
|
|
31540
|
+
const letterSpacing = run.kind === "text" ? run.letterSpacing || 0 : 0;
|
|
29716
31541
|
const width = getMeasuredTextWidth(text, font, letterSpacing, ctx2);
|
|
29717
31542
|
return roundValue(width);
|
|
29718
31543
|
};
|
|
@@ -30607,8 +32432,12 @@ getBlocks_fn = function(descriptor) {
|
|
|
30607
32432
|
}
|
|
30608
32433
|
const blockIdPrefix = `hf-${descriptor.kind}-${descriptor.id}-`;
|
|
30609
32434
|
const converterContext = __privateMethod(this, _HeaderFooterLayoutAdapter_instances, getConverterContext_fn).call(this);
|
|
32435
|
+
const rootConverter = __privateGet(this, _manager).rootEditor?.converter;
|
|
32436
|
+
const providedMedia = __privateGet(this, _mediaFiles);
|
|
32437
|
+
const fallbackMedia = rootConverter?.media;
|
|
32438
|
+
const mediaFiles = providedMedia && Object.keys(providedMedia).length > 0 ? providedMedia : fallbackMedia;
|
|
30610
32439
|
const result = toFlowBlocks(doc2, {
|
|
30611
|
-
mediaFiles
|
|
32440
|
+
mediaFiles,
|
|
30612
32441
|
blockIdPrefix,
|
|
30613
32442
|
converterContext
|
|
30614
32443
|
});
|
|
@@ -30722,6 +32551,7 @@ const _PresentationEditor = class _PresentationEditor extends EventEmitter {
|
|
|
30722
32551
|
__privateAdd(this, _clickCount, 0);
|
|
30723
32552
|
__privateAdd(this, _lastClickTime, 0);
|
|
30724
32553
|
__privateAdd(this, _lastClickPosition, { x: 0, y: 0 });
|
|
32554
|
+
__privateAdd(this, _lastSelectedImageBlockId, null);
|
|
30725
32555
|
// Remote cursor/presence state management
|
|
30726
32556
|
/** Map of clientId -> normalized remote cursor state */
|
|
30727
32557
|
__privateAdd(this, _remoteCursorState, /* @__PURE__ */ new Map());
|
|
@@ -30821,6 +32651,53 @@ const _PresentationEditor = class _PresentationEditor extends EventEmitter {
|
|
|
30821
32651
|
}
|
|
30822
32652
|
return;
|
|
30823
32653
|
}
|
|
32654
|
+
const fragmentHit = getFragmentAtPosition(
|
|
32655
|
+
__privateGet(this, _layoutState).layout,
|
|
32656
|
+
__privateGet(this, _layoutState).blocks,
|
|
32657
|
+
__privateGet(this, _layoutState).measures,
|
|
32658
|
+
hit.pos
|
|
32659
|
+
);
|
|
32660
|
+
if (fragmentHit && (fragmentHit.fragment.kind === "image" || fragmentHit.fragment.kind === "drawing")) {
|
|
32661
|
+
const doc2 = __privateGet(this, _editor3).state.doc;
|
|
32662
|
+
try {
|
|
32663
|
+
const tr = __privateGet(this, _editor3).state.tr.setSelection(NodeSelection.create(doc2, hit.pos));
|
|
32664
|
+
__privateGet(this, _editor3).view?.dispatch(tr);
|
|
32665
|
+
if (__privateGet(this, _lastSelectedImageBlockId) && __privateGet(this, _lastSelectedImageBlockId) !== fragmentHit.fragment.blockId) {
|
|
32666
|
+
this.emit("imageDeselected", { blockId: __privateGet(this, _lastSelectedImageBlockId) });
|
|
32667
|
+
}
|
|
32668
|
+
if (fragmentHit.fragment.kind === "image") {
|
|
32669
|
+
const targetElement = __privateGet(this, _viewportHost).querySelector(
|
|
32670
|
+
`.superdoc-image-fragment[data-pm-start="${fragmentHit.fragment.pmStart}"]`
|
|
32671
|
+
);
|
|
32672
|
+
if (targetElement) {
|
|
32673
|
+
this.emit("imageSelected", {
|
|
32674
|
+
element: targetElement,
|
|
32675
|
+
blockId: fragmentHit.fragment.blockId,
|
|
32676
|
+
pmStart: fragmentHit.fragment.pmStart
|
|
32677
|
+
});
|
|
32678
|
+
__privateSet(this, _lastSelectedImageBlockId, fragmentHit.fragment.blockId);
|
|
32679
|
+
}
|
|
32680
|
+
}
|
|
32681
|
+
} catch (error) {
|
|
32682
|
+
if (process$1.env.NODE_ENV === "development") {
|
|
32683
|
+
console.warn("[PresentationEditor] Failed to create NodeSelection for atomic fragment:", error);
|
|
32684
|
+
}
|
|
32685
|
+
}
|
|
32686
|
+
__privateMethod(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
|
|
32687
|
+
if (document.activeElement instanceof HTMLElement) {
|
|
32688
|
+
document.activeElement.blur();
|
|
32689
|
+
}
|
|
32690
|
+
const editorDom2 = __privateGet(this, _editor3).view?.dom;
|
|
32691
|
+
if (editorDom2) {
|
|
32692
|
+
editorDom2.focus();
|
|
32693
|
+
__privateGet(this, _editor3).view?.focus();
|
|
32694
|
+
}
|
|
32695
|
+
return;
|
|
32696
|
+
}
|
|
32697
|
+
if (__privateGet(this, _lastSelectedImageBlockId)) {
|
|
32698
|
+
this.emit("imageDeselected", { blockId: __privateGet(this, _lastSelectedImageBlockId) });
|
|
32699
|
+
__privateSet(this, _lastSelectedImageBlockId, null);
|
|
32700
|
+
}
|
|
30824
32701
|
const clickDepth = __privateMethod(this, _PresentationEditor_instances, registerPointerClick_fn).call(this, event);
|
|
30825
32702
|
let handledByDepth = false;
|
|
30826
32703
|
if (__privateGet(this, _session).mode === "body") {
|
|
@@ -31888,6 +33765,7 @@ _hoverRegion = new WeakMap();
|
|
|
31888
33765
|
_clickCount = new WeakMap();
|
|
31889
33766
|
_lastClickTime = new WeakMap();
|
|
31890
33767
|
_lastClickPosition = new WeakMap();
|
|
33768
|
+
_lastSelectedImageBlockId = new WeakMap();
|
|
31891
33769
|
_remoteCursorState = new WeakMap();
|
|
31892
33770
|
_remoteCursorDirty = new WeakMap();
|
|
31893
33771
|
_remoteCursorOverlay = new WeakMap();
|
|
@@ -32367,7 +34245,9 @@ initHeaderFooterRegistry_fn = function() {
|
|
|
32367
34245
|
const converter = __privateGet(this, _editor3).converter;
|
|
32368
34246
|
__privateSet(this, _headerFooterIdentifier, extractIdentifierFromConverter(converter));
|
|
32369
34247
|
__privateSet(this, _headerFooterManager, new HeaderFooterEditorManager(__privateGet(this, _editor3)));
|
|
32370
|
-
const
|
|
34248
|
+
const optionsMedia = __privateGet(this, _options)?.mediaFiles;
|
|
34249
|
+
const storageMedia = __privateGet(this, _editor3).storage?.image?.media;
|
|
34250
|
+
const mediaFiles = optionsMedia ?? storageMedia;
|
|
32371
34251
|
__privateSet(this, _headerFooterAdapter, new HeaderFooterLayoutAdapter(
|
|
32372
34252
|
__privateGet(this, _headerFooterManager),
|
|
32373
34253
|
mediaFiles
|
|
@@ -32862,7 +34742,9 @@ buildHeaderFooterInput_fn = function() {
|
|
|
32862
34742
|
computeHeaderFooterConstraints_fn = function() {
|
|
32863
34743
|
const pageSize = __privateGet(this, _layoutOptions).pageSize ?? DEFAULT_PAGE_SIZE;
|
|
32864
34744
|
const margins = __privateGet(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
|
|
32865
|
-
const
|
|
34745
|
+
const marginLeft = margins.left ?? DEFAULT_MARGINS.left;
|
|
34746
|
+
const marginRight = margins.right ?? DEFAULT_MARGINS.right;
|
|
34747
|
+
const width = pageSize.w - (marginLeft + marginRight);
|
|
32866
34748
|
if (!Number.isFinite(width) || width <= 0) {
|
|
32867
34749
|
return null;
|
|
32868
34750
|
}
|
|
@@ -32870,7 +34752,10 @@ computeHeaderFooterConstraints_fn = function() {
|
|
|
32870
34752
|
const height = Math.max(headerSpace, footerSpace, 1);
|
|
32871
34753
|
return {
|
|
32872
34754
|
width,
|
|
32873
|
-
height
|
|
34755
|
+
height,
|
|
34756
|
+
// Pass actual page dimensions for page-relative anchor positioning in headers/footers
|
|
34757
|
+
pageWidth: pageSize.w,
|
|
34758
|
+
margins: { left: marginLeft, right: marginRight }
|
|
32874
34759
|
};
|
|
32875
34760
|
};
|
|
32876
34761
|
updateDecorationProviders_fn = function(layout) {
|
|
@@ -32893,10 +34778,11 @@ createDecorationProvider_fn = function(kind, layout) {
|
|
|
32893
34778
|
if (!variant || !variant.layout?.pages?.length) {
|
|
32894
34779
|
return null;
|
|
32895
34780
|
}
|
|
32896
|
-
const slotPage =
|
|
34781
|
+
const slotPage = __privateMethod(this, _PresentationEditor_instances, findHeaderFooterPageForPageNumber_fn).call(this, variant.layout.pages, pageNumber);
|
|
32897
34782
|
if (!slotPage) {
|
|
32898
34783
|
return null;
|
|
32899
34784
|
}
|
|
34785
|
+
const fragments = slotPage.fragments ?? [];
|
|
32900
34786
|
const pageHeight = page?.size?.h ?? layout.pageSize?.h ?? __privateGet(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
|
|
32901
34787
|
const margins = pageMargins ?? layout.pages[0]?.margins ?? __privateGet(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
|
|
32902
34788
|
const box = __privateMethod(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins, pageHeight);
|
|
@@ -32904,7 +34790,7 @@ createDecorationProvider_fn = function(kind, layout) {
|
|
|
32904
34790
|
const fallbackId = __privateGet(this, _headerFooterManager)?.getVariantId(kind, headerFooterType);
|
|
32905
34791
|
const finalHeaderId = headerId ?? fallbackId ?? void 0;
|
|
32906
34792
|
return {
|
|
32907
|
-
fragments
|
|
34793
|
+
fragments,
|
|
32908
34794
|
height: box.height,
|
|
32909
34795
|
contentHeight: variant.layout.height ?? box.height,
|
|
32910
34796
|
offset: box.offset,
|
|
@@ -32927,6 +34813,40 @@ createDecorationProvider_fn = function(kind, layout) {
|
|
|
32927
34813
|
};
|
|
32928
34814
|
};
|
|
32929
34815
|
};
|
|
34816
|
+
/**
|
|
34817
|
+
* Finds the header/footer page layout for a given page number with bucket fallback.
|
|
34818
|
+
*
|
|
34819
|
+
* Lookup strategy:
|
|
34820
|
+
* 1. Try exact match first (find page with matching number)
|
|
34821
|
+
* 2. If bucketing is used, fall back to the bucket's representative page
|
|
34822
|
+
* 3. Finally, fall back to the first available page
|
|
34823
|
+
*
|
|
34824
|
+
* Digit buckets (for large documents):
|
|
34825
|
+
* - d1: pages 1-9 → representative page 5
|
|
34826
|
+
* - d2: pages 10-99 → representative page 50
|
|
34827
|
+
* - d3: pages 100-999 → representative page 500
|
|
34828
|
+
* - d4: pages 1000+ → representative page 5000
|
|
34829
|
+
*
|
|
34830
|
+
* @param pages - Array of header/footer layout pages from the variant
|
|
34831
|
+
* @param pageNumber - Physical page number to find layout for (1-indexed)
|
|
34832
|
+
* @returns Header/footer page layout, or undefined if no suitable page found
|
|
34833
|
+
*/
|
|
34834
|
+
findHeaderFooterPageForPageNumber_fn = function(pages, pageNumber) {
|
|
34835
|
+
if (!pages || pages.length === 0) {
|
|
34836
|
+
return void 0;
|
|
34837
|
+
}
|
|
34838
|
+
const exactMatch = pages.find((p) => p.number === pageNumber);
|
|
34839
|
+
if (exactMatch) {
|
|
34840
|
+
return exactMatch;
|
|
34841
|
+
}
|
|
34842
|
+
const bucket = getBucketForPageNumber(pageNumber);
|
|
34843
|
+
const representative = getBucketRepresentative(bucket);
|
|
34844
|
+
const bucketMatch = pages.find((p) => p.number === representative);
|
|
34845
|
+
if (bucketMatch) {
|
|
34846
|
+
return bucketMatch;
|
|
34847
|
+
}
|
|
34848
|
+
return pages[0];
|
|
34849
|
+
};
|
|
32930
34850
|
computeDecorationBox_fn = function(kind, pageMargins, pageHeight) {
|
|
32931
34851
|
const margins = pageMargins ?? __privateGet(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
|
|
32932
34852
|
const pageSize = __privateGet(this, _layoutOptions).pageSize ?? DEFAULT_PAGE_SIZE;
|
|
@@ -44560,15 +46480,21 @@ const Image = Node$1.create({
|
|
|
44560
46480
|
*/
|
|
44561
46481
|
simplePos: { rendered: false },
|
|
44562
46482
|
extension: { rendered: false },
|
|
46483
|
+
shouldStretch: {
|
|
46484
|
+
default: false,
|
|
46485
|
+
rendered: false
|
|
46486
|
+
},
|
|
44563
46487
|
size: {
|
|
44564
46488
|
default: {},
|
|
44565
|
-
renderDOM: ({ size, extension }) => {
|
|
46489
|
+
renderDOM: ({ size, extension, shouldStretch }) => {
|
|
44566
46490
|
let style = "";
|
|
44567
46491
|
let { width, height } = size ?? {};
|
|
44568
46492
|
if (width) style += `width: ${width}px;`;
|
|
44569
46493
|
if (height && ["emf", "wmf"].includes(extension))
|
|
44570
46494
|
style += `height: ${height}px; border: 1px solid black; position: absolute;`;
|
|
44571
|
-
else if (height
|
|
46495
|
+
else if (height && shouldStretch) {
|
|
46496
|
+
style += `height: ${height}px; object-fit: fill;`;
|
|
46497
|
+
} else if (height) style += "height: auto;";
|
|
44572
46498
|
return { style };
|
|
44573
46499
|
}
|
|
44574
46500
|
},
|
|
@@ -44632,7 +46558,11 @@ const Image = Node$1.create({
|
|
|
44632
46558
|
switch (type) {
|
|
44633
46559
|
case "None":
|
|
44634
46560
|
style += "position: absolute;";
|
|
44635
|
-
|
|
46561
|
+
const relativeHeight = node.attrs.originalAttributes?.relativeHeight;
|
|
46562
|
+
if (relativeHeight != null) {
|
|
46563
|
+
const zIndex = Math.floor(relativeHeight / 1e6);
|
|
46564
|
+
style += `z-index: ${zIndex};`;
|
|
46565
|
+
} else if (attrs.behindDoc) {
|
|
44636
46566
|
style += "z-index: -1;";
|
|
44637
46567
|
} else {
|
|
44638
46568
|
style += "z-index: 1;";
|
|
@@ -44738,12 +46668,20 @@ const Image = Node$1.create({
|
|
|
44738
46668
|
if (!style.includes("float: left;")) {
|
|
44739
46669
|
style += "float: left;";
|
|
44740
46670
|
}
|
|
46671
|
+
} else if (!anchorData.alignH && marginOffset?.horizontal != null) {
|
|
46672
|
+
const isAbsolutelyPositioned = style.includes("position: absolute;");
|
|
46673
|
+
if (isAbsolutelyPositioned) {
|
|
46674
|
+
style += `left: ${baseHorizontal}px;`;
|
|
46675
|
+
style += "max-width: none;";
|
|
46676
|
+
baseHorizontal = 0;
|
|
46677
|
+
}
|
|
44741
46678
|
}
|
|
44742
46679
|
break;
|
|
44743
46680
|
}
|
|
44744
46681
|
}
|
|
44745
46682
|
if (hasAnchorData || hasMarginOffsets) {
|
|
44746
46683
|
const relativeFromPageV = anchorData?.vRelativeFrom === "page";
|
|
46684
|
+
const relativeFromMarginV = anchorData?.vRelativeFrom === "margin";
|
|
44747
46685
|
const maxMarginV = 500;
|
|
44748
46686
|
const baseTop = Math.max(0, marginOffset?.top ?? 0);
|
|
44749
46687
|
let rotationHorizontal = 0;
|
|
@@ -44764,7 +46702,7 @@ const Image = Node$1.create({
|
|
|
44764
46702
|
margin.left += horizontal;
|
|
44765
46703
|
}
|
|
44766
46704
|
}
|
|
44767
|
-
if (top2) {
|
|
46705
|
+
if (top2 && !relativeFromMarginV) {
|
|
44768
46706
|
if (relativeFromPageV && top2 >= maxMarginV) margin.top += maxMarginV;
|
|
44769
46707
|
else margin.top += top2;
|
|
44770
46708
|
}
|
|
@@ -45596,15 +47534,24 @@ const ContentBlock = Node$1.create({
|
|
|
45596
47534
|
},
|
|
45597
47535
|
size: {
|
|
45598
47536
|
default: null,
|
|
45599
|
-
renderDOM: (
|
|
45600
|
-
if (!size) return {};
|
|
47537
|
+
renderDOM: (attrs) => {
|
|
47538
|
+
if (!attrs.size) return {};
|
|
45601
47539
|
let style = "";
|
|
45602
|
-
if (size.top) style += `top: ${size.top}px; `;
|
|
45603
|
-
if (size.left) style += `left: ${size.left}px; `;
|
|
45604
|
-
if (
|
|
45605
|
-
|
|
45606
|
-
|
|
45607
|
-
style += `height: ${
|
|
47540
|
+
if (attrs.size.top) style += `top: ${attrs.size.top}px; `;
|
|
47541
|
+
if (attrs.size.left) style += `left: ${attrs.size.left}px; `;
|
|
47542
|
+
if (attrs.size.width)
|
|
47543
|
+
style += `width: ${attrs.size.width.toString().endsWith("%") ? attrs.size.width : `${attrs.size.width}px`}; `;
|
|
47544
|
+
if (attrs.size.height)
|
|
47545
|
+
style += `height: ${attrs.size.height.toString().endsWith("%") ? attrs.size.height : `${attrs.size.height}px`}; `;
|
|
47546
|
+
if (attrs.marginOffset?.horizontal != null || attrs.marginOffset?.top != null) {
|
|
47547
|
+
style += "position: absolute; ";
|
|
47548
|
+
const relativeHeight = attrs.originalAttributes?.relativeHeight;
|
|
47549
|
+
if (relativeHeight != null) {
|
|
47550
|
+
const zIndex = Math.floor(relativeHeight / 1e6);
|
|
47551
|
+
style += `z-index: ${zIndex}; `;
|
|
47552
|
+
} else {
|
|
47553
|
+
style += "z-index: 1; ";
|
|
47554
|
+
}
|
|
45608
47555
|
}
|
|
45609
47556
|
return { style };
|
|
45610
47557
|
}
|
|
@@ -45623,6 +47570,13 @@ const ContentBlock = Node$1.create({
|
|
|
45623
47570
|
},
|
|
45624
47571
|
attributes: {
|
|
45625
47572
|
rendered: false
|
|
47573
|
+
},
|
|
47574
|
+
originalAttributes: {
|
|
47575
|
+
rendered: false
|
|
47576
|
+
},
|
|
47577
|
+
marginOffset: {
|
|
47578
|
+
default: null,
|
|
47579
|
+
rendered: false
|
|
45626
47580
|
}
|
|
45627
47581
|
};
|
|
45628
47582
|
},
|
|
@@ -46012,8 +47966,167 @@ const TableOfContents = Node$1.create({
|
|
|
46012
47966
|
};
|
|
46013
47967
|
}
|
|
46014
47968
|
});
|
|
47969
|
+
function createGradient(gradientData, gradientId) {
|
|
47970
|
+
const { gradientType, stops, angle } = gradientData;
|
|
47971
|
+
if (!stops || stops.length === 0) {
|
|
47972
|
+
return null;
|
|
47973
|
+
}
|
|
47974
|
+
let gradient;
|
|
47975
|
+
if (gradientType === "linear") {
|
|
47976
|
+
gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
|
|
47977
|
+
gradient.setAttribute("id", gradientId);
|
|
47978
|
+
const radians = angle * Math.PI / 180;
|
|
47979
|
+
const x1 = 50 - 50 * Math.cos(radians);
|
|
47980
|
+
const y1 = 50 + 50 * Math.sin(radians);
|
|
47981
|
+
const x2 = 50 + 50 * Math.cos(radians);
|
|
47982
|
+
const y2 = 50 - 50 * Math.sin(radians);
|
|
47983
|
+
gradient.setAttribute("x1", `${x1}%`);
|
|
47984
|
+
gradient.setAttribute("y1", `${y1}%`);
|
|
47985
|
+
gradient.setAttribute("x2", `${x2}%`);
|
|
47986
|
+
gradient.setAttribute("y2", `${y2}%`);
|
|
47987
|
+
} else {
|
|
47988
|
+
gradient = document.createElementNS("http://www.w3.org/2000/svg", "radialGradient");
|
|
47989
|
+
gradient.setAttribute("id", gradientId);
|
|
47990
|
+
gradient.setAttribute("cx", "50%");
|
|
47991
|
+
gradient.setAttribute("cy", "50%");
|
|
47992
|
+
gradient.setAttribute("r", "50%");
|
|
47993
|
+
}
|
|
47994
|
+
stops.forEach((stop) => {
|
|
47995
|
+
const stopElement = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
|
47996
|
+
stopElement.setAttribute("offset", `${stop.position * 100}%`);
|
|
47997
|
+
stopElement.setAttribute("stop-color", stop.color);
|
|
47998
|
+
if (stop.alpha != null && stop.alpha < 1) {
|
|
47999
|
+
stopElement.setAttribute("stop-opacity", stop.alpha.toString());
|
|
48000
|
+
}
|
|
48001
|
+
gradient.appendChild(stopElement);
|
|
48002
|
+
});
|
|
48003
|
+
return gradient;
|
|
48004
|
+
}
|
|
48005
|
+
function createTextElement(textContent2, textAlign, width, height) {
|
|
48006
|
+
const foreignObject = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
|
|
48007
|
+
foreignObject.setAttribute("x", "0");
|
|
48008
|
+
foreignObject.setAttribute("y", "0");
|
|
48009
|
+
foreignObject.setAttribute("width", width.toString());
|
|
48010
|
+
foreignObject.setAttribute("height", height.toString());
|
|
48011
|
+
const div2 = document.createElement("div");
|
|
48012
|
+
div2.style.width = "100%";
|
|
48013
|
+
div2.style.height = "100%";
|
|
48014
|
+
div2.style.display = "flex";
|
|
48015
|
+
div2.style.flexDirection = "column";
|
|
48016
|
+
div2.style.justifyContent = "center";
|
|
48017
|
+
div2.style.padding = "10px";
|
|
48018
|
+
div2.style.boxSizing = "border-box";
|
|
48019
|
+
div2.style.wordWrap = "break-word";
|
|
48020
|
+
div2.style.overflowWrap = "break-word";
|
|
48021
|
+
div2.style.fontSize = "12px";
|
|
48022
|
+
div2.style.lineHeight = "1.2";
|
|
48023
|
+
if (textAlign === "center") {
|
|
48024
|
+
div2.style.textAlign = "center";
|
|
48025
|
+
} else if (textAlign === "right" || textAlign === "r") {
|
|
48026
|
+
div2.style.textAlign = "right";
|
|
48027
|
+
} else {
|
|
48028
|
+
div2.style.textAlign = "left";
|
|
48029
|
+
}
|
|
48030
|
+
let currentParagraph = document.createElement("div");
|
|
48031
|
+
textContent2.parts.forEach((part) => {
|
|
48032
|
+
if (part.isLineBreak) {
|
|
48033
|
+
div2.appendChild(currentParagraph);
|
|
48034
|
+
currentParagraph = document.createElement("div");
|
|
48035
|
+
if (part.isEmptyParagraph) {
|
|
48036
|
+
currentParagraph.style.minHeight = "1em";
|
|
48037
|
+
}
|
|
48038
|
+
} else {
|
|
48039
|
+
const span = document.createElement("span");
|
|
48040
|
+
span.textContent = part.text;
|
|
48041
|
+
if (part.formatting) {
|
|
48042
|
+
if (part.formatting.bold) {
|
|
48043
|
+
span.style.fontWeight = "bold";
|
|
48044
|
+
}
|
|
48045
|
+
if (part.formatting.italic) {
|
|
48046
|
+
span.style.fontStyle = "italic";
|
|
48047
|
+
}
|
|
48048
|
+
if (part.formatting.color) {
|
|
48049
|
+
span.style.color = `#${part.formatting.color}`;
|
|
48050
|
+
}
|
|
48051
|
+
if (part.formatting.fontSize) {
|
|
48052
|
+
span.style.fontSize = `${part.formatting.fontSize}px`;
|
|
48053
|
+
}
|
|
48054
|
+
}
|
|
48055
|
+
currentParagraph.appendChild(span);
|
|
48056
|
+
}
|
|
48057
|
+
});
|
|
48058
|
+
div2.appendChild(currentParagraph);
|
|
48059
|
+
foreignObject.appendChild(div2);
|
|
48060
|
+
return foreignObject;
|
|
48061
|
+
}
|
|
48062
|
+
function applyGradientToSVG(svg, gradientData) {
|
|
48063
|
+
const { gradientType, stops, angle } = gradientData;
|
|
48064
|
+
const gradientId = `gradient-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
48065
|
+
let defs = svg.querySelector("defs");
|
|
48066
|
+
if (!defs) {
|
|
48067
|
+
defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
48068
|
+
svg.insertBefore(defs, svg.firstChild);
|
|
48069
|
+
}
|
|
48070
|
+
let gradient;
|
|
48071
|
+
if (gradientType === "linear") {
|
|
48072
|
+
gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
|
|
48073
|
+
gradient.setAttribute("id", gradientId);
|
|
48074
|
+
const radians = angle * Math.PI / 180;
|
|
48075
|
+
const x1 = 50 - 50 * Math.cos(radians);
|
|
48076
|
+
const y1 = 50 + 50 * Math.sin(radians);
|
|
48077
|
+
const x2 = 50 + 50 * Math.cos(radians);
|
|
48078
|
+
const y2 = 50 - 50 * Math.sin(radians);
|
|
48079
|
+
gradient.setAttribute("x1", `${x1}%`);
|
|
48080
|
+
gradient.setAttribute("y1", `${y1}%`);
|
|
48081
|
+
gradient.setAttribute("x2", `${x2}%`);
|
|
48082
|
+
gradient.setAttribute("y2", `${y2}%`);
|
|
48083
|
+
} else {
|
|
48084
|
+
gradient = document.createElementNS("http://www.w3.org/2000/svg", "radialGradient");
|
|
48085
|
+
gradient.setAttribute("id", gradientId);
|
|
48086
|
+
gradient.setAttribute("cx", "50%");
|
|
48087
|
+
gradient.setAttribute("cy", "50%");
|
|
48088
|
+
gradient.setAttribute("r", "50%");
|
|
48089
|
+
}
|
|
48090
|
+
stops.forEach((stop) => {
|
|
48091
|
+
const stopElement = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
|
48092
|
+
stopElement.setAttribute("offset", `${stop.position * 100}%`);
|
|
48093
|
+
stopElement.setAttribute("stop-color", stop.color);
|
|
48094
|
+
if (stop.alpha != null && stop.alpha < 1) {
|
|
48095
|
+
stopElement.setAttribute("stop-opacity", stop.alpha.toString());
|
|
48096
|
+
}
|
|
48097
|
+
gradient.appendChild(stopElement);
|
|
48098
|
+
});
|
|
48099
|
+
defs.appendChild(gradient);
|
|
48100
|
+
const filledElements = svg.querySelectorAll('[fill]:not([fill="none"])');
|
|
48101
|
+
filledElements.forEach((el) => {
|
|
48102
|
+
el.setAttribute("fill", `url(#${gradientId})`);
|
|
48103
|
+
});
|
|
48104
|
+
}
|
|
48105
|
+
function applyAlphaToSVG(svg, alphaData) {
|
|
48106
|
+
const { color, alpha } = alphaData;
|
|
48107
|
+
const filledElements = svg.querySelectorAll('[fill]:not([fill="none"])');
|
|
48108
|
+
filledElements.forEach((el) => {
|
|
48109
|
+
el.setAttribute("fill", color);
|
|
48110
|
+
el.setAttribute("fill-opacity", alpha.toString());
|
|
48111
|
+
});
|
|
48112
|
+
}
|
|
48113
|
+
function generateTransforms(attrs) {
|
|
48114
|
+
const transforms = [];
|
|
48115
|
+
if (attrs.rotation != null) {
|
|
48116
|
+
transforms.push(`rotate(${attrs.rotation}deg)`);
|
|
48117
|
+
}
|
|
48118
|
+
if (attrs.flipH) {
|
|
48119
|
+
transforms.push(`scaleX(-1)`);
|
|
48120
|
+
}
|
|
48121
|
+
if (attrs.flipV) {
|
|
48122
|
+
transforms.push(`scaleY(-1)`);
|
|
48123
|
+
}
|
|
48124
|
+
return transforms;
|
|
48125
|
+
}
|
|
48126
|
+
const Z_INDEX_SCALE_FACTOR = 1e6;
|
|
46015
48127
|
class VectorShapeView {
|
|
46016
48128
|
constructor(props) {
|
|
48129
|
+
__privateAdd(this, _VectorShapeView_instances);
|
|
46017
48130
|
__publicField(this, "node");
|
|
46018
48131
|
__publicField(this, "view");
|
|
46019
48132
|
__publicField(this, "getPos");
|
|
@@ -46035,6 +48148,7 @@ class VectorShapeView {
|
|
|
46035
48148
|
}
|
|
46036
48149
|
mount() {
|
|
46037
48150
|
this.buildView();
|
|
48151
|
+
__privateMethod(this, _VectorShapeView_instances, ensureParentPositioned_fn).call(this);
|
|
46038
48152
|
}
|
|
46039
48153
|
get dom() {
|
|
46040
48154
|
return this.root;
|
|
@@ -46049,49 +48163,264 @@ class VectorShapeView {
|
|
|
46049
48163
|
element.setAttribute("data-vector-shape", "");
|
|
46050
48164
|
element.style.width = `${attrs.width}px`;
|
|
46051
48165
|
element.style.height = `${attrs.height}px`;
|
|
48166
|
+
const positioningStyle = this.getPositioningStyle(attrs);
|
|
48167
|
+
if (positioningStyle) {
|
|
48168
|
+
element.style.cssText += positioningStyle;
|
|
48169
|
+
}
|
|
46052
48170
|
const transforms = this.generateTransform();
|
|
46053
|
-
|
|
46054
|
-
|
|
48171
|
+
const positioningTransform = element.style.transform;
|
|
48172
|
+
const combinedTransforms = [];
|
|
48173
|
+
if (positioningTransform && positioningTransform.trim() !== "") {
|
|
48174
|
+
combinedTransforms.push(positioningTransform.trim());
|
|
48175
|
+
}
|
|
48176
|
+
if (Array.isArray(transforms) && transforms.length > 0) {
|
|
48177
|
+
const validTransforms = transforms.filter(
|
|
48178
|
+
(t) => t !== null && t !== void 0 && typeof t === "string" && t.trim() !== ""
|
|
48179
|
+
);
|
|
48180
|
+
if (validTransforms.length > 0) {
|
|
48181
|
+
combinedTransforms.push(...validTransforms);
|
|
48182
|
+
}
|
|
46055
48183
|
}
|
|
46056
|
-
|
|
46057
|
-
|
|
46058
|
-
|
|
46059
|
-
|
|
46060
|
-
|
|
46061
|
-
|
|
46062
|
-
|
|
46063
|
-
|
|
48184
|
+
if (combinedTransforms.length > 0) {
|
|
48185
|
+
element.style.transform = combinedTransforms.join(" ");
|
|
48186
|
+
}
|
|
48187
|
+
const svg = this.createSVGElement(attrs);
|
|
48188
|
+
if (svg) {
|
|
48189
|
+
element.appendChild(svg);
|
|
48190
|
+
if (attrs.textContent && attrs.textContent.parts) {
|
|
48191
|
+
const textElement = this.createTextElement(attrs.textContent, attrs.textAlign, attrs.width, attrs.height);
|
|
48192
|
+
if (textElement) {
|
|
48193
|
+
svg.appendChild(textElement);
|
|
48194
|
+
}
|
|
48195
|
+
}
|
|
46064
48196
|
}
|
|
46065
48197
|
return { element };
|
|
46066
48198
|
}
|
|
46067
|
-
|
|
46068
|
-
const
|
|
46069
|
-
|
|
46070
|
-
|
|
46071
|
-
transforms.push(`rotate(${attrs.rotation}deg)`);
|
|
48199
|
+
getPositioningStyle(attrs) {
|
|
48200
|
+
const { anchorData, marginOffset, wrap, originalAttributes } = attrs;
|
|
48201
|
+
if (!anchorData && !marginOffset?.horizontal && !marginOffset?.top) {
|
|
48202
|
+
return "";
|
|
46072
48203
|
}
|
|
46073
|
-
|
|
46074
|
-
|
|
48204
|
+
let style = "";
|
|
48205
|
+
const margin = { left: 0, right: 0, top: 0 };
|
|
48206
|
+
let centered = false;
|
|
48207
|
+
let floatRight = false;
|
|
48208
|
+
let baseHorizontal = marginOffset?.horizontal || 0;
|
|
48209
|
+
if (wrap?.type === "None") {
|
|
48210
|
+
style += "position: absolute;";
|
|
48211
|
+
const relativeHeight = originalAttributes?.relativeHeight;
|
|
48212
|
+
if (relativeHeight != null) {
|
|
48213
|
+
const zIndex = Math.floor(relativeHeight / Z_INDEX_SCALE_FACTOR);
|
|
48214
|
+
style += `z-index: ${zIndex};`;
|
|
48215
|
+
} else if (wrap?.attrs?.behindDoc) {
|
|
48216
|
+
style += "z-index: -1;";
|
|
48217
|
+
} else {
|
|
48218
|
+
style += "z-index: 1;";
|
|
48219
|
+
}
|
|
46075
48220
|
}
|
|
46076
|
-
if (
|
|
46077
|
-
|
|
48221
|
+
if (anchorData) {
|
|
48222
|
+
switch (anchorData.hRelativeFrom) {
|
|
48223
|
+
case "page":
|
|
48224
|
+
const pageStyles2 = this.editor?.converter?.pageStyles || this.editor?.options?.parentEditor?.converter?.pageStyles;
|
|
48225
|
+
margin.left -= inchesToPixels(pageStyles2?.pageMargins?.left) || 0;
|
|
48226
|
+
break;
|
|
48227
|
+
case "margin":
|
|
48228
|
+
if (anchorData.alignH === "center") {
|
|
48229
|
+
style += "position: absolute; left: 50%; transform: translateX(-50%);";
|
|
48230
|
+
}
|
|
48231
|
+
if (anchorData.alignH === "left" || anchorData.alignH === "right") {
|
|
48232
|
+
style += `position: absolute; ${anchorData.alignH}: 0;`;
|
|
48233
|
+
}
|
|
48234
|
+
break;
|
|
48235
|
+
case "column":
|
|
48236
|
+
if (anchorData.alignH === "center") {
|
|
48237
|
+
centered = true;
|
|
48238
|
+
} else if (anchorData.alignH === "right") {
|
|
48239
|
+
floatRight = true;
|
|
48240
|
+
if (!style.includes("float: right;")) {
|
|
48241
|
+
style += "float: right;";
|
|
48242
|
+
}
|
|
48243
|
+
} else if (anchorData.alignH === "left") {
|
|
48244
|
+
if (!style.includes("float: left;")) {
|
|
48245
|
+
style += "float: left;";
|
|
48246
|
+
}
|
|
48247
|
+
} else if (!anchorData.alignH && marginOffset?.horizontal != null) {
|
|
48248
|
+
const isAbsolutelyPositioned2 = style.includes("position: absolute;");
|
|
48249
|
+
if (isAbsolutelyPositioned2) {
|
|
48250
|
+
style += `left: ${baseHorizontal}px;`;
|
|
48251
|
+
baseHorizontal = 0;
|
|
48252
|
+
}
|
|
48253
|
+
}
|
|
48254
|
+
break;
|
|
48255
|
+
}
|
|
48256
|
+
}
|
|
48257
|
+
const isAbsolutelyPositioned = style.includes("position: absolute;");
|
|
48258
|
+
if (anchorData || marginOffset?.horizontal != null || marginOffset?.top != null) {
|
|
48259
|
+
const horizontal = baseHorizontal;
|
|
48260
|
+
const top2 = marginOffset?.top ?? 0;
|
|
48261
|
+
if (isAbsolutelyPositioned) {
|
|
48262
|
+
if (horizontal && !style.includes("left:")) {
|
|
48263
|
+
style += `left: ${horizontal}px;`;
|
|
48264
|
+
}
|
|
48265
|
+
if (top2 != null) {
|
|
48266
|
+
style += `top: ${top2}px;`;
|
|
48267
|
+
}
|
|
48268
|
+
} else {
|
|
48269
|
+
if (horizontal) {
|
|
48270
|
+
if (floatRight) {
|
|
48271
|
+
margin.right += horizontal;
|
|
48272
|
+
} else {
|
|
48273
|
+
margin.left += horizontal;
|
|
48274
|
+
}
|
|
48275
|
+
}
|
|
48276
|
+
if (top2 > 0) {
|
|
48277
|
+
margin.top += top2;
|
|
48278
|
+
}
|
|
48279
|
+
}
|
|
48280
|
+
}
|
|
48281
|
+
if (centered) {
|
|
48282
|
+
style += "margin-left: auto; margin-right: auto;";
|
|
48283
|
+
} else if (!isAbsolutelyPositioned) {
|
|
48284
|
+
if (margin.left) style += `margin-left: ${margin.left}px;`;
|
|
48285
|
+
if (margin.right) style += `margin-right: ${margin.right}px;`;
|
|
46078
48286
|
}
|
|
46079
|
-
|
|
48287
|
+
if (!isAbsolutelyPositioned && margin.top) style += `margin-top: ${margin.top}px;`;
|
|
48288
|
+
return style;
|
|
46080
48289
|
}
|
|
46081
|
-
|
|
48290
|
+
generateTransform() {
|
|
48291
|
+
return generateTransforms(this.node.attrs);
|
|
48292
|
+
}
|
|
48293
|
+
createSVGElement(attrs) {
|
|
48294
|
+
const { kind, fillColor, strokeColor, strokeWidth, width, height } = attrs;
|
|
48295
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
48296
|
+
svg.setAttribute("width", width.toString());
|
|
48297
|
+
svg.setAttribute("height", height.toString());
|
|
48298
|
+
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
48299
|
+
svg.style.display = "block";
|
|
48300
|
+
const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
48301
|
+
svg.appendChild(defs);
|
|
48302
|
+
let fill = "none";
|
|
48303
|
+
let fillOpacity = 1;
|
|
48304
|
+
if (fillColor) {
|
|
48305
|
+
if (typeof fillColor === "object") {
|
|
48306
|
+
if (fillColor.type === "gradient") {
|
|
48307
|
+
const gradientId = `gradient-${Math.random().toString(36).slice(2, 11)}-${Date.now()}`;
|
|
48308
|
+
const gradient = this.createGradient(fillColor, gradientId);
|
|
48309
|
+
if (gradient) {
|
|
48310
|
+
defs.appendChild(gradient);
|
|
48311
|
+
fill = `url(#${gradientId})`;
|
|
48312
|
+
}
|
|
48313
|
+
} else if (fillColor.type === "solidWithAlpha") {
|
|
48314
|
+
fill = fillColor.color;
|
|
48315
|
+
fillOpacity = fillColor.alpha;
|
|
48316
|
+
}
|
|
48317
|
+
} else {
|
|
48318
|
+
fill = fillColor;
|
|
48319
|
+
}
|
|
48320
|
+
}
|
|
48321
|
+
const stroke = strokeColor === null ? "none" : strokeColor || "none";
|
|
48322
|
+
const strokeW = strokeColor === null ? 0 : strokeColor ? strokeWidth || 1 : 0;
|
|
48323
|
+
let shapeElement;
|
|
48324
|
+
switch (kind) {
|
|
48325
|
+
case "rect":
|
|
48326
|
+
shapeElement = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
48327
|
+
shapeElement.setAttribute("x", "0");
|
|
48328
|
+
shapeElement.setAttribute("y", "0");
|
|
48329
|
+
shapeElement.setAttribute("width", width.toString());
|
|
48330
|
+
shapeElement.setAttribute("height", height.toString());
|
|
48331
|
+
break;
|
|
48332
|
+
case "roundRect":
|
|
48333
|
+
shapeElement = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
48334
|
+
shapeElement.setAttribute("x", "0");
|
|
48335
|
+
shapeElement.setAttribute("y", "0");
|
|
48336
|
+
shapeElement.setAttribute("width", width.toString());
|
|
48337
|
+
shapeElement.setAttribute("height", height.toString());
|
|
48338
|
+
const radius = Math.min(width, height) * 0.05;
|
|
48339
|
+
shapeElement.setAttribute("rx", radius.toString());
|
|
48340
|
+
shapeElement.setAttribute("ry", radius.toString());
|
|
48341
|
+
break;
|
|
48342
|
+
case "ellipse":
|
|
48343
|
+
shapeElement = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
|
|
48344
|
+
shapeElement.setAttribute("cx", (width / 2).toString());
|
|
48345
|
+
shapeElement.setAttribute("cy", (height / 2).toString());
|
|
48346
|
+
shapeElement.setAttribute("rx", (width / 2).toString());
|
|
48347
|
+
shapeElement.setAttribute("ry", (height / 2).toString());
|
|
48348
|
+
break;
|
|
48349
|
+
case "circle":
|
|
48350
|
+
shapeElement = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
|
|
48351
|
+
shapeElement.setAttribute("cx", (width / 2).toString());
|
|
48352
|
+
shapeElement.setAttribute("cy", (height / 2).toString());
|
|
48353
|
+
shapeElement.setAttribute("rx", (width / 2).toString());
|
|
48354
|
+
shapeElement.setAttribute("ry", (height / 2).toString());
|
|
48355
|
+
break;
|
|
48356
|
+
default:
|
|
48357
|
+
try {
|
|
48358
|
+
const svgTemplate = this.generateSVG({ kind, fillColor, strokeColor, strokeWidth, width, height });
|
|
48359
|
+
if (svgTemplate) {
|
|
48360
|
+
const tempDiv = document.createElement("div");
|
|
48361
|
+
tempDiv.innerHTML = svgTemplate;
|
|
48362
|
+
const tempSvg = tempDiv.querySelector("svg");
|
|
48363
|
+
if (tempSvg) {
|
|
48364
|
+
tempSvg.setAttribute("width", width.toString());
|
|
48365
|
+
tempSvg.setAttribute("height", height.toString());
|
|
48366
|
+
tempSvg.setAttribute("preserveAspectRatio", "none");
|
|
48367
|
+
tempSvg.style.width = `${width}px`;
|
|
48368
|
+
tempSvg.style.height = `${height}px`;
|
|
48369
|
+
tempSvg.style.display = "block";
|
|
48370
|
+
return tempSvg;
|
|
48371
|
+
}
|
|
48372
|
+
}
|
|
48373
|
+
} catch (error) {
|
|
48374
|
+
console.warn("Failed to generate SVG for shape:", kind, error);
|
|
48375
|
+
return null;
|
|
48376
|
+
}
|
|
48377
|
+
return null;
|
|
48378
|
+
}
|
|
48379
|
+
shapeElement.setAttribute("fill", fill);
|
|
48380
|
+
if (fillOpacity < 1) {
|
|
48381
|
+
shapeElement.setAttribute("fill-opacity", fillOpacity.toString());
|
|
48382
|
+
}
|
|
48383
|
+
shapeElement.setAttribute("stroke", stroke);
|
|
48384
|
+
shapeElement.setAttribute("stroke-width", strokeW.toString());
|
|
48385
|
+
svg.appendChild(shapeElement);
|
|
48386
|
+
return svg;
|
|
48387
|
+
}
|
|
48388
|
+
createGradient(gradientData, gradientId) {
|
|
48389
|
+
return createGradient(gradientData, gradientId);
|
|
48390
|
+
}
|
|
48391
|
+
generateSVG({ kind, fillColor, strokeColor, strokeWidth, width, height }) {
|
|
46082
48392
|
try {
|
|
48393
|
+
let fill = fillColor || "none";
|
|
48394
|
+
if (fillColor && typeof fillColor === "object") {
|
|
48395
|
+
if (fillColor.type === "gradient") {
|
|
48396
|
+
fill = "#cccccc";
|
|
48397
|
+
} else if (fillColor.type === "solidWithAlpha") {
|
|
48398
|
+
fill = fillColor.color;
|
|
48399
|
+
}
|
|
48400
|
+
}
|
|
46083
48401
|
return k({
|
|
46084
48402
|
preset: kind,
|
|
46085
48403
|
styleOverrides: {
|
|
46086
|
-
fill
|
|
48404
|
+
fill,
|
|
46087
48405
|
stroke: strokeColor || "none",
|
|
46088
48406
|
strokeWidth: strokeWidth || 0
|
|
46089
|
-
}
|
|
48407
|
+
},
|
|
48408
|
+
width,
|
|
48409
|
+
height
|
|
46090
48410
|
});
|
|
46091
48411
|
} catch {
|
|
46092
48412
|
return null;
|
|
46093
48413
|
}
|
|
46094
48414
|
}
|
|
48415
|
+
applyGradientToSVG(svg, gradientData) {
|
|
48416
|
+
applyGradientToSVG(svg, gradientData);
|
|
48417
|
+
}
|
|
48418
|
+
applyAlphaToSVG(svg, alphaData) {
|
|
48419
|
+
applyAlphaToSVG(svg, alphaData);
|
|
48420
|
+
}
|
|
48421
|
+
createTextElement(textContent2, textAlign, width, height) {
|
|
48422
|
+
return createTextElement(textContent2, textAlign, width, height);
|
|
48423
|
+
}
|
|
46095
48424
|
buildView() {
|
|
46096
48425
|
const { element } = this.createElement();
|
|
46097
48426
|
this.root = element;
|
|
@@ -46100,6 +48429,37 @@ class VectorShapeView {
|
|
|
46100
48429
|
return false;
|
|
46101
48430
|
}
|
|
46102
48431
|
}
|
|
48432
|
+
_VectorShapeView_instances = new WeakSet();
|
|
48433
|
+
/**
|
|
48434
|
+
* Ensures the parent paragraph element is positioned for absolute-positioned vector shapes.
|
|
48435
|
+
*
|
|
48436
|
+
* For vector shapes with wrap type 'None' (absolutely positioned), the parent paragraph
|
|
48437
|
+
* element must have `position: relative` to establish a containing block for CSS absolute
|
|
48438
|
+
* positioning. This allows the vector shape's `top` and `left` offsets to position correctly
|
|
48439
|
+
* relative to the paragraph.
|
|
48440
|
+
*
|
|
48441
|
+
* Uses requestAnimationFrame to defer the DOM manipulation until after the element is fully
|
|
48442
|
+
* mounted in the DOM tree. This prevents race conditions where the parent element might not
|
|
48443
|
+
* yet be available during the initial render phase.
|
|
48444
|
+
*
|
|
48445
|
+
* Only applies to wrap type 'None' - inline and floated elements do not require this setup.
|
|
48446
|
+
*/
|
|
48447
|
+
ensureParentPositioned_fn = function() {
|
|
48448
|
+
const wrapType = this.node.attrs.wrap?.type;
|
|
48449
|
+
if (wrapType !== "None") return;
|
|
48450
|
+
if (typeof globalThis !== "undefined" && globalThis.requestAnimationFrame) {
|
|
48451
|
+
globalThis.requestAnimationFrame(() => {
|
|
48452
|
+
try {
|
|
48453
|
+
const parent = this.root?.parentElement;
|
|
48454
|
+
if (parent && parent.tagName === "P") {
|
|
48455
|
+
parent.style.position = "relative";
|
|
48456
|
+
}
|
|
48457
|
+
} catch (error) {
|
|
48458
|
+
console.warn("Failed to position parent element for vector shape:", error);
|
|
48459
|
+
}
|
|
48460
|
+
});
|
|
48461
|
+
}
|
|
48462
|
+
};
|
|
46103
48463
|
const VectorShape = Node$1.create({
|
|
46104
48464
|
name: "vectorShape",
|
|
46105
48465
|
group: "inline",
|
|
@@ -46175,8 +48535,42 @@ const VectorShape = Node$1.create({
|
|
|
46175
48535
|
return { "data-flip-v": attrs.flipV };
|
|
46176
48536
|
}
|
|
46177
48537
|
},
|
|
48538
|
+
wrap: {
|
|
48539
|
+
default: { type: "Inline" },
|
|
48540
|
+
rendered: false
|
|
48541
|
+
},
|
|
48542
|
+
anchorData: {
|
|
48543
|
+
default: null,
|
|
48544
|
+
rendered: false
|
|
48545
|
+
},
|
|
48546
|
+
isAnchor: {
|
|
48547
|
+
rendered: false
|
|
48548
|
+
},
|
|
48549
|
+
marginOffset: {
|
|
48550
|
+
default: {},
|
|
48551
|
+
rendered: false
|
|
48552
|
+
},
|
|
46178
48553
|
drawingContent: {
|
|
46179
48554
|
rendered: false
|
|
48555
|
+
},
|
|
48556
|
+
originalAttributes: {
|
|
48557
|
+
rendered: false
|
|
48558
|
+
},
|
|
48559
|
+
textContent: {
|
|
48560
|
+
default: null,
|
|
48561
|
+
rendered: false
|
|
48562
|
+
},
|
|
48563
|
+
textAlign: {
|
|
48564
|
+
default: "center",
|
|
48565
|
+
rendered: false
|
|
48566
|
+
},
|
|
48567
|
+
textVerticalAlign: {
|
|
48568
|
+
default: "center",
|
|
48569
|
+
rendered: false
|
|
48570
|
+
},
|
|
48571
|
+
textInsets: {
|
|
48572
|
+
default: null,
|
|
48573
|
+
rendered: false
|
|
46180
48574
|
}
|
|
46181
48575
|
};
|
|
46182
48576
|
},
|
|
@@ -46197,6 +48591,7 @@ const VectorShape = Node$1.create({
|
|
|
46197
48591
|
});
|
|
46198
48592
|
class ShapeGroupView {
|
|
46199
48593
|
constructor(props) {
|
|
48594
|
+
__privateAdd(this, _ShapeGroupView_instances);
|
|
46200
48595
|
__publicField(this, "node");
|
|
46201
48596
|
__publicField(this, "view");
|
|
46202
48597
|
__publicField(this, "getPos");
|
|
@@ -46218,6 +48613,7 @@ class ShapeGroupView {
|
|
|
46218
48613
|
}
|
|
46219
48614
|
mount() {
|
|
46220
48615
|
this.buildView();
|
|
48616
|
+
__privateMethod(this, _ShapeGroupView_instances, ensureParentPositioned_fn2).call(this);
|
|
46221
48617
|
}
|
|
46222
48618
|
get dom() {
|
|
46223
48619
|
return this.root;
|
|
@@ -46227,7 +48623,7 @@ class ShapeGroupView {
|
|
|
46227
48623
|
}
|
|
46228
48624
|
createElement() {
|
|
46229
48625
|
const attrs = this.node.attrs;
|
|
46230
|
-
const { groupTransform, shapes, size } = attrs;
|
|
48626
|
+
const { groupTransform, shapes, size, marginOffset, originalAttributes, wrap, anchorData } = attrs;
|
|
46231
48627
|
const container = document.createElement("div");
|
|
46232
48628
|
container.classList.add("sd-shape-group");
|
|
46233
48629
|
container.setAttribute("data-shape-group", "");
|
|
@@ -46237,6 +48633,55 @@ class ShapeGroupView {
|
|
|
46237
48633
|
container.style.height = `${height}px`;
|
|
46238
48634
|
container.style.position = "relative";
|
|
46239
48635
|
container.style.display = "inline-block";
|
|
48636
|
+
const wrapType = wrap?.type || "Inline";
|
|
48637
|
+
if (wrapType === "None") {
|
|
48638
|
+
container.style.position = "absolute";
|
|
48639
|
+
if (marginOffset?.horizontal != null) {
|
|
48640
|
+
container.style.left = `${marginOffset.horizontal}px`;
|
|
48641
|
+
}
|
|
48642
|
+
const isColumnRelative = anchorData?.hRelativeFrom === "column";
|
|
48643
|
+
if (isColumnRelative && !anchorData?.alignH && marginOffset?.horizontal != null) {
|
|
48644
|
+
container.style.maxWidth = "none";
|
|
48645
|
+
}
|
|
48646
|
+
if (marginOffset?.top != null) {
|
|
48647
|
+
container.style.top = `${marginOffset.top}px`;
|
|
48648
|
+
}
|
|
48649
|
+
const relativeHeight = originalAttributes?.relativeHeight;
|
|
48650
|
+
if (relativeHeight != null) {
|
|
48651
|
+
const zIndex = Math.floor(relativeHeight / 1e6);
|
|
48652
|
+
container.style.zIndex = zIndex.toString();
|
|
48653
|
+
} else {
|
|
48654
|
+
container.style.zIndex = "1";
|
|
48655
|
+
}
|
|
48656
|
+
} else if (wrapType === "Square") {
|
|
48657
|
+
container.style.float = "left";
|
|
48658
|
+
container.style.clear = "both";
|
|
48659
|
+
if (marginOffset?.horizontal != null) {
|
|
48660
|
+
container.style.marginLeft = `${marginOffset.horizontal}px`;
|
|
48661
|
+
}
|
|
48662
|
+
if (marginOffset?.top != null) {
|
|
48663
|
+
container.style.marginTop = `${marginOffset.top}px`;
|
|
48664
|
+
}
|
|
48665
|
+
if (wrap?.attrs?.distLeft) {
|
|
48666
|
+
container.style.marginLeft = `${(marginOffset?.horizontal || 0) + wrap.attrs.distLeft}px`;
|
|
48667
|
+
}
|
|
48668
|
+
if (wrap?.attrs?.distRight) {
|
|
48669
|
+
container.style.marginRight = `${wrap.attrs.distRight}px`;
|
|
48670
|
+
}
|
|
48671
|
+
if (wrap?.attrs?.distTop) {
|
|
48672
|
+
container.style.marginTop = `${(marginOffset?.top || 0) + wrap.attrs.distTop}px`;
|
|
48673
|
+
}
|
|
48674
|
+
if (wrap?.attrs?.distBottom) {
|
|
48675
|
+
container.style.marginBottom = `${wrap.attrs.distBottom}px`;
|
|
48676
|
+
}
|
|
48677
|
+
} else {
|
|
48678
|
+
if (marginOffset?.horizontal != null) {
|
|
48679
|
+
container.style.marginLeft = `${marginOffset.horizontal}px`;
|
|
48680
|
+
}
|
|
48681
|
+
if (marginOffset?.top != null) {
|
|
48682
|
+
container.style.marginTop = `${marginOffset.top}px`;
|
|
48683
|
+
}
|
|
48684
|
+
}
|
|
46240
48685
|
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
46241
48686
|
svg.setAttribute("version", "1.1");
|
|
46242
48687
|
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
@@ -46244,26 +48689,33 @@ class ShapeGroupView {
|
|
|
46244
48689
|
svg.setAttribute("height", height.toString());
|
|
46245
48690
|
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
46246
48691
|
svg.style.display = "block";
|
|
48692
|
+
const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
48693
|
+
svg.appendChild(defs);
|
|
46247
48694
|
if (shapes && Array.isArray(shapes)) {
|
|
46248
|
-
shapes.forEach((shape) => {
|
|
48695
|
+
shapes.forEach((shape, index2) => {
|
|
46249
48696
|
if (shape.shapeType === "vectorShape") {
|
|
46250
|
-
const shapeElement = this.createShapeElement(shape, groupTransform);
|
|
48697
|
+
const shapeElement = this.createShapeElement(shape, groupTransform, defs, index2);
|
|
46251
48698
|
if (shapeElement) {
|
|
46252
48699
|
svg.appendChild(shapeElement);
|
|
46253
48700
|
}
|
|
48701
|
+
} else if (shape.shapeType === "image") {
|
|
48702
|
+
const imageElement = this.createImageElement(shape, groupTransform);
|
|
48703
|
+
if (imageElement) {
|
|
48704
|
+
svg.appendChild(imageElement);
|
|
48705
|
+
}
|
|
46254
48706
|
}
|
|
46255
48707
|
});
|
|
46256
48708
|
}
|
|
46257
48709
|
container.appendChild(svg);
|
|
46258
48710
|
return { element: container };
|
|
46259
48711
|
}
|
|
46260
|
-
createShapeElement(shape) {
|
|
48712
|
+
createShapeElement(shape, groupTransform, defs, shapeIndex) {
|
|
46261
48713
|
const attrs = shape.attrs;
|
|
46262
48714
|
if (!attrs) return null;
|
|
46263
|
-
const x = attrs.x
|
|
46264
|
-
const y = attrs.y
|
|
46265
|
-
const width = attrs.width
|
|
46266
|
-
const height = attrs.height
|
|
48715
|
+
const x = attrs.x ?? 0;
|
|
48716
|
+
const y = attrs.y ?? 0;
|
|
48717
|
+
const width = attrs.width ?? 100;
|
|
48718
|
+
const height = attrs.height ?? 100;
|
|
46267
48719
|
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
46268
48720
|
const transforms = [];
|
|
46269
48721
|
transforms.push(`translate(${x}, ${y})`);
|
|
@@ -46280,16 +48732,44 @@ class ShapeGroupView {
|
|
|
46280
48732
|
g.setAttribute("transform", transforms.join(" "));
|
|
46281
48733
|
}
|
|
46282
48734
|
const shapeKind = attrs.kind || "rect";
|
|
46283
|
-
const fillColor = attrs.fillColor
|
|
46284
|
-
const strokeColor = attrs.strokeColor
|
|
46285
|
-
const strokeWidth = attrs.strokeWidth
|
|
48735
|
+
const fillColor = attrs.fillColor === null ? null : attrs.fillColor ?? "#5b9bd5";
|
|
48736
|
+
const strokeColor = attrs.strokeColor === null ? null : attrs.strokeColor ?? "#000000";
|
|
48737
|
+
const strokeWidth = attrs.strokeWidth ?? 1;
|
|
48738
|
+
let fillValue = fillColor;
|
|
48739
|
+
if (fillColor && typeof fillColor === "object" && fillColor.type === "gradient") {
|
|
48740
|
+
const gradientId = `gradient-${shapeIndex}-${Date.now()}-${Math.floor(Math.random() * 1e9)}`;
|
|
48741
|
+
const gradient = this.createGradient(fillColor, gradientId);
|
|
48742
|
+
defs.appendChild(gradient);
|
|
48743
|
+
fillValue = `url(#${gradientId})`;
|
|
48744
|
+
} else if (fillColor === null) {
|
|
48745
|
+
fillValue = "none";
|
|
48746
|
+
} else if (typeof fillColor === "string") {
|
|
48747
|
+
fillValue = fillColor;
|
|
48748
|
+
}
|
|
48749
|
+
if (shapeKind === "line") {
|
|
48750
|
+
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
48751
|
+
line.setAttribute("x1", "0");
|
|
48752
|
+
line.setAttribute("y1", "0");
|
|
48753
|
+
line.setAttribute("x2", width.toString());
|
|
48754
|
+
line.setAttribute("y2", height.toString());
|
|
48755
|
+
line.setAttribute("stroke", strokeColor === null ? "none" : strokeColor);
|
|
48756
|
+
line.setAttribute("stroke-width", (strokeColor === null ? 0 : strokeWidth).toString());
|
|
48757
|
+
g.appendChild(line);
|
|
48758
|
+
if (attrs.textContent && attrs.textContent.parts) {
|
|
48759
|
+
const textGroup = this.createTextElement(attrs.textContent, attrs.textAlign, width, height);
|
|
48760
|
+
if (textGroup) {
|
|
48761
|
+
g.appendChild(textGroup);
|
|
48762
|
+
}
|
|
48763
|
+
}
|
|
48764
|
+
return g;
|
|
48765
|
+
}
|
|
46286
48766
|
try {
|
|
46287
48767
|
const svgContent = k({
|
|
46288
48768
|
preset: shapeKind,
|
|
46289
48769
|
styleOverrides: {
|
|
46290
|
-
fill:
|
|
46291
|
-
stroke: strokeColor
|
|
46292
|
-
strokeWidth:
|
|
48770
|
+
fill: fillValue || "none",
|
|
48771
|
+
stroke: strokeColor === null ? "none" : strokeColor,
|
|
48772
|
+
strokeWidth: strokeColor === null ? 0 : strokeWidth
|
|
46293
48773
|
},
|
|
46294
48774
|
width,
|
|
46295
48775
|
height
|
|
@@ -46358,13 +48838,42 @@ class ShapeGroupView {
|
|
|
46358
48838
|
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
46359
48839
|
rect.setAttribute("width", width.toString());
|
|
46360
48840
|
rect.setAttribute("height", height.toString());
|
|
46361
|
-
rect.setAttribute("fill", fillColor);
|
|
46362
|
-
rect.setAttribute("stroke", strokeColor);
|
|
46363
|
-
rect.setAttribute("stroke-width", strokeWidth.toString());
|
|
48841
|
+
rect.setAttribute("fill", fillColor === null ? "none" : typeof fillColor === "string" ? fillColor : "#cccccc");
|
|
48842
|
+
rect.setAttribute("stroke", strokeColor === null ? "none" : strokeColor);
|
|
48843
|
+
rect.setAttribute("stroke-width", strokeColor === null ? "0" : strokeWidth.toString());
|
|
46364
48844
|
g.appendChild(rect);
|
|
46365
48845
|
}
|
|
48846
|
+
if (attrs.textContent && attrs.textContent.parts) {
|
|
48847
|
+
const textGroup = this.createTextElement(attrs.textContent, attrs.textAlign, width, height);
|
|
48848
|
+
if (textGroup) {
|
|
48849
|
+
g.appendChild(textGroup);
|
|
48850
|
+
}
|
|
48851
|
+
}
|
|
46366
48852
|
return g;
|
|
46367
48853
|
}
|
|
48854
|
+
createTextElement(textContent2, textAlign, width, height) {
|
|
48855
|
+
return createTextElement(textContent2, textAlign, width, height);
|
|
48856
|
+
}
|
|
48857
|
+
createGradient(gradientData, gradientId) {
|
|
48858
|
+
return createGradient(gradientData, gradientId);
|
|
48859
|
+
}
|
|
48860
|
+
createImageElement(shape, _groupTransform) {
|
|
48861
|
+
const attrs = shape.attrs;
|
|
48862
|
+
if (!attrs) return null;
|
|
48863
|
+
const x = attrs.x || 0;
|
|
48864
|
+
const y = attrs.y || 0;
|
|
48865
|
+
const width = attrs.width || 100;
|
|
48866
|
+
const height = attrs.height || 100;
|
|
48867
|
+
const image = document.createElementNS("http://www.w3.org/2000/svg", "image");
|
|
48868
|
+
image.setAttribute("x", x.toString());
|
|
48869
|
+
image.setAttribute("y", y.toString());
|
|
48870
|
+
image.setAttribute("width", width.toString());
|
|
48871
|
+
image.setAttribute("height", height.toString());
|
|
48872
|
+
const src = this.editor?.storage?.image?.media?.[attrs.src] ?? attrs.src;
|
|
48873
|
+
image.setAttribute("href", src);
|
|
48874
|
+
image.setAttribute("preserveAspectRatio", "none");
|
|
48875
|
+
return image;
|
|
48876
|
+
}
|
|
46368
48877
|
buildView() {
|
|
46369
48878
|
const { element } = this.createElement();
|
|
46370
48879
|
this.root = element;
|
|
@@ -46373,6 +48882,37 @@ class ShapeGroupView {
|
|
|
46373
48882
|
return false;
|
|
46374
48883
|
}
|
|
46375
48884
|
}
|
|
48885
|
+
_ShapeGroupView_instances = new WeakSet();
|
|
48886
|
+
/**
|
|
48887
|
+
* Ensures the parent paragraph element is positioned for absolute-positioned shape groups.
|
|
48888
|
+
*
|
|
48889
|
+
* For shape groups with wrap type 'None' (absolutely positioned), the parent paragraph
|
|
48890
|
+
* element must have `position: relative` to establish a containing block for CSS absolute
|
|
48891
|
+
* positioning. This allows the shape group's `top` and `left` offsets to position correctly
|
|
48892
|
+
* relative to the paragraph.
|
|
48893
|
+
*
|
|
48894
|
+
* Uses requestAnimationFrame to defer the DOM manipulation until after the element is fully
|
|
48895
|
+
* mounted in the DOM tree. This prevents race conditions where the parent element might not
|
|
48896
|
+
* yet be available during the initial render phase.
|
|
48897
|
+
*
|
|
48898
|
+
* Only applies to wrap type 'None' - inline and floated elements do not require this setup.
|
|
48899
|
+
*/
|
|
48900
|
+
ensureParentPositioned_fn2 = function() {
|
|
48901
|
+
const wrapType = this.node.attrs.wrap?.type || "Inline";
|
|
48902
|
+
if (wrapType !== "None") return;
|
|
48903
|
+
if (typeof globalThis !== "undefined" && globalThis.requestAnimationFrame) {
|
|
48904
|
+
globalThis.requestAnimationFrame(() => {
|
|
48905
|
+
try {
|
|
48906
|
+
const parent = this.root?.parentElement;
|
|
48907
|
+
if (parent && parent.tagName === "P") {
|
|
48908
|
+
parent.style.position = "relative";
|
|
48909
|
+
}
|
|
48910
|
+
} catch (error) {
|
|
48911
|
+
console.warn("Failed to position parent element for shape group:", error);
|
|
48912
|
+
}
|
|
48913
|
+
});
|
|
48914
|
+
}
|
|
48915
|
+
};
|
|
46376
48916
|
const ShapeGroup = Node$1.create({
|
|
46377
48917
|
name: "shapeGroup",
|
|
46378
48918
|
group: "inline",
|
|
@@ -46429,6 +48969,17 @@ const ShapeGroup = Node$1.create({
|
|
|
46429
48969
|
},
|
|
46430
48970
|
drawingContent: {
|
|
46431
48971
|
rendered: false
|
|
48972
|
+
},
|
|
48973
|
+
wrap: {
|
|
48974
|
+
default: { type: "Inline" },
|
|
48975
|
+
rendered: false
|
|
48976
|
+
},
|
|
48977
|
+
anchorData: {
|
|
48978
|
+
default: null,
|
|
48979
|
+
rendered: false
|
|
48980
|
+
},
|
|
48981
|
+
originalAttributes: {
|
|
48982
|
+
rendered: false
|
|
46432
48983
|
}
|
|
46433
48984
|
};
|
|
46434
48985
|
},
|