@stll/folio-core 0.6.1 → 0.8.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/blockRange.d.ts +13 -2
- package/dist/ai-edits/blockRange.js +23 -2
- package/dist/ai-edits/index.d.ts +4 -2
- package/dist/ai-edits/index.js +3 -1
- package/dist/ai-edits/scoped-reading.d.ts +9 -0
- package/dist/ai-edits/scoped-reading.js +60 -0
- package/dist/ai-edits/snapshot.js +13 -4
- package/dist/ai-edits/types.d.ts +44 -2
- package/dist/compat/eigenpal.d.ts +5 -2
- package/dist/compat/eigenpal.js +4 -1
- package/dist/controller/fontReadiness.d.ts +29 -0
- package/dist/controller/fontReadiness.js +139 -0
- package/dist/controller/layoutPipeline.js +86 -11
- package/dist/docx/blockContentParser.js +51 -8
- package/dist/docx/capabilities.d.ts +41 -0
- package/dist/docx/capabilities.js +322 -0
- package/dist/docx/compatibility.d.ts +34 -2
- package/dist/docx/compatibility.js +128 -38
- package/dist/docx/conformance.d.ts +6 -0
- package/dist/docx/conformance.js +18 -0
- package/dist/docx/ensureParaIds.d.ts +29 -0
- package/dist/docx/ensureParaIds.js +423 -0
- package/dist/docx/groupDrawingParser.d.ts +1 -1
- package/dist/docx/groupDrawingParser.js +49 -8
- package/dist/docx/numberingParser.js +1 -0
- package/dist/docx/paragraphParser.js +9 -0
- package/dist/docx/paragraphTextBoxEnrichment.js +141 -2
- package/dist/docx/parser.js +2 -0
- package/dist/docx/runParser.js +11 -2
- package/dist/docx/selectiveXmlPatch.d.ts +10 -1
- package/dist/docx/selectiveXmlPatch.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +4 -0
- package/dist/docx/serializer/runSerializer.js +7 -2
- package/dist/docx/serializer/tableSerializer.js +4 -0
- package/dist/docx/server/boundedArchive.d.ts +24 -0
- package/dist/docx/server/boundedArchive.js +106 -0
- package/dist/docx/server/extractDocxText.d.ts +23 -0
- package/dist/docx/server/extractDocxText.js +154 -0
- package/dist/docx/tableParser.js +8 -0
- package/dist/docx/textBoxParser.js +6 -1
- package/dist/docx/vmlImageParser.js +145 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/layout-bridge/convert/headerFooterLayout.js +16 -2
- package/dist/layout-bridge/convert/paragraphFrames.d.ts +7 -0
- package/dist/layout-bridge/convert/paragraphFrames.js +136 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +106 -13
- package/dist/layout-bridge/engine/hitTest.js +2 -1
- package/dist/layout-bridge/engine/selectionRects.js +2 -1
- package/dist/layout-engine/headerFooterRefs.d.ts +7 -0
- package/dist/layout-engine/headerFooterRefs.js +40 -0
- package/dist/layout-engine/index.d.ts +3 -2
- package/dist/layout-engine/index.js +125 -72
- package/dist/layout-engine/keep-together.d.ts +7 -5
- package/dist/layout-engine/keep-together.js +20 -4
- package/dist/layout-engine/measure/cache.js +2 -0
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +3 -1
- package/dist/layout-engine/measure/listMarkerWidth.js +23 -4
- package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
- package/dist/layout-engine/measure/measureBlocks.js +133 -51
- package/dist/layout-engine/measure/measureParagraph.js +42 -15
- package/dist/layout-engine/measure/tableCellGrid.d.ts +15 -0
- package/dist/layout-engine/measure/tableCellGrid.js +62 -0
- package/dist/layout-engine/measure/textBoxParagraphLayout.d.ts +18 -0
- package/dist/layout-engine/measure/textBoxParagraphLayout.js +32 -0
- package/dist/layout-engine/paginator.d.ts +2 -1
- package/dist/layout-engine/paginator.js +17 -8
- package/dist/layout-engine/paragraphFrame.d.ts +22 -0
- package/dist/layout-engine/paragraphFrame.js +17 -0
- package/dist/layout-engine/paragraphSequence.d.ts +7 -0
- package/dist/layout-engine/paragraphSequence.js +25 -0
- package/dist/layout-engine/paragraphSpacing.d.ts +17 -0
- package/dist/layout-engine/paragraphSpacing.js +30 -0
- package/dist/layout-engine/renderedBreakReconciliation.d.ts +58 -0
- package/dist/layout-engine/renderedBreakReconciliation.js +63 -0
- package/dist/layout-engine/types.d.ts +31 -10
- package/dist/layout-engine/types.js +15 -2
- package/dist/layout-painter/renderPage.js +2 -2
- package/dist/layout-painter/renderParagraph.js +94 -10
- package/dist/layout-painter/renderTable.js +42 -12
- package/dist/layout-painter/renderTextBox.js +17 -7
- package/dist/managers/DocumentLoaderManager.js +1 -1
- package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
- package/dist/paged-layout/sectionBlockWidths.js +9 -0
- package/dist/paged-layout/sectionGeometry.js +1 -1
- package/dist/prosemirror/attrs/index.js +11 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +2 -0
- package/dist/prosemirror/conversion/toProseDoc.js +29 -23
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -0
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +68 -16
- package/dist/prosemirror/extensions/nodes/TableExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -1
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +7 -0
- package/dist/prosemirror/schema/nodes.d.ts +6 -3
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/utils/tabCalculator.js +1 -1
- package/dist/server.d.ts +6 -2
- package/dist/server.js +5 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/utils/createDocument.js +26 -18
- package/dist/utils/formatToStyle.js +3 -3
- package/dist/utils/hexId.d.ts +8 -1
- package/dist/utils/hexId.js +11 -3
- package/dist/utils/units.d.ts +6 -6
- package/dist/utils/units.js +8 -8
- package/package.json +1 -1
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { NUMBER_FORMAT_VALUES } from "../../types/documentEnumValues.js";
|
|
2
|
-
import { halfPointsToPixels, halfPointsToPoints, pointsToPixels } from "../../utils/units.js";
|
|
2
|
+
import { AUTO_PARAGRAPH_SPACING_PX, halfPointsToPixels, halfPointsToPoints, pointsToPixels } from "../../utils/units.js";
|
|
3
3
|
import { padDecimal } from "../../docx/numberingParser.js";
|
|
4
4
|
import { DEFAULT_TEXTBOX_MARGINS } from "../../layout-engine/types.js";
|
|
5
5
|
import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
|
|
6
6
|
import { resolveShadingFill } from "../../utils/formatToStyle.js";
|
|
7
7
|
import { convertBulletToUnicode } from "../../docx/bulletMarkers.js";
|
|
8
8
|
import { setTextBoxGroupId } from "../../layout-engine/textBoxGroup.js";
|
|
9
|
+
import { setParagraphFrame } from "../../layout-engine/paragraphFrame.js";
|
|
9
10
|
import { getColumns } from "../sectionColumns.js";
|
|
10
11
|
import { directionIsRtl } from "../../prosemirror/paragraphDirection.js";
|
|
11
12
|
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
|
|
12
13
|
import { autospacingMatchesBase } from "../../prosemirror/autospacingBase.js";
|
|
13
14
|
import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
|
|
14
15
|
import { assertValidProseMirrorDocument } from "../../prosemirror/validation.js";
|
|
16
|
+
import { groupParagraphFrames } from "./paragraphFrames.js";
|
|
15
17
|
//#region src/layout-bridge/convert/toFlowBlocks.ts
|
|
16
18
|
const DEFAULT_FONT = "Calibri";
|
|
17
19
|
const DEFAULT_TABLE_CELL_MARGIN_TWIPS = {
|
|
@@ -613,6 +615,9 @@ function readNumberFormats(value) {
|
|
|
613
615
|
function readListMarkerSuffix(value) {
|
|
614
616
|
if (value === "tab" || value === "space" || value === "nothing") return value;
|
|
615
617
|
}
|
|
618
|
+
function readListMarkerAlignment(value) {
|
|
619
|
+
if (value === "left" || value === "center" || value === "right") return value;
|
|
620
|
+
}
|
|
616
621
|
function toPreviousListAttrs(previousFormatting) {
|
|
617
622
|
const attrs = {};
|
|
618
623
|
const numPr = previousFormatting["numPr"];
|
|
@@ -639,6 +644,8 @@ function toPreviousListAttrs(previousFormatting) {
|
|
|
639
644
|
if (typeof listMarkerFontFamily === "string") attrs.listMarkerFontFamily = listMarkerFontFamily;
|
|
640
645
|
const listMarkerFontSize = previousFormatting["listMarkerFontSize"];
|
|
641
646
|
if (typeof listMarkerFontSize === "number") attrs.listMarkerFontSize = listMarkerFontSize;
|
|
647
|
+
const listMarkerAlignment = readListMarkerAlignment(previousFormatting["listMarkerAlignment"]);
|
|
648
|
+
if (listMarkerAlignment) attrs.listMarkerAlignment = listMarkerAlignment;
|
|
642
649
|
const listMarkerSuffix = readListMarkerSuffix(previousFormatting["listMarkerSuffix"]);
|
|
643
650
|
if (listMarkerSuffix) attrs.listMarkerSuffix = listMarkerSuffix;
|
|
644
651
|
return attrs;
|
|
@@ -662,6 +669,7 @@ function applyDeletedListMarkerAttrs(attrs, change, listCounters, listAbstractCo
|
|
|
662
669
|
if (previousListAttrs.listMarkerHidden !== void 0) attrs.listMarkerHidden = previousListAttrs.listMarkerHidden;
|
|
663
670
|
if (previousListAttrs.listMarkerFontFamily) attrs.listMarkerFontFamily = previousListAttrs.listMarkerFontFamily;
|
|
664
671
|
if (previousListAttrs.listMarkerFontSize) attrs.listMarkerFontSize = previousListAttrs.listMarkerFontSize;
|
|
672
|
+
if (previousListAttrs.listMarkerAlignment) attrs.listMarkerAlignment = previousListAttrs.listMarkerAlignment;
|
|
665
673
|
if (previousListAttrs.listMarkerSuffix) attrs.listMarkerSuffix = previousListAttrs.listMarkerSuffix;
|
|
666
674
|
}
|
|
667
675
|
function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounters, listSeenNumIds, defaultTabStopTwips, originalListCounters, originalListAbstractCounters, originalListSeenNumIds) {
|
|
@@ -673,6 +681,7 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
673
681
|
else if (align === "center") attrs.alignment = "center";
|
|
674
682
|
else if (align === "right") attrs.alignment = "right";
|
|
675
683
|
}
|
|
684
|
+
if (typeof pmAttrs.outlineLevel === "number") attrs.outlineLevel = pmAttrs.outlineLevel;
|
|
676
685
|
const spaceBefore = pmAttrs.spaceBefore;
|
|
677
686
|
const spaceAfter = pmAttrs.spaceAfter;
|
|
678
687
|
const lineSpacing = pmAttrs.lineSpacing;
|
|
@@ -680,10 +689,14 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
680
689
|
const autoAfter = autospacingMatchesBase(pmAttrs._autospacingBase, "after", spaceAfter);
|
|
681
690
|
if (autoBefore || autoAfter || typeof spaceBefore === "number" || typeof spaceAfter === "number" || typeof lineSpacing === "number") {
|
|
682
691
|
attrs.spacing = {};
|
|
683
|
-
if (autoBefore) attrs.spacing.before =
|
|
692
|
+
if (autoBefore) attrs.spacing.before = AUTO_PARAGRAPH_SPACING_PX;
|
|
684
693
|
else if (typeof spaceBefore === "number") attrs.spacing.before = twipsToPixels(spaceBefore);
|
|
685
|
-
if (autoAfter) attrs.spacing.after =
|
|
694
|
+
if (autoAfter) attrs.spacing.after = AUTO_PARAGRAPH_SPACING_PX;
|
|
686
695
|
else if (typeof spaceAfter === "number") attrs.spacing.after = twipsToPixels(spaceAfter);
|
|
696
|
+
if (autoBefore || autoAfter) attrs.automaticSpacing = {
|
|
697
|
+
...autoBefore ? { before: true } : {},
|
|
698
|
+
...autoAfter ? { after: true } : {}
|
|
699
|
+
};
|
|
687
700
|
const pmSpacingExplicit = pmAttrs.spacingExplicit;
|
|
688
701
|
const spacingFromDocDefaults = pmAttrs.spacingFromDocDefaults;
|
|
689
702
|
const explicit = {};
|
|
@@ -703,7 +716,7 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
703
716
|
let indentLeft = typeof pmAttrs.indentLeft === "number" ? pmAttrs.indentLeft : void 0;
|
|
704
717
|
let indentFirstLine = typeof pmAttrs.indentFirstLine === "number" ? pmAttrs.indentFirstLine : void 0;
|
|
705
718
|
let hangingIndent = pmAttrs.hangingIndent;
|
|
706
|
-
if (pmAttrs.numPr?.numId && indentLeft === void 0) {
|
|
719
|
+
if (pmAttrs.numPr?.numId && indentLeft === void 0 && indentFirstLine === void 0) {
|
|
707
720
|
indentLeft = ((pmAttrs.numPr.ilvl ?? 0) + 1) * 720;
|
|
708
721
|
if (indentFirstLine === void 0) {
|
|
709
722
|
indentFirstLine = -360;
|
|
@@ -788,6 +801,7 @@ function convertParagraphAttrs(pmAttrs, theme, listCounters, listAbstractCounter
|
|
|
788
801
|
if (pmAttrs.listMarkerHidden) attrs.listMarkerHidden = true;
|
|
789
802
|
if (pmAttrs.listMarkerFontFamily) attrs.listMarkerFontFamily = pmAttrs.listMarkerFontFamily;
|
|
790
803
|
if (pmAttrs.listMarkerFontSize) attrs.listMarkerFontSize = pmAttrs.listMarkerFontSize;
|
|
804
|
+
if (pmAttrs.listMarkerAlignment) attrs.listMarkerAlignment = pmAttrs.listMarkerAlignment;
|
|
791
805
|
if (pmAttrs.listMarkerSuffix) attrs.listMarkerSuffix = pmAttrs.listMarkerSuffix;
|
|
792
806
|
if (pmAttrs.listMarkerSecondSlotOffsetTwips !== void 0) attrs.listMarkerSecondSlotOffsetTwips = pmAttrs.listMarkerSecondSlotOffsetTwips;
|
|
793
807
|
if (!pmAttrs.numPr) {
|
|
@@ -829,7 +843,9 @@ function convertParagraph(node, startPos, options) {
|
|
|
829
843
|
const attrs = convertParagraphAttrs(pmAttrs, options.theme, options.listCounters, options.listAbstractCounters, options.listSeenNumIds, options.defaultTabStopTwips, options.originalListCounters, options.originalListAbstractCounters, options.originalListSeenNumIds);
|
|
830
844
|
const defaultTextFormatting = pmAttrs.defaultTextFormatting;
|
|
831
845
|
if (runs.length === 0) {
|
|
846
|
+
if (pmAttrs._originalFormatting && Object.entries(pmAttrs._originalFormatting).some(([key, value]) => key !== "runProperties" && value !== void 0 && value !== null)) attrs.hasDirectParagraphFormatting = true;
|
|
832
847
|
const paragraphMarkFormatting = pmAttrs._originalFormatting?.runProperties;
|
|
848
|
+
if (paragraphMarkFormatting && Object.values(paragraphMarkFormatting).some((value) => value !== void 0 && value !== null)) attrs.hasDirectParagraphMarkFormatting = true;
|
|
833
849
|
if (paragraphMarkFormatting?.fontSize !== void 0) attrs.defaultFontSize = paragraphMarkFormatting.fontSize / 2;
|
|
834
850
|
const paragraphMarkFontFamily = paragraphMarkFormatting?.fontFamily?.ascii ?? paragraphMarkFormatting?.fontFamily?.hAnsi;
|
|
835
851
|
if (paragraphMarkFontFamily) attrs.defaultFontFamily = paragraphMarkFontFamily;
|
|
@@ -839,7 +855,7 @@ function convertParagraph(node, startPos, options) {
|
|
|
839
855
|
if (attrs.listMarker !== void 0) attrs.listMarkerHidden = true;
|
|
840
856
|
}
|
|
841
857
|
const bookmarkNames = pmAttrs.bookmarks?.map((b) => b.name);
|
|
842
|
-
|
|
858
|
+
const block = {
|
|
843
859
|
kind: "paragraph",
|
|
844
860
|
id: nextBlockId(),
|
|
845
861
|
runs,
|
|
@@ -849,6 +865,62 @@ function convertParagraph(node, startPos, options) {
|
|
|
849
865
|
pmStart: startPos,
|
|
850
866
|
pmEnd: startPos + node.nodeSize
|
|
851
867
|
};
|
|
868
|
+
const frame = pmAttrs._originalFormatting?.frame;
|
|
869
|
+
if (frame !== void 0 && frame.dropCap !== "drop" && frame.dropCap !== "margin") setParagraphFrame(block, {
|
|
870
|
+
...frame.width !== void 0 ? { width: twipsToPixels(frame.width) } : {},
|
|
871
|
+
...frame.height !== void 0 ? { height: twipsToPixels(frame.height) } : {},
|
|
872
|
+
...frame.hSpace !== void 0 ? { hSpace: twipsToPixels(frame.hSpace) } : {},
|
|
873
|
+
...frame.vSpace !== void 0 ? { vSpace: twipsToPixels(frame.vSpace) } : {},
|
|
874
|
+
...frame.hAnchor !== void 0 ? { hAnchor: frame.hAnchor } : {},
|
|
875
|
+
...frame.vAnchor !== void 0 ? { vAnchor: frame.vAnchor } : {},
|
|
876
|
+
...frame.x !== void 0 ? { x: twipsToPixels(frame.x) } : {},
|
|
877
|
+
...frame.y !== void 0 ? { y: twipsToPixels(frame.y) } : {},
|
|
878
|
+
...frame.xAlign !== void 0 ? { xAlign: frame.xAlign } : {},
|
|
879
|
+
...frame.yAlign !== void 0 ? { yAlign: frame.yAlign } : {},
|
|
880
|
+
...frame.wrap !== void 0 ? { wrap: frame.wrap } : {}
|
|
881
|
+
});
|
|
882
|
+
return block;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Word keeps terminal empty body paragraphs after a final table as editable
|
|
886
|
+
* anchors, but they do not create a page of their own. Preserve every block
|
|
887
|
+
* and PM range while collapsing only the contiguous, run-free suffix; empty
|
|
888
|
+
* paragraphs elsewhere still retain their normal line height.
|
|
889
|
+
*/
|
|
890
|
+
function isPaintlessTerminalParagraph(block) {
|
|
891
|
+
if (block?.kind !== "paragraph" || block.runs.length !== 0) return false;
|
|
892
|
+
const attrs = block.attrs;
|
|
893
|
+
return !(attrs?.listMarker !== void 0 && !attrs.listMarkerHidden || attrs?.borders?.top || attrs?.borders?.bottom || attrs?.borders?.left || attrs?.borders?.right || attrs?.borders?.between || attrs?.borders?.bar || attrs?.shading || attrs?.spacingExplicit?.before || attrs?.spacingExplicit?.after || attrs?.pageBreakBefore || attrs?.renderedPageBreakBefore);
|
|
894
|
+
}
|
|
895
|
+
function suppressTerminalEmptyParagraphsAfterTable(blocks) {
|
|
896
|
+
let suffixStart = blocks.length;
|
|
897
|
+
while (suffixStart > 0 && isPaintlessTerminalParagraph(blocks[suffixStart - 1])) suffixStart -= 1;
|
|
898
|
+
if (suffixStart === blocks.length || suffixStart === 0 || blocks[suffixStart - 1]?.kind !== "table") return;
|
|
899
|
+
for (let index = suffixStart; index < blocks.length; index += 1) {
|
|
900
|
+
const block = blocks[index];
|
|
901
|
+
if (isPaintlessTerminalParagraph(block)) block.attrs = {
|
|
902
|
+
...block.attrs,
|
|
903
|
+
suppressEmptyParagraphHeight: true
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
function suppressFinalParagraphInRepeatedEmptySuffix(blocks) {
|
|
908
|
+
let suffixStart = blocks.length;
|
|
909
|
+
while (suffixStart > 0 && isPaintlessTerminalParagraph(blocks[suffixStart - 1])) suffixStart -= 1;
|
|
910
|
+
if (suffixStart === 0 || blocks.length - suffixStart < 2 || blocks[suffixStart - 1]?.kind === "table") return;
|
|
911
|
+
const finalBlock = blocks.at(-1);
|
|
912
|
+
if (isPaintlessTerminalParagraph(finalBlock)) finalBlock.attrs = {
|
|
913
|
+
...finalBlock.attrs,
|
|
914
|
+
suppressEmptyParagraphHeight: true
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
function reserveLeadingEmptyOutlineHeight(blocks) {
|
|
918
|
+
const firstBlock = blocks.at(0);
|
|
919
|
+
if (firstBlock?.kind !== "paragraph" || firstBlock.runs.length !== 0 || firstBlock.attrs?.outlineLevel !== 0) return;
|
|
920
|
+
firstBlock.attrs = {
|
|
921
|
+
...firstBlock.attrs,
|
|
922
|
+
reserveEmptyOutlineHeight: true
|
|
923
|
+
};
|
|
852
924
|
}
|
|
853
925
|
/**
|
|
854
926
|
* Convert border width from eighths of a point to pixels.
|
|
@@ -946,7 +1018,7 @@ function convertTableCell(node, startPos, options, tableCellMargins) {
|
|
|
946
1018
|
};
|
|
947
1019
|
const cell = {
|
|
948
1020
|
id: nextBlockId(),
|
|
949
|
-
blocks,
|
|
1021
|
+
blocks: groupParagraphFrames(blocks, nextBlockId),
|
|
950
1022
|
colSpan: attrs.colspan,
|
|
951
1023
|
rowSpan: attrs.rowspan,
|
|
952
1024
|
padding
|
|
@@ -974,6 +1046,8 @@ function convertTableRow(node, startPos, options, tableCellMargins) {
|
|
|
974
1046
|
id: nextBlockId(),
|
|
975
1047
|
cells
|
|
976
1048
|
};
|
|
1049
|
+
if (attrs._originalFormatting?.gridBefore) row.gridBefore = attrs._originalFormatting.gridBefore;
|
|
1050
|
+
if (attrs._originalFormatting?.gridAfter) row.gridAfter = attrs._originalFormatting.gridAfter;
|
|
977
1051
|
if (attrs.height) row.height = twipsToPixels(attrs.height);
|
|
978
1052
|
if (attrs.heightRule) row.heightRule = attrs.heightRule;
|
|
979
1053
|
if (attrs.isHeader) row.isHeader = attrs.isHeader;
|
|
@@ -1001,7 +1075,8 @@ function convertTable(node, startPos, options) {
|
|
|
1001
1075
|
}
|
|
1002
1076
|
const justification = attrs.justification;
|
|
1003
1077
|
const originalFormatting = attrs._originalFormatting;
|
|
1004
|
-
const
|
|
1078
|
+
const effectiveIndent = attrs._resolvedIndent ?? originalFormatting?.indent;
|
|
1079
|
+
const indentPx = effectiveIndent?.value !== void 0 && effectiveIndent?.type === "dxa" ? twipsToPixels(effectiveIndent.value) : void 0;
|
|
1005
1080
|
const floating = attrs.floating;
|
|
1006
1081
|
let floatingPx;
|
|
1007
1082
|
if (floating) {
|
|
@@ -1098,6 +1173,7 @@ function convertTextBoxNode(node, startPos, opts) {
|
|
|
1098
1173
|
pmEnd: startPos + node.nodeSize
|
|
1099
1174
|
};
|
|
1100
1175
|
if (attrs.height !== void 0) textBox.height = attrs.height;
|
|
1176
|
+
if (attrs.autoFit !== void 0) textBox.autoFit = attrs.autoFit;
|
|
1101
1177
|
if (attrs.fillColor !== void 0) textBox.fillColor = attrs.fillColor;
|
|
1102
1178
|
if (attrs.outlineWidth !== void 0) textBox.outlineWidth = attrs.outlineWidth;
|
|
1103
1179
|
if (attrs.outlineColor !== void 0) textBox.outlineColor = attrs.outlineColor;
|
|
@@ -1216,8 +1292,12 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1216
1292
|
switch (node.type.name) {
|
|
1217
1293
|
case "paragraph": {
|
|
1218
1294
|
const pmAttrs = expectParagraphAttrs(node);
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1295
|
+
const secProps = pmAttrs._sectionProperties;
|
|
1296
|
+
const hasSectionBreak = secProps !== void 0 || pmAttrs.sectionBreakType !== null && pmAttrs.sectionBreakType !== void 0;
|
|
1297
|
+
const hasListFormatting = pmAttrs.numPr !== null && pmAttrs.numPr !== void 0 || pmAttrs.listMarker !== null && pmAttrs.listMarker !== void 0;
|
|
1298
|
+
const firstChild = node.firstChild;
|
|
1299
|
+
const startsWithColumnBreak = firstChild?.type.name === "hardBreak" && expectHardBreakAttrs(firstChild).breakType === "column";
|
|
1300
|
+
if (node.childCount === 1 && startsWithColumnBreak) {
|
|
1221
1301
|
const columnBreak = {
|
|
1222
1302
|
kind: "columnBreak",
|
|
1223
1303
|
id: nextBlockId(),
|
|
@@ -1225,9 +1305,19 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1225
1305
|
pmEnd: pos + node.nodeSize
|
|
1226
1306
|
};
|
|
1227
1307
|
trackedPush(columnBreak);
|
|
1228
|
-
} else
|
|
1229
|
-
|
|
1230
|
-
|
|
1308
|
+
} else if (startsWithColumnBreak && firstChild) {
|
|
1309
|
+
const columnBreak = {
|
|
1310
|
+
kind: "columnBreak",
|
|
1311
|
+
id: nextBlockId(),
|
|
1312
|
+
pmStart: pos + 1,
|
|
1313
|
+
pmEnd: pos + 1 + firstChild.nodeSize
|
|
1314
|
+
};
|
|
1315
|
+
trackedPush(columnBreak);
|
|
1316
|
+
const paragraph = convertParagraph(node, pos, opts);
|
|
1317
|
+
if (paragraph.runs.at(0)?.kind === "lineBreak") paragraph.runs.shift();
|
|
1318
|
+
trackedPush(paragraph);
|
|
1319
|
+
} else if (node.content.size > 0 || hasListFormatting || !hasSectionBreak) trackedPush(convertParagraph(node, pos, opts));
|
|
1320
|
+
if (hasSectionBreak) {
|
|
1231
1321
|
const sectionBreak = {
|
|
1232
1322
|
kind: "sectionBreak",
|
|
1233
1323
|
id: nextBlockId()
|
|
@@ -1288,7 +1378,10 @@ function toFlowBlocks(doc, options = {}) {
|
|
|
1288
1378
|
doc.forEach((node, nodeOffset) => {
|
|
1289
1379
|
visit(node, offset + nodeOffset);
|
|
1290
1380
|
});
|
|
1291
|
-
|
|
1381
|
+
reserveLeadingEmptyOutlineHeight(blocks);
|
|
1382
|
+
suppressTerminalEmptyParagraphsAfterTable(blocks);
|
|
1383
|
+
suppressFinalParagraphInRepeatedEmptySuffix(blocks);
|
|
1384
|
+
return groupParagraphFrames(mergeRunInParagraphs(blocks), nextBlockId);
|
|
1292
1385
|
}
|
|
1293
1386
|
/**
|
|
1294
1387
|
* Merge consecutive paragraph blocks where the first carries
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { measuredLineRangeHeight } from "../../layout-engine/lineFlow.js";
|
|
2
|
+
import { getTableRowLeadingWidth } from "../../layout-engine/types.js";
|
|
2
3
|
import { getHeaderRowsHeight } from "../../layout-engine/index.js";
|
|
3
4
|
//#region src/layout-bridge/engine/hitTest.ts
|
|
4
5
|
/**
|
|
@@ -213,7 +214,7 @@ function hitTestTableCell(pageHit, blocks, measures, pagePoint) {
|
|
|
213
214
|
const rowMeasure = tableMeasure.rows[rowIndex];
|
|
214
215
|
const row = tableBlock.rows[rowIndex];
|
|
215
216
|
if (!rowMeasure || !row) continue;
|
|
216
|
-
let colX =
|
|
217
|
+
let colX = getTableRowLeadingWidth(row, tableMeasure.columnWidths);
|
|
217
218
|
let colIndex = -1;
|
|
218
219
|
if (rowMeasure.cells.length === 0 || row.cells.length === 0) continue;
|
|
219
220
|
for (let c = 0; c < rowMeasure.cells.length; c++) {
|
|
@@ -2,6 +2,7 @@ import { measureRun } from "../../layout-engine/measure/measureProvider.js";
|
|
|
2
2
|
import { buildRunFontStyle } from "../../layout-engine/measure/measureHelpers.js";
|
|
3
3
|
import { inlineImageBoundingBox } from "../../utils/rotationBoundingBox.js";
|
|
4
4
|
import { measuredLineContentOffset } from "../../layout-engine/lineFlow.js";
|
|
5
|
+
import { getTableRowLeadingWidth } from "../../layout-engine/types.js";
|
|
5
6
|
import { measureParagraph } from "../../layout-engine/measure/measureParagraph.js";
|
|
6
7
|
import { buildTableCellFloatingZones, getTableCellContentWidth, getTableCellFloatingImages } from "../../layout-engine/measure/tableCellFloating.js";
|
|
7
8
|
import { getHeaderRowsHeight } from "../../layout-engine/index.js";
|
|
@@ -314,7 +315,7 @@ function selectionToRects(layout, blocks, measures, from, to) {
|
|
|
314
315
|
if (!row || !rowMeasure) continue;
|
|
315
316
|
const clipTop = tableFragment.topClip ?? 0;
|
|
316
317
|
const clipBottom = tableFragment.bottomClip ?? rowMeasure.height;
|
|
317
|
-
let cellX =
|
|
318
|
+
let cellX = getTableRowLeadingWidth(row, tableMeasure.columnWidths);
|
|
318
319
|
for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
|
|
319
320
|
const cell = row.cells[cellIndex];
|
|
320
321
|
const cellMeasure = rowMeasure.cells[cellIndex];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { PageHeaderFooterRefs } from "./types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/layout-engine/headerFooterRefs.d.ts
|
|
5
|
+
declare const resolveSectionHeaderFooterRefs: (documentModel: document_d_exports.Document | null | undefined) => PageHeaderFooterRefs[] | undefined;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { resolveSectionHeaderFooterRefs };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/layout-engine/headerFooterRefs.ts
|
|
2
|
+
const resolveSectionRefs = (props, inherited, documentEvenAndOddHeaders) => {
|
|
3
|
+
const refs = {
|
|
4
|
+
...inherited,
|
|
5
|
+
evenAndOddHeaders: props.evenAndOddHeaders ?? documentEvenAndOddHeaders
|
|
6
|
+
};
|
|
7
|
+
if (props.titlePg !== void 0) refs.titlePg = props.titlePg;
|
|
8
|
+
for (const ref of props.headerReferences ?? []) if (ref.type === "default") refs.headerDefault = ref.rId;
|
|
9
|
+
else if (ref.type === "first") refs.headerFirst = ref.rId;
|
|
10
|
+
else refs.headerEven = ref.rId;
|
|
11
|
+
for (const ref of props.footerReferences ?? []) if (ref.type === "default") refs.footerDefault = ref.rId;
|
|
12
|
+
else if (ref.type === "first") refs.footerFirst = ref.rId;
|
|
13
|
+
else refs.footerEven = ref.rId;
|
|
14
|
+
return refs;
|
|
15
|
+
};
|
|
16
|
+
const inheritedRefsFrom = (refs) => ({
|
|
17
|
+
...refs.headerDefault === void 0 ? {} : { headerDefault: refs.headerDefault },
|
|
18
|
+
...refs.headerFirst === void 0 ? {} : { headerFirst: refs.headerFirst },
|
|
19
|
+
...refs.headerEven === void 0 ? {} : { headerEven: refs.headerEven },
|
|
20
|
+
...refs.footerDefault === void 0 ? {} : { footerDefault: refs.footerDefault },
|
|
21
|
+
...refs.footerFirst === void 0 ? {} : { footerFirst: refs.footerFirst },
|
|
22
|
+
...refs.footerEven === void 0 ? {} : { footerEven: refs.footerEven }
|
|
23
|
+
});
|
|
24
|
+
const resolveSectionHeaderFooterRefs = (documentModel) => {
|
|
25
|
+
const body = documentModel?.package.document;
|
|
26
|
+
if (!body) return;
|
|
27
|
+
const sections = [];
|
|
28
|
+
if (body.sections && body.sections.length > 0) sections.push(...body.sections.map(({ properties }) => properties));
|
|
29
|
+
else if (body.finalSectionProperties) sections.push(body.finalSectionProperties);
|
|
30
|
+
if (sections.length === 0) return;
|
|
31
|
+
const documentEvenAndOddHeaders = documentModel.package.settings?.evenAndOddHeaders === true;
|
|
32
|
+
let inherited = {};
|
|
33
|
+
return sections.map((props) => {
|
|
34
|
+
const refs = resolveSectionRefs(props, inherited, documentEvenAndOddHeaders);
|
|
35
|
+
inherited = inheritedRefsFrom(refs);
|
|
36
|
+
return refs;
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { resolveSectionHeaderFooterRefs };
|
|
@@ -1,6 +1,7 @@
|
|
|
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, 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, 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
|
+
import { resolveSectionHeaderFooterRefs } from "./headerFooterRefs.js";
|
|
4
5
|
import { BreakDecision, SectionState, applyPendingToActive, createInitialSectionState, getEffectiveColumns, getEffectiveMargins, getEffectivePageSize, scheduleSectionBreak } from "./section-breaks.js";
|
|
5
6
|
import { assertExhaustiveFlowBlock, findPageIndexContainingPmPos } from "./pmPageIndex.js";
|
|
6
7
|
|
|
@@ -43,4 +44,4 @@ declare function layoutDocument(blocks: FlowBlock[], measures: Measure[], option
|
|
|
43
44
|
*/
|
|
44
45
|
declare function getHeaderRowsHeight(measure: TableMeasure, headerRowCount: number): number;
|
|
45
46
|
//#endregion
|
|
46
|
-
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, hasKeepLines, hasPageBreakBefore, isFloatingImageRun, isFloatingTextBoxBlock, isTextWrappingFloatingImageRun, layoutDocument, 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, 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 };
|