@stll/folio-core 0.10.0 → 0.12.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.js +602 -50
- 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 +67 -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/table-cell-mutations.d.ts +48 -0
- package/dist/ai-edits/table-cell-mutations.js +237 -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 +100 -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 +34 -0
- package/dist/compat/eigenpal.js +1 -1
- 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/collaborationModules.d.ts +7 -0
- package/dist/controller/collaborationModules.js +15 -0
- package/dist/controller/contentControlWidgetController.d.ts +55 -0
- package/dist/controller/contentControlWidgetController.js +141 -0
- package/dist/controller/folioEditor.d.ts +1 -1
- package/dist/controller/fontReadiness.js +2 -0
- package/dist/controller/headerFooterEditorManager.d.ts +41 -0
- package/dist/controller/headerFooterEditorManager.js +182 -0
- package/dist/controller/hiddenEditorApi.js +2 -2
- package/dist/controller/hiddenEditorManager.d.ts +13 -2
- package/dist/controller/hiddenEditorManager.js +32 -11
- package/dist/controller/layoutPipeline.d.ts +2 -0
- package/dist/controller/layoutPipeline.js +16 -1
- package/dist/controller/noteEditorManager.d.ts +36 -0
- package/dist/controller/noteEditorManager.js +210 -0
- package/dist/document-operations.d.ts +35 -3
- package/dist/document-operations.js +161 -3
- package/dist/docx/blockContentParser.js +2 -2
- package/dist/docx/commentParser.js +6 -1
- package/dist/docx/conformance.js +8 -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/ensureParaIds.js +1 -1
- package/dist/docx/fieldParser.js +1 -1
- package/dist/docx/notePropertiesParser.js +1 -1
- package/dist/docx/numberingParser.js +1 -1
- package/dist/docx/paragraphParser.js +63 -58
- 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 +1 -1
- package/dist/docx/runParser.js +4 -2
- package/dist/docx/sdtProperties.js +1 -1
- package/dist/docx/sectionParser.js +1 -1
- package/dist/docx/selectiveSave.js +1 -1
- package/dist/docx/serializer/commentSerializer.js +1 -2
- 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 +7 -1
- package/dist/docx/serializer/runSerializer.js +4 -2
- package/dist/docx/serializer/stylesSerializer.js +1 -1
- package/dist/docx/serializer/tableSerializer.d.ts +5 -4
- package/dist/docx/serializer/tableSerializer.js +17 -13
- 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/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 +11 -1
- package/dist/docx/shapeParser.js +1 -1
- package/dist/docx/styleParser.js +4 -2
- package/dist/docx/tableParser.js +18 -7
- package/dist/docx/textBoxParser.d.ts +3 -3
- package/dist/docx/textBoxParser.js +16 -12
- package/dist/docx/xmlSafety.d.ts +5 -0
- package/dist/docx/xmlSafety.js +9 -0
- package/dist/fields/resolveFieldValues.js +1 -3
- 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.js +1 -1
- 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 +136 -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 +43 -28
- 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 +21 -5
- package/dist/layout-engine/measure/lineBreakProvider.js +53 -34
- package/dist/layout-engine/measure/measureBlocks.js +6 -3
- package/dist/layout-engine/measure/measureContainer.js +1 -1
- package/dist/layout-engine/measure/measureHelpers.d.ts +1 -1
- package/dist/layout-engine/measure/measureHelpers.js +3 -3
- package/dist/layout-engine/measure/measureParagraph.js +69 -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 +26 -13
- package/dist/layout-painter/registry/modules/textBox.js +5 -1
- package/dist/layout-painter/renderPage.d.ts +5 -2
- package/dist/layout-painter/renderPage.js +56 -12
- package/dist/layout-painter/renderParagraph.js +22 -6
- package/dist/layout-painter/renderTable.d.ts +5 -1
- package/dist/layout-painter/renderTable.js +5 -2
- package/dist/layout-painter/renderTextBox.d.ts +2 -1
- package/dist/layout-painter/renderTextBox.js +25 -14
- package/dist/managers/DocumentLoaderManager.js +1 -1
- package/dist/managers/FindReplaceManager.d.ts +8 -0
- package/dist/managers/FindReplaceManager.js +18 -0
- package/dist/managers/TableSelectionManager.d.ts +6 -0
- package/dist/managers/TableSelectionManager.js +14 -0
- package/dist/model.js +1 -1
- package/dist/prosemirror/attrs/index.d.ts +4 -2
- package/dist/prosemirror/attrs/index.js +154 -18
- package/dist/prosemirror/commands/comments.d.ts +3 -3
- package/dist/prosemirror/commands/comments.js +248 -12
- package/dist/prosemirror/commands/contentControls.js +1 -1
- package/dist/prosemirror/commands/index.js +1 -1
- 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/conversion/fromProseDoc.d.ts +2 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +286 -61
- 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 +347 -98
- package/dist/prosemirror/extensions/ExtensionManager.js +1 -1
- package/dist/prosemirror/extensions/StarterKit.js +6 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +4 -1
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +1 -0
- 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/marks/CharacterSpacingExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.d.ts +9 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +24 -1
- 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.js +9 -3
- 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/findReplaceSelection.d.ts +6 -1
- package/dist/prosemirror/findReplaceSelection.js +57 -13
- package/dist/prosemirror/plugins/contentControlWidgets.d.ts +34 -8
- package/dist/prosemirror/plugins/contentControlWidgets.js +125 -91
- package/dist/prosemirror/plugins/selectionTracker.js +1 -0
- package/dist/prosemirror/plugins/suggestionMode.js +1 -1
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +5 -1
- package/dist/prosemirror/schema/nodes.d.ts +64 -7
- 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/BodySelectionOverlay.d.ts +31 -0
- package/dist/render-dom/BodySelectionOverlay.js +76 -0
- package/dist/render-dom/HeaderFooterSelectionOverlay.d.ts +28 -0
- package/dist/render-dom/HeaderFooterSelectionOverlay.js +121 -0
- package/dist/render-dom/RemoteSelectionOverlay.d.ts +30 -0
- package/dist/render-dom/RemoteSelectionOverlay.js +67 -0
- package/dist/render-dom/RenderedDomContext.d.ts +40 -0
- package/dist/render-dom/RenderedDomContext.js +126 -0
- package/dist/render-dom/resolveSidebarItemPositions.d.ts +33 -0
- package/dist/render-dom/resolveSidebarItemPositions.js +45 -0
- package/dist/server.d.ts +6 -2
- package/dist/server.js +5 -1
- package/dist/utils/findReplace.d.ts +32 -0
- package/dist/utils/findReplace.js +118 -0
- package/dist/utils/fontFamilyMerge.js +9 -11
- package/dist/utils/fontLoader.js +3 -2
- package/dist/utils/fontResolver.js +22 -4
- package/dist/utils/fontWeights.d.ts +1 -1
- package/dist/utils/fontWeights.js +1 -1
- package/dist/utils/headerFooter.js +24 -1
- package/dist/utils/paragraphFormattingMerge.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { expectTableCellAttrs } from "../prosemirror/attrs/index.js";
|
|
2
|
+
import { standaloneTableCellFromProseMirror } from "../prosemirror/conversion/fromProseDoc.js";
|
|
3
|
+
import { markStructuralChange } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
|
|
4
|
+
import { standaloneTableCellToProseMirror } from "../prosemirror/conversion/toProseDoc.js";
|
|
5
|
+
import { tableRectanglesEqual } from "./table-mutation-plan.js";
|
|
6
|
+
import { tableRectangleCutsMergedCell } from "./table-targets.js";
|
|
7
|
+
import { Result } from "better-result";
|
|
8
|
+
import { TableMap } from "prosemirror-tables";
|
|
9
|
+
import { Fragment } from "prosemirror-model";
|
|
10
|
+
//#region src/ai-edits/table-cell-mutations.ts
|
|
11
|
+
const mergeTableRectangle = ({ tr, tablePosition, table, rectangle }) => {
|
|
12
|
+
const map = TableMap.get(table);
|
|
13
|
+
if (rectangle.left < 0 || rectangle.top < 0 || rectangle.right > map.width || rectangle.bottom > map.height || rectangle.left >= rectangle.right || rectangle.top >= rectangle.bottom || rectangle.right - rectangle.left === 1 && rectangle.bottom - rectangle.top === 1 || tableRectangleCutsMergedCell(map, rectangle)) return null;
|
|
14
|
+
const tableStart = tablePosition + 1;
|
|
15
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16
|
+
const cells = [];
|
|
17
|
+
let appendedContent = Fragment.empty;
|
|
18
|
+
for (let row = rectangle.top; row < rectangle.bottom; row++) for (let column = rectangle.left; column < rectangle.right; column++) {
|
|
19
|
+
const cellPosition = map.map[row * map.width + column];
|
|
20
|
+
if (cellPosition === void 0 || seen.has(cellPosition)) continue;
|
|
21
|
+
const cell = table.nodeAt(cellPosition);
|
|
22
|
+
if (!cell) return null;
|
|
23
|
+
seen.add(cellPosition);
|
|
24
|
+
cells.push({
|
|
25
|
+
position: cellPosition,
|
|
26
|
+
cell
|
|
27
|
+
});
|
|
28
|
+
if (cells.length > 1 && !isEmptyTableCell(cell)) appendedContent = appendedContent.append(cell.content);
|
|
29
|
+
}
|
|
30
|
+
const merged = cells.at(0);
|
|
31
|
+
if (!merged || cells.length < 2) return null;
|
|
32
|
+
const colspan = merged.cell.attrs["colspan"];
|
|
33
|
+
const rowspan = merged.cell.attrs["rowspan"];
|
|
34
|
+
const colwidth = merged.cell.attrs["colwidth"];
|
|
35
|
+
if (typeof colspan !== "number" || !Number.isInteger(colspan) || colspan < 1 || typeof rowspan !== "number" || !Number.isInteger(rowspan) || rowspan < 1 || colwidth !== null && colwidth !== void 0 && (!Array.isArray(colwidth) || colwidth.length !== colspan || !colwidth.every((width) => typeof width === "number"))) return null;
|
|
36
|
+
const mergedColspan = rectangle.right - rectangle.left;
|
|
37
|
+
const nextColwidth = Array.isArray(colwidth) ? [...colwidth] : null;
|
|
38
|
+
while (nextColwidth && nextColwidth.length < mergedColspan) nextColwidth.push(0);
|
|
39
|
+
const mapFrom = tr.mapping.maps.length;
|
|
40
|
+
for (const { position: cellPosition, cell } of cells.slice(1)) {
|
|
41
|
+
const position = tr.mapping.slice(mapFrom).map(tableStart + cellPosition);
|
|
42
|
+
tr = tr.delete(position, position + cell.nodeSize);
|
|
43
|
+
}
|
|
44
|
+
const absoluteMergedPosition = tableStart + merged.position;
|
|
45
|
+
tr = tr.setNodeMarkup(absoluteMergedPosition, void 0, {
|
|
46
|
+
...merged.cell.attrs,
|
|
47
|
+
colspan: mergedColspan,
|
|
48
|
+
rowspan: rectangle.bottom - rectangle.top,
|
|
49
|
+
colwidth: nextColwidth
|
|
50
|
+
});
|
|
51
|
+
if (appendedContent.size > 0) {
|
|
52
|
+
const contentEnd = absoluteMergedPosition + 1 + merged.cell.content.size;
|
|
53
|
+
const contentStart = isEmptyTableCell(merged.cell) ? absoluteMergedPosition + 1 : contentEnd;
|
|
54
|
+
tr = tr.replaceWith(contentStart, contentEnd, appendedContent);
|
|
55
|
+
}
|
|
56
|
+
return tr;
|
|
57
|
+
};
|
|
58
|
+
const mergeTrackedVerticalTableCells = ({ tr, tablePosition, table, rectangle, revisionId, author, date }) => {
|
|
59
|
+
const map = TableMap.get(table);
|
|
60
|
+
if (rectangle.right - rectangle.left !== 1 || rectangle.bottom - rectangle.top < 2 || rectangle.left < 0 || rectangle.top < 0 || rectangle.right > map.width || rectangle.bottom > map.height || tableRectangleCutsMergedCell(map, rectangle)) return null;
|
|
61
|
+
const cells = [];
|
|
62
|
+
for (let row = rectangle.top; row < rectangle.bottom; row++) {
|
|
63
|
+
const position = map.map[row * map.width + rectangle.left];
|
|
64
|
+
if (position === void 0) return null;
|
|
65
|
+
const cell = table.nodeAt(position);
|
|
66
|
+
if (!cell || !tableRectanglesEqual(map.findCell(position), {
|
|
67
|
+
left: rectangle.left,
|
|
68
|
+
top: row,
|
|
69
|
+
right: rectangle.right,
|
|
70
|
+
bottom: row + 1
|
|
71
|
+
})) return null;
|
|
72
|
+
const attrs = expectTableCellAttrs(cell);
|
|
73
|
+
if (attrs.colspan !== 1 || attrs.rowspan !== 1 || attrs.cellMarker !== void 0 || attrs._docxVMergeContinuationCells !== void 0 || attrs._preserveVMergeRestart === true || attrs._originalFormatting?.vMerge !== void 0) return null;
|
|
74
|
+
cells.push({
|
|
75
|
+
position,
|
|
76
|
+
cell
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const origin = cells.at(0);
|
|
80
|
+
if (!origin || cells.length !== rectangle.bottom - rectangle.top || cells.some(({ cell }) => cell.type !== origin.cell.type) || cells.slice(1).some(({ cell }) => !isEmptyTableCell(cell))) return null;
|
|
81
|
+
const continuationCells = [];
|
|
82
|
+
for (const { cell } of cells.slice(1)) {
|
|
83
|
+
const continuation = standaloneTableCellFromProseMirror(cell);
|
|
84
|
+
continuation.formatting = {
|
|
85
|
+
...continuation.formatting,
|
|
86
|
+
vMerge: "continue"
|
|
87
|
+
};
|
|
88
|
+
continuation.structuralChange = {
|
|
89
|
+
type: "tableCellMerge",
|
|
90
|
+
info: {
|
|
91
|
+
id: revisionId,
|
|
92
|
+
author,
|
|
93
|
+
date
|
|
94
|
+
},
|
|
95
|
+
verticalMerge: "continue",
|
|
96
|
+
verticalMergeOriginal: "rest"
|
|
97
|
+
};
|
|
98
|
+
continuationCells.push(continuation);
|
|
99
|
+
}
|
|
100
|
+
const nextTr = mergeTableRectangle({
|
|
101
|
+
tr,
|
|
102
|
+
tablePosition,
|
|
103
|
+
table,
|
|
104
|
+
rectangle
|
|
105
|
+
});
|
|
106
|
+
if (!nextTr) return null;
|
|
107
|
+
nextTr.setNodeAttribute(tablePosition + 1 + origin.position, "_docxVMergeContinuationCells", continuationCells);
|
|
108
|
+
markStructuralChange(nextTr);
|
|
109
|
+
return nextTr;
|
|
110
|
+
};
|
|
111
|
+
const splitTableRectangle = ({ tr, tablePosition, table, rectangle }) => {
|
|
112
|
+
const map = TableMap.get(table);
|
|
113
|
+
if (rectangle.left < 0 || rectangle.top < 0 || rectangle.right > map.width || rectangle.bottom > map.height || rectangle.left >= rectangle.right || rectangle.top >= rectangle.bottom || rectangle.right - rectangle.left === 1 && rectangle.bottom - rectangle.top === 1) return null;
|
|
114
|
+
const cellPosition = map.map[rectangle.top * map.width + rectangle.left];
|
|
115
|
+
if (cellPosition === void 0) return null;
|
|
116
|
+
if (!tableRectanglesEqual(map.findCell(cellPosition), rectangle)) return null;
|
|
117
|
+
const cell = table.nodeAt(cellPosition);
|
|
118
|
+
if (!cell) return null;
|
|
119
|
+
const colspan = cell.attrs["colspan"];
|
|
120
|
+
const rowspan = cell.attrs["rowspan"];
|
|
121
|
+
const colwidth = cell.attrs["colwidth"];
|
|
122
|
+
if (typeof colspan !== "number" || !Number.isInteger(colspan) || colspan !== rectangle.right - rectangle.left || typeof rowspan !== "number" || !Number.isInteger(rowspan) || rowspan !== rectangle.bottom - rectangle.top || colwidth !== null && colwidth !== void 0 && (!Array.isArray(colwidth) || colwidth.length !== colspan || !colwidth.every((width) => typeof width === "number"))) return null;
|
|
123
|
+
const baseAttrs = {
|
|
124
|
+
...cell.attrs,
|
|
125
|
+
colspan: 1,
|
|
126
|
+
rowspan: 1,
|
|
127
|
+
_preserveVMergeRestart: null,
|
|
128
|
+
_docxVMergeContinuationCells: null
|
|
129
|
+
};
|
|
130
|
+
const attrsByColumn = Array.from({ length: colspan }, (_, index) => ({
|
|
131
|
+
...baseAttrs,
|
|
132
|
+
colwidth: Array.isArray(colwidth) && typeof colwidth[index] === "number" && colwidth[index] > 0 ? [colwidth[index]] : null
|
|
133
|
+
}));
|
|
134
|
+
const tableStart = tablePosition + 1;
|
|
135
|
+
const insertions = [];
|
|
136
|
+
for (let row = rectangle.top; row < rectangle.bottom; row++) {
|
|
137
|
+
let position = map.positionAt(row, rectangle.left, table);
|
|
138
|
+
if (row === rectangle.top) position += cell.nodeSize;
|
|
139
|
+
for (let column = rectangle.left; column < rectangle.right; column++) {
|
|
140
|
+
if (row === rectangle.top && column === rectangle.left) continue;
|
|
141
|
+
const attrs = attrsByColumn[column - rectangle.left];
|
|
142
|
+
const nextCell = attrs ? cell.type.createAndFill(attrs) : null;
|
|
143
|
+
if (!nextCell) return null;
|
|
144
|
+
insertions.push({
|
|
145
|
+
position: tableStart + position,
|
|
146
|
+
cell: nextCell
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const mapFrom = tr.mapping.maps.length;
|
|
151
|
+
for (const insertion of insertions) tr = tr.insert(tr.mapping.slice(mapFrom).map(insertion.position, 1), insertion.cell);
|
|
152
|
+
return tr.setNodeMarkup(tableStart + cellPosition, void 0, attrsByColumn[0]);
|
|
153
|
+
};
|
|
154
|
+
const splitTrackedVerticalTableCell = ({ tr, tablePosition, table, rectangle, revisionId, author, date }) => {
|
|
155
|
+
const map = TableMap.get(table);
|
|
156
|
+
if (rectangle.right - rectangle.left !== 1 || rectangle.bottom - rectangle.top < 2 || rectangle.left < 0 || rectangle.top < 0 || rectangle.right > map.width || rectangle.bottom > map.height) return null;
|
|
157
|
+
const relativeCellPosition = map.map[rectangle.top * map.width + rectangle.left];
|
|
158
|
+
if (relativeCellPosition === void 0) return null;
|
|
159
|
+
if (!tableRectanglesEqual(map.findCell(relativeCellPosition), rectangle)) return null;
|
|
160
|
+
const cell = table.nodeAt(relativeCellPosition);
|
|
161
|
+
if (!cell) return null;
|
|
162
|
+
const attrs = expectTableCellAttrs(cell);
|
|
163
|
+
if (attrs.colspan !== 1 || attrs.rowspan !== rectangle.bottom - rectangle.top || attrs.cellMarker !== void 0) return null;
|
|
164
|
+
const continuationCells = attrs._docxVMergeContinuationCells;
|
|
165
|
+
if (continuationCells !== void 0 && continuationCells.length !== rectangle.bottom - rectangle.top - 1) return null;
|
|
166
|
+
const marker = {
|
|
167
|
+
kind: "merge",
|
|
168
|
+
info: {
|
|
169
|
+
revisionId,
|
|
170
|
+
author,
|
|
171
|
+
date
|
|
172
|
+
},
|
|
173
|
+
verticalMergeOriginal: "continue"
|
|
174
|
+
};
|
|
175
|
+
const insertedCells = [];
|
|
176
|
+
for (let index = 0; index < rectangle.bottom - rectangle.top - 1; index++) {
|
|
177
|
+
const source = continuationCells?.[index];
|
|
178
|
+
if (source?.structuralChange !== void 0) return null;
|
|
179
|
+
const insertedCell = source ? trackedSplitCellFromStoredSource({
|
|
180
|
+
origin: cell,
|
|
181
|
+
source,
|
|
182
|
+
marker
|
|
183
|
+
}) : cell.type.createAndFill({
|
|
184
|
+
...cell.attrs,
|
|
185
|
+
rowspan: 1,
|
|
186
|
+
cellMarker: marker,
|
|
187
|
+
_originalFormatting: formattingWithoutVerticalMerge(attrs._originalFormatting),
|
|
188
|
+
_preserveVMergeRestart: null,
|
|
189
|
+
_docxVMergeContinuationCells: null
|
|
190
|
+
});
|
|
191
|
+
if (!insertedCell) return null;
|
|
192
|
+
insertedCells.push(insertedCell);
|
|
193
|
+
}
|
|
194
|
+
const tableStart = tablePosition + 1;
|
|
195
|
+
const mapFrom = tr.mapping.maps.length;
|
|
196
|
+
for (const [index, insertedCell] of insertedCells.entries()) {
|
|
197
|
+
const row = rectangle.top + index + 1;
|
|
198
|
+
const position = tableStart + map.positionAt(row, rectangle.left, table);
|
|
199
|
+
tr = tr.insert(tr.mapping.slice(mapFrom).map(position, 1), insertedCell);
|
|
200
|
+
}
|
|
201
|
+
tr = tr.setNodeMarkup(tableStart + relativeCellPosition, void 0, {
|
|
202
|
+
...cell.attrs,
|
|
203
|
+
rowspan: 1,
|
|
204
|
+
_originalFormatting: formattingWithoutVerticalMerge(attrs._originalFormatting),
|
|
205
|
+
_preserveVMergeRestart: null,
|
|
206
|
+
_docxVMergeContinuationCells: null
|
|
207
|
+
});
|
|
208
|
+
markStructuralChange(tr);
|
|
209
|
+
return tr;
|
|
210
|
+
};
|
|
211
|
+
const isEmptyTableCell = (cell) => cell.childCount === 1 && cell.firstChild?.isTextblock === true && cell.firstChild.childCount === 0;
|
|
212
|
+
const trackedSplitCellFromStoredSource = ({ origin, source, marker }) => {
|
|
213
|
+
const formatting = formattingWithoutVerticalMerge(source.formatting);
|
|
214
|
+
const converted = standaloneTableCellToProseMirror({
|
|
215
|
+
type: "tableCell",
|
|
216
|
+
...formatting ? { formatting } : {},
|
|
217
|
+
...source.propertyChanges ? { propertyChanges: source.propertyChanges } : {},
|
|
218
|
+
content: source.content
|
|
219
|
+
}, origin.type.name === "tableHeader" ? "tableHeader" : "tableCell");
|
|
220
|
+
const compatible = Result.try(() => origin.type.schema.nodeFromJSON(converted.toJSON())).unwrapOr(null);
|
|
221
|
+
if (!compatible) return null;
|
|
222
|
+
return compatible.type.create({
|
|
223
|
+
...compatible.attrs,
|
|
224
|
+
rowspan: 1,
|
|
225
|
+
cellMarker: marker,
|
|
226
|
+
_preserveVMergeRestart: null,
|
|
227
|
+
_docxVMergeContinuationCells: null
|
|
228
|
+
}, compatible.content);
|
|
229
|
+
};
|
|
230
|
+
const formattingWithoutVerticalMerge = (formatting) => {
|
|
231
|
+
if (!formatting) return;
|
|
232
|
+
const next = { ...formatting };
|
|
233
|
+
delete next.vMerge;
|
|
234
|
+
return next;
|
|
235
|
+
};
|
|
236
|
+
//#endregion
|
|
237
|
+
export { mergeTableRectangle, mergeTrackedVerticalTableCells, splitTableRectangle, splitTrackedVerticalTableCell };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/ai-edits/table-mutation-plan.d.ts
|
|
2
|
+
type TableRectangle = {
|
|
3
|
+
left: number;
|
|
4
|
+
top: number;
|
|
5
|
+
right: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
};
|
|
8
|
+
type TableMutationPlanTarget = {
|
|
9
|
+
type: "none";
|
|
10
|
+
} | {
|
|
11
|
+
type: "tableStructure";
|
|
12
|
+
tablePosition: number;
|
|
13
|
+
} | {
|
|
14
|
+
type: "mergeCells";
|
|
15
|
+
tablePosition: number;
|
|
16
|
+
rectangle: TableRectangle;
|
|
17
|
+
} | {
|
|
18
|
+
type: "splitCell";
|
|
19
|
+
tablePosition: number;
|
|
20
|
+
rectangle: TableRectangle;
|
|
21
|
+
};
|
|
22
|
+
type TableMutationPlanCandidate<T> = {
|
|
23
|
+
item: T;
|
|
24
|
+
operationId: string;
|
|
25
|
+
target: TableMutationPlanTarget;
|
|
26
|
+
};
|
|
27
|
+
type TableMutationPlanSkip = {
|
|
28
|
+
id: string;
|
|
29
|
+
reason: "noopOperation" | "unsupportedBlock";
|
|
30
|
+
};
|
|
31
|
+
type TableMutationPlan<T> = {
|
|
32
|
+
executable: T[];
|
|
33
|
+
skipped: TableMutationPlanSkip[];
|
|
34
|
+
};
|
|
35
|
+
declare const planTableMutations: <T>(candidates: readonly TableMutationPlanCandidate<T>[]) => TableMutationPlan<T>;
|
|
36
|
+
declare const tableRectanglesEqual: (left: TableRectangle, right: TableRectangle) => boolean;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { TableMutationPlanTarget, TableRectangle, planTableMutations, tableRectanglesEqual };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//#region src/ai-edits/table-mutation-plan.ts
|
|
2
|
+
const planTableMutations = (candidates) => {
|
|
3
|
+
const tableStructureMutations = /* @__PURE__ */ new Set();
|
|
4
|
+
const mergeTables = /* @__PURE__ */ new Set();
|
|
5
|
+
const splitTables = /* @__PURE__ */ new Set();
|
|
6
|
+
for (const { target } of candidates) switch (target.type) {
|
|
7
|
+
case "tableStructure":
|
|
8
|
+
tableStructureMutations.add(target.tablePosition);
|
|
9
|
+
break;
|
|
10
|
+
case "mergeCells":
|
|
11
|
+
mergeTables.add(target.tablePosition);
|
|
12
|
+
break;
|
|
13
|
+
case "splitCell":
|
|
14
|
+
splitTables.add(target.tablePosition);
|
|
15
|
+
break;
|
|
16
|
+
case "none": break;
|
|
17
|
+
}
|
|
18
|
+
const mergeRectanglesByTable = /* @__PURE__ */ new Map();
|
|
19
|
+
const splitRectanglesByTable = /* @__PURE__ */ new Map();
|
|
20
|
+
const executable = [];
|
|
21
|
+
const skipped = [];
|
|
22
|
+
for (const candidate of candidates) {
|
|
23
|
+
const { target } = candidate;
|
|
24
|
+
if (target.type === "mergeCells") {
|
|
25
|
+
if (tableStructureMutations.has(target.tablePosition) || splitTables.has(target.tablePosition)) {
|
|
26
|
+
skipped.push({
|
|
27
|
+
id: candidate.operationId,
|
|
28
|
+
reason: "unsupportedBlock"
|
|
29
|
+
});
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const claimedRectangles = mergeRectanglesByTable.get(target.tablePosition) ?? [];
|
|
33
|
+
if (claimedRectangles.some((rectangle) => tableRectanglesEqual(rectangle, target.rectangle))) {
|
|
34
|
+
skipped.push({
|
|
35
|
+
id: candidate.operationId,
|
|
36
|
+
reason: "noopOperation"
|
|
37
|
+
});
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (claimedRectangles.some((rectangle) => tableRectanglesOverlap(rectangle, target.rectangle))) {
|
|
41
|
+
skipped.push({
|
|
42
|
+
id: candidate.operationId,
|
|
43
|
+
reason: "unsupportedBlock"
|
|
44
|
+
});
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
claimedRectangles.push(target.rectangle);
|
|
48
|
+
mergeRectanglesByTable.set(target.tablePosition, claimedRectangles);
|
|
49
|
+
executable.push(candidate.item);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (target.type === "splitCell") {
|
|
53
|
+
if (tableStructureMutations.has(target.tablePosition) || mergeTables.has(target.tablePosition)) {
|
|
54
|
+
skipped.push({
|
|
55
|
+
id: candidate.operationId,
|
|
56
|
+
reason: "unsupportedBlock"
|
|
57
|
+
});
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const claimedRectangles = splitRectanglesByTable.get(target.tablePosition) ?? [];
|
|
61
|
+
if (claimedRectangles.some((rectangle) => tableRectanglesEqual(rectangle, target.rectangle))) {
|
|
62
|
+
skipped.push({
|
|
63
|
+
id: candidate.operationId,
|
|
64
|
+
reason: "noopOperation"
|
|
65
|
+
});
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (claimedRectangles.some((rectangle) => tableRectanglesOverlap(rectangle, target.rectangle))) {
|
|
69
|
+
skipped.push({
|
|
70
|
+
id: candidate.operationId,
|
|
71
|
+
reason: "unsupportedBlock"
|
|
72
|
+
});
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
claimedRectangles.push(target.rectangle);
|
|
76
|
+
splitRectanglesByTable.set(target.tablePosition, claimedRectangles);
|
|
77
|
+
executable.push(candidate.item);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
executable.push(candidate.item);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
executable,
|
|
84
|
+
skipped
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
const tableRectanglesOverlap = (left, right) => left.left < right.right && right.left < left.right && left.top < right.bottom && right.top < left.bottom;
|
|
88
|
+
const tableRectanglesEqual = (left, right) => left.left === right.left && left.top === right.top && left.right === right.right && left.bottom === right.bottom;
|
|
89
|
+
//#endregion
|
|
90
|
+
export { planTableMutations, tableRectanglesEqual };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { TableRowTarget } from "./table-targets.js";
|
|
2
|
+
import { Transaction } from "prosemirror-state";
|
|
3
|
+
import { Node } from "prosemirror-model";
|
|
4
|
+
|
|
5
|
+
//#region src/ai-edits/table-row-column-mutations.d.ts
|
|
6
|
+
type TableRowInsertion = {
|
|
7
|
+
tableStart: number;
|
|
8
|
+
rowPosition: number;
|
|
9
|
+
rowType: Node["type"];
|
|
10
|
+
cells: readonly Node[];
|
|
11
|
+
rowspanUpdates: readonly number[];
|
|
12
|
+
};
|
|
13
|
+
type TableRowDeletion = Omit<TableRowTarget, "table">;
|
|
14
|
+
type TableColumnInsertion = {
|
|
15
|
+
tablePosition: number;
|
|
16
|
+
columnIndex: number;
|
|
17
|
+
};
|
|
18
|
+
type TableColumnDeletion = TableColumnInsertion;
|
|
19
|
+
type TableStructureRevision = {
|
|
20
|
+
revisionId: number;
|
|
21
|
+
author: string;
|
|
22
|
+
date: string;
|
|
23
|
+
};
|
|
24
|
+
type TableRowColumnMutationResult = {
|
|
25
|
+
type: "applied";
|
|
26
|
+
transaction: Transaction;
|
|
27
|
+
revisionId: number | null;
|
|
28
|
+
} | {
|
|
29
|
+
type: "unsupported";
|
|
30
|
+
};
|
|
31
|
+
declare const getTableColumnCoordinateKey: ({
|
|
32
|
+
tablePosition,
|
|
33
|
+
columnIndex
|
|
34
|
+
}: TableColumnInsertion) => string;
|
|
35
|
+
type FindTableColumnInsertionOptions = {
|
|
36
|
+
doc: Node;
|
|
37
|
+
blockFrom: number;
|
|
38
|
+
position: "after" | "before";
|
|
39
|
+
};
|
|
40
|
+
declare const findTableColumnInsertion: ({
|
|
41
|
+
doc,
|
|
42
|
+
blockFrom,
|
|
43
|
+
position
|
|
44
|
+
}: FindTableColumnInsertionOptions) => (TableColumnInsertion & {
|
|
45
|
+
boundaryPosition: number;
|
|
46
|
+
}) | null;
|
|
47
|
+
type FindTableRowInsertionOptions = FindTableColumnInsertionOptions;
|
|
48
|
+
declare const findTableRowInsertion: ({
|
|
49
|
+
doc,
|
|
50
|
+
blockFrom,
|
|
51
|
+
position
|
|
52
|
+
}: FindTableRowInsertionOptions) => TableRowInsertion | null;
|
|
53
|
+
type ApplyTableRowInsertionOptions = {
|
|
54
|
+
tr: Transaction;
|
|
55
|
+
insertion: TableRowInsertion;
|
|
56
|
+
cellTexts: readonly string[] | undefined;
|
|
57
|
+
revision: TableStructureRevision | null;
|
|
58
|
+
};
|
|
59
|
+
declare const applyTableRowInsertion: ({
|
|
60
|
+
tr,
|
|
61
|
+
insertion,
|
|
62
|
+
cellTexts,
|
|
63
|
+
revision
|
|
64
|
+
}: ApplyTableRowInsertionOptions) => TableRowColumnMutationResult;
|
|
65
|
+
type ApplyTableColumnInsertionOptions = {
|
|
66
|
+
tr: Transaction;
|
|
67
|
+
insertion: TableColumnInsertion;
|
|
68
|
+
cellTexts: readonly string[] | undefined;
|
|
69
|
+
revision: TableStructureRevision | null;
|
|
70
|
+
};
|
|
71
|
+
declare const applyTableColumnInsertion: ({
|
|
72
|
+
tr,
|
|
73
|
+
insertion,
|
|
74
|
+
cellTexts,
|
|
75
|
+
revision
|
|
76
|
+
}: ApplyTableColumnInsertionOptions) => TableRowColumnMutationResult;
|
|
77
|
+
type ApplyTableColumnDeletionOptions = {
|
|
78
|
+
tr: Transaction;
|
|
79
|
+
deletion: TableColumnDeletion;
|
|
80
|
+
insertedColumnCount: number;
|
|
81
|
+
revision: TableStructureRevision | null;
|
|
82
|
+
};
|
|
83
|
+
declare const applyTableColumnDeletion: ({
|
|
84
|
+
tr,
|
|
85
|
+
deletion,
|
|
86
|
+
insertedColumnCount,
|
|
87
|
+
revision
|
|
88
|
+
}: ApplyTableColumnDeletionOptions) => TableRowColumnMutationResult;
|
|
89
|
+
type ApplyTableRowDeletionOptions = {
|
|
90
|
+
tr: Transaction;
|
|
91
|
+
deletion: TableRowDeletion;
|
|
92
|
+
revision: TableStructureRevision | null;
|
|
93
|
+
};
|
|
94
|
+
declare const applyTableRowDeletion: ({
|
|
95
|
+
tr,
|
|
96
|
+
deletion,
|
|
97
|
+
revision
|
|
98
|
+
}: ApplyTableRowDeletionOptions) => TableRowColumnMutationResult;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { TableColumnDeletion, TableColumnInsertion, TableRowDeletion, TableRowInsertion, TableStructureRevision, applyTableColumnDeletion, applyTableColumnInsertion, applyTableRowDeletion, applyTableRowInsertion, findTableColumnInsertion, findTableRowInsertion, getTableColumnCoordinateKey };
|