@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
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { markStructuralChange } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
|
|
2
|
+
import { stripBlockIdentityAttrs } from "./block-identity.js";
|
|
3
|
+
import { findEnclosingTableCell, findEnclosingTableRow } from "./table-targets.js";
|
|
4
|
+
import { TableMap, columnIsHeader, removeColumn, removeRow, rowIsHeader, tableNodeTypes } from "prosemirror-tables";
|
|
5
|
+
//#region src/ai-edits/table-row-column-mutations.ts
|
|
6
|
+
const getTableColumnCoordinateKey = ({ tablePosition, columnIndex }) => `${tablePosition}:${columnIndex}`;
|
|
7
|
+
const findTableColumnInsertion = ({ doc, blockFrom, position }) => {
|
|
8
|
+
const target = findEnclosingTableCell(doc, blockFrom);
|
|
9
|
+
if (!target) return null;
|
|
10
|
+
return {
|
|
11
|
+
tablePosition: target.tablePosition,
|
|
12
|
+
columnIndex: position === "before" ? target.leftColumnIndex : target.rightColumnIndex,
|
|
13
|
+
boundaryPosition: position === "before" ? target.cellPosition : target.cellEndPosition
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const findTableRowInsertion = ({ doc, blockFrom, position }) => {
|
|
17
|
+
const target = findEnclosingTableRow(doc, blockFrom);
|
|
18
|
+
if (!target) return null;
|
|
19
|
+
const map = TableMap.get(target.table);
|
|
20
|
+
const rowIndex = position === "before" ? target.rowIndex : target.rowIndex + 1;
|
|
21
|
+
return buildTableRowInsertion({
|
|
22
|
+
map,
|
|
23
|
+
table: target.table,
|
|
24
|
+
tableStart: target.tableStart,
|
|
25
|
+
rowIndex
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const applyTableRowInsertion = ({ tr, insertion, cellTexts, revision }) => {
|
|
29
|
+
if (revision && insertion.rowspanUpdates.length > 0) return { type: "unsupported" };
|
|
30
|
+
const liveRowspanUpdates = [];
|
|
31
|
+
for (const updatePosition of insertion.rowspanUpdates) {
|
|
32
|
+
const cellPosition = insertion.tableStart + updatePosition;
|
|
33
|
+
const liveCell = tr.doc.nodeAt(cellPosition);
|
|
34
|
+
const rowspan = liveCell?.attrs["rowspan"];
|
|
35
|
+
if (!liveCell || typeof rowspan !== "number") return { type: "unsupported" };
|
|
36
|
+
liveRowspanUpdates.push({
|
|
37
|
+
position: cellPosition,
|
|
38
|
+
cell: liveCell,
|
|
39
|
+
rowspan
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
for (const update of liveRowspanUpdates) tr.setNodeMarkup(update.position, void 0, {
|
|
43
|
+
...update.cell.attrs,
|
|
44
|
+
rowspan: update.rowspan + 1
|
|
45
|
+
});
|
|
46
|
+
const rowAttrs = revision ? { trIns: revision } : null;
|
|
47
|
+
const row = insertion.rowType.create(rowAttrs, insertion.cells);
|
|
48
|
+
tr.insert(insertion.rowPosition, populateTableRow(row, cellTexts));
|
|
49
|
+
return applied(tr, revision);
|
|
50
|
+
};
|
|
51
|
+
const applyTableColumnInsertion = ({ tr, insertion, cellTexts, revision }) => {
|
|
52
|
+
const tablePosition = tr.mapping.map(insertion.tablePosition, 1);
|
|
53
|
+
const table = tr.doc.nodeAt(tablePosition);
|
|
54
|
+
if (!table || table.type.spec["tableRole"] !== "table") return { type: "unsupported" };
|
|
55
|
+
const actions = buildTableColumnInsertionActions({
|
|
56
|
+
map: TableMap.get(table),
|
|
57
|
+
table,
|
|
58
|
+
columnIndex: insertion.columnIndex,
|
|
59
|
+
cellTexts
|
|
60
|
+
});
|
|
61
|
+
if (!actions || revision && actions.some(({ type }) => type === "setColspan")) return { type: "unsupported" };
|
|
62
|
+
const mapFrom = tr.mapping.maps.length;
|
|
63
|
+
for (const action of actions) {
|
|
64
|
+
const position = tr.mapping.slice(mapFrom).map(tablePosition + 1 + action.position);
|
|
65
|
+
if (action.type === "setColspan") {
|
|
66
|
+
tr.setNodeMarkup(position, void 0, action.attrs);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const cell = revision ? action.cell.type.create({
|
|
70
|
+
...action.cell.attrs,
|
|
71
|
+
cellMarker: {
|
|
72
|
+
kind: "ins",
|
|
73
|
+
info: revision
|
|
74
|
+
}
|
|
75
|
+
}, action.cell.content) : action.cell;
|
|
76
|
+
tr.insert(position, cell);
|
|
77
|
+
}
|
|
78
|
+
return applied(tr, revision);
|
|
79
|
+
};
|
|
80
|
+
const applyTableColumnDeletion = ({ tr, deletion, insertedColumnCount, revision }) => {
|
|
81
|
+
const tablePosition = tr.mapping.map(deletion.tablePosition, 1);
|
|
82
|
+
const table = tr.doc.nodeAt(tablePosition);
|
|
83
|
+
if (!table || table.type.spec["tableRole"] !== "table") return { type: "unsupported" };
|
|
84
|
+
const map = TableMap.get(table);
|
|
85
|
+
const columnIndex = deletion.columnIndex + insertedColumnCount;
|
|
86
|
+
if (columnIndex < 0 || columnIndex >= map.width) return { type: "unsupported" };
|
|
87
|
+
if (revision) {
|
|
88
|
+
const cellPositions = getTableColumnDeletionCellPositions({
|
|
89
|
+
map,
|
|
90
|
+
table,
|
|
91
|
+
columnIndex
|
|
92
|
+
});
|
|
93
|
+
if (!cellPositions) return { type: "unsupported" };
|
|
94
|
+
for (const cellPosition of cellPositions) tr.setNodeAttribute(tablePosition + 1 + cellPosition, "cellMarker", {
|
|
95
|
+
kind: "del",
|
|
96
|
+
info: revision
|
|
97
|
+
});
|
|
98
|
+
markStructuralChange(tr);
|
|
99
|
+
return applied(tr, revision);
|
|
100
|
+
}
|
|
101
|
+
if (map.width === 1) {
|
|
102
|
+
const transaction = deleteTableNode({
|
|
103
|
+
tr,
|
|
104
|
+
tablePosition,
|
|
105
|
+
table
|
|
106
|
+
});
|
|
107
|
+
return transaction ? applied(transaction, null) : { type: "unsupported" };
|
|
108
|
+
}
|
|
109
|
+
removeColumn(tr, {
|
|
110
|
+
map,
|
|
111
|
+
table,
|
|
112
|
+
tableStart: tablePosition + 1,
|
|
113
|
+
left: columnIndex,
|
|
114
|
+
top: 0,
|
|
115
|
+
right: columnIndex + 1,
|
|
116
|
+
bottom: map.height
|
|
117
|
+
}, columnIndex);
|
|
118
|
+
return applied(tr, null);
|
|
119
|
+
};
|
|
120
|
+
const applyTableRowDeletion = ({ tr, deletion, revision }) => {
|
|
121
|
+
if (revision) {
|
|
122
|
+
const rowPosition = tr.mapping.map(deletion.rowPosition);
|
|
123
|
+
const row = tr.doc.nodeAt(rowPosition);
|
|
124
|
+
if (!row || row.type.spec["tableRole"] !== "row" || row.attrs["trIns"] != null || row.attrs["trDel"] != null) return { type: "unsupported" };
|
|
125
|
+
tr.setNodeAttribute(rowPosition, "trDel", revision);
|
|
126
|
+
markStructuralChange(tr);
|
|
127
|
+
return applied(tr, revision);
|
|
128
|
+
}
|
|
129
|
+
const table = tr.doc.nodeAt(deletion.tablePosition);
|
|
130
|
+
if (!table || table.type.spec["tableRole"] !== "table" || deletion.rowIndex >= table.childCount) return { type: "unsupported" };
|
|
131
|
+
if (table.childCount === 1) {
|
|
132
|
+
const transaction = deleteTableNode({
|
|
133
|
+
tr,
|
|
134
|
+
tablePosition: deletion.tablePosition,
|
|
135
|
+
table
|
|
136
|
+
});
|
|
137
|
+
return transaction ? applied(transaction, null) : { type: "unsupported" };
|
|
138
|
+
}
|
|
139
|
+
const map = TableMap.get(table);
|
|
140
|
+
removeRow(tr, {
|
|
141
|
+
map,
|
|
142
|
+
table,
|
|
143
|
+
tableStart: deletion.tableStart,
|
|
144
|
+
left: 0,
|
|
145
|
+
top: deletion.rowIndex,
|
|
146
|
+
right: map.width,
|
|
147
|
+
bottom: deletion.rowIndex + 1
|
|
148
|
+
}, deletion.rowIndex);
|
|
149
|
+
return applied(tr, null);
|
|
150
|
+
};
|
|
151
|
+
const applied = (transaction, revision) => ({
|
|
152
|
+
type: "applied",
|
|
153
|
+
transaction,
|
|
154
|
+
revisionId: revision?.revisionId ?? null
|
|
155
|
+
});
|
|
156
|
+
const deleteTableNode = ({ tr, tablePosition, table }) => {
|
|
157
|
+
const tableEnd = tablePosition + table.nodeSize;
|
|
158
|
+
const resolved = tr.doc.resolve(tablePosition);
|
|
159
|
+
const parent = resolved.parent;
|
|
160
|
+
const tableIndex = resolved.index();
|
|
161
|
+
if (parent.canReplace(tableIndex, tableIndex + 1)) return tr.delete(tablePosition, tableEnd);
|
|
162
|
+
const emptyParagraph = tr.doc.type.schema.nodes["paragraph"]?.createAndFill();
|
|
163
|
+
if (!emptyParagraph || !parent.canReplaceWith(tableIndex, tableIndex + 1, emptyParagraph.type, emptyParagraph.marks)) return null;
|
|
164
|
+
return tr.replaceWith(tablePosition, tableEnd, emptyParagraph);
|
|
165
|
+
};
|
|
166
|
+
const buildTableRowInsertion = ({ map, table, tableStart, rowIndex }) => {
|
|
167
|
+
const cells = [];
|
|
168
|
+
const rowspanUpdates = [];
|
|
169
|
+
let referenceRow = rowIndex > 0 ? -1 : 0;
|
|
170
|
+
if (rowIsHeader(map, table, rowIndex + referenceRow)) referenceRow = rowIndex === 0 || rowIndex === map.height ? null : 0;
|
|
171
|
+
for (let col = 0, index = map.width * rowIndex; col < map.width; col++, index++) {
|
|
172
|
+
if (rowIndex > 0 && rowIndex < map.height && map.map[index] === map.map[index - map.width]) {
|
|
173
|
+
const cellPosition = map.map[index];
|
|
174
|
+
if (cellPosition === void 0) return null;
|
|
175
|
+
const cell = table.nodeAt(cellPosition);
|
|
176
|
+
if (!cell) return null;
|
|
177
|
+
const colspan = cell.attrs["colspan"];
|
|
178
|
+
if (typeof colspan !== "number" || colspan < 1) return null;
|
|
179
|
+
rowspanUpdates.push(cellPosition);
|
|
180
|
+
col += colspan - 1;
|
|
181
|
+
index += colspan - 1;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const referencePosition = referenceRow === null ? void 0 : map.map[index + referenceRow * map.width];
|
|
185
|
+
const cell = (referencePosition === void 0 ? tableNodeTypes(table.type.schema).cell : table.nodeAt(referencePosition)?.type)?.createAndFill();
|
|
186
|
+
if (!cell) return null;
|
|
187
|
+
cells.push(cell);
|
|
188
|
+
}
|
|
189
|
+
if (cells.length === 0) return null;
|
|
190
|
+
let rowPosition = tableStart;
|
|
191
|
+
for (let index = 0; index < rowIndex; index++) rowPosition += table.child(index).nodeSize;
|
|
192
|
+
return {
|
|
193
|
+
tableStart,
|
|
194
|
+
rowPosition,
|
|
195
|
+
rowType: tableNodeTypes(table.type.schema).row,
|
|
196
|
+
cells,
|
|
197
|
+
rowspanUpdates
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const populateTableRow = (row, cellTexts) => {
|
|
201
|
+
if (cellTexts === void 0) return row;
|
|
202
|
+
const cells = [];
|
|
203
|
+
row.forEach((cell, _offset, index) => {
|
|
204
|
+
const paragraph = cell.firstChild;
|
|
205
|
+
if (!paragraph?.isTextblock) {
|
|
206
|
+
cells.push(cell);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const text = cellTexts[index] ?? "";
|
|
210
|
+
const content = text.length > 0 ? row.type.schema.text(text) : null;
|
|
211
|
+
const nextParagraph = paragraph.type.create(stripBlockIdentityAttrs(paragraph.attrs), content);
|
|
212
|
+
cells.push(cell.type.create(cell.attrs, nextParagraph));
|
|
213
|
+
});
|
|
214
|
+
return row.type.create(row.attrs, cells);
|
|
215
|
+
};
|
|
216
|
+
const getInsertedPhysicalColumnRows = (map, columnIndex) => {
|
|
217
|
+
const rows = [];
|
|
218
|
+
for (let row = 0; row < map.height; row++) {
|
|
219
|
+
const index = row * map.width + columnIndex;
|
|
220
|
+
if (!(columnIndex > 0 && columnIndex < map.width && map.map[index - 1] === map.map[index])) rows.push(row);
|
|
221
|
+
}
|
|
222
|
+
return rows;
|
|
223
|
+
};
|
|
224
|
+
const expandTableCellColspan = (cell, colspanOffset) => {
|
|
225
|
+
const colspan = cell.attrs["colspan"];
|
|
226
|
+
const rowspan = cell.attrs["rowspan"];
|
|
227
|
+
const colwidth = cell.attrs["colwidth"];
|
|
228
|
+
if (typeof colspan !== "number" || !Number.isInteger(colspan) || colspan < 1 || typeof rowspan !== "number" || !Number.isInteger(rowspan) || rowspan < 1 || !Number.isInteger(colspanOffset) || colspanOffset < 0 || colspanOffset > colspan) return null;
|
|
229
|
+
if (colwidth !== null && !Array.isArray(colwidth)) return null;
|
|
230
|
+
if (Array.isArray(colwidth) && !colwidth.every((width) => typeof width === "number")) return null;
|
|
231
|
+
const nextColwidth = Array.isArray(colwidth) ? [...colwidth] : null;
|
|
232
|
+
nextColwidth?.splice(colspanOffset, 0, 0);
|
|
233
|
+
return {
|
|
234
|
+
...cell.attrs,
|
|
235
|
+
colspan: colspan + 1,
|
|
236
|
+
colwidth: nextColwidth
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
const populateTableCell = (cell, text) => {
|
|
240
|
+
const paragraph = cell.firstChild;
|
|
241
|
+
if (!paragraph?.isTextblock) return null;
|
|
242
|
+
const content = text.length > 0 ? cell.type.schema.text(text) : null;
|
|
243
|
+
const nextParagraph = paragraph.type.create(stripBlockIdentityAttrs(paragraph.attrs), content);
|
|
244
|
+
return cell.type.create(cell.attrs, nextParagraph);
|
|
245
|
+
};
|
|
246
|
+
const buildTableColumnInsertionActions = ({ map, table, columnIndex, cellTexts }) => {
|
|
247
|
+
if (columnIndex < 0 || columnIndex > map.width) return null;
|
|
248
|
+
const physicalRows = getInsertedPhysicalColumnRows(map, columnIndex);
|
|
249
|
+
if ((cellTexts?.length ?? 0) > physicalRows.length) return null;
|
|
250
|
+
let referenceColumn = columnIndex > 0 ? -1 : 0;
|
|
251
|
+
if (columnIsHeader(map, table, columnIndex + referenceColumn)) referenceColumn = columnIndex === 0 || columnIndex === map.width ? null : 0;
|
|
252
|
+
const actions = [];
|
|
253
|
+
let physicalCellIndex = 0;
|
|
254
|
+
for (let row = 0; row < map.height; row++) {
|
|
255
|
+
const index = row * map.width + columnIndex;
|
|
256
|
+
if (columnIndex > 0 && columnIndex < map.width && map.map[index - 1] === map.map[index]) {
|
|
257
|
+
const position = map.map[index];
|
|
258
|
+
if (position === void 0) return null;
|
|
259
|
+
const cell = table.nodeAt(position);
|
|
260
|
+
if (!cell) return null;
|
|
261
|
+
const colspanOffset = columnIndex - map.colCount(position);
|
|
262
|
+
const attrs = expandTableCellColspan(cell, colspanOffset);
|
|
263
|
+
if (!attrs) return null;
|
|
264
|
+
actions.push({
|
|
265
|
+
type: "setColspan",
|
|
266
|
+
position,
|
|
267
|
+
attrs
|
|
268
|
+
});
|
|
269
|
+
row += Number(cell.attrs["rowspan"]) - 1;
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
const referencePosition = referenceColumn === null ? void 0 : map.map[index + referenceColumn];
|
|
273
|
+
const cell = (referencePosition === void 0 ? tableNodeTypes(table.type.schema).cell : table.nodeAt(referencePosition)?.type)?.createAndFill();
|
|
274
|
+
if (!cell) return null;
|
|
275
|
+
const populatedCell = populateTableCell(cell, cellTexts?.[physicalCellIndex] ?? "");
|
|
276
|
+
if (!populatedCell) return null;
|
|
277
|
+
actions.push({
|
|
278
|
+
type: "insertCell",
|
|
279
|
+
position: map.positionAt(row, columnIndex, table),
|
|
280
|
+
cell: populatedCell
|
|
281
|
+
});
|
|
282
|
+
physicalCellIndex++;
|
|
283
|
+
}
|
|
284
|
+
return actions;
|
|
285
|
+
};
|
|
286
|
+
const getTableColumnDeletionCellPositions = ({ map, table, columnIndex }) => {
|
|
287
|
+
if (columnIndex < 0 || columnIndex >= map.width) return null;
|
|
288
|
+
const positions = /* @__PURE__ */ new Set();
|
|
289
|
+
for (let row = 0; row < map.height; row++) {
|
|
290
|
+
const position = map.map[row * map.width + columnIndex];
|
|
291
|
+
if (position === void 0) return null;
|
|
292
|
+
const cell = table.nodeAt(position);
|
|
293
|
+
const tableRole = cell?.type.spec["tableRole"];
|
|
294
|
+
if (!cell || tableRole !== "cell" && tableRole !== "header_cell" || cell.attrs["colspan"] !== 1 || cell.attrs["cellMarker"] != null) return null;
|
|
295
|
+
positions.add(position);
|
|
296
|
+
}
|
|
297
|
+
return [...positions];
|
|
298
|
+
};
|
|
299
|
+
//#endregion
|
|
300
|
+
export { applyTableColumnDeletion, applyTableColumnInsertion, applyTableRowDeletion, applyTableRowInsertion, findTableColumnInsertion, findTableRowInsertion, getTableColumnCoordinateKey };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { TableRectangle } from "./table-mutation-plan.js";
|
|
2
|
+
import { Node } from "prosemirror-model";
|
|
3
|
+
import { TableMap } from "prosemirror-tables";
|
|
4
|
+
|
|
5
|
+
//#region src/ai-edits/table-targets.d.ts
|
|
6
|
+
type TableBoundary = {
|
|
7
|
+
before: number;
|
|
8
|
+
after: number;
|
|
9
|
+
};
|
|
10
|
+
type TableRowTarget = {
|
|
11
|
+
table: Node;
|
|
12
|
+
tableStart: number;
|
|
13
|
+
tablePosition: number;
|
|
14
|
+
rowIndex: number;
|
|
15
|
+
rowPosition: number;
|
|
16
|
+
};
|
|
17
|
+
type TableCellTarget = {
|
|
18
|
+
tablePosition: number;
|
|
19
|
+
cellPosition: number;
|
|
20
|
+
cellEndPosition: number;
|
|
21
|
+
leftColumnIndex: number;
|
|
22
|
+
rightColumnIndex: number;
|
|
23
|
+
topRowIndex: number;
|
|
24
|
+
bottomRowIndex: number;
|
|
25
|
+
};
|
|
26
|
+
/** Resolve the nearest enclosing table boundary for block-adjacent insertions. */
|
|
27
|
+
declare const findEnclosingTableBoundary: (doc: Node, blockFrom: number) => TableBoundary | null;
|
|
28
|
+
declare const findEnclosingTableRow: (doc: Node, blockFrom: number) => TableRowTarget | null;
|
|
29
|
+
declare const findEnclosingTableCell: (doc: Node, blockFrom: number) => TableCellTarget | null;
|
|
30
|
+
declare const tableRectangleCutsMergedCell: (map: TableMap, rectangle: TableRectangle) => boolean;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { TableBoundary, TableCellTarget, TableRowTarget, findEnclosingTableBoundary, findEnclosingTableCell, findEnclosingTableRow, tableRectangleCutsMergedCell };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { TableMap } from "prosemirror-tables";
|
|
2
|
+
//#region src/ai-edits/table-targets.ts
|
|
3
|
+
/** Resolve the nearest enclosing table boundary for block-adjacent insertions. */
|
|
4
|
+
const findEnclosingTableBoundary = (doc, blockFrom) => {
|
|
5
|
+
const resolved = doc.resolve(blockFrom);
|
|
6
|
+
for (let depth = resolved.depth; depth > 0; depth--) if (resolved.node(depth).type.name === "table") return {
|
|
7
|
+
before: resolved.before(depth),
|
|
8
|
+
after: resolved.after(depth)
|
|
9
|
+
};
|
|
10
|
+
return null;
|
|
11
|
+
};
|
|
12
|
+
const findEnclosingTableRow = (doc, blockFrom) => {
|
|
13
|
+
const resolved = doc.resolve(blockFrom);
|
|
14
|
+
for (let rowDepth = resolved.depth; rowDepth > 0; rowDepth--) {
|
|
15
|
+
if (resolved.node(rowDepth).type.spec["tableRole"] !== "row") continue;
|
|
16
|
+
const tableDepth = rowDepth - 1;
|
|
17
|
+
const table = resolved.node(tableDepth);
|
|
18
|
+
if (table.type.spec["tableRole"] !== "table") return null;
|
|
19
|
+
return {
|
|
20
|
+
table,
|
|
21
|
+
tableStart: resolved.start(tableDepth),
|
|
22
|
+
tablePosition: resolved.before(tableDepth),
|
|
23
|
+
rowIndex: resolved.index(tableDepth),
|
|
24
|
+
rowPosition: resolved.before(rowDepth)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
};
|
|
29
|
+
const findEnclosingTableCell = (doc, blockFrom) => {
|
|
30
|
+
const resolved = doc.resolve(blockFrom);
|
|
31
|
+
for (let cellDepth = resolved.depth; cellDepth > 0; cellDepth--) {
|
|
32
|
+
const cell = resolved.node(cellDepth);
|
|
33
|
+
const tableRole = cell.type.spec["tableRole"];
|
|
34
|
+
if (tableRole !== "cell" && tableRole !== "header_cell") continue;
|
|
35
|
+
const rowDepth = cellDepth - 1;
|
|
36
|
+
const tableDepth = rowDepth - 1;
|
|
37
|
+
if (tableDepth < 0) return null;
|
|
38
|
+
if (resolved.node(rowDepth).type.spec["tableRole"] !== "row" || resolved.node(tableDepth).type.spec["tableRole"] !== "table") return null;
|
|
39
|
+
const table = resolved.node(tableDepth);
|
|
40
|
+
const tableStart = resolved.start(tableDepth);
|
|
41
|
+
const cellPosition = resolved.before(cellDepth);
|
|
42
|
+
const cellRectangle = TableMap.get(table).findCell(cellPosition - tableStart);
|
|
43
|
+
return {
|
|
44
|
+
tablePosition: resolved.before(tableDepth),
|
|
45
|
+
cellPosition,
|
|
46
|
+
cellEndPosition: cellPosition + cell.nodeSize,
|
|
47
|
+
leftColumnIndex: cellRectangle.left,
|
|
48
|
+
rightColumnIndex: cellRectangle.right,
|
|
49
|
+
topRowIndex: cellRectangle.top,
|
|
50
|
+
bottomRowIndex: cellRectangle.bottom
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
};
|
|
55
|
+
const tableRectangleCutsMergedCell = (map, rectangle) => {
|
|
56
|
+
if (rectangle.left < 0 || rectangle.top < 0 || rectangle.right > map.width || rectangle.bottom > map.height) return false;
|
|
57
|
+
for (let row = rectangle.top; row < rectangle.bottom; row++) {
|
|
58
|
+
const leftIndex = row * map.width + rectangle.left;
|
|
59
|
+
const rightIndex = row * map.width + rectangle.right - 1;
|
|
60
|
+
if (rectangle.left > 0 && map.map[leftIndex] === map.map[leftIndex - 1] || rectangle.right < map.width && map.map[rightIndex] === map.map[rightIndex + 1]) return true;
|
|
61
|
+
}
|
|
62
|
+
for (let column = rectangle.left; column < rectangle.right; column++) {
|
|
63
|
+
const topIndex = rectangle.top * map.width + column;
|
|
64
|
+
const bottomIndex = (rectangle.bottom - 1) * map.width + column;
|
|
65
|
+
if (rectangle.top > 0 && map.map[topIndex] === map.map[topIndex - map.width] || rectangle.bottom < map.height && map.map[bottomIndex] === map.map[bottomIndex + map.width]) return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
};
|
|
69
|
+
//#endregion
|
|
70
|
+
export { findEnclosingTableBoundary, findEnclosingTableCell, findEnclosingTableRow, tableRectangleCutsMergedCell };
|
package/dist/ai-edits/types.d.ts
CHANGED
|
@@ -122,6 +122,13 @@ type FolioAISignatureParty = {
|
|
|
122
122
|
};
|
|
123
123
|
type FolioAIEditOperation = FolioAIEditReviewMeta & {
|
|
124
124
|
precondition?: FolioAIEditPrecondition;
|
|
125
|
+
/**
|
|
126
|
+
* Groups this operation's produced marks under one logical suggestion so the
|
|
127
|
+
* host can accept/reject them together. Only consulted in `"suggested"` apply
|
|
128
|
+
* mode; ignored otherwise. When omitted in suggested mode the applier falls
|
|
129
|
+
* back to the operation `id`, giving per-operation grouping.
|
|
130
|
+
*/
|
|
131
|
+
suggestionId?: string;
|
|
125
132
|
} & ({
|
|
126
133
|
id: string;
|
|
127
134
|
type: "replaceInBlock";
|
|
@@ -196,8 +203,56 @@ type FolioAIEditOperation = FolioAIEditReviewMeta & {
|
|
|
196
203
|
position?: "after" | "before";
|
|
197
204
|
parties: FolioAISignatureParty[];
|
|
198
205
|
comment?: FolioAIComment;
|
|
206
|
+
} | {
|
|
207
|
+
id: string;
|
|
208
|
+
type: "insertTableRow"; /** Stable paragraph anchor inside the row that receives the new sibling. */
|
|
209
|
+
blockId: string;
|
|
210
|
+
position?: "after" | "before"; /** Initial text for each physical cell in source order; omitted cells stay empty. */
|
|
211
|
+
cellTexts?: string[];
|
|
212
|
+
} | {
|
|
213
|
+
id: string;
|
|
214
|
+
type: "deleteTableRow"; /** Stable paragraph anchor inside the row to delete. */
|
|
215
|
+
blockId: string;
|
|
216
|
+
} | {
|
|
217
|
+
id: string;
|
|
218
|
+
type: "insertTableColumn"; /** Stable paragraph anchor inside the cell that receives the new sibling column. */
|
|
219
|
+
blockId: string;
|
|
220
|
+
position?: "after" | "before"; /** Initial text for newly created physical cells in row order. */
|
|
221
|
+
cellTexts?: string[];
|
|
222
|
+
} | {
|
|
223
|
+
id: string;
|
|
224
|
+
type: "deleteTableColumn"; /** Stable paragraph anchor inside the column to delete. */
|
|
225
|
+
blockId: string;
|
|
226
|
+
} | ({
|
|
227
|
+
id: string;
|
|
228
|
+
type: "mergeTableCells"; /** Stable paragraph anchor inside the first cell. */
|
|
229
|
+
blockId: string;
|
|
230
|
+
} & ({
|
|
231
|
+
/** Stable paragraph anchor inside the opposite corner cell. */endBlockId: string;
|
|
232
|
+
rowCount?: never;
|
|
233
|
+
} | {
|
|
234
|
+
/** Number of grid rows to merge downward from the anchored cell. */rowCount: number;
|
|
235
|
+
endBlockId?: never;
|
|
236
|
+
})) | {
|
|
237
|
+
id: string;
|
|
238
|
+
type: "splitTableCell"; /** Stable paragraph anchor inside the cell to split. */
|
|
239
|
+
blockId: string;
|
|
199
240
|
});
|
|
200
|
-
|
|
241
|
+
/**
|
|
242
|
+
* How AI-authored operations are applied:
|
|
243
|
+
* - `"direct"` — edits are written straight into the document.
|
|
244
|
+
* - `"tracked-changes"` — edits land as normal tracked changes (`w:ins`/`w:del`).
|
|
245
|
+
* - `"suggested"` — edits land as tracked changes carrying `"suggested"`
|
|
246
|
+
* provenance: rendered with the tracked-change grammar but stripped from
|
|
247
|
+
* serialized DOCX until a human accepts them. Behaves like `"tracked-changes"`
|
|
248
|
+
* and covers the inline text/format operations (replaceInBlock, replaceRange,
|
|
249
|
+
* formatRange) plus the block and table row/column structural operations
|
|
250
|
+
* (insertAfterBlock, insertBeforeBlock, replaceBlock, deleteBlock,
|
|
251
|
+
* insertSignatureTable, insertTableRow, deleteTableRow, insertTableColumn,
|
|
252
|
+
* deleteTableColumn). Only comment operations and cell merge/split report
|
|
253
|
+
* `unsupportedMode`.
|
|
254
|
+
*/
|
|
255
|
+
type FolioAIEditApplyMode = "direct" | "tracked-changes" | "suggested";
|
|
201
256
|
type FolioAIEditSkipReason = "missingBlock" | "changedBlock" | "ambiguousFind" | "missingFind" | "unsupportedBlock" | "unsupportedMode" | "atomicBatchRejected" | "preconditionFailed" | "staleRange" | "emptyOperation"
|
|
202
257
|
/**
|
|
203
258
|
* The operation would not change the document — find equals
|
|
@@ -225,6 +280,12 @@ type FolioAIEditAppliedOperation = {
|
|
|
225
280
|
* belonging to this op.
|
|
226
281
|
*/
|
|
227
282
|
revisionIds?: readonly number[];
|
|
283
|
+
/**
|
|
284
|
+
* The suggestion id stamped on every mark this operation produced (only set
|
|
285
|
+
* in `"suggested"` apply mode). Pass it to `acceptSuggestion` /
|
|
286
|
+
* `rejectSuggestion` / `scrollToSuggestion` to resolve the whole suggestion.
|
|
287
|
+
*/
|
|
288
|
+
suggestionId?: string;
|
|
228
289
|
};
|
|
229
290
|
type FolioAIEditSkippedOperation = {
|
|
230
291
|
id: string;
|
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
//#region src/ai-edits/word-diff.ts
|
|
2
2
|
const tokenize = (s) => s.match(/\s+|\S+/gu) ?? [];
|
|
3
|
+
/**
|
|
4
|
+
* Cell budget for the O(n*m) word-diff DP table below, mirroring
|
|
5
|
+
* `MAX_LCS_CELLS` in `version-comparison.ts`. `before`/`after` come from
|
|
6
|
+
* attacker-controlled document text (a `modified` block pair), so an
|
|
7
|
+
* unbounded pair of large strings would otherwise force a quadratic-sized
|
|
8
|
+
* allocation. Past this budget, skip the DP and fall back to a single
|
|
9
|
+
* whole-string `del` + `ins` pair — a coarser diff, but O(1) memory.
|
|
10
|
+
*/
|
|
11
|
+
const MAX_WORD_DIFF_CELLS = 4e6;
|
|
3
12
|
const diffWordSegments = (before, after) => {
|
|
4
13
|
const a = tokenize(before);
|
|
5
14
|
const b = tokenize(after);
|
|
6
15
|
if (a.length === 0 && b.length === 0) return [];
|
|
7
16
|
const m = a.length;
|
|
8
17
|
const n = b.length;
|
|
18
|
+
if (m * n > MAX_WORD_DIFF_CELLS) {
|
|
19
|
+
const segments = [];
|
|
20
|
+
if (before.length > 0) segments.push({
|
|
21
|
+
type: "del",
|
|
22
|
+
text: before
|
|
23
|
+
});
|
|
24
|
+
if (after.length > 0) segments.push({
|
|
25
|
+
type: "ins",
|
|
26
|
+
text: after
|
|
27
|
+
});
|
|
28
|
+
return segments;
|
|
29
|
+
}
|
|
9
30
|
const dp = Array.from({ length: m + 1 }, () => Array.from({ length: n + 1 }, () => 0));
|
|
10
31
|
for (let i = 0; i < m; i++) for (let j = 0; j < n; j++) {
|
|
11
32
|
const row = dp[i + 1];
|
|
@@ -27,9 +27,9 @@ import { AcceptAutocompleteResult, AutocompleteSuggestionPluginOptions, Autocomp
|
|
|
27
27
|
import { ImageMeta, ImageRef, MarkdownOptions, MarkdownResult } from "../markdown/types.js";
|
|
28
28
|
import { fromMarkdown } from "../markdown/fromMarkdown.js";
|
|
29
29
|
import { toMarkdown, toMarkdownResult } from "../markdown/index.js";
|
|
30
|
-
import { EmbeddedFont, EmbeddedFontParts, extractEmbeddedFonts, getEmbeddedFontFaces } from "../fonts/embeddedFonts.js";
|
|
31
|
-
import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "../utils/fontResolver.js";
|
|
30
|
+
import { EmbeddedFont, EmbeddedFontParts, buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
|
|
31
|
+
import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
|
|
32
32
|
import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
|
|
33
33
|
type Document = document_d_exports.Document;
|
|
34
34
|
type DocxConformanceClass = document_d_exports.DocxConformanceClass;
|
|
35
|
-
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
35
|
+
export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidFolioDocumentOperationBatchError, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
package/dist/compat/eigenpal.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
|
|
1
2
|
import { deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
|
|
2
3
|
import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText } from "../ai-edits/snapshot.js";
|
|
3
4
|
import { diffWordSegments } from "../ai-edits/word-diff.js";
|
|
@@ -13,7 +14,6 @@ import { DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
|
|
|
13
14
|
import { buildPositionalText } from "../ai-suggestions/text-positions.js";
|
|
14
15
|
import { isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/conflict.js";
|
|
15
16
|
import { applySuggestions } from "../ai-suggestions/apply.js";
|
|
16
|
-
import { getGoogleFontsEnabled, setGoogleFontsEnabled } from "../utils/fontResolver.js";
|
|
17
17
|
import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "../prosemirror/plugins/aiSuggestionDecorations.js";
|
|
18
18
|
import { scrollFolioPositionIntoView } from "../paged-layout/scrollToPmPosition.js";
|
|
19
19
|
import { getFolioCaretViewportRect, getFolioSelectionViewportRect } from "../paged-layout/selectionViewportRect.js";
|
|
@@ -25,6 +25,6 @@ import { clearTemplateSlashMenu, consumeTemplateSlashQuery, getTemplateSlashMenu
|
|
|
25
25
|
import { DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, acceptAutocompleteSuggestion, acceptAutocompleteWord, appendAutocompleteToken, autocompleteSuggestionKey, autocompleteSuggestionPlugin, clearAutocompleteSuggestion, finishAutocompleteSuggestion, getAutocompleteSuggestion, shouldTriggerAutocomplete, startAutocompleteSuggestion } from "../prosemirror/plugins/autocompleteSuggestion.js";
|
|
26
26
|
import { fromMarkdown } from "../markdown/fromMarkdown.js";
|
|
27
27
|
import { toMarkdown, toMarkdownResult } from "../markdown/index.js";
|
|
28
|
-
import { extractEmbeddedFonts, getEmbeddedFontFaces } from "../fonts/embeddedFonts.js";
|
|
28
|
+
import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
|
|
29
29
|
import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
|
|
30
|
-
export { DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
30
|
+
export { DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatDate } from "../docx/fieldParser.js";
|
|
2
1
|
import { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError } from "./errors.js";
|
|
2
|
+
import { formatDate } from "../docx/fieldParser.js";
|
|
3
3
|
//#region src/content-controls/mutateContentControls.ts
|
|
4
4
|
/**
|
|
5
5
|
* Pure (immutable) write helpers for block-level content controls.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { EditorView } from "prosemirror-view";
|
|
2
|
+
|
|
3
|
+
//#region src/controller/activeEditorStory.d.ts
|
|
4
|
+
type ActiveEditorStoryTarget = {
|
|
5
|
+
type: "note";
|
|
6
|
+
view: EditorView;
|
|
7
|
+
} | {
|
|
8
|
+
type: "headerFooter";
|
|
9
|
+
view: EditorView;
|
|
10
|
+
} | {
|
|
11
|
+
type: "body";
|
|
12
|
+
view: EditorView;
|
|
13
|
+
} | {
|
|
14
|
+
type: "none";
|
|
15
|
+
view: null;
|
|
16
|
+
};
|
|
17
|
+
type ActiveEditorStoryCandidates = {
|
|
18
|
+
bodyView: EditorView | null;
|
|
19
|
+
headerFooterView: EditorView | null;
|
|
20
|
+
noteView: EditorView | null;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the single command target across editable document stories.
|
|
24
|
+
*
|
|
25
|
+
* A visible note panel takes precedence over header/footer mode, which takes
|
|
26
|
+
* precedence over the body. Keeping this order in core prevents framework
|
|
27
|
+
* adapters from sending formatting, focus, or history commands to a story
|
|
28
|
+
* hidden behind another active editor surface during an async UI transition.
|
|
29
|
+
*/
|
|
30
|
+
declare const resolveActiveEditorStory: ({
|
|
31
|
+
bodyView,
|
|
32
|
+
headerFooterView,
|
|
33
|
+
noteView
|
|
34
|
+
}: ActiveEditorStoryCandidates) => ActiveEditorStoryTarget;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { ActiveEditorStoryCandidates, ActiveEditorStoryTarget, resolveActiveEditorStory };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/controller/activeEditorStory.ts
|
|
2
|
+
const NO_ACTIVE_STORY = {
|
|
3
|
+
type: "none",
|
|
4
|
+
view: null
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the single command target across editable document stories.
|
|
8
|
+
*
|
|
9
|
+
* A visible note panel takes precedence over header/footer mode, which takes
|
|
10
|
+
* precedence over the body. Keeping this order in core prevents framework
|
|
11
|
+
* adapters from sending formatting, focus, or history commands to a story
|
|
12
|
+
* hidden behind another active editor surface during an async UI transition.
|
|
13
|
+
*/
|
|
14
|
+
const resolveActiveEditorStory = ({ bodyView, headerFooterView, noteView }) => {
|
|
15
|
+
if (noteView) return {
|
|
16
|
+
type: "note",
|
|
17
|
+
view: noteView
|
|
18
|
+
};
|
|
19
|
+
if (headerFooterView) return {
|
|
20
|
+
type: "headerFooter",
|
|
21
|
+
view: headerFooterView
|
|
22
|
+
};
|
|
23
|
+
if (bodyView) return {
|
|
24
|
+
type: "body",
|
|
25
|
+
view: bodyView
|
|
26
|
+
};
|
|
27
|
+
return NO_ACTIVE_STORY;
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { resolveActiveEditorStory };
|