@stll/folio-core 0.56.0 → 0.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.js +122 -22
- package/dist/ai-edits/batch-claims.d.ts +3 -1
- package/dist/ai-edits/batch-claims.js +25 -1
- package/dist/ai-edits/table-row-column-mutations.js +17 -3
- package/dist/ai-suggestions/apply.js +20 -1
- package/dist/compare/inline-atoms.js +40 -16
- package/dist/compare/inline-provenance.js +12 -5
- package/dist/compat/eigenpal.d.ts +2 -1
- package/dist/compat/eigenpal.js +2 -1
- package/dist/controller/canonicalClipboard.d.ts +3 -1
- package/dist/controller/canonicalClipboard.js +31 -13
- package/dist/controller/canonicalComments.d.ts +41 -0
- package/dist/controller/canonicalComments.js +152 -0
- package/dist/controller/canonicalComposition.d.ts +17 -4
- package/dist/controller/canonicalComposition.js +125 -20
- package/dist/controller/canonicalInlineProjection.d.ts +6 -1
- package/dist/controller/canonicalInlineProjection.js +86 -3
- package/dist/controller/canonicalInput.d.ts +1 -1
- package/dist/controller/canonicalInput.js +14 -4
- package/dist/controller/canonicalInputTimer.d.ts +10 -1
- package/dist/controller/canonicalInputTimer.js +24 -1
- package/dist/controller/canonicalPublicOperations.d.ts +2 -2
- package/dist/controller/canonicalPublicOperations.js +107 -15
- package/dist/controller/canonicalSelection.d.ts +18 -0
- package/dist/controller/canonicalSelection.js +41 -0
- package/dist/controller/canonicalSession.d.ts +4 -1
- package/dist/controller/canonicalSession.js +106 -36
- package/dist/controller/canonicalStoryEditor.d.ts +3 -1
- package/dist/controller/canonicalStoryEditor.js +21 -1
- package/dist/controller/canonicalStructure.js +8 -3
- package/dist/controller/folioEditor.js +13 -0
- package/dist/controller/headerFooterEditorManager.d.ts +1 -1
- package/dist/controller/headerFooterEditorManager.js +25 -11
- package/dist/controller/hiddenEditorApi.d.ts +13 -2
- package/dist/controller/hiddenEditorApi.js +5 -1
- package/dist/controller/hiddenEditorManager.d.ts +3 -1
- package/dist/controller/hiddenEditorManager.js +167 -14
- package/dist/controller/noteEditorManager.d.ts +1 -1
- package/dist/controller/noteEditorManager.js +28 -13
- package/dist/docx/builtInStyles.js +13 -6
- package/dist/docx/containerChildren.gen.d.ts +3 -1
- package/dist/docx/containerChildren.gen.js +33 -1
- package/dist/docx/fieldParser.js +14 -2
- package/dist/docx/hyperlinkParser.d.ts +1 -1
- package/dist/docx/hyperlinkParser.js +20 -1
- package/dist/docx/inlineWrapperContent.d.ts +4 -4
- package/dist/docx/inlineWrapperContent.js +4 -4
- package/dist/docx/linkedSdtPreservation.d.ts +10 -0
- package/dist/docx/linkedSdtPreservation.js +37 -0
- package/dist/docx/listRendering.d.ts +18 -0
- package/dist/{prosemirror/conversion/listRenderingDefinition.js → docx/listRendering.js} +17 -3
- package/dist/docx/paragraphParser.js +88 -67
- package/dist/docx/paragraphPropertySource.d.ts +22 -1
- package/dist/docx/paragraphPropertySource.js +107 -1
- package/dist/docx/preservedRunContent.js +2 -1
- package/dist/docx/relsParser.js +26 -2
- package/dist/docx/rezip.js +9 -6
- package/dist/docx/selectiveSave.js +10 -8
- package/dist/docx/serializer/commentSerializer.d.ts +4 -1
- package/dist/docx/serializer/commentSerializer.js +7 -3
- package/dist/docx/serializer/paragraphSerializer.js +207 -94
- package/dist/docx/server/materializeYjsDocx.js +15 -7
- package/dist/docx/server/migrateYjsAttrSchema.js +17 -5
- package/dist/i18n/messages/ar.gen.js +4 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
- package/dist/i18n/messages/catalogs.gen.js +68 -0
- package/dist/i18n/messages/cs.gen.js +4 -0
- package/dist/i18n/messages/de.gen.js +4 -0
- package/dist/i18n/messages/en.gen.js +4 -0
- package/dist/i18n/messages/es.gen.js +4 -0
- package/dist/i18n/messages/et.gen.js +4 -0
- package/dist/i18n/messages/fr.gen.js +4 -0
- package/dist/i18n/messages/he.gen.js +4 -0
- package/dist/i18n/messages/hi.gen.js +4 -0
- package/dist/i18n/messages/hu.gen.js +4 -0
- package/dist/i18n/messages/lt.gen.js +4 -0
- package/dist/i18n/messages/lv.gen.js +4 -0
- package/dist/i18n/messages/messages.gen.d.ts +4 -0
- package/dist/i18n/messages/pl.gen.js +4 -0
- package/dist/i18n/messages/pt-BR.gen.js +4 -0
- package/dist/i18n/messages/sk.gen.js +4 -0
- package/dist/i18n/messages/tr.gen.js +4 -0
- package/dist/i18n/messages/zh-CN.gen.js +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/revisionResolutionInline.js +25 -3
- package/dist/markdown/internals.js +7 -0
- package/dist/markdown/renderParagraph.js +11 -12
- package/dist/markdown/renderRuns.js +3 -13
- package/dist/markdown/types.d.ts +3 -0
- package/dist/panel-layout.d.ts +11 -9
- package/dist/panel-layout.js +13 -9
- package/dist/prosemirror/addTrackedDeletionMark.d.ts +18 -0
- package/dist/prosemirror/addTrackedDeletionMark.js +87 -0
- package/dist/prosemirror/attrs/index.js +9 -0
- package/dist/prosemirror/commands/comments.js +60 -35
- package/dist/prosemirror/commands/propertyChangeScope.js +3 -6
- package/dist/prosemirror/commands/resolveParagraphProperties.js +22 -13
- package/dist/prosemirror/commentOps.js +15 -1
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +8 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +150 -30
- package/dist/prosemirror/conversion/toProseDoc.js +128 -40
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +22 -5
- package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +74 -25
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +11 -0
- package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +22 -14
- package/dist/prosemirror/extensions/marks/markUtils.js +8 -7
- package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +5 -2
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +8 -1
- package/dist/prosemirror/fieldRepresentation.d.ts +8 -0
- package/dist/prosemirror/fieldRepresentation.js +18 -0
- package/dist/prosemirror/hyperlinkRemoval.d.ts +13 -1
- package/dist/prosemirror/hyperlinkRemoval.js +28 -9
- package/dist/prosemirror/imagePictureNames.d.ts +12 -0
- package/dist/prosemirror/imagePictureNames.js +20 -0
- package/dist/prosemirror/listNumbering.js +11 -5
- package/dist/prosemirror/noteReferenceOccurrenceId.d.ts +5 -0
- package/dist/prosemirror/noteReferenceOccurrenceId.js +5 -0
- package/dist/prosemirror/noteReferenceOccurrences.d.ts +21 -0
- package/dist/prosemirror/noteReferenceOccurrences.js +185 -0
- package/dist/prosemirror/noteReferenceReview.js +14 -1
- package/dist/prosemirror/paragraphFormattingProvenance.js +1 -0
- package/dist/prosemirror/plugins/documentStyles.d.ts +4 -1
- package/dist/prosemirror/plugins/documentStyles.js +17 -10
- package/dist/prosemirror/plugins/suggestionMode.js +47 -49
- package/dist/prosemirror/preservedXmlReview.d.ts +6 -0
- package/dist/prosemirror/preservedXmlReview.js +35 -0
- package/dist/prosemirror/runFormattingFromMarks.js +2 -2
- package/dist/prosemirror/runFormattingReconciliation.js +5 -4
- package/dist/prosemirror/runPropertyChangeResolution.d.ts +8 -1
- package/dist/prosemirror/runPropertyChangeResolution.js +24 -2
- package/dist/prosemirror/runStyleFormatting.d.ts +74 -2
- package/dist/prosemirror/runStyleFormatting.js +20 -1
- package/dist/prosemirror/schema/marks.d.ts +1 -0
- package/dist/prosemirror/schema/nodes.d.ts +3 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +4 -1
- package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +15 -15
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +69 -28
- package/dist/prosemirror/styles/styleResolver.d.ts +4 -1
- package/dist/prosemirror/styles/styleResolver.js +32 -11
- package/dist/prosemirror/textInput.d.ts +5 -1
- package/dist/prosemirror/textInput.js +3 -3
- package/dist/prosemirror/trackedRevisionPath.d.ts +5 -1
- package/dist/prosemirror/trackedRevisionPath.js +39 -1
- package/dist/prosemirror/validation.js +3 -5
- package/dist/prosemirror/yjsDocumentMetadata.d.ts +9 -3
- package/dist/prosemirror/yjsDocumentMetadata.js +37 -8
- package/dist/types/canonicalCapabilities.d.ts +18 -18
- package/dist/types/canonicalCapabilities.js +18 -18
- package/dist/types/canonicalComments.d.ts +51 -0
- package/dist/types/canonicalComments.js +0 -0
- package/dist/types/canonicalSections.d.ts +12 -0
- package/dist/types/canonicalSections.js +0 -0
- package/dist/utils/headingCollector.js +45 -4
- package/dist/utils/outlineDepth.d.ts +9 -0
- package/dist/utils/outlineDepth.js +9 -0
- package/package.json +2 -2
- package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +0 -6
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { XmlElement } from "./xmlParser.js";
|
|
2
|
+
//#region src/docx/linkedSdtPreservation.d.ts
|
|
3
|
+
declare const UnrepresentableLinkedSdtRevisionError_base: import("better-result").TaggedErrorClass<"UnrepresentableLinkedSdtRevisionError">;
|
|
4
|
+
declare class UnrepresentableLinkedSdtRevisionError extends UnrepresentableLinkedSdtRevisionError_base<{
|
|
5
|
+
message: string;
|
|
6
|
+
}> {}
|
|
7
|
+
/** Capture only the unsupported hyperlink child, never its enclosing revision. */
|
|
8
|
+
declare const preserveLinkedSdt: (root: XmlElement) => import("@stll/docx-core/model").PreservedInline;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { UnrepresentableLinkedSdtRevisionError, preserveLinkedSdt };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { preserveInlineChild } from "./preservedRunContent.js";
|
|
2
|
+
import { WORDPROCESSINGML_NAMESPACE_URIS, getChildElements, getLocalName } from "./xmlParser.js";
|
|
3
|
+
import { TaggedError } from "better-result";
|
|
4
|
+
//#region src/docx/linkedSdtPreservation.ts
|
|
5
|
+
var UnrepresentableLinkedSdtRevisionError = class extends TaggedError("UnrepresentableLinkedSdtRevisionError") {};
|
|
6
|
+
/** Capture only the unsupported hyperlink child, never its enclosing revision. */
|
|
7
|
+
const preserveLinkedSdt = (root) => {
|
|
8
|
+
const pending = getChildElements(root);
|
|
9
|
+
while (pending.length > 0) {
|
|
10
|
+
const node = pending.pop();
|
|
11
|
+
if (!node) continue;
|
|
12
|
+
const wordprocessing = WORDPROCESSINGML_NAMESPACE_URIS.has(node.namespaceUri ?? "");
|
|
13
|
+
const name = getLocalName(node.name);
|
|
14
|
+
if (wordprocessing && [
|
|
15
|
+
"ins",
|
|
16
|
+
"del",
|
|
17
|
+
"moveFrom",
|
|
18
|
+
"moveTo",
|
|
19
|
+
"rPrChange",
|
|
20
|
+
"pPrChange",
|
|
21
|
+
"sectPrChange",
|
|
22
|
+
"tblPrChange",
|
|
23
|
+
"tblGridChange",
|
|
24
|
+
"trPrChange",
|
|
25
|
+
"tblPrExChange",
|
|
26
|
+
"tcPrChange",
|
|
27
|
+
"cellIns",
|
|
28
|
+
"cellDel",
|
|
29
|
+
"cellMerge",
|
|
30
|
+
"numberingChange"
|
|
31
|
+
].includes(name)) throw new UnrepresentableLinkedSdtRevisionError({ message: "A content control under a hyperlink cannot preserve nested revisions as opaque XML." });
|
|
32
|
+
pending.push(...getChildElements(node));
|
|
33
|
+
}
|
|
34
|
+
return preserveInlineChild(root);
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { UnrepresentableLinkedSdtRevisionError, preserveLinkedSdt };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { NumberingMap } from "./numberingParser.js";
|
|
3
|
+
//#region src/docx/listRendering.d.ts
|
|
4
|
+
/** Compare scalar fields directly; only nested records need canonical ordering. */
|
|
5
|
+
declare const listRenderingDefinitionsMatch: (left: document_d_exports.ListRendering, right: document_d_exports.ListRendering) => boolean;
|
|
6
|
+
type ListRenderingDefinition = {
|
|
7
|
+
rendering: document_d_exports.ListRendering | null;
|
|
8
|
+
nextSlotOffset: number | undefined;
|
|
9
|
+
};
|
|
10
|
+
/** Resolve numbering facts independently of any paragraph's cached counters. */
|
|
11
|
+
declare const resolveListRenderingDefinition: (numPr: {
|
|
12
|
+
numId: number;
|
|
13
|
+
ilvl?: number;
|
|
14
|
+
}, numbering: NumberingMap | undefined) => ListRenderingDefinition;
|
|
15
|
+
/** Keep content-derived counter/folded-field facts only while their definition is current. */
|
|
16
|
+
declare const resolveCachedListRendering: (cached: document_d_exports.ListRendering | undefined, { rendering, nextSlotOffset }: ListRenderingDefinition) => document_d_exports.ListRendering | null;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { ListRenderingDefinition, listRenderingDefinitionsMatch, resolveCachedListRendering, resolveListRenderingDefinition };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { canonicalJson } from "
|
|
2
|
-
|
|
1
|
+
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
2
|
+
import { computeListRendering } from "./numberingParser.js";
|
|
3
|
+
//#region src/docx/listRendering.ts
|
|
3
4
|
const DEFINITION_FIELDS = Object.values({
|
|
4
5
|
marker: {
|
|
5
6
|
key: "marker",
|
|
@@ -93,5 +94,18 @@ const listRenderingDefinitionsMatch = (left, right) => {
|
|
|
93
94
|
}
|
|
94
95
|
return true;
|
|
95
96
|
};
|
|
97
|
+
/** Resolve numbering facts independently of any paragraph's cached counters. */
|
|
98
|
+
const resolveListRenderingDefinition = (numPr, numbering) => {
|
|
99
|
+
const nextLevel = numbering?.getLevel(numPr.numId, (numPr.ilvl ?? 0) + 1);
|
|
100
|
+
return {
|
|
101
|
+
rendering: numbering === void 0 ? null : computeListRendering(numPr, numbering),
|
|
102
|
+
nextSlotOffset: nextLevel?.pPr?.hangingIndent === true && nextLevel.pPr.indentFirstLine !== void 0 && nextLevel.pPr.indentFirstLine < 0 ? -nextLevel.pPr.indentFirstLine : void 0
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
/** Keep content-derived counter/folded-field facts only while their definition is current. */
|
|
106
|
+
const resolveCachedListRendering = (cached, { rendering, nextSlotOffset }) => {
|
|
107
|
+
if (rendering === null) return null;
|
|
108
|
+
return cached !== void 0 && listRenderingDefinitionsMatch(cached, rendering) && (cached.markerSecondSlotOffsetTwips === void 0 || cached.markerSecondSlotOffsetTwips === nextSlotOffset) ? cached : rendering;
|
|
109
|
+
};
|
|
96
110
|
//#endregion
|
|
97
|
-
export { listRenderingDefinitionsMatch };
|
|
111
|
+
export { listRenderingDefinitionsMatch, resolveCachedListRendering, resolveListRenderingDefinition };
|
|
@@ -7,8 +7,9 @@ import { parseFieldType } from "./fieldParser.js";
|
|
|
7
7
|
import { fieldStateOf, parseFieldState } from "./fieldState.js";
|
|
8
8
|
import { foldListNumberFields, isListNumberField, isListNumberGapMarker, isTabOnlyRun } from "./foldedListNumberFields.js";
|
|
9
9
|
import { HYPERLINK_CHILD_HANDLERS, parseHyperlink as parseHyperlink$1, parseHyperlinkShell } from "./hyperlinkParser.js";
|
|
10
|
-
import { isHyperlinkContent, isInlineSdtContent, isTrackedChangeWrapperChild } from "./inlineWrapperContent.js";
|
|
10
|
+
import { isHyperlinkContent, isInlineSdtContent, isSimpleFieldContent, isTrackedChangeWrapperChild } from "./inlineWrapperContent.js";
|
|
11
11
|
import { inlineWrapperOf } from "./inlineWrapperParser.js";
|
|
12
|
+
import { preserveLinkedSdt } from "./linkedSdtPreservation.js";
|
|
12
13
|
import { parseMarkupRangeMarker, parseMoveBookmarkMarker } from "./markupRangeMarker.js";
|
|
13
14
|
import { counterFormatOf, markerAlignmentForLevel, markerFormattingFromLevel, numberingLevelHasMarkerSlot } from "./numberingParser.js";
|
|
14
15
|
import { mergeParagraphNumbering as mergeParagraphNumbering$1, paragraphNumberingReferenceId as paragraphNumberingReferenceId$1, resolveParagraphNumbering as resolveParagraphNumbering$1 } from "./numberingReference.js";
|
|
@@ -357,15 +358,14 @@ const mathContentOf = (child) => {
|
|
|
357
358
|
if (plainText) equation.plainText = plainText;
|
|
358
359
|
return equation;
|
|
359
360
|
};
|
|
360
|
-
|
|
361
|
-
|
|
361
|
+
/** Preserve a link across nested revision owners, rather than dropping its shell. */
|
|
362
|
+
const linkedRevisionContent = (wrapped, linkOver) => {
|
|
362
363
|
const content = [];
|
|
363
364
|
let linked = [];
|
|
364
365
|
const flushLinked = () => {
|
|
365
|
-
if (linked.length
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
366
|
+
if (linked.length === 0) return;
|
|
367
|
+
content.push(linkOver(linked));
|
|
368
|
+
linked = [];
|
|
369
369
|
};
|
|
370
370
|
for (const item of wrapped) {
|
|
371
371
|
if (isHyperlinkContent(item)) {
|
|
@@ -373,9 +373,28 @@ const hoistRevision = (wrapper) => (child, { styles, theme, rels, media, preview
|
|
|
373
373
|
continue;
|
|
374
374
|
}
|
|
375
375
|
flushLinked();
|
|
376
|
-
|
|
376
|
+
switch (item.type) {
|
|
377
|
+
case "insertion":
|
|
378
|
+
case "deletion":
|
|
379
|
+
case "moveFrom":
|
|
380
|
+
case "moveTo":
|
|
381
|
+
content.push({
|
|
382
|
+
...item,
|
|
383
|
+
content: linkedRevisionContent(item.content, linkOver)
|
|
384
|
+
});
|
|
385
|
+
break;
|
|
386
|
+
case "inlineSdt": return panic("An SDT under a hyperlink must retain its opaque source span");
|
|
387
|
+
default:
|
|
388
|
+
if (isTrackedChangeWrapperChild(item)) content.push(item);
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
377
391
|
}
|
|
378
392
|
flushLinked();
|
|
393
|
+
return content;
|
|
394
|
+
};
|
|
395
|
+
const hoistRevision = (wrapper) => (child, { styles, theme, rels, media, previews, inScopeXmlns, items, linkOver }) => {
|
|
396
|
+
const wrapped = parseParagraphContents(child, styles, theme, null, rels, media, previews, wrapper === "deletion" || wrapper === "moveFrom" ? "deletion" : "default", inScopeXmlns, "hyperlink");
|
|
397
|
+
const content = linkedRevisionContent(wrapped, linkOver);
|
|
379
398
|
items.push({
|
|
380
399
|
type: "hoistedRevision",
|
|
381
400
|
wrapper,
|
|
@@ -503,6 +522,27 @@ function parseSimpleField(node, styles, theme, rels, media, rootXmlns, previews)
|
|
|
503
522
|
const fieldInlineWrapper = (element) => (child, context) => {
|
|
504
523
|
context.push(parseFieldInlineWrapper(element, child, context));
|
|
505
524
|
};
|
|
525
|
+
/** Read a field's revision with the same ownership rules as a paragraph revision. */
|
|
526
|
+
const fieldTrackedChange = (type) => (child, { push, styles, theme, rels, media, previews, inScopeXmlns }) => {
|
|
527
|
+
const parsedContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, type === "deletion" || type === "moveFrom" ? "deletion" : "default", inScopeXmlns);
|
|
528
|
+
if (parsedContent.length === 0 || !parsedContent.every(isTrackedChangeWrapperChild)) {
|
|
529
|
+
push(preserveInlineChild(child));
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
const contents = [];
|
|
533
|
+
pushTrackedChangeWrapper({
|
|
534
|
+
contents,
|
|
535
|
+
type,
|
|
536
|
+
info: parseTrackedChangeInfo(child),
|
|
537
|
+
resolutionJoins: parseResolutionJoins(child),
|
|
538
|
+
content: parsedContent,
|
|
539
|
+
preserveEmpty: true
|
|
540
|
+
});
|
|
541
|
+
for (const content of contents) {
|
|
542
|
+
if (!isSimpleFieldContent(content)) panic("A parsed field revision must be a field child");
|
|
543
|
+
push(content);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
506
546
|
/**
|
|
507
547
|
* What a `w:fldSimple` does with every child its content model declares.
|
|
508
548
|
*
|
|
@@ -516,7 +556,10 @@ const SIMPLE_FIELD_CHILD_HANDLERS = {
|
|
|
516
556
|
push(parseRun(child, styles, theme, rels, media, inScopeXmlns, previews));
|
|
517
557
|
},
|
|
518
558
|
hyperlink: (child, { push, styles, theme, rels, media, previews, inScopeXmlns }) => {
|
|
519
|
-
|
|
559
|
+
for (const content of parseHyperlinkParagraphContents(child, rels, styles, theme, media, inScopeXmlns, previews)) {
|
|
560
|
+
if (!isSimpleFieldContent(content)) panic("A parsed field hyperlink must be a field child");
|
|
561
|
+
push(content);
|
|
562
|
+
}
|
|
520
563
|
},
|
|
521
564
|
bdo: fieldInlineWrapper("bdo"),
|
|
522
565
|
dir: fieldInlineWrapper("dir"),
|
|
@@ -534,16 +577,16 @@ const SIMPLE_FIELD_CHILD_HANDLERS = {
|
|
|
534
577
|
customXmlMoveFromRangeStart: CAPTURE,
|
|
535
578
|
customXmlMoveToRangeEnd: CAPTURE,
|
|
536
579
|
customXmlMoveToRangeStart: CAPTURE,
|
|
537
|
-
del:
|
|
580
|
+
del: fieldTrackedChange("deletion"),
|
|
538
581
|
fldData: CAPTURE,
|
|
539
582
|
fldSimple: (child, { push }) => {
|
|
540
583
|
push(preserveInlineChild(child));
|
|
541
584
|
},
|
|
542
|
-
ins:
|
|
543
|
-
moveFrom:
|
|
585
|
+
ins: fieldTrackedChange("insertion"),
|
|
586
|
+
moveFrom: fieldTrackedChange("moveFrom"),
|
|
544
587
|
moveFromRangeEnd: CAPTURE,
|
|
545
588
|
moveFromRangeStart: CAPTURE,
|
|
546
|
-
moveTo:
|
|
589
|
+
moveTo: fieldTrackedChange("moveTo"),
|
|
547
590
|
moveToRangeEnd: CAPTURE,
|
|
548
591
|
moveToRangeStart: CAPTURE,
|
|
549
592
|
permEnd: CAPTURE,
|
|
@@ -819,7 +862,7 @@ const assembledFieldBeginsOf = (container) => {
|
|
|
819
862
|
if (hasBegin) open.push(child);
|
|
820
863
|
if (hasEnd && open.length > 0) {
|
|
821
864
|
const closed = open.pop();
|
|
822
|
-
if (closed !== void 0 && open.length === 0) assembled.add(closed);
|
|
865
|
+
if (closed !== void 0 && open.length === 0 && !findWordprocessingChild(beginFieldCharOf(closed), "fldData")) assembled.add(closed);
|
|
823
866
|
}
|
|
824
867
|
}
|
|
825
868
|
return assembled;
|
|
@@ -830,17 +873,29 @@ const assembledFieldBeginsOf = (container) => {
|
|
|
830
873
|
* recursion is this same walk and `inlineWrapperOf` reads what the element
|
|
831
874
|
* adds.
|
|
832
875
|
*/
|
|
833
|
-
const paragraphInlineWrapper = (element) => (child, { styles, theme, rels, media, previews, trackedContext, inScopeXmlns, contents }) => {
|
|
834
|
-
contents.push(inlineWrapperOf(element, child, parseParagraphContents(child, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child))));
|
|
876
|
+
const paragraphInlineWrapper = (element) => (child, { styles, theme, rels, media, previews, trackedContext, inScopeXmlns, inlineScope, contents }) => {
|
|
877
|
+
contents.push(inlineWrapperOf(element, child, parseParagraphContents(child, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child), inlineScope)));
|
|
835
878
|
};
|
|
836
|
-
const PARAGRAPH_CONTENT_UNDECLARED = { AlternateContent: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns }) => {
|
|
879
|
+
const PARAGRAPH_CONTENT_UNDECLARED = { AlternateContent: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns, inlineScope }) => {
|
|
837
880
|
const selectedBranch = selectAlternateContentBranch(child);
|
|
838
|
-
if (selectedBranch) contents.push(...parseParagraphContents(selectedBranch, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child)));
|
|
881
|
+
if (selectedBranch) contents.push(...parseParagraphContents(selectedBranch, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child), inlineScope));
|
|
839
882
|
} };
|
|
840
883
|
const PARAGRAPH_CONTENT_UNDECLARED_NAMESPACES = { [OMML_NAMESPACE]: (child, { contents }) => {
|
|
841
884
|
const equation = mathContentOf(child);
|
|
842
885
|
if (equation !== void 0) contents.push(equation);
|
|
843
886
|
} };
|
|
887
|
+
/** All revision wrappers retain typed review ownership while parsing their children. */
|
|
888
|
+
const trackedParagraphRevision = (type) => (child, { contents, styles, theme, rels, media, previews, inScopeXmlns, inlineScope }) => {
|
|
889
|
+
const resolutionJoins = parseResolutionJoins(child);
|
|
890
|
+
const parsedContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, type === "deletion" || type === "moveFrom" ? "deletion" : "default", inScopeXmlns, inlineScope);
|
|
891
|
+
pushTrackedChangeSegments({
|
|
892
|
+
contents,
|
|
893
|
+
type,
|
|
894
|
+
info: parseTrackedChangeInfo(child),
|
|
895
|
+
resolutionJoins,
|
|
896
|
+
parsedContent
|
|
897
|
+
});
|
|
898
|
+
};
|
|
844
899
|
const PARAGRAPH_CONTENT_HANDLERS = {
|
|
845
900
|
r: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns, scan }) => {
|
|
846
901
|
const runElement = trackedContext === "deletion" ? normalizeDeletionContentElement(child) : child;
|
|
@@ -977,8 +1032,9 @@ const PARAGRAPH_CONTENT_HANDLERS = {
|
|
|
977
1032
|
contents.push(kept);
|
|
978
1033
|
}
|
|
979
1034
|
},
|
|
980
|
-
hyperlink: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
|
|
981
|
-
|
|
1035
|
+
hyperlink: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns, trackedContext }) => {
|
|
1036
|
+
const linkElement = trackedContext === "deletion" ? normalizeDeletionContentElement(child) : child;
|
|
1037
|
+
contents.push(...parseHyperlinkParagraphContents(linkElement, rels, styles, theme, media, inScopeXmlns, previews));
|
|
982
1038
|
},
|
|
983
1039
|
bookmarkStart: (child, { contents }) => {
|
|
984
1040
|
contents.push(parseBookmarkStart(child));
|
|
@@ -1014,12 +1070,16 @@ const PARAGRAPH_CONTENT_HANDLERS = {
|
|
|
1014
1070
|
customXmlMoveToRangeStart: CAPTURE,
|
|
1015
1071
|
smartTagPr: SMART_TAG_PROPERTIES_OWNER,
|
|
1016
1072
|
customXmlPr: CUSTOM_XML_PROPERTIES_OWNER,
|
|
1017
|
-
sdt: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns }) => {
|
|
1073
|
+
sdt: (child, { contents, styles, theme, rels, media, previews, trackedContext, inScopeXmlns, inlineScope }) => {
|
|
1074
|
+
if (inlineScope === "hyperlink") {
|
|
1075
|
+
contents.push(preserveLinkedSdt(child));
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1018
1078
|
const sdtPr = findWordprocessingChild(child, "sdtPr");
|
|
1019
1079
|
const sdtEndPr = findWordprocessingChild(child, "sdtEndPr");
|
|
1020
1080
|
const sdtContentEl = findWordprocessingChild(child, "sdtContent");
|
|
1021
1081
|
if (sdtContentEl) {
|
|
1022
|
-
const sdtParsed = parseParagraphContents(sdtContentEl, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child));
|
|
1082
|
+
const sdtParsed = parseParagraphContents(sdtContentEl, styles, theme, null, rels, media, previews, trackedContext, mergeXmlnsDeclarations(inScopeXmlns, child), inlineScope);
|
|
1023
1083
|
const properties = parseSdtProperties(sdtPr, sdtEndPr);
|
|
1024
1084
|
const captured = captureSdtSiblingMarkers(child);
|
|
1025
1085
|
if (captured.before.length > 0) properties.rawSdtChildrenBeforeContent = captured.before;
|
|
@@ -1031,50 +1091,10 @@ const PARAGRAPH_CONTENT_HANDLERS = {
|
|
|
1031
1091
|
});
|
|
1032
1092
|
}
|
|
1033
1093
|
},
|
|
1034
|
-
ins: (
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
contents,
|
|
1039
|
-
type: "insertion",
|
|
1040
|
-
info: insInfo,
|
|
1041
|
-
resolutionJoins: parseResolutionJoins(child),
|
|
1042
|
-
parsedContent: insContent
|
|
1043
|
-
});
|
|
1044
|
-
},
|
|
1045
|
-
del: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
|
|
1046
|
-
const delInfo = parseTrackedChangeInfo(child);
|
|
1047
|
-
const delContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, "deletion", inScopeXmlns);
|
|
1048
|
-
pushTrackedChangeSegments({
|
|
1049
|
-
contents,
|
|
1050
|
-
type: "deletion",
|
|
1051
|
-
info: delInfo,
|
|
1052
|
-
resolutionJoins: parseResolutionJoins(child),
|
|
1053
|
-
parsedContent: delContent
|
|
1054
|
-
});
|
|
1055
|
-
},
|
|
1056
|
-
moveFrom: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
|
|
1057
|
-
const moveFromInfo = parseTrackedChangeInfo(child);
|
|
1058
|
-
const moveFromContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, "deletion", inScopeXmlns);
|
|
1059
|
-
pushTrackedChangeSegments({
|
|
1060
|
-
contents,
|
|
1061
|
-
type: "moveFrom",
|
|
1062
|
-
info: moveFromInfo,
|
|
1063
|
-
resolutionJoins: parseResolutionJoins(child),
|
|
1064
|
-
parsedContent: moveFromContent
|
|
1065
|
-
});
|
|
1066
|
-
},
|
|
1067
|
-
moveTo: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
|
|
1068
|
-
const moveToInfo = parseTrackedChangeInfo(child);
|
|
1069
|
-
const moveToContent = parseParagraphContents(child, styles, theme, null, rels, media, previews, "default", inScopeXmlns);
|
|
1070
|
-
pushTrackedChangeSegments({
|
|
1071
|
-
contents,
|
|
1072
|
-
type: "moveTo",
|
|
1073
|
-
info: moveToInfo,
|
|
1074
|
-
resolutionJoins: parseResolutionJoins(child),
|
|
1075
|
-
parsedContent: moveToContent
|
|
1076
|
-
});
|
|
1077
|
-
},
|
|
1094
|
+
ins: trackedParagraphRevision("insertion"),
|
|
1095
|
+
del: trackedParagraphRevision("deletion"),
|
|
1096
|
+
moveFrom: trackedParagraphRevision("moveFrom"),
|
|
1097
|
+
moveTo: trackedParagraphRevision("moveTo"),
|
|
1078
1098
|
smartTag: paragraphInlineWrapper("smartTag"),
|
|
1079
1099
|
moveFromRangeStart: (child, { contents }) => {
|
|
1080
1100
|
contents.push({
|
|
@@ -1120,7 +1140,7 @@ const PARAGRAPH_CONTENT_HANDLERS = {
|
|
|
1120
1140
|
*
|
|
1121
1141
|
* Returns the parsed content and any complex fields that span multiple runs
|
|
1122
1142
|
*/
|
|
1123
|
-
function parseParagraphContents(paraElement, styles, theme, _numbering, rels, media, previews, trackedContext = "default", rootXmlns = {}) {
|
|
1143
|
+
function parseParagraphContents(paraElement, styles, theme, _numbering, rels, media, previews, trackedContext = "default", rootXmlns = {}, inlineScope = "paragraph") {
|
|
1124
1144
|
const contents = [];
|
|
1125
1145
|
const inScopeXmlns = mergeXmlnsDeclarations(rootXmlns, paraElement);
|
|
1126
1146
|
const scan = {
|
|
@@ -1154,6 +1174,7 @@ function parseParagraphContents(paraElement, styles, theme, _numbering, rels, me
|
|
|
1154
1174
|
media,
|
|
1155
1175
|
previews,
|
|
1156
1176
|
trackedContext,
|
|
1177
|
+
inlineScope,
|
|
1157
1178
|
inScopeXmlns,
|
|
1158
1179
|
contents,
|
|
1159
1180
|
scan
|
|
@@ -4,10 +4,27 @@ import { Fragment, Mark, Node, NodeType } from "prosemirror-model";
|
|
|
4
4
|
import { Transaction } from "prosemirror-state";
|
|
5
5
|
//#region src/docx/paragraphPropertySource.d.ts
|
|
6
6
|
declare const paragraphPropertySourceEmissionFingerprint: unique symbol;
|
|
7
|
+
declare const paragraphPropertySourceIndentationBaseline: unique symbol;
|
|
8
|
+
declare const INDENTATION_FIELDS: readonly ["indentLeft", "indentRight", "indentFirstLine", "hangingIndent"];
|
|
7
9
|
type ParagraphPropertySource = Readonly<{
|
|
8
10
|
xml: string;
|
|
9
11
|
[paragraphPropertySourceEmissionFingerprint]: string;
|
|
12
|
+
[paragraphPropertySourceIndentationBaseline]: Readonly<Pick<document_d_exports.ParagraphFormatting, (typeof INDENTATION_FIELDS)[number]>>;
|
|
10
13
|
}>;
|
|
14
|
+
type IndentationFormatting = Pick<document_d_exports.ParagraphFormatting, (typeof INDENTATION_FIELDS)[number]>;
|
|
15
|
+
type CopyParagraphIndentationProjectionOptions = {
|
|
16
|
+
target: document_d_exports.Paragraph;
|
|
17
|
+
source: document_d_exports.Paragraph;
|
|
18
|
+
};
|
|
19
|
+
/** Retain effective-value provenance without copying a durable source identity. */
|
|
20
|
+
declare const copyParagraphIndentationProjection: ({ target, source }: CopyParagraphIndentationProjectionOptions) => void;
|
|
21
|
+
type AssignParagraphIndentationProjectionOptions = {
|
|
22
|
+
paragraph: document_d_exports.Paragraph;
|
|
23
|
+
authored: document_d_exports.ParagraphFormatting | undefined;
|
|
24
|
+
inherited: IndentationFormatting;
|
|
25
|
+
};
|
|
26
|
+
/** Keep the model's effective indentation without making inherited values authored. */
|
|
27
|
+
declare const assignParagraphIndentationProjection: ({ paragraph, authored, inherited }: AssignParagraphIndentationProjectionOptions) => void;
|
|
11
28
|
declare const PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR = "_docxParagraphSourceToken";
|
|
12
29
|
declare const PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR = "_docxParagraphSourceContract";
|
|
13
30
|
/** Durable identity nested inside opaque collapsed-cell ProseMirror attrs; stripped on restore. */
|
|
@@ -30,6 +47,10 @@ declare const paragraphPropertySourceTokenMatchesContract: (token: unknown, cont
|
|
|
30
47
|
declare const visitDocumentStoryParagraphs: (content: document_d_exports.Document["package"]["document"]["content"], visit: (paragraph: document_d_exports.Paragraph) => void) => void;
|
|
31
48
|
declare const assignParagraphPropertySource: (paragraph: document_d_exports.Paragraph, xml: string) => void;
|
|
32
49
|
declare const getParagraphPropertySource: (paragraph: document_d_exports.Paragraph) => ParagraphPropertySource | undefined;
|
|
50
|
+
/** Read authored indentation while preserving edits to the parsed effective values. */
|
|
51
|
+
declare const paragraphFormattingWithAuthoredIndentation: (paragraph: document_d_exports.Paragraph) => document_d_exports.ParagraphFormatting | undefined;
|
|
52
|
+
/** Equal effective values must not replay a capture that lacks newly authored indentation. */
|
|
53
|
+
declare const paragraphPropertySourceMatchesAuthoredIndentation: (paragraph: document_d_exports.Paragraph) => boolean;
|
|
33
54
|
declare const paragraphPropertySourceMatchesEmission: (source: ParagraphPropertySource, emission: ModeledParagraphFormattingEmission) => boolean;
|
|
34
55
|
/** Copy the captured `w:pPr` without claiming the source paragraph's durable identity. */
|
|
35
56
|
declare const copyParagraphPropertyCapture: (target: document_d_exports.Paragraph, source: document_d_exports.Paragraph) => void;
|
|
@@ -150,4 +171,4 @@ declare const linkParagraphPropertySourceCandidate: (target: document_d_exports.
|
|
|
150
171
|
declare const getParagraphPropertySourceCandidate: (paragraph: document_d_exports.Paragraph) => document_d_exports.Paragraph | undefined;
|
|
151
172
|
declare const getParagraphPropertySourceTransferId: (paragraph: document_d_exports.Paragraph) => string | undefined;
|
|
152
173
|
//#endregion
|
|
153
|
-
export { DecodedTableCellParagraphSourcePayload, PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceTransfer, ParagraphPropertySourceValidationCode, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, TableCellParagraphPropertySourceBinding, TableCellParagraphSourcePayloadErrorClassification, assignDocumentParagraphPropertySourceContract, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, inspectParagraphSourceIdentity, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, markParagraphPropertySourceTransfers, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
|
|
174
|
+
export { DecodedTableCellParagraphSourcePayload, PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceTransfer, ParagraphPropertySourceValidationCode, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, TableCellParagraphPropertySourceBinding, TableCellParagraphSourcePayloadErrorClassification, assignDocumentParagraphPropertySourceContract, assignParagraphIndentationProjection, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphIndentationProjection, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, inspectParagraphSourceIdentity, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, markParagraphPropertySourceTransfers, paragraphFormattingWithAuthoredIndentation, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesAuthoredIndentation, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
|
|
@@ -1,12 +1,66 @@
|
|
|
1
1
|
import { modelParagraphFormattingEmission } from "../internal/paragraphFormattingSerialization.js";
|
|
2
2
|
import { canonicalJson } from "../utils/canonicalJson.js";
|
|
3
3
|
import { copyHeaderFooterBaselineHandles, copyHeaderFooterPackageBaselines } from "./headerFooterVerbatim.js";
|
|
4
|
+
import { parseParagraphProperties } from "./paragraphProperties.js";
|
|
4
5
|
import { visitDocxParagraphs } from "./paragraphTraversal.js";
|
|
6
|
+
import { parseXmlDocument } from "./xmlParser.js";
|
|
5
7
|
import { TaggedError, panic } from "better-result";
|
|
6
8
|
import { PluginKey } from "prosemirror-state";
|
|
7
9
|
//#region src/docx/paragraphPropertySource.ts
|
|
8
10
|
const paragraphPropertySourceEmissionFingerprint = Symbol("paragraphPropertySourceEmissionFingerprint");
|
|
11
|
+
const paragraphPropertySourceIndentationBaseline = Symbol("paragraphPropertySourceIndentationBaseline");
|
|
12
|
+
const INDENTATION_FIELDS = [
|
|
13
|
+
"indentLeft",
|
|
14
|
+
"indentRight",
|
|
15
|
+
"indentFirstLine",
|
|
16
|
+
"hangingIndent"
|
|
17
|
+
];
|
|
9
18
|
const paragraphPropertyCapture = Symbol("paragraphPropertyCapture");
|
|
19
|
+
const paragraphIndentationProjection = Symbol("paragraphIndentationProjection");
|
|
20
|
+
const indentationProjections = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
const indentationProjectionFor = (paragraph) => {
|
|
22
|
+
const handle = Object.getOwnPropertyDescriptor(paragraph, paragraphIndentationProjection)?.value;
|
|
23
|
+
return typeof handle === "object" && handle !== null ? indentationProjections.get(handle) : void 0;
|
|
24
|
+
};
|
|
25
|
+
/** Retain effective-value provenance without copying a durable source identity. */
|
|
26
|
+
const copyParagraphIndentationProjection = ({ target, source }) => {
|
|
27
|
+
if (Object.hasOwn(target, paragraphIndentationProjection)) return;
|
|
28
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, paragraphIndentationProjection);
|
|
29
|
+
if (descriptor && indentationProjectionFor(source)) Object.defineProperty(target, paragraphIndentationProjection, descriptor);
|
|
30
|
+
};
|
|
31
|
+
const indentationFields = (formatting) => ({
|
|
32
|
+
indentLeft: formatting?.indentLeft,
|
|
33
|
+
indentRight: formatting?.indentRight,
|
|
34
|
+
indentFirstLine: formatting?.indentFirstLine,
|
|
35
|
+
hangingIndent: formatting?.hangingIndent
|
|
36
|
+
});
|
|
37
|
+
/** Keep the model's effective indentation without making inherited values authored. */
|
|
38
|
+
const assignParagraphIndentationProjection = ({ paragraph, authored, inherited }) => {
|
|
39
|
+
const effective = {
|
|
40
|
+
...inherited,
|
|
41
|
+
...indentationFields(authored)
|
|
42
|
+
};
|
|
43
|
+
for (const key of INDENTATION_FIELDS) if (authored?.[key] === void 0) {
|
|
44
|
+
const value = inherited[key];
|
|
45
|
+
if (value === void 0) Reflect.deleteProperty(effective, key);
|
|
46
|
+
else Object.assign(effective, { [key]: value });
|
|
47
|
+
}
|
|
48
|
+
if (authored?.indentFirstLine !== void 0 && authored.hangingIndent === void 0) Reflect.deleteProperty(effective, "hangingIndent");
|
|
49
|
+
paragraph.formatting = {
|
|
50
|
+
...authored,
|
|
51
|
+
...effective
|
|
52
|
+
};
|
|
53
|
+
const handle = Object.freeze({});
|
|
54
|
+
indentationProjections.set(handle, Object.freeze({
|
|
55
|
+
effective: Object.freeze(indentationFields(paragraph.formatting)),
|
|
56
|
+
authored: Object.freeze(indentationFields(authored))
|
|
57
|
+
}));
|
|
58
|
+
Object.defineProperty(paragraph, paragraphIndentationProjection, {
|
|
59
|
+
value: handle,
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true
|
|
62
|
+
});
|
|
63
|
+
};
|
|
10
64
|
const paragraphPropertyCaptures = /* @__PURE__ */ new WeakMap();
|
|
11
65
|
const paragraphSourceRecordKinds = /* @__PURE__ */ new WeakMap();
|
|
12
66
|
const captureForParagraph = (paragraph) => {
|
|
@@ -27,6 +81,12 @@ const paragraphFormattingEmissionFingerprint = (emission) => canonicalJson(emiss
|
|
|
27
81
|
const ownedParagraphPropertySource = (paragraph, xml) => {
|
|
28
82
|
return Object.freeze({
|
|
29
83
|
xml,
|
|
84
|
+
[paragraphPropertySourceIndentationBaseline]: Object.freeze({
|
|
85
|
+
indentLeft: paragraph.formatting?.indentLeft,
|
|
86
|
+
indentRight: paragraph.formatting?.indentRight,
|
|
87
|
+
indentFirstLine: paragraph.formatting?.indentFirstLine,
|
|
88
|
+
hangingIndent: paragraph.formatting?.hangingIndent
|
|
89
|
+
}),
|
|
30
90
|
[paragraphPropertySourceEmissionFingerprint]: paragraphFormattingEmissionFingerprint(modelParagraphFormattingEmission(paragraph.formatting))
|
|
31
91
|
});
|
|
32
92
|
};
|
|
@@ -113,9 +173,54 @@ const assignParagraphPropertySource = (paragraph, xml) => {
|
|
|
113
173
|
});
|
|
114
174
|
};
|
|
115
175
|
const getParagraphPropertySource = (paragraph) => captureForParagraph(paragraph)?.source;
|
|
176
|
+
const directFormattingBySource = /* @__PURE__ */ new WeakMap();
|
|
177
|
+
/** Read authored indentation while preserving edits to the parsed effective values. */
|
|
178
|
+
const paragraphFormattingWithAuthoredIndentation = (paragraph) => {
|
|
179
|
+
const source = getParagraphPropertySource(paragraph);
|
|
180
|
+
const projection = indentationProjectionFor(paragraph);
|
|
181
|
+
if (source === void 0 && projection === void 0) return paragraph.formatting;
|
|
182
|
+
let direct = source === void 0 ? void 0 : directFormattingBySource.get(source);
|
|
183
|
+
if (source !== void 0 && direct === void 0) {
|
|
184
|
+
direct = { formatting: parseParagraphProperties(parseXmlDocument(source.xml), null) };
|
|
185
|
+
directFormattingBySource.set(source, direct);
|
|
186
|
+
}
|
|
187
|
+
const result = { ...paragraph.formatting };
|
|
188
|
+
const baseline = projection?.effective ?? source?.[paragraphPropertySourceIndentationBaseline];
|
|
189
|
+
if (baseline === void 0) return paragraph.formatting;
|
|
190
|
+
const authored = projection?.authored ?? direct?.formatting;
|
|
191
|
+
const firstLineChanged = paragraph.formatting?.indentFirstLine !== baseline.indentFirstLine || paragraph.formatting?.hangingIndent !== baseline.hangingIndent;
|
|
192
|
+
for (const key of INDENTATION_FIELDS) {
|
|
193
|
+
if ((key === "indentFirstLine" || key === "hangingIndent") && firstLineChanged) continue;
|
|
194
|
+
if (paragraph.formatting?.[key] !== baseline[key]) continue;
|
|
195
|
+
Reflect.deleteProperty(result, key);
|
|
196
|
+
const value = authored?.[key];
|
|
197
|
+
if (value !== void 0) Object.assign(result, { [key]: value });
|
|
198
|
+
}
|
|
199
|
+
return Object.keys(result).length === 0 ? void 0 : result;
|
|
200
|
+
};
|
|
201
|
+
/** Equal effective values must not replay a capture that lacks newly authored indentation. */
|
|
202
|
+
const paragraphPropertySourceMatchesAuthoredIndentation = (paragraph) => {
|
|
203
|
+
const source = getParagraphPropertySource(paragraph);
|
|
204
|
+
if (source === void 0) return true;
|
|
205
|
+
const authored = paragraphFormattingWithAuthoredIndentation(paragraph);
|
|
206
|
+
const original = directFormattingBySource.get(source)?.formatting;
|
|
207
|
+
const indentationEmission = (formatting) => {
|
|
208
|
+
const indentation = {};
|
|
209
|
+
for (const key of INDENTATION_FIELDS) {
|
|
210
|
+
const value = formatting?.[key];
|
|
211
|
+
if (value !== void 0) Object.assign(indentation, { [key]: value });
|
|
212
|
+
}
|
|
213
|
+
return modelParagraphFormattingEmission(indentation);
|
|
214
|
+
};
|
|
215
|
+
return canonicalJson(indentationEmission(authored)) === canonicalJson(indentationEmission(original));
|
|
216
|
+
};
|
|
116
217
|
const paragraphPropertySourceMatchesEmission = (source, emission) => source[paragraphPropertySourceEmissionFingerprint] === paragraphFormattingEmissionFingerprint(emission);
|
|
117
218
|
/** Copy the captured `w:pPr` without claiming the source paragraph's durable identity. */
|
|
118
219
|
const copyParagraphPropertyCapture = (target, source) => {
|
|
220
|
+
copyParagraphIndentationProjection({
|
|
221
|
+
target,
|
|
222
|
+
source
|
|
223
|
+
});
|
|
119
224
|
const capture = captureForParagraph(source);
|
|
120
225
|
if (capture) attachParagraphCapture(target, capture);
|
|
121
226
|
const kind = paragraphPropertySourceTokens.has(source) || paragraphSourceRecordKinds.get(source) === "durable" ? "durable" : "capture-only";
|
|
@@ -215,6 +320,7 @@ const cloneParagraphWithoutPropertySource = (paragraph, overrides) => {
|
|
|
215
320
|
...overrides
|
|
216
321
|
};
|
|
217
322
|
Reflect.deleteProperty(cloned, paragraphPropertyCapture);
|
|
323
|
+
Reflect.deleteProperty(cloned, paragraphIndentationProjection);
|
|
218
324
|
return cloned;
|
|
219
325
|
};
|
|
220
326
|
const paragraphsIn = (document) => {
|
|
@@ -766,4 +872,4 @@ const linkParagraphPropertySourceCandidate = (target, source) => {
|
|
|
766
872
|
const getParagraphPropertySourceCandidate = (paragraph) => paragraphPropertySourceCandidates.get(paragraph);
|
|
767
873
|
const getParagraphPropertySourceTransferId = (paragraph) => paragraphPropertySourceTransferIds.get(paragraph);
|
|
768
874
|
//#endregion
|
|
769
|
-
export { PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, assignDocumentParagraphPropertySourceContract, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, inspectParagraphSourceIdentity, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, markParagraphPropertySourceTransfers, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
|
|
875
|
+
export { PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, assignDocumentParagraphPropertySourceContract, assignParagraphIndentationProjection, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphIndentationProjection, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, inspectParagraphSourceIdentity, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, markParagraphPropertySourceTransfers, paragraphFormattingWithAuthoredIndentation, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesAuthoredIndentation, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
|
|
@@ -14,7 +14,7 @@ const VISIBLE_TEXT_CHILDREN = /* @__PURE__ */ new Map([["ruby", ["rubyBase"]]]);
|
|
|
14
14
|
const MAX_PRESERVED_TEXT_LENGTH = 1e5;
|
|
15
15
|
const collectTextContent = (element, into) => {
|
|
16
16
|
for (const child of getChildElements(element)) {
|
|
17
|
-
if (getLocalName(child.name) === "t") {
|
|
17
|
+
if (getLocalName(child.name) === "t" || getLocalName(child.name) === "delText") {
|
|
18
18
|
into.push(getTextContent(child));
|
|
19
19
|
continue;
|
|
20
20
|
}
|
|
@@ -67,6 +67,7 @@ const VISIBLE_TEXT_INLINE_CHILDREN = /* @__PURE__ */ new Set([
|
|
|
67
67
|
"customXml",
|
|
68
68
|
"fldSimple",
|
|
69
69
|
"hyperlink",
|
|
70
|
+
"sdt",
|
|
70
71
|
"smartTag"
|
|
71
72
|
]);
|
|
72
73
|
/**
|
package/dist/docx/relsParser.js
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
import { getAttribute, getChildElements, parseXmlDocument } from "./xmlParser.js";
|
|
2
|
+
import { COMMENT_PART_RELATIONSHIPS } from "@stll/docx-core/model";
|
|
2
3
|
//#region src/docx/relsParser.ts
|
|
3
4
|
/**
|
|
5
|
+
* Relationship Parser
|
|
6
|
+
*
|
|
7
|
+
* Parses .rels files from DOCX packages to map relationship IDs (rId)
|
|
8
|
+
* to their targets (images, hyperlinks, headers, footers, etc.).
|
|
9
|
+
*
|
|
10
|
+
* .rels files are XML with structure:
|
|
11
|
+
* <Relationships xmlns="...">
|
|
12
|
+
* <Relationship Id="rId1" Type="..." Target="..." TargetMode="External|Internal"/>
|
|
13
|
+
* </Relationships>
|
|
14
|
+
*
|
|
15
|
+
* Key relationship types:
|
|
16
|
+
* - image: Embedded images (word/media/*)
|
|
17
|
+
* - hyperlink: External URLs (TargetMode="External")
|
|
18
|
+
* - header: Header XML files
|
|
19
|
+
* - footer: Footer XML files
|
|
20
|
+
* - footnotes: Footnotes XML
|
|
21
|
+
* - endnotes: Endnotes XML
|
|
22
|
+
* - styles: styles.xml
|
|
23
|
+
* - numbering: numbering.xml
|
|
24
|
+
* - fontTable: fontTable.xml
|
|
25
|
+
* - theme: theme/theme1.xml
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
4
28
|
* Relationship type constants for common types
|
|
5
29
|
*/
|
|
6
30
|
const RELATIONSHIP_TYPES = {
|
|
@@ -24,8 +48,8 @@ const RELATIONSHIP_TYPES = {
|
|
|
24
48
|
extendedProperties: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
|
|
25
49
|
customProperties: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties",
|
|
26
50
|
customXml: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml",
|
|
27
|
-
comments:
|
|
28
|
-
commentsExtended:
|
|
51
|
+
comments: COMMENT_PART_RELATIONSHIPS.comments.type,
|
|
52
|
+
commentsExtended: COMMENT_PART_RELATIONSHIPS.commentsExtended.type
|
|
29
53
|
};
|
|
30
54
|
const STRICT_OFFICE_RELATIONSHIP_PREFIX = "http://purl.oclc.org/ooxml/officeDocument/relationships/";
|
|
31
55
|
const TRANSITIONAL_OFFICE_RELATIONSHIP_PREFIX = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/";
|