@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,210 @@
|
|
|
1
|
+
import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js";
|
|
2
|
+
import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
|
|
3
|
+
import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
|
|
4
|
+
import { ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
|
|
5
|
+
import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
|
|
6
|
+
import { schema } from "../prosemirror/schema/index.js";
|
|
7
|
+
import { footnoteToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
|
|
8
|
+
import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
|
|
9
|
+
import { isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
|
|
10
|
+
import { EditorState } from "prosemirror-state";
|
|
11
|
+
import { EditorView } from "prosemirror-view";
|
|
12
|
+
//#region src/controller/noteEditorManager.ts
|
|
13
|
+
/** Framework-neutral lifecycle owner for editable footnote and endnote stories. */
|
|
14
|
+
const EMPTY_PLUGINS = [];
|
|
15
|
+
const storyMapKey = ({ kind, noteId }) => `${kind}:${String(noteId)}`;
|
|
16
|
+
const isNormalFootnote = (note) => !isSeparatorFootnote(note);
|
|
17
|
+
const isNormalEndnote = (note) => !isSeparatorEndnote(note);
|
|
18
|
+
const enumerateDocumentNoteStories = (document) => [...(document?.package.footnotes ?? []).filter(isNormalFootnote).map(({ id }) => ({
|
|
19
|
+
kind: "footnote",
|
|
20
|
+
noteId: id
|
|
21
|
+
})), ...(document?.package.endnotes ?? []).filter(isNormalEndnote).map(({ id }) => ({
|
|
22
|
+
kind: "endnote",
|
|
23
|
+
noteId: id
|
|
24
|
+
}))];
|
|
25
|
+
const resolveNote = (document, story) => {
|
|
26
|
+
return (story.kind === "footnote" ? document?.package.footnotes : document?.package.endnotes)?.find(({ id }) => id === story.noteId) ?? null;
|
|
27
|
+
};
|
|
28
|
+
const noteToProseDocument = (note, styles, theme) => {
|
|
29
|
+
const options = {};
|
|
30
|
+
if (styles) options.styles = styles;
|
|
31
|
+
if (theme !== void 0) options.theme = theme;
|
|
32
|
+
return footnoteToProseDoc(note.content, options);
|
|
33
|
+
};
|
|
34
|
+
const buildInitialState = (document, styles, manager, externalPlugins) => {
|
|
35
|
+
return ensureBaseDirectionInState(ensureParaIdsInState(EditorState.create({
|
|
36
|
+
doc: document,
|
|
37
|
+
schema,
|
|
38
|
+
plugins: [
|
|
39
|
+
...manager.getPlugins(),
|
|
40
|
+
...externalPlugins,
|
|
41
|
+
createDocumentStylesPlugin(styles)
|
|
42
|
+
]
|
|
43
|
+
})));
|
|
44
|
+
};
|
|
45
|
+
const createNoteEditorManager = (deps) => {
|
|
46
|
+
const mounted = /* @__PURE__ */ new Map();
|
|
47
|
+
let active = null;
|
|
48
|
+
const updateVisibility = () => {
|
|
49
|
+
const activeKey = active ? storyMapKey(active) : null;
|
|
50
|
+
for (const [key, story] of mounted) story.mountNode.hidden = key !== activeKey;
|
|
51
|
+
};
|
|
52
|
+
const destroyMounted = (story) => {
|
|
53
|
+
story.view.destroy();
|
|
54
|
+
story.manager.destroy();
|
|
55
|
+
story.mountNode.remove();
|
|
56
|
+
};
|
|
57
|
+
const destroy = () => {
|
|
58
|
+
for (const story of mounted.values()) destroyMounted(story);
|
|
59
|
+
mounted.clear();
|
|
60
|
+
active = null;
|
|
61
|
+
};
|
|
62
|
+
const sync = () => {
|
|
63
|
+
const host = deps.getHost();
|
|
64
|
+
if (!host) return;
|
|
65
|
+
const document = deps.getDocument();
|
|
66
|
+
const styles = deps.getStyles();
|
|
67
|
+
const theme = deps.getTheme();
|
|
68
|
+
const externalPlugins = deps.getPlugins?.() ?? EMPTY_PLUGINS;
|
|
69
|
+
const wanted = new Map(enumerateDocumentNoteStories(document).map((story) => [storyMapKey(story), story]));
|
|
70
|
+
const activeKey = active ? storyMapKey(active) : null;
|
|
71
|
+
for (const [key, story] of mounted) {
|
|
72
|
+
if (wanted.has(key)) continue;
|
|
73
|
+
destroyMounted(story);
|
|
74
|
+
mounted.delete(key);
|
|
75
|
+
}
|
|
76
|
+
for (const [key, storyKey] of wanted) {
|
|
77
|
+
if (!mounted.has(key) && key !== activeKey) continue;
|
|
78
|
+
const note = resolveNote(document, storyKey);
|
|
79
|
+
if (!note) continue;
|
|
80
|
+
const existing = mounted.get(key);
|
|
81
|
+
if (existing) {
|
|
82
|
+
if (existing.mountNode.parentElement !== host) host.append(existing.mountNode);
|
|
83
|
+
const nextProseDocument = noteToProseDocument(note, styles, theme);
|
|
84
|
+
const contextIsCurrent = existing.appliedStyles === styles && existing.appliedTheme === theme && existing.appliedPlugins === externalPlugins;
|
|
85
|
+
if ((existing.appliedNote === note && existing.appliedContent === note.content || existing.appliedProseDocument.eq(nextProseDocument)) && contextIsCurrent) {
|
|
86
|
+
existing.appliedNote = note;
|
|
87
|
+
existing.appliedContent = note.content;
|
|
88
|
+
existing.appliedProseDocument = nextProseDocument;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
existing.view.updateState(buildInitialState(nextProseDocument, styles, existing.manager, externalPlugins));
|
|
92
|
+
existing.appliedNote = note;
|
|
93
|
+
existing.appliedContent = note.content;
|
|
94
|
+
existing.appliedStyles = styles;
|
|
95
|
+
existing.appliedTheme = theme;
|
|
96
|
+
existing.appliedPlugins = externalPlugins;
|
|
97
|
+
existing.appliedProseDocument = nextProseDocument;
|
|
98
|
+
existing.dirty = false;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const manager = new ExtensionManager(createStarterKit());
|
|
102
|
+
manager.buildSchema();
|
|
103
|
+
manager.initializeRuntime();
|
|
104
|
+
const mountNode = host.ownerDocument.createElement("div");
|
|
105
|
+
mountNode.dataset["noteKind"] = storyKey.kind;
|
|
106
|
+
mountNode.dataset["noteId"] = String(storyKey.noteId);
|
|
107
|
+
host.append(mountNode);
|
|
108
|
+
const proseDocument = noteToProseDocument(note, styles, theme);
|
|
109
|
+
const view = new EditorView(mountNode, {
|
|
110
|
+
state: buildInitialState(proseDocument, styles, manager, externalPlugins),
|
|
111
|
+
dispatchTransaction(transaction) {
|
|
112
|
+
view.updateState(view.state.apply(transaction));
|
|
113
|
+
const mountedStory = mounted.get(key);
|
|
114
|
+
if (mountedStory && transaction.docChanged) mountedStory.dirty = true;
|
|
115
|
+
deps.onTransaction?.({
|
|
116
|
+
...storyKey,
|
|
117
|
+
docChanged: transaction.docChanged,
|
|
118
|
+
selectionChanged: transaction.selectionSet,
|
|
119
|
+
view
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
mounted.set(key, {
|
|
124
|
+
appliedContent: note.content,
|
|
125
|
+
appliedNote: note,
|
|
126
|
+
appliedPlugins: externalPlugins,
|
|
127
|
+
appliedProseDocument: proseDocument,
|
|
128
|
+
appliedStyles: styles,
|
|
129
|
+
appliedTheme: theme,
|
|
130
|
+
dirty: false,
|
|
131
|
+
manager,
|
|
132
|
+
mountNode,
|
|
133
|
+
note: storyKey,
|
|
134
|
+
view
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (active && !wanted.has(storyMapKey(active))) active = null;
|
|
138
|
+
updateVisibility();
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
activate: (story) => {
|
|
142
|
+
active = story;
|
|
143
|
+
sync();
|
|
144
|
+
if (!story) return null;
|
|
145
|
+
const view = mounted.get(storyMapKey(story))?.view ?? null;
|
|
146
|
+
if (view) return view;
|
|
147
|
+
active = null;
|
|
148
|
+
updateVisibility();
|
|
149
|
+
return null;
|
|
150
|
+
},
|
|
151
|
+
destroy,
|
|
152
|
+
getActive: () => active,
|
|
153
|
+
getView: (story) => mounted.get(storyMapKey(story))?.view ?? null,
|
|
154
|
+
listStories: () => enumerateDocumentNoteStories(deps.getDocument()),
|
|
155
|
+
snapshotDocument: (document) => {
|
|
156
|
+
let footnotes = document.package.footnotes;
|
|
157
|
+
let endnotes = document.package.endnotes;
|
|
158
|
+
let footnotesChanged = false;
|
|
159
|
+
let endnotesChanged = false;
|
|
160
|
+
for (const story of mounted.values()) {
|
|
161
|
+
if (!story.dirty) continue;
|
|
162
|
+
if (story.note.kind === "footnote") {
|
|
163
|
+
const index = footnotes?.findIndex(({ id }) => id === story.note.noteId) ?? -1;
|
|
164
|
+
const current = index === -1 ? null : footnotes?.at(index);
|
|
165
|
+
if (!current || !footnotes) continue;
|
|
166
|
+
if (!footnotesChanged) {
|
|
167
|
+
footnotes = [...footnotes];
|
|
168
|
+
footnotesChanged = true;
|
|
169
|
+
}
|
|
170
|
+
const updated = {
|
|
171
|
+
...current,
|
|
172
|
+
content: proseDocToBlocks(story.view.state.doc)
|
|
173
|
+
};
|
|
174
|
+
footnotes[index] = updated;
|
|
175
|
+
story.appliedNote = updated;
|
|
176
|
+
story.appliedContent = updated.content;
|
|
177
|
+
story.appliedProseDocument = noteToProseDocument(updated, story.appliedStyles, story.appliedTheme);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const index = endnotes?.findIndex(({ id }) => id === story.note.noteId) ?? -1;
|
|
181
|
+
const current = index === -1 ? null : endnotes?.at(index);
|
|
182
|
+
if (!current || !endnotes) continue;
|
|
183
|
+
if (!endnotesChanged) {
|
|
184
|
+
endnotes = [...endnotes];
|
|
185
|
+
endnotesChanged = true;
|
|
186
|
+
}
|
|
187
|
+
const updated = {
|
|
188
|
+
...current,
|
|
189
|
+
content: proseDocToBlocks(story.view.state.doc)
|
|
190
|
+
};
|
|
191
|
+
endnotes[index] = updated;
|
|
192
|
+
story.appliedNote = updated;
|
|
193
|
+
story.appliedContent = updated.content;
|
|
194
|
+
story.appliedProseDocument = noteToProseDocument(updated, story.appliedStyles, story.appliedTheme);
|
|
195
|
+
}
|
|
196
|
+
if (!footnotesChanged && !endnotesChanged) return document;
|
|
197
|
+
return {
|
|
198
|
+
...document,
|
|
199
|
+
package: {
|
|
200
|
+
...document.package,
|
|
201
|
+
...footnotesChanged && footnotes ? { footnotes } : {},
|
|
202
|
+
...endnotesChanged && endnotes ? { endnotes } : {}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
sync
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
//#endregion
|
|
210
|
+
export { createNoteEditorManager, enumerateDocumentNoteStories };
|
|
@@ -3,8 +3,8 @@ import { FolioAIEditView } from "./ai-edits/apply.js";
|
|
|
3
3
|
|
|
4
4
|
//#region src/document-operations.d.ts
|
|
5
5
|
declare const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION: 1;
|
|
6
|
-
declare const FOLIO_DOCUMENT_OPERATION_TYPES: readonly ["replaceInBlock", "replaceRange", "commentOnRange", "formatRange", "insertAfterBlock", "insertBeforeBlock", "replaceBlock", "deleteBlock", "commentOnBlock", "insertSignatureTable"];
|
|
7
|
-
declare const FOLIO_DOCUMENT_OPERATION_MODES: readonly ["direct", "tracked-changes"];
|
|
6
|
+
declare const FOLIO_DOCUMENT_OPERATION_TYPES: readonly ["replaceInBlock", "replaceRange", "commentOnRange", "formatRange", "insertAfterBlock", "insertBeforeBlock", "replaceBlock", "deleteBlock", "commentOnBlock", "insertSignatureTable", "insertTableRow", "deleteTableRow", "insertTableColumn", "deleteTableColumn", "mergeTableCells", "splitTableCell"];
|
|
7
|
+
declare const FOLIO_DOCUMENT_OPERATION_MODES: readonly ["direct", "tracked-changes", "suggested"];
|
|
8
8
|
declare const FOLIO_DOCUMENT_OPERATION_STORIES: readonly ["main", "header", "footer", "footnote", "endnote"];
|
|
9
9
|
declare const FOLIO_DOCUMENT_OPERATION_PRECONDITIONS: readonly ["blockTextHash"];
|
|
10
10
|
declare const FOLIO_DOCUMENT_OPERATION_BATCH_MODES: readonly ["best-effort", "atomic"];
|
|
@@ -13,16 +13,22 @@ type FolioDocumentOperationMode = FolioAIEditApplyMode;
|
|
|
13
13
|
type FolioDocumentOperationPrecondition = FolioAIEditPrecondition;
|
|
14
14
|
type FolioDocumentOperationType = FolioDocumentOperation["type"];
|
|
15
15
|
declare const FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE: Readonly<{
|
|
16
|
-
readonly replaceInBlock: readonly ["direct", "tracked-changes"];
|
|
17
|
-
readonly replaceRange: readonly ["direct", "tracked-changes"];
|
|
16
|
+
readonly replaceInBlock: readonly ["direct", "tracked-changes", "suggested"];
|
|
17
|
+
readonly replaceRange: readonly ["direct", "tracked-changes", "suggested"];
|
|
18
18
|
readonly commentOnRange: readonly ["direct", "tracked-changes"];
|
|
19
|
-
readonly formatRange: readonly ["direct"];
|
|
20
|
-
readonly insertAfterBlock: readonly ["direct", "tracked-changes"];
|
|
21
|
-
readonly insertBeforeBlock: readonly ["direct", "tracked-changes"];
|
|
22
|
-
readonly replaceBlock: readonly ["direct", "tracked-changes"];
|
|
23
|
-
readonly deleteBlock: readonly ["direct", "tracked-changes"];
|
|
19
|
+
readonly formatRange: readonly ["direct", "tracked-changes", "suggested"];
|
|
20
|
+
readonly insertAfterBlock: readonly ["direct", "tracked-changes", "suggested"];
|
|
21
|
+
readonly insertBeforeBlock: readonly ["direct", "tracked-changes", "suggested"];
|
|
22
|
+
readonly replaceBlock: readonly ["direct", "tracked-changes", "suggested"];
|
|
23
|
+
readonly deleteBlock: readonly ["direct", "tracked-changes", "suggested"];
|
|
24
24
|
readonly commentOnBlock: readonly ["direct", "tracked-changes"];
|
|
25
|
-
readonly insertSignatureTable: readonly ["direct"];
|
|
25
|
+
readonly insertSignatureTable: readonly ["direct", "suggested"];
|
|
26
|
+
readonly insertTableRow: readonly ["direct", "tracked-changes", "suggested"];
|
|
27
|
+
readonly deleteTableRow: readonly ["direct", "tracked-changes", "suggested"];
|
|
28
|
+
readonly insertTableColumn: readonly ["direct", "tracked-changes", "suggested"];
|
|
29
|
+
readonly deleteTableColumn: readonly ["direct", "tracked-changes", "suggested"];
|
|
30
|
+
readonly mergeTableCells: readonly ["direct", "tracked-changes"];
|
|
31
|
+
readonly splitTableCell: readonly ["direct", "tracked-changes"];
|
|
26
32
|
}>;
|
|
27
33
|
type FolioDocumentOperationCapabilities = {
|
|
28
34
|
readonly version: typeof FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION;
|
|
@@ -96,10 +102,36 @@ type FolioDocumentOperationAffectedTarget = {
|
|
|
96
102
|
story: FolioDocumentOperationStory;
|
|
97
103
|
anchorBlockId: string;
|
|
98
104
|
position: "before" | "after";
|
|
99
|
-
content: "block" | "signatureTable";
|
|
105
|
+
content: "block" | "signatureTable" | "tableRow" | "tableColumn";
|
|
100
106
|
} | {
|
|
101
107
|
type: "comment";
|
|
102
108
|
commentId: number;
|
|
109
|
+
} | {
|
|
110
|
+
type: "tableRow";
|
|
111
|
+
story: FolioDocumentOperationStory;
|
|
112
|
+
anchorBlockId: string;
|
|
113
|
+
effect: "deleted";
|
|
114
|
+
} | {
|
|
115
|
+
type: "tableColumn";
|
|
116
|
+
story: FolioDocumentOperationStory;
|
|
117
|
+
anchorBlockId: string;
|
|
118
|
+
effect: "deleted";
|
|
119
|
+
} | ({
|
|
120
|
+
type: "tableCells";
|
|
121
|
+
story: FolioDocumentOperationStory;
|
|
122
|
+
anchorBlockId: string;
|
|
123
|
+
effect: "merged";
|
|
124
|
+
} & ({
|
|
125
|
+
endAnchorBlockId: string;
|
|
126
|
+
rowCount?: never;
|
|
127
|
+
} | {
|
|
128
|
+
rowCount: number;
|
|
129
|
+
endAnchorBlockId?: never;
|
|
130
|
+
})) | {
|
|
131
|
+
type: "tableCell";
|
|
132
|
+
story: FolioDocumentOperationStory;
|
|
133
|
+
anchorBlockId: string;
|
|
134
|
+
effect: "split";
|
|
103
135
|
};
|
|
104
136
|
/** Input-ordered effect receipt for one successfully applied operation. */
|
|
105
137
|
type FolioDocumentOperationReceipt = {
|
|
@@ -12,9 +12,19 @@ const FOLIO_DOCUMENT_OPERATION_TYPES = Object.freeze([
|
|
|
12
12
|
"replaceBlock",
|
|
13
13
|
"deleteBlock",
|
|
14
14
|
"commentOnBlock",
|
|
15
|
-
"insertSignatureTable"
|
|
15
|
+
"insertSignatureTable",
|
|
16
|
+
"insertTableRow",
|
|
17
|
+
"deleteTableRow",
|
|
18
|
+
"insertTableColumn",
|
|
19
|
+
"deleteTableColumn",
|
|
20
|
+
"mergeTableCells",
|
|
21
|
+
"splitTableCell"
|
|
22
|
+
]);
|
|
23
|
+
const FOLIO_DOCUMENT_OPERATION_MODES = Object.freeze([
|
|
24
|
+
"direct",
|
|
25
|
+
"tracked-changes",
|
|
26
|
+
"suggested"
|
|
16
27
|
]);
|
|
17
|
-
const FOLIO_DOCUMENT_OPERATION_MODES = Object.freeze(["direct", "tracked-changes"]);
|
|
18
28
|
const FOLIO_DOCUMENT_OPERATION_STORIES = Object.freeze([
|
|
19
29
|
"main",
|
|
20
30
|
"header",
|
|
@@ -24,19 +34,26 @@ const FOLIO_DOCUMENT_OPERATION_STORIES = Object.freeze([
|
|
|
24
34
|
]);
|
|
25
35
|
const FOLIO_DOCUMENT_OPERATION_PRECONDITIONS = Object.freeze(["blockTextHash"]);
|
|
26
36
|
const FOLIO_DOCUMENT_OPERATION_BATCH_MODES = Object.freeze(["best-effort", "atomic"]);
|
|
27
|
-
const DIRECT_AND_TRACKED_MODES =
|
|
28
|
-
const
|
|
37
|
+
const DIRECT_AND_TRACKED_MODES = Object.freeze(["direct", "tracked-changes"]);
|
|
38
|
+
const DIRECT_TRACKED_AND_SUGGESTED_MODES = FOLIO_DOCUMENT_OPERATION_MODES;
|
|
39
|
+
const DIRECT_AND_SUGGESTED_MODES = Object.freeze(["direct", "suggested"]);
|
|
29
40
|
const FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE = Object.freeze({
|
|
30
|
-
replaceInBlock:
|
|
31
|
-
replaceRange:
|
|
41
|
+
replaceInBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
42
|
+
replaceRange: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
32
43
|
commentOnRange: DIRECT_AND_TRACKED_MODES,
|
|
33
|
-
formatRange:
|
|
34
|
-
insertAfterBlock:
|
|
35
|
-
insertBeforeBlock:
|
|
36
|
-
replaceBlock:
|
|
37
|
-
deleteBlock:
|
|
44
|
+
formatRange: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
45
|
+
insertAfterBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
46
|
+
insertBeforeBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
47
|
+
replaceBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
48
|
+
deleteBlock: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
38
49
|
commentOnBlock: DIRECT_AND_TRACKED_MODES,
|
|
39
|
-
insertSignatureTable:
|
|
50
|
+
insertSignatureTable: DIRECT_AND_SUGGESTED_MODES,
|
|
51
|
+
insertTableRow: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
52
|
+
deleteTableRow: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
53
|
+
insertTableColumn: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
54
|
+
deleteTableColumn: DIRECT_TRACKED_AND_SUGGESTED_MODES,
|
|
55
|
+
mergeTableCells: DIRECT_AND_TRACKED_MODES,
|
|
56
|
+
splitTableCell: DIRECT_AND_TRACKED_MODES
|
|
40
57
|
});
|
|
41
58
|
const DOCUMENT_OPERATION_CAPABILITIES = Object.freeze({
|
|
42
59
|
version: 1,
|
|
@@ -51,8 +68,8 @@ const DOCUMENT_OPERATION_CAPABILITIES = Object.freeze({
|
|
|
51
68
|
const getFolioDocumentOperationCapabilities = () => DOCUMENT_OPERATION_CAPABILITIES;
|
|
52
69
|
const includesDocumentOperationMode = (supportedModes, mode) => supportedModes.includes(mode);
|
|
53
70
|
const isFolioDocumentOperationModeSupported = (operationType, mode) => {
|
|
71
|
+
if (!Object.hasOwn(FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, operationType)) return false;
|
|
54
72
|
const supportedModes = FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE[operationType];
|
|
55
|
-
if (supportedModes === void 0) return false;
|
|
56
73
|
return includesDocumentOperationMode(supportedModes, mode);
|
|
57
74
|
};
|
|
58
75
|
const isSupportedFolioDocumentOperationVersion = (value) => value === 1;
|
|
@@ -94,6 +111,15 @@ const readOptionalBoolean = (value, key, path) => {
|
|
|
94
111
|
if (typeof candidate === "boolean") return candidate;
|
|
95
112
|
return invalidBatch(`${path}.${key}`, "expected a boolean when provided");
|
|
96
113
|
};
|
|
114
|
+
const readOptionalStringArray = (value, key, path) => {
|
|
115
|
+
const candidate = value[key];
|
|
116
|
+
if (candidate === void 0) return;
|
|
117
|
+
if (!Array.isArray(candidate)) return invalidBatch(`${path}.${key}`, "expected an array when provided");
|
|
118
|
+
return candidate.map((item, index) => {
|
|
119
|
+
if (typeof item === "string") return item;
|
|
120
|
+
return invalidBatch(`${path}.${key}[${index}]`, "expected a string");
|
|
121
|
+
});
|
|
122
|
+
};
|
|
97
123
|
const readNonNegativeInteger = (value, key, path) => {
|
|
98
124
|
const candidate = value[key];
|
|
99
125
|
if (typeof candidate === "number" && Number.isInteger(candidate) && candidate >= 0) return candidate;
|
|
@@ -183,7 +209,8 @@ const COMMON_OPERATION_KEYS = [
|
|
|
183
209
|
"blockId",
|
|
184
210
|
"severity",
|
|
185
211
|
"area",
|
|
186
|
-
"precondition"
|
|
212
|
+
"precondition",
|
|
213
|
+
"suggestionId"
|
|
187
214
|
];
|
|
188
215
|
const parseSignatureParties = (value, path) => {
|
|
189
216
|
const parties = value["parties"];
|
|
@@ -211,10 +238,12 @@ const parseDocumentOperation = (value, index) => {
|
|
|
211
238
|
const type = readString(value, "type", path);
|
|
212
239
|
const reviewMeta = readReviewMeta(value, path);
|
|
213
240
|
const precondition = readOptionalPrecondition(value, path);
|
|
241
|
+
const suggestionId = readOptionalString(value, "suggestionId", path);
|
|
214
242
|
const comment = readOptionalComment(value, path);
|
|
215
243
|
const operationMeta = {
|
|
216
244
|
...reviewMeta,
|
|
217
|
-
...precondition !== void 0 && { precondition }
|
|
245
|
+
...precondition !== void 0 && { precondition },
|
|
246
|
+
...suggestionId !== void 0 && { suggestionId }
|
|
218
247
|
};
|
|
219
248
|
if (type === "replaceRange") {
|
|
220
249
|
assertAllowedKeys(value, path, [
|
|
@@ -225,7 +254,8 @@ const parseDocumentOperation = (value, index) => {
|
|
|
225
254
|
"comment",
|
|
226
255
|
"severity",
|
|
227
256
|
"area",
|
|
228
|
-
"precondition"
|
|
257
|
+
"precondition",
|
|
258
|
+
"suggestionId"
|
|
229
259
|
]);
|
|
230
260
|
return {
|
|
231
261
|
...operationMeta,
|
|
@@ -263,7 +293,8 @@ const parseDocumentOperation = (value, index) => {
|
|
|
263
293
|
"formatting",
|
|
264
294
|
"severity",
|
|
265
295
|
"area",
|
|
266
|
-
"precondition"
|
|
296
|
+
"precondition",
|
|
297
|
+
"suggestionId"
|
|
267
298
|
]);
|
|
268
299
|
return {
|
|
269
300
|
...operationMeta,
|
|
@@ -382,6 +413,98 @@ const parseDocumentOperation = (value, index) => {
|
|
|
382
413
|
...comment !== void 0 && { comment }
|
|
383
414
|
};
|
|
384
415
|
}
|
|
416
|
+
if (type === "insertTableRow") {
|
|
417
|
+
assertAllowedKeys(value, path, [
|
|
418
|
+
...COMMON_OPERATION_KEYS,
|
|
419
|
+
"position",
|
|
420
|
+
"cellTexts"
|
|
421
|
+
]);
|
|
422
|
+
const position = value["position"];
|
|
423
|
+
if (position !== void 0 && position !== "after" && position !== "before") return invalidBatch(`${path}.position`, "expected \"after\" or \"before\" when provided");
|
|
424
|
+
const cellTexts = readOptionalStringArray(value, "cellTexts", path);
|
|
425
|
+
return {
|
|
426
|
+
...operationMeta,
|
|
427
|
+
id,
|
|
428
|
+
type,
|
|
429
|
+
blockId,
|
|
430
|
+
...position !== void 0 && { position },
|
|
431
|
+
...cellTexts !== void 0 && { cellTexts }
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
if (type === "deleteTableRow") {
|
|
435
|
+
assertAllowedKeys(value, path, COMMON_OPERATION_KEYS);
|
|
436
|
+
return {
|
|
437
|
+
...operationMeta,
|
|
438
|
+
id,
|
|
439
|
+
type,
|
|
440
|
+
blockId
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
if (type === "insertTableColumn") {
|
|
444
|
+
assertAllowedKeys(value, path, [
|
|
445
|
+
...COMMON_OPERATION_KEYS,
|
|
446
|
+
"position",
|
|
447
|
+
"cellTexts"
|
|
448
|
+
]);
|
|
449
|
+
const position = value["position"];
|
|
450
|
+
if (position !== void 0 && position !== "after" && position !== "before") return invalidBatch(`${path}.position`, "expected \"after\" or \"before\" when provided");
|
|
451
|
+
const cellTexts = readOptionalStringArray(value, "cellTexts", path);
|
|
452
|
+
return {
|
|
453
|
+
...operationMeta,
|
|
454
|
+
id,
|
|
455
|
+
type,
|
|
456
|
+
blockId,
|
|
457
|
+
...position !== void 0 && { position },
|
|
458
|
+
...cellTexts !== void 0 && { cellTexts }
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
if (type === "deleteTableColumn") {
|
|
462
|
+
assertAllowedKeys(value, path, COMMON_OPERATION_KEYS);
|
|
463
|
+
return {
|
|
464
|
+
...operationMeta,
|
|
465
|
+
id,
|
|
466
|
+
type,
|
|
467
|
+
blockId
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
if (type === "mergeTableCells") {
|
|
471
|
+
assertAllowedKeys(value, path, [
|
|
472
|
+
...COMMON_OPERATION_KEYS,
|
|
473
|
+
"endBlockId",
|
|
474
|
+
"rowCount"
|
|
475
|
+
]);
|
|
476
|
+
const endBlockId = readOptionalString(value, "endBlockId", path);
|
|
477
|
+
const rawRowCount = value["rowCount"];
|
|
478
|
+
if (endBlockId === void 0 === (rawRowCount === void 0)) return invalidBatch(path, "expected exactly one of endBlockId or rowCount");
|
|
479
|
+
if (endBlockId !== void 0) {
|
|
480
|
+
if (endBlockId.length === 0) return invalidBatch(`${path}.endBlockId`, "expected a non-empty string");
|
|
481
|
+
return {
|
|
482
|
+
...operationMeta,
|
|
483
|
+
id,
|
|
484
|
+
type,
|
|
485
|
+
blockId,
|
|
486
|
+
endBlockId
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
const rowCount = readNonNegativeInteger(value, "rowCount", path);
|
|
490
|
+
if (rowCount < 2) return invalidBatch(`${path}.rowCount`, "expected an integer greater than or equal to 2");
|
|
491
|
+
return {
|
|
492
|
+
...operationMeta,
|
|
493
|
+
id,
|
|
494
|
+
type,
|
|
495
|
+
blockId,
|
|
496
|
+
rowCount
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
if (type === "splitTableCell") {
|
|
500
|
+
assertAllowedKeys(value, path, COMMON_OPERATION_KEYS);
|
|
501
|
+
return {
|
|
502
|
+
...operationMeta,
|
|
503
|
+
id,
|
|
504
|
+
type,
|
|
505
|
+
blockId
|
|
506
|
+
};
|
|
507
|
+
}
|
|
385
508
|
return invalidBatch(`${path}.type`, `unsupported operation type "${type}"`);
|
|
386
509
|
};
|
|
387
510
|
const parseFolioDocumentOperationBatch = (value) => {
|
|
@@ -397,7 +520,7 @@ const parseFolioDocumentOperationBatch = (value) => {
|
|
|
397
520
|
const operations = value["operations"];
|
|
398
521
|
if (!Array.isArray(operations)) return invalidBatch("$.operations", "expected an array");
|
|
399
522
|
const mode = value["mode"];
|
|
400
|
-
if (mode !== void 0 && mode !== "direct" && mode !== "tracked-changes") return invalidBatch("$.mode", "expected \"direct\"
|
|
523
|
+
if (mode !== void 0 && mode !== "direct" && mode !== "tracked-changes" && mode !== "suggested") return invalidBatch("$.mode", "expected \"direct\", \"tracked-changes\", or \"suggested\" when provided");
|
|
401
524
|
const atomic = readOptionalBoolean(value, "atomic", "$");
|
|
402
525
|
const dryRun = readOptionalBoolean(value, "dryRun", "$");
|
|
403
526
|
const parsedOperations = operations.map(parseDocumentOperation);
|
|
@@ -498,6 +621,51 @@ const getPrimaryAffectedTarget = (operation, story) => {
|
|
|
498
621
|
position: operation.position ?? "after",
|
|
499
622
|
content: "signatureTable"
|
|
500
623
|
};
|
|
624
|
+
case "insertTableRow": return {
|
|
625
|
+
type: "insertion",
|
|
626
|
+
story,
|
|
627
|
+
anchorBlockId: operation.blockId,
|
|
628
|
+
position: operation.position ?? "after",
|
|
629
|
+
content: "tableRow"
|
|
630
|
+
};
|
|
631
|
+
case "deleteTableRow": return {
|
|
632
|
+
type: "tableRow",
|
|
633
|
+
story,
|
|
634
|
+
anchorBlockId: operation.blockId,
|
|
635
|
+
effect: "deleted"
|
|
636
|
+
};
|
|
637
|
+
case "insertTableColumn": return {
|
|
638
|
+
type: "insertion",
|
|
639
|
+
story,
|
|
640
|
+
anchorBlockId: operation.blockId,
|
|
641
|
+
position: operation.position ?? "after",
|
|
642
|
+
content: "tableColumn"
|
|
643
|
+
};
|
|
644
|
+
case "deleteTableColumn": return {
|
|
645
|
+
type: "tableColumn",
|
|
646
|
+
story,
|
|
647
|
+
anchorBlockId: operation.blockId,
|
|
648
|
+
effect: "deleted"
|
|
649
|
+
};
|
|
650
|
+
case "mergeTableCells": return operation.rowCount !== void 0 ? {
|
|
651
|
+
type: "tableCells",
|
|
652
|
+
story,
|
|
653
|
+
anchorBlockId: operation.blockId,
|
|
654
|
+
rowCount: operation.rowCount,
|
|
655
|
+
effect: "merged"
|
|
656
|
+
} : {
|
|
657
|
+
type: "tableCells",
|
|
658
|
+
story,
|
|
659
|
+
anchorBlockId: operation.blockId,
|
|
660
|
+
endAnchorBlockId: operation.endBlockId,
|
|
661
|
+
effect: "merged"
|
|
662
|
+
};
|
|
663
|
+
case "splitTableCell": return {
|
|
664
|
+
type: "tableCell",
|
|
665
|
+
story,
|
|
666
|
+
anchorBlockId: operation.blockId,
|
|
667
|
+
effect: "split"
|
|
668
|
+
};
|
|
501
669
|
}
|
|
502
670
|
};
|
|
503
671
|
/** Build deterministic affected-target receipts from operations and their applied entries. */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { elementToXml, findChild, getChildElements, getLocalName, mergeXmlnsDeclarations } from "./xmlParser.js";
|
|
2
|
+
import { padDecimal } from "./numberingParser.js";
|
|
2
3
|
import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
|
|
3
4
|
import { parseSdtProperties } from "./sdtProperties.js";
|
|
4
5
|
import { parseParagraph } from "./paragraphParser.js";
|
|
5
6
|
import { appendBookmarkMarkerToLastParagraphInBlocks, prependBookmarkMarkersToFirstParagraphInBlocks } from "./bookmarkPlacement.js";
|
|
6
7
|
import { convertBulletToUnicode } from "./bulletMarkers.js";
|
|
7
|
-
import { padDecimal } from "./numberingParser.js";
|
|
8
8
|
import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
|
|
9
9
|
import { parseTable } from "./tableParser.js";
|
|
10
10
|
//#region src/docx/blockContentParser.ts
|
|
@@ -53,7 +53,7 @@ const formatNumber = (value, numFmt) => {
|
|
|
53
53
|
default: return String(value);
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
|
-
const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList }) => {
|
|
56
|
+
const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList, siblingNumIdsByAbstractNumId }) => {
|
|
57
57
|
const listRendering = paragraph.listRendering;
|
|
58
58
|
if (!listRendering || !numbering) {
|
|
59
59
|
previousList.abstractNumId = null;
|
|
@@ -73,6 +73,14 @@ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounter
|
|
|
73
73
|
const counters = listCounters.get(numId);
|
|
74
74
|
if (!counters) return;
|
|
75
75
|
const abstractNumId = numbering.getAbstractNumId(numId);
|
|
76
|
+
if (firstEncounter && abstractNumId !== null) {
|
|
77
|
+
let siblingNumIds = siblingNumIdsByAbstractNumId.get(abstractNumId);
|
|
78
|
+
if (!siblingNumIds) {
|
|
79
|
+
siblingNumIds = /* @__PURE__ */ new Set();
|
|
80
|
+
siblingNumIdsByAbstractNumId.set(abstractNumId, siblingNumIds);
|
|
81
|
+
}
|
|
82
|
+
siblingNumIds.add(numId);
|
|
83
|
+
}
|
|
76
84
|
const styleNumbering = paragraph.formatting?.numPrFromStyle;
|
|
77
85
|
let resumedAbstractCounters;
|
|
78
86
|
const resumesRestartedInstance = firstEncounter && listRendering.startOverride === void 0 && abstractNumId !== null && previousList.abstractNumId === abstractNumId && previousList.numId !== null && previousList.numId !== numId && restartedNumIds.has(previousList.numId);
|
|
@@ -101,9 +109,13 @@ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounter
|
|
|
101
109
|
counters[level + 1] = (childCounter === void 0 || Number.isNaN(childCounter) ? 0 : childCounter) + childAdvances;
|
|
102
110
|
}
|
|
103
111
|
if (abstractNumId !== null) {
|
|
104
|
-
if (resumedAbstractCounters)
|
|
105
|
-
|
|
106
|
-
for (
|
|
112
|
+
if (resumedAbstractCounters) {
|
|
113
|
+
const siblingNumIds = siblingNumIdsByAbstractNumId.get(abstractNumId);
|
|
114
|
+
for (const otherNumId of siblingNumIds ?? []) {
|
|
115
|
+
const otherCounters = listCounters.get(otherNumId);
|
|
116
|
+
if (otherNumId === numId || !otherCounters || !otherCounters.every((value, index) => Object.is(value, resumedAbstractCounters[index]))) continue;
|
|
117
|
+
for (let i = 0; i < otherCounters.length; i += 1) otherCounters[i] = counters[i] ?? NaN;
|
|
118
|
+
}
|
|
107
119
|
}
|
|
108
120
|
abstractCounters.set(abstractNumId, [...counters]);
|
|
109
121
|
}
|
|
@@ -140,6 +152,7 @@ const parseBlockContent = (parent, styles, theme, numbering, rels, media, option
|
|
|
140
152
|
fromStyle: false,
|
|
141
153
|
numId: null
|
|
142
154
|
},
|
|
155
|
+
siblingNumIdsByAbstractNumId: /* @__PURE__ */ new Map(),
|
|
143
156
|
options: {
|
|
144
157
|
...options,
|
|
145
158
|
rootXmlns: mergeXmlnsDeclarations(options?.rootXmlns ?? {}, parent)
|
|
@@ -154,13 +167,14 @@ const parseBlockContentWithState = (parent, styles, theme, numbering, rels, medi
|
|
|
154
167
|
if (localName === "p") {
|
|
155
168
|
const paragraph = parseParagraph(child, styles, theme, numbering, rels, media, state.options);
|
|
156
169
|
prependPendingBookmarkMarkers(paragraph, pendingBookmarkMarkers);
|
|
157
|
-
enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media);
|
|
170
|
+
enrichParagraphTextBoxes(paragraph, child, styles, theme, numbering, rels, media, parseTable);
|
|
158
171
|
computeListMarker(paragraph, {
|
|
159
172
|
numbering,
|
|
160
173
|
listCounters: state.listCounters,
|
|
161
174
|
abstractCounters: state.abstractCounters,
|
|
162
175
|
restartedNumIds: state.restartedNumIds,
|
|
163
|
-
previousList: state.previousList
|
|
176
|
+
previousList: state.previousList,
|
|
177
|
+
siblingNumIdsByAbstractNumId: state.siblingNumIdsByAbstractNumId
|
|
164
178
|
});
|
|
165
179
|
content.push(paragraph);
|
|
166
180
|
continue;
|
|
@@ -75,7 +75,8 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
|
|
|
75
75
|
for (const child of children) {
|
|
76
76
|
if ((child.name?.replace(/^.*:/u, "") ?? "") !== "comment") continue;
|
|
77
77
|
const id = Number.parseInt(getAttribute(child, "w", "id") ?? "0", 10);
|
|
78
|
-
const
|
|
78
|
+
const rawAuthor = getAttribute(child, "w", "author");
|
|
79
|
+
const author = parseCommentAuthor(rawAuthor);
|
|
79
80
|
const rawInitials = getAttribute(child, "w", "initials");
|
|
80
81
|
const initials = rawInitials !== null ? String(rawInitials) : void 0;
|
|
81
82
|
const rawDate = getAttribute(child, "w", "date");
|
|
@@ -123,5 +124,9 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
|
|
|
123
124
|
}
|
|
124
125
|
return comments;
|
|
125
126
|
}
|
|
127
|
+
const parseCommentAuthor = (author) => {
|
|
128
|
+
if (author === "") return "";
|
|
129
|
+
return author?.trim() || "Unknown";
|
|
130
|
+
};
|
|
126
131
|
//#endregion
|
|
127
132
|
export { parseComments, parseCommentsExtended };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
|
|
3
|
+
//#region src/docx/commentRangeIntegrity.d.ts
|
|
4
|
+
declare const withoutOrphanCommentRanges: (doc: document_d_exports.Document) => document_d_exports.Document;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { withoutOrphanCommentRanges };
|