@stll/folio-core 0.36.0 → 0.37.1
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 +59 -1
- package/dist/ai-edits/apply.js +689 -367
- package/dist/ai-edits/block-identity.d.ts +4 -1
- package/dist/ai-edits/block-identity.js +4 -1
- package/dist/ai-edits/blockRange.js +14 -14
- package/dist/ai-edits/clean-text.d.ts +40 -1
- package/dist/ai-edits/clean-text.js +52 -2
- package/dist/ai-edits/headless.d.ts +3 -1
- package/dist/ai-edits/headless.js +133 -71
- package/dist/ai-edits/index.d.ts +3 -3
- package/dist/ai-edits/index.js +2 -2
- package/dist/ai-edits/read.js +38 -20
- package/dist/ai-edits/snapshot.d.ts +14 -6
- package/dist/ai-edits/snapshot.js +99 -19
- package/dist/ai-edits/table-cell-mutations.js +1 -1
- package/dist/ai-edits/table-row-column-mutations.js +7 -0
- package/dist/ai-edits/table-template.d.ts +11 -1
- package/dist/ai-edits/table-template.js +49 -17
- package/dist/ai-edits/types.d.ts +60 -57
- package/dist/ai-suggestions/conflict.js +1 -4
- package/dist/ai-suggestions/text-positions.d.ts +8 -0
- package/dist/ai-suggestions/text-positions.js +27 -5
- package/dist/compare/__fixtures__/body-sequence.js +3 -4
- package/dist/compare/column-alignment.d.ts +13 -13
- package/dist/compare/column-alignment.js +78 -39
- package/dist/compare/compare.d.ts +4 -3
- package/dist/compare/compare.js +41 -5
- package/dist/compare/content-alignment.d.ts +95 -0
- package/dist/compare/content-alignment.js +1450 -0
- package/dist/compare/content-types.d.ts +100 -0
- package/dist/compare/content-types.js +0 -0
- package/dist/compare/content.d.ts +209 -0
- package/dist/compare/content.js +885 -0
- package/dist/compare/formatting.d.ts +5 -5
- package/dist/compare/formatting.js +6 -4
- package/dist/compare/plan.d.ts +6 -1
- package/dist/compare/plan.js +201 -569
- package/dist/compare/scenario.d.ts +2 -2
- package/dist/compare/types.d.ts +3 -3
- package/dist/compare/verification.d.ts +2 -2
- package/dist/compare/verification.js +25 -8
- package/dist/compat/eigenpal.d.ts +5 -3
- package/dist/compat/eigenpal.js +3 -2
- package/dist/controller/headerFooterEditorManager.js +14 -6
- package/dist/controller/hiddenEditorManager.d.ts +7 -2
- package/dist/controller/hiddenEditorManager.js +15 -6
- package/dist/controller/layoutPipeline.js +5 -3
- package/dist/controller/noteEditorManager.js +12 -7
- package/dist/display-list/build/headerFooterPrimitives.js +1 -0
- package/dist/display-list/build/storyPrimitives.d.ts +5 -2
- package/dist/display-list/build/storyPrimitives.js +60 -3
- package/dist/display-list/build/tablePrimitives.js +30 -0
- package/dist/display-list/primitives.d.ts +1 -1
- package/dist/document-operations.d.ts +8 -6
- package/dist/document-operations.js +121 -26
- package/dist/docx/blockContentParser.js +6 -27
- package/dist/docx/ensureParaIds.js +9 -4
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +4 -1
- package/dist/docx/paragraphParser.js +7 -6
- package/dist/docx/paragraphTraversal.js +30 -34
- package/dist/docx/rezip.d.ts +0 -8
- package/dist/docx/rezip.js +41 -16
- package/dist/docx/runParser.js +4 -2
- package/dist/docx/serializer/paragraphSerializer.js +2 -0
- package/dist/docx/serializer/runSerializer.js +5 -3
- package/dist/docx/serializer/trackedChangeAttributes.d.ts +3 -1
- package/dist/docx/serializer/trackedChangeAttributes.js +11 -1
- package/dist/docx/server/build.d.ts +1 -1
- package/dist/headless-layout.js +5 -4
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -2
- package/dist/internal/headlessRevisionResolution.d.ts +23 -0
- package/dist/internal/headlessRevisionResolution.js +176 -0
- package/dist/internal/headlessRevisionResolutionGuard.d.ts +12 -0
- package/dist/internal/headlessRevisionResolutionGuard.js +28 -0
- package/dist/internal/pageBreakRunDescendantIndex.d.ts +9 -0
- package/dist/internal/pageBreakRunDescendantIndex.js +27 -0
- package/dist/internal/pageBreakRunPartition.d.ts +26 -0
- package/dist/internal/pageBreakRunPartition.js +35 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.d.ts +15 -0
- package/dist/internal/pageBreakRunSourceDescendantIndex.js +126 -0
- package/dist/internal/sectionEndpointResolution.d.ts +32 -0
- package/dist/internal/sectionEndpointResolution.js +38 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +16 -4
- package/dist/layout-bridge/convert/headerFooterLayout.js +48 -5
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +4 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +379 -75
- package/dist/layout-bridge/dom/clickToPositionDom.d.ts +8 -1
- package/dist/layout-bridge/dom/clickToPositionDom.js +114 -40
- package/dist/layout-bridge/dom/textStreamDom.d.ts +24 -0
- package/dist/layout-bridge/dom/textStreamDom.js +75 -0
- package/dist/layout-bridge/headerFooterLayout.js +16 -30
- package/dist/layout-engine/index.js +12 -3
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.d.ts +17 -0
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +24 -0
- package/dist/layout-engine/renderedBreakReconciliation.js +1 -1
- package/dist/layout-engine/types.d.ts +7 -0
- package/dist/layout-painter/imageLayout.d.ts +1 -1
- package/dist/layout-painter/renderTable.js +20 -0
- package/dist/model.d.ts +1 -1
- package/dist/paged-layout/rangeProjection.js +6 -9
- package/dist/paged-layout/transactionDirtyRange.d.ts +3 -1
- package/dist/paged-layout/transactionDirtyRange.js +23 -1
- package/dist/prosemirror/attrs/index.d.ts +7 -3
- package/dist/prosemirror/attrs/index.js +113 -7
- package/dist/prosemirror/bookmarkBoundaryIntegrity.d.ts +9 -0
- package/dist/prosemirror/bookmarkBoundaryIntegrity.js +22 -0
- package/dist/prosemirror/commands/comments.d.ts +10 -1
- package/dist/prosemirror/commands/comments.js +167 -59
- package/dist/prosemirror/commands/formatPainter.d.ts +45 -10
- package/dist/prosemirror/commands/formatPainter.js +319 -63
- package/dist/prosemirror/commands/index.d.ts +2 -2
- package/dist/prosemirror/commands/pageBreak.d.ts +5 -2
- package/dist/prosemirror/commands/pageBreak.js +18 -36
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +7 -5
- package/dist/prosemirror/commands/propertyChangeScope.js +27 -18
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +7 -2
- package/dist/prosemirror/conversion/fromProseDoc.js +809 -209
- package/dist/prosemirror/conversion/runShadingMark.js +2 -2
- package/dist/prosemirror/conversion/toProseDoc.d.ts +26 -1
- package/dist/prosemirror/conversion/toProseDoc.js +416 -283
- package/dist/prosemirror/extensions/StarterKit.js +4 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +12 -8
- package/dist/prosemirror/extensions/features/ListExtension.js +95 -123
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +27 -1
- package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +134 -30
- package/dist/prosemirror/extensions/features/pasteCleanup.js +9 -15
- package/dist/prosemirror/extensions/marks/BoldExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.d.ts +4 -7
- package/dist/prosemirror/extensions/marks/CharacterStyleExtension.js +5 -11
- package/dist/prosemirror/extensions/marks/FontSizeExtension.js +3 -3
- package/dist/prosemirror/extensions/marks/ItalicExtension.js +4 -3
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +13 -0
- package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +39 -0
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.d.ts +7 -1
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +67 -21
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +8 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +88 -2
- package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +44 -3
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
- package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +15 -4
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/nodes/PageBreakRunExtension.js +36 -0
- package/dist/prosemirror/findReplaceSelection.js +8 -3
- package/dist/prosemirror/index.d.ts +3 -3
- package/dist/prosemirror/listMarker.d.ts +26 -1
- package/dist/prosemirror/listMarker.js +108 -14
- package/dist/prosemirror/pageBreakRunProjection.d.ts +28 -0
- package/dist/prosemirror/pageBreakRunProjection.js +47 -0
- package/dist/prosemirror/paraText.js +6 -0
- package/dist/prosemirror/paragraphSpacing.d.ts +29 -0
- package/dist/prosemirror/paragraphSpacing.js +125 -0
- package/dist/prosemirror/plugins/documentNumbering.d.ts +8 -0
- package/dist/prosemirror/plugins/documentNumbering.js +18 -0
- package/dist/prosemirror/plugins/pmTextScan.d.ts +3 -2
- package/dist/prosemirror/plugins/pmTextScan.js +14 -4
- package/dist/prosemirror/plugins/suggestionMode.js +8 -10
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +16 -0
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +61 -0
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +64 -0
- package/dist/prosemirror/runFormattingInlineCarriers.js +121 -0
- package/dist/prosemirror/runFormattingProvenance.d.ts +12 -0
- package/dist/prosemirror/runFormattingProvenance.js +48 -0
- package/dist/prosemirror/runFormattingReconciliation.d.ts +25 -0
- package/dist/prosemirror/runFormattingReconciliation.js +54 -0
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +18 -0
- package/dist/prosemirror/runPropertyChangeResolution.js +18 -0
- package/dist/prosemirror/runStyleFormatting.d.ts +50 -0
- package/dist/prosemirror/runStyleFormatting.js +105 -0
- package/dist/prosemirror/schema/index.d.ts +3 -3
- package/dist/prosemirror/schema/marks.d.ts +82 -9
- package/dist/prosemirror/schema/marks.js +73 -1
- package/dist/prosemirror/schema/nodes.d.ts +18 -5
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +14 -2
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +44 -23
- package/dist/prosemirror/styles/styleResolver.d.ts +10 -13
- package/dist/prosemirror/styles/styleResolver.js +3 -3
- package/dist/prosemirror/styles/styleToggleCascade.d.ts +8 -1
- package/dist/prosemirror/styles/styleToggleCascade.js +24 -1
- package/dist/prosemirror/tableGridMutation.d.ts +20 -0
- package/dist/prosemirror/tableGridMutation.js +30 -0
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +31 -0
- package/dist/prosemirror/trackedRunInlineAtoms.js +39 -0
- package/dist/prosemirror/utils/visualLineNavigation.js +27 -31
- package/dist/prosemirror/validation.js +23 -4
- package/dist/render-dom/HeaderFooterSelectionOverlay.js +20 -20
- package/dist/render-dom/RenderedDomContext.js +17 -34
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/dist/style-engine/styleEngine.d.ts +1 -1
- package/dist/utils/clipboard.js +1 -1
- package/dist/utils/findReplace.js +38 -21
- package/dist/version-comparison.d.ts +38 -44
- package/dist/version-comparison.js +270 -401
- package/package.json +3 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createTableCellFlowState, placeTableCellBlock } from "../../layout-engine/measure/tableCellFlow.js";
|
|
2
2
|
import { buildTableCellGrid, buildTableCellPlacements, getSourceCellAt } from "../../layout-engine/measure/tableCellGrid.js";
|
|
3
|
+
import { tableFragmentBottomBorders } from "../../layout-engine/measure/tableFragmentBorderGeometry.js";
|
|
3
4
|
import { resolveTableCellPadding } from "../../layout-engine/types.js";
|
|
4
5
|
import { HIT_REGION_KINDS } from "../primitives.js";
|
|
5
6
|
import { parseDisplayColor } from "./colors.js";
|
|
@@ -332,6 +333,28 @@ const paintTableBody = ({ composer, block, measure, xPx, yPx, fromRow, toRow, he
|
|
|
332
333
|
cursorYPx += rowMeasure.height;
|
|
333
334
|
}
|
|
334
335
|
};
|
|
336
|
+
const paintFragmentBottomBorders = ({ composer, fragment, block, measure, context }) => {
|
|
337
|
+
if (fragment.continuesOnNext !== true || fragment.bottomClip === void 0) return;
|
|
338
|
+
const primitives = [];
|
|
339
|
+
for (const { left, width, border } of tableFragmentBottomBorders({
|
|
340
|
+
fragment,
|
|
341
|
+
block,
|
|
342
|
+
measure
|
|
343
|
+
})) {
|
|
344
|
+
const stroke = strokeFor(border, context, "table fragment bottom border");
|
|
345
|
+
if (!stroke) continue;
|
|
346
|
+
const yPx = fragment.y + fragment.height - stroke.thicknessPx / 2;
|
|
347
|
+
primitives.push({
|
|
348
|
+
kind: "line",
|
|
349
|
+
x1Px: fragment.x + left,
|
|
350
|
+
y1Px: yPx,
|
|
351
|
+
x2Px: fragment.x + left + width,
|
|
352
|
+
y2Px: yPx,
|
|
353
|
+
stroke
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
composer.push(primitives);
|
|
357
|
+
};
|
|
335
358
|
/** A whole, unpaginated table: what a nested table inside a cell or box is. */
|
|
336
359
|
const paintTableBlock = ({ composer, block, measure, xPx, yPx, context, paintTextBox }) => paintTableBody({
|
|
337
360
|
composer,
|
|
@@ -404,6 +427,13 @@ const paintTableFragment = ({ composer, fragment, block, measure, context, paint
|
|
|
404
427
|
children: [...clipped.primitives()],
|
|
405
428
|
regions: [...clipped.regions()]
|
|
406
429
|
}]);
|
|
430
|
+
paintFragmentBottomBorders({
|
|
431
|
+
composer,
|
|
432
|
+
fragment,
|
|
433
|
+
block,
|
|
434
|
+
measure,
|
|
435
|
+
context
|
|
436
|
+
});
|
|
407
437
|
};
|
|
408
438
|
//#endregion
|
|
409
439
|
export { paintTableBlock, paintTableFragment };
|
|
@@ -15,7 +15,7 @@ import { hasComplexScript, isComplexScriptCodePoint } from "../utils/scriptSegme
|
|
|
15
15
|
* advances rightward from its origin whatever the paragraph does.
|
|
16
16
|
*/
|
|
17
17
|
declare const glyphCellOffsetsPx: (run: DisplayGlyphRun) => readonly number[];
|
|
18
|
-
declare const DISPLAY_PRIMITIVE_KINDS: ("
|
|
18
|
+
declare const DISPLAY_PRIMITIVE_KINDS: ("image" | "glyphRun" | "rect" | "line" | "clipGroup" | "rotateGroup" | "opacityGroup")[];
|
|
19
19
|
/**
|
|
20
20
|
* Dash geometry of each stroke pattern, as multiples of the stroke thickness.
|
|
21
21
|
*
|
|
@@ -5,6 +5,8 @@ import { FolioAIEditView, FolioRevisionStamp, FolioWordDiffOptions } from "./ai-
|
|
|
5
5
|
declare const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION: 1;
|
|
6
6
|
/** Direct paragraph-alignment values accepted by the operation contract. */
|
|
7
7
|
declare const FOLIO_PARAGRAPH_ALIGNMENT_VALUES: readonly ("left" | "center" | "right" | "both" | "distribute" | "mediumKashida" | "highKashida" | "lowKashida" | "thaiDistribute")[];
|
|
8
|
+
/** `w:spacing/@w:lineRule` values accepted by the operation contract. */
|
|
9
|
+
declare const FOLIO_LINE_SPACING_RULE_VALUES: readonly ("auto" | "exact" | "atLeast")[];
|
|
8
10
|
declare const FOLIO_DOCUMENT_OPERATION_TYPES: readonly ["replaceInBlock", "replaceRange", "commentOnRange", "formatRange", "insertAfterBlock", "insertBeforeBlock", "replaceBlock", "deleteBlock", "splitBlock", "mergeBlockWithNext", "setBlockParagraphProperties", "insertTable", "deleteTable", "commentOnBlock", "insertSignatureTable", "insertTableRow", "deleteTableRow", "insertTableColumn", "deleteTableColumn", "mergeTableCells", "splitTableCell"];
|
|
9
11
|
declare const FOLIO_DOCUMENT_OPERATION_MODES: readonly ["direct", "tracked-changes", "suggested"];
|
|
10
12
|
declare const FOLIO_DOCUMENT_OPERATION_STORIES: readonly ["main", "header", "footer", "footnote", "endnote"];
|
|
@@ -95,12 +97,12 @@ declare const FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE: Readonly<{
|
|
|
95
97
|
readonly replaceRange: readonly ["id", "type", "range", "severity", "area", "precondition", "suggestionId", "replace", "comment"];
|
|
96
98
|
readonly commentOnRange: readonly ["id", "type", "range", "severity", "area", "precondition", "comment"];
|
|
97
99
|
readonly formatRange: readonly ["id", "type", "range", "severity", "area", "precondition", "suggestionId", "formatting"];
|
|
98
|
-
readonly insertAfterBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "alignment", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
|
|
99
|
-
readonly insertBeforeBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "alignment", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
|
|
100
|
+
readonly insertAfterBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "alignment", "spacing", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
|
|
101
|
+
readonly insertBeforeBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "alignment", "spacing", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
|
|
100
102
|
readonly replaceBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "preserveFormatting", "styleId", "comment"];
|
|
101
103
|
readonly deleteBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "moveId", "comment"];
|
|
102
|
-
readonly splitBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "offset", "separator"];
|
|
103
|
-
readonly mergeBlockWithNext: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "separator"];
|
|
104
|
+
readonly splitBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "offset", "separator", "firstParagraphProperties", "secondParagraphProperties"];
|
|
105
|
+
readonly mergeBlockWithNext: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "separator", "mergedParagraphProperties"];
|
|
104
106
|
readonly setBlockParagraphProperties: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "properties"];
|
|
105
107
|
readonly insertTable: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "position", "rows"];
|
|
106
108
|
readonly deleteTable: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId"];
|
|
@@ -119,7 +121,7 @@ declare const parseFolioDocumentOperationBatch: (value: unknown) => FolioDocumen
|
|
|
119
121
|
* review queue instead of applying it; the core apply path never produces it.
|
|
120
122
|
*/
|
|
121
123
|
type FolioDocumentOperationStatus = "committed" | "previewed" | "rejected" | "queued";
|
|
122
|
-
type FolioDocumentOperationRecovery = "refreshDocument" | "narrowMatch" | "changeMode" | "changeTarget" | "removeOperation" | "inspectBatch" | "retryLater";
|
|
124
|
+
type FolioDocumentOperationRecovery = "refreshDocument" | "narrowMatch" | "changeMode" | "changeTarget" | "removeOperation" | "inspectBatch" | "resolveTrackedChange" | "retryLater";
|
|
123
125
|
type FolioDocumentOperationIssue = {
|
|
124
126
|
operationId: string;
|
|
125
127
|
operationIndex: number;
|
|
@@ -280,4 +282,4 @@ type ApplyFolioDocumentOperationsOptions = {
|
|
|
280
282
|
};
|
|
281
283
|
declare const applyFolioDocumentOperations: ({ view, snapshot, batch, story, author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates }: ApplyFolioDocumentOperationsOptions) => FolioDocumentOperationResult;
|
|
282
284
|
//#endregion
|
|
283
|
-
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_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 };
|
|
285
|
+
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_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 };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { applyFolioAIEditOperations, previewFolioAIEditOperations } from "./ai-edits/apply.js";
|
|
2
|
-
import { PARAGRAPH_ALIGNMENT_VALUES } from "./types/documentEnumValues.js";
|
|
2
|
+
import { LINE_SPACING_RULE_VALUES, PARAGRAPH_ALIGNMENT_VALUES } from "./types/documentEnumValues.js";
|
|
3
3
|
import { TaggedError } from "better-result";
|
|
4
4
|
//#region src/document-operations.ts
|
|
5
5
|
const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION = 1;
|
|
6
6
|
/** Direct paragraph-alignment values accepted by the operation contract. */
|
|
7
7
|
const FOLIO_PARAGRAPH_ALIGNMENT_VALUES = Object.freeze([...PARAGRAPH_ALIGNMENT_VALUES]);
|
|
8
|
+
/** `w:spacing/@w:lineRule` values accepted by the operation contract. */
|
|
9
|
+
const FOLIO_LINE_SPACING_RULE_VALUES = Object.freeze([...LINE_SPACING_RULE_VALUES]);
|
|
8
10
|
const FOLIO_DOCUMENT_OPERATION_TYPES = Object.freeze([
|
|
9
11
|
"replaceInBlock",
|
|
10
12
|
"replaceRange",
|
|
@@ -146,6 +148,12 @@ const readOptionalBoolean = (value, key, path) => {
|
|
|
146
148
|
if (typeof candidate === "boolean") return candidate;
|
|
147
149
|
return invalidBatch(`${path}.${key}`, "expected a boolean when provided");
|
|
148
150
|
};
|
|
151
|
+
const readClearableBoolean = (value, key, path) => {
|
|
152
|
+
const candidate = value[key];
|
|
153
|
+
if (candidate === void 0 || candidate === null) return candidate;
|
|
154
|
+
if (typeof candidate === "boolean") return candidate;
|
|
155
|
+
return invalidBatch(`${path}.${key}`, "expected a boolean or null when provided");
|
|
156
|
+
};
|
|
149
157
|
const readClearableNonEmptyString = (value, key, path) => {
|
|
150
158
|
const candidate = value[key];
|
|
151
159
|
if (candidate === void 0 || candidate === null) return candidate;
|
|
@@ -175,8 +183,8 @@ const readOptionalStringArray = (value, key, path) => {
|
|
|
175
183
|
};
|
|
176
184
|
const readNonNegativeInteger = (value, key, path) => {
|
|
177
185
|
const candidate = value[key];
|
|
178
|
-
if (typeof candidate === "number" && Number.
|
|
179
|
-
return invalidBatch(`${path}.${key}`, "expected a non-negative integer");
|
|
186
|
+
if (typeof candidate === "number" && Number.isSafeInteger(candidate) && candidate >= 0) return candidate;
|
|
187
|
+
return invalidBatch(`${path}.${key}`, "expected a non-negative safe integer");
|
|
180
188
|
};
|
|
181
189
|
/**
|
|
182
190
|
* A non-negative integer that may also be cleared. `undefined` is "say
|
|
@@ -194,6 +202,46 @@ const readClearableParagraphAlignment = ({ value, key, path }) => {
|
|
|
194
202
|
for (const alignment of FOLIO_PARAGRAPH_ALIGNMENT_VALUES) if (candidate === alignment) return alignment;
|
|
195
203
|
return invalidBatch(`${path}.${key}`, `expected one of ${FOLIO_PARAGRAPH_ALIGNMENT_VALUES.join(", ")} or null when provided`);
|
|
196
204
|
};
|
|
205
|
+
const PARAGRAPH_SPACING_KEYS = [
|
|
206
|
+
"spaceBefore",
|
|
207
|
+
"spaceAfter",
|
|
208
|
+
"lineSpacing",
|
|
209
|
+
"lineSpacingRule",
|
|
210
|
+
"beforeAutospacing",
|
|
211
|
+
"afterAutospacing"
|
|
212
|
+
];
|
|
213
|
+
const isLineSpacingRule = (value) => FOLIO_LINE_SPACING_RULE_VALUES.some((rule) => value === rule);
|
|
214
|
+
/**
|
|
215
|
+
* Read one complete direct `w:spacing` cluster. Individual fields are
|
|
216
|
+
* optional so explicit zero and false survive; null removes the child.
|
|
217
|
+
*/
|
|
218
|
+
const readClearableParagraphSpacing = ({ value, key, path }) => {
|
|
219
|
+
const candidate = value[key];
|
|
220
|
+
if (candidate === void 0 || candidate === null) return candidate;
|
|
221
|
+
const spacingPath = `${path}.${key}`;
|
|
222
|
+
if (!isPlainObject(candidate)) return invalidBatch(spacingPath, "expected an object or null when provided");
|
|
223
|
+
assertAllowedKeys(candidate, spacingPath, PARAGRAPH_SPACING_KEYS);
|
|
224
|
+
if (Object.keys(candidate).length === 0) return invalidBatch(spacingPath, "expected at least one spacing property");
|
|
225
|
+
const spacing = {};
|
|
226
|
+
for (const unsignedKey of ["spaceBefore", "spaceAfter"]) if (candidate[unsignedKey] !== void 0) spacing[unsignedKey] = readNonNegativeInteger(candidate, unsignedKey, spacingPath);
|
|
227
|
+
const lineSpacing = candidate["lineSpacing"];
|
|
228
|
+
if (lineSpacing !== void 0) {
|
|
229
|
+
if (typeof lineSpacing !== "number" || !Number.isSafeInteger(lineSpacing)) return invalidBatch(`${spacingPath}.lineSpacing`, "expected a safe signed integer when provided");
|
|
230
|
+
spacing.lineSpacing = lineSpacing;
|
|
231
|
+
}
|
|
232
|
+
const lineSpacingRule = candidate["lineSpacingRule"];
|
|
233
|
+
if (lineSpacingRule !== void 0) {
|
|
234
|
+
if (!isLineSpacingRule(lineSpacingRule)) return invalidBatch(`${spacingPath}.lineSpacingRule`, `expected one of ${FOLIO_LINE_SPACING_RULE_VALUES.join(", ")} when provided`);
|
|
235
|
+
spacing.lineSpacingRule = lineSpacingRule;
|
|
236
|
+
}
|
|
237
|
+
for (const booleanKey of ["beforeAutospacing", "afterAutospacing"]) {
|
|
238
|
+
const booleanValue = candidate[booleanKey];
|
|
239
|
+
if (booleanValue === void 0) continue;
|
|
240
|
+
if (typeof booleanValue !== "boolean") return invalidBatch(`${spacingPath}.${booleanKey}`, "expected a boolean when provided");
|
|
241
|
+
spacing[booleanKey] = booleanValue;
|
|
242
|
+
}
|
|
243
|
+
return spacing;
|
|
244
|
+
};
|
|
197
245
|
/**
|
|
198
246
|
* A rectangular grid of cell texts. Rectangular because a table whose rows
|
|
199
247
|
* hold different cell counts is not a table any consumer can lay out, and the
|
|
@@ -214,14 +262,15 @@ const readTableRows = (value, path) => {
|
|
|
214
262
|
if (parsed.some((row) => row.length !== width)) return invalidBatch(rowsPath, "expected every row to hold the same number of cells");
|
|
215
263
|
return parsed;
|
|
216
264
|
};
|
|
217
|
-
const readParagraphProperties = (value, path) => {
|
|
218
|
-
const candidate = value[
|
|
219
|
-
const propertiesPath = `${path}
|
|
265
|
+
const readParagraphProperties = ({ value, key, path }) => {
|
|
266
|
+
const candidate = value[key];
|
|
267
|
+
const propertiesPath = `${path}.${key}`;
|
|
220
268
|
if (!isPlainObject(candidate)) return invalidBatch(propertiesPath, "expected an object");
|
|
221
269
|
assertAllowedKeys(candidate, propertiesPath, [
|
|
222
270
|
"styleId",
|
|
223
271
|
"listLevel",
|
|
224
|
-
"alignment"
|
|
272
|
+
"alignment",
|
|
273
|
+
"spacing"
|
|
225
274
|
]);
|
|
226
275
|
const styleId = candidate["styleId"] === null ? null : readOptionalString(candidate, "styleId", propertiesPath);
|
|
227
276
|
const listLevel = readClearableNonNegativeInteger(candidate, "listLevel", propertiesPath);
|
|
@@ -230,11 +279,17 @@ const readParagraphProperties = (value, path) => {
|
|
|
230
279
|
key: "alignment",
|
|
231
280
|
path: propertiesPath
|
|
232
281
|
});
|
|
233
|
-
|
|
282
|
+
const spacing = readClearableParagraphSpacing({
|
|
283
|
+
value: candidate,
|
|
284
|
+
key: "spacing",
|
|
285
|
+
path: propertiesPath
|
|
286
|
+
});
|
|
287
|
+
if (styleId === void 0 && listLevel === void 0 && alignment === void 0 && spacing === void 0) return invalidBatch(propertiesPath, "expected at least one property to set");
|
|
234
288
|
return {
|
|
235
289
|
...styleId !== void 0 && { styleId },
|
|
236
290
|
...listLevel !== void 0 && { listLevel },
|
|
237
|
-
...alignment !== void 0 && { alignment }
|
|
291
|
+
...alignment !== void 0 && { alignment },
|
|
292
|
+
...spacing !== void 0 && { spacing }
|
|
238
293
|
};
|
|
239
294
|
};
|
|
240
295
|
const readTextRange = (value, path) => {
|
|
@@ -280,10 +335,10 @@ const readInlineFormatting = (value, path) => {
|
|
|
280
335
|
"fontSizePt",
|
|
281
336
|
"color"
|
|
282
337
|
]);
|
|
283
|
-
const bold =
|
|
284
|
-
const italic =
|
|
285
|
-
const underline =
|
|
286
|
-
const strike =
|
|
338
|
+
const bold = readClearableBoolean(candidate, "bold", formattingPath);
|
|
339
|
+
const italic = readClearableBoolean(candidate, "italic", formattingPath);
|
|
340
|
+
const underline = readClearableBoolean(candidate, "underline", formattingPath);
|
|
341
|
+
const strike = readClearableBoolean(candidate, "strike", formattingPath);
|
|
287
342
|
const fontFamily = readClearableNonEmptyString(candidate, "fontFamily", formattingPath);
|
|
288
343
|
const fontSizePt = readClearableFontSize(candidate, "fontSizePt", formattingPath);
|
|
289
344
|
const color = readClearableRgbColor(candidate, "color", formattingPath);
|
|
@@ -374,6 +429,7 @@ const FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE = Object.freeze({
|
|
|
374
429
|
"text",
|
|
375
430
|
"inheritFormatting",
|
|
376
431
|
"alignment",
|
|
432
|
+
"spacing",
|
|
377
433
|
"listLevel",
|
|
378
434
|
"moveId",
|
|
379
435
|
"pageBreakBefore",
|
|
@@ -385,6 +441,7 @@ const FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE = Object.freeze({
|
|
|
385
441
|
"text",
|
|
386
442
|
"inheritFormatting",
|
|
387
443
|
"alignment",
|
|
444
|
+
"spacing",
|
|
388
445
|
"listLevel",
|
|
389
446
|
"moveId",
|
|
390
447
|
"pageBreakBefore",
|
|
@@ -406,9 +463,15 @@ const FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE = Object.freeze({
|
|
|
406
463
|
splitBlock: [
|
|
407
464
|
...COMMON_OPERATION_KEYS,
|
|
408
465
|
"offset",
|
|
409
|
-
"separator"
|
|
466
|
+
"separator",
|
|
467
|
+
"firstParagraphProperties",
|
|
468
|
+
"secondParagraphProperties"
|
|
469
|
+
],
|
|
470
|
+
mergeBlockWithNext: [
|
|
471
|
+
...COMMON_OPERATION_KEYS,
|
|
472
|
+
"separator",
|
|
473
|
+
"mergedParagraphProperties"
|
|
410
474
|
],
|
|
411
|
-
mergeBlockWithNext: [...COMMON_OPERATION_KEYS, "separator"],
|
|
412
475
|
setBlockParagraphProperties: [...COMMON_OPERATION_KEYS, "properties"],
|
|
413
476
|
insertTable: [
|
|
414
477
|
...COMMON_OPERATION_KEYS,
|
|
@@ -531,24 +594,48 @@ const parseDocumentOperation = (value, index) => {
|
|
|
531
594
|
id,
|
|
532
595
|
type,
|
|
533
596
|
blockId,
|
|
534
|
-
properties: readParagraphProperties(
|
|
597
|
+
properties: readParagraphProperties({
|
|
598
|
+
value,
|
|
599
|
+
key: "properties",
|
|
600
|
+
path
|
|
601
|
+
})
|
|
535
602
|
};
|
|
536
603
|
if (type === "splitBlock" || type === "mergeBlockWithNext") {
|
|
537
604
|
const separator = readOptionalString(value, "separator", path);
|
|
538
|
-
if (type === "mergeBlockWithNext")
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
605
|
+
if (type === "mergeBlockWithNext") {
|
|
606
|
+
const mergedParagraphProperties = value["mergedParagraphProperties"] === void 0 ? void 0 : readParagraphProperties({
|
|
607
|
+
value,
|
|
608
|
+
key: "mergedParagraphProperties",
|
|
609
|
+
path
|
|
610
|
+
});
|
|
611
|
+
return {
|
|
612
|
+
...operationMeta,
|
|
613
|
+
id,
|
|
614
|
+
type,
|
|
615
|
+
blockId,
|
|
616
|
+
...separator !== void 0 && { separator },
|
|
617
|
+
...mergedParagraphProperties !== void 0 && { mergedParagraphProperties }
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
const firstParagraphProperties = value["firstParagraphProperties"] === void 0 ? void 0 : readParagraphProperties({
|
|
621
|
+
value,
|
|
622
|
+
key: "firstParagraphProperties",
|
|
623
|
+
path
|
|
624
|
+
});
|
|
625
|
+
const secondParagraphProperties = value["secondParagraphProperties"] === void 0 ? void 0 : readParagraphProperties({
|
|
626
|
+
value,
|
|
627
|
+
key: "secondParagraphProperties",
|
|
628
|
+
path
|
|
629
|
+
});
|
|
545
630
|
return {
|
|
546
631
|
...operationMeta,
|
|
547
632
|
id,
|
|
548
633
|
type,
|
|
549
634
|
blockId,
|
|
550
635
|
offset: readNonNegativeInteger(value, "offset", path),
|
|
551
|
-
...separator !== void 0 && { separator }
|
|
636
|
+
...separator !== void 0 && { separator },
|
|
637
|
+
...firstParagraphProperties !== void 0 && { firstParagraphProperties },
|
|
638
|
+
...secondParagraphProperties !== void 0 && { secondParagraphProperties }
|
|
552
639
|
};
|
|
553
640
|
}
|
|
554
641
|
if (type === "replaceInBlock") return {
|
|
@@ -571,6 +658,11 @@ const parseDocumentOperation = (value, index) => {
|
|
|
571
658
|
key: "alignment",
|
|
572
659
|
path
|
|
573
660
|
});
|
|
661
|
+
const spacing = readClearableParagraphSpacing({
|
|
662
|
+
value,
|
|
663
|
+
key: "spacing",
|
|
664
|
+
path
|
|
665
|
+
});
|
|
574
666
|
return {
|
|
575
667
|
...operationMeta,
|
|
576
668
|
id,
|
|
@@ -579,6 +671,7 @@ const parseDocumentOperation = (value, index) => {
|
|
|
579
671
|
text: readString(value, "text", path),
|
|
580
672
|
...inheritFormatting !== void 0 && { inheritFormatting },
|
|
581
673
|
...alignment !== void 0 && { alignment },
|
|
674
|
+
...spacing !== void 0 && { spacing },
|
|
582
675
|
...listLevel !== void 0 && { listLevel },
|
|
583
676
|
...moveId !== void 0 && { moveId },
|
|
584
677
|
...pageBreakBefore !== void 0 && { pageBreakBefore },
|
|
@@ -762,6 +855,8 @@ const recoveryByReason = {
|
|
|
762
855
|
preconditionFailed: "refreshDocument",
|
|
763
856
|
staleRange: "refreshDocument",
|
|
764
857
|
emptyOperation: "removeOperation",
|
|
858
|
+
pendingParagraphPropertyChange: "resolveTrackedChange",
|
|
859
|
+
pendingRunPropertyChange: "resolveTrackedChange",
|
|
765
860
|
noopOperation: "removeOperation",
|
|
766
861
|
documentVersionMismatch: "refreshDocument",
|
|
767
862
|
documentNotEditable: "retryLater"
|
|
@@ -778,7 +873,7 @@ const getFolioDocumentOperationIssues = (operations, skipped) => {
|
|
|
778
873
|
operationIndex,
|
|
779
874
|
path: `$.operations[${operationIndex}]`,
|
|
780
875
|
code: reason,
|
|
781
|
-
retryable: reason !== "emptyOperation" && reason !== "noopOperation",
|
|
876
|
+
retryable: reason !== "emptyOperation" && reason !== "noopOperation" && reason !== "pendingParagraphPropertyChange" && reason !== "pendingRunPropertyChange",
|
|
782
877
|
recovery: recoveryByReason[reason]
|
|
783
878
|
};
|
|
784
879
|
});
|
|
@@ -1008,4 +1103,4 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
1008
1103
|
};
|
|
1009
1104
|
};
|
|
1010
1105
|
//#endregion
|
|
1011
|
-
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_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
1106
|
+
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_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
@@ -9,7 +9,7 @@ import { parseTable } from "./tableParser.js";
|
|
|
9
9
|
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
10
10
|
import { findChild, getChildElements, getLocalName, mergeXmlnsDeclarations } from "./xmlParser.js";
|
|
11
11
|
//#region src/docx/blockContentParser.ts
|
|
12
|
-
const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList
|
|
12
|
+
const computeListMarker = (paragraph, { numbering, listCounters, abstractCounters, restartedNumIds, previousList }) => {
|
|
13
13
|
const listRendering = paragraph.listRendering;
|
|
14
14
|
if (!listRendering || !numbering) {
|
|
15
15
|
previousList.abstractNumId = null;
|
|
@@ -26,26 +26,17 @@ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounter
|
|
|
26
26
|
}
|
|
27
27
|
const firstEncounter = !listCounters.has(numId);
|
|
28
28
|
if (firstEncounter) listCounters.set(numId, Array.from({ length: 9 }).fill(NaN));
|
|
29
|
-
|
|
29
|
+
let counters = listCounters.get(numId);
|
|
30
30
|
if (!counters) return;
|
|
31
31
|
const abstractNumId = numbering.getAbstractNumId(numId);
|
|
32
|
-
if (firstEncounter && abstractNumId !== null) {
|
|
33
|
-
let siblingNumIds = siblingNumIdsByAbstractNumId.get(abstractNumId);
|
|
34
|
-
if (!siblingNumIds) {
|
|
35
|
-
siblingNumIds = /* @__PURE__ */ new Set();
|
|
36
|
-
siblingNumIdsByAbstractNumId.set(abstractNumId, siblingNumIds);
|
|
37
|
-
}
|
|
38
|
-
siblingNumIds.add(numId);
|
|
39
|
-
}
|
|
40
32
|
const styleNumbering = paragraph.formatting?.numPrFromStyle;
|
|
41
|
-
let resumedAbstractCounters;
|
|
42
33
|
const resumesRestartedInstance = firstEncounter && listRendering.startOverride === void 0 && abstractNumId !== null && previousList.abstractNumId === abstractNumId && previousList.numId !== null && previousList.numId !== numId && restartedNumIds.has(previousList.numId);
|
|
43
34
|
const resumesStyleInstance = firstEncounter && !styleNumbering && listRendering.startOverride === void 0 && abstractNumId !== null && previousList.abstractNumId === abstractNumId && previousList.fromStyle === true;
|
|
44
35
|
if (abstractNumId !== null && (styleNumbering || resumesRestartedInstance || resumesStyleInstance)) {
|
|
45
36
|
const latestAbstractCounters = abstractCounters.get(abstractNumId);
|
|
46
37
|
if (latestAbstractCounters) {
|
|
47
|
-
|
|
48
|
-
|
|
38
|
+
counters = latestAbstractCounters;
|
|
39
|
+
listCounters.set(numId, counters);
|
|
49
40
|
}
|
|
50
41
|
}
|
|
51
42
|
if (listRendering.startOverride !== void 0 || resumesRestartedInstance || previousList.numId === numId && restartedNumIds.has(numId)) restartedNumIds.add(numId);
|
|
@@ -64,17 +55,7 @@ const computeListMarker = (paragraph, { numbering, listCounters, abstractCounter
|
|
|
64
55
|
const childCounter = counters[level + 1];
|
|
65
56
|
counters[level + 1] = (childCounter === void 0 || Number.isNaN(childCounter) ? 0 : childCounter) + childAdvances;
|
|
66
57
|
}
|
|
67
|
-
if (abstractNumId !== null)
|
|
68
|
-
if (resumedAbstractCounters) {
|
|
69
|
-
const siblingNumIds = siblingNumIdsByAbstractNumId.get(abstractNumId);
|
|
70
|
-
for (const otherNumId of siblingNumIds ?? []) {
|
|
71
|
-
const otherCounters = listCounters.get(otherNumId);
|
|
72
|
-
if (otherNumId === numId || !otherCounters || !otherCounters.every((value, index) => Object.is(value, resumedAbstractCounters[index]))) continue;
|
|
73
|
-
for (let i = 0; i < otherCounters.length; i += 1) otherCounters[i] = counters[i] ?? NaN;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
abstractCounters.set(abstractNumId, [...counters]);
|
|
77
|
-
}
|
|
58
|
+
if (abstractNumId !== null) abstractCounters.set(abstractNumId, counters);
|
|
78
59
|
previousList.abstractNumId = abstractNumId;
|
|
79
60
|
previousList.fromStyle = Boolean(styleNumbering);
|
|
80
61
|
previousList.numId = numId;
|
|
@@ -108,7 +89,6 @@ const parseBlockContent = (parent, styles, theme, numbering, rels, media, option
|
|
|
108
89
|
fromStyle: false,
|
|
109
90
|
numId: null
|
|
110
91
|
},
|
|
111
|
-
siblingNumIdsByAbstractNumId: /* @__PURE__ */ new Map(),
|
|
112
92
|
options: {
|
|
113
93
|
...options,
|
|
114
94
|
rootXmlns: mergeXmlnsDeclarations(options?.rootXmlns ?? {}, parent)
|
|
@@ -129,8 +109,7 @@ const parseBlockContentWithState = (parent, styles, theme, numbering, rels, medi
|
|
|
129
109
|
listCounters: state.listCounters,
|
|
130
110
|
abstractCounters: state.abstractCounters,
|
|
131
111
|
restartedNumIds: state.restartedNumIds,
|
|
132
|
-
previousList: state.previousList
|
|
133
|
-
siblingNumIdsByAbstractNumId: state.siblingNumIdsByAbstractNumId
|
|
112
|
+
previousList: state.previousList
|
|
134
113
|
});
|
|
135
114
|
content.push(paragraph);
|
|
136
115
|
continue;
|
|
@@ -392,10 +392,15 @@ const ensureParaIdsInternal = async (docx, options) => {
|
|
|
392
392
|
};
|
|
393
393
|
const zip = await JSZip.loadAsync(docx);
|
|
394
394
|
if (hasDigitalSignatureParts(zip) && options.allowSignedPackageMutation !== true) throw createEnsureParaIdsError("Refusing to normalize a digitally signed package because rewriting OOXML invalidates its signatures. Warn the user and pass allowSignedPackageMutation only if invalidation is acceptable.");
|
|
395
|
-
for (const [partPath, content] of updates)
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
395
|
+
for (const [partPath, content] of updates) {
|
|
396
|
+
const sourceEntry = zip.file(partPath);
|
|
397
|
+
if (sourceEntry === null) throw createEnsureParaIdsError(`Package part disappeared during normalization: ${partPath}`);
|
|
398
|
+
zip.file(partPath, content, {
|
|
399
|
+
compression: "DEFLATE",
|
|
400
|
+
compressionOptions: { level: 6 },
|
|
401
|
+
date: sourceEntry.date
|
|
402
|
+
});
|
|
403
|
+
}
|
|
399
404
|
return {
|
|
400
405
|
docx: await zip.generateAsync({
|
|
401
406
|
type: "uint8array",
|
|
@@ -80,5 +80,7 @@ declare function getBulletCharacter(level: document_d_exports.ListLevel): string
|
|
|
80
80
|
* Check if a list level is a bullet (not numbered)
|
|
81
81
|
*/
|
|
82
82
|
declare function isBulletLevel(level: document_d_exports.ListLevel): boolean;
|
|
83
|
+
/** Whether a numbering level reserves horizontal space for a visible marker. */
|
|
84
|
+
declare const numberingLevelHasMarkerSlot: (level: Pick<document_d_exports.ListLevel, "numFmt">) => boolean;
|
|
83
85
|
//#endregion
|
|
84
|
-
export { NumberingMap, computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numPrEqual, padDecimal, parseNumbering, renderListMarker };
|
|
86
|
+
export { NumberingMap, computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numPrEqual, numberingLevelHasMarkerSlot, padDecimal, parseNumbering, renderListMarker };
|
|
@@ -542,6 +542,7 @@ function computeListRendering(numPr, numbering) {
|
|
|
542
542
|
level: ilvl,
|
|
543
543
|
numId,
|
|
544
544
|
marker: level.lvlText,
|
|
545
|
+
markerTemplate: level.lvlText,
|
|
545
546
|
isBullet: level.numFmt === "bullet",
|
|
546
547
|
numFmt: level.isLgl ? "decimal" : level.numFmt,
|
|
547
548
|
levelNumFmts,
|
|
@@ -609,5 +610,7 @@ function getBulletCharacter(level) {
|
|
|
609
610
|
function isBulletLevel(level) {
|
|
610
611
|
return level.numFmt === "bullet" || level.numFmt === "none";
|
|
611
612
|
}
|
|
613
|
+
/** Whether a numbering level reserves horizontal space for a visible marker. */
|
|
614
|
+
const numberingLevelHasMarkerSlot = (level) => level.numFmt !== "none";
|
|
612
615
|
//#endregion
|
|
613
|
-
export { computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numPrEqual, padDecimal, parseNumbering, renderListMarker };
|
|
616
|
+
export { computeListRendering, createNumberingMap, formatOoxmlCounter as formatNumber, getBulletCharacter, getCachedNumberingMap, isBulletLevel, markerFormattingFromLevel, numPrEqual, numberingLevelHasMarkerSlot, padDecimal, parseNumbering, renderListMarker };
|
|
@@ -4,7 +4,7 @@ import { isValidHexId } from "../utils/hexId.js";
|
|
|
4
4
|
import { parseBookmarkEnd as parseBookmarkEnd$1, parseBookmarkStart as parseBookmarkStart$1 } from "./bookmarkParser.js";
|
|
5
5
|
import { parseFieldType } from "./fieldParser.js";
|
|
6
6
|
import { parseHyperlink as parseHyperlink$1, parseHyperlinkChild } from "./hyperlinkParser.js";
|
|
7
|
-
import { markerFormattingFromLevel } from "./numberingParser.js";
|
|
7
|
+
import { markerFormattingFromLevel, numberingLevelHasMarkerSlot } from "./numberingParser.js";
|
|
8
8
|
import { paraIdInRange } from "./paraIdRangeNormalization.js";
|
|
9
9
|
import { assignParagraphPropertySource } from "./paragraphPropertySource.js";
|
|
10
10
|
import { BorderStyleSchema, FrameWrapSchema, FrameXAlignSchema, FrameYAlignSchema, LineSpacingRuleSchema, ParagraphAlignmentSchema, ShadingPatternSchema, TabLeaderSchema, TabStopAlignmentSchema, ThemeColorSlotSchema, narrowEnum } from "./parserEnums.js";
|
|
@@ -495,10 +495,10 @@ function normalizeDeletionContentElement(node) {
|
|
|
495
495
|
let mappedName = node.name;
|
|
496
496
|
if (localName === "delText") mappedName = replaceLocalName(node.name, "t");
|
|
497
497
|
else if (localName === "delInstrText") mappedName = replaceLocalName(node.name, "instrText");
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
498
|
+
return cloneElement(node, {
|
|
499
|
+
...mappedName !== void 0 ? { name: mappedName } : {},
|
|
500
|
+
...node.elements ? { elements: node.elements.map(normalizeDeletionContentElement) } : {}
|
|
501
|
+
});
|
|
502
502
|
}
|
|
503
503
|
function parseParagraphPropertyChanges(pPr, theme, styles, currentFormatting) {
|
|
504
504
|
if (!pPr) return;
|
|
@@ -1122,6 +1122,7 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
|
|
|
1122
1122
|
level: ilvl,
|
|
1123
1123
|
numId,
|
|
1124
1124
|
marker: level.lvlText,
|
|
1125
|
+
markerTemplate: level.lvlText,
|
|
1125
1126
|
isBullet: level.numFmt === "bullet",
|
|
1126
1127
|
levelNumFmts,
|
|
1127
1128
|
levelStarts
|
|
@@ -1186,7 +1187,7 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
|
|
|
1186
1187
|
const directHanging = directInd ? parseNumericAttribute(directInd, "w", "hanging") : void 0;
|
|
1187
1188
|
const hasDirectFirstLineOrHanging = directFirstLine !== void 0 && directFirstLine !== 0 || directHanging !== void 0 && directHanging !== 0;
|
|
1188
1189
|
if (!hasDirectLeft && !chainInd.left && level.pPr.indentLeft !== void 0) paragraph.formatting.indentLeft = level.pPr.indentLeft;
|
|
1189
|
-
if (!hasDirectFirstLineOrHanging && !chainInd.firstLine) {
|
|
1190
|
+
if (!hasDirectFirstLineOrHanging && !chainInd.firstLine && numberingLevelHasMarkerSlot(level)) {
|
|
1190
1191
|
if (level.pPr.indentFirstLine !== void 0) paragraph.formatting.indentFirstLine = level.pPr.indentFirstLine;
|
|
1191
1192
|
if (level.pPr.hangingIndent !== void 0) paragraph.formatting.hangingIndent = level.pPr.hangingIndent;
|
|
1192
1193
|
}
|
|
@@ -1,41 +1,37 @@
|
|
|
1
1
|
//#region src/docx/paragraphTraversal.ts
|
|
2
2
|
/** Visit every run directly owned by a paragraph's inline-content tree. */
|
|
3
3
|
const visitParagraphRuns = (paragraph, visit) => {
|
|
4
|
-
const visitRun = (run) => {
|
|
5
|
-
visit(run);
|
|
6
|
-
};
|
|
7
|
-
const visitHyperlink = (hyperlink) => {
|
|
8
|
-
for (const child of hyperlink.children) if (child.type === "run") visitRun(child);
|
|
9
|
-
};
|
|
10
|
-
const visitInlineContent = (content) => {
|
|
11
|
-
for (const child of content) {
|
|
12
|
-
if (child.type === "run") {
|
|
13
|
-
visitRun(child);
|
|
14
|
-
continue;
|
|
15
|
-
}
|
|
16
|
-
if (child.type === "hyperlink") visitHyperlink(child);
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
4
|
const visitParagraphContent = (content) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
5
|
+
switch (content.type) {
|
|
6
|
+
case "run":
|
|
7
|
+
visit(content);
|
|
8
|
+
return;
|
|
9
|
+
case "hyperlink":
|
|
10
|
+
for (const child of content.children) visitParagraphContent(child);
|
|
11
|
+
return;
|
|
12
|
+
case "simpleField":
|
|
13
|
+
case "insertion":
|
|
14
|
+
case "deletion":
|
|
15
|
+
case "moveFrom":
|
|
16
|
+
case "moveTo":
|
|
17
|
+
case "inlineSdt":
|
|
18
|
+
for (const child of content.content) visitParagraphContent(child);
|
|
19
|
+
return;
|
|
20
|
+
case "complexField":
|
|
21
|
+
for (const run of content.fieldCode) visit(run);
|
|
22
|
+
for (const run of content.fieldResult) visit(run);
|
|
23
|
+
return;
|
|
24
|
+
case "bookmarkStart":
|
|
25
|
+
case "bookmarkEnd":
|
|
26
|
+
case "commentRangeStart":
|
|
27
|
+
case "commentRangeEnd":
|
|
28
|
+
case "commentReference":
|
|
29
|
+
case "moveFromRangeStart":
|
|
30
|
+
case "moveFromRangeEnd":
|
|
31
|
+
case "moveToRangeStart":
|
|
32
|
+
case "moveToRangeEnd":
|
|
33
|
+
case "mathEquation": return;
|
|
34
|
+
default: return content;
|
|
39
35
|
}
|
|
40
36
|
};
|
|
41
37
|
for (const content of paragraph.content) visitParagraphContent(content);
|
package/dist/docx/rezip.d.ts
CHANGED
|
@@ -28,14 +28,6 @@ type RepackOptions = {
|
|
|
28
28
|
/** Changed note paragraphs that must be serialized even without source paraIds. */
|
|
29
29
|
changedNoteParaIds?: ReadonlySet<string>;
|
|
30
30
|
};
|
|
31
|
-
/**
|
|
32
|
-
* Repack a Document into a valid DOCX file
|
|
33
|
-
*
|
|
34
|
-
* @param doc - Document with modified content
|
|
35
|
-
* @param options - Optional repack options
|
|
36
|
-
* @returns Promise resolving to DOCX as ArrayBuffer
|
|
37
|
-
* @throws {Error} if document has no original buffer for round-trip
|
|
38
|
-
*/
|
|
39
31
|
declare function repackDocx(doc: document_d_exports.Document, options?: RepackOptions): Promise<ArrayBuffer>;
|
|
40
32
|
/**
|
|
41
33
|
* Repack a Document using raw content for more control
|