@stll/folio-core 0.54.2 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.js +185 -33
- package/dist/ai-edits/headless.js +3 -2
- package/dist/ai-edits/types.d.ts +7 -1
- package/dist/compare/compare.js +1 -0
- package/dist/compare/content-types.d.ts +3 -15
- package/dist/compare/reproducible-package.d.ts +0 -17
- package/dist/compare/reproducible-package.js +12 -18
- package/dist/controller/canonicalClipboard.d.ts +23 -0
- package/dist/controller/canonicalClipboard.js +476 -0
- package/dist/controller/canonicalClipboardResources.d.ts +21 -0
- package/dist/controller/canonicalClipboardResources.js +382 -0
- package/dist/controller/canonicalComposition.d.ts +53 -0
- package/dist/controller/canonicalComposition.js +296 -0
- package/dist/controller/canonicalInlineProjection.d.ts +113 -0
- package/dist/controller/canonicalInlineProjection.js +393 -0
- package/dist/controller/canonicalInput.d.ts +54 -0
- package/dist/controller/canonicalInput.js +377 -0
- package/dist/controller/canonicalInputTimer.d.ts +7 -0
- package/dist/controller/canonicalInputTimer.js +11 -0
- package/dist/controller/canonicalOperations.d.ts +22 -0
- package/dist/controller/canonicalOperations.js +85 -0
- package/dist/controller/canonicalPublicOperations.d.ts +48 -0
- package/dist/controller/canonicalPublicOperations.js +556 -0
- package/dist/controller/canonicalReview.d.ts +12 -0
- package/dist/controller/canonicalReview.js +19 -0
- package/dist/controller/canonicalSession.d.ts +167 -0
- package/dist/controller/canonicalSession.js +1186 -0
- package/dist/controller/canonicalStoryEditor.d.ts +36 -0
- package/dist/controller/canonicalStoryEditor.js +87 -0
- package/dist/controller/canonicalStructure.d.ts +16 -0
- package/dist/controller/canonicalStructure.js +322 -0
- package/dist/controller/canonicalTocSelection.d.ts +11 -0
- package/dist/controller/canonicalTocSelection.js +43 -0
- package/dist/controller/folioEditor.d.ts +3 -10
- package/dist/controller/folioEditor.js +14 -4
- package/dist/controller/headerFooterEditorManager.d.ts +5 -0
- package/dist/controller/headerFooterEditorManager.js +72 -3
- package/dist/controller/hiddenEditorApi.d.ts +45 -0
- package/dist/controller/hiddenEditorApi.js +29 -8
- package/dist/controller/hiddenEditorManager.d.ts +13 -2
- package/dist/controller/hiddenEditorManager.js +639 -31
- package/dist/controller/layoutPipeline.d.ts +1 -1
- package/dist/controller/layoutPipeline.js +2 -0
- package/dist/controller/noteEditorManager.d.ts +5 -0
- package/dist/controller/noteEditorManager.js +114 -15
- package/dist/document-operations.d.ts +8 -1
- package/dist/document-operations.js +6 -4
- package/dist/docx/attributeRemainder.js +1 -0
- package/dist/docx/blockPlainText.d.ts +1 -1
- package/dist/docx/blockPlainText.js +11 -3
- package/dist/docx/canonicalResourceSave.d.ts +16 -0
- package/dist/docx/canonicalResourceSave.js +27 -0
- package/dist/docx/canonicalSave.d.ts +29 -0
- package/dist/docx/canonicalSave.js +101 -0
- package/dist/docx/canonicalSessionInput.d.ts +11 -0
- package/dist/docx/canonicalSessionInput.js +27 -0
- package/dist/docx/canonicalStoryRepack.d.ts +10 -0
- package/dist/docx/canonicalStoryRepack.js +74 -0
- package/dist/docx/contentTypeRegistry.d.ts +8 -0
- package/dist/docx/contentTypeRegistry.js +64 -0
- package/dist/docx/documentParser.d.ts +1 -13
- package/dist/docx/documentParser.js +1 -47
- package/dist/docx/ensureParaIds.d.ts +7 -1
- package/dist/docx/ensureParaIds.js +173 -215
- package/dist/docx/foldedListNumberFields.d.ts +85 -0
- package/dist/docx/foldedListNumberFields.js +267 -0
- package/dist/docx/footnoteParser.d.ts +1 -11
- package/dist/docx/footnoteParser.js +1 -16
- package/dist/docx/headerFooterParser.d.ts +1 -9
- package/dist/docx/headerFooterParser.js +1 -12
- package/dist/docx/headerFooterVerbatim.d.ts +39 -1
- package/dist/docx/headerFooterVerbatim.js +173 -2
- package/dist/docx/imageParser.d.ts +13 -1
- package/dist/docx/imageParser.js +20 -11
- package/dist/docx/metadataPrivacy.js +6 -1
- package/dist/docx/noteIds.d.ts +5 -0
- package/dist/docx/noteIds.js +6 -2
- package/dist/docx/noteReferenceMark.d.ts +3 -1
- package/dist/docx/noteReferenceMark.js +15 -14
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +17 -3
- package/dist/docx/packageParts.d.ts +3 -1
- package/dist/docx/packageParts.js +74 -19
- package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
- package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
- package/dist/docx/paragraphParser.js +101 -53
- package/dist/docx/paragraphPropertySource.d.ts +15 -1
- package/dist/docx/paragraphPropertySource.js +77 -22
- package/dist/docx/parser.js +3 -1
- package/dist/docx/removeHeaderFooterParts.js +17 -6
- package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
- package/dist/docx/reviewHistoryNamespace.js +4 -0
- package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
- package/dist/docx/reviewResolutionProvenance.js +153 -0
- package/dist/docx/rezip.d.ts +54 -6
- package/dist/docx/rezip.js +835 -257
- package/dist/docx/runConsolidator.d.ts +2 -58
- package/dist/docx/runConsolidator.js +3 -175
- package/dist/docx/runParser.d.ts +2 -1
- package/dist/docx/runParser.js +156 -116
- package/dist/docx/saveDiagnostics.d.ts +22 -0
- package/dist/docx/saveDiagnostics.js +0 -0
- package/dist/docx/selectiveSave.d.ts +3 -1
- package/dist/docx/selectiveSave.js +36 -4
- package/dist/docx/selectiveXmlPatch.d.ts +16 -8
- package/dist/docx/selectiveXmlPatch.js +81 -7
- package/dist/docx/serializer/documentSerializer.d.ts +9 -2
- package/dist/docx/serializer/documentSerializer.js +29 -10
- package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
- package/dist/docx/serializer/headerFooterSerializer.js +19 -11
- package/dist/docx/serializer/noteSerializer.d.ts +2 -2
- package/dist/docx/serializer/noteSerializer.js +24 -8
- package/dist/docx/serializer/paragraphSerializer.js +41 -4
- package/dist/docx/serializer/partNamespaces.js +2 -1
- package/dist/docx/serializer/runSerializer.js +3 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
- package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
- package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
- package/dist/docx/settingsParser.d.ts +1 -2
- package/dist/docx/settingsParser.js +5 -6
- package/dist/docx/storyBlockReplay.d.ts +31 -0
- package/dist/docx/storyBlockReplay.js +471 -0
- package/dist/docx/storyPlainText.d.ts +20 -0
- package/dist/docx/storyPlainText.js +23 -0
- package/dist/docx/streamingXmlParser.d.ts +22 -1
- package/dist/docx/streamingXmlParser.js +49 -3
- package/dist/docx/structuralXmlPatch.js +18 -23
- package/dist/docx/styleParser.d.ts +5 -1
- package/dist/docx/styleParser.js +1 -1
- package/dist/docx/tableParser.d.ts +1 -8
- package/dist/docx/tableParser.js +1 -28
- package/dist/docx/textBoxParser.d.ts +1 -5
- package/dist/docx/textBoxParser.js +1 -20
- package/dist/docx/unzip.js +6 -1
- package/dist/docx/verbatimCapture.d.ts +3 -1
- package/dist/docx/verbatimCapture.js +49 -6
- package/dist/i18n/messages/ar.gen.d.ts +5 -0
- package/dist/i18n/messages/ar.gen.js +656 -0
- package/dist/i18n/messages/cs.gen.d.ts +5 -0
- package/dist/i18n/messages/cs.gen.js +656 -0
- package/dist/i18n/messages/de.gen.d.ts +5 -0
- package/dist/i18n/messages/de.gen.js +656 -0
- package/dist/i18n/messages/en.gen.d.ts +5 -0
- package/dist/i18n/messages/en.gen.js +656 -0
- package/dist/i18n/messages/es.gen.d.ts +5 -0
- package/dist/i18n/messages/es.gen.js +656 -0
- package/dist/i18n/messages/et.gen.d.ts +5 -0
- package/dist/i18n/messages/et.gen.js +656 -0
- package/dist/i18n/messages/fr.gen.d.ts +5 -0
- package/dist/i18n/messages/fr.gen.js +656 -0
- package/dist/i18n/messages/he.gen.d.ts +5 -0
- package/dist/i18n/messages/he.gen.js +656 -0
- package/dist/i18n/messages/hi.gen.d.ts +5 -0
- package/dist/i18n/messages/hi.gen.js +656 -0
- package/dist/i18n/messages/hu.gen.d.ts +5 -0
- package/dist/i18n/messages/hu.gen.js +656 -0
- package/dist/i18n/messages/locales.d.ts +5 -0
- package/dist/i18n/messages/locales.js +22 -0
- package/dist/i18n/messages/lt.gen.d.ts +5 -0
- package/dist/i18n/messages/lt.gen.js +656 -0
- package/dist/i18n/messages/lv.gen.d.ts +5 -0
- package/dist/i18n/messages/lv.gen.js +656 -0
- package/dist/i18n/messages/pl.gen.d.ts +5 -0
- package/dist/i18n/messages/pl.gen.js +656 -0
- package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
- package/dist/i18n/messages/pt-BR.gen.js +656 -0
- package/dist/i18n/messages/sk.gen.d.ts +5 -0
- package/dist/i18n/messages/sk.gen.js +656 -0
- package/dist/i18n/messages/tr.gen.d.ts +5 -0
- package/dist/i18n/messages/tr.gen.js +656 -0
- package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
- package/dist/i18n/messages/zh-CN.gen.js +656 -0
- package/dist/i18n/messages.d.ts +2 -3
- package/dist/i18n/messages.js +1 -19
- package/dist/internal/acceptedBlockProjection.d.ts +12 -0
- package/dist/internal/acceptedBlockProjection.js +45 -0
- package/dist/internal/noteMarkerAttrs.d.ts +8 -0
- package/dist/internal/noteMarkerAttrs.js +16 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
- package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
- package/dist/internal/prosemirrorAttrBoundary.js +50 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
- package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
- package/dist/layout-bridge/convert/noteReferences.js +1 -6
- package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
- package/dist/managers/DocumentLoaderManager.d.ts +1 -0
- package/dist/managers/DocumentLoaderManager.js +9 -1
- package/dist/markdown/escape.d.ts +3 -1
- package/dist/markdown/escape.js +9 -2
- package/dist/markdown/renderBlock.js +20 -121
- package/dist/markdown/renderParagraph.js +13 -15
- package/dist/markdown/renderRuns.d.ts +7 -1
- package/dist/markdown/renderRuns.js +35 -15
- package/dist/markdown/renderTable.js +2 -0
- package/dist/markdown/types.d.ts +3 -9
- package/dist/prosemirror/attrs/index.d.ts +2 -12
- package/dist/prosemirror/attrs/index.js +22 -48
- package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
- package/dist/prosemirror/canonicalCommands.d.ts +121 -0
- package/dist/prosemirror/canonicalCommands.js +35 -0
- package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
- package/dist/prosemirror/canonicalSelectionRange.js +15 -0
- package/dist/prosemirror/clipboardIntent.d.ts +7 -0
- package/dist/prosemirror/clipboardIntent.js +9 -0
- package/dist/prosemirror/commands/pageBreak.js +15 -1
- package/dist/prosemirror/commands/pastePlainText.js +2 -1
- package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
- package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
- package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
- package/dist/prosemirror/conversion/toProseDoc.d.ts +11 -4
- package/dist/prosemirror/conversion/toProseDoc.js +55 -14
- package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
- package/dist/prosemirror/executeEditorCommand.js +26 -0
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +88 -48
- package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +56 -28
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
- package/dist/prosemirror/extensions/marks/markUtils.js +72 -8
- package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
- package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
- package/dist/prosemirror/insertOperations.js +2 -1
- package/dist/prosemirror/listMarker.d.ts +1 -0
- package/dist/prosemirror/listMarker.js +16 -7
- package/dist/prosemirror/listNumbering.js +26 -5
- package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
- package/dist/prosemirror/listRenderingAttrs.js +3 -0
- package/dist/prosemirror/markupViewNotes.js +3 -2
- package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
- package/dist/prosemirror/noteReferenceReview.js +5 -3
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
- package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
- package/dist/prosemirror/plugins/suggestionMode.js +57 -7
- package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
- package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
- package/dist/prosemirror/runFormattingFromMarks.js +15 -1
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
- package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
- package/dist/prosemirror/schema/marks.d.ts +2 -0
- package/dist/prosemirror/schema/nodes.d.ts +10 -2
- package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
- package/dist/prosemirror/textInput.js +5 -1
- package/dist/prosemirror/trackedRevisionPath.js +2 -1
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
- package/dist/prosemirror/validation.js +4 -0
- package/dist/types/canonicalCapabilities.d.ts +215 -0
- package/dist/types/canonicalCapabilities.js +212 -0
- package/dist/types/canonicalSave.d.ts +11 -0
- package/dist/types/canonicalSave.js +0 -0
- package/dist/types/content.d.ts +2 -2
- package/dist/types/docxSerialization.d.ts +14 -0
- package/dist/types/docxSerialization.js +7 -0
- package/dist/utils/createDocument.js +2 -2
- package/package.json +16 -4
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { TemplatePreviewEntry, TemplatePreviewHiddenRange } from "../prosemirror/plugins/templatePreviewValues.js";
|
|
3
3
|
import { ColumnLayout, FlowBlock, FootnoteContent, HeaderFooterContent, Layout, Measure, PageHeaderFooterRefs, PageMargins } from "../layout-engine/types.js";
|
|
4
|
+
import { LayoutRunOptions } from "./layoutRunOptions.js";
|
|
4
5
|
import { DisplayMode } from "../managers/EditorModeManager.js";
|
|
5
6
|
import { LayoutSession } from "./layoutSession.js";
|
|
6
|
-
import { LayoutRunOptions } from "./layoutRunOptions.js";
|
|
7
7
|
import { HyphenationReadiness } from "./hyphenationReadiness.js";
|
|
8
8
|
import { ConvertHeaderFooterOptions, HeaderFooterMetrics } from "../layout-bridge/convert/headerFooterLayout.js";
|
|
9
9
|
import "../layout-engine/index.js";
|
|
@@ -244,6 +244,7 @@ function runLayoutPipelineMeasured(deps, state, options) {
|
|
|
244
244
|
const hfMeasureBlocks = (hfBlocks, hfWidth) => measureBlocks(hfBlocks, hfWidth, void 0, void 0, buildHeaderFooterFieldValues(hfBlocks, pageCount, hfClock, fieldInputs), { allowEndTabOverflow: true });
|
|
245
245
|
return {
|
|
246
246
|
...flowOpts.styles ? { styles: flowOpts.styles } : {},
|
|
247
|
+
...document?.package.numbering === void 0 ? {} : { numbering: document.package.numbering },
|
|
247
248
|
...flowOpts.defaultSize === void 0 ? {} : { defaultSize: flowOpts.defaultSize },
|
|
248
249
|
..._theme !== void 0 ? { theme: _theme } : {},
|
|
249
250
|
fontAlternates,
|
|
@@ -377,6 +378,7 @@ function runLayoutPipelineMeasured(deps, state, options) {
|
|
|
377
378
|
if (flowOpts.styles) noteOptions.styles = flowOpts.styles;
|
|
378
379
|
if (flowOpts.defaultSize !== void 0) noteOptions.defaultSize = flowOpts.defaultSize;
|
|
379
380
|
if (_theme !== void 0) noteOptions.theme = _theme;
|
|
381
|
+
if (document?.package.numbering !== void 0) noteOptions.numbering = document.package.numbering;
|
|
380
382
|
noteOptions.fontAlternates = fontAlternates;
|
|
381
383
|
if (defaultTabStop !== void 0) noteOptions.defaultTabStopTwips = defaultTabStop;
|
|
382
384
|
if (flowOpts.lineBreakRules) noteOptions.lineBreakRules = flowOpts.lineBreakRules;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { CanonicalGap } from "../types/canonicalCapabilities.js";
|
|
3
|
+
import { HiddenEditorApi } from "./hiddenEditorApi.js";
|
|
2
4
|
import { NoteStoryKey } from "../types/editor-story.js";
|
|
3
5
|
import { Plugin } from "prosemirror-state";
|
|
4
6
|
import { DirectEditorProps, EditorView } from "prosemirror-view";
|
|
@@ -12,6 +14,9 @@ type NoteEditorTransaction = NoteStoryKey & {
|
|
|
12
14
|
type NoteEditorManagerDeps = {
|
|
13
15
|
createView?: ((mountNode: HTMLElement, props: DirectEditorProps) => EditorView) | undefined;
|
|
14
16
|
getDocument: () => document_d_exports.Document | null;
|
|
17
|
+
getCanonicalApi?: (() => HiddenEditorApi | null) | undefined;
|
|
18
|
+
getExperimentalSession?: (() => "canonical" | undefined) | undefined;
|
|
19
|
+
onSessionRefusal?: ((reason: string, gap: CanonicalGap) => void) | undefined;
|
|
15
20
|
getHost: () => HTMLElement | null;
|
|
16
21
|
getPlugins?: (() => Plugin[]) | undefined;
|
|
17
22
|
getStyles: () => document_d_exports.StyleDefinitions | null | undefined;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
|
|
2
|
+
import { cloneDocumentWithParagraphPropertySources } from "../docx/paragraphPropertySource.js";
|
|
3
|
+
import { visitDocxParagraphs, visitParagraphRuns } from "../docx/paragraphTraversal.js";
|
|
2
4
|
import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
|
|
3
5
|
import { footnoteToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
|
|
4
6
|
import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js";
|
|
@@ -9,7 +11,10 @@ import { createDocumentNumberingPlugin } from "../prosemirror/plugins/documentNu
|
|
|
9
11
|
import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
|
|
10
12
|
import { schema } from "../prosemirror/schema/index.js";
|
|
11
13
|
import { storyListNumbering } from "../prosemirror/storyListNumbering.js";
|
|
12
|
-
import {
|
|
14
|
+
import { CANONICAL_GAP, usesCanonicalSession } from "../types/canonicalCapabilities.js";
|
|
15
|
+
import { createCanonicalStoryEditor } from "./canonicalStoryEditor.js";
|
|
16
|
+
import { OP_STORIES } from "@stll/docx-core/ops";
|
|
17
|
+
import { EditorState, TextSelection } from "prosemirror-state";
|
|
13
18
|
import { EditorView } from "prosemirror-view";
|
|
14
19
|
//#region src/controller/noteEditorManager.ts
|
|
15
20
|
/** Framework-neutral lifecycle owner for editable footnote and endnote stories. */
|
|
@@ -28,12 +33,7 @@ const enumerateDocumentNoteStories = (document) => [...(document?.package.footno
|
|
|
28
33
|
const resolveNote = (document, story) => {
|
|
29
34
|
return (story.kind === "footnote" ? document?.package.footnotes : document?.package.endnotes)?.find(({ id }) => id === story.noteId) ?? null;
|
|
30
35
|
};
|
|
31
|
-
const noteToProseDocument = (note,
|
|
32
|
-
const options = {};
|
|
33
|
-
if (styles) options.styles = styles;
|
|
34
|
-
if (theme !== void 0) options.theme = theme;
|
|
35
|
-
return footnoteToProseDoc(note.content, options);
|
|
36
|
-
};
|
|
36
|
+
const noteToProseDocument = (note, options) => footnoteToProseDoc(note.content, options);
|
|
37
37
|
const buildInitialState = (document, styles, numbering, manager, externalPlugins) => {
|
|
38
38
|
return ensureBaseDirectionInState(ensureParaIdsInState(EditorState.create({
|
|
39
39
|
doc: document,
|
|
@@ -46,6 +46,31 @@ const buildInitialState = (document, styles, numbering, manager, externalPlugins
|
|
|
46
46
|
]
|
|
47
47
|
})));
|
|
48
48
|
};
|
|
49
|
+
/** Automatic note marks have no PM width; retain their authored runs on default writeback. */
|
|
50
|
+
const preserveNoteMarkers = ({ source, projected }) => {
|
|
51
|
+
const marks = [];
|
|
52
|
+
visitDocxParagraphs({ documentBody: { content: source } }, (paragraph) => visitParagraphRuns(paragraph, (run) => {
|
|
53
|
+
const content = run.content.filter((child) => child.type === "noteMarker");
|
|
54
|
+
if (content.length > 0) marks.push({
|
|
55
|
+
...run,
|
|
56
|
+
content
|
|
57
|
+
});
|
|
58
|
+
}));
|
|
59
|
+
if (marks.length === 0) return projected;
|
|
60
|
+
let hasMarker = false;
|
|
61
|
+
visitDocxParagraphs({ documentBody: { content: projected } }, (paragraph) => visitParagraphRuns(paragraph, (run) => {
|
|
62
|
+
if (run.content.some((child) => child.type === "noteMarker")) hasMarker = true;
|
|
63
|
+
}));
|
|
64
|
+
if (hasMarker) return projected;
|
|
65
|
+
const owned = cloneDocumentWithParagraphPropertySources({ package: { document: { content: projected } } }).package.document.content;
|
|
66
|
+
const paragraphs = [];
|
|
67
|
+
visitDocxParagraphs({ documentBody: { content: owned } }, (paragraph) => {
|
|
68
|
+
paragraphs.push(paragraph);
|
|
69
|
+
});
|
|
70
|
+
const first = paragraphs.at(0);
|
|
71
|
+
if (first) first.content.unshift(...marks);
|
|
72
|
+
return owned;
|
|
73
|
+
};
|
|
49
74
|
const createNoteEditorManager = (deps) => {
|
|
50
75
|
const mounted = /* @__PURE__ */ new Map();
|
|
51
76
|
let active = null;
|
|
@@ -66,10 +91,16 @@ const createNoteEditorManager = (deps) => {
|
|
|
66
91
|
const sync = () => {
|
|
67
92
|
const host = deps.getHost();
|
|
68
93
|
if (!host) return;
|
|
69
|
-
|
|
94
|
+
if (usesCanonicalSession(deps.getExperimentalSession?.(), CANONICAL_GAP.secondaryStories) && !deps.getCanonicalApi?.()?.getCanonicalStoryProjection(OP_STORIES.MAIN)) return;
|
|
95
|
+
const document = usesCanonicalSession(deps.getExperimentalSession?.(), CANONICAL_GAP.secondaryStories) ? deps.getCanonicalApi?.()?.getCanonicalDocument() ?? deps.getDocument() : deps.getDocument();
|
|
70
96
|
const styles = deps.getStyles();
|
|
71
97
|
const theme = deps.getTheme();
|
|
72
98
|
const numbering = document?.package.numbering;
|
|
99
|
+
const proseOptions = {
|
|
100
|
+
...styles ? { styles } : {},
|
|
101
|
+
...theme !== void 0 ? { theme } : {},
|
|
102
|
+
...numbering !== void 0 ? { numbering } : {}
|
|
103
|
+
};
|
|
73
104
|
const externalPlugins = deps.getPlugins?.() ?? EMPTY_PLUGINS;
|
|
74
105
|
const wanted = new Map(enumerateDocumentNoteStories(document).map((story) => [storyMapKey(story), story]));
|
|
75
106
|
const activeKey = active ? storyMapKey(active) : null;
|
|
@@ -85,7 +116,33 @@ const createNoteEditorManager = (deps) => {
|
|
|
85
116
|
const existing = mounted.get(key);
|
|
86
117
|
if (existing) {
|
|
87
118
|
if (existing.mountNode.parentElement !== host) host.append(existing.mountNode);
|
|
88
|
-
|
|
119
|
+
if (usesCanonicalSession(deps.getExperimentalSession?.(), CANONICAL_GAP.secondaryStories)) {
|
|
120
|
+
const projected = deps.getCanonicalApi?.()?.getCanonicalStoryProjection({
|
|
121
|
+
kind: storyKey.kind,
|
|
122
|
+
id: storyKey.noteId
|
|
123
|
+
});
|
|
124
|
+
if (projected && !existing.view.state.doc.eq(projected)) {
|
|
125
|
+
const transaction = existing.view.state.tr.replaceWith(0, existing.view.state.doc.content.size, projected.content);
|
|
126
|
+
const restored = deps.getCanonicalApi?.()?.getCanonicalStorySelection({
|
|
127
|
+
kind: storyKey.kind,
|
|
128
|
+
id: storyKey.noteId
|
|
129
|
+
});
|
|
130
|
+
const anchor = Math.min(existing.view.state.selection.anchor, projected.content.size);
|
|
131
|
+
transaction.setSelection(restored ? TextSelection.create(transaction.doc, restored.anchor, restored.head) : TextSelection.near(transaction.doc.resolve(anchor)));
|
|
132
|
+
transaction.setMeta("addToHistory", false);
|
|
133
|
+
existing.view.updateState(existing.view.state.apply(transaction));
|
|
134
|
+
}
|
|
135
|
+
existing.appliedNote = note;
|
|
136
|
+
existing.appliedContent = note.content;
|
|
137
|
+
existing.appliedProseDocument = existing.view.state.doc;
|
|
138
|
+
existing.appliedStyles = styles;
|
|
139
|
+
existing.appliedTheme = theme;
|
|
140
|
+
existing.appliedNumbering = numbering;
|
|
141
|
+
existing.appliedPlugins = externalPlugins;
|
|
142
|
+
existing.dirty = false;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const nextProseDocument = noteToProseDocument(note, proseOptions);
|
|
89
146
|
const contextIsCurrent = existing.appliedStyles === styles && existing.appliedTheme === theme && existing.appliedNumbering === numbering && existing.appliedPlugins === externalPlugins;
|
|
90
147
|
if ((existing.appliedNote === note && existing.appliedContent === note.content || existing.appliedProseDocument.eq(nextProseDocument)) && contextIsCurrent) {
|
|
91
148
|
existing.appliedNote = note;
|
|
@@ -111,10 +168,40 @@ const createNoteEditorManager = (deps) => {
|
|
|
111
168
|
mountNode.dataset["noteKind"] = storyKey.kind;
|
|
112
169
|
mountNode.dataset["noteId"] = String(storyKey.noteId);
|
|
113
170
|
host.append(mountNode);
|
|
114
|
-
const proseDocument = noteToProseDocument(note,
|
|
171
|
+
const proseDocument = noteToProseDocument(note, proseOptions);
|
|
172
|
+
const canonical = createCanonicalStoryEditor({
|
|
173
|
+
story: {
|
|
174
|
+
kind: storyKey.kind,
|
|
175
|
+
id: storyKey.noteId
|
|
176
|
+
},
|
|
177
|
+
getView: () => view,
|
|
178
|
+
getApi: () => deps.getCanonicalApi?.() ?? null,
|
|
179
|
+
enabled: () => usesCanonicalSession(deps.getExperimentalSession?.(), CANONICAL_GAP.secondaryStories),
|
|
180
|
+
onRefusal: deps.onSessionRefusal,
|
|
181
|
+
onSelectionChange: () => deps.onTransaction?.({
|
|
182
|
+
...storyKey,
|
|
183
|
+
view,
|
|
184
|
+
docChanged: false,
|
|
185
|
+
selectionChanged: true
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
const canonicalProjection = usesCanonicalSession(deps.getExperimentalSession?.(), CANONICAL_GAP.secondaryStories) ? deps.getCanonicalApi?.()?.getCanonicalStoryProjection({
|
|
189
|
+
kind: storyKey.kind,
|
|
190
|
+
id: storyKey.noteId
|
|
191
|
+
}) : null;
|
|
192
|
+
if (usesCanonicalSession(deps.getExperimentalSession?.(), CANONICAL_GAP.secondaryStories) && !canonicalProjection) {
|
|
193
|
+
manager.destroy();
|
|
194
|
+
mountNode.remove();
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
115
197
|
const view = (deps.createView ?? createEditorView)(mountNode, {
|
|
116
|
-
|
|
198
|
+
...canonical.props,
|
|
199
|
+
state: canonicalProjection ? EditorState.create({
|
|
200
|
+
doc: canonicalProjection,
|
|
201
|
+
plugins: [createDocumentStylesPlugin(styles), createDocumentNumberingPlugin(numbering)]
|
|
202
|
+
}) : buildInitialState(proseDocument, styles, numbering, manager, externalPlugins),
|
|
117
203
|
dispatchTransaction(transaction) {
|
|
204
|
+
if (canonical.dispatch(transaction)) return;
|
|
118
205
|
view.updateState(view.state.apply(transaction));
|
|
119
206
|
const mountedStory = mounted.get(key);
|
|
120
207
|
if (mountedStory && transaction.docChanged) mountedStory.dirty = true;
|
|
@@ -160,6 +247,7 @@ const createNoteEditorManager = (deps) => {
|
|
|
160
247
|
getView: (story) => mounted.get(storyMapKey(story))?.view ?? null,
|
|
161
248
|
listStories: () => enumerateDocumentNoteStories(deps.getDocument()),
|
|
162
249
|
snapshotDocument: (document) => {
|
|
250
|
+
if (usesCanonicalSession(deps.getExperimentalSession?.(), CANONICAL_GAP.secondaryStories)) return deps.getCanonicalApi?.()?.getCanonicalDocument() ?? document;
|
|
163
251
|
let footnotes = document.package.footnotes;
|
|
164
252
|
let endnotes = document.package.endnotes;
|
|
165
253
|
let footnotesChanged = false;
|
|
@@ -169,6 +257,11 @@ const createNoteEditorManager = (deps) => {
|
|
|
169
257
|
if (!story.dirty) continue;
|
|
170
258
|
const lists = storyListNumbering(story.view.state, numbering);
|
|
171
259
|
numbering = lists.numbering;
|
|
260
|
+
const proseOptions = {
|
|
261
|
+
...story.appliedStyles ? { styles: story.appliedStyles } : {},
|
|
262
|
+
...story.appliedTheme !== void 0 ? { theme: story.appliedTheme } : {},
|
|
263
|
+
...numbering !== void 0 ? { numbering } : {}
|
|
264
|
+
};
|
|
172
265
|
if (story.note.kind === "footnote") {
|
|
173
266
|
const index = footnotes?.findIndex(({ id }) => id === story.note.noteId) ?? -1;
|
|
174
267
|
const current = index === -1 ? null : footnotes?.at(index);
|
|
@@ -179,12 +272,15 @@ const createNoteEditorManager = (deps) => {
|
|
|
179
272
|
}
|
|
180
273
|
const updated = {
|
|
181
274
|
...current,
|
|
182
|
-
content:
|
|
275
|
+
content: preserveNoteMarkers({
|
|
276
|
+
source: current.content,
|
|
277
|
+
projected: proseDocToBlocks(lists.doc, current.content, document.package.styles)
|
|
278
|
+
})
|
|
183
279
|
};
|
|
184
280
|
footnotes[index] = updated;
|
|
185
281
|
story.appliedNote = updated;
|
|
186
282
|
story.appliedContent = updated.content;
|
|
187
|
-
story.appliedProseDocument = noteToProseDocument(updated,
|
|
283
|
+
story.appliedProseDocument = noteToProseDocument(updated, proseOptions);
|
|
188
284
|
continue;
|
|
189
285
|
}
|
|
190
286
|
const index = endnotes?.findIndex(({ id }) => id === story.note.noteId) ?? -1;
|
|
@@ -196,12 +292,15 @@ const createNoteEditorManager = (deps) => {
|
|
|
196
292
|
}
|
|
197
293
|
const updated = {
|
|
198
294
|
...current,
|
|
199
|
-
content:
|
|
295
|
+
content: preserveNoteMarkers({
|
|
296
|
+
source: current.content,
|
|
297
|
+
projected: proseDocToBlocks(lists.doc, current.content, document.package.styles)
|
|
298
|
+
})
|
|
200
299
|
};
|
|
201
300
|
endnotes[index] = updated;
|
|
202
301
|
story.appliedNote = updated;
|
|
203
302
|
story.appliedContent = updated.content;
|
|
204
|
-
story.appliedProseDocument = noteToProseDocument(updated,
|
|
303
|
+
story.appliedProseDocument = noteToProseDocument(updated, proseOptions);
|
|
205
304
|
}
|
|
206
305
|
if (!footnotesChanged && !endnotesChanged) return document;
|
|
207
306
|
return {
|
|
@@ -132,6 +132,7 @@ type FolioDocumentOperationIssue = {
|
|
|
132
132
|
code: FolioAIEditSkippedOperation["reason"];
|
|
133
133
|
retryable: boolean;
|
|
134
134
|
recovery: FolioDocumentOperationRecovery;
|
|
135
|
+
canonicalRefusal?: FolioAIEditSkippedOperation["canonicalRefusal"];
|
|
135
136
|
/** The skip's detail, when it has one; see {@link FolioAIEditSkippedOperation.message}. */
|
|
136
137
|
message?: string;
|
|
137
138
|
};
|
|
@@ -264,6 +265,12 @@ type FolioDocumentOperationResult = (FolioDocumentOperationResultBase & {
|
|
|
264
265
|
declare const getFolioDocumentOperationIssues: (operations: readonly FolioDocumentOperation[], skipped: readonly FolioAIEditSkippedOperation[]) => FolioDocumentOperationIssue[];
|
|
265
266
|
/** Build deterministic affected-target receipts from operations and their applied entries. */
|
|
266
267
|
declare const getFolioDocumentOperationReceipts: (operations: readonly FolioDocumentOperation[], applied: readonly FolioAIEditAppliedOperation[]) => FolioDocumentOperationReceipt[];
|
|
268
|
+
type GetFolioDocumentOperationReceiptsForStoryOptions = {
|
|
269
|
+
operations: readonly FolioDocumentOperation[];
|
|
270
|
+
applied: readonly FolioAIEditAppliedOperation[];
|
|
271
|
+
story: FolioDocumentOperationStory;
|
|
272
|
+
};
|
|
273
|
+
declare const getFolioDocumentOperationReceiptsForStory: ({ operations, applied, story }: GetFolioDocumentOperationReceiptsForStoryOptions) => FolioDocumentOperationReceipt[];
|
|
267
274
|
type ApplyFolioDocumentOperationsOptions = {
|
|
268
275
|
view: FolioAIEditView;
|
|
269
276
|
snapshot: FolioAIEditSnapshot;
|
|
@@ -301,4 +308,4 @@ type ApplyFolioDocumentOperationsOptions = {
|
|
|
301
308
|
};
|
|
302
309
|
declare const applyFolioDocumentOperations: ({ view, snapshot, batch, story, author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates, replacementBackground, undefinedStyles }: ApplyFolioDocumentOperationsOptions) => FolioDocumentOperationResult;
|
|
303
310
|
//#endregion
|
|
304
|
-
export { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PAGE_BREAK_CLEAR_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationBatchPrecondition, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationQueuedOperation, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
311
|
+
export { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PAGE_BREAK_CLEAR_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationBatchPrecondition, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationQueuedOperation, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOperationReceiptsForStory, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
@@ -1072,22 +1072,24 @@ const recoveryByReason = {
|
|
|
1072
1072
|
missingStyle: "refreshDocument",
|
|
1073
1073
|
missingNumbering: "refreshDocument",
|
|
1074
1074
|
invalidResult: "refreshDocument",
|
|
1075
|
-
pendingDeletion: "resolveTrackedChange"
|
|
1075
|
+
pendingDeletion: "resolveTrackedChange",
|
|
1076
|
+
pendingParagraphMarkDeletion: "resolveTrackedChange"
|
|
1076
1077
|
};
|
|
1077
1078
|
const getFolioDocumentOperationIssues = (operations, skipped) => {
|
|
1078
1079
|
const indexById = /* @__PURE__ */ new Map();
|
|
1079
1080
|
operations.forEach(({ id }, index) => {
|
|
1080
1081
|
indexById.set(id, index);
|
|
1081
1082
|
});
|
|
1082
|
-
return skipped.map(({ id, reason, message }) => {
|
|
1083
|
+
return skipped.map(({ id, reason, message, canonicalRefusal }) => {
|
|
1083
1084
|
const operationIndex = indexById.get(id) ?? -1;
|
|
1084
1085
|
return {
|
|
1085
1086
|
operationId: id,
|
|
1086
1087
|
operationIndex,
|
|
1087
1088
|
path: `$.operations[${operationIndex}]`,
|
|
1088
1089
|
code: reason,
|
|
1089
|
-
retryable: reason !== "emptyOperation" && reason !== "noopOperation" && reason !== "pendingParagraphPropertyChange" && reason !== "pendingRunPropertyChange" && reason !== "pendingDeletion" && reason !== "payloadDoesNotFit" && reason !== "protectedReference" && reason !== "invalidResult",
|
|
1090
|
+
retryable: reason !== "emptyOperation" && reason !== "noopOperation" && reason !== "pendingParagraphPropertyChange" && reason !== "pendingRunPropertyChange" && reason !== "pendingDeletion" && reason !== "pendingParagraphMarkDeletion" && reason !== "payloadDoesNotFit" && reason !== "protectedReference" && reason !== "invalidResult",
|
|
1090
1091
|
recovery: recoveryByReason[reason],
|
|
1092
|
+
...canonicalRefusal === void 0 ? {} : { canonicalRefusal },
|
|
1091
1093
|
...message !== void 0 && { message }
|
|
1092
1094
|
};
|
|
1093
1095
|
});
|
|
@@ -1468,4 +1470,4 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
1468
1470
|
};
|
|
1469
1471
|
};
|
|
1470
1472
|
//#endregion
|
|
1471
|
-
export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PAGE_BREAK_CLEAR_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
1473
|
+
export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PAGE_BREAK_CLEAR_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOperationReceiptsForStory, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
@@ -55,6 +55,7 @@ const attributeRemainder = ({ element, modelled }) => {
|
|
|
55
55
|
const name = getLocalName(spelling);
|
|
56
56
|
if (modelled.has(name)) continue;
|
|
57
57
|
const namespace = resolveAttributeNamespaceUri(element, spelling);
|
|
58
|
+
if (namespace === OOXML_NAMESPACES.mc.uri && name === "Ignorable") continue;
|
|
58
59
|
if (namespace !== void 0 && !CANONICAL_PREFIX.has(namespace)) continue;
|
|
59
60
|
remainder.push({
|
|
60
61
|
...namespace === void 0 ? {} : { namespace },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
//#region src/docx/blockPlainText.d.ts
|
|
3
|
-
/** One entry per block
|
|
3
|
+
/** One entry per accepted block; deleted breaks and table structure resolve together. */
|
|
4
4
|
declare const collectBlockTexts: (blocks: readonly document_d_exports.BlockContent[]) => string[];
|
|
5
5
|
declare const blockPlainText: (blocks: readonly document_d_exports.BlockContent[]) => string;
|
|
6
6
|
//#endregion
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { projectAcceptedBlocks } from "../internal/acceptedBlockProjection.js";
|
|
1
2
|
import { ALT_CHUNK_READER_DIAGNOSTIC, isAltChunkMarkup } from "./altChunk.js";
|
|
2
3
|
import { OPAQUE_REVISION_CARRIER_READER_DIAGNOSTIC, isOpaqueNestedRowMarkup, opaqueRevisionCarrierName } from "./opaqueCarrier.js";
|
|
3
4
|
import { getParagraphText } from "./paragraphParser.js";
|
|
@@ -18,7 +19,7 @@ import { panic } from "better-result";
|
|
|
18
19
|
* everything below block level and reads the accepted tracked-change view.
|
|
19
20
|
*/
|
|
20
21
|
/** One entry per block, so callers can join or count lines as they need. */
|
|
21
|
-
const
|
|
22
|
+
const collectResolvedBlockTexts = (blocks) => {
|
|
22
23
|
const texts = [];
|
|
23
24
|
for (const block of blocks) switch (block.type) {
|
|
24
25
|
case "paragraph":
|
|
@@ -27,12 +28,12 @@ const collectBlockTexts = (blocks) => {
|
|
|
27
28
|
case "table":
|
|
28
29
|
for (const row of block.rows) {
|
|
29
30
|
if (row.formatting?.hidden === true) continue;
|
|
30
|
-
texts.push(row.cells.map((cell) =>
|
|
31
|
+
texts.push(row.cells.map((cell) => collectResolvedBlockTexts(cell.content).join("\n")).join(" "));
|
|
31
32
|
}
|
|
32
33
|
break;
|
|
33
34
|
case "blockSdt":
|
|
34
35
|
case "blockCustomXml":
|
|
35
|
-
texts.push(...
|
|
36
|
+
texts.push(...collectResolvedBlockTexts(block.content));
|
|
36
37
|
break;
|
|
37
38
|
case "preservedBlock":
|
|
38
39
|
if (isAltChunkMarkup(block.xml)) texts.push(block.readerText === void 0 ? ALT_CHUNK_READER_DIAGNOSTIC : `${ALT_CHUNK_READER_DIAGNOSTIC}\n${block.readerText}`);
|
|
@@ -45,6 +46,13 @@ const collectBlockTexts = (blocks) => {
|
|
|
45
46
|
}
|
|
46
47
|
return texts;
|
|
47
48
|
};
|
|
49
|
+
/** One entry per accepted block; deleted breaks and table structure resolve together. */
|
|
50
|
+
const collectBlockTexts = (blocks) => {
|
|
51
|
+
const projection = projectAcceptedBlocks(blocks, void 0);
|
|
52
|
+
const texts = collectResolvedBlockTexts(projection?.blocks ?? blocks);
|
|
53
|
+
if (projection?.completeness === "partial") texts.push("[Unresolved tracked structural changes]");
|
|
54
|
+
return texts;
|
|
55
|
+
};
|
|
48
56
|
const blockPlainText = (blocks) => collectBlockTexts(blocks).join("\n");
|
|
49
57
|
//#endregion
|
|
50
58
|
export { blockPlainText, collectBlockTexts };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { CANONICAL_GAP } from "../types/canonicalCapabilities.js";
|
|
3
|
+
import { SaveDiagnostic } from "./saveDiagnostics.js";
|
|
4
|
+
//#region src/docx/canonicalResourceSave.d.ts
|
|
5
|
+
declare const CanonicalResourceSaveRefusalError_base: import("better-result").TaggedErrorClass<"CanonicalResourceSaveRefusalError">;
|
|
6
|
+
declare class CanonicalResourceSaveRefusalError extends CanonicalResourceSaveRefusalError_base<{
|
|
7
|
+
message: string;
|
|
8
|
+
gap: typeof CANONICAL_GAP.resourceReplacement;
|
|
9
|
+
diagnostic: Extract<SaveDiagnostic, {
|
|
10
|
+
type: "canonicalResourceReplacement";
|
|
11
|
+
}>;
|
|
12
|
+
}> {}
|
|
13
|
+
/** Full and selective package writers preserve existing style/media source entries. */
|
|
14
|
+
declare const canonicalResourceReplacementOf: (document: document_d_exports.Document) => string | undefined;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { CanonicalResourceSaveRefusalError, canonicalResourceReplacementOf };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
2
|
+
import { getDocumentSourceBaseline } from "./headerFooterVerbatim.js";
|
|
3
|
+
import { TaggedError } from "better-result";
|
|
4
|
+
//#region src/docx/canonicalResourceSave.ts
|
|
5
|
+
var CanonicalResourceSaveRefusalError = class extends TaggedError("CanonicalResourceSaveRefusalError") {};
|
|
6
|
+
/** Full and selective package writers preserve existing style/media source entries. */
|
|
7
|
+
const canonicalResourceReplacementOf = (document) => {
|
|
8
|
+
const source = getDocumentSourceBaseline(document);
|
|
9
|
+
if (source.type !== "captured" || !document.originalBuffer) return void 0;
|
|
10
|
+
const baseline = source.resourceStyles;
|
|
11
|
+
const current = document.package.styles;
|
|
12
|
+
if (baseline) {
|
|
13
|
+
const { styles: sourceStyles, ...sourceDefaults } = baseline;
|
|
14
|
+
const { styles: currentStyles, ...currentDefaults } = current ?? { styles: [] };
|
|
15
|
+
const currentById = new Map(currentStyles.map((style) => [style.styleId, style]));
|
|
16
|
+
if (canonicalJson(sourceDefaults) !== canonicalJson(currentDefaults) || sourceStyles.some((style) => canonicalJson(style) !== canonicalJson(currentById.get(style.styleId)))) return "word/styles.xml";
|
|
17
|
+
}
|
|
18
|
+
for (const [path, media] of source.resourceMedia) {
|
|
19
|
+
const currentMedia = document.package.media?.get(path);
|
|
20
|
+
if (!currentMedia || media.mimeType !== currentMedia.mimeType) return path;
|
|
21
|
+
const sourceBytes = new Uint8Array(media.data);
|
|
22
|
+
const currentBytes = new Uint8Array(currentMedia.data);
|
|
23
|
+
if (sourceBytes.length !== currentBytes.length || sourceBytes.some((byte, index) => byte !== currentBytes[index])) return path;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { CanonicalResourceSaveRefusalError, canonicalResourceReplacementOf };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CANONICAL_GAP } from "../types/canonicalCapabilities.js";
|
|
2
|
+
import { SaveDiagnostic } from "./saveDiagnostics.js";
|
|
3
|
+
import { CanonicalSaveSnapshot } from "../types/canonicalSave.js";
|
|
4
|
+
import { FolioGetDocxOptions } from "../types/docxSerialization.js";
|
|
5
|
+
import { TripwireResult } from "./selectiveSaveTripwire.js";
|
|
6
|
+
import { FolioSelectiveSaveFlags } from "./selectiveSaveFlags.js";
|
|
7
|
+
//#region src/docx/canonicalSave.d.ts
|
|
8
|
+
declare const CanonicalSaveDiagnosticError_base: import("better-result").TaggedErrorClass<"CanonicalSaveDiagnosticError">;
|
|
9
|
+
/** Forward a fidelity fallback through the adapters' existing error channel. */
|
|
10
|
+
declare class CanonicalSaveDiagnosticError extends CanonicalSaveDiagnosticError_base<{
|
|
11
|
+
message: string;
|
|
12
|
+
gap: typeof CANONICAL_GAP.save;
|
|
13
|
+
diagnostic: SaveDiagnostic;
|
|
14
|
+
}> {}
|
|
15
|
+
type SerializeCanonicalSaveOptions = {
|
|
16
|
+
snapshot: CanonicalSaveSnapshot;
|
|
17
|
+
options?: FolioGetDocxOptions | undefined;
|
|
18
|
+
featureFlags?: FolioSelectiveSaveFlags | undefined;
|
|
19
|
+
};
|
|
20
|
+
/** Model and change signals come from one committed snapshot, never from PM. */
|
|
21
|
+
declare const serializeCanonicalSave: ({ snapshot, options, featureFlags }: SerializeCanonicalSaveOptions) => Promise<{
|
|
22
|
+
buffer: ArrayBuffer;
|
|
23
|
+
document: import("@stll/docx-core").Document;
|
|
24
|
+
version: number;
|
|
25
|
+
diagnostics: SaveDiagnostic[];
|
|
26
|
+
tripwireResult: TripwireResult | null;
|
|
27
|
+
}>;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { CanonicalSaveDiagnosticError, serializeCanonicalSave };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { withoutUnreferencedNotes } from "../prosemirror/noteReferenceReview.js";
|
|
2
|
+
import { CANONICAL_GAP } from "../types/canonicalCapabilities.js";
|
|
3
|
+
import { FOLIO_DOCX_SERIALIZATION_MODE } from "../types/docxSerialization.js";
|
|
4
|
+
import { CanonicalResourceSaveRefusalError, canonicalResourceReplacementOf } from "./canonicalResourceSave.js";
|
|
5
|
+
import { repackWithCanonicalStoryRemovals } from "./canonicalStoryRepack.js";
|
|
6
|
+
import { getDocumentSourceBaseline } from "./headerFooterVerbatim.js";
|
|
7
|
+
import { resolveSelectiveSaveFlags } from "./selectiveSaveFlags.js";
|
|
8
|
+
import { Result, TaggedError } from "better-result";
|
|
9
|
+
//#region src/docx/canonicalSave.ts
|
|
10
|
+
/** Forward a fidelity fallback through the adapters' existing error channel. */
|
|
11
|
+
var CanonicalSaveDiagnosticError = class extends TaggedError("CanonicalSaveDiagnosticError") {};
|
|
12
|
+
/** Model and change signals come from one committed snapshot, never from PM. */
|
|
13
|
+
const serializeCanonicalSave = async ({ snapshot, options, featureFlags }) => {
|
|
14
|
+
const document = withoutUnreferencedNotes(snapshot.document);
|
|
15
|
+
const replacementPart = snapshot.structure === "changed" ? canonicalResourceReplacementOf(document) : void 0;
|
|
16
|
+
if (replacementPart) {
|
|
17
|
+
const diagnostic = {
|
|
18
|
+
type: "canonicalResourceReplacement",
|
|
19
|
+
gap: CANONICAL_GAP.resourceReplacement,
|
|
20
|
+
part: replacementPart
|
|
21
|
+
};
|
|
22
|
+
options?.onDiagnostic?.(diagnostic);
|
|
23
|
+
throw new CanonicalResourceSaveRefusalError({
|
|
24
|
+
message: "Canonical save cannot preserve this package resource replacement.",
|
|
25
|
+
gap: CANONICAL_GAP.resourceReplacement,
|
|
26
|
+
diagnostic
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const baseline = document.originalBuffer;
|
|
30
|
+
const flags = resolveSelectiveSaveFlags(featureFlags);
|
|
31
|
+
const diagnostics = [];
|
|
32
|
+
const onDiagnostic = (diagnostic) => {
|
|
33
|
+
if (!diagnostics.some((existing) => existing.type === diagnostic.type && existing.part === diagnostic.part)) diagnostics.push(diagnostic);
|
|
34
|
+
};
|
|
35
|
+
const { repackDocx, createDocx } = await import("./rezip.js");
|
|
36
|
+
const useSelective = flags.selectiveSave && options?.mode !== FOLIO_DOCX_SERIALIZATION_MODE.full;
|
|
37
|
+
let selectiveBuffer = null;
|
|
38
|
+
if (baseline && (useSelective || flags.selectiveSaveTripwire)) {
|
|
39
|
+
const { attemptSelectiveSave } = await import("./selectiveSave.js");
|
|
40
|
+
selectiveBuffer = await attemptSelectiveSave(document, baseline, {
|
|
41
|
+
bodyAuthority: "canonical",
|
|
42
|
+
changedParaIds: new Set(snapshot.changedBlockIds),
|
|
43
|
+
structuralChange: snapshot.structure === "changed",
|
|
44
|
+
hasUntrackedChanges: false,
|
|
45
|
+
maxBytes: flags.selectiveSaveMaxBytes,
|
|
46
|
+
onDiagnostic
|
|
47
|
+
});
|
|
48
|
+
if (useSelective && !selectiveBuffer) onDiagnostic({
|
|
49
|
+
type: "selectiveSaveRefused",
|
|
50
|
+
part: "word/document.xml"
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const repack = () => {
|
|
54
|
+
if (baseline && getDocumentSourceBaseline(document).type === "missing") onDiagnostic({
|
|
55
|
+
type: "sourceReplayUnavailable",
|
|
56
|
+
part: "word/document.xml"
|
|
57
|
+
});
|
|
58
|
+
return baseline ? repackWithCanonicalStoryRemovals({
|
|
59
|
+
document,
|
|
60
|
+
repack: () => repackDocx(document, {
|
|
61
|
+
onDiagnostic,
|
|
62
|
+
bodyAuthority: "canonical"
|
|
63
|
+
})
|
|
64
|
+
}) : createDocx(document, {
|
|
65
|
+
onDiagnostic,
|
|
66
|
+
bodyAuthority: "canonical"
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
let buffer = useSelective ? selectiveBuffer : null;
|
|
70
|
+
let fullBuffer = null;
|
|
71
|
+
if (!buffer) {
|
|
72
|
+
fullBuffer = await repack();
|
|
73
|
+
buffer = fullBuffer;
|
|
74
|
+
} else if (flags.selectiveSaveTripwire) {
|
|
75
|
+
const full = await Result.tryPromise({
|
|
76
|
+
try: repack,
|
|
77
|
+
catch: (error) => error
|
|
78
|
+
});
|
|
79
|
+
if (full.isOk()) fullBuffer = full.value;
|
|
80
|
+
}
|
|
81
|
+
let tripwireResult = null;
|
|
82
|
+
if (flags.selectiveSaveTripwire && fullBuffer) {
|
|
83
|
+
const { compareSelectiveVsFull } = await import("./selectiveSaveTripwire.js");
|
|
84
|
+
const capturedFullBuffer = fullBuffer;
|
|
85
|
+
const compared = await Result.tryPromise({
|
|
86
|
+
try: () => compareSelectiveVsFull(selectiveBuffer, capturedFullBuffer),
|
|
87
|
+
catch: (error) => error
|
|
88
|
+
});
|
|
89
|
+
if (compared.isOk()) tripwireResult = compared.value;
|
|
90
|
+
}
|
|
91
|
+
for (const diagnostic of diagnostics) options?.onDiagnostic?.(diagnostic);
|
|
92
|
+
return {
|
|
93
|
+
buffer,
|
|
94
|
+
document,
|
|
95
|
+
version: snapshot.version,
|
|
96
|
+
diagnostics,
|
|
97
|
+
tripwireResult
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
export { CanonicalSaveDiagnosticError, serializeCanonicalSave };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DocxInput } from "../utils/docxInput.js";
|
|
2
|
+
//#region src/docx/canonicalSessionInput.d.ts
|
|
3
|
+
declare const CanonicalDocxInputError_base: import("better-result").TaggedErrorClass<"CanonicalDocxInputError">;
|
|
4
|
+
declare class CanonicalDocxInputError extends CanonicalDocxInputError_base<{
|
|
5
|
+
message: string;
|
|
6
|
+
cause?: unknown;
|
|
7
|
+
}> {}
|
|
8
|
+
/** Canonical seeding supports plaintext packages; refuse encryption before ZIP normalization. */
|
|
9
|
+
declare const prepareCanonicalDocxInput: (input: DocxInput) => Promise<import("better-result").Err<ArrayBuffer, CanonicalDocxInputError> | import("better-result").Ok<Uint8Array<ArrayBufferLike>, CanonicalDocxInputError>>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { CanonicalDocxInputError, prepareCanonicalDocxInput };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { toArrayBuffer } from "../utils/docxInput.js";
|
|
2
|
+
import { DOCX_CONTAINER_TYPES, detectDocxContainerType } from "./encryption/containerFormat.js";
|
|
3
|
+
import { ensureParaIds } from "./ensureParaIds.js";
|
|
4
|
+
import { Result, TaggedError } from "better-result";
|
|
5
|
+
//#region src/docx/canonicalSessionInput.ts
|
|
6
|
+
var CanonicalDocxInputError = class extends TaggedError("CanonicalDocxInputError") {};
|
|
7
|
+
/** Canonical seeding supports plaintext packages; refuse encryption before ZIP normalization. */
|
|
8
|
+
const prepareCanonicalDocxInput = async (input) => {
|
|
9
|
+
const bytes = await Result.tryPromise({
|
|
10
|
+
try: () => toArrayBuffer(input),
|
|
11
|
+
catch: (cause) => new CanonicalDocxInputError({
|
|
12
|
+
message: "Cannot read canonical document bytes.",
|
|
13
|
+
cause
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
if (bytes.isErr()) return bytes;
|
|
17
|
+
if (detectDocxContainerType(bytes.value) === DOCX_CONTAINER_TYPES.CFB) return Result.err(new CanonicalDocxInputError({ message: "Password-protected documents are unavailable in the experimental canonical session." }));
|
|
18
|
+
return Result.tryPromise({
|
|
19
|
+
try: async () => (await ensureParaIds(bytes.value)).docx,
|
|
20
|
+
catch: (cause) => new CanonicalDocxInputError({
|
|
21
|
+
message: cause instanceof Error ? cause.message : "Canonical document normalization failed.",
|
|
22
|
+
cause
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { CanonicalDocxInputError, prepareCanonicalDocxInput };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
//#region src/docx/canonicalStoryRepack.d.ts
|
|
3
|
+
type CanonicalStoryRepackOptions<T> = {
|
|
4
|
+
document: document_d_exports.Document;
|
|
5
|
+
repack: () => Promise<T>;
|
|
6
|
+
};
|
|
7
|
+
/** Authorize exact canonical section removals and references missing from the committed snapshot. */
|
|
8
|
+
declare const repackWithCanonicalStoryRemovals: <T>({ document, repack }: CanonicalStoryRepackOptions<T>) => Promise<T>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { repackWithCanonicalStoryRemovals };
|