@stll/folio-core 0.37.4 → 0.38.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 +275 -88
- package/dist/ai-edits/clean-text.js +12 -1
- package/dist/ai-edits/headless.d.ts +110 -0
- package/dist/ai-edits/headless.js +569 -40
- package/dist/ai-edits/index.d.ts +2 -1
- package/dist/ai-edits/snapshot.d.ts +24 -1
- package/dist/ai-edits/snapshot.js +206 -9
- package/dist/ai-edits/table-geometry.d.ts +7 -7
- package/dist/ai-edits/table-geometry.js +43 -27
- package/dist/ai-edits/table-template.d.ts +2 -1
- package/dist/ai-edits/table-template.js +9 -3
- package/dist/ai-edits/types.d.ts +38 -16
- package/dist/compare/__fixtures__/body-sequence.d.ts +4 -0
- package/dist/compare/__fixtures__/body-sequence.js +5 -3
- package/dist/compare/compare.d.ts +26 -2
- package/dist/compare/compare.js +444 -16
- package/dist/compare/content-alignment.js +216 -137
- package/dist/compare/content-types.d.ts +36 -2
- package/dist/compare/content.d.ts +13 -10
- package/dist/compare/content.js +69 -23
- package/dist/compare/formatting.d.ts +4 -22
- package/dist/compare/formatting.js +8 -112
- package/dist/compare/inline-atom-resources.d.ts +6 -0
- package/dist/compare/inline-atom-resources.js +26 -0
- package/dist/compare/inline-atoms.d.ts +35 -0
- package/dist/compare/inline-atoms.js +383 -0
- package/dist/compare/inline-provenance.d.ts +36 -0
- package/dist/compare/inline-provenance.js +334 -0
- package/dist/compare/plan.d.ts +4 -1
- package/dist/compare/plan.js +32 -4
- package/dist/compare/scenario.d.ts +4 -6
- package/dist/compare/section-boundary-properties.d.ts +63 -0
- package/dist/compare/section-boundary-properties.js +235 -0
- package/dist/compare/style-resources.d.ts +30 -0
- package/dist/compare/style-resources.js +404 -0
- package/dist/compare/types.d.ts +50 -11
- package/dist/compare/types.js +3 -1
- package/dist/compare/verification.d.ts +3 -5
- package/dist/compare/verification.js +8 -39
- package/dist/compat/eigenpal.d.ts +4 -4
- package/dist/compat/eigenpal.js +3 -3
- package/dist/document-operations.d.ts +5 -3
- package/dist/document-operations.js +112 -5
- package/dist/docx/blockContentParser.js +14 -2
- package/dist/docx/drawingIdNormalization.js +43 -2
- package/dist/docx/drawingRelationships.d.ts +10 -0
- package/dist/docx/drawingRelationships.js +28 -0
- package/dist/docx/fieldParser.js +1 -1
- package/dist/docx/hyperlinkParser.js +3 -5
- package/dist/docx/imageRawXml.d.ts +8 -0
- package/dist/docx/imageRawXml.js +13 -0
- package/dist/docx/newImage.d.ts +2 -2
- package/dist/docx/newImage.js +3 -3
- package/dist/docx/numberingParser.d.ts +1 -13
- package/dist/docx/numberingParser.js +31 -37
- package/dist/docx/paragraphParser.js +12 -9
- package/dist/docx/paragraphPropertySource.d.ts +8 -5
- package/dist/docx/paragraphPropertySource.js +16 -4
- package/dist/docx/removeHeaderFooterParts.d.ts +14 -0
- package/dist/docx/removeHeaderFooterParts.js +87 -0
- package/dist/docx/rezip.d.ts +3 -1
- package/dist/docx/rezip.js +143 -41
- package/dist/docx/runParser.js +16 -5
- package/dist/docx/sectionParser.js +3 -0
- package/dist/docx/sectionReferenceHistory.d.ts +17 -0
- package/dist/docx/sectionReferenceHistory.js +59 -0
- package/dist/docx/selectiveSave.js +11 -31
- package/dist/docx/selectiveXmlPatch.d.ts +8 -1
- package/dist/docx/selectiveXmlPatch.js +62 -2
- package/dist/docx/serializer/borderSerializer.d.ts +4 -1
- package/dist/docx/serializer/borderSerializer.js +20 -18
- package/dist/docx/serializer/commentSerializer.js +1 -1
- package/dist/docx/serializer/numberingSerializer.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +13 -177
- package/dist/docx/serializer/partNamespaces.d.ts +1 -1
- package/dist/docx/serializer/partNamespaces.js +4 -0
- package/dist/docx/serializer/runSerializer.d.ts +1 -5
- package/dist/docx/serializer/runSerializer.js +4 -130
- package/dist/docx/serializer/sectionPropertiesSerializer.js +5 -2
- package/dist/docx/serializer/stylesSerializer.js +1 -1
- package/dist/docx/serializer/textFormattingSerializer.d.ts +17 -0
- package/dist/docx/serializer/textFormattingSerializer.js +144 -0
- package/dist/docx/tableParser.js +21 -11
- package/dist/docx/xmlParser.d.ts +10 -1
- package/dist/docx/xmlParser.js +23 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/internal/compare/inline-presentation.d.ts +20 -0
- package/dist/internal/compare/inline-presentation.js +222 -0
- package/dist/internal/paragraphFormattingSerialization.d.ts +25 -0
- package/dist/internal/paragraphFormattingSerialization.js +164 -0
- package/dist/internal/sectionReferenceResolution.d.ts +21 -0
- package/dist/internal/sectionReferenceResolution.js +72 -0
- package/dist/layout-bridge/convert/toFlowBlocks.js +1 -0
- package/dist/markdown/renderRuns.js +1 -0
- package/dist/markdown/renderTable.js +1 -0
- package/dist/prosemirror/attrs/index.js +20 -1
- package/dist/prosemirror/commands/comments.d.ts +11 -1
- package/dist/prosemirror/commands/comments.js +68 -6
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +9 -3
- package/dist/prosemirror/commands/propertyChangeScope.js +4 -10
- package/dist/prosemirror/conversion/fromProseDoc.js +22 -22
- package/dist/prosemirror/conversion/toProseDoc.js +16 -57
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
- package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +3 -0
- package/dist/prosemirror/imageCommit.js +7 -9
- package/dist/prosemirror/paragraphIndentation.d.ts +21 -0
- package/dist/prosemirror/paragraphIndentation.js +72 -0
- package/dist/prosemirror/plugins/documentNumbering.d.ts +3 -1
- package/dist/prosemirror/plugins/documentNumbering.js +7 -1
- package/dist/prosemirror/plugins/documentStyles.d.ts +3 -1
- package/dist/prosemirror/plugins/documentStyles.js +7 -1
- package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +3 -1
- package/dist/prosemirror/rebaseParagraphRunFormatting.js +2 -1
- package/dist/prosemirror/runFormattingInlineCarriers.d.ts +15 -2
- package/dist/prosemirror/runFormattingInlineCarriers.js +33 -3
- package/dist/prosemirror/runStyleFormatting.d.ts +15 -2
- package/dist/prosemirror/runStyleFormatting.js +76 -2
- package/dist/prosemirror/schema/marks.d.ts +3 -1
- package/dist/prosemirror/schema/marks.js +2 -0
- package/dist/prosemirror/schema/nodes.d.ts +3 -0
- package/dist/prosemirror/tableCellRevisionVisibility.d.ts +6 -0
- package/dist/prosemirror/tableCellRevisionVisibility.js +14 -0
- package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
- package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
- package/dist/redline.js +15 -2
- package/dist/server.d.ts +3 -2
- package/dist/server.js +2 -2
- package/dist/version-comparison.d.ts +2 -0
- package/dist/version-comparison.js +30 -29
- package/package.json +2 -2
|
@@ -12,12 +12,14 @@ import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
|
12
12
|
import { reconstructRejectedRunFormattingMarks } from "../runPropertyChangeResolution.js";
|
|
13
13
|
import { paragraphRunStyleContextAt } from "../runStyleFormatting.js";
|
|
14
14
|
import { getTableCellMergeChange } from "../tableCellMergeRevision.js";
|
|
15
|
+
import { isTableCellRetainedInReviewView } from "../tableCellRevisionVisibility.js";
|
|
15
16
|
import { reconcileTableGridAfterColumnRemoval } from "../tableGridMutation.js";
|
|
16
17
|
import { holdsNoContent } from "../zeroWidthAnchors.js";
|
|
17
18
|
import { hasSerializableParagraphPropertyChange, paragraphPropertiesSnapshot, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch } from "./propertyChangeScope.js";
|
|
18
19
|
import { hasMatchingCollapsedTableCellMerge, resolveCollapsedTableCellMerge, resolveVisibleTableCellMerge } from "./tableCellMergeResolution.js";
|
|
19
20
|
import { TableMap, removeRow } from "prosemirror-tables";
|
|
20
|
-
import {
|
|
21
|
+
import { Mapping } from "prosemirror-transform";
|
|
22
|
+
import { PARAGRAPH_MARK_CHANGE_KINDS, REVIEW_CARRIERS } from "@stll/docx-core/model";
|
|
21
23
|
//#region src/prosemirror/commands/comments.ts
|
|
22
24
|
/**
|
|
23
25
|
* Add a comment mark to the current selection.
|
|
@@ -120,7 +122,11 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
|
|
|
120
122
|
if (matches.length > 0) {
|
|
121
123
|
const remaining = sectionChanges.filter((c) => revisionSet !== null && (!c.info || !revisionSet.has(c.info.id)));
|
|
122
124
|
let restored = { ...sectionProperties };
|
|
123
|
-
if (mode === "reject") for (const change of matches.toReversed()) restored = sectionRejectProperties(
|
|
125
|
+
if (mode === "reject") for (const change of matches.toReversed()) restored = sectionRejectProperties({
|
|
126
|
+
live: restored,
|
|
127
|
+
previousProperties: change.previousProperties,
|
|
128
|
+
previousReferences: change.previousReferences
|
|
129
|
+
});
|
|
124
130
|
delete restored.propertyChanges;
|
|
125
131
|
if (remaining.length > 0) restored.propertyChanges = remaining;
|
|
126
132
|
nextAttrs = nextAttrs ?? { ...node.attrs };
|
|
@@ -132,7 +138,12 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
|
|
|
132
138
|
nextAttrs,
|
|
133
139
|
paragraphPosition: pos,
|
|
134
140
|
styleResolver,
|
|
135
|
-
tr
|
|
141
|
+
tr,
|
|
142
|
+
...mode === "reject" && { shouldRebase: (inline) => {
|
|
143
|
+
const deleted = inline.marks.some(({ type }) => type.name === "deletion");
|
|
144
|
+
const direct = inline.marks.some(({ type }) => type.name === "runFormattingOverride");
|
|
145
|
+
return !deleted || !direct;
|
|
146
|
+
} }
|
|
136
147
|
});
|
|
137
148
|
else tr.setNodeMarkup(pos, void 0, nextAttrs);
|
|
138
149
|
return true;
|
|
@@ -309,11 +320,45 @@ function resolveChange(from, to, mode, revisionIds, execution = "legacy") {
|
|
|
309
320
|
removedEndpointCount: removedSectionEndpointCount,
|
|
310
321
|
removedReferences: removedSectionReferences
|
|
311
322
|
});
|
|
323
|
+
if (!terminalTableDeletionIsPending(tr)) resolveTerminalTableReviewCarrier(tr, mode);
|
|
312
324
|
if (tr.steps.length > 0) dispatch(tr);
|
|
313
325
|
}
|
|
314
326
|
return true;
|
|
315
327
|
};
|
|
316
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* The receiver belongs to the deleted terminal table, not every revision in
|
|
331
|
+
* the document. Keep it through independently resolved changes, then resolve
|
|
332
|
+
* it as soon as that table's deletion has been decided.
|
|
333
|
+
*/
|
|
334
|
+
const terminalTableDeletionIsPending = (tr) => {
|
|
335
|
+
let terminalTable = null;
|
|
336
|
+
for (let index = tr.doc.childCount - 1; index >= 0; index--) {
|
|
337
|
+
const node = tr.doc.child(index);
|
|
338
|
+
if (node.type.name === "table") {
|
|
339
|
+
terminalTable = node;
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (terminalTable === null) return false;
|
|
344
|
+
let pending = false;
|
|
345
|
+
terminalTable.descendants((node) => {
|
|
346
|
+
pending ||= node.type.name === "tableRow" && isTableRowRevisionAttr(node.attrs["trDel"]) || node.type.name !== "tableRow" && node.marks.some((mark) => mark.type.name === "deletion");
|
|
347
|
+
return !pending;
|
|
348
|
+
});
|
|
349
|
+
return pending;
|
|
350
|
+
};
|
|
351
|
+
/** Resolve the Folio-only receiver Word needs after a terminal deleted table. */
|
|
352
|
+
const resolveTerminalTableReviewCarrier = (tr, mode) => {
|
|
353
|
+
const carrier = tr.doc.lastChild;
|
|
354
|
+
if (carrier?.type.name !== "paragraph" || carrier.attrs["reviewCarrier"] !== REVIEW_CARRIERS.TERMINAL_TABLE) return;
|
|
355
|
+
const position = tr.doc.content.size - carrier.nodeSize;
|
|
356
|
+
if (mode === "accept") {
|
|
357
|
+
tr.setNodeAttribute(position, "reviewCarrier", void 0);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
tr.delete(position, position + carrier.nodeSize);
|
|
361
|
+
};
|
|
317
362
|
const resolveRunPropertyChange = ({ tr, node, from, to, mark, mode, revisionSet, styleResolver }) => {
|
|
318
363
|
const { changes } = expectRunPropertyChangeMarkAttrs(mark);
|
|
319
364
|
const matches = changes.filter((change) => revisionSet === null || revisionSet.has(change.info.id));
|
|
@@ -401,11 +446,11 @@ function collectTableCellStructuralOps(node, cellPos, mode, revisionSet) {
|
|
|
401
446
|
revisionSet
|
|
402
447
|
});
|
|
403
448
|
else {
|
|
404
|
-
const
|
|
449
|
+
const view = mode === "accept" ? "final" : "original";
|
|
405
450
|
operations.push({
|
|
406
451
|
type: "membership",
|
|
407
452
|
cellPos,
|
|
408
|
-
action:
|
|
453
|
+
action: isTableCellRetainedInReviewView(marker.kind, view) ? "clear" : "remove"
|
|
409
454
|
});
|
|
410
455
|
}
|
|
411
456
|
if (hasMatchingCollapsedTableCellMerge(node, revisionSet)) operations.push({
|
|
@@ -671,6 +716,23 @@ function resolveAllChangesInHeadlessState(state, mode) {
|
|
|
671
716
|
return resolvedState;
|
|
672
717
|
}
|
|
673
718
|
/**
|
|
719
|
+
* Resolve through the editor command path when a caller must map a position in
|
|
720
|
+
* the reviewed document back to the tracked source. The bulk resolver is
|
|
721
|
+
* faster, but deliberately replaces inline content without retaining mapping.
|
|
722
|
+
*/
|
|
723
|
+
const resolveAllChangesInHeadlessStateWithMapping = (state, mode) => {
|
|
724
|
+
let resolvedState = state;
|
|
725
|
+
let mapping = new Mapping();
|
|
726
|
+
resolveChange(0, state.doc.content.size, mode)(state, (transaction) => {
|
|
727
|
+
resolvedState = state.apply(transaction);
|
|
728
|
+
mapping = transaction.mapping;
|
|
729
|
+
});
|
|
730
|
+
return {
|
|
731
|
+
state: resolvedState,
|
|
732
|
+
mapping
|
|
733
|
+
};
|
|
734
|
+
};
|
|
735
|
+
/**
|
|
674
736
|
* Find the document range covered by all revision carriers with any of the
|
|
675
737
|
* given ids. Returns null when none are present (already accepted/rejected, or
|
|
676
738
|
* never existed). A replace operation typically passes two ids; standalone
|
|
@@ -1664,4 +1726,4 @@ function findPreviousChange(state, startPos) {
|
|
|
1664
1726
|
return result.value;
|
|
1665
1727
|
}
|
|
1666
1728
|
//#endregion
|
|
1667
|
-
export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState };
|
|
1729
|
+
export { acceptAIEditRevision, acceptAllChanges, acceptAllSuggestions, acceptChange, acceptSuggestion, addCommentMark, findAIEditRevisionRange, findChangeAtPosition, findNextChange, findParagraphBoundaryChangeAtPosition, findPreviousChange, findSuggestionRange, getSuggestions, rejectAIEditRevision, rejectAllChanges, rejectAllSuggestions, rejectChange, rejectSuggestion, removeCommentMark, resolveAllChangesInHeadlessState, resolveAllChangesInHeadlessStateWithMapping };
|
|
@@ -66,10 +66,16 @@ declare function paragraphRejectOriginalFormatting(previousFormatting: Paragraph
|
|
|
66
66
|
* Rejected section properties: the stored old sectPr wholesale, preserving
|
|
67
67
|
* the live header/footer references — `EG_HdrFtrReferences` is not part of
|
|
68
68
|
* the `CT_SectPrBase` payload a `w:sectPrChange` stores (ECMA-376
|
|
69
|
-
* §17.13.5.32), so those children survive a reject.
|
|
70
|
-
*
|
|
69
|
+
* §17.13.5.32), so those children survive a native reject. An explicit Folio reference
|
|
70
|
+
* history replaces that selection, including restoring its absence. The
|
|
71
|
+
* caller re-attaches whatever `propertyChanges` remain unresolved.
|
|
71
72
|
*/
|
|
72
|
-
|
|
73
|
+
type SectionRejectPropertiesOptions = {
|
|
74
|
+
live: document_d_exports.SectionProperties;
|
|
75
|
+
previousProperties: document_d_exports.SectionProperties | undefined;
|
|
76
|
+
previousReferences?: document_d_exports.SectionPropertyChange["previousReferences"];
|
|
77
|
+
};
|
|
78
|
+
declare function sectionRejectProperties({ live, previousProperties, previousReferences }: SectionRejectPropertiesOptions): document_d_exports.SectionProperties;
|
|
73
79
|
/**
|
|
74
80
|
* Attr patch for rejecting a `w:tblPrChange`: the stored old tblPr wholesale
|
|
75
81
|
* (`w:tblPrChange` stores the complete previous tblPr, so every tblPr-derived
|
|
@@ -220,19 +220,13 @@ function paragraphRejectOriginalFormatting(previousFormatting, liveOriginal) {
|
|
|
220
220
|
if (Object.keys(result).length === 0) return null;
|
|
221
221
|
return result;
|
|
222
222
|
}
|
|
223
|
-
|
|
224
|
-
* Rejected section properties: the stored old sectPr wholesale, preserving
|
|
225
|
-
* the live header/footer references — `EG_HdrFtrReferences` is not part of
|
|
226
|
-
* the `CT_SectPrBase` payload a `w:sectPrChange` stores (ECMA-376
|
|
227
|
-
* §17.13.5.32), so those children survive a reject. The caller re-attaches
|
|
228
|
-
* whatever `propertyChanges` remain unresolved.
|
|
229
|
-
*/
|
|
230
|
-
function sectionRejectProperties(live, previousProperties) {
|
|
223
|
+
function sectionRejectProperties({ live, previousProperties, previousReferences }) {
|
|
231
224
|
const restored = { ...previousProperties };
|
|
232
225
|
delete restored.propertyChanges;
|
|
233
|
-
|
|
226
|
+
const references = previousReferences ?? live;
|
|
227
|
+
if (references.headerReferences) restored.headerReferences = references.headerReferences;
|
|
234
228
|
else delete restored.headerReferences;
|
|
235
|
-
if (
|
|
229
|
+
if (references.footerReferences) restored.footerReferences = references.footerReferences;
|
|
236
230
|
else delete restored.footerReferences;
|
|
237
231
|
return restored;
|
|
238
232
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { imageRawXmlFingerprint } from "../../docx/imageRawXml.js";
|
|
2
2
|
import { PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, ParagraphPropertySourceValidationError, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, linkParagraphPropertySourceCandidate, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceTokenMatchesContract, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings } from "../../docx/paragraphPropertySource.js";
|
|
3
3
|
import { visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
4
4
|
import { ShapeOutlineStyleSchema, narrowEnum } from "../../docx/parserEnums.js";
|
|
5
5
|
import { DATE_UTC_ATTRIBUTE } from "../../docx/trackedChangeInfo.js";
|
|
6
|
+
import { isStyleSourcedParagraphNumbering, modelParagraphFormattingEmission, sameAuthoredParagraphNumberingReference } from "../../internal/paragraphFormattingSerialization.js";
|
|
6
7
|
import { createStyleEngine } from "../../style-engine/styleEngine.js";
|
|
7
8
|
import { OUTLINE_STYLE_CSS_ALIASES, normalizeShapeTextAnchor } from "../../types/documentEnumValues.js";
|
|
8
9
|
import { canonicalJson } from "../../utils/canonicalJson.js";
|
|
@@ -106,9 +107,10 @@ const uniqueParagraphsById = (content, includeTransferIds = false) => {
|
|
|
106
107
|
const restoreParagraphPropertySource = (paragraph, baseParagraph) => {
|
|
107
108
|
copyParagraphPropertySource(paragraph, baseParagraph);
|
|
108
109
|
const baseFormatting = baseParagraph.formatting;
|
|
109
|
-
if (!baseFormatting
|
|
110
|
-
const { numPr, numPrFromStyle
|
|
111
|
-
if (
|
|
110
|
+
if (!baseFormatting) return;
|
|
111
|
+
const { numPr, numPrFromStyle } = baseFormatting;
|
|
112
|
+
if (!numPr || !numPrFromStyle || !isStyleSourcedParagraphNumbering(numPr, numPrFromStyle)) return;
|
|
113
|
+
if (canonicalJson(modelParagraphFormattingEmission(paragraph.formatting)) !== canonicalJson(modelParagraphFormattingEmission(baseFormatting))) return;
|
|
112
114
|
paragraph.formatting = {
|
|
113
115
|
...paragraph.formatting,
|
|
114
116
|
numPr,
|
|
@@ -741,6 +743,7 @@ function convertPMParagraph(node, documentCounts, textBoxAnchorMarkers, styleRes
|
|
|
741
743
|
};
|
|
742
744
|
if (attrs.paraId) paragraph.paraId = attrs.paraId;
|
|
743
745
|
if (attrs.textId) paragraph.textId = attrs.textId;
|
|
746
|
+
if (attrs.reviewCarrier) paragraph.reviewCarrier = attrs.reviewCarrier;
|
|
744
747
|
const pFormatting = paragraphAttrsToFormatting(attrs);
|
|
745
748
|
if (pFormatting) paragraph.formatting = pFormatting;
|
|
746
749
|
const listRendering = listRenderingFromAttrs(attrs);
|
|
@@ -777,15 +780,6 @@ const propertyChangeFromAttrs = (change) => {
|
|
|
777
780
|
...currentFormatting !== void 0 && { currentFormatting }
|
|
778
781
|
};
|
|
779
782
|
};
|
|
780
|
-
/**
|
|
781
|
-
* Whether the paragraph's numbering still comes verbatim from its style —
|
|
782
|
-
* serialize no direct `<w:numPr>` then. The moment a list command changes
|
|
783
|
-
* `numPr` the values diverge and the numbering serializes as direct
|
|
784
|
-
* formatting, so a stale provenance value can never swallow a user edit.
|
|
785
|
-
*/
|
|
786
|
-
function isStyleSourcedNumPr(attrs) {
|
|
787
|
-
return attrs.numPrFromStyle != null && attrs.numPr != null && numPrEqual(attrs.numPr, attrs.numPrFromStyle);
|
|
788
|
-
}
|
|
789
783
|
function assignBooleanToggle(result, attrs, orig, key) {
|
|
790
784
|
const value = attrs[key] ?? void 0;
|
|
791
785
|
if (value === (orig[key] ?? void 0)) return;
|
|
@@ -834,10 +828,10 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
834
828
|
else Reflect.deleteProperty(result, "lineSpacingRule");
|
|
835
829
|
if (directAlignment === void 0) Reflect.deleteProperty(result, "alignment");
|
|
836
830
|
else result.alignment = directAlignment;
|
|
837
|
-
if (
|
|
831
|
+
if (isStyleSourcedParagraphNumbering(attrs.numPr, attrs.numPrFromStyle)) {
|
|
838
832
|
delete result.numPr;
|
|
839
833
|
delete result.numPrFromStyle;
|
|
840
|
-
} else if (attrs.numPr !== orig.numPr && !
|
|
834
|
+
} else if (attrs.numPr !== orig.numPr && !sameAuthoredParagraphNumberingReference(attrs.numPr, orig.numPr)) {
|
|
841
835
|
if (attrs.numPr) result.numPr = attrs.numPr;
|
|
842
836
|
else delete result.numPr;
|
|
843
837
|
delete result.numPrFromStyle;
|
|
@@ -874,7 +868,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
874
868
|
if (attrs.indentRight) f.indentRight = attrs.indentRight;
|
|
875
869
|
if (attrs.indentFirstLine) f.indentFirstLine = attrs.indentFirstLine;
|
|
876
870
|
if (attrs.hangingIndent) f.hangingIndent = attrs.hangingIndent;
|
|
877
|
-
if (attrs.numPr && !
|
|
871
|
+
if (attrs.numPr && !isStyleSourcedParagraphNumbering(attrs.numPr, attrs.numPrFromStyle)) f.numPr = attrs.numPr;
|
|
878
872
|
if (attrs.styleId) f.styleId = attrs.styleId;
|
|
879
873
|
if (attrs.borders) f.borders = attrs.borders;
|
|
880
874
|
if (attrs.shading) f.shading = attrs.shading;
|
|
@@ -1145,6 +1139,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
1145
1139
|
}));
|
|
1146
1140
|
return;
|
|
1147
1141
|
}
|
|
1142
|
+
if (node.type.name === "math") {
|
|
1143
|
+
currentTrackedChange.wrapper.content.push(createMathFromNode(node));
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1148
1146
|
const run = createTrackedChangeRun({
|
|
1149
1147
|
...formattingContext,
|
|
1150
1148
|
marks: otherMarks,
|
|
@@ -1718,9 +1716,6 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1718
1716
|
case "NUMPAGES":
|
|
1719
1717
|
displayText = "1";
|
|
1720
1718
|
break;
|
|
1721
|
-
default:
|
|
1722
|
-
displayText = " ";
|
|
1723
|
-
break;
|
|
1724
1719
|
}
|
|
1725
1720
|
const displayRun = {
|
|
1726
1721
|
type: "run",
|
|
@@ -1732,13 +1727,14 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1732
1727
|
};
|
|
1733
1728
|
if (marks && node.type.name === "field") restoreRunPropertyChanges(displayRun, marks);
|
|
1734
1729
|
const fieldContent = extractedContent.length > 0 ? synchronizeFieldDisplayText(extractedContent, displayText, displayRun) : [];
|
|
1730
|
+
const fallbackFieldContent = displayText ? [displayRun] : [];
|
|
1735
1731
|
if (attrs.fieldKind === "complex") {
|
|
1736
1732
|
const complex = {
|
|
1737
1733
|
type: "complexField",
|
|
1738
1734
|
instruction: attrs.instruction,
|
|
1739
1735
|
fieldType: attrs.fieldType,
|
|
1740
1736
|
fieldCode: [],
|
|
1741
|
-
fieldResult: fieldContent.length > 0 ? fieldContent.filter((content) => content.type === "run") :
|
|
1737
|
+
fieldResult: fieldContent.length > 0 ? fieldContent.filter((content) => content.type === "run") : fallbackFieldContent
|
|
1742
1738
|
};
|
|
1743
1739
|
if (attrs.fldLock) complex.fldLock = true;
|
|
1744
1740
|
if (attrs.dirty) complex.dirty = true;
|
|
@@ -1748,7 +1744,7 @@ function createFieldFromNode(node, { baseParagraphFormatting, inheritedFormattin
|
|
|
1748
1744
|
type: "simpleField",
|
|
1749
1745
|
instruction: attrs.instruction,
|
|
1750
1746
|
fieldType: attrs.fieldType,
|
|
1751
|
-
content: fieldContent.length > 0 ? fieldContent :
|
|
1747
|
+
content: fieldContent.length > 0 ? fieldContent : fallbackFieldContent
|
|
1752
1748
|
};
|
|
1753
1749
|
if (attrs.fldLock) simple.fldLock = true;
|
|
1754
1750
|
if (attrs.dirty) simple.dirty = true;
|
|
@@ -1881,7 +1877,8 @@ function createImageRun(node) {
|
|
|
1881
1877
|
} : {
|
|
1882
1878
|
type: "drawing",
|
|
1883
1879
|
image,
|
|
1884
|
-
...attrs._docxRawXml ? { rawXml: attrs._docxRawXml } : {}
|
|
1880
|
+
...attrs._docxRawXml ? { rawXml: attrs._docxRawXml } : {},
|
|
1881
|
+
...attrs._docxRawXml ? { rawImageFingerprint: imageRawXmlFingerprint(image) } : {}
|
|
1885
1882
|
}]
|
|
1886
1883
|
};
|
|
1887
1884
|
}
|
|
@@ -1967,6 +1964,7 @@ const RUN_FORMATTING_VISUAL_GROUPS = {
|
|
|
1967
1964
|
smallCaps: "smallCaps",
|
|
1968
1965
|
allCaps: "allCaps",
|
|
1969
1966
|
hidden: "hidden",
|
|
1967
|
+
noProof: null,
|
|
1970
1968
|
color: "color",
|
|
1971
1969
|
highlight: "highlight",
|
|
1972
1970
|
shading: "shading",
|
|
@@ -2000,6 +1998,7 @@ const RUN_FORMATTING_FAST_PATH_DISPOSITION = {
|
|
|
2000
1998
|
smallCaps: "visual",
|
|
2001
1999
|
allCaps: "visual",
|
|
2002
2000
|
hidden: "visual",
|
|
2001
|
+
noProof: "structural",
|
|
2003
2002
|
color: "visual",
|
|
2004
2003
|
highlight: "visual",
|
|
2005
2004
|
shading: "visual",
|
|
@@ -2189,6 +2188,7 @@ const DIRECT_OVERRIDE_FORMATTING_PROPERTIES = [
|
|
|
2189
2188
|
"emboss",
|
|
2190
2189
|
"fontSizeCs",
|
|
2191
2190
|
"hidden",
|
|
2191
|
+
"noProof",
|
|
2192
2192
|
"imprint",
|
|
2193
2193
|
"italic",
|
|
2194
2194
|
"italicCs",
|
|
@@ -13,7 +13,7 @@ import { stampNumberedRefFieldBaselines } from "../numberedRefFields.js";
|
|
|
13
13
|
import { pageBreakRunParagraphProjectionDispositionForFeatures } from "../pageBreakRunProjection.js";
|
|
14
14
|
import { directionFromBidi } from "../paragraphDirection.js";
|
|
15
15
|
import { lineSpacingProvenanceFromSpacing } from "../paragraphSpacing.js";
|
|
16
|
-
import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
16
|
+
import { getParagraphMarkSuppressionOverrides, hasDirectRunFormatting, resolveParagraphBodyRunFormatting, stripParagraphMarkFormattingForBodyRuns, stripParagraphMarkOnlyFormatting, suppressParagraphMarkFormatting } from "../runStyleFormatting.js";
|
|
17
17
|
import { schema } from "../schema/index.js";
|
|
18
18
|
import { COMPLEX_SCRIPT_RUN_PROPERTY_KEYS } from "../schema/marks.js";
|
|
19
19
|
import { cascadeStyleTextFormatting } from "../styles/styleToggleCascade.js";
|
|
@@ -202,45 +202,14 @@ function convertParagraph(paragraph, styleResolver, context, activeCommentIds, e
|
|
|
202
202
|
if (!node) return;
|
|
203
203
|
emitInlineNodes([node]);
|
|
204
204
|
};
|
|
205
|
-
let styleRunFormatting;
|
|
206
|
-
let paragraphStyleRunFormatting;
|
|
207
|
-
let paragraphStyleFontFamily;
|
|
208
|
-
if (styleResolver) {
|
|
209
|
-
const resolved = styleResolver.resolveParagraphStyle(paragraph.formatting?.styleId);
|
|
210
|
-
styleRunFormatting = extraRunFormatting === void 0 ? resolved.runFormatting : withoutFontFamily(resolved.runFormatting);
|
|
211
|
-
const paragraphStyle = paragraph.formatting?.styleId ? styleResolver.getStyle(paragraph.formatting.styleId) ?? styleResolver.getDefaultParagraphStyle() : styleResolver.getDefaultParagraphStyle();
|
|
212
|
-
paragraphStyleRunFormatting = paragraphStyle?.type === "paragraph" ? paragraphStyle.rPr : void 0;
|
|
213
|
-
paragraphStyleFontFamily = resolveParagraphStyleFontFamily(paragraph.formatting?.styleId, styleResolver);
|
|
214
|
-
}
|
|
215
205
|
const paragraphRunFormatting = resolveRunFormattingWithoutDefaults(paragraph.formatting?.runProperties, styleResolver);
|
|
216
206
|
let inheritableParagraphRunFormatting;
|
|
217
207
|
if (paragraphRunFormatting && !isTocParagraph && paragraph.formatting?.styleId === void 0) inheritableParagraphRunFormatting = stripParagraphMarkFormattingForBodyRuns(paragraphRunFormatting);
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
formatting: extraRunFormatting,
|
|
226
|
-
type: "style"
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
formatting: paragraphStyleRunFormatting,
|
|
230
|
-
type: "style"
|
|
231
|
-
}
|
|
232
|
-
], { ordinaryFormatting: ordinaryStyleFormatting });
|
|
233
|
-
let baseRunFormatting = orderedToggleFormatting.formatting;
|
|
234
|
-
if (paragraphStyleFontFamily) baseRunFormatting = mergeTextFormatting(baseRunFormatting, { fontFamily: paragraphStyleFontFamily });
|
|
235
|
-
const defaultCharacterFormatting = styleResolver?.getDefaultCharacterStyle()?.rPr;
|
|
236
|
-
const ordinaryBaseWithDefaultCharacter = mergeTextFormatting(defaultCharacterFormatting, baseRunFormatting);
|
|
237
|
-
const defaultCharacterStyleCascade = cascadeStyleTextFormatting([{
|
|
238
|
-
cascade: orderedToggleFormatting,
|
|
239
|
-
type: "carried"
|
|
240
|
-
}, {
|
|
241
|
-
formatting: defaultCharacterFormatting,
|
|
242
|
-
type: "style"
|
|
243
|
-
}], { ordinaryFormatting: ordinaryBaseWithDefaultCharacter });
|
|
208
|
+
const { baseFormatting: baseRunFormatting, baseToggleCascade: orderedToggleFormatting, defaultFormatting: ordinaryBaseWithDefaultCharacter, defaultToggleCascade: defaultCharacterStyleCascade } = resolveParagraphBodyRunFormatting({
|
|
209
|
+
styleId: paragraph.formatting?.styleId,
|
|
210
|
+
tableRunFormatting: extraRunFormatting,
|
|
211
|
+
styleResolver
|
|
212
|
+
});
|
|
244
213
|
const ordinaryDefaultRunFormatting = mergeTextFormatting(ordinaryBaseWithDefaultCharacter, inheritableParagraphRunFormatting);
|
|
245
214
|
const defaultToggleCascade = cascadeStyleTextFormatting([{
|
|
246
215
|
cascade: defaultCharacterStyleCascade,
|
|
@@ -250,8 +219,11 @@ function convertParagraph(paragraph, styleResolver, context, activeCommentIds, e
|
|
|
250
219
|
type: "direct"
|
|
251
220
|
}], { ordinaryFormatting: ordinaryDefaultRunFormatting });
|
|
252
221
|
const defaultRunFormatting = defaultToggleCascade.formatting;
|
|
253
|
-
if (extraRunFormatting !== void 0)
|
|
254
|
-
|
|
222
|
+
if (extraRunFormatting !== void 0) {
|
|
223
|
+
attrs._tableRunFormatting = extraRunFormatting;
|
|
224
|
+
if (defaultRunFormatting) attrs.defaultTextFormatting = defaultRunFormatting;
|
|
225
|
+
else delete attrs.defaultTextFormatting;
|
|
226
|
+
}
|
|
255
227
|
const getInheritedRunFormatting = (formatting, fieldType) => {
|
|
256
228
|
const hasCharacterStyle = formatting?.styleId !== void 0;
|
|
257
229
|
const inheritedBaseFormatting = hasCharacterStyle ? baseRunFormatting : ordinaryBaseWithDefaultCharacter;
|
|
@@ -350,24 +322,6 @@ function convertParagraph(paragraph, styleResolver, context, activeCommentIds, e
|
|
|
350
322
|
content: inlineNodes
|
|
351
323
|
});
|
|
352
324
|
}
|
|
353
|
-
const withoutFontFamily = (formatting) => {
|
|
354
|
-
if (!formatting?.fontFamily) return formatting;
|
|
355
|
-
const { fontFamily: _fontFamily, ...withoutFont } = formatting;
|
|
356
|
-
return Object.keys(withoutFont).length > 0 ? withoutFont : void 0;
|
|
357
|
-
};
|
|
358
|
-
const resolveParagraphStyleFontFamily = (styleId, styleResolver) => {
|
|
359
|
-
let style = styleId ? styleResolver.getStyle(styleId) : styleResolver.getDefaultParagraphStyle();
|
|
360
|
-
const visited = /* @__PURE__ */ new Set();
|
|
361
|
-
const styleChain = [];
|
|
362
|
-
while (style?.type === "paragraph" && !visited.has(style.styleId)) {
|
|
363
|
-
visited.add(style.styleId);
|
|
364
|
-
if (style.rPr?.fontFamily) styleChain.push({ fontFamily: style.rPr.fontFamily });
|
|
365
|
-
style = style.basedOn ? styleResolver.getStyle(style.basedOn) : void 0;
|
|
366
|
-
}
|
|
367
|
-
let formatting;
|
|
368
|
-
for (const styleFormatting of styleChain.toReversed()) formatting = mergeTextFormatting(formatting, styleFormatting);
|
|
369
|
-
return formatting?.fontFamily;
|
|
370
|
-
};
|
|
371
325
|
/**
|
|
372
326
|
* Apply comment marks to PM nodes within a comment range.
|
|
373
327
|
*/
|
|
@@ -418,6 +372,9 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, next
|
|
|
418
372
|
textBoxAnchors
|
|
419
373
|
});
|
|
420
374
|
if (fieldNode) nodes.push(fieldNode);
|
|
375
|
+
} else if (item.type === "mathEquation") {
|
|
376
|
+
const mathNode = convertMathEquation(item);
|
|
377
|
+
if (mathNode) nodes.push(mathNode);
|
|
421
378
|
} else if (item.type === "insertion" || item.type === "deletion" || item.type === "moveFrom" || item.type === "moveTo") {
|
|
422
379
|
const nestedMarkType = item.type === "insertion" || item.type === "moveTo" ? "insertion" : "deletion";
|
|
423
380
|
const nestedMoveKind = item.type === "moveFrom" || item.type === "moveTo" ? item.type : null;
|
|
@@ -460,6 +417,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
460
417
|
const attrs = {};
|
|
461
418
|
if (paragraph.paraId) attrs.paraId = paragraph.paraId;
|
|
462
419
|
if (paragraph.textId) attrs.textId = paragraph.textId;
|
|
420
|
+
if (paragraph.reviewCarrier) attrs.reviewCarrier = paragraph.reviewCarrier;
|
|
463
421
|
if (styleId) attrs.styleId = styleId;
|
|
464
422
|
if (tableOfContentsLevel !== void 0) attrs._tableOfContentsLevel = tableOfContentsLevel;
|
|
465
423
|
if (formatting?.numPr) attrs.numPr = formatting.numPr;
|
|
@@ -1415,6 +1373,7 @@ const RUN_FORMATTING_INFERENCE = {
|
|
|
1415
1373
|
smallCaps: "visible-boolean",
|
|
1416
1374
|
allCaps: "visible-boolean",
|
|
1417
1375
|
hidden: "visible-boolean",
|
|
1376
|
+
noProof: "structural",
|
|
1418
1377
|
color: "color",
|
|
1419
1378
|
highlight: "visible-value",
|
|
1420
1379
|
shading: "preserve",
|
|
@@ -188,6 +188,7 @@ const paragraphNodeSpec = {
|
|
|
188
188
|
[PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR]: { default: null },
|
|
189
189
|
idStability: { default: void 0 },
|
|
190
190
|
textId: { default: null },
|
|
191
|
+
reviewCarrier: { default: void 0 },
|
|
191
192
|
alignment: { default: null },
|
|
192
193
|
alignmentFromStyle: { default: void 0 },
|
|
193
194
|
kinsoku: { default: null },
|
|
@@ -240,6 +241,7 @@ const paragraphNodeSpec = {
|
|
|
240
241
|
contextualSpacing: { default: null },
|
|
241
242
|
runInWithNext: { default: null },
|
|
242
243
|
defaultTextFormatting: { default: null },
|
|
244
|
+
_tableRunFormatting: { default: void 0 },
|
|
243
245
|
sectionBreakType: { default: null },
|
|
244
246
|
direction: { default: null },
|
|
245
247
|
outlineLevel: { default: null },
|
|
@@ -19,6 +19,7 @@ function buildRunFormattingOverrideAttrs(formatting, options) {
|
|
|
19
19
|
if (formatting?.allCaps !== void 0) attrs.allCaps = formatting.allCaps;
|
|
20
20
|
if (formatting?.smallCaps !== void 0) attrs.smallCaps = formatting.smallCaps;
|
|
21
21
|
if (formatting?.hidden !== void 0) attrs.hidden = formatting.hidden;
|
|
22
|
+
if (formatting?.noProof !== void 0) attrs.noProof = formatting.noProof;
|
|
22
23
|
if (formatting?.emboss !== void 0) attrs.emboss = formatting.emboss;
|
|
23
24
|
if (formatting?.imprint !== void 0) attrs.imprint = formatting.imprint;
|
|
24
25
|
if (formatting?.shadow !== void 0) attrs.shadow = formatting.shadow;
|
|
@@ -58,6 +59,7 @@ function applyRunFormattingOverrideAttrs(formatting, attrs) {
|
|
|
58
59
|
if (attrs.allCaps !== void 0) formatting.allCaps = attrs.allCaps;
|
|
59
60
|
if (attrs.smallCaps !== void 0) formatting.smallCaps = attrs.smallCaps;
|
|
60
61
|
if (attrs.hidden !== void 0) formatting.hidden = attrs.hidden;
|
|
62
|
+
if (attrs.noProof !== void 0) formatting.noProof = attrs.noProof;
|
|
61
63
|
if (attrs.emboss !== void 0) formatting.emboss = attrs.emboss;
|
|
62
64
|
if (attrs.imprint !== void 0) formatting.imprint = attrs.imprint;
|
|
63
65
|
if (attrs.shadow !== void 0) formatting.shadow = attrs.shadow;
|
|
@@ -101,6 +103,7 @@ const RunFormattingOverrideExtension = createMarkExtension({
|
|
|
101
103
|
allCaps: { default: null },
|
|
102
104
|
smallCaps: { default: null },
|
|
103
105
|
hidden: { default: null },
|
|
106
|
+
noProof: { default: null },
|
|
104
107
|
emboss: { default: null },
|
|
105
108
|
imprint: { default: null },
|
|
106
109
|
shadow: { default: null },
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { expectImageAttrs, mergeImageAttrs } from "./attrs/index.js";
|
|
2
|
+
import { DRAWING_RAW_XML_MODES } from "@stll/docx-core/model";
|
|
1
3
|
//#region src/prosemirror/imageCommit.ts
|
|
2
4
|
const MIN_IMAGE_PX = 20;
|
|
3
5
|
const MAX_IMAGE_PX = 2e3;
|
|
@@ -40,6 +42,7 @@ function isFloatingImage(node) {
|
|
|
40
42
|
function imageNodeAt(view, pmPos) {
|
|
41
43
|
const node = view.state.doc.nodeAt(pmPos);
|
|
42
44
|
if (!node || node.type.name !== "image") return null;
|
|
45
|
+
if (expectImageAttrs(node)._docxRawXmlMode === DRAWING_RAW_XML_MODES.PRESERVE_ONLY) return null;
|
|
43
46
|
return node;
|
|
44
47
|
}
|
|
45
48
|
/**
|
|
@@ -50,11 +53,10 @@ function commitImageResize(view, pmPos, newWidth, newHeight) {
|
|
|
50
53
|
try {
|
|
51
54
|
const node = imageNodeAt(view, pmPos);
|
|
52
55
|
if (!node) return null;
|
|
53
|
-
view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, {
|
|
54
|
-
...node.attrs,
|
|
56
|
+
view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, mergeImageAttrs(node, {
|
|
55
57
|
width: newWidth,
|
|
56
58
|
height: newHeight
|
|
57
|
-
}));
|
|
59
|
+
})));
|
|
58
60
|
return pmPos;
|
|
59
61
|
} catch {
|
|
60
62
|
return null;
|
|
@@ -69,7 +71,7 @@ function commitImageFloatMove(view, pmPos, hOffsetEmu, vOffsetEmu) {
|
|
|
69
71
|
try {
|
|
70
72
|
const node = imageNodeAt(view, pmPos);
|
|
71
73
|
if (!node) return null;
|
|
72
|
-
|
|
74
|
+
view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, mergeImageAttrs(node, { position: {
|
|
73
75
|
horizontal: {
|
|
74
76
|
posOffset: hOffsetEmu,
|
|
75
77
|
relativeTo: "margin"
|
|
@@ -78,11 +80,7 @@ function commitImageFloatMove(view, pmPos, hOffsetEmu, vOffsetEmu) {
|
|
|
78
80
|
posOffset: vOffsetEmu,
|
|
79
81
|
relativeTo: "margin"
|
|
80
82
|
}
|
|
81
|
-
};
|
|
82
|
-
view.dispatch(view.state.tr.setNodeMarkup(pmPos, void 0, {
|
|
83
|
-
...node.attrs,
|
|
84
|
-
position: newPosition
|
|
85
|
-
}));
|
|
83
|
+
} })));
|
|
86
84
|
return pmPos;
|
|
87
85
|
} catch {
|
|
88
86
|
return null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { FolioContentParagraphIndentation } from "../compare/content-types.js";
|
|
3
|
+
import { ParagraphAttrs } from "./schema/nodes.js";
|
|
4
|
+
//#region src/prosemirror/paragraphIndentation.d.ts
|
|
5
|
+
/** The authored `w:ind` attribute cluster. */
|
|
6
|
+
type DirectParagraphIndentation = FolioContentParagraphIndentation;
|
|
7
|
+
/** Project only authored `w:ind` attributes, preserving zero and false. */
|
|
8
|
+
declare const paragraphIndentationFromFormatting: (formatting: document_d_exports.ParagraphFormatting | null | undefined) => DirectParagraphIndentation | undefined;
|
|
9
|
+
/** Read direct indentation without materializing values inherited from a style. */
|
|
10
|
+
declare const directParagraphIndentation: (attrs: ParagraphAttrs) => DirectParagraphIndentation | undefined;
|
|
11
|
+
declare const paragraphIndentationEqual: (left: DirectParagraphIndentation | null | undefined, right: DirectParagraphIndentation | null | undefined) => boolean;
|
|
12
|
+
/** Replace the complete direct `w:ind` cluster in canonical formatting. */
|
|
13
|
+
declare const withDirectParagraphIndentation: (formatting: document_d_exports.ParagraphFormatting | null | undefined, indentation: DirectParagraphIndentation | null | undefined) => document_d_exports.ParagraphFormatting | undefined;
|
|
14
|
+
type ParagraphIndentationAttrPatchOptions = {
|
|
15
|
+
direct: DirectParagraphIndentation | null | undefined;
|
|
16
|
+
inherited: DirectParagraphIndentation | null | undefined;
|
|
17
|
+
};
|
|
18
|
+
/** Project direct-over-inherited indentation into paragraph attrs. */
|
|
19
|
+
declare const paragraphIndentationAttrPatch: ({ direct, inherited }: ParagraphIndentationAttrPatchOptions) => Record<string, unknown>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { DirectParagraphIndentation, directParagraphIndentation, paragraphIndentationAttrPatch, paragraphIndentationEqual, paragraphIndentationFromFormatting, withDirectParagraphIndentation };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { panic } from "better-result";
|
|
2
|
+
//#region src/prosemirror/paragraphIndentation.ts
|
|
3
|
+
const DIRECT_PARAGRAPH_INDENTATION_KEYS = [
|
|
4
|
+
"indentLeft",
|
|
5
|
+
"indentRight",
|
|
6
|
+
"indentFirstLine",
|
|
7
|
+
"hangingIndent"
|
|
8
|
+
];
|
|
9
|
+
const copyIndentationValue = ({ target, key, value }) => {
|
|
10
|
+
switch (key) {
|
|
11
|
+
case "hangingIndent":
|
|
12
|
+
if (typeof value === "boolean") target.hangingIndent = value;
|
|
13
|
+
return;
|
|
14
|
+
case "indentLeft":
|
|
15
|
+
case "indentRight":
|
|
16
|
+
case "indentFirstLine":
|
|
17
|
+
if (typeof value === "number") target[key] = value;
|
|
18
|
+
return;
|
|
19
|
+
default: return panic("Unhandled paragraph indentation property", { key });
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/** Project only authored `w:ind` attributes, preserving zero and false. */
|
|
23
|
+
const paragraphIndentationFromFormatting = (formatting) => {
|
|
24
|
+
if (!formatting) return;
|
|
25
|
+
const indentation = {};
|
|
26
|
+
for (const key of DIRECT_PARAGRAPH_INDENTATION_KEYS) copyIndentationValue({
|
|
27
|
+
target: indentation,
|
|
28
|
+
key,
|
|
29
|
+
value: formatting[key]
|
|
30
|
+
});
|
|
31
|
+
if (indentation.indentFirstLine !== void 0 && indentation.hangingIndent === void 0) indentation.hangingIndent = false;
|
|
32
|
+
return Object.keys(indentation).length > 0 ? indentation : void 0;
|
|
33
|
+
};
|
|
34
|
+
/** Read direct indentation without materializing values inherited from a style. */
|
|
35
|
+
const directParagraphIndentation = (attrs) => {
|
|
36
|
+
const original = paragraphIndentationFromFormatting(attrs._originalFormatting);
|
|
37
|
+
if (!original) return;
|
|
38
|
+
const indentation = {};
|
|
39
|
+
for (const key of DIRECT_PARAGRAPH_INDENTATION_KEYS) {
|
|
40
|
+
if (original[key] === void 0) continue;
|
|
41
|
+
copyIndentationValue({
|
|
42
|
+
target: indentation,
|
|
43
|
+
key,
|
|
44
|
+
value: attrs[key]
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return Object.keys(indentation).length > 0 ? indentation : void 0;
|
|
48
|
+
};
|
|
49
|
+
const paragraphIndentationEqual = (left, right) => DIRECT_PARAGRAPH_INDENTATION_KEYS.every((key) => left?.[key] === right?.[key]);
|
|
50
|
+
/** Replace the complete direct `w:ind` cluster in canonical formatting. */
|
|
51
|
+
const withDirectParagraphIndentation = (formatting, indentation) => {
|
|
52
|
+
const result = { ...formatting };
|
|
53
|
+
for (const key of DIRECT_PARAGRAPH_INDENTATION_KEYS) Reflect.deleteProperty(result, key);
|
|
54
|
+
if (indentation) Object.assign(result, indentation);
|
|
55
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
56
|
+
};
|
|
57
|
+
/** Project direct-over-inherited indentation into paragraph attrs. */
|
|
58
|
+
const paragraphIndentationAttrPatch = ({ direct, inherited }) => {
|
|
59
|
+
const effective = {
|
|
60
|
+
...inherited,
|
|
61
|
+
...direct
|
|
62
|
+
};
|
|
63
|
+
const hangingIndent = direct?.indentFirstLine === void 0 ? effective.hangingIndent ?? false : direct.hangingIndent === true;
|
|
64
|
+
return {
|
|
65
|
+
indentLeft: effective.indentLeft ?? null,
|
|
66
|
+
indentRight: effective.indentRight ?? null,
|
|
67
|
+
indentFirstLine: effective.indentFirstLine ?? null,
|
|
68
|
+
hangingIndent
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
export { directParagraphIndentation, paragraphIndentationAttrPatch, paragraphIndentationEqual, paragraphIndentationFromFormatting, withDirectParagraphIndentation };
|
|
@@ -4,5 +4,7 @@ import { EditorState, Plugin } from "prosemirror-state";
|
|
|
4
4
|
//#region src/prosemirror/plugins/documentNumbering.d.ts
|
|
5
5
|
declare const createDocumentNumberingPlugin: (definitions: document_d_exports.NumberingDefinitions | null | undefined) => Plugin;
|
|
6
6
|
declare const getDocumentNumbering: (state: EditorState) => NumberingMap | null;
|
|
7
|
+
/** Replace numbering state while retaining every unrelated plugin state. */
|
|
8
|
+
declare const withDocumentNumbering: (state: EditorState, definitions: document_d_exports.NumberingDefinitions) => EditorState;
|
|
7
9
|
//#endregion
|
|
8
|
-
export { createDocumentNumberingPlugin, getDocumentNumbering };
|
|
10
|
+
export { createDocumentNumberingPlugin, getDocumentNumbering, withDocumentNumbering };
|