@stll/folio-core 0.66.1 → 0.66.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.d.ts +13 -1
- package/dist/ai-edits/apply.js +533 -136
- package/dist/ai-edits/batch-claims.d.ts +26 -0
- package/dist/ai-edits/batch-claims.js +30 -5
- package/dist/ai-edits/headless.d.ts +6 -0
- package/dist/ai-edits/headless.js +25 -3
- package/dist/ai-edits/newListNumbering.d.ts +4 -1
- package/dist/ai-edits/newListNumbering.js +4 -2
- package/dist/ai-edits/types.d.ts +1 -1
- package/dist/document-operations.d.ts +13 -1
- package/dist/document-operations.js +11 -4
- package/dist/docx/listNumberingInstances.d.ts +6 -4
- package/dist/docx/listNumberingInstances.js +12 -11
- package/dist/docx/numberingIds.d.ts +10 -0
- package/dist/docx/numberingIds.js +5 -1
- package/dist/docx/paragraphParser.js +16 -3
- package/dist/docx/paragraphProperties.js +2 -1
- package/dist/docx/serializer/paragraphSerializer.js +86 -66
- package/dist/i18n/messages/ar.gen.js +1 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +17 -0
- package/dist/i18n/messages/catalogs.gen.js +17 -0
- package/dist/i18n/messages/cs.gen.js +1 -0
- package/dist/i18n/messages/de.gen.js +1 -0
- package/dist/i18n/messages/en.gen.js +1 -0
- package/dist/i18n/messages/es.gen.js +1 -0
- package/dist/i18n/messages/et.gen.js +1 -0
- package/dist/i18n/messages/fr.gen.js +1 -0
- package/dist/i18n/messages/he.gen.js +1 -0
- package/dist/i18n/messages/hi.gen.js +1 -0
- package/dist/i18n/messages/hu.gen.js +1 -0
- package/dist/i18n/messages/lt.gen.js +1 -0
- package/dist/i18n/messages/lv.gen.js +1 -0
- package/dist/i18n/messages/messages.gen.d.ts +1 -0
- package/dist/i18n/messages/pl.gen.js +1 -0
- package/dist/i18n/messages/pt-BR.gen.js +1 -0
- package/dist/i18n/messages/sk.gen.js +1 -0
- package/dist/i18n/messages/tr.gen.js +1 -0
- package/dist/i18n/messages/zh-CN.gen.js +1 -0
- package/dist/internal/wholeStoryRevisionResolution.d.ts +1 -1
- package/dist/internal/wholeStoryRevisionResolution.js +24 -9
- package/dist/layout-bridge/convert/runMarkFormatting.js +1 -0
- package/dist/markdown/renderRuns.js +68 -12
- package/dist/prosemirror/commands/comments.js +2 -0
- package/dist/prosemirror/commands/resolveParagraphProperties.js +15 -2
- package/dist/prosemirror/conversion/fromProseDoc.js +55 -18
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +23 -1
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +46 -1
- package/dist/prosemirror/conversion/toProseDoc.js +15 -9
- package/dist/prosemirror/extensions/StarterKit.js +1 -1
- package/dist/prosemirror/extensions/features/pasteCleanup.js +6 -0
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -1
- package/dist/prosemirror/extensions/markRegistry.d.ts +3 -1
- package/dist/prosemirror/extensions/markRegistry.js +3 -0
- package/dist/prosemirror/extensions/marks/HyphenElementExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/marks/HyphenElementExtension.js +54 -0
- package/dist/prosemirror/fieldRepresentation.js +2 -1
- package/dist/prosemirror/hyphenElementAttrs.d.ts +10 -0
- package/dist/prosemirror/hyphenElementAttrs.js +32 -0
- package/dist/prosemirror/keptRangeBoundaries.d.ts +2 -0
- package/dist/prosemirror/keptRangeBoundaries.js +1 -1
- package/dist/prosemirror/listNumbering.js +3 -2
- package/dist/prosemirror/paragraphIndentation.js +2 -1
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +1 -14
- package/dist/prosemirror/paragraphPropertyCarry.js +4 -28
- package/dist/prosemirror/plugins/suggestionMode.js +19 -6
- package/dist/prosemirror/replacedAnnotations.d.ts +1 -0
- package/dist/prosemirror/replacedAnnotations.js +1 -0
- package/dist/prosemirror/sectionCarrier.d.ts +8 -0
- package/dist/prosemirror/sectionCarrier.js +29 -1
- package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +10 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +12 -2
- package/dist/prosemirror/tableRunIn.d.ts +24 -9
- package/dist/prosemirror/tableRunIn.js +107 -21
- package/dist/prosemirror/textInput.js +3 -1
- package/dist/prosemirror/validation.js +6 -0
- package/dist/utils/createDocument.js +11 -8
- package/dist/utils/formatToStyle.js +2 -2
- package/dist/utils/units.d.ts +5 -0
- package/dist/utils/units.js +6 -1
- package/package.json +3 -3
|
@@ -26,6 +26,12 @@ type PositionRange = {
|
|
|
26
26
|
from: number;
|
|
27
27
|
to: number;
|
|
28
28
|
};
|
|
29
|
+
/** A paragraph before a deleted one that ends its container; see `paragraphsBefore`. */
|
|
30
|
+
type ParagraphBefore = {
|
|
31
|
+
block: number;
|
|
32
|
+
/** Its break is not already pending deletion. */
|
|
33
|
+
keepsBreak: boolean;
|
|
34
|
+
};
|
|
29
35
|
/** The text an operation rewrites (`text`), only marks (`annotation`), or breaks (`split`). */
|
|
30
36
|
type InlineClaim = {
|
|
31
37
|
type: "text" | "annotation" | "split";
|
|
@@ -55,6 +61,17 @@ export type BatchClaim = InlineClaim |
|
|
|
55
61
|
* any other does — see `followedByInsertion`.
|
|
56
62
|
*/
|
|
57
63
|
keepsParagraph: boolean;
|
|
64
|
+
/** The paragraph ends its container, before anything the batch adds. */
|
|
65
|
+
endsContainer: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Tracked, the paragraphs before one that ends its container, nearest
|
|
68
|
+
* first, up to the container's start or a block that is not one. The
|
|
69
|
+
* nearest the batch keeps, when its break stays, is the one whose break
|
|
70
|
+
* the deletion retires: accepting runs it into this paragraph with its
|
|
71
|
+
* own properties, as applied directly this one goes. Empty applied
|
|
72
|
+
* directly, and for a paragraph that ends nothing.
|
|
73
|
+
*/
|
|
74
|
+
paragraphsBefore: readonly ParagraphBefore[];
|
|
58
75
|
} |
|
|
59
76
|
/**
|
|
60
77
|
* Joins `block` with the block starting at `next`, where `block` ends.
|
|
@@ -128,6 +145,15 @@ export declare class BatchClaims {
|
|
|
128
145
|
private readonly columnInsertions;
|
|
129
146
|
/** Accepted deletions that keep their paragraph, by where the paragraph starts and ends. */
|
|
130
147
|
private readonly keptParagraphs;
|
|
148
|
+
/**
|
|
149
|
+
* Whether a tracked deletion of a paragraph that ends its container retires
|
|
150
|
+
* the break of the paragraph before, given the claims accepted so far: the
|
|
151
|
+
* nearest paragraph before it the batch does not delete keeps its break,
|
|
152
|
+
* and no merge of the batch deletes that break first.
|
|
153
|
+
*/
|
|
154
|
+
private retiresBreakBefore;
|
|
155
|
+
/** `role` with what it takes from the batch's other claims settled. */
|
|
156
|
+
private settled;
|
|
131
157
|
/** `claim`'s roles, given the insertions accepted so far. */
|
|
132
158
|
private rolesOf;
|
|
133
159
|
/**
|
|
@@ -43,7 +43,10 @@ const blockRolesOf = (claim) => {
|
|
|
43
43
|
block: claim.block,
|
|
44
44
|
role: {
|
|
45
45
|
kind: "deleteBlock",
|
|
46
|
-
keepsParagraph: claim.keepsParagraph
|
|
46
|
+
keepsParagraph: claim.keepsParagraph,
|
|
47
|
+
endsContainer: claim.endsContainer,
|
|
48
|
+
paragraphsBefore: claim.paragraphsBefore,
|
|
49
|
+
retiresBreakBefore: false
|
|
47
50
|
}
|
|
48
51
|
}];
|
|
49
52
|
case "merge": return [{
|
|
@@ -105,7 +108,7 @@ const rolesConflict = (left, right) => {
|
|
|
105
108
|
if (ROLE_RANK[right.kind] > ROLE_RANK[left.kind]) return rolesConflict(right, left);
|
|
106
109
|
switch (left.kind) {
|
|
107
110
|
case "deleteBlock": switch (right.kind) {
|
|
108
|
-
case "paragraphProperties": return !left.keepsParagraph;
|
|
111
|
+
case "paragraphProperties": return left.endsContainer && (!left.keepsParagraph || left.retiresBreakBefore);
|
|
109
112
|
case "mergeNext": return false;
|
|
110
113
|
default: return true;
|
|
111
114
|
}
|
|
@@ -122,7 +125,7 @@ const rolesConflict = (left, right) => {
|
|
|
122
125
|
case "mergeNext": return false;
|
|
123
126
|
default: return true;
|
|
124
127
|
}
|
|
125
|
-
case "mergeNext": return right.kind === "paragraphProperties" &&
|
|
128
|
+
case "mergeNext": return right.kind === "paragraphProperties" && left.setsProperties;
|
|
126
129
|
case "paragraphProperties": return right.kind === "split" || right.kind === "paragraphProperties";
|
|
127
130
|
case "split":
|
|
128
131
|
case "text":
|
|
@@ -155,6 +158,27 @@ var BatchClaims = class {
|
|
|
155
158
|
columnInsertions = /* @__PURE__ */ new Map();
|
|
156
159
|
/** Accepted deletions that keep their paragraph, by where the paragraph starts and ends. */
|
|
157
160
|
keptParagraphs = /* @__PURE__ */ new Map();
|
|
161
|
+
/**
|
|
162
|
+
* Whether a tracked deletion of a paragraph that ends its container retires
|
|
163
|
+
* the break of the paragraph before, given the claims accepted so far: the
|
|
164
|
+
* nearest paragraph before it the batch does not delete keeps its break,
|
|
165
|
+
* and no merge of the batch deletes that break first.
|
|
166
|
+
*/
|
|
167
|
+
retiresBreakBefore(role) {
|
|
168
|
+
for (const { block, keepsBreak } of role.paragraphsBefore) {
|
|
169
|
+
const entries = this.blocks.get(block) ?? [];
|
|
170
|
+
if (entries.some((entry) => entry.role.kind === "deleteBlock")) continue;
|
|
171
|
+
return keepsBreak && !entries.some((entry) => entry.role.kind === "mergeOwn");
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
/** `role` with what it takes from the batch's other claims settled. */
|
|
176
|
+
settled(role) {
|
|
177
|
+
return role.kind === "deleteBlock" ? {
|
|
178
|
+
...role,
|
|
179
|
+
retiresBreakBefore: this.retiresBreakBefore(role)
|
|
180
|
+
} : role;
|
|
181
|
+
}
|
|
158
182
|
/** `claim`'s roles, given the insertions accepted so far. */
|
|
159
183
|
rolesOf(claim) {
|
|
160
184
|
return blockRolesOf(claim).map(({ block, role }) => role.kind === "deleteBlock" && role.keepsParagraph && claim.type === "deleteBlock" && (this.insertions.has(claim.end) || this.insertions.has(claim.block)) ? {
|
|
@@ -184,8 +208,9 @@ var BatchClaims = class {
|
|
|
184
208
|
* conflicts with none.
|
|
185
209
|
*/
|
|
186
210
|
conflictOf(claim) {
|
|
187
|
-
for (const { block, role } of this.rolesOf(claim)) {
|
|
188
|
-
|
|
211
|
+
for (const { block, role: claimed } of this.rolesOf(claim)) {
|
|
212
|
+
const role = this.settled(claimed);
|
|
213
|
+
for (const entry of this.blocks.get(block) ?? []) if (rolesConflict(this.settled(entry.role), role)) return entry.operationId;
|
|
189
214
|
const fold = this.foldAt(block);
|
|
190
215
|
if (fold !== null) return fold;
|
|
191
216
|
if (role.kind === "deleteBlock") continue;
|
|
@@ -383,6 +383,12 @@ export declare class FolioDocxReviewer {
|
|
|
383
383
|
* the anchor map the apply layer resolves operations against.
|
|
384
384
|
*/
|
|
385
385
|
snapshot(): FolioAIEditSnapshot;
|
|
386
|
+
/**
|
|
387
|
+
* The numbering ids every story but `story` defines: the package's and the
|
|
388
|
+
* lists each story started. Numbering ids are package-wide, while a story's
|
|
389
|
+
* state completes its numbering from its own paragraphs only.
|
|
390
|
+
*/
|
|
391
|
+
private numberingIdsOutside;
|
|
386
392
|
/** Every suggestion id the document's stories still carry. */
|
|
387
393
|
private activeSuggestionIds;
|
|
388
394
|
/** Export staged AI operations for storage by the host, outside the DOCX. */
|
|
@@ -2,7 +2,7 @@ import { matchInlineAtoms } from "../compare/inline-atoms.js";
|
|
|
2
2
|
import { matchInlineProvenance } from "../compare/inline-provenance.js";
|
|
3
3
|
import { stageSectionBoundaryProperties } from "../compare/section-boundary-properties.js";
|
|
4
4
|
import { importReferencedStyleDefinitions, styleClosureNumberingReferences } from "../compare/style-resources.js";
|
|
5
|
-
import {
|
|
5
|
+
import { applyFolioDocumentOperationsInPackage } from "../document-operations.js";
|
|
6
6
|
import { removeCommentMarkers } from "../docx/commentAnchorIndex.js";
|
|
7
7
|
import { applyReplyThreadMarkers } from "../docx/commentReplyMarkers.js";
|
|
8
8
|
import { commentTextParagraph } from "../docx/commentTextParagraph.js";
|
|
@@ -620,6 +620,26 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
620
620
|
snapshot() {
|
|
621
621
|
return createStateSnapshot(this.state);
|
|
622
622
|
}
|
|
623
|
+
/**
|
|
624
|
+
* The numbering ids every story but `story` defines: the package's and the
|
|
625
|
+
* lists each story started. Numbering ids are package-wide, while a story's
|
|
626
|
+
* state completes its numbering from its own paragraphs only.
|
|
627
|
+
*/
|
|
628
|
+
numberingIdsOutside(story) {
|
|
629
|
+
const key = editableStoryKey(story);
|
|
630
|
+
const states = [...story.type === "main" ? [] : [this.state], ...[...this.secondaryStoryStates.values()].filter(({ handle }) => editableStoryKey(handle) !== key).map(({ state }) => state)];
|
|
631
|
+
const numIds = /* @__PURE__ */ new Set();
|
|
632
|
+
const abstractNumIds = /* @__PURE__ */ new Set();
|
|
633
|
+
for (const state of states) {
|
|
634
|
+
const definitions = getDocumentNumbering(state)?.definitions;
|
|
635
|
+
for (const { numId } of definitions?.nums ?? []) numIds.add(numId);
|
|
636
|
+
for (const { abstractNumId } of definitions?.abstractNums ?? []) abstractNumIds.add(abstractNumId);
|
|
637
|
+
}
|
|
638
|
+
return {
|
|
639
|
+
numIds,
|
|
640
|
+
abstractNumIds
|
|
641
|
+
};
|
|
642
|
+
}
|
|
623
643
|
/** Every suggestion id the document's stories still carry. */
|
|
624
644
|
activeSuggestionIds() {
|
|
625
645
|
const active = new Set(getSuggestions(this.state).map(({ suggestionId }) => suggestionId));
|
|
@@ -904,7 +924,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
904
924
|
view.state = view.state.apply(transaction);
|
|
905
925
|
}
|
|
906
926
|
};
|
|
907
|
-
const result =
|
|
927
|
+
const result = applyFolioDocumentOperationsInPackage({
|
|
908
928
|
view,
|
|
909
929
|
snapshot: sourceSnapshot,
|
|
910
930
|
batch,
|
|
@@ -915,6 +935,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
915
935
|
...tableTemplates !== void 0 && { tableTemplates },
|
|
916
936
|
...replacementBackground !== void 0 && { replacementBackground },
|
|
917
937
|
undefinedReferences,
|
|
938
|
+
numberingIdsElsewhere: this.numberingIdsOutside(story),
|
|
918
939
|
...restagesSuggestions === true ? { restagesSuggestions } : { pendingSuggestionIds: this.activeSuggestionIds() },
|
|
919
940
|
createCommentId: (text) => {
|
|
920
941
|
const comment = createReviewerComment({
|
|
@@ -1577,9 +1598,10 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
1577
1598
|
view.state = view.state.apply(transaction);
|
|
1578
1599
|
}
|
|
1579
1600
|
};
|
|
1580
|
-
const applied =
|
|
1601
|
+
const applied = applyFolioDocumentOperationsInPackage({
|
|
1581
1602
|
undefinedReferences: "refuse",
|
|
1582
1603
|
restagesSuggestions: true,
|
|
1604
|
+
numberingIdsElsewhere: this.numberingIdsOutside(story),
|
|
1583
1605
|
view,
|
|
1584
1606
|
snapshot,
|
|
1585
1607
|
batch: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NumberingIdsInUse } from "../docx/numberingIds.js";
|
|
1
2
|
import { FolioContentStatedNumbering } from "../compare/content-types.js";
|
|
2
3
|
import { ListKind } from "../docx/listNumberingInstances.js";
|
|
3
4
|
import { FolioAIEditOperation, FolioAIListNumbering, FolioAINewListReference, FolioAIResolvedEditOperation } from "./types.js";
|
|
@@ -23,6 +24,8 @@ export declare const stageNewListOperations: (operations: readonly FolioAIEditOp
|
|
|
23
24
|
* Replace every new-list request with a reference to an instance minted for
|
|
24
25
|
* its operation: one instance per operation and kind. `numbering` is the map
|
|
25
26
|
* the batch applies against; the result's map adds the minted instances.
|
|
27
|
+
* `elsewhere` holds the ids the package's other stories define, which no
|
|
28
|
+
* minted instance takes.
|
|
26
29
|
*/
|
|
27
|
-
export declare const resolveNewListOperations: (operations: readonly FolioAIStagedEditOperation[], numbering: NumberingMap | null) => ResolvedNewLists;
|
|
30
|
+
export declare const resolveNewListOperations: (operations: readonly FolioAIStagedEditOperation[], numbering: NumberingMap | null, elsewhere: NumberingIdsInUse) => ResolvedNewLists;
|
|
28
31
|
export {};
|
|
@@ -82,8 +82,10 @@ const stageNewListOperations = (operations) => deferNewListRequests(operations);
|
|
|
82
82
|
* Replace every new-list request with a reference to an instance minted for
|
|
83
83
|
* its operation: one instance per operation and kind. `numbering` is the map
|
|
84
84
|
* the batch applies against; the result's map adds the minted instances.
|
|
85
|
+
* `elsewhere` holds the ids the package's other stories define, which no
|
|
86
|
+
* minted instance takes.
|
|
85
87
|
*/
|
|
86
|
-
const resolveNewListOperations = (operations, numbering) => {
|
|
88
|
+
const resolveNewListOperations = (operations, numbering, elsewhere) => {
|
|
87
89
|
let definitions = numbering?.definitions;
|
|
88
90
|
let minted = false;
|
|
89
91
|
return {
|
|
@@ -94,7 +96,7 @@ const resolveNewListOperations = (operations, numbering) => {
|
|
|
94
96
|
if (value.kind !== "deferredNewList") return value;
|
|
95
97
|
let numId = instances.get(value.allocation);
|
|
96
98
|
if (numId === void 0) {
|
|
97
|
-
const instance = mintListInstance(definitions, { kind: value.allocation.format });
|
|
99
|
+
const instance = mintListInstance(definitions, { kind: value.allocation.format }, elsewhere);
|
|
98
100
|
definitions = instance.definitions;
|
|
99
101
|
minted = true;
|
|
100
102
|
numId = instance.numId;
|
package/dist/ai-edits/types.d.ts
CHANGED
|
@@ -654,7 +654,7 @@ export type FolioAIEditSkipReason = "missingBlock" | "changedBlock" | "ambiguous
|
|
|
654
654
|
* next to it.
|
|
655
655
|
*/
|
|
656
656
|
"pendingDeletion" |
|
|
657
|
-
/** Resolve the removed paragraph mark before editing its properties separately. */
|
|
657
|
+
/** Resolve the removed paragraph mark before editing its properties separately, or before inserting a paragraph between it and a table. */
|
|
658
658
|
"pendingParagraphMarkDeletion";
|
|
659
659
|
export type FolioAIEditAppliedOperation = {
|
|
660
660
|
id: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NumberingIdsInUse } from "./docx/numberingIds.js";
|
|
1
2
|
import { document_d_exports } from "./types/document.js";
|
|
2
3
|
import { FolioTableTemplates } from "./ai-edits/table-template.js";
|
|
3
4
|
import { FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditNormalization, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAITextRangeHandle } from "./ai-edits/types.js";
|
|
@@ -313,5 +314,16 @@ export type ApplyFolioDocumentOperationsOptions = {
|
|
|
313
314
|
*/
|
|
314
315
|
restagesSuggestions?: boolean;
|
|
315
316
|
};
|
|
316
|
-
export declare const applyFolioDocumentOperations: (
|
|
317
|
+
export declare const applyFolioDocumentOperations: (input: ApplyFolioDocumentOperationsOptions) => FolioDocumentOperationResult;
|
|
318
|
+
/**
|
|
319
|
+
* Options of a caller that holds every story of the package: the numbering
|
|
320
|
+
* ids (`w:num`, `w:abstractNum`) the other stories define. A list the batch
|
|
321
|
+
* starts takes none of them, so its id names it in every story and survives a
|
|
322
|
+
* save.
|
|
323
|
+
*/
|
|
324
|
+
type ApplyFolioDocumentOperationsInPackageOptions = ApplyFolioDocumentOperationsOptions & {
|
|
325
|
+
numberingIdsElsewhere: NumberingIdsInUse;
|
|
326
|
+
};
|
|
327
|
+
/** {@link applyFolioDocumentOperations} for a caller holding every story. Internal. */
|
|
328
|
+
export declare const applyFolioDocumentOperationsInPackage: ({ view, snapshot, batch, story, author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates, replacementBackground, undefinedReferences, pendingSuggestionIds, numberingIdsElsewhere, restagesSuggestions }: ApplyFolioDocumentOperationsInPackageOptions) => FolioDocumentOperationResult;
|
|
317
329
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { applyFolioAIEditOperationsInPackage, previewFolioAIEditOperationsWithResult } from "./ai-edits/apply.js";
|
|
2
2
|
import { describeModelError, findIntroducedModelErrors } from "./ai-edits/result-validation.js";
|
|
3
3
|
import { LIST_KINDS } from "./docx/listNumberingInstances.js";
|
|
4
|
+
import { NO_NUMBERING_IDS_IN_USE } from "./docx/numberingIds.js";
|
|
4
5
|
import { getSuggestions } from "./prosemirror/commands/comments.js";
|
|
5
6
|
import { completeNumberingForDoc } from "./prosemirror/listInstanceReferences.js";
|
|
6
7
|
import { outlineLevelFromAttrValue } from "./prosemirror/outlineLevelAttr.js";
|
|
@@ -1290,7 +1291,12 @@ const inOperationOrder = (operations, skipped) => {
|
|
|
1290
1291
|
const indexById = new Map(operations.map(({ id }, index) => [id, index]));
|
|
1291
1292
|
return [...skipped].sort((left, right) => (indexById.get(left.id) ?? -1) - (indexById.get(right.id) ?? -1));
|
|
1292
1293
|
};
|
|
1293
|
-
const applyFolioDocumentOperations = (
|
|
1294
|
+
const applyFolioDocumentOperations = (input) => applyFolioDocumentOperationsInPackage({
|
|
1295
|
+
...input,
|
|
1296
|
+
numberingIdsElsewhere: NO_NUMBERING_IDS_IN_USE
|
|
1297
|
+
});
|
|
1298
|
+
/** {@link applyFolioDocumentOperations} for a caller holding every story. Internal. */
|
|
1299
|
+
const applyFolioDocumentOperationsInPackage = ({ view, snapshot, batch, story = "main", author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates, replacementBackground, undefinedReferences, pendingSuggestionIds, numberingIdsElsewhere, restagesSuggestions }) => {
|
|
1294
1300
|
const validatedBatch = parseFolioDocumentOperationBatch(batch);
|
|
1295
1301
|
const parsedBatch = restagesSuggestions === true ? validatedBatch : withDistinctSuggestionIds(validatedBatch, /* @__PURE__ */ new Set([...getSuggestions(view.state).map(({ suggestionId }) => suggestionId), ...pendingSuggestionIds ?? []]));
|
|
1296
1302
|
const isAtomic = parsedBatch.atomic === true;
|
|
@@ -1306,6 +1312,7 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
1306
1312
|
...wordDiff !== void 0 && { wordDiff },
|
|
1307
1313
|
...tableTemplates !== void 0 && { tableTemplates },
|
|
1308
1314
|
...replacementBackground !== void 0 && { replacementBackground },
|
|
1315
|
+
numberingIdsElsewhere,
|
|
1309
1316
|
undefinedReferences
|
|
1310
1317
|
};
|
|
1311
1318
|
if (preview) return {
|
|
@@ -1319,7 +1326,7 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
1319
1326
|
const held = {};
|
|
1320
1327
|
const commentIds = [];
|
|
1321
1328
|
return {
|
|
1322
|
-
outcome:
|
|
1329
|
+
outcome: applyFolioAIEditOperationsInPackage({
|
|
1323
1330
|
...common,
|
|
1324
1331
|
view: {
|
|
1325
1332
|
state: view.state,
|
|
@@ -1510,4 +1517,4 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
|
|
|
1510
1517
|
undoHandle: result.applied.length > 0 && createUndoHandle !== void 0 ? createUndoHandle() : null
|
|
1511
1518
|
};
|
|
1512
1519
|
};
|
|
1513
|
-
export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PAGE_BREAK_CLEAR_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOperationReceiptsForStory, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
1520
|
+
export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_LINE_SPACING_RULE_VALUES, FOLIO_PAGE_BREAK_CLEAR_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, applyFolioDocumentOperationsInPackage, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOperationReceiptsForStory, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NumberingIdsInUse } from "./numberingIds.js";
|
|
1
2
|
import { document_d_exports } from "../types/document.js";
|
|
2
3
|
/** The two kinds of list a command can create. */
|
|
3
4
|
export declare const LIST_KINDS: readonly ["bullet", "numbered"];
|
|
@@ -23,10 +24,11 @@ type MintedListInstance = {
|
|
|
23
24
|
/**
|
|
24
25
|
* Define a new list: a new `w:abstractNum` of the requested kind and the
|
|
25
26
|
* `w:num` naming it. `definitions` must already hold every instance the
|
|
26
|
-
*
|
|
27
|
-
* collide with none of
|
|
27
|
+
* story references (see {@link completeListNumbering}), and `elsewhere` the
|
|
28
|
+
* ids the package's other stories define, so the new ids collide with none of
|
|
29
|
+
* them.
|
|
28
30
|
*/
|
|
29
|
-
export declare const mintListInstance: (definitions: document_d_exports.NumberingDefinitions | null | undefined, { kind, format, start }: NewListDefinition) => MintedListInstance;
|
|
31
|
+
export declare const mintListInstance: (definitions: document_d_exports.NumberingDefinitions | null | undefined, { kind, format, start }: NewListDefinition, elsewhere: NumberingIdsInUse) => MintedListInstance;
|
|
30
32
|
type RestartListInstanceOptions = {
|
|
31
33
|
abstractNumId: number;
|
|
32
34
|
ilvl: number;
|
|
@@ -38,7 +40,7 @@ type RestartListInstanceOptions = {
|
|
|
38
40
|
* makes a consumer count the instance on its own rather than continue the
|
|
39
41
|
* other instances of the same definition.
|
|
40
42
|
*/
|
|
41
|
-
export declare const restartListInstance: (definitions: document_d_exports.NumberingDefinitions | null | undefined, { abstractNumId, ilvl, start }: RestartListInstanceOptions) => MintedListInstance;
|
|
43
|
+
export declare const restartListInstance: (definitions: document_d_exports.NumberingDefinitions | null | undefined, { abstractNumId, ilvl, start }: RestartListInstanceOptions, elsewhere: NumberingIdsInUse) => MintedListInstance;
|
|
42
44
|
/** One paragraph's numbering reference and the rendering it resolved to. */
|
|
43
45
|
export type ListInstanceReference = {
|
|
44
46
|
numId: number;
|
|
@@ -117,25 +117,26 @@ const EMPTY_DEFINITIONS = {
|
|
|
117
117
|
nums: []
|
|
118
118
|
};
|
|
119
119
|
/** A fresh `w:numId` for `definitions`; zero is reserved for "no numbering". */
|
|
120
|
-
const nextNumId = (definitions) => mintNumberingId({
|
|
120
|
+
const nextNumId = (definitions, elsewhere) => mintNumberingId({
|
|
121
121
|
kind: "num",
|
|
122
|
-
existingIds: (definitions?.nums ?? []).map(({ numId }) => numId)
|
|
122
|
+
existingIds: [...(definitions?.nums ?? []).map(({ numId }) => numId), ...elsewhere.numIds]
|
|
123
123
|
});
|
|
124
124
|
/** A fresh `w:abstractNumId` for `definitions`. */
|
|
125
|
-
const nextAbstractNumId = (definitions) => mintNumberingId({
|
|
125
|
+
const nextAbstractNumId = (definitions, elsewhere) => mintNumberingId({
|
|
126
126
|
kind: "abstract",
|
|
127
|
-
existingIds: (definitions?.abstractNums ?? []).map(({ abstractNumId }) => abstractNumId)
|
|
127
|
+
existingIds: [...(definitions?.abstractNums ?? []).map(({ abstractNumId }) => abstractNumId), ...elsewhere.abstractNumIds]
|
|
128
128
|
});
|
|
129
129
|
/**
|
|
130
130
|
* Define a new list: a new `w:abstractNum` of the requested kind and the
|
|
131
131
|
* `w:num` naming it. `definitions` must already hold every instance the
|
|
132
|
-
*
|
|
133
|
-
* collide with none of
|
|
132
|
+
* story references (see {@link completeListNumbering}), and `elsewhere` the
|
|
133
|
+
* ids the package's other stories define, so the new ids collide with none of
|
|
134
|
+
* them.
|
|
134
135
|
*/
|
|
135
|
-
const mintListInstance = (definitions, { kind, format, start }) => {
|
|
136
|
+
const mintListInstance = (definitions, { kind, format, start }, elsewhere) => {
|
|
136
137
|
const current = definitions ?? EMPTY_DEFINITIONS;
|
|
137
|
-
const numId = nextNumId(current);
|
|
138
|
-
const abstractNumId = nextAbstractNumId(current);
|
|
138
|
+
const numId = nextNumId(current, elsewhere);
|
|
139
|
+
const abstractNumId = nextAbstractNumId(current, elsewhere);
|
|
139
140
|
const levelOverrides = levelZeroStart(start);
|
|
140
141
|
const instance = {
|
|
141
142
|
numId,
|
|
@@ -161,9 +162,9 @@ const mintListInstance = (definitions, { kind, format, start }) => {
|
|
|
161
162
|
* makes a consumer count the instance on its own rather than continue the
|
|
162
163
|
* other instances of the same definition.
|
|
163
164
|
*/
|
|
164
|
-
const restartListInstance = (definitions, { abstractNumId, ilvl, start }) => {
|
|
165
|
+
const restartListInstance = (definitions, { abstractNumId, ilvl, start }, elsewhere) => {
|
|
165
166
|
const current = definitions ?? EMPTY_DEFINITIONS;
|
|
166
|
-
const numId = nextNumId(current);
|
|
167
|
+
const numId = nextNumId(current, elsewhere);
|
|
167
168
|
const instance = {
|
|
168
169
|
numId,
|
|
169
170
|
abstractNumId,
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
type NumberingKind = "num" | "abstract";
|
|
2
|
+
/**
|
|
3
|
+
* Numbering ids (`w:num`, `w:abstractNum`) defined outside the numbering a
|
|
4
|
+
* caller allocates against: the lists the package's other stories define. The
|
|
5
|
+
* ids are package-wide, so a list minted in one story takes none of them.
|
|
6
|
+
*/
|
|
7
|
+
export type NumberingIdsInUse = {
|
|
8
|
+
numIds: ReadonlySet<number>;
|
|
9
|
+
abstractNumIds: ReadonlySet<number>;
|
|
10
|
+
};
|
|
11
|
+
export declare const NO_NUMBERING_IDS_IN_USE: NumberingIdsInUse;
|
|
2
12
|
type MintNumberingIdOptions = {
|
|
3
13
|
kind: NumberingKind;
|
|
4
14
|
existingIds: Iterable<number>;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { createNumericIdAllocator } from "./numericIdAllocator.js";
|
|
2
2
|
// src/docx/numberingIds.ts
|
|
3
|
+
const NO_NUMBERING_IDS_IN_USE = {
|
|
4
|
+
numIds: /* @__PURE__ */ new Set(),
|
|
5
|
+
abstractNumIds: /* @__PURE__ */ new Set()
|
|
6
|
+
};
|
|
3
7
|
/** Independent offline packages can allocate deterministically without retaining realm state. */
|
|
4
8
|
const createNumberingIdAllocator = (kind, existingIds) => {
|
|
5
9
|
const allocator = createNumericIdAllocator({
|
|
@@ -12,4 +16,4 @@ const createNumberingIdAllocator = (kind, existingIds) => {
|
|
|
12
16
|
const mintNumberingId = ({ kind, existingIds }) => {
|
|
13
17
|
return createNumberingIdAllocator(kind, existingIds).next();
|
|
14
18
|
};
|
|
15
|
-
export { createNumberingIdAllocator, mintNumberingId };
|
|
19
|
+
export { NO_NUMBERING_IDS_IN_USE, createNumberingIdAllocator, mintNumberingId };
|
|
@@ -168,6 +168,19 @@ function paragraphStartsWithRenderedPageBreak(node) {
|
|
|
168
168
|
if (outcome === "forced") return sawRenderedPageBreak;
|
|
169
169
|
return outcome === "visible" && sawRenderedPageBreak;
|
|
170
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* How each revision's content is read. A deletion's runs spell their text
|
|
173
|
+
* `w:delText` (ISO/IEC 29500-1 §17.3.3.7), read here as the text it stands
|
|
174
|
+
* for. A move source's runs spell it `w:t` (§17.13.5.22), which that reading
|
|
175
|
+
* leaves as it is; it also accepts the `w:delText` some writers put there, so
|
|
176
|
+
* both spellings give the same model, which the serializer writes as `w:t`.
|
|
177
|
+
*/
|
|
178
|
+
const TRACKED_CHANGE_PARSE_CONTEXT = {
|
|
179
|
+
insertion: "default",
|
|
180
|
+
deletion: "deletion",
|
|
181
|
+
moveFrom: "deletion",
|
|
182
|
+
moveTo: "default"
|
|
183
|
+
};
|
|
171
184
|
function replaceLocalName(name, localName) {
|
|
172
185
|
if (!name) return `w:${localName}`;
|
|
173
186
|
const colonIndex = name.indexOf(":");
|
|
@@ -405,7 +418,7 @@ const linkedRevisionContent = (wrapped, linkOver) => {
|
|
|
405
418
|
return content;
|
|
406
419
|
};
|
|
407
420
|
const hoistRevision = (wrapper) => (child, { styles, theme, rels, media, previews, inScopeXmlns, items, linkOver }) => {
|
|
408
|
-
const wrapped = parseParagraphContents(child, styles, theme, null, rels, media, previews, wrapper
|
|
421
|
+
const wrapped = parseParagraphContents(child, styles, theme, null, rels, media, previews, TRACKED_CHANGE_PARSE_CONTEXT[wrapper], inScopeXmlns, "hyperlink");
|
|
409
422
|
const content = linkedRevisionContent(wrapped, linkOver);
|
|
410
423
|
items.push({
|
|
411
424
|
type: "hoistedRevision",
|
|
@@ -537,7 +550,7 @@ const fieldInlineWrapper = (element) => (child, context) => {
|
|
|
537
550
|
};
|
|
538
551
|
/** Read a field's revision with the same ownership rules as a paragraph revision. */
|
|
539
552
|
const fieldTrackedChange = (type) => (child, { push, styles, theme, rels, media, previews, inScopeXmlns }) => {
|
|
540
|
-
const parsedContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, type
|
|
553
|
+
const parsedContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, TRACKED_CHANGE_PARSE_CONTEXT[type], inScopeXmlns);
|
|
541
554
|
if (parsedContent.length === 0 || !parsedContent.every(isTrackedChangeWrapperChild)) {
|
|
542
555
|
push(preserveInlineChild(child));
|
|
543
556
|
return;
|
|
@@ -901,7 +914,7 @@ const PARAGRAPH_CONTENT_UNDECLARED_NAMESPACES = { [OMML_NAMESPACE]: (child, { co
|
|
|
901
914
|
/** All revision wrappers retain typed review ownership while parsing their children. */
|
|
902
915
|
const trackedParagraphRevision = (type) => (child, { contents, styles, theme, rels, media, previews, inScopeXmlns, inlineScope }) => {
|
|
903
916
|
const resolutionJoins = parseResolutionJoins(child);
|
|
904
|
-
const parsedContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, type
|
|
917
|
+
const parsedContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, TRACKED_CHANGE_PARSE_CONTEXT[type], inScopeXmlns, inlineScope);
|
|
905
918
|
pushTrackedChangeSegments({
|
|
906
919
|
contents,
|
|
907
920
|
type,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hangingFirstLineIndent } from "../utils/units.js";
|
|
1
2
|
import { readAttributeBag } from "./attributeRemainder.js";
|
|
2
3
|
import { parseBorderSpec } from "./borderParser.js";
|
|
3
4
|
import { CAPTURE, dispatchChildrenWithContext, ownedElsewhere, sequencePositions } from "./containerChildren.js";
|
|
@@ -296,7 +297,7 @@ const readParagraphIndentation = (ind, formatting) => {
|
|
|
296
297
|
if (firstLine !== void 0) formatting.indentFirstLine = firstLine;
|
|
297
298
|
const hanging = parseNumericAttribute(ind, "w", "hanging");
|
|
298
299
|
if (hanging !== void 0) {
|
|
299
|
-
formatting.indentFirstLine =
|
|
300
|
+
formatting.indentFirstLine = hangingFirstLineIndent(hanging);
|
|
300
301
|
formatting.hangingIndent = true;
|
|
301
302
|
}
|
|
302
303
|
if (!(left !== void 0 || right !== void 0 || firstLine !== void 0 || hanging !== void 0)) return false;
|