@stll/folio-core 0.52.0 → 0.53.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/README.md +23 -0
- package/dist/ai-edits/apply.d.ts +26 -1
- package/dist/ai-edits/apply.js +1519 -105
- package/dist/ai-edits/batch-claims.d.ts +130 -0
- package/dist/ai-edits/batch-claims.js +244 -0
- package/dist/ai-edits/blockRange.js +9 -3
- package/dist/ai-edits/character-boundaries.d.ts +43 -0
- package/dist/ai-edits/character-boundaries.js +95 -0
- package/dist/ai-edits/clean-text.d.ts +33 -3
- package/dist/ai-edits/clean-text.js +52 -6
- package/dist/ai-edits/comment-lifecycle.d.ts +18 -0
- package/dist/ai-edits/comment-lifecycle.js +52 -0
- package/dist/ai-edits/headless.d.ts +71 -7
- package/dist/ai-edits/headless.js +381 -41
- package/dist/ai-edits/index.d.ts +2 -1
- package/dist/ai-edits/index.js +2 -1
- package/dist/ai-edits/minimal-replacement.d.ts +21 -6
- package/dist/ai-edits/minimal-replacement.js +134 -15
- package/dist/ai-edits/newListNumbering.d.ts +23 -0
- package/dist/ai-edits/newListNumbering.js +94 -0
- package/dist/ai-edits/note-references.d.ts +96 -0
- package/dist/ai-edits/note-references.js +139 -0
- package/dist/ai-edits/pending-suggestions.d.ts +79 -0
- package/dist/ai-edits/pending-suggestions.js +306 -0
- package/dist/ai-edits/read.d.ts +1 -1
- package/dist/ai-edits/read.js +56 -43
- package/dist/ai-edits/result-validation.d.ts +29 -0
- package/dist/ai-edits/result-validation.js +164 -0
- package/dist/ai-edits/snapshot.d.ts +36 -3
- package/dist/ai-edits/snapshot.js +177 -23
- package/dist/ai-edits/table-cell-mutations.d.ts +1 -1
- package/dist/ai-edits/table-cell-mutations.js +4 -1
- package/dist/ai-edits/table-geometry.d.ts +1 -1
- package/dist/ai-edits/table-row-column-mutations.d.ts +38 -16
- package/dist/ai-edits/table-row-column-mutations.js +61 -26
- package/dist/ai-edits/types.d.ts +155 -16
- package/dist/compare/compare.d.ts +1 -1
- package/dist/compare/compare.js +65 -16
- package/dist/compare/content-alignment.js +13 -2
- package/dist/compare/content-types.d.ts +7 -0
- package/dist/compare/content.d.ts +4 -1
- package/dist/compare/content.js +6 -1
- package/dist/compare/formatting.js +2 -1
- package/dist/compare/inline-atoms.d.ts +21 -4
- package/dist/compare/inline-atoms.js +138 -16
- package/dist/compare/plan.js +10 -5
- package/dist/compare/scenario.js +14 -3
- package/dist/compare/section-boundary-properties.js +1 -1
- package/dist/compare/types.d.ts +4 -2
- package/dist/compare/types.js +2 -1
- package/dist/compare/verification.d.ts +1 -1
- package/dist/compare/verification.js +15 -3
- package/dist/controller/committedLayoutDiff.d.ts +25 -0
- package/dist/controller/committedLayoutDiff.js +71 -0
- package/dist/controller/contentControlWidgetController.d.ts +1 -1
- package/dist/controller/folioEditor.d.ts +1 -1
- package/dist/controller/fontReadiness.d.ts +70 -3
- package/dist/controller/fontReadiness.js +100 -10
- package/dist/controller/headerFooterEditorManager.js +6 -1
- package/dist/controller/layoutPipeline.d.ts +12 -10
- package/dist/controller/layoutPipeline.js +62 -9
- package/dist/controller/layoutRunOptions.d.ts +24 -0
- package/dist/controller/layoutRunOptions.js +17 -0
- package/dist/controller/layoutScheduler.d.ts +19 -14
- package/dist/controller/layoutScheduler.js +15 -12
- package/dist/controller/layoutSession.d.ts +26 -2
- package/dist/controller/layoutSession.js +1 -1
- package/dist/controller/noteEditorManager.js +8 -3
- package/dist/document-operations.d.ts +11 -2
- package/dist/document-operations.js +230 -21
- package/dist/docx/altChunk.d.ts +8 -0
- package/dist/docx/altChunk.js +17 -0
- package/dist/docx/attributeRemainder.d.ts +1 -1
- package/dist/docx/blockContentParser.d.ts +64 -1
- package/dist/docx/blockContentParser.js +17 -4
- package/dist/docx/blockCustomXmlShell.d.ts +7 -0
- package/dist/docx/blockCustomXmlShell.js +14 -0
- package/dist/docx/blockPlainText.js +7 -0
- package/dist/docx/commentAnchorIndex.js +1 -1
- package/dist/docx/commentRangeIntegrity.js +8 -3
- package/dist/docx/commentReferenceNormalization.js +1 -1
- package/dist/docx/commentReplyMarkers.js +20 -1
- package/dist/docx/compatibility.d.ts +1 -1
- package/dist/docx/compatibility.js +34 -13
- package/dist/docx/containerChildren.gen.d.ts +1 -1
- package/dist/docx/containerChildren.gen.js +1 -0
- package/dist/docx/documentParser.js +12 -12
- package/dist/docx/drawingIdNormalization.d.ts +3 -1
- package/dist/docx/drawingIdNormalization.js +6 -1
- package/dist/docx/ensureParaIds.js +119 -97
- package/dist/docx/footnoteParser.js +8 -4
- package/dist/docx/headerFooterParser.js +3 -3
- package/dist/docx/headerFooterReferenceNormalization.d.ts +20 -1
- package/dist/docx/headerFooterReferenceNormalization.js +52 -27
- package/dist/docx/hyperlinkParser.d.ts +1 -1
- package/dist/docx/index.d.ts +1 -1
- package/dist/docx/listNumberingInstances.d.ts +59 -0
- package/dist/docx/listNumberingInstances.js +249 -0
- package/dist/docx/normalizeBaseDirection.js +2 -1
- package/dist/docx/opaqueCarrier.d.ts +7 -0
- package/dist/docx/opaqueCarrier.js +38 -0
- package/dist/docx/packageParts.js +4 -1
- package/dist/docx/paragraphParser.js +91 -24
- package/dist/docx/paragraphPropertySource.d.ts +4 -2
- package/dist/docx/paragraphPropertySource.js +7 -1
- package/dist/docx/paragraphTraversal.js +1 -0
- package/dist/docx/parseWarningMessage.js +4 -1
- package/dist/docx/parser.js +173 -20
- package/dist/docx/rezip.js +27 -5
- package/dist/docx/sdtProperties.js +1 -1
- package/dist/docx/sdtPropertiesPatch.js +3 -0
- package/dist/docx/selectiveSave.js +16 -9
- package/dist/docx/selectiveXmlPatch.js +106 -37
- package/dist/docx/serializer/blockCustomXmlSerializer.d.ts +5 -0
- package/dist/docx/serializer/blockCustomXmlSerializer.js +4 -0
- package/dist/docx/serializer/documentSerializer.js +2 -0
- package/dist/docx/serializer/headerFooterSerializer.js +2 -0
- package/dist/docx/serializer/noteSerializer.js +3 -1
- package/dist/docx/serializer/paragraphSerializer.js +33 -9
- package/dist/docx/serializer/tableSerializer.js +25 -38
- package/dist/docx/server/createBilingualDocument.js +3 -3
- package/dist/docx/tableParser.d.ts +157 -1
- package/dist/docx/tableParser.js +89 -10
- package/dist/docx/textBoxParser.js +1 -1
- package/dist/docx/unzip.d.ts +2 -1
- package/dist/docx/unzip.js +1 -1
- package/dist/docx/wordprocessingPrefixes.d.ts +78 -0
- package/dist/docx/wordprocessingPrefixes.js +286 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +136 -0
- package/dist/i18n/messages/catalogs.gen.js +153 -17
- package/dist/i18n/messages/messages.gen.d.ts +8 -0
- package/dist/internal/compare/inline-presentation.d.ts +2 -1
- package/dist/internal/compare/inline-presentation.js +11 -10
- package/dist/internal/headlessRevisionResolutionGuard.d.ts +2 -8
- package/dist/internal/headlessRevisionResolutionGuard.js +2 -11
- package/dist/internal/indexedPositionMap.d.ts +11 -0
- package/dist/internal/indexedPositionMap.js +42 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +2 -1
- package/dist/internal/revisionResolutionEdits.d.ts +13 -0
- package/dist/internal/revisionResolutionEdits.js +19 -0
- package/dist/internal/revisionResolutionInline.d.ts +24 -0
- package/dist/internal/{headlessRevisionResolution.js → revisionResolutionInline.js} +61 -43
- package/dist/internal/revisionResolutionStep.d.ts +34 -0
- package/dist/internal/revisionResolutionStep.js +282 -0
- package/dist/internal/revisionResolutionTracking.d.ts +11 -0
- package/dist/internal/revisionResolutionTracking.js +124 -0
- package/dist/internal/wholeStoryRevisionResolution.d.ts +56 -0
- package/dist/internal/wholeStoryRevisionResolution.js +530 -0
- package/dist/layout-bridge/convert/markupViewFlow.d.ts +20 -0
- package/dist/layout-bridge/convert/markupViewFlow.js +123 -0
- package/dist/layout-bridge/convert/tableConversion.js +1 -1
- package/dist/layout-bridge/convert/toFlowBlocks.js +10 -1
- package/dist/layout-engine/layoutInstrumentation.d.ts +9 -1
- package/dist/layout-engine/layoutInstrumentation.js +4 -1
- package/dist/layout-engine/measure/cache.d.ts +18 -1
- package/dist/layout-engine/measure/cache.js +31 -1
- package/dist/layout-engine/measure/font-metrics.worker.js +3 -7
- package/dist/layout-engine/measure/measureContainer.js +7 -47
- package/dist/layout-engine/measure/measureHelpers.d.ts +6 -1
- package/dist/layout-engine/measure/measureHelpers.js +22 -2
- package/dist/layout-engine/measure/measureWorker.js +2 -3
- package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +6 -7
- package/dist/layout-engine/measure/measureWorkerProtocol.js +1 -2
- package/dist/layout-engine/types.d.ts +6 -0
- package/dist/layout-painter/renderPage.js +1 -0
- package/dist/layout-painter/renderParagraph.js +1 -1
- package/dist/managers/ContextMenuManager.js +5 -2
- package/dist/managers/types.d.ts +3 -0
- package/dist/markdown/fromMarkdown.js +2 -1
- package/dist/markdown/internals.d.ts +11 -1
- package/dist/markdown/internals.js +24 -3
- package/dist/markdown/renderBlock.js +39 -9
- package/dist/markdown/renderParagraph.d.ts +13 -1
- package/dist/markdown/renderParagraph.js +85 -38
- package/dist/markdown/renderRuns.js +3 -10
- package/dist/markdown/renderTable.js +24 -12
- package/dist/markdown/trailers.js +2 -2
- package/dist/markdown/types.d.ts +29 -7
- package/dist/paged-layout/incrementalMeasure.d.ts +1 -2
- package/dist/paged-layout/incrementalMeasure.js +1 -9
- package/dist/paged-layout/transactionDirtyRange.d.ts +1 -3
- package/dist/paged-layout/transactionDirtyRange.js +29 -41
- package/dist/panel-layout.d.ts +83 -0
- package/dist/panel-layout.js +96 -0
- package/dist/prosemirror/anchoredTextBoxes.d.ts +37 -0
- package/dist/prosemirror/anchoredTextBoxes.js +156 -0
- package/dist/prosemirror/attrs/index.d.ts +6 -2
- package/dist/prosemirror/attrs/index.js +172 -1
- package/dist/prosemirror/commands/comments.d.ts +7 -8
- package/dist/prosemirror/commands/comments.js +241 -207
- package/dist/prosemirror/commands/contentControls.d.ts +1 -1
- package/dist/prosemirror/commands/formatPainter.d.ts +1 -1
- package/dist/prosemirror/commands/formatting.d.ts +1 -1
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/index.js +2 -2
- package/dist/prosemirror/commands/paragraph.d.ts +7 -1
- package/dist/prosemirror/commands/paragraph.js +9 -1
- package/dist/prosemirror/commands/paragraphBookmarkJoin.d.ts +13 -0
- package/dist/prosemirror/commands/paragraphBookmarkJoin.js +22 -0
- package/dist/prosemirror/commands/pastePlainText.d.ts +1 -1
- package/dist/prosemirror/commands/resolveAllTableChanges.d.ts +40 -0
- package/dist/prosemirror/commands/resolveAllTableChanges.js +615 -0
- package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.d.ts +15 -0
- package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.js +46 -0
- package/dist/prosemirror/commands/resolveParagraphProperties.d.ts +16 -0
- package/dist/prosemirror/commands/resolveParagraphProperties.js +59 -0
- package/dist/prosemirror/commands/sectionBreak.js +2 -1
- package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +8 -2
- package/dist/prosemirror/commands/tableCellMergeResolution.js +1 -1
- package/dist/prosemirror/contentControlRevisions.d.ts +1 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +181 -31
- package/dist/prosemirror/conversion/toProseDoc.js +39 -4
- package/dist/prosemirror/emptyFieldResultRuns.d.ts +18 -0
- package/dist/prosemirror/emptyFieldResultRuns.js +33 -0
- package/dist/prosemirror/extensions/ExtensionManager.d.ts +1 -1
- package/dist/prosemirror/extensions/ExtensionManager.js +3 -1
- package/dist/prosemirror/extensions/StarterKit.js +3 -1
- package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -0
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +3 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +161 -123
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +19 -2
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +33 -20
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +31 -2
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +270 -99
- package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +3 -2
- package/dist/prosemirror/extensions/features/pasteCleanup.js +2 -1
- package/dist/prosemirror/extensions/features/pastedHtmlLists.d.ts +12 -0
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +126 -0
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +21 -5
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +21 -18
- package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +37 -17
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +7 -2
- package/dist/prosemirror/extensions/marks/markUtils.js +8 -2
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +10 -0
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +35 -0
- package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.js +52 -0
- package/dist/prosemirror/extensions/nodes/FieldExtension.d.ts +3 -3
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +50 -15
- package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +4 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +1 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +19 -18
- package/dist/prosemirror/extensions/types.d.ts +4 -1
- package/dist/prosemirror/findReplaceSelection.js +1 -1
- package/dist/prosemirror/index.d.ts +3 -2
- package/dist/prosemirror/index.js +3 -2
- package/dist/prosemirror/indexedNodeLookup.d.ts +17 -0
- package/dist/prosemirror/indexedNodeLookup.js +103 -0
- package/dist/prosemirror/listAutoformatMarkers.d.ts +19 -0
- package/dist/prosemirror/listAutoformatMarkers.js +98 -0
- package/dist/prosemirror/listInstanceReferences.d.ts +12 -0
- package/dist/prosemirror/listInstanceReferences.js +72 -0
- package/dist/prosemirror/listLabels.d.ts +24 -0
- package/dist/prosemirror/listLabels.js +111 -0
- package/dist/prosemirror/listNumbering.d.ts +110 -0
- package/dist/prosemirror/listNumbering.js +345 -0
- package/dist/prosemirror/listRenderingAttrs.d.ts +11 -2
- package/dist/prosemirror/listRenderingAttrs.js +8 -1
- package/dist/prosemirror/markupViewProjection.d.ts +95 -0
- package/dist/prosemirror/markupViewProjection.js +83 -0
- package/dist/prosemirror/numberingAttr.d.ts +9 -1
- package/dist/prosemirror/numberingAttr.js +9 -1
- package/dist/prosemirror/outlineLevelAttr.js +1 -1
- package/dist/prosemirror/paragraphIndentation.d.ts +10 -1
- package/dist/prosemirror/paragraphIndentation.js +29 -7
- package/dist/prosemirror/paragraphMarkJoin.d.ts +19 -0
- package/dist/prosemirror/paragraphMarkJoin.js +24 -0
- package/dist/prosemirror/plugins/createDocScanPlugin.d.ts +1 -1
- package/dist/prosemirror/plugins/documentNumbering.d.ts +27 -1
- package/dist/prosemirror/plugins/documentNumbering.js +97 -11
- package/dist/prosemirror/plugins/documentStyles.d.ts +10 -1
- package/dist/prosemirror/plugins/documentStyles.js +14 -1
- package/dist/prosemirror/plugins/suggestionMode.d.ts +16 -2
- package/dist/prosemirror/plugins/suggestionMode.js +116 -52
- package/dist/prosemirror/plugins/templateDirectives.d.ts +1 -1
- package/dist/prosemirror/plugins/transactionInvariants.d.ts +32 -0
- package/dist/prosemirror/plugins/transactionInvariants.js +86 -0
- package/dist/prosemirror/positionSweep.d.ts +24 -0
- package/dist/prosemirror/positionSweep.js +222 -0
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +1 -1
- package/dist/prosemirror/rejoinRunCarriers.d.ts +1 -1
- package/dist/prosemirror/replacedAnnotations.d.ts +33 -1
- package/dist/prosemirror/replacedAnnotations.js +170 -1
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +1 -1
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/index.js +3 -0
- package/dist/prosemirror/schema/nodes.d.ts +42 -11
- package/dist/prosemirror/sectionMarkEdits.d.ts +20 -0
- package/dist/prosemirror/sectionMarkEdits.js +59 -0
- package/dist/prosemirror/storyListNumbering.d.ts +17 -0
- package/dist/prosemirror/storyListNumbering.js +102 -0
- package/dist/prosemirror/tableGridMutation.d.ts +48 -2
- package/dist/prosemirror/tableGridMutation.js +106 -1
- package/dist/prosemirror/validation.js +5 -1
- package/dist/redline.js +93 -9
- package/dist/render-dom/BodySelectionOverlay.d.ts +4 -1
- package/dist/render-dom/BodySelectionOverlay.js +3 -2
- package/dist/utils/findReplace.js +2 -2
- package/dist/utils/mergeDocumentContent.js +1 -1
- package/dist/utils/noteReferenceLabels.d.ts +36 -0
- package/dist/utils/noteReferenceLabels.js +32 -0
- package/dist/utils/replaceText.js +1 -1
- package/dist/version-comparison.d.ts +1 -0
- package/dist/version-comparison.js +1 -0
- package/package.json +3 -2
- package/dist/internal/headlessRevisionResolution.d.ts +0 -23
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { applyFolioAIEditOperations,
|
|
1
|
+
import { applyFolioAIEditOperations, previewFolioAIEditOperationsWithResult } from "./ai-edits/apply.js";
|
|
2
|
+
import { describeModelError, findIntroducedModelErrors } from "./ai-edits/result-validation.js";
|
|
3
|
+
import { LIST_KINDS } from "./docx/listNumberingInstances.js";
|
|
2
4
|
import { isNumberingReference } from "./docx/numberingReference.js";
|
|
5
|
+
import { completeNumberingForDoc } from "./prosemirror/listInstanceReferences.js";
|
|
6
|
+
import { outlineLevelFromAttrValue } from "./prosemirror/outlineLevelAttr.js";
|
|
7
|
+
import { getStatedDocumentNumbering } from "./prosemirror/plugins/documentNumbering.js";
|
|
3
8
|
import { LINE_SPACING_RULE_VALUES, PARAGRAPH_ALIGNMENT_VALUES } from "./types/documentEnumValues.js";
|
|
4
9
|
import { TaggedError } from "better-result";
|
|
5
10
|
import { sanitizeXmlCharacters } from "@stll/docx-core";
|
|
@@ -293,11 +298,40 @@ const readClearableParagraphIndentation = ({ value, key, path }) => {
|
|
|
293
298
|
}
|
|
294
299
|
return indentation;
|
|
295
300
|
};
|
|
301
|
+
/** `w:ilvl` names one of an abstract numbering's nine levels. */
|
|
302
|
+
const MAX_NEW_LIST_LEVEL = 8;
|
|
303
|
+
const LIST_KIND_SET = new Set(LIST_KINDS);
|
|
304
|
+
const isListKind = (value) => LIST_KIND_SET.has(value);
|
|
305
|
+
/** `{ start: "new", kind, level? }`: a list the operation starts. */
|
|
306
|
+
const readNewListReference = (candidate, numberingPath) => {
|
|
307
|
+
assertAllowedKeys(candidate, numberingPath, [
|
|
308
|
+
"start",
|
|
309
|
+
"kind",
|
|
310
|
+
"level"
|
|
311
|
+
]);
|
|
312
|
+
const kind = candidate["kind"];
|
|
313
|
+
if (typeof kind !== "string" || !isListKind(kind)) return invalidBatch(`${numberingPath}.kind`, `expected one of ${LIST_KINDS.join(", ")}`);
|
|
314
|
+
if (candidate["level"] === void 0) return {
|
|
315
|
+
start: "new",
|
|
316
|
+
kind
|
|
317
|
+
};
|
|
318
|
+
const level = readNonNegativeInteger(candidate, "level", numberingPath);
|
|
319
|
+
if (level > MAX_NEW_LIST_LEVEL) return invalidBatch(`${numberingPath}.level`, `expected at most ${MAX_NEW_LIST_LEVEL}`);
|
|
320
|
+
return {
|
|
321
|
+
start: "new",
|
|
322
|
+
kind,
|
|
323
|
+
level
|
|
324
|
+
};
|
|
325
|
+
};
|
|
296
326
|
const readClearableNumbering = ({ value, key, path }) => {
|
|
297
327
|
const candidate = value[key];
|
|
298
328
|
if (candidate === void 0 || candidate === null) return candidate;
|
|
299
329
|
const numberingPath = `${path}.${key}`;
|
|
300
330
|
if (!isPlainObject(candidate)) return invalidBatch(numberingPath, "expected an object or null when provided");
|
|
331
|
+
if (candidate["start"] !== void 0) {
|
|
332
|
+
if (candidate["start"] !== "new") return invalidBatch(`${numberingPath}.start`, "expected \"new\"");
|
|
333
|
+
return readNewListReference(candidate, numberingPath);
|
|
334
|
+
}
|
|
301
335
|
assertAllowedKeys(candidate, numberingPath, ["numId", "level"]);
|
|
302
336
|
const numId = readNonNegativeInteger(candidate, "numId", numberingPath);
|
|
303
337
|
if (!isNumberingReference(numId)) return invalidBatch(`${numberingPath}.numId`, "expected a positive integer");
|
|
@@ -326,12 +360,22 @@ const readTableRows = (value, path) => {
|
|
|
326
360
|
if (parsed.some((row) => row.length !== width)) return invalidBatch(rowsPath, "expected every row to hold the same number of cells");
|
|
327
361
|
return parsed;
|
|
328
362
|
};
|
|
363
|
+
const readClearableOutlineLevel = (value, path) => {
|
|
364
|
+
const candidate = value["outlineLevel"];
|
|
365
|
+
if (candidate === void 0 || candidate === null) return candidate;
|
|
366
|
+
if (!isPlainObject(candidate)) return invalidBatch(`${path}.outlineLevel`, "expected an outline level");
|
|
367
|
+
assertAllowedKeys(candidate, `${path}.outlineLevel`, ["kind", "level"]);
|
|
368
|
+
const outlineLevel = outlineLevelFromAttrValue(candidate);
|
|
369
|
+
if (outlineLevel === null) return invalidBatch(`${path}.outlineLevel`, "expected a valid outline level");
|
|
370
|
+
return outlineLevel;
|
|
371
|
+
};
|
|
329
372
|
const readParagraphProperties = ({ value, key, path }) => {
|
|
330
373
|
const candidate = value[key];
|
|
331
374
|
const propertiesPath = `${path}.${key}`;
|
|
332
375
|
if (!isPlainObject(candidate)) return invalidBatch(propertiesPath, "expected an object");
|
|
333
376
|
assertAllowedKeys(candidate, propertiesPath, [
|
|
334
377
|
"styleId",
|
|
378
|
+
"outlineLevel",
|
|
335
379
|
"listLevel",
|
|
336
380
|
"numbering",
|
|
337
381
|
"alignment",
|
|
@@ -339,6 +383,7 @@ const readParagraphProperties = ({ value, key, path }) => {
|
|
|
339
383
|
"indentation"
|
|
340
384
|
]);
|
|
341
385
|
const styleId = candidate["styleId"] === null ? null : readOptionalString(candidate, "styleId", propertiesPath);
|
|
386
|
+
const outlineLevel = readClearableOutlineLevel(candidate, propertiesPath);
|
|
342
387
|
const listLevel = readClearableNonNegativeInteger(candidate, "listLevel", propertiesPath);
|
|
343
388
|
const numbering = readClearableNumbering({
|
|
344
389
|
value: candidate,
|
|
@@ -360,9 +405,10 @@ const readParagraphProperties = ({ value, key, path }) => {
|
|
|
360
405
|
key: "indentation",
|
|
361
406
|
path: propertiesPath
|
|
362
407
|
});
|
|
363
|
-
if (styleId === void 0 && listLevel === void 0 && numbering === void 0 && alignment === void 0 && spacing === void 0 && indentation === void 0) return invalidBatch(propertiesPath, "expected at least one property to set");
|
|
408
|
+
if (styleId === void 0 && outlineLevel === void 0 && listLevel === void 0 && numbering === void 0 && alignment === void 0 && spacing === void 0 && indentation === void 0) return invalidBatch(propertiesPath, "expected at least one property to set");
|
|
364
409
|
return {
|
|
365
410
|
...styleId !== void 0 && { styleId },
|
|
411
|
+
...outlineLevel !== void 0 && { outlineLevel },
|
|
366
412
|
...listLevel !== void 0 && { listLevel },
|
|
367
413
|
...numbering !== void 0 && { numbering },
|
|
368
414
|
...alignment !== void 0 && { alignment },
|
|
@@ -515,6 +561,7 @@ const OPERATION_KEY_DECISIONS = {
|
|
|
515
561
|
pageBreakBefore: true,
|
|
516
562
|
hardPageBreak: true,
|
|
517
563
|
styleId: true,
|
|
564
|
+
outlineLevel: true,
|
|
518
565
|
comment: true
|
|
519
566
|
},
|
|
520
567
|
insertBeforeBlock: {
|
|
@@ -532,6 +579,7 @@ const OPERATION_KEY_DECISIONS = {
|
|
|
532
579
|
pageBreakBefore: true,
|
|
533
580
|
hardPageBreak: true,
|
|
534
581
|
styleId: true,
|
|
582
|
+
outlineLevel: true,
|
|
535
583
|
comment: true
|
|
536
584
|
},
|
|
537
585
|
replaceBlock: {
|
|
@@ -783,6 +831,7 @@ const parseDocumentOperation = (value, index) => {
|
|
|
783
831
|
const pageBreakBefore = readOptionalBoolean(value, "pageBreakBefore", path);
|
|
784
832
|
const hardPageBreak = readOptionalHardPageBreak(value, path);
|
|
785
833
|
const styleId = value["styleId"] === null ? null : readOptionalString(value, "styleId", path);
|
|
834
|
+
const outlineLevel = readClearableOutlineLevel(value, path);
|
|
786
835
|
const moveId = readOptionalString(value, "moveId", path);
|
|
787
836
|
const listLevel = readClearableNonNegativeInteger(value, "listLevel", path);
|
|
788
837
|
const numbering = readClearableNumbering({
|
|
@@ -810,7 +859,7 @@ const parseDocumentOperation = (value, index) => {
|
|
|
810
859
|
const formattingScope = value["formattingScope"];
|
|
811
860
|
if (formattingScope !== void 0 && formattingScope !== "firstParagraph" && formattingScope !== "allParagraphs") return invalidBatch(`${path}.formattingScope`, "expected \"firstParagraph\" or \"allParagraphs\" when provided");
|
|
812
861
|
const text = readString(value, "text", path);
|
|
813
|
-
if (hardPageBreak !== void 0 && text.length > 0) return invalidBatch(`${path}.text`, "
|
|
862
|
+
if (hardPageBreak !== void 0 && text.length > 0) return invalidBatch(`${path}.text`, "omit hardPageBreak to insert text, or set text to \"\" to insert a hard page break");
|
|
814
863
|
if (hardPageBreak !== void 0 && pageBreakBefore !== void 0) return invalidBatch(`${path}.pageBreakBefore`, "cannot combine hardPageBreak with pageBreakBefore");
|
|
815
864
|
if (hardPageBreak !== void 0 && lineBreakMode !== void 0) return invalidBatch(`${path}.lineBreakMode`, "cannot combine hardPageBreak with lineBreakMode");
|
|
816
865
|
return {
|
|
@@ -831,6 +880,7 @@ const parseDocumentOperation = (value, index) => {
|
|
|
831
880
|
...pageBreakBefore !== void 0 && { pageBreakBefore },
|
|
832
881
|
...hardPageBreak !== void 0 && { hardPageBreak },
|
|
833
882
|
...styleId !== void 0 && { styleId },
|
|
883
|
+
...outlineLevel !== void 0 && { outlineLevel },
|
|
834
884
|
...comment !== void 0 && { comment }
|
|
835
885
|
};
|
|
836
886
|
}
|
|
@@ -1014,22 +1064,31 @@ const recoveryByReason = {
|
|
|
1014
1064
|
pendingRunPropertyChange: "resolveTrackedChange",
|
|
1015
1065
|
noopOperation: "removeOperation",
|
|
1016
1066
|
documentVersionMismatch: "refreshDocument",
|
|
1017
|
-
documentNotEditable: "retryLater"
|
|
1067
|
+
documentNotEditable: "retryLater",
|
|
1068
|
+
payloadDoesNotFit: "changeTarget",
|
|
1069
|
+
overlappingOperation: "refreshDocument",
|
|
1070
|
+
splitsCharacter: "changeTarget",
|
|
1071
|
+
protectedReference: "narrowMatch",
|
|
1072
|
+
missingStyle: "refreshDocument",
|
|
1073
|
+
missingNumbering: "refreshDocument",
|
|
1074
|
+
invalidResult: "refreshDocument",
|
|
1075
|
+
pendingDeletion: "resolveTrackedChange"
|
|
1018
1076
|
};
|
|
1019
1077
|
const getFolioDocumentOperationIssues = (operations, skipped) => {
|
|
1020
1078
|
const indexById = /* @__PURE__ */ new Map();
|
|
1021
1079
|
operations.forEach(({ id }, index) => {
|
|
1022
1080
|
indexById.set(id, index);
|
|
1023
1081
|
});
|
|
1024
|
-
return skipped.map(({ id, reason }) => {
|
|
1082
|
+
return skipped.map(({ id, reason, message }) => {
|
|
1025
1083
|
const operationIndex = indexById.get(id) ?? -1;
|
|
1026
1084
|
return {
|
|
1027
1085
|
operationId: id,
|
|
1028
1086
|
operationIndex,
|
|
1029
1087
|
path: `$.operations[${operationIndex}]`,
|
|
1030
1088
|
code: reason,
|
|
1031
|
-
retryable: reason !== "emptyOperation" && reason !== "noopOperation" && reason !== "pendingParagraphPropertyChange" && reason !== "pendingRunPropertyChange",
|
|
1032
|
-
recovery: recoveryByReason[reason]
|
|
1089
|
+
retryable: reason !== "emptyOperation" && reason !== "noopOperation" && reason !== "pendingParagraphPropertyChange" && reason !== "pendingRunPropertyChange" && reason !== "pendingDeletion" && reason !== "payloadDoesNotFit" && reason !== "protectedReference" && reason !== "invalidResult",
|
|
1090
|
+
recovery: recoveryByReason[reason],
|
|
1091
|
+
...message !== void 0 && { message }
|
|
1033
1092
|
};
|
|
1034
1093
|
});
|
|
1035
1094
|
};
|
|
@@ -1183,26 +1242,173 @@ const getFolioDocumentOperationReceiptsForStory = ({ operations, applied, story
|
|
|
1183
1242
|
});
|
|
1184
1243
|
return receipts;
|
|
1185
1244
|
};
|
|
1186
|
-
const
|
|
1245
|
+
const NO_COMMIT = () => {};
|
|
1246
|
+
/** Skips reported in the order of the operations they belong to. */
|
|
1247
|
+
const inOperationOrder = (operations, skipped) => {
|
|
1248
|
+
const indexById = new Map(operations.map(({ id }, index) => [id, index]));
|
|
1249
|
+
return [...skipped].sort((left, right) => (indexById.get(left.id) ?? -1) - (indexById.get(right.id) ?? -1));
|
|
1250
|
+
};
|
|
1251
|
+
const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates, replacementBackground, undefinedStyles }) => {
|
|
1187
1252
|
const parsedBatch = parseFolioDocumentOperationBatch(batch);
|
|
1188
|
-
const
|
|
1189
|
-
|
|
1190
|
-
|
|
1253
|
+
const isAtomic = parsedBatch.atomic === true;
|
|
1254
|
+
const beforeDoc = view.state.doc;
|
|
1255
|
+
const packageNumbering = getStatedDocumentNumbering(view.state);
|
|
1256
|
+
const attempt = (operations, preview) => {
|
|
1257
|
+
const common = {
|
|
1191
1258
|
snapshot,
|
|
1192
|
-
operations
|
|
1259
|
+
operations,
|
|
1193
1260
|
mode: parsedBatch.mode ?? "tracked-changes",
|
|
1194
1261
|
...author !== void 0 && { author },
|
|
1195
|
-
...targetCreateCommentId !== void 0 && { createCommentId: targetCreateCommentId },
|
|
1196
1262
|
...revisionStamp !== void 0 && { revisionStamp },
|
|
1197
1263
|
...wordDiff !== void 0 && { wordDiff },
|
|
1198
1264
|
...tableTemplates !== void 0 && { tableTemplates },
|
|
1199
|
-
...replacementBackground !== void 0 && { replacementBackground }
|
|
1265
|
+
...replacementBackground !== void 0 && { replacementBackground },
|
|
1266
|
+
...undefinedStyles !== void 0 && { undefinedStyles }
|
|
1267
|
+
};
|
|
1268
|
+
if (preview) return {
|
|
1269
|
+
...previewFolioAIEditOperationsWithResult({
|
|
1270
|
+
...common,
|
|
1271
|
+
view,
|
|
1272
|
+
...createCommentId !== void 0 && { createCommentId }
|
|
1273
|
+
}),
|
|
1274
|
+
commit: NO_COMMIT
|
|
1275
|
+
};
|
|
1276
|
+
const held = {};
|
|
1277
|
+
const commentIds = [];
|
|
1278
|
+
return {
|
|
1279
|
+
outcome: applyFolioAIEditOperations({
|
|
1280
|
+
...common,
|
|
1281
|
+
view: {
|
|
1282
|
+
state: view.state,
|
|
1283
|
+
dispatch: (transaction) => {
|
|
1284
|
+
held.transaction = transaction;
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
...createCommentId !== void 0 && { createCommentId: (text) => {
|
|
1288
|
+
const id = createCommentId(text);
|
|
1289
|
+
commentIds.push(id);
|
|
1290
|
+
return id;
|
|
1291
|
+
} }
|
|
1292
|
+
}),
|
|
1293
|
+
doc: held.transaction?.doc ?? null,
|
|
1294
|
+
commentIds,
|
|
1295
|
+
commit: () => {
|
|
1296
|
+
if (held.transaction !== void 0) view.dispatch(held.transaction);
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
};
|
|
1300
|
+
const introducedErrors = (run) => {
|
|
1301
|
+
if (run.doc === null || run.outcome.applied.length === 0) return [];
|
|
1302
|
+
const numbering = packageNumbering === void 0 ? void 0 : completeNumberingForDoc(packageNumbering ?? void 0, run.doc) ?? null;
|
|
1303
|
+
return findIntroducedModelErrors(beforeDoc, run.doc, {
|
|
1304
|
+
numbering,
|
|
1305
|
+
createdCommentIds: run.commentIds,
|
|
1306
|
+
...author !== void 0 && { commentAuthor: author }
|
|
1200
1307
|
});
|
|
1201
1308
|
};
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1309
|
+
/**
|
|
1310
|
+
* An attempt on the refusal path, where the applier runs on subsets of the
|
|
1311
|
+
* batch it was not asked to apply: a throw there is one more reason to
|
|
1312
|
+
* refuse, never a reason to fail a batch the first run could apply.
|
|
1313
|
+
*/
|
|
1314
|
+
const checkedAttempt = (operations, preview) => {
|
|
1315
|
+
try {
|
|
1316
|
+
const run = attempt(operations, preview);
|
|
1317
|
+
return {
|
|
1318
|
+
run,
|
|
1319
|
+
error: introducedErrors(run)[0]
|
|
1320
|
+
};
|
|
1321
|
+
} catch (error) {
|
|
1322
|
+
return {
|
|
1323
|
+
run: null,
|
|
1324
|
+
error: {
|
|
1325
|
+
path: "package.document",
|
|
1326
|
+
message: `the operation could not be applied (${error instanceof Error ? error.message : String(error)}).`,
|
|
1327
|
+
severity: "error"
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
/**
|
|
1333
|
+
* Which applied operations produced the unsaveable result: each one is
|
|
1334
|
+
* previewed alone against the unchanged story. When none fails alone, the
|
|
1335
|
+
* failure is their combination, and every one of them is refused.
|
|
1336
|
+
*/
|
|
1337
|
+
const refuseInvalidResult = (run, firstError) => {
|
|
1338
|
+
const operationsById = new Map(parsedBatch.operations.map((operation) => [operation.id, operation]));
|
|
1339
|
+
const refused = [];
|
|
1340
|
+
for (const { id } of run.outcome.applied) {
|
|
1341
|
+
const operation = operationsById.get(id);
|
|
1342
|
+
if (operation === void 0) continue;
|
|
1343
|
+
const alone = checkedAttempt([operation], true).error;
|
|
1344
|
+
if (alone !== void 0) refused.push({
|
|
1345
|
+
id,
|
|
1346
|
+
reason: "invalidResult",
|
|
1347
|
+
message: describeModelError(alone)
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
if (refused.length > 0) return refused;
|
|
1351
|
+
return run.outcome.applied.map(({ id }) => ({
|
|
1352
|
+
id,
|
|
1353
|
+
reason: "invalidResult",
|
|
1354
|
+
message: describeModelError(firstError)
|
|
1355
|
+
}));
|
|
1356
|
+
};
|
|
1357
|
+
/**
|
|
1358
|
+
* Apply (or preview) the batch and check the result with the save-time
|
|
1359
|
+
* validator before anything reaches the caller. Operations whose result would
|
|
1360
|
+
* not save are skipped with `invalidResult`; in a best-effort batch the rest
|
|
1361
|
+
* is applied again without them, in an atomic one nothing is.
|
|
1362
|
+
*/
|
|
1363
|
+
const guardedAttempt = (preview) => {
|
|
1364
|
+
const first = attempt(parsedBatch.operations, preview);
|
|
1365
|
+
const [firstError] = introducedErrors(first);
|
|
1366
|
+
if (firstError === void 0) return {
|
|
1367
|
+
outcome: {
|
|
1368
|
+
...first.outcome,
|
|
1369
|
+
skipped: inOperationOrder(parsedBatch.operations, first.outcome.skipped)
|
|
1370
|
+
},
|
|
1371
|
+
commit: first.commit
|
|
1372
|
+
};
|
|
1373
|
+
const refused = refuseInvalidResult(first, firstError);
|
|
1374
|
+
const refusedIds = new Set(refused.map(({ id }) => id));
|
|
1375
|
+
if (isAtomic) return {
|
|
1376
|
+
outcome: {
|
|
1377
|
+
...first.outcome,
|
|
1378
|
+
applied: [],
|
|
1379
|
+
skipped: inOperationOrder(parsedBatch.operations, [...first.outcome.skipped, ...refused])
|
|
1380
|
+
},
|
|
1381
|
+
commit: NO_COMMIT
|
|
1382
|
+
};
|
|
1383
|
+
const second = checkedAttempt(parsedBatch.operations.filter(({ id }) => !refusedIds.has(id)), preview);
|
|
1384
|
+
if (second.run === null || second.error !== void 0) {
|
|
1385
|
+
const reported = second.run?.outcome ?? first.outcome;
|
|
1386
|
+
return {
|
|
1387
|
+
outcome: {
|
|
1388
|
+
...reported,
|
|
1389
|
+
applied: [],
|
|
1390
|
+
skipped: inOperationOrder(parsedBatch.operations, [
|
|
1391
|
+
...reported.skipped.filter(({ id }) => !refusedIds.has(id)),
|
|
1392
|
+
...refused,
|
|
1393
|
+
...reported.applied.filter(({ id }) => !refusedIds.has(id)).map(({ id }) => ({
|
|
1394
|
+
id,
|
|
1395
|
+
reason: "invalidResult",
|
|
1396
|
+
message: describeModelError(second.error ?? firstError)
|
|
1397
|
+
}))
|
|
1398
|
+
])
|
|
1399
|
+
},
|
|
1400
|
+
commit: NO_COMMIT
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
return {
|
|
1404
|
+
outcome: {
|
|
1405
|
+
...second.run.outcome,
|
|
1406
|
+
skipped: inOperationOrder(parsedBatch.operations, [...second.run.outcome.skipped, ...refused])
|
|
1407
|
+
},
|
|
1408
|
+
commit: second.run.commit
|
|
1409
|
+
};
|
|
1410
|
+
};
|
|
1411
|
+
const preview = () => guardedAttempt(true).outcome;
|
|
1206
1412
|
const atomicResult = (previewResult, status) => {
|
|
1207
1413
|
const skippedById = new Map(previewResult.skipped.map((operation) => [operation.id, operation]));
|
|
1208
1414
|
const skipped = parsedBatch.operations.map(({ id }) => skippedById.get(id) ?? {
|
|
@@ -1223,7 +1429,7 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
1223
1429
|
};
|
|
1224
1430
|
if (parsedBatch.dryRun === true) {
|
|
1225
1431
|
const previewResult = preview();
|
|
1226
|
-
if (
|
|
1432
|
+
if (isAtomic && previewResult.skipped.length > 0) return atomicResult(previewResult, "previewed");
|
|
1227
1433
|
return {
|
|
1228
1434
|
version: 1,
|
|
1229
1435
|
status: "previewed",
|
|
@@ -1240,11 +1446,14 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
1240
1446
|
nextRevisionId: previewResult.nextRevisionId
|
|
1241
1447
|
};
|
|
1242
1448
|
}
|
|
1243
|
-
if (
|
|
1449
|
+
if (isAtomic) {
|
|
1244
1450
|
const previewResult = preview();
|
|
1245
1451
|
if (previewResult.skipped.length > 0) return atomicResult(previewResult, "rejected");
|
|
1246
1452
|
}
|
|
1247
|
-
const
|
|
1453
|
+
const guarded = guardedAttempt(false);
|
|
1454
|
+
const result = guarded.outcome;
|
|
1455
|
+
if (isAtomic && result.skipped.some(({ reason }) => reason === "invalidResult")) return atomicResult(result, "rejected");
|
|
1456
|
+
guarded.commit();
|
|
1248
1457
|
return {
|
|
1249
1458
|
version: 1,
|
|
1250
1459
|
status: "committed",
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/docx/altChunk.d.ts
|
|
2
|
+
declare const ALT_CHUNK_READER_DIAGNOSTIC = "[Unsupported w:altChunk content]";
|
|
3
|
+
declare const ALT_CHUNK_PLAIN_TEXT_LIMIT_BYTES = 1000000;
|
|
4
|
+
/** The captured fragment's expanded name, not its source prefix, identifies w:altChunk. */
|
|
5
|
+
declare const isAltChunkMarkup: (xml: string) => boolean;
|
|
6
|
+
declare const getAltChunkRelationshipId: (xml: string) => string | undefined;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { ALT_CHUNK_PLAIN_TEXT_LIMIT_BYTES, ALT_CHUNK_READER_DIAGNOSTIC, getAltChunkRelationshipId, isAltChunkMarkup };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { OOXML_NAMESPACE_SCOPE, WORDPROCESSINGML_NAMESPACE_URIS, getAttribute, getChildElements, getLocalName, parseXml } from "./xmlParser.js";
|
|
2
|
+
//#region src/docx/altChunk.ts
|
|
3
|
+
const ALT_CHUNK_READER_DIAGNOSTIC = "[Unsupported w:altChunk content]";
|
|
4
|
+
const ALT_CHUNK_PLAIN_TEXT_LIMIT_BYTES = 1e6;
|
|
5
|
+
const OFFICE_RELATIONSHIPS_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
6
|
+
/** The captured fragment's expanded name, not its source prefix, identifies w:altChunk. */
|
|
7
|
+
const isAltChunkMarkup = (xml) => {
|
|
8
|
+
const element = getChildElements(parseXml(xml, OOXML_NAMESPACE_SCOPE)).at(0);
|
|
9
|
+
return element?.type === "element" && getLocalName(element.name) === "altChunk" && WORDPROCESSINGML_NAMESPACE_URIS.has(element.namespaceUri ?? "");
|
|
10
|
+
};
|
|
11
|
+
const getAltChunkRelationshipId = (xml) => {
|
|
12
|
+
const element = getChildElements(parseXml(xml, OOXML_NAMESPACE_SCOPE)).at(0);
|
|
13
|
+
if (element?.type !== "element" || getLocalName(element.name) !== "altChunk" || !WORDPROCESSINGML_NAMESPACE_URIS.has(element.namespaceUri ?? "")) return;
|
|
14
|
+
return getAttribute(element, OFFICE_RELATIONSHIPS_NAMESPACE_URI, "id") ?? void 0;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { ALT_CHUNK_PLAIN_TEXT_LIMIT_BYTES, ALT_CHUNK_READER_DIAGNOSTIC, getAltChunkRelationshipId, isAltChunkMarkup };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ModelledAttributes } from "./propertyElementAttributes.js";
|
|
2
1
|
import { XmlElement } from "./xmlParser.js";
|
|
2
|
+
import { ModelledAttributes } from "./propertyElementAttributes.js";
|
|
3
3
|
import { PreservedAttribute } from "@stll/docx-core/model";
|
|
4
4
|
//#region src/docx/attributeRemainder.d.ts
|
|
5
5
|
declare const InvalidPreservedAttributeError_base: import("better-result").TaggedErrorClass<"InvalidPreservedAttributeError">;
|
|
@@ -2,6 +2,7 @@ import { document_d_exports } from "../types/document.js";
|
|
|
2
2
|
import { NumberingMap } from "./numberingParser.js";
|
|
3
3
|
import { ParseContext } from "./parseContext.js";
|
|
4
4
|
import { XmlElement } from "./xmlParser.js";
|
|
5
|
+
import { OwnedElsewhere } from "./containerChildren.js";
|
|
5
6
|
import { PreviewLedger } from "./previewBudget.js";
|
|
6
7
|
import { StyleMap } from "./styleParser.js";
|
|
7
8
|
//#region src/docx/blockContentParser.d.ts
|
|
@@ -11,6 +12,68 @@ type ParseBlockContentOptions = {
|
|
|
11
12
|
context?: ParseContext | undefined;
|
|
12
13
|
previews?: PreviewLedger;
|
|
13
14
|
};
|
|
15
|
+
/** The options every block below the entry point reads, with its ledger settled. */
|
|
16
|
+
type BlockContentScope = ParseBlockContentOptions & {
|
|
17
|
+
previews: PreviewLedger;
|
|
18
|
+
};
|
|
19
|
+
type PreviousListState = {
|
|
20
|
+
abstractNumId: number | null;
|
|
21
|
+
fromStyle: boolean;
|
|
22
|
+
numId: number | null;
|
|
23
|
+
};
|
|
24
|
+
type ParseBlockContentState = {
|
|
25
|
+
listCounters: Map<number, number[]>;
|
|
26
|
+
abstractCounters: Map<number, number[]>;
|
|
27
|
+
restartedNumIds: Set<number>;
|
|
28
|
+
previousList: PreviousListState;
|
|
29
|
+
options: BlockContentScope;
|
|
30
|
+
};
|
|
14
31
|
declare const parseBlockContent: (parent: XmlElement, styles: StyleMap | null, theme: document_d_exports.Theme | null, numbering: NumberingMap | null, rels: document_d_exports.RelationshipMap | null, media: Map<string, document_d_exports.MediaFile> | null, options?: ParseBlockContentOptions) => document_d_exports.BlockContent[];
|
|
32
|
+
/** The parts and maps a block sequence is read against. */
|
|
33
|
+
type BlockContentResources = {
|
|
34
|
+
styles: StyleMap | null;
|
|
35
|
+
theme: document_d_exports.Theme | null;
|
|
36
|
+
numbering: NumberingMap | null;
|
|
37
|
+
rels: document_d_exports.RelationshipMap | null;
|
|
38
|
+
media: Map<string, document_d_exports.MediaFile> | null;
|
|
39
|
+
};
|
|
40
|
+
/** One block container's children as they are read. */
|
|
41
|
+
type BlockContentWalk = {
|
|
42
|
+
resources: BlockContentResources;
|
|
43
|
+
state: ParseBlockContentState;
|
|
44
|
+
modelled: document_d_exports.BlockContent[];
|
|
45
|
+
};
|
|
46
|
+
declare const BLOCK_CONTENT_HANDLERS: {
|
|
47
|
+
readonly altChunk: "capture";
|
|
48
|
+
readonly commentRangeEnd: "capture";
|
|
49
|
+
readonly commentRangeStart: "capture";
|
|
50
|
+
readonly customXmlDelRangeEnd: "capture";
|
|
51
|
+
readonly customXmlDelRangeStart: "capture";
|
|
52
|
+
readonly customXmlInsRangeEnd: "capture";
|
|
53
|
+
readonly customXmlInsRangeStart: "capture";
|
|
54
|
+
readonly customXmlMoveFromRangeEnd: "capture";
|
|
55
|
+
readonly customXmlMoveFromRangeStart: "capture";
|
|
56
|
+
readonly customXmlMoveToRangeEnd: "capture";
|
|
57
|
+
readonly customXmlMoveToRangeStart: "capture";
|
|
58
|
+
readonly del: "capture";
|
|
59
|
+
readonly ins: "capture";
|
|
60
|
+
readonly moveFrom: "capture";
|
|
61
|
+
readonly moveFromRangeEnd: "capture";
|
|
62
|
+
readonly moveFromRangeStart: "capture";
|
|
63
|
+
readonly moveTo: "capture";
|
|
64
|
+
readonly moveToRangeEnd: "capture";
|
|
65
|
+
readonly moveToRangeStart: "capture";
|
|
66
|
+
readonly permEnd: "capture";
|
|
67
|
+
readonly permStart: "capture";
|
|
68
|
+
readonly proofErr: "capture";
|
|
69
|
+
readonly sectPr: OwnedElsewhere<"block-content", "sectPr">;
|
|
70
|
+
readonly tcPr: OwnedElsewhere<"block-content", "tcPr">;
|
|
71
|
+
readonly p: (child: XmlElement, { resources: { styles, theme, numbering, rels, media }, state, modelled }: BlockContentWalk) => void;
|
|
72
|
+
readonly tbl: (child: XmlElement, { resources: { styles, theme, numbering, rels, media }, state, modelled }: BlockContentWalk) => "capture" | undefined;
|
|
73
|
+
readonly sdt: (child: XmlElement, { resources: { styles, theme, numbering, rels, media }, state, modelled }: BlockContentWalk) => void;
|
|
74
|
+
readonly customXml: (child: XmlElement, { resources: { styles, theme, numbering, rels, media }, state, modelled }: BlockContentWalk) => void;
|
|
75
|
+
readonly bookmarkStart: (child: XmlElement, { modelled }: BlockContentWalk) => void;
|
|
76
|
+
readonly bookmarkEnd: (child: XmlElement, { modelled }: BlockContentWalk) => void;
|
|
77
|
+
};
|
|
15
78
|
//#endregion
|
|
16
|
-
export { parseBlockContent };
|
|
79
|
+
export { BLOCK_CONTENT_HANDLERS, parseBlockContent };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { blockCustomXmlShell } from "./blockCustomXmlShell.js";
|
|
1
2
|
import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
|
|
2
3
|
import { bulletMarkerFontName, convertBulletToUnicode } from "./bulletMarkers.js";
|
|
3
4
|
import { CAPTURE, dispatchChildrenWithContext, ownedElsewhere, withPreservedChildren } from "./containerChildren.js";
|
|
@@ -8,7 +9,7 @@ import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
|
|
|
8
9
|
import { standalonePreviewLedger } from "./previewBudget.js";
|
|
9
10
|
import { captureSdtSiblingMarkers, parseSdtProperties } from "./sdtProperties.js";
|
|
10
11
|
import { parseTable } from "./tableParser.js";
|
|
11
|
-
import { findWordprocessingChild, mergeXmlnsDeclarations, selectAlternateContentBranch } from "./xmlParser.js";
|
|
12
|
+
import { findWordprocessingChild, getLocalName, mergeXmlnsDeclarations, selectAlternateContentBranch } from "./xmlParser.js";
|
|
12
13
|
//#region src/docx/blockContentParser.ts
|
|
13
14
|
const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList }) => {
|
|
14
15
|
const listRendering = paragraph.listRendering;
|
|
@@ -131,6 +132,13 @@ const BLOCK_CONTENT_UNDECLARED = { AlternateContent: (child, { resources: { styl
|
|
|
131
132
|
if (!selectedBranch) return;
|
|
132
133
|
modelled.push(...parseBlockContentWithState(selectedBranch, styles, theme, numbering, rels, media, withContainerXmlns(withContainerXmlns(state, child), selectedBranch)));
|
|
133
134
|
} };
|
|
135
|
+
const parseBlockCustomXml = (child, styles, theme, numbering, rels, media, state) => {
|
|
136
|
+
return {
|
|
137
|
+
type: "blockCustomXml",
|
|
138
|
+
...blockCustomXmlShell(child),
|
|
139
|
+
content: parseBlockContentWithState(child, styles, theme, numbering, rels, media, withContainerXmlns(state, child))
|
|
140
|
+
};
|
|
141
|
+
};
|
|
134
142
|
const BLOCK_CONTENT_HANDLERS = {
|
|
135
143
|
p: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
|
|
136
144
|
const paragraph = parseParagraph(child, styles, theme, numbering, rels, media, {
|
|
@@ -149,12 +157,18 @@ const BLOCK_CONTENT_HANDLERS = {
|
|
|
149
157
|
},
|
|
150
158
|
tbl: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
|
|
151
159
|
const table = parseTable(child, styles, theme, numbering, rels, media, state.options);
|
|
152
|
-
if (!table) return
|
|
160
|
+
if (!table) return child.elements?.some((tableChild) => {
|
|
161
|
+
const localName = getLocalName(tableChild.name ?? "");
|
|
162
|
+
return localName !== "tblPr" && localName !== "tblGrid";
|
|
163
|
+
}) ?? false ? CAPTURE : void 0;
|
|
153
164
|
modelled.push(table);
|
|
154
165
|
},
|
|
155
166
|
sdt: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
|
|
156
167
|
modelled.push(parseBlockSdt(child, styles, theme, numbering, rels, media, state));
|
|
157
168
|
},
|
|
169
|
+
customXml: (child, { resources: { styles, theme, numbering, rels, media }, state, modelled }) => {
|
|
170
|
+
modelled.push(parseBlockCustomXml(child, styles, theme, numbering, rels, media, state));
|
|
171
|
+
},
|
|
158
172
|
bookmarkStart: (child, { modelled }) => {
|
|
159
173
|
modelled.push(parseBookmarkStart(child));
|
|
160
174
|
},
|
|
@@ -165,7 +179,6 @@ const BLOCK_CONTENT_HANDLERS = {
|
|
|
165
179
|
altChunk: CAPTURE,
|
|
166
180
|
commentRangeEnd: CAPTURE,
|
|
167
181
|
commentRangeStart: CAPTURE,
|
|
168
|
-
customXml: CAPTURE,
|
|
169
182
|
customXmlDelRangeEnd: CAPTURE,
|
|
170
183
|
customXmlDelRangeStart: CAPTURE,
|
|
171
184
|
customXmlInsRangeEnd: CAPTURE,
|
|
@@ -223,4 +236,4 @@ const parseBlockSdt = (child, styles, theme, numbering, rels, media, state) => {
|
|
|
223
236
|
};
|
|
224
237
|
};
|
|
225
238
|
//#endregion
|
|
226
|
-
export { parseBlockContent };
|
|
239
|
+
export { BLOCK_CONTENT_HANDLERS, parseBlockContent };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { XmlElement } from "./xmlParser.js";
|
|
3
|
+
//#region src/docx/blockCustomXmlShell.d.ts
|
|
4
|
+
/** Capture the wrapper independently of its modeled and preserved children. */
|
|
5
|
+
declare const blockCustomXmlShell: (element: XmlElement) => Pick<document_d_exports.BlockCustomXml, "openingXml" | "closingXml">;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { blockCustomXmlShell };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
2
|
+
import { cloneElement } from "./xmlParser.js";
|
|
3
|
+
//#region src/docx/blockCustomXmlShell.ts
|
|
4
|
+
/** Capture the wrapper independently of its modeled and preserved children. */
|
|
5
|
+
const blockCustomXmlShell = (element) => {
|
|
6
|
+
const shell = captureVerbatimXml(cloneElement(element, { elements: [] }));
|
|
7
|
+
const name = element.name ?? "w:customXml";
|
|
8
|
+
return {
|
|
9
|
+
openingXml: shell.endsWith("/>") ? `${shell.slice(0, -2)}>` : shell,
|
|
10
|
+
closingXml: `</${name}>`
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { blockCustomXmlShell };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ALT_CHUNK_READER_DIAGNOSTIC, isAltChunkMarkup } from "./altChunk.js";
|
|
2
|
+
import { OPAQUE_REVISION_CARRIER_READER_DIAGNOSTIC, isOpaqueNestedRowMarkup, opaqueRevisionCarrierName } from "./opaqueCarrier.js";
|
|
1
3
|
import { getParagraphText } from "./paragraphParser.js";
|
|
2
4
|
import { panic } from "better-result";
|
|
3
5
|
//#region src/docx/blockPlainText.ts
|
|
@@ -29,9 +31,14 @@ const collectBlockTexts = (blocks) => {
|
|
|
29
31
|
}
|
|
30
32
|
break;
|
|
31
33
|
case "blockSdt":
|
|
34
|
+
case "blockCustomXml":
|
|
32
35
|
texts.push(...collectBlockTexts(block.content));
|
|
33
36
|
break;
|
|
34
37
|
case "preservedBlock":
|
|
38
|
+
if (isAltChunkMarkup(block.xml)) texts.push(block.readerText === void 0 ? ALT_CHUNK_READER_DIAGNOSTIC : `${ALT_CHUNK_READER_DIAGNOSTIC}\n${block.readerText}`);
|
|
39
|
+
else if (opaqueRevisionCarrierName(block.xml) !== void 0) texts.push(OPAQUE_REVISION_CARRIER_READER_DIAGNOSTIC);
|
|
40
|
+
else if (isOpaqueNestedRowMarkup(block.xml)) texts.push("[Unsupported nested w:tr content]");
|
|
41
|
+
break;
|
|
35
42
|
case "bookmarkStart":
|
|
36
43
|
case "bookmarkEnd": break;
|
|
37
44
|
default: panic(`Unsupported block in plain-text extraction: ${JSON.stringify(block)}`);
|
|
@@ -19,7 +19,7 @@ const visitCommentMarkers = (blocks, visit) => {
|
|
|
19
19
|
for (const row of block.rows) for (const cell of row.cells) visitBlocks(cell.content);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
if (block.type !== "blockSdt") return;
|
|
22
|
+
if (block.type !== "blockSdt" && block.type !== "blockCustomXml") return;
|
|
23
23
|
visitBlocks(block.content);
|
|
24
24
|
};
|
|
25
25
|
const visitBlocks = (nested) => {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
|
|
2
2
|
//#region src/docx/commentRangeIntegrity.ts
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* A range marker under any prefix, or none: this is the guard a splice is
|
|
5
|
+
* refused by, and a guard that only knows `w:` passes every patch of a part
|
|
6
|
+
* that spells WordprocessingML another way.
|
|
7
|
+
*/
|
|
8
|
+
const COMMENT_RANGE_MARKER_PATTERN = /<(?:[\w.-]+:)?commentRange(Start|End)(?:\s[^>]*?)?\s(?:[\w.-]+:)?id=["'](\d+)["']/gu;
|
|
4
9
|
/**
|
|
5
10
|
* Comment ids whose range is not a start followed by an end in this story's
|
|
6
11
|
* XML. Either half alone is invalid OOXML and anchors nothing: Word shows no
|
|
@@ -147,7 +152,7 @@ const withoutOrphanBlockMarkers = (blocks, validCommentIds) => {
|
|
|
147
152
|
const withoutOrphanBlockMarker = (block, validCommentIds) => {
|
|
148
153
|
if (block.type === "paragraph") return withoutOrphanParagraphMarkers(block, validCommentIds);
|
|
149
154
|
if (block.type === "table") return withoutOrphanTableMarkers(block, validCommentIds);
|
|
150
|
-
if (block.type !== "blockSdt") return block;
|
|
155
|
+
if (block.type !== "blockSdt" && block.type !== "blockCustomXml") return block;
|
|
151
156
|
const content = withoutOrphanBlockMarkers(block.content, validCommentIds);
|
|
152
157
|
if (!content) return block;
|
|
153
158
|
return {
|
|
@@ -204,7 +209,7 @@ const withoutOrphanTableCellBlockMarkers = (blocks, validCommentIds) => {
|
|
|
204
209
|
const withoutOrphanTableCellBlockMarker = (block, validCommentIds) => {
|
|
205
210
|
if (block.type === "paragraph") return withoutOrphanParagraphMarkers(block, validCommentIds);
|
|
206
211
|
if (block.type === "table") return withoutOrphanTableMarkers(block, validCommentIds);
|
|
207
|
-
if (block.type === "blockSdt") {
|
|
212
|
+
if (block.type === "blockSdt" || block.type === "blockCustomXml") {
|
|
208
213
|
const content = withoutOrphanTableCellBlockMarkers(block.content, validCommentIds);
|
|
209
214
|
return content ? {
|
|
210
215
|
...block,
|
|
@@ -40,7 +40,7 @@ const normalizeCommentReferences = ({ documentBody, comments, headers, footers,
|
|
|
40
40
|
normalizeTable(block);
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
|
-
if (block.type !== "blockSdt") return;
|
|
43
|
+
if (block.type !== "blockSdt" && block.type !== "blockCustomXml") return;
|
|
44
44
|
normalizeBlocks(block.content);
|
|
45
45
|
};
|
|
46
46
|
const normalizeBlocks = (blocks) => {
|