@stll/folio-core 0.11.0 → 0.13.0
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/ai-edits/apply.d.ts +2 -1
- package/dist/ai-edits/apply.js +693 -63
- package/dist/ai-edits/block-identity.d.ts +4 -0
- package/dist/ai-edits/block-identity.js +9 -0
- package/dist/ai-edits/blockRange.d.ts +28 -1
- package/dist/ai-edits/blockRange.js +68 -2
- package/dist/ai-edits/clean-text.js +2 -1
- package/dist/ai-edits/headless.d.ts +4 -4
- package/dist/ai-edits/headless.js +9 -9
- package/dist/ai-edits/index.d.ts +2 -2
- package/dist/ai-edits/index.js +2 -2
- package/dist/ai-edits/read.d.ts +7 -7
- package/dist/ai-edits/read.js +110 -3
- package/dist/ai-edits/snapshot.js +21 -3
- package/dist/ai-edits/table-cell-mutations.d.ts +48 -0
- package/dist/ai-edits/table-cell-mutations.js +238 -0
- package/dist/ai-edits/table-mutation-plan.d.ts +38 -0
- package/dist/ai-edits/table-mutation-plan.js +90 -0
- package/dist/ai-edits/table-row-column-mutations.d.ts +108 -0
- package/dist/ai-edits/table-row-column-mutations.js +300 -0
- package/dist/ai-edits/table-targets.d.ts +32 -0
- package/dist/ai-edits/table-targets.js +70 -0
- package/dist/ai-edits/types.d.ts +62 -1
- package/dist/ai-edits/word-diff.js +21 -0
- package/dist/compat/eigenpal.d.ts +3 -3
- package/dist/compat/eigenpal.js +3 -3
- package/dist/content-controls/mutateContentControls.js +1 -1
- package/dist/controller/activeEditorStory.d.ts +36 -0
- package/dist/controller/activeEditorStory.js +30 -0
- package/dist/controller/contentControlWidgetController.d.ts +55 -0
- package/dist/controller/contentControlWidgetController.js +141 -0
- package/dist/controller/fontReadiness.js +2 -0
- package/dist/controller/headerFooterEditorManager.js +2 -2
- package/dist/controller/hiddenEditorApi.js +2 -2
- package/dist/controller/hiddenEditorManager.d.ts +12 -1
- package/dist/controller/hiddenEditorManager.js +44 -12
- package/dist/controller/layoutPipeline.d.ts +2 -0
- package/dist/controller/layoutPipeline.js +17 -2
- package/dist/controller/noteEditorManager.d.ts +36 -0
- package/dist/controller/noteEditorManager.js +210 -0
- package/dist/document-operations.d.ts +43 -11
- package/dist/document-operations.js +186 -18
- package/dist/docx/blockContentParser.js +21 -7
- package/dist/docx/commentParser.js +6 -1
- package/dist/docx/commentRangeIntegrity.d.ts +6 -0
- package/dist/docx/commentRangeIntegrity.js +186 -0
- package/dist/docx/conformance.js +62 -1
- package/dist/docx/documentGrid.d.ts +8 -0
- package/dist/docx/documentGrid.js +8 -0
- package/dist/docx/drawingUtils.js +1 -1
- package/dist/docx/encryption/agileDecryption.js +12 -2
- package/dist/docx/encryption/compoundFile.js +6 -1
- package/dist/docx/encryption/encryptionInfo.d.ts +9 -1
- package/dist/docx/encryption/encryptionInfo.js +18 -2
- package/dist/docx/encryption/openEncryptedDocx.js +1 -1
- package/dist/docx/ensureParaIds.js +8 -7
- package/dist/docx/fieldParser.js +1 -1
- package/dist/docx/groupDrawingParser.js +10 -5
- package/dist/docx/hyperlinkParser.js +1 -1
- package/dist/docx/imageParser.js +10 -6
- package/dist/docx/metadataPrivacy.js +17 -3
- package/dist/docx/notePropertiesParser.js +1 -1
- package/dist/docx/numberingParser.js +1 -1
- package/dist/docx/paragraphParser.js +70 -61
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +67 -13
- package/dist/docx/paragraphTraversal.js +1 -1
- package/dist/docx/parser.js +3 -3
- package/dist/docx/rezip.js +20 -9
- package/dist/docx/runParser.js +17 -6
- package/dist/docx/sdtProperties.js +1 -1
- package/dist/docx/sectionParser.js +18 -5
- package/dist/docx/selectiveSave.js +5 -1
- package/dist/docx/selectiveXmlPatch.d.ts +22 -1
- package/dist/docx/selectiveXmlPatch.js +61 -1
- package/dist/docx/serializer/blockSdtSerializer.js +3 -2
- package/dist/docx/serializer/commentSerializer.js +5 -6
- package/dist/docx/serializer/documentSerializer.js +2 -2
- package/dist/docx/serializer/headerFooterSerializer.js +2 -2
- package/dist/docx/serializer/noteSerializer.js +2 -2
- package/dist/docx/serializer/paragraphSerializer.js +23 -15
- package/dist/docx/serializer/runSerializer.js +25 -21
- package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -1
- package/dist/docx/serializer/stylesSerializer.js +1 -1
- package/dist/docx/serializer/tableSerializer.d.ts +5 -4
- package/dist/docx/serializer/tableSerializer.js +26 -20
- package/dist/docx/serializer/xmlUtils.d.ts +13 -1
- package/dist/docx/serializer/xmlUtils.js +27 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.d.ts +87 -0
- package/dist/docx/server/applyDocxXmlPatchProposal.js +204 -0
- package/dist/docx/server/boundedArchive.d.ts +14 -3
- package/dist/docx/server/boundedArchive.js +56 -11
- package/dist/docx/server/evaluateDocxXmlPatchProposal.d.ts +85 -0
- package/dist/docx/server/evaluateDocxXmlPatchProposal.js +361 -0
- package/dist/docx/server/extractDocxText.js +55 -8
- package/dist/docx/server/inspectDocxPackage.d.ts +70 -0
- package/dist/docx/server/inspectDocxPackage.js +217 -0
- package/dist/docx/server/validateDocxConformance.d.ts +41 -0
- package/dist/docx/server/validateDocxConformance.js +336 -0
- package/dist/docx/settingsParser.js +26 -3
- package/dist/docx/shapeParser.js +1 -1
- package/dist/docx/styleParser.js +4 -2
- package/dist/docx/tableParser.d.ts +8 -1
- package/dist/docx/tableParser.js +31 -10
- package/dist/docx/textBoxParser.d.ts +3 -3
- package/dist/docx/textBoxParser.js +16 -12
- package/dist/docx/unzip.js +1 -0
- package/dist/docx/vmlImageParser.js +11 -3
- package/dist/docx/xmlParser.js +11 -1
- package/dist/docx/xmlSafety.d.ts +5 -0
- package/dist/docx/xmlSafety.js +9 -0
- package/dist/fields/resolveFieldValues.js +1 -3
- package/dist/fonts/embeddedFonts.d.ts +33 -5
- package/dist/fonts/embeddedFonts.js +37 -8
- package/dist/i18n/messages/catalogs.gen.d.ts +17 -0
- package/dist/i18n/messages/catalogs.gen.js +17 -0
- package/dist/i18n/messages/messages.gen.d.ts +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +47 -40
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +3 -0
- package/dist/layout-bridge/convert/templatePreviewFlow.js +3 -3
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +151 -20
- package/dist/layout-bridge/dom/noteStoryDom.d.ts +6 -0
- package/dist/layout-bridge/dom/noteStoryDom.js +17 -0
- package/dist/layout-bridge/engine/clickToPosition.js +2 -2
- package/dist/layout-engine/index.d.ts +2 -2
- package/dist/layout-engine/index.js +58 -30
- package/dist/layout-engine/justificationCompatibility.d.ts +6 -0
- package/dist/layout-engine/justificationCompatibility.js +8 -0
- package/dist/layout-engine/keep-together.js +11 -1
- package/dist/layout-engine/measure/cache.js +23 -5
- package/dist/layout-engine/measure/effectiveLineBreakPolicy.js +8 -2
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +2 -2
- package/dist/layout-engine/measure/lineBreakProvider.js +56 -37
- package/dist/layout-engine/measure/measureBlocks.js +15 -4
- package/dist/layout-engine/measure/measureContainer.js +1 -1
- package/dist/layout-engine/measure/measureHelpers.d.ts +11 -2
- package/dist/layout-engine/measure/measureHelpers.js +15 -4
- package/dist/layout-engine/measure/measureParagraph.js +85 -25
- package/dist/layout-engine/measure/measureProvider.js +4 -3
- package/dist/layout-engine/measure/tableCellFlow.js +5 -2
- package/dist/layout-engine/measure/textBoxParagraphLayout.d.ts +9 -7
- package/dist/layout-engine/measure/textBoxParagraphLayout.js +22 -6
- package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +3 -1
- package/dist/layout-engine/measure/textMeasurementPolicy.js +7 -1
- package/dist/layout-engine/paginator.js +5 -1
- package/dist/layout-engine/paragraphSpacing.d.ts +28 -4
- package/dist/layout-engine/paragraphSpacing.js +107 -13
- package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
- package/dist/layout-engine/types.d.ts +48 -15
- package/dist/layout-painter/registry/modules/textBox.js +5 -1
- package/dist/layout-painter/renderImage.d.ts +12 -1
- package/dist/layout-painter/renderImage.js +21 -4
- package/dist/layout-painter/renderPage.d.ts +5 -2
- package/dist/layout-painter/renderPage.js +59 -14
- package/dist/layout-painter/renderParagraph.js +55 -15
- package/dist/layout-painter/renderTable.d.ts +5 -1
- package/dist/layout-painter/renderTable.js +7 -3
- package/dist/layout-painter/renderTextBox.d.ts +2 -1
- package/dist/layout-painter/renderTextBox.js +25 -14
- package/dist/layout-painter/renderWatermark.d.ts +1 -1
- package/dist/layout-painter/renderWatermark.js +2 -1
- package/dist/managers/DocumentLoaderManager.js +1 -1
- package/dist/markdown/fromMarkdown.js +1 -1
- package/dist/model.js +1 -1
- package/dist/prosemirror/attrs/index.d.ts +4 -2
- package/dist/prosemirror/attrs/index.js +175 -18
- package/dist/prosemirror/commands/comments.d.ts +79 -4
- package/dist/prosemirror/commands/comments.js +622 -13
- package/dist/prosemirror/commands/contentControls.js +1 -1
- package/dist/prosemirror/commands/hyperlink.js +15 -1
- package/dist/prosemirror/commands/image.js +7 -1
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/index.js +2 -2
- package/dist/prosemirror/commands/pageBreak.js +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +2 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +3 -2
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +9 -0
- package/dist/prosemirror/commands/tableCellMergeResolution.js +181 -0
- package/dist/prosemirror/commentIdAllocator.js +13 -3
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +404 -62
- package/dist/prosemirror/conversion/index.js +1 -1
- package/dist/prosemirror/conversion/sdtAttrs.d.ts +9 -0
- package/dist/prosemirror/conversion/sdtAttrs.js +49 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +2 -1
- package/dist/prosemirror/conversion/toProseDoc.js +364 -103
- package/dist/prosemirror/extensions/ExtensionManager.js +1 -1
- package/dist/prosemirror/extensions/StarterKit.js +6 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +6 -2
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -0
- package/dist/prosemirror/extensions/features/ImagePasteExtension.js +10 -2
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +10 -1
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +93 -2
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +2 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +6 -2
- package/dist/prosemirror/extensions/features/pasteCleanup.js +15 -2
- package/dist/prosemirror/extensions/marks/CharacterSpacingExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +30 -4
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.d.ts +9 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +70 -11
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
- package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.d.ts +7 -0
- package/dist/prosemirror/extensions/nodes/RenderedPageBreakExtension.js +22 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +1 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +14 -6
- package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.d.ts +13 -0
- package/dist/prosemirror/extensions/nodes/TextBoxAnchorExtension.js +41 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +5 -2
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +4 -1
- package/dist/prosemirror/index.d.ts +1 -1
- package/dist/prosemirror/index.js +1 -1
- package/dist/prosemirror/plugins/contentControlWidgets.d.ts +36 -10
- package/dist/prosemirror/plugins/contentControlWidgets.js +128 -94
- package/dist/prosemirror/plugins/revisionIds.d.ts +23 -0
- package/dist/prosemirror/plugins/revisionIds.js +57 -0
- package/dist/prosemirror/plugins/selectionTracker.js +1 -0
- package/dist/prosemirror/plugins/suggestionMode.js +5 -4
- package/dist/prosemirror/runFormattingMarkNames.d.ts +14 -0
- package/dist/prosemirror/runFormattingMarkNames.js +40 -0
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +30 -3
- package/dist/prosemirror/schema/marks.js +15 -0
- package/dist/prosemirror/schema/nodes.d.ts +111 -6
- package/dist/prosemirror/selectionState.js +1 -0
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/tableCellMergeRevision.d.ts +9 -0
- package/dist/prosemirror/tableCellMergeRevision.js +22 -0
- package/dist/prosemirror/textBoxAnchorAttrs.d.ts +9 -0
- package/dist/prosemirror/textBoxAnchorAttrs.js +33 -0
- package/dist/prosemirror/utils/extractTrackedChanges.d.ts +1 -1
- package/dist/prosemirror/utils/extractTrackedChanges.js +62 -14
- package/dist/prosemirror/validation.js +9 -1
- package/dist/render-dom/RemoteSelectionOverlay.js +2 -2
- package/dist/server.d.ts +7 -3
- package/dist/server.js +7 -3
- package/dist/utils/clipboard.d.ts +10 -1
- package/dist/utils/clipboard.js +33 -6
- package/dist/utils/colorResolver.d.ts +8 -1
- package/dist/utils/colorResolver.js +35 -5
- package/dist/utils/fontFamilyMerge.js +9 -11
- package/dist/utils/fontLoader.js +3 -2
- package/dist/utils/fontResolver.d.ts +2 -1
- package/dist/utils/fontResolver.js +31 -7
- package/dist/utils/fontWeights.d.ts +1 -1
- package/dist/utils/fontWeights.js +1 -1
- package/dist/utils/hexId.d.ts +11 -1
- package/dist/utils/hexId.js +11 -1
- package/dist/utils/paragraphFormattingMerge.js +1 -0
- package/dist/utils/sanitizeImageSrc.d.ts +21 -0
- package/dist/utils/sanitizeImageSrc.js +30 -0
- package/dist/utils/stripXmlDeclarations.d.ts +11 -0
- package/dist/utils/stripXmlDeclarations.js +35 -0
- package/dist/version-comparison.d.ts +22 -2
- package/dist/version-comparison.js +41 -12
- package/dist/watermark/index.d.ts +11 -1
- package/dist/watermark/index.js +22 -1
- package/package.json +3 -2
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { NUMBER_FORMAT_VALUES } from "../../types/documentEnumValues.js";
|
|
2
|
-
import { AUTO_PARAGRAPH_SPACING_PX, halfPointsToPixels, halfPointsToPoints, pointsToPixels } from "../../utils/units.js";
|
|
3
|
-
import { convertBulletToUnicode } from "../../docx/bulletMarkers.js";
|
|
4
|
-
import { padDecimal } from "../../docx/numberingParser.js";
|
|
5
|
-
import { autospacingMatchesBase } from "../../prosemirror/autospacingBase.js";
|
|
6
2
|
import { directionIsRtl } from "../../prosemirror/paragraphDirection.js";
|
|
7
3
|
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
|
|
4
|
+
import { padDecimal } from "../../docx/numberingParser.js";
|
|
5
|
+
import { AUTO_PARAGRAPH_SPACING_PX, halfPointsToPixels, halfPointsToPoints, pointsToPixels } from "../../utils/units.js";
|
|
6
|
+
import { autospacingMatchesBase } from "../../prosemirror/autospacingBase.js";
|
|
8
7
|
import { assertValidProseMirrorDocument } from "../../prosemirror/validation.js";
|
|
9
8
|
import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
|
|
10
9
|
import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
|
|
10
|
+
import { resolveThemeFont } from "../../utils/fontResolver.js";
|
|
11
11
|
import { resolveShadingFill } from "../../utils/formatToStyle.js";
|
|
12
|
+
import { convertBulletToUnicode } from "../../docx/bulletMarkers.js";
|
|
12
13
|
import { DEFAULT_TEXTBOX_MARGINS } from "../../layout-engine/types.js";
|
|
14
|
+
import { resolveDocumentGridLinePitch } from "../../docx/documentGrid.js";
|
|
13
15
|
import { setTextBoxGroupId } from "../../layout-engine/textBoxGroup.js";
|
|
14
16
|
import { setParagraphFrame } from "../../layout-engine/paragraphFrame.js";
|
|
15
17
|
import { getColumns } from "../sectionColumns.js";
|
|
@@ -239,9 +241,10 @@ function extractRunFormatting(marks, theme) {
|
|
|
239
241
|
break;
|
|
240
242
|
case "fontFamily": {
|
|
241
243
|
const attrs = expectFontFamilyMarkAttrs(mark);
|
|
242
|
-
const font = attrs
|
|
244
|
+
const font = resolveWesternThemeFont(attrs, theme);
|
|
243
245
|
if (font) formatting.fontFamily = font;
|
|
244
|
-
|
|
246
|
+
const eastAsiaFont = resolveEastAsiaThemeFont(attrs, theme);
|
|
247
|
+
if (eastAsiaFont) formatting.eastAsiaFontFamily = eastAsiaFont;
|
|
245
248
|
break;
|
|
246
249
|
}
|
|
247
250
|
case "language": {
|
|
@@ -330,6 +333,10 @@ function extractRunFormatting(marks, theme) {
|
|
|
330
333
|
formatting.changeAuthor = attrs.author;
|
|
331
334
|
if (attrs.date !== void 0) formatting.changeDate = attrs.date;
|
|
332
335
|
formatting.changeRevisionId = attrs.revisionId;
|
|
336
|
+
if (attrs.provenance === "suggested") {
|
|
337
|
+
formatting.isSuggestion = true;
|
|
338
|
+
if (attrs.suggestionId) formatting.suggestionId = attrs.suggestionId;
|
|
339
|
+
}
|
|
333
340
|
break;
|
|
334
341
|
}
|
|
335
342
|
case "deletion": {
|
|
@@ -338,6 +345,10 @@ function extractRunFormatting(marks, theme) {
|
|
|
338
345
|
formatting.changeAuthor = attrs.author;
|
|
339
346
|
if (attrs.date !== void 0) formatting.changeDate = attrs.date;
|
|
340
347
|
formatting.changeRevisionId = attrs.revisionId;
|
|
348
|
+
if (attrs.provenance === "suggested") {
|
|
349
|
+
formatting.isSuggestion = true;
|
|
350
|
+
if (attrs.suggestionId) formatting.suggestionId = attrs.suggestionId;
|
|
351
|
+
}
|
|
341
352
|
break;
|
|
342
353
|
}
|
|
343
354
|
default: break;
|
|
@@ -345,6 +356,13 @@ function extractRunFormatting(marks, theme) {
|
|
|
345
356
|
if (hasNoteRef && formatting.subscript) delete formatting.superscript;
|
|
346
357
|
return formatting;
|
|
347
358
|
}
|
|
359
|
+
const resolveWesternThemeFont = (fontFamily, theme) => {
|
|
360
|
+
const themeRef = fontFamily.asciiTheme ?? fontFamily.hAnsiTheme;
|
|
361
|
+
return (themeRef ? resolveThemeFont(themeRef, theme?.fontScheme) : null) ?? fontFamily.ascii ?? fontFamily.hAnsi ?? void 0;
|
|
362
|
+
};
|
|
363
|
+
const resolveEastAsiaThemeFont = (fontFamily, theme) => {
|
|
364
|
+
return (fontFamily.eastAsiaTheme ? resolveThemeFont(fontFamily.eastAsiaTheme, theme?.fontScheme) : null) ?? fontFamily.eastAsia ?? void 0;
|
|
365
|
+
};
|
|
348
366
|
function isAutomaticTextColorValue(color) {
|
|
349
367
|
const rgb = color.rgb?.trim().toLowerCase();
|
|
350
368
|
return color.auto === true || rgb === "auto" || !rgb && !color.themeColor;
|
|
@@ -381,9 +399,10 @@ function paragraphRunDefaults(pmAttrs, theme) {
|
|
|
381
399
|
const defaultTextFormatting = pmAttrs.defaultTextFormatting;
|
|
382
400
|
if (!defaultTextFormatting) return {};
|
|
383
401
|
const result = {};
|
|
384
|
-
const fontFamily = defaultTextFormatting.fontFamily
|
|
402
|
+
const fontFamily = defaultTextFormatting.fontFamily ? resolveWesternThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
|
|
385
403
|
if (fontFamily) result.fontFamily = fontFamily;
|
|
386
|
-
|
|
404
|
+
const eastAsiaFontFamily = defaultTextFormatting.fontFamily ? resolveEastAsiaThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
|
|
405
|
+
if (eastAsiaFontFamily) result.eastAsiaFontFamily = eastAsiaFontFamily;
|
|
387
406
|
if (defaultTextFormatting.language) result.language = { ...defaultTextFormatting.language };
|
|
388
407
|
if (defaultTextFormatting.fontSize !== void 0) result.fontSize = defaultTextFormatting.fontSize / 2;
|
|
389
408
|
if (defaultTextFormatting.bold !== void 0) result.bold = defaultTextFormatting.bold;
|
|
@@ -444,6 +463,9 @@ function buildImageRun(attrs, constrained, pmStart, pmEnd, trackedChange) {
|
|
|
444
463
|
if (attrs.cropRight != null) run.cropRight = attrs.cropRight;
|
|
445
464
|
if (attrs.cropBottom != null) run.cropBottom = attrs.cropBottom;
|
|
446
465
|
if (attrs.cropLeft != null) run.cropLeft = attrs.cropLeft;
|
|
466
|
+
if (attrs.borderWidth != null) run.borderWidth = attrs.borderWidth;
|
|
467
|
+
if (attrs.borderColor) run.borderColor = attrs.borderColor;
|
|
468
|
+
if (attrs.borderStyle) run.borderStyle = attrs.borderStyle;
|
|
447
469
|
if (attrs.position !== void 0) run.position = attrs.position;
|
|
448
470
|
if (attrs.layoutInCell !== void 0) run.layoutInCell = attrs.layoutInCell;
|
|
449
471
|
if (trackedChange?.isInsertion) run.isInsertion = true;
|
|
@@ -488,7 +510,21 @@ function paragraphToRuns(node, startPos, _options) {
|
|
|
488
510
|
const paraDefaults = paragraphRunDefaults(pmAttrs, theme);
|
|
489
511
|
const paragraphStyleId = pmAttrs.styleId;
|
|
490
512
|
const inTocParagraph = typeof paragraphStyleId === "string" && TOC_STYLE_ID.test(paragraphStyleId);
|
|
513
|
+
let leadingRenderedPageBreakPending = pmAttrs.renderedPageBreakBefore === true;
|
|
491
514
|
function pushRunsForChild(child, childPos) {
|
|
515
|
+
if (child.type.name === "renderedPageBreak") {
|
|
516
|
+
if (leadingRenderedPageBreakPending) {
|
|
517
|
+
leadingRenderedPageBreakPending = false;
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
runs.push({
|
|
521
|
+
kind: "renderedPageBreak",
|
|
522
|
+
pmStart: childPos,
|
|
523
|
+
pmEnd: childPos + child.nodeSize
|
|
524
|
+
});
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
if (child.type.name !== "sdt") leadingRenderedPageBreakPending = false;
|
|
492
528
|
if (child.isText && child.text) {
|
|
493
529
|
const formatting = extractRunFormatting(child.marks, theme);
|
|
494
530
|
if (inTocParagraph) stripTocHyperlinkStyle(formatting);
|
|
@@ -700,6 +736,7 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
700
736
|
const spaceBefore = pmAttrs.spaceBefore;
|
|
701
737
|
const spaceAfter = pmAttrs.spaceAfter;
|
|
702
738
|
const lineSpacing = pmAttrs.lineSpacing;
|
|
739
|
+
if (typeof pmAttrs.snapToGrid === "boolean") attrs.snapToGrid = pmAttrs.snapToGrid;
|
|
703
740
|
const autoBefore = autospacingMatchesBase(pmAttrs._autospacingBase, "before", spaceBefore);
|
|
704
741
|
const autoAfter = autospacingMatchesBase(pmAttrs._autospacingBase, "after", spaceAfter);
|
|
705
742
|
if (autoBefore || autoAfter || typeof spaceBefore === "number" || typeof spaceAfter === "number" || typeof lineSpacing === "number") {
|
|
@@ -714,9 +751,10 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
714
751
|
};
|
|
715
752
|
const pmSpacingExplicit = pmAttrs.spacingExplicit;
|
|
716
753
|
const spacingFromDocDefaults = pmAttrs.spacingFromDocDefaults;
|
|
754
|
+
const spacingFromImplicitDefaultStyle = pmAttrs.spacingFromImplicitDefaultStyle;
|
|
717
755
|
const explicit = {};
|
|
718
|
-
if (autoBefore || pmSpacingExplicit?.before || spacingFromDocDefaults?.before) explicit.before = true;
|
|
719
|
-
if (autoAfter || pmSpacingExplicit?.after || spacingFromDocDefaults?.after) explicit.after = true;
|
|
756
|
+
if (autoBefore || pmSpacingExplicit?.before || spacingFromDocDefaults?.before || spacingFromImplicitDefaultStyle?.before) explicit.before = true;
|
|
757
|
+
if (autoAfter || pmSpacingExplicit?.after || spacingFromDocDefaults?.after || spacingFromImplicitDefaultStyle?.after) explicit.after = true;
|
|
720
758
|
if (explicit.before !== void 0 || explicit.after !== void 0) attrs.spacingExplicit = explicit;
|
|
721
759
|
if (typeof lineSpacing === "number") if (pmAttrs.lineSpacingRule === "exact" || pmAttrs.lineSpacingRule === "atLeast") {
|
|
722
760
|
attrs.spacing.line = twipsToPixels(lineSpacing);
|
|
@@ -831,8 +869,9 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
831
869
|
const dtf = pmAttrs.defaultTextFormatting;
|
|
832
870
|
if (dtf) {
|
|
833
871
|
if (dtf.fontSize !== void 0) attrs.defaultFontSize = dtf.fontSize / 2;
|
|
872
|
+
if (attrs.listMarker !== void 0 && !attrs.listMarkerHidden && dtf.fontSizeCs !== void 0 && (dtf.fontSize === void 0 || dtf.fontSizeCs > dtf.fontSize)) attrs.listParagraphMarkFontSize = dtf.fontSizeCs / 2;
|
|
834
873
|
if (dtf.fontFamily) {
|
|
835
|
-
const resolvedFamily = dtf.fontFamily
|
|
874
|
+
const resolvedFamily = resolveWesternThemeFont(dtf.fontFamily, theme);
|
|
836
875
|
if (resolvedFamily) attrs.defaultFontFamily = resolvedFamily;
|
|
837
876
|
}
|
|
838
877
|
}
|
|
@@ -856,19 +895,23 @@ function mapTabAlignment(align) {
|
|
|
856
895
|
/**
|
|
857
896
|
* Convert a paragraph node to a ParagraphBlock.
|
|
858
897
|
*/
|
|
898
|
+
function hasOnlyVisuallyEmptyTextRuns(runs) {
|
|
899
|
+
return runs.length > 0 && runs.every((run) => run.kind === "text" && run.text.replace(/\u00a0/gu, " ").trim().length === 0);
|
|
900
|
+
}
|
|
859
901
|
function convertParagraph(node, startPos, options) {
|
|
860
902
|
const pmAttrs = expectParagraphAttrs(node);
|
|
861
903
|
const runs = paragraphToRuns(node, startPos, options);
|
|
862
904
|
const attrs = convertParagraphAttrs(pmAttrs, options.theme, options.listCounters, options.listAbstractCounters, options.listSeenNumIds, options.defaultTabStopTwips, options.originalListCounters, options.originalListAbstractCounters, options.originalListSeenNumIds);
|
|
863
905
|
if (options.lineBreakRules) attrs.lineBreakRules = options.lineBreakRules;
|
|
906
|
+
if (options.justificationCompatibility) attrs.justificationCompatibility = options.justificationCompatibility;
|
|
864
907
|
if (options.automaticHyphenation) attrs.automaticHyphenation = options.automaticHyphenation;
|
|
865
908
|
const defaultTextFormatting = pmAttrs.defaultTextFormatting;
|
|
866
|
-
if (runs.length === 0) {
|
|
909
|
+
if (runs.length === 0 || hasOnlyVisuallyEmptyTextRuns(runs)) {
|
|
867
910
|
if (pmAttrs._originalFormatting && Object.entries(pmAttrs._originalFormatting).some(([key, value]) => key !== "runProperties" && value !== void 0 && value !== null)) attrs.hasDirectParagraphFormatting = true;
|
|
868
911
|
const paragraphMarkFormatting = pmAttrs._originalFormatting?.runProperties;
|
|
869
912
|
if (paragraphMarkFormatting && Object.values(paragraphMarkFormatting).some((value) => value !== void 0 && value !== null)) attrs.hasDirectParagraphMarkFormatting = true;
|
|
870
913
|
if (paragraphMarkFormatting?.fontSize !== void 0) attrs.defaultFontSize = paragraphMarkFormatting.fontSize / 2;
|
|
871
|
-
const paragraphMarkFontFamily = paragraphMarkFormatting?.fontFamily
|
|
914
|
+
const paragraphMarkFontFamily = paragraphMarkFormatting?.fontFamily ? resolveWesternThemeFont(paragraphMarkFormatting.fontFamily, options.theme) : void 0;
|
|
872
915
|
if (paragraphMarkFontFamily) attrs.defaultFontFamily = paragraphMarkFontFamily;
|
|
873
916
|
}
|
|
874
917
|
if (runs.length === 0 && defaultTextFormatting?.hidden === true) {
|
|
@@ -1037,12 +1080,13 @@ function convertTableCell(node, startPos, options, tableCellMargins) {
|
|
|
1037
1080
|
suppressEmptyParagraphHeight: true
|
|
1038
1081
|
};
|
|
1039
1082
|
const attrs = expectTableCellAttrs(node);
|
|
1083
|
+
if (attrs.hideMark && trailingBlock?.kind === "paragraph" && trailingBlock.runs.every((run) => run.kind === "text" && run.text.length === 0)) trailingBlock.attrs = {
|
|
1084
|
+
...trailingBlock.attrs,
|
|
1085
|
+
suppressEmptyParagraphHeight: true
|
|
1086
|
+
};
|
|
1040
1087
|
const margins = attrs.margins;
|
|
1041
1088
|
const resolvePaddingSide = (side, cellTwips, tableTwips) => {
|
|
1042
|
-
if (cellTwips !== void 0)
|
|
1043
|
-
const px = twipsToPixels(cellTwips);
|
|
1044
|
-
if (px > 0) return px;
|
|
1045
|
-
}
|
|
1089
|
+
if (cellTwips !== void 0) return twipsToPixels(cellTwips);
|
|
1046
1090
|
if (tableTwips !== void 0) return twipsToPixels(tableTwips);
|
|
1047
1091
|
return twipsToPixels(DEFAULT_TABLE_CELL_MARGIN_TWIPS[side]);
|
|
1048
1092
|
};
|
|
@@ -1182,6 +1226,9 @@ function convertImage(node, startPos, pageContentHeight) {
|
|
|
1182
1226
|
if (attrs.cropRight != null) imgBlock.cropRight = attrs.cropRight;
|
|
1183
1227
|
if (attrs.cropBottom != null) imgBlock.cropBottom = attrs.cropBottom;
|
|
1184
1228
|
if (attrs.cropLeft != null) imgBlock.cropLeft = attrs.cropLeft;
|
|
1229
|
+
if (attrs.borderWidth != null) imgBlock.borderWidth = attrs.borderWidth;
|
|
1230
|
+
if (attrs.borderColor) imgBlock.borderColor = attrs.borderColor;
|
|
1231
|
+
if (attrs.borderStyle) imgBlock.borderStyle = attrs.borderStyle;
|
|
1185
1232
|
return imgBlock;
|
|
1186
1233
|
}
|
|
1187
1234
|
/**
|
|
@@ -1191,10 +1238,12 @@ function convertTextBoxNode(node, startPos, opts) {
|
|
|
1191
1238
|
const attrs = expectTextBoxAttrs(node);
|
|
1192
1239
|
const contentBlocks = [];
|
|
1193
1240
|
node.forEach((child, offset) => {
|
|
1241
|
+
const childPos = startPos + 1 + offset;
|
|
1194
1242
|
if (child.type.name === "paragraph") {
|
|
1195
|
-
|
|
1196
|
-
|
|
1243
|
+
contentBlocks.push(convertParagraph(child, childPos, opts));
|
|
1244
|
+
return;
|
|
1197
1245
|
}
|
|
1246
|
+
if (child.type.name === "table") contentBlocks.push(convertTable(child, childPos, opts));
|
|
1198
1247
|
});
|
|
1199
1248
|
const textBox = {
|
|
1200
1249
|
kind: "textBox",
|
|
@@ -1271,6 +1320,23 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1271
1320
|
tagBlockWithSdtStack(block);
|
|
1272
1321
|
blocks.push(block);
|
|
1273
1322
|
};
|
|
1323
|
+
const trailingPageBreakSectionPositions = /* @__PURE__ */ new Set();
|
|
1324
|
+
const consumedPageBreakPositions = /* @__PURE__ */ new Set();
|
|
1325
|
+
const collectTrailingPageBreakSections = (parent, contentStart) => {
|
|
1326
|
+
let childStart = contentStart;
|
|
1327
|
+
for (let index = 0; index < parent.childCount; index += 1) {
|
|
1328
|
+
const child = parent.child(index);
|
|
1329
|
+
const next = index + 1 < parent.childCount ? parent.child(index + 1) : void 0;
|
|
1330
|
+
const paragraphAttrs = child.type.name === "paragraph" ? expectParagraphAttrs(child) : void 0;
|
|
1331
|
+
if (paragraphAttrs && next?.type.name === "pageBreak" && paragraphAttrs._trailingPageBreak === true && (paragraphAttrs._sectionProperties || paragraphAttrs.sectionBreakType)) {
|
|
1332
|
+
trailingPageBreakSectionPositions.add(childStart);
|
|
1333
|
+
consumedPageBreakPositions.add(childStart + child.nodeSize);
|
|
1334
|
+
}
|
|
1335
|
+
if (child.type.name === "blockSdt") collectTrailingPageBreakSections(child, childStart + 1);
|
|
1336
|
+
childStart += child.nodeSize;
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
collectTrailingPageBreakSections(doc, offset);
|
|
1274
1340
|
const visit = (node, pos) => {
|
|
1275
1341
|
switch (node.type.name) {
|
|
1276
1342
|
case "blockSdt": {
|
|
@@ -1356,6 +1422,41 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1356
1422
|
trackedPush(paragraph);
|
|
1357
1423
|
} else if (node.content.size > 0 || hasListFormatting || !hasSectionBreak) trackedPush(convertParagraph(node, pos, opts));
|
|
1358
1424
|
if (hasSectionBreak) {
|
|
1425
|
+
if (trailingPageBreakSectionPositions.has(pos)) {
|
|
1426
|
+
const sourceParagraph = blocks.at(-1);
|
|
1427
|
+
if (sourceParagraph?.kind === "paragraph" && sourceParagraph.pmStart === pos) {
|
|
1428
|
+
const pageBreak = {
|
|
1429
|
+
kind: "pageBreak",
|
|
1430
|
+
id: nextBlockId(),
|
|
1431
|
+
pmStart: pos + node.nodeSize,
|
|
1432
|
+
pmEnd: pos + node.nodeSize + 1
|
|
1433
|
+
};
|
|
1434
|
+
trackedPush(pageBreak);
|
|
1435
|
+
const sourceAttrs = sourceParagraph.attrs;
|
|
1436
|
+
const carrierSpacing = sourceAttrs?.spacing ? { ...sourceAttrs.spacing } : void 0;
|
|
1437
|
+
if (carrierSpacing) delete carrierSpacing.before;
|
|
1438
|
+
const carrierAttrs = {
|
|
1439
|
+
...carrierSpacing ? { spacing: carrierSpacing } : {},
|
|
1440
|
+
...sourceAttrs?.automaticSpacing?.after === true ? { automaticSpacing: { after: true } } : {},
|
|
1441
|
+
...sourceAttrs?.spacingExplicit?.after === true ? { spacingExplicit: { after: true } } : {},
|
|
1442
|
+
...sourceAttrs?.hasDirectParagraphFormatting === true ? { hasDirectParagraphFormatting: true } : {},
|
|
1443
|
+
...sourceAttrs?.hasDirectParagraphMarkFormatting === true ? { hasDirectParagraphMarkFormatting: true } : {},
|
|
1444
|
+
...sourceAttrs?.snapToGrid !== void 0 ? { snapToGrid: sourceAttrs.snapToGrid } : {},
|
|
1445
|
+
...sourceAttrs?.documentGridLinePitch !== void 0 ? { documentGridLinePitch: sourceAttrs.documentGridLinePitch } : {},
|
|
1446
|
+
...sourceAttrs?.defaultFontSize !== void 0 ? { defaultFontSize: sourceAttrs.defaultFontSize } : {},
|
|
1447
|
+
...sourceAttrs?.defaultFontFamily !== void 0 ? { defaultFontFamily: sourceAttrs.defaultFontFamily } : {}
|
|
1448
|
+
};
|
|
1449
|
+
const carrier = {
|
|
1450
|
+
kind: "paragraph",
|
|
1451
|
+
id: nextBlockId(),
|
|
1452
|
+
runs: [],
|
|
1453
|
+
attrs: carrierAttrs,
|
|
1454
|
+
pmStart: pos + node.nodeSize,
|
|
1455
|
+
pmEnd: pos + node.nodeSize
|
|
1456
|
+
};
|
|
1457
|
+
trackedPush(carrier);
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1359
1460
|
const sectionBreak = {
|
|
1360
1461
|
kind: "sectionBreak",
|
|
1361
1462
|
id: nextBlockId()
|
|
@@ -1363,6 +1464,8 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1363
1464
|
const breakType = secProps?.sectionStart ?? pmAttrs.sectionBreakType;
|
|
1364
1465
|
if (breakType) sectionBreak.type = breakType;
|
|
1365
1466
|
if (secProps) {
|
|
1467
|
+
const documentGridLinePitchTwips = resolveDocumentGridLinePitch(secProps.docGrid);
|
|
1468
|
+
if (documentGridLinePitchTwips !== void 0) sectionBreak.documentGridLinePitchTwips = documentGridLinePitchTwips;
|
|
1366
1469
|
if (secProps.pageWidth || secProps.pageHeight) sectionBreak.pageSize = {
|
|
1367
1470
|
w: twipsToPixels(secProps.pageWidth ?? 12240),
|
|
1368
1471
|
h: twipsToPixels(secProps.pageHeight ?? 15840)
|
|
@@ -1401,6 +1504,7 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1401
1504
|
break;
|
|
1402
1505
|
case "horizontalRule":
|
|
1403
1506
|
case "pageBreak": {
|
|
1507
|
+
if (consumedPageBreakPositions.has(pos)) break;
|
|
1404
1508
|
const pb = {
|
|
1405
1509
|
kind: "pageBreak",
|
|
1406
1510
|
id: nextBlockId(),
|
|
@@ -1419,7 +1523,34 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1419
1523
|
reserveLeadingEmptyOutlineHeight(blocks);
|
|
1420
1524
|
suppressTerminalEmptyParagraphsAfterTable(blocks);
|
|
1421
1525
|
suppressFinalParagraphInRepeatedEmptySuffix(blocks);
|
|
1422
|
-
return groupParagraphFrames(mergeRunInParagraphs(blocks), nextBlockId);
|
|
1526
|
+
return groupParagraphFrames(applySectionDocumentGrid(mergeRunInParagraphs(blocks), opts.finalSectionDocumentGridLinePitchTwips), nextBlockId);
|
|
1527
|
+
}
|
|
1528
|
+
function applySectionDocumentGrid(blocks, finalLinePitchTwips) {
|
|
1529
|
+
const result = [...blocks];
|
|
1530
|
+
let sectionStart = 0;
|
|
1531
|
+
const stampSection = (end, linePitchTwips) => {
|
|
1532
|
+
if (linePitchTwips === void 0 || linePitchTwips <= 0) return;
|
|
1533
|
+
const linePitch = twipsToPixels(linePitchTwips);
|
|
1534
|
+
for (let index = sectionStart; index < end; index += 1) {
|
|
1535
|
+
const block = result[index];
|
|
1536
|
+
if (block?.kind !== "paragraph") continue;
|
|
1537
|
+
result[index] = {
|
|
1538
|
+
...block,
|
|
1539
|
+
attrs: {
|
|
1540
|
+
...block.attrs,
|
|
1541
|
+
documentGridLinePitch: linePitch
|
|
1542
|
+
}
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
};
|
|
1546
|
+
for (let index = 0; index < blocks.length; index += 1) {
|
|
1547
|
+
const block = blocks[index];
|
|
1548
|
+
if (block?.kind !== "sectionBreak") continue;
|
|
1549
|
+
stampSection(index, block.documentGridLinePitchTwips);
|
|
1550
|
+
sectionStart = index + 1;
|
|
1551
|
+
}
|
|
1552
|
+
stampSection(blocks.length, finalLinePitchTwips);
|
|
1553
|
+
return result;
|
|
1423
1554
|
}
|
|
1424
1555
|
/**
|
|
1425
1556
|
* Merge consecutive paragraph blocks where the first carries
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/layout-bridge/dom/noteStoryDom.ts
|
|
2
|
+
const isClosestNoteTarget = (value) => typeof value === "object" && value !== null && "closest" in value && typeof value.closest === "function";
|
|
3
|
+
const findNoteStoryForTarget = (target) => {
|
|
4
|
+
if (!isClosestNoteTarget(target)) return null;
|
|
5
|
+
const noteTarget = target.closest("[data-note-kind][data-note-id]");
|
|
6
|
+
const kind = noteTarget?.dataset["noteKind"];
|
|
7
|
+
const rawNoteId = noteTarget?.dataset["noteId"] ?? "";
|
|
8
|
+
if (!/^-?\d+$/u.test(rawNoteId)) return null;
|
|
9
|
+
const noteId = Number(rawNoteId);
|
|
10
|
+
if (kind !== "footnote" && kind !== "endnote" || !Number.isSafeInteger(noteId)) return null;
|
|
11
|
+
return {
|
|
12
|
+
kind,
|
|
13
|
+
noteId
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { findNoteStoryForTarget };
|
|
@@ -72,7 +72,7 @@ function computeLinePmRange(block, line) {
|
|
|
72
72
|
if (!run) continue;
|
|
73
73
|
if (runIndex < line.fromRun) {
|
|
74
74
|
if (run.kind === "text") charOffset += run.text.length;
|
|
75
|
-
else if (run.kind === "tab" || run.kind === "lineBreak") charOffset += 1;
|
|
75
|
+
else if (run.kind === "tab" || run.kind === "lineBreak" || run.kind === "renderedPageBreak") charOffset += 1;
|
|
76
76
|
else if (run.kind === "image") charOffset += 1;
|
|
77
77
|
} else if (runIndex === line.fromRun) {
|
|
78
78
|
charOffset += line.fromChar;
|
|
@@ -90,7 +90,7 @@ function computeLinePmRange(block, line) {
|
|
|
90
90
|
const start = runIndex === line.fromRun ? line.fromChar : 0;
|
|
91
91
|
const end = runIndex === line.toRun ? line.toChar : text.length;
|
|
92
92
|
lineLength += end - start;
|
|
93
|
-
} else if (run.kind === "tab" || run.kind === "lineBreak") lineLength += 1;
|
|
93
|
+
} else if (run.kind === "tab" || run.kind === "lineBreak" || run.kind === "renderedPageBreak") lineLength += 1;
|
|
94
94
|
else if (run.kind === "image") lineLength += 1;
|
|
95
95
|
}
|
|
96
96
|
pmEnd = pmStart + lineLength;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned } from "./types.js";
|
|
1
|
+
import { BlockId, BorderStyle, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned } from "./types.js";
|
|
2
2
|
import { PageState, Paginator, PaginatorOptions, createPaginator } from "./paginator.js";
|
|
3
3
|
import { KeepNextChain, calculateChainHeight, computeKeepNextChains, getMidChainIndices, hasKeepLines, hasPageBreakBefore } from "./keep-together.js";
|
|
4
4
|
import { resolveSectionHeaderFooterRefs } from "./headerFooterRefs.js";
|
|
@@ -44,4 +44,4 @@ declare function layoutDocument(blocks: FlowBlock[], measures: Measure[], option
|
|
|
44
44
|
*/
|
|
45
45
|
declare function getHeaderRowsHeight(measure: TableMeasure, headerRowCount: number): number;
|
|
46
46
|
//#endregion
|
|
47
|
-
export { BlockId, BorderStyle, type BreakDecision, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, type KeepNextChain, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, type PageState, type Paginator, type PaginatorOptions, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionLayoutConfig, type SectionState, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, applyContextualSpacing, applyPendingToActive, assertExhaustiveFlowBlock, calculateChainHeight, collectSectionConfigs, computeKeepNextChains, createInitialSectionState, createPaginator, findPageIndexContainingPmPos, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, getHeaderRowsHeight, getMidChainIndices, getTableRowLeadingWidth, hasKeepLines, hasPageBreakBefore, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, layoutDocument, resolveSectionHeaderFooterRefs, scheduleSectionBreak, tableColumnsArePinned };
|
|
47
|
+
export { BlockId, BorderStyle, type BreakDecision, CellBorderSpec, CellBorders, ColumnBreakBlock, ColumnBreakMeasure, ColumnLayout, DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, DocumentPosition, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, FieldRun, FloatingTablePosition, FlowBlock, FootnoteContent, Fragment, FragmentBase, HeaderFooterContent, HeaderFooterContentHeights, HeaderFooterLayout, HitTestResult, HyperlinkInfo, ImageBlock, ImageFragment, ImageMeasure, ImageRun, ImageRunPosition, type KeepNextChain, Layout, LayoutOptions, LineBreakRun, ListNumPr, MathRun, Measure, MeasuredLine, Page, PageBreakBlock, PageBreakMeasure, PageHeaderFooterRefs, PageMargins, type PageState, type Paginator, type PaginatorOptions, ParagraphAttrs, ParagraphBlock, ParagraphBorders, ParagraphFragment, ParagraphIndent, ParagraphMeasure, ParagraphSpacing, RenderedPageBreakRun, Run, RunFormatting, SdtGroup, SectionBreakBlock, SectionBreakMeasure, SectionLayoutConfig, type SectionState, TabAlignment, TabRun, TabStop, TableBlock, TableCell, TableCellMeasure, TableFragment, TableMeasure, TableRow, TableRowMeasure, TextBoxBlock, TextBoxFlowAttrs, TextBoxFragment, TextBoxMeasure, TextRun, applyContextualSpacing, applyPendingToActive, assertExhaustiveFlowBlock, calculateChainHeight, collectSectionConfigs, computeKeepNextChains, createInitialSectionState, createPaginator, findPageIndexContainingPmPos, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, getHeaderRowsHeight, getMidChainIndices, getTableRowLeadingWidth, hasKeepLines, hasPageBreakBefore, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, layoutDocument, resolveSectionHeaderFooterRefs, scheduleSectionBreak, tableColumnsArePinned };
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { emuToPixels } from "../utils/units.js";
|
|
2
2
|
import { measuredLineAdvance } from "./lineFlow.js";
|
|
3
3
|
import { DEFAULT_TEXTBOX_MARGINS, DEFAULT_TEXTBOX_WIDTH, FOOTNOTE_ENTRY_MARGIN_BOTTOM, FOOTNOTE_FALLBACK_LINE_HEIGHT, FOOTNOTE_SEPARATOR_HEIGHT, floatingTextBoxReservesBand, floatingTextBoxWrapsText, getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, tableColumnsArePinned } from "./types.js";
|
|
4
|
-
import { getParagraphSpacingAfter, getParagraphSpacingBefore } from "./paragraphSpacing.js";
|
|
4
|
+
import { collapseParagraphSpacing, getParagraphSpacingAfter, getParagraphSpacingBefore, paragraphsShareStyle, resolveEffectiveParagraphSpacingTree } from "./paragraphSpacing.js";
|
|
5
5
|
import { calculateChainHeight, computeKeepNextChains, getMidChainIndices, hasKeepLines, hasPageBreakBefore } from "./keep-together.js";
|
|
6
|
-
import { continuesNumberedSequence } from "./paragraphSequence.js";
|
|
7
6
|
import { createPaginator } from "./paginator.js";
|
|
8
7
|
import { getParagraphFragmentPmRange } from "./paragraphFragmentRange.js";
|
|
9
8
|
import { INITIAL_RENDERED_BREAK_STATE, reconcileAfterBlock, reconcileBreakBeforeBlock, recordReflowBoundary } from "./renderedBreakReconciliation.js";
|
|
@@ -19,6 +18,7 @@ import { panic } from "better-result";
|
|
|
19
18
|
*
|
|
20
19
|
* Converts blocks + measures into positioned fragments on pages.
|
|
21
20
|
*/
|
|
21
|
+
const RENDERED_BREAK_REFLOW_TOLERANCE_LINES = 3;
|
|
22
22
|
const DEFAULT_COLUMNS = {
|
|
23
23
|
count: 1,
|
|
24
24
|
gap: 0
|
|
@@ -58,7 +58,10 @@ function balancedParagraphSectionHeight({ blocks, measures, startIndex, endIndex
|
|
|
58
58
|
const measure = measures[index];
|
|
59
59
|
if (block?.kind !== "paragraph" || measure?.kind !== "paragraph") return;
|
|
60
60
|
if (block.attrs?.keepNext === true || block.attrs?.keepLines === true || block.runs.some((run) => run.kind === "text" && run.footnoteRefId !== void 0)) return;
|
|
61
|
-
const leadingSpacing =
|
|
61
|
+
const leadingSpacing = collapseParagraphSpacing({
|
|
62
|
+
before: getParagraphSpacingBefore(block),
|
|
63
|
+
after: trailingSpacing
|
|
64
|
+
});
|
|
62
65
|
if (measure.lines.length === 0) {
|
|
63
66
|
if (leadingSpacing > 0) {
|
|
64
67
|
lineUnits.push(leadingSpacing);
|
|
@@ -117,7 +120,7 @@ function applyContextualSpacing(blocks) {
|
|
|
117
120
|
if (curr.kind !== "paragraph" || next.kind !== "paragraph") continue;
|
|
118
121
|
const currAttrs = curr.attrs;
|
|
119
122
|
const nextAttrs = next.attrs;
|
|
120
|
-
if (
|
|
123
|
+
if (!paragraphsShareStyle(curr, next)) continue;
|
|
121
124
|
if (currAttrs?.contextualSpacing && currAttrs.spacing) currAttrs.spacing = {
|
|
122
125
|
...currAttrs.spacing,
|
|
123
126
|
after: 0
|
|
@@ -130,24 +133,6 @@ function applyContextualSpacing(blocks) {
|
|
|
130
133
|
for (const block of blocks) if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells) applyContextualSpacing(cell.blocks);
|
|
131
134
|
else if (block.kind === "textBox") applyContextualSpacing(block.content);
|
|
132
135
|
}
|
|
133
|
-
/** Suppress automatic inter-item spacing within one numbered sequence. */
|
|
134
|
-
const applyAutomaticListSpacing = (blocks) => {
|
|
135
|
-
for (let index = 1; index < blocks.length; index++) {
|
|
136
|
-
const previous = blocks[index - 1];
|
|
137
|
-
const current = blocks[index];
|
|
138
|
-
if (previous?.kind !== "paragraph" || current?.kind !== "paragraph" || !continuesNumberedSequence(previous, current)) continue;
|
|
139
|
-
if (previous.attrs?.automaticSpacing?.after && previous.attrs.spacing) previous.attrs.spacing = {
|
|
140
|
-
...previous.attrs.spacing,
|
|
141
|
-
after: 0
|
|
142
|
-
};
|
|
143
|
-
if (current.attrs?.automaticSpacing?.before && current.attrs.spacing) current.attrs.spacing = {
|
|
144
|
-
...current.attrs.spacing,
|
|
145
|
-
before: 0
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
for (const block of blocks) if (block.kind === "table") for (const row of block.rows) for (const cell of row.cells) applyAutomaticListSpacing(cell.blocks);
|
|
149
|
-
else if (block.kind === "textBox") applyAutomaticListSpacing(block.content);
|
|
150
|
-
};
|
|
151
136
|
/**
|
|
152
137
|
* Layout a document: convert blocks + measures into pages with positioned fragments.
|
|
153
138
|
*
|
|
@@ -196,8 +181,7 @@ function layoutDocument(blocks, measures, options) {
|
|
|
196
181
|
...options.footnoteReservedHeights !== void 0 ? { footnoteReservedHeights: options.footnoteReservedHeights } : {},
|
|
197
182
|
...options.sectionHeaderFooterRefs !== void 0 ? { sectionHeaderFooterRefs: options.sectionHeaderFooterRefs } : {}
|
|
198
183
|
});
|
|
199
|
-
|
|
200
|
-
applyAutomaticListSpacing(blocks);
|
|
184
|
+
blocks = resolveEffectiveParagraphSpacingTree(blocks);
|
|
201
185
|
const keepNextChains = computeKeepNextChains(blocks);
|
|
202
186
|
const midChainIndices = getMidChainIndices(keepNextChains);
|
|
203
187
|
const blocksById = /* @__PURE__ */ new Map();
|
|
@@ -210,7 +194,9 @@ function layoutDocument(blocks, measures, options) {
|
|
|
210
194
|
for (let i = 0; i < blocks.length; i++) {
|
|
211
195
|
const block = blocks[i];
|
|
212
196
|
const measure = measures[i];
|
|
213
|
-
const
|
|
197
|
+
const firstLine = measure.kind === "paragraph" ? measure.lines.at(0) : void 0;
|
|
198
|
+
const firstLineAdvance = firstLine ? measuredLineAdvance(firstLine) : 0;
|
|
199
|
+
const renderedBreakNeedsSnap = measure.kind === "paragraph" && (!paginator.fits(measure.totalHeight) || firstLineAdvance > 0 && paginator.getAvailableHeight() <= firstLineAdvance * RENDERED_BREAK_REFLOW_TOLERANCE_LINES);
|
|
214
200
|
const hasExplicitPageBreak = hasPageBreakBefore(block);
|
|
215
201
|
const breakDecision = reconcileBreakBeforeBlock({
|
|
216
202
|
state: renderedBreakState,
|
|
@@ -370,11 +356,20 @@ function layoutParagraph({ block, measure, paginator, contentWidth, footnoteHeig
|
|
|
370
356
|
while (currentLineIndex < lines.length) {
|
|
371
357
|
const state = paginator.getCurrentState();
|
|
372
358
|
const availableHeight = paginator.getAvailableHeight();
|
|
359
|
+
const currentLine = lines.at(currentLineIndex);
|
|
360
|
+
const markerAlreadySatisfied = state.columnIndex === 0 && state.cursorY === state.topMargin && state.page.fragments.length === 0;
|
|
361
|
+
if (currentLine?.renderedPageBreakBefore === true && !markerAlreadySatisfied && availableHeight <= measuredLineAdvance(currentLine) * RENDERED_BREAK_REFLOW_TOLERANCE_LINES) {
|
|
362
|
+
paginator.forcePageBreak();
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
373
365
|
if (currentLineIndex === 0 && state.trailingSpacing > 0 && state.cursorY !== state.topMargin) {
|
|
374
366
|
const firstLine = lines[0];
|
|
375
367
|
const firstLineRefs = getLineFootnoteRefs(block, firstLine.fromRun, firstLine.toRun, footnoteHeightById);
|
|
376
368
|
const firstLineHeight = measuredLineAdvance(firstLine) + firstLineRefs.height;
|
|
377
|
-
const collapsedLead =
|
|
369
|
+
const collapsedLead = collapseParagraphSpacing({
|
|
370
|
+
before: spaceBefore,
|
|
371
|
+
after: state.trailingSpacing
|
|
372
|
+
});
|
|
378
373
|
const columnCapacity = state.contentBottom - state.topMargin;
|
|
379
374
|
if (collapsedLead + firstLineHeight > availableHeight && spaceBefore + firstLineHeight <= columnCapacity) {
|
|
380
375
|
paginator.ensureFits(collapsedLead + firstLineHeight);
|
|
@@ -385,10 +380,18 @@ function layoutParagraph({ block, measure, paginator, contentWidth, footnoteHeig
|
|
|
385
380
|
let linesFnHeight = 0;
|
|
386
381
|
const linesFnIds = [];
|
|
387
382
|
let fittingLines = 0;
|
|
388
|
-
|
|
383
|
+
let forcePageBreakAfterFragment = false;
|
|
384
|
+
const firstFragmentSpaceBefore = currentLineIndex === 0 ? collapseParagraphSpacing({
|
|
385
|
+
before: spaceBefore,
|
|
386
|
+
after: state.trailingSpacing
|
|
387
|
+
}) : 0;
|
|
389
388
|
for (let j = currentLineIndex; j < lines.length; j++) {
|
|
390
389
|
const line = lines[j];
|
|
391
390
|
const lineAdvance = measuredLineAdvance(line);
|
|
391
|
+
if (j > currentLineIndex && line.renderedPageBreakBefore === true && availableHeight - (linesHeight + firstFragmentSpaceBefore + linesFnHeight) <= lineAdvance * RENDERED_BREAK_REFLOW_TOLERANCE_LINES) {
|
|
392
|
+
forcePageBreakAfterFragment = true;
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
392
395
|
const lineRefs = getLineFootnoteRefs(block, line.fromRun, line.toRun, footnoteHeightById);
|
|
393
396
|
const totalWithLine = linesHeight + lineAdvance;
|
|
394
397
|
if (totalWithLine + firstFragmentSpaceBefore + linesFnHeight + lineRefs.height <= availableHeight || fittingLines === 0) {
|
|
@@ -447,7 +450,8 @@ function layoutParagraph({ block, measure, paginator, contentWidth, footnoteHeig
|
|
|
447
450
|
fragment.y = paginator.addFragment(fragment, linesHeight, effectiveSpaceBefore, effectiveSpaceAfter).y;
|
|
448
451
|
if (linesFnHeight > 0) paginator.addFootnoteHeight(linesFnHeight, linesFnIds);
|
|
449
452
|
currentLineIndex += fittingLines;
|
|
450
|
-
if (currentLineIndex < lines.length) if (
|
|
453
|
+
if (currentLineIndex < lines.length) if (forcePageBreakAfterFragment) paginator.forcePageBreak();
|
|
454
|
+
else if (forceBreakAfterFragment) paginator.forceColumnBreak();
|
|
451
455
|
else paginator.ensureFits(measuredLineAdvance(lines[currentLineIndex]));
|
|
452
456
|
}
|
|
453
457
|
}
|
|
@@ -469,6 +473,20 @@ function getHeaderRowsHeight(measure, headerRowCount) {
|
|
|
469
473
|
for (let i = 0; i < headerRowCount && i < measure.rows.length; i++) height += measure.rows[i].height;
|
|
470
474
|
return height;
|
|
471
475
|
}
|
|
476
|
+
const tableRowStartsWithRenderedPageBreak = (block, rowIndex) => block.rows[rowIndex]?.cells.some((cell) => {
|
|
477
|
+
const firstBlock = cell.blocks.at(0);
|
|
478
|
+
return firstBlock?.kind === "paragraph" && firstBlock.attrs?.renderedPageBreakBefore === true;
|
|
479
|
+
}) ?? false;
|
|
480
|
+
const flowBlockHasTrackedChanges = (block) => {
|
|
481
|
+
if (block.kind === "paragraph") return block.runs.some((run) => {
|
|
482
|
+
if (run.kind === "lineBreak") return false;
|
|
483
|
+
return run.isInsertion || run.isDeletion;
|
|
484
|
+
});
|
|
485
|
+
if (block.kind === "table") return block.rows.some((row) => row.cells.some((cell) => cell.blocks.some(flowBlockHasTrackedChanges)));
|
|
486
|
+
if (block.kind === "textBox") return block.content.some(flowBlockHasTrackedChanges);
|
|
487
|
+
return false;
|
|
488
|
+
};
|
|
489
|
+
const tableRowHasTrackedChanges = (block, rowIndex) => block.rows[rowIndex]?.cells.some((cell) => cell.blocks.some(flowBlockHasTrackedChanges)) ?? false;
|
|
472
490
|
/**
|
|
473
491
|
* Layout a table block onto pages.
|
|
474
492
|
*/
|
|
@@ -511,6 +529,13 @@ function layoutTable(block, measure, paginator, footnoteHeightById) {
|
|
|
511
529
|
return oversized || row.height > currentAvailableHeight;
|
|
512
530
|
};
|
|
513
531
|
while (currentRowIndex < rows.length) {
|
|
532
|
+
const rowState = paginator.getCurrentState();
|
|
533
|
+
const rowHeaderOverhead = shouldRepeatHeaderRows(currentRowIndex, 0, rowState) ? headerRowsHeight : 0;
|
|
534
|
+
const rowAvailableHeight = paginator.getAvailableHeight() - rowHeaderOverhead - rowState.trailingSpacing;
|
|
535
|
+
if (!(rowState.cursorY === rowState.topMargin && rowState.page.fragments.length === 0) && tableRowStartsWithRenderedPageBreak(block, currentRowIndex) && !tableRowHasTrackedChanges(block, currentRowIndex) && rows[currentRowIndex].height > rowAvailableHeight) {
|
|
536
|
+
paginator.forcePageBreak();
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
514
539
|
const splittableRow = rows[currentRowIndex];
|
|
515
540
|
if (canSplitRow(currentRowIndex)) {
|
|
516
541
|
let consumed = 0;
|
|
@@ -642,7 +667,7 @@ function layoutTable(block, measure, paginator, footnoteHeightById) {
|
|
|
642
667
|
}
|
|
643
668
|
}
|
|
644
669
|
function collectTableRowFootnoteIds(row, footnoteHeightById) {
|
|
645
|
-
if (!row || !footnoteHeightById) return [];
|
|
670
|
+
if (!row || !footnoteHeightById || row.hidden) return [];
|
|
646
671
|
const ids = [];
|
|
647
672
|
const walk = (blocks) => {
|
|
648
673
|
for (const block of blocks) {
|
|
@@ -651,7 +676,10 @@ function collectTableRowFootnoteIds(row, footnoteHeightById) {
|
|
|
651
676
|
continue;
|
|
652
677
|
}
|
|
653
678
|
if (block.kind === "table") {
|
|
654
|
-
for (const nestedRow of block.rows)
|
|
679
|
+
for (const nestedRow of block.rows) {
|
|
680
|
+
if (nestedRow.hidden) continue;
|
|
681
|
+
for (const cell of nestedRow.cells) walk(cell.blocks);
|
|
682
|
+
}
|
|
655
683
|
continue;
|
|
656
684
|
}
|
|
657
685
|
if (block.kind === "textBox") walk(block.content);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ParagraphAttrs } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/layout-engine/justificationCompatibility.d.ts
|
|
4
|
+
declare function resolveJustificationCompatibility(compatibilityMode: number | undefined): NonNullable<ParagraphAttrs["justificationCompatibility"]> | undefined;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { resolveJustificationCompatibility };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/layout-engine/justificationCompatibility.ts
|
|
2
|
+
const LEGACY_JUSTIFICATION_MAX_COMPATIBILITY_MODE = 14;
|
|
3
|
+
function resolveJustificationCompatibility(compatibilityMode) {
|
|
4
|
+
if (compatibilityMode === void 0 || compatibilityMode > LEGACY_JUSTIFICATION_MAX_COMPATIBILITY_MODE) return;
|
|
5
|
+
return { type: "legacy" };
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { resolveJustificationCompatibility };
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
import { collapseParagraphSpacing } from "./paragraphSpacing.js";
|
|
1
2
|
//#region src/layout-engine/keep-together.ts
|
|
3
|
+
/**
|
|
4
|
+
* Keep Together Logic - Handle keepNext and keepLines paragraph properties
|
|
5
|
+
*
|
|
6
|
+
* DOCX paragraphs can have keepNext (keep with next paragraph) and keepLines
|
|
7
|
+
* (keep all lines together) properties that affect pagination.
|
|
8
|
+
*/
|
|
2
9
|
function isVisuallyEmptyParagraph(block) {
|
|
3
10
|
if (block.runs.length === 0) return true;
|
|
4
11
|
if (block.runs.length !== 1) return false;
|
|
@@ -87,7 +94,10 @@ function calculateChainHeight(chain, blocks, measures) {
|
|
|
87
94
|
const successorBlock = blocks[successorIndex];
|
|
88
95
|
const successorMeasure = measures[successorIndex];
|
|
89
96
|
if (successorBlock?.kind !== "paragraph" || successorMeasure?.kind !== "paragraph") return totalHeight;
|
|
90
|
-
totalHeight +=
|
|
97
|
+
totalHeight += collapseParagraphSpacing({
|
|
98
|
+
before: successorBlock.attrs?.spacing?.before ?? 0,
|
|
99
|
+
after: trailingSpacing
|
|
100
|
+
});
|
|
91
101
|
const firstLine = successorMeasure.lines.at(0);
|
|
92
102
|
if (!firstLine) return totalHeight;
|
|
93
103
|
const isAnchor = index === successorIndices.length - 1 && chain.anchorIndex !== -1;
|