@stll/folio-core 0.35.0 → 0.36.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 +370 -118
- package/dist/ai-edits/headless.js +16 -10
- package/dist/ai-edits/index.d.ts +2 -2
- package/dist/ai-edits/index.js +2 -2
- package/dist/ai-edits/snapshot.js +6 -1
- package/dist/ai-edits/types.d.ts +19 -6
- package/dist/ai-edits/word-diff.d.ts +18 -3
- package/dist/ai-edits/word-diff.js +556 -67
- package/dist/compare/compare.js +7 -16
- package/dist/compare/plan.js +8 -5
- package/dist/compare/verification.d.ts +8 -9
- package/dist/compare/verification.js +51 -46
- package/dist/compat/eigenpal.d.ts +2 -2
- package/dist/compat/eigenpal.js +2 -2
- package/dist/controller/headerFooterEditorManager.js +5 -5
- package/dist/controller/hiddenEditorApi.js +1 -1
- package/dist/controller/noteEditorManager.js +2 -2
- package/dist/document-operations.d.ts +5 -3
- package/dist/document-operations.js +32 -5
- package/dist/docx/commentParser.js +2 -4
- package/dist/docx/commentRangeIntegrity.js +2 -4
- package/dist/docx/documentClone.d.ts +2 -0
- package/dist/docx/documentClone.js +2 -0
- package/dist/docx/headerFooterParser.js +2 -4
- package/dist/docx/normalizeBaseDirection.js +5 -7
- package/dist/docx/paragraphParser.js +27 -29
- package/dist/docx/paragraphPropertySource.d.ts +49 -0
- package/dist/docx/paragraphPropertySource.js +113 -0
- package/dist/docx/runConsolidator.js +3 -4
- package/dist/docx/runParser.js +2 -15
- package/dist/docx/sectionParser.js +1 -15
- package/dist/docx/serializer/paragraphSerializer.js +287 -30
- package/dist/docx/serializer/runSerializer.js +2 -10
- package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -10
- package/dist/docx/serializer/tableSerializer.js +4 -23
- package/dist/docx/serializer/trackedChangeAttributes.d.ts +9 -0
- package/dist/docx/serializer/trackedChangeAttributes.js +21 -0
- package/dist/docx/server/createBilingualDocument.js +8 -10
- package/dist/docx/server/evaluateDocxXmlPatchProposal.js +22 -13
- package/dist/docx/server/validateDocxConformance.js +17 -13
- package/dist/docx/tableParser.js +1 -37
- package/dist/docx/trackedChangeInfo.d.ts +11 -0
- package/dist/docx/trackedChangeInfo.js +38 -0
- package/dist/docx/verbatimCapture.d.ts +20 -9
- package/dist/docx/verbatimCapture.js +208 -8
- package/dist/docx/xmlParser.d.ts +3 -1
- package/dist/docx/xmlParser.js +6 -1
- package/dist/docx/xmlSafety.d.ts +1 -1
- package/dist/docx/xmlSafety.js +157 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/layout-bridge/convert/headerFooterLayout.js +4 -4
- package/dist/layout-bridge/convert/toFlowBlocks.js +12 -7
- package/dist/markdown/renderBlock.js +7 -10
- package/dist/prosemirror/attrs/index.js +15 -0
- package/dist/prosemirror/commands/comments.js +365 -32
- package/dist/prosemirror/commands/pageBreak.js +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +26 -4
- package/dist/prosemirror/commands/propertyChangeScope.js +65 -3
- package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -4
- package/dist/prosemirror/conversion/fromProseDoc.js +130 -18
- package/dist/prosemirror/conversion/toProseDoc.js +27 -12
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +48 -4
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -1
- package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +20 -7
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
- package/dist/prosemirror/paragraphAlignment.d.ts +12 -0
- package/dist/prosemirror/paragraphAlignment.js +13 -0
- package/dist/prosemirror/plugins/suggestionMode.js +1 -1
- package/dist/prosemirror/schema/marks.d.ts +2 -0
- package/dist/prosemirror/schema/nodes.d.ts +12 -1
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/redline.js +4 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/dist/utils/mergeDocumentContent.js +3 -3
- package/dist/utils/replaceText.js +2 -1
- package/dist/version-comparison.js +6 -4
- package/dist/watermark/index.js +2 -4
- package/package.json +7 -2
|
@@ -1,7 +1,52 @@
|
|
|
1
|
+
import { expectParagraphAttrs } from "../attrs/index.js";
|
|
1
2
|
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
3
|
+
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
2
4
|
import { directionFromBidi } from "../paragraphDirection.js";
|
|
3
5
|
//#region src/prosemirror/commands/propertyChangeScope.ts
|
|
4
6
|
/**
|
|
7
|
+
* Remove selected entries from an oldest-to-newest paragraph-property chain.
|
|
8
|
+
* A retained entry immediately after a removed run inherits that run's
|
|
9
|
+
* earliest previous snapshot. Only a removed trailing run restores the live
|
|
10
|
+
* paragraph properties. This makes repeated scoped rejection independent of
|
|
11
|
+
* the order in which revisions are resolved.
|
|
12
|
+
*/
|
|
13
|
+
const removeParagraphPropertyChanges = (changes, shouldRemove) => {
|
|
14
|
+
const remaining = [];
|
|
15
|
+
let removedPrevious;
|
|
16
|
+
let removedAny = false;
|
|
17
|
+
let removingRun = false;
|
|
18
|
+
for (const change of changes) {
|
|
19
|
+
if (shouldRemove(change)) {
|
|
20
|
+
if (!removingRun) {
|
|
21
|
+
removedPrevious = change.previousFormatting;
|
|
22
|
+
removingRun = true;
|
|
23
|
+
}
|
|
24
|
+
removedAny = true;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!removingRun) {
|
|
28
|
+
remaining.push(change);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const rebased = { ...change };
|
|
32
|
+
if (removedPrevious === void 0) Reflect.deleteProperty(rebased, "previousFormatting");
|
|
33
|
+
else rebased.previousFormatting = removedPrevious;
|
|
34
|
+
remaining.push(rebased);
|
|
35
|
+
removedPrevious = void 0;
|
|
36
|
+
removingRun = false;
|
|
37
|
+
}
|
|
38
|
+
if (!removedAny) return { type: "unchanged" };
|
|
39
|
+
if (!removingRun) return {
|
|
40
|
+
type: "keep-live",
|
|
41
|
+
remaining
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
type: "restore-previous",
|
|
45
|
+
remaining,
|
|
46
|
+
previousFormatting: removedPrevious
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
5
50
|
* Paragraph attrs governed by a `w:pPrChange` — the attrs
|
|
6
51
|
* `paragraphFormattingToAttrs` (conversion/toProseDoc.ts) can produce from a
|
|
7
52
|
* parsed `CT_PPrBase` (ECMA-376 §17.13.5.29). Rejecting a pPrChange restores
|
|
@@ -17,7 +62,8 @@ import { directionFromBidi } from "../paragraphDirection.js";
|
|
|
17
62
|
* `runInWithNext` (`w:specVanish` lives in that rPr)
|
|
18
63
|
* - load-time style/numbering bookkeeping the command layer cannot recompute
|
|
19
64
|
* without a style resolver: `numPrFromStyle`, the `list*` rendering attrs,
|
|
20
|
-
* `
|
|
65
|
+
* `alignmentFromStyle`, `spacingFromDocDefaults`,
|
|
66
|
+
* `spacingFromImplicitDefaultStyle`
|
|
21
67
|
*/
|
|
22
68
|
const PPR_CHANGE_SCOPED_ATTR_KEYS = [
|
|
23
69
|
"styleId",
|
|
@@ -47,6 +93,20 @@ const PPR_CHANGE_SCOPED_ATTR_KEYS = [
|
|
|
47
93
|
"_autospacingBase"
|
|
48
94
|
];
|
|
49
95
|
const PPR_CHANGE_SCOPED_ATTR_KEY_SET = new Set(PPR_CHANGE_SCOPED_ATTR_KEYS);
|
|
96
|
+
/** The in-scope paragraph properties as they stand, for a `w:pPrChange` record. */
|
|
97
|
+
const paragraphPropertiesSnapshot = (node) => {
|
|
98
|
+
const attrs = expectParagraphAttrs(node);
|
|
99
|
+
const snapshot = {};
|
|
100
|
+
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS) {
|
|
101
|
+
if (key === "alignment") continue;
|
|
102
|
+
const value = attrs[key];
|
|
103
|
+
if (key === "hangingIndent" && value === false && attrs._originalFormatting?.hangingIndent === void 0) continue;
|
|
104
|
+
if (value !== null && value !== void 0) snapshot[key] = value;
|
|
105
|
+
}
|
|
106
|
+
const directAlignment = directParagraphAlignment(attrs);
|
|
107
|
+
if (directAlignment !== void 0) snapshot["alignment"] = directAlignment;
|
|
108
|
+
return snapshot;
|
|
109
|
+
};
|
|
50
110
|
/**
|
|
51
111
|
* Parser-shaped `ParagraphFormatting` keys that must NOT merge through to
|
|
52
112
|
* attrs verbatim: they either normalize to a differently named attr
|
|
@@ -108,10 +168,12 @@ const PPR_CHANGE_SCOPED_FORMATTING_KEYS = [
|
|
|
108
168
|
* the scoped set (editor-created list suggestions snapshot list-rendering
|
|
109
169
|
* bookkeeping attrs) merge through 1:1 so their pre-change values restore too.
|
|
110
170
|
*/
|
|
111
|
-
function paragraphRejectAttrPatch(previousFormatting) {
|
|
171
|
+
function paragraphRejectAttrPatch(previousFormatting, alignmentFromStyle) {
|
|
112
172
|
const prev = previousFormatting ?? {};
|
|
113
173
|
const patch = {};
|
|
114
174
|
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS) patch[key] = Object.hasOwn(prev, key) ? prev[key] ?? null : null;
|
|
175
|
+
if (!Object.hasOwn(prev, "alignment")) patch["alignment"] = alignmentFromStyle ?? null;
|
|
176
|
+
patch["alignmentFromStyle"] = alignmentFromStyle;
|
|
115
177
|
if (!Object.hasOwn(prev, "direction")) patch["direction"] = directionFromBidi(prev.bidi);
|
|
116
178
|
if (!Object.hasOwn(prev, "_autospacingBase")) patch["_autospacingBase"] = autospacingBaseFromFormatting(prev);
|
|
117
179
|
for (const [key, value] of Object.entries(prev)) {
|
|
@@ -241,4 +303,4 @@ function isRecord(value) {
|
|
|
241
303
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
242
304
|
}
|
|
243
305
|
//#endregion
|
|
244
|
-
export { PPR_CHANGE_SCOPED_ATTR_KEYS, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch };
|
|
306
|
+
export { PPR_CHANGE_SCOPED_ATTR_KEYS, paragraphPropertiesSnapshot, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch };
|
|
@@ -2,9 +2,7 @@ import { document_d_exports } from "../../types/document.js";
|
|
|
2
2
|
import { TableAttrs, TableCellAttrs, TableRowAttrs } from "../schema/nodes.js";
|
|
3
3
|
import { Mark, Node } from "prosemirror-model";
|
|
4
4
|
//#region src/prosemirror/conversion/fromProseDoc.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* Convert a ProseMirror document to our Document type
|
|
7
|
-
*/
|
|
5
|
+
/** Convert a ProseMirror document to the document model. */
|
|
8
6
|
declare function fromProseDoc(pmDoc: Node, baseDocument?: document_d_exports.Document): document_d_exports.Document;
|
|
9
7
|
/**
|
|
10
8
|
* Convert ProseMirror marks to TextFormatting
|
|
@@ -32,6 +30,6 @@ declare function updateDocumentContent(originalDocument: document_d_exports.Docu
|
|
|
32
30
|
* Used for converting edited header/footer PM content back to the document
|
|
33
31
|
* model.
|
|
34
32
|
*/
|
|
35
|
-
declare function proseDocToBlocks(pmDoc: Node): document_d_exports.BlockContent[];
|
|
33
|
+
declare function proseDocToBlocks(pmDoc: Node, baseContent?: document_d_exports.BlockContent[]): document_d_exports.BlockContent[];
|
|
36
34
|
//#endregion
|
|
37
35
|
export { fromProseDoc, marksToTextFormatting, proseDocToBlocks, standaloneTableCellFromProseMirror, tableAttrsToFormatting, tableCellAttrsToFormatting, tableRowAttrsToFormatting, updateDocumentContent };
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { numPrEqual } from "../../docx/numberingParser.js";
|
|
2
|
+
import { copyParagraphPropertySource, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceTransferId, linkParagraphPropertySourceCandidate, recreateProseNodeWithParagraphPropertySource } from "../../docx/paragraphPropertySource.js";
|
|
3
|
+
import { visitDocxParagraphs } from "../../docx/paragraphTraversal.js";
|
|
2
4
|
import { ShapeOutlineStyleSchema, narrowEnum } from "../../docx/parserEnums.js";
|
|
5
|
+
import { DATE_UTC_ATTRIBUTE } from "../../docx/trackedChangeInfo.js";
|
|
3
6
|
import { OUTLINE_STYLE_CSS_ALIASES, normalizeShapeTextAnchor } from "../../types/documentEnumValues.js";
|
|
4
7
|
import { canonicalJson } from "../../utils/canonicalJson.js";
|
|
5
8
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
@@ -7,8 +10,10 @@ import { pixelsToEmu } from "../../utils/units.js";
|
|
|
7
10
|
import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
|
|
8
11
|
import { autospacingMatchesBase, hasAutospacingBaseSide } from "../autospacingBase.js";
|
|
9
12
|
import { expectBookmarkBoundaryAttrs } from "../bookmarkBoundaryAttrs.js";
|
|
13
|
+
import { paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, removeParagraphPropertyChanges } from "../commands/propertyChangeScope.js";
|
|
10
14
|
import { applyRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
11
15
|
import { resolveNumberedRefFields } from "../numberedRefFields.js";
|
|
16
|
+
import { directParagraphAlignment } from "../paragraphAlignment.js";
|
|
12
17
|
import { directionToBidi } from "../paragraphDirection.js";
|
|
13
18
|
import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
|
|
14
19
|
import { parseShapeGeometryAdjustments } from "../shapeGeometryAdjustments.js";
|
|
@@ -76,12 +81,68 @@ function textBoxWrapFromAttrs(attrs) {
|
|
|
76
81
|
if (attrs.distRight !== void 0) wrap.distR = pixelsToEmu(attrs.distRight);
|
|
77
82
|
return wrap;
|
|
78
83
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
const assignUniqueParagraph = (paragraphs, paraId, paragraph) => {
|
|
85
|
+
const existing = paragraphs.get(paraId);
|
|
86
|
+
if (!paragraphs.has(paraId) || existing === paragraph) {
|
|
87
|
+
paragraphs.set(paraId, paragraph);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
paragraphs.set(paraId, null);
|
|
91
|
+
};
|
|
92
|
+
const uniqueParagraphsById = (content, includeTransferIds = false) => {
|
|
93
|
+
const paragraphs = /* @__PURE__ */ new Map();
|
|
94
|
+
visitDocxParagraphs({ documentBody: { content } }, (paragraph) => {
|
|
95
|
+
const { paraId } = paragraph;
|
|
96
|
+
if (paraId) assignUniqueParagraph(paragraphs, paraId, paragraph);
|
|
97
|
+
const transferId = includeTransferIds ? getParagraphPropertySourceTransferId(paragraph) : void 0;
|
|
98
|
+
if (transferId) assignUniqueParagraph(paragraphs, transferId, paragraph);
|
|
99
|
+
});
|
|
100
|
+
return paragraphs;
|
|
101
|
+
};
|
|
102
|
+
const restoreParagraphPropertySources = (content, baseContent, linkedTargets, linkedSources) => {
|
|
103
|
+
const baseParagraphs = uniqueParagraphsById(baseContent, true);
|
|
104
|
+
for (const [paraId, paragraph] of uniqueParagraphsById(content)) {
|
|
105
|
+
const baseParagraph = baseParagraphs.get(paraId);
|
|
106
|
+
if (!paragraph || !baseParagraph || linkedTargets.has(paragraph) || linkedSources.has(baseParagraph) || !getParagraphPropertySource(baseParagraph)) continue;
|
|
107
|
+
copyParagraphPropertySource(paragraph, baseParagraph);
|
|
108
|
+
const baseFormatting = baseParagraph.formatting;
|
|
109
|
+
if (!baseFormatting?.numPr || !baseFormatting.numPrFromStyle || !numPrEqual(baseFormatting.numPr, baseFormatting.numPrFromStyle)) continue;
|
|
110
|
+
const { numPr, numPrFromStyle, ...authoredFormatting } = baseFormatting;
|
|
111
|
+
if (canonicalJson(paragraph.formatting ?? {}) !== canonicalJson(authoredFormatting)) continue;
|
|
112
|
+
paragraph.formatting = {
|
|
113
|
+
...paragraph.formatting,
|
|
114
|
+
numPr,
|
|
115
|
+
numPrFromStyle
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const restoreLinkedParagraphPropertySources = (content) => {
|
|
120
|
+
const targetsBySource = /* @__PURE__ */ new Map();
|
|
121
|
+
const linkedTargets = /* @__PURE__ */ new Set();
|
|
122
|
+
visitDocxParagraphs({ documentBody: { content } }, (paragraph) => {
|
|
123
|
+
const source = getParagraphPropertySourceCandidate(paragraph);
|
|
124
|
+
if (!source) return;
|
|
125
|
+
linkedTargets.add(paragraph);
|
|
126
|
+
const targets = targetsBySource.get(source);
|
|
127
|
+
if (targets) targets.push(paragraph);
|
|
128
|
+
else targetsBySource.set(source, [paragraph]);
|
|
129
|
+
});
|
|
130
|
+
for (const [source, targets] of targetsBySource) if (targets.length === 1) {
|
|
131
|
+
const target = targets.at(0);
|
|
132
|
+
if (target) copyParagraphPropertySource(target, source);
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
targets: linkedTargets,
|
|
136
|
+
sources: new Set(targetsBySource.keys())
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
/** Convert a ProseMirror document to the document model. */
|
|
82
140
|
function fromProseDoc(pmDoc, baseDocument) {
|
|
83
141
|
assertValidProseMirrorDocument(pmDoc, "Cannot convert invalid ProseMirror document to DOCX model");
|
|
84
|
-
const
|
|
142
|
+
const blocks = extractBlocks(pmDoc);
|
|
143
|
+
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
144
|
+
if (baseDocument) restoreParagraphPropertySources(blocks, baseDocument.package.document.content, linkedSources.targets, linkedSources.sources);
|
|
145
|
+
const documentBody = { content: blocks };
|
|
85
146
|
if (baseDocument?.package.document.finalSectionProperties) documentBody.finalSectionProperties = baseDocument.package.document.finalSectionProperties;
|
|
86
147
|
if (baseDocument?.package.document.sections) documentBody.sections = baseDocument.package.document.sections;
|
|
87
148
|
if (baseDocument?.package.document.comments) documentBody.comments = baseDocument.package.document.comments;
|
|
@@ -131,6 +192,22 @@ function stripSuggestedInlineMarks(marks) {
|
|
|
131
192
|
*/
|
|
132
193
|
function stripSuggestedNodeAttrs(node) {
|
|
133
194
|
const name = node.type.name;
|
|
195
|
+
if (name === "paragraph") {
|
|
196
|
+
const propertyChanges = expectParagraphAttrs(node)._propertyChanges;
|
|
197
|
+
if (!Array.isArray(propertyChanges)) return null;
|
|
198
|
+
if (!propertyChanges.some(({ info }) => info.provenance === "suggested")) return null;
|
|
199
|
+
const removal = removeParagraphPropertyChanges(propertyChanges, ({ info }) => info.provenance === "suggested");
|
|
200
|
+
if (removal.type === "unchanged") return null;
|
|
201
|
+
const nextAttrs = {
|
|
202
|
+
...node.attrs,
|
|
203
|
+
_propertyChanges: removal.remaining.length > 0 ? removal.remaining : null
|
|
204
|
+
};
|
|
205
|
+
if (removal.type === "restore-previous") {
|
|
206
|
+
Object.assign(nextAttrs, paragraphRejectAttrPatch(removal.previousFormatting));
|
|
207
|
+
nextAttrs["_originalFormatting"] = paragraphRejectOriginalFormatting(removal.previousFormatting, nextAttrs["_originalFormatting"]);
|
|
208
|
+
}
|
|
209
|
+
return nextAttrs;
|
|
210
|
+
}
|
|
134
211
|
if (name === "tableRow") {
|
|
135
212
|
const rowAttrs = expectTableRowAttrs(node);
|
|
136
213
|
if (rowAttrs.trDel?.provenance === "suggested") return {
|
|
@@ -192,7 +269,10 @@ function mapSuggestionStrippedNode(node) {
|
|
|
192
269
|
});
|
|
193
270
|
if (!changed) return node;
|
|
194
271
|
const content = Fragment.fromArray(children);
|
|
195
|
-
return
|
|
272
|
+
return recreateProseNodeWithParagraphPropertySource(node, {
|
|
273
|
+
...nextAttrs === null ? {} : { attrs: nextAttrs },
|
|
274
|
+
content
|
|
275
|
+
});
|
|
196
276
|
}
|
|
197
277
|
/**
|
|
198
278
|
* Strip suggested (AI-proposed) tracked changes from a document so it
|
|
@@ -208,10 +288,10 @@ function materializeNumberedRefValues(doc) {
|
|
|
208
288
|
const visit = (node) => {
|
|
209
289
|
if (node.type.name === "field" || node.type.name === "structuredField") {
|
|
210
290
|
const displayText = results.get(node);
|
|
211
|
-
if (displayText !== void 0) return node
|
|
291
|
+
if (displayText !== void 0) return recreateProseNodeWithParagraphPropertySource(node, { attrs: {
|
|
212
292
|
...node.attrs,
|
|
213
293
|
displayText
|
|
214
|
-
}
|
|
294
|
+
} });
|
|
215
295
|
return node;
|
|
216
296
|
}
|
|
217
297
|
if (node.childCount === 0) return node;
|
|
@@ -222,7 +302,7 @@ function materializeNumberedRefValues(doc) {
|
|
|
222
302
|
children.push(mappedChild);
|
|
223
303
|
changed ||= mappedChild !== child;
|
|
224
304
|
});
|
|
225
|
-
return changed ? node
|
|
305
|
+
return changed ? recreateProseNodeWithParagraphPropertySource(node, { content: Fragment.fromArray(children) }) : node;
|
|
226
306
|
};
|
|
227
307
|
return visit(doc);
|
|
228
308
|
}
|
|
@@ -541,12 +621,20 @@ function convertPMParagraph(node, documentCounts, textBoxAnchorMarkers) {
|
|
|
541
621
|
else if (attrs.sectionBreakType) paragraph.sectionProperties = { sectionStart: attrs.sectionBreakType };
|
|
542
622
|
if (attrs._propertyChanges && attrs._propertyChanges.length > 0) paragraph.propertyChanges = attrs._propertyChanges.map(propertyChangeFromAttrs);
|
|
543
623
|
if (attrs.pPrMark) paragraph.pPrMark = attrs.pPrMark;
|
|
624
|
+
linkParagraphPropertySourceCandidate(paragraph, node);
|
|
544
625
|
return paragraph;
|
|
545
626
|
}
|
|
546
627
|
const propertyChangeFromAttrs = (change) => {
|
|
547
|
-
const { previousFormatting, currentFormatting,
|
|
548
|
-
|
|
549
|
-
|
|
628
|
+
const { previousFormatting, currentFormatting, info, ...changeInfo } = change;
|
|
629
|
+
const serializedInfo = { ...info };
|
|
630
|
+
Reflect.deleteProperty(serializedInfo, "provenance");
|
|
631
|
+
Reflect.deleteProperty(serializedInfo, "suggestionId");
|
|
632
|
+
const normalizedChangeInfo = {
|
|
633
|
+
...changeInfo,
|
|
634
|
+
info: serializedInfo
|
|
635
|
+
};
|
|
636
|
+
if (previousFormatting === void 0) return currentFormatting === void 0 ? normalizedChangeInfo : {
|
|
637
|
+
...normalizedChangeInfo,
|
|
550
638
|
currentFormatting
|
|
551
639
|
};
|
|
552
640
|
const { numPr, ...previousWithoutNumPr } = previousFormatting;
|
|
@@ -555,7 +643,7 @@ const propertyChangeFromAttrs = (change) => {
|
|
|
555
643
|
numPr
|
|
556
644
|
};
|
|
557
645
|
return {
|
|
558
|
-
...
|
|
646
|
+
...normalizedChangeInfo,
|
|
559
647
|
previousFormatting: normalizedPrevious,
|
|
560
648
|
...currentFormatting !== void 0 && { currentFormatting }
|
|
561
649
|
};
|
|
@@ -576,6 +664,7 @@ function assignBooleanToggle(result, attrs, orig, key) {
|
|
|
576
664
|
else result[key] = value;
|
|
577
665
|
}
|
|
578
666
|
function paragraphAttrsToFormatting(attrs) {
|
|
667
|
+
const directAlignment = directParagraphAlignment(attrs);
|
|
579
668
|
const spaceBefore = Reflect.get(attrs, "spaceBefore");
|
|
580
669
|
const spaceAfter = Reflect.get(attrs, "spaceAfter");
|
|
581
670
|
const beforeHasAutospacingBase = hasAutospacingBaseSide(attrs._autospacingBase, "before");
|
|
@@ -609,8 +698,8 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
609
698
|
if (attrs.lineSpacingRule) result.lineSpacingRule = attrs.lineSpacingRule;
|
|
610
699
|
else Reflect.deleteProperty(result, "lineSpacingRule");
|
|
611
700
|
}
|
|
612
|
-
if (
|
|
613
|
-
else
|
|
701
|
+
if (directAlignment === void 0) Reflect.deleteProperty(result, "alignment");
|
|
702
|
+
else result.alignment = directAlignment;
|
|
614
703
|
if (isStyleSourcedNumPr(attrs)) {
|
|
615
704
|
delete result.numPr;
|
|
616
705
|
delete result.numPrFromStyle;
|
|
@@ -636,9 +725,9 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
636
725
|
}
|
|
637
726
|
const outlineLevel = Reflect.get(attrs, "outlineLevel");
|
|
638
727
|
const bidi = directionToBidi(attrs.direction);
|
|
639
|
-
if (!(
|
|
728
|
+
if (!(directAlignment !== void 0 || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || hasDirectLineSpacing || attrs.snapToGrid != null || attrs.indentLeft || attrs.indentRight || attrs.indentFirstLine || attrs.numPr || attrs.styleId || attrs.borders || attrs.shading || attrs.tabs || typeof outlineLevel === "number" || attrs.contextualSpacing || attrs.spacingExplicit || bidi != null || attrs.pageBreakBefore != null || attrs.widowControl != null || attrs.kinsoku != null || attrs.overflowPunctuation != null || attrs.suppressAutoHyphens != null)) return;
|
|
640
729
|
const f = {};
|
|
641
|
-
if (
|
|
730
|
+
if (directAlignment !== void 0) f.alignment = directAlignment;
|
|
642
731
|
if (shouldSerializeSpaceBefore) f.spaceBefore = spaceBefore;
|
|
643
732
|
if (beforeAutospacingEdited) f.beforeAutospacing = false;
|
|
644
733
|
if (shouldSerializeSpaceAfter) f.spaceAfter = spaceAfter;
|
|
@@ -794,6 +883,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
794
883
|
id: changeAttrs.revisionId,
|
|
795
884
|
author: changeAttrs.author || "Unknown",
|
|
796
885
|
...changeAttrs.date ? { date: changeAttrs.date } : {},
|
|
886
|
+
...changeAttrs.utcDate ? { utcDate: {
|
|
887
|
+
attribute: DATE_UTC_ATTRIBUTE,
|
|
888
|
+
value: changeAttrs.utcDate
|
|
889
|
+
} } : {},
|
|
797
890
|
...changeAttrs.initials ? { initials: changeAttrs.initials } : {}
|
|
798
891
|
};
|
|
799
892
|
if (insertionMark) content.push({
|
|
@@ -819,6 +912,10 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
|
|
|
819
912
|
author: changeAttrs.author || "Unknown"
|
|
820
913
|
};
|
|
821
914
|
if (changeAttrs.date) info.date = changeAttrs.date;
|
|
915
|
+
if (changeAttrs.utcDate) info.utcDate = {
|
|
916
|
+
attribute: DATE_UTC_ATTRIBUTE,
|
|
917
|
+
value: changeAttrs.utcDate
|
|
918
|
+
};
|
|
822
919
|
if (changeAttrs.initials) info.initials = changeAttrs.initials;
|
|
823
920
|
let type;
|
|
824
921
|
if (insertionMark) type = changeAttrs.moveKind === "moveTo" ? "moveTo" : "insertion";
|
|
@@ -1934,6 +2031,10 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges) {
|
|
|
1934
2031
|
id: attrs.trIns.revisionId,
|
|
1935
2032
|
author: attrs.trIns.author,
|
|
1936
2033
|
...attrs.trIns.date != null && { date: attrs.trIns.date },
|
|
2034
|
+
...attrs.trIns.utcDate != null && { utcDate: {
|
|
2035
|
+
attribute: "w16du:dateUtc",
|
|
2036
|
+
value: attrs.trIns.utcDate
|
|
2037
|
+
} },
|
|
1937
2038
|
...attrs.trIns.initials != null && { initials: attrs.trIns.initials }
|
|
1938
2039
|
}
|
|
1939
2040
|
};
|
|
@@ -1943,6 +2044,10 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges) {
|
|
|
1943
2044
|
id: attrs.trDel.revisionId,
|
|
1944
2045
|
author: attrs.trDel.author,
|
|
1945
2046
|
...attrs.trDel.date != null && { date: attrs.trDel.date },
|
|
2047
|
+
...attrs.trDel.utcDate != null && { utcDate: {
|
|
2048
|
+
attribute: "w16du:dateUtc",
|
|
2049
|
+
value: attrs.trDel.utcDate
|
|
2050
|
+
} },
|
|
1946
2051
|
...attrs.trDel.initials != null && { initials: attrs.trDel.initials }
|
|
1947
2052
|
}
|
|
1948
2053
|
};
|
|
@@ -2025,6 +2130,10 @@ function convertPMTableCell(node, documentCounts) {
|
|
|
2025
2130
|
id: attrs.cellMarker.info.revisionId,
|
|
2026
2131
|
author: attrs.cellMarker.info.author,
|
|
2027
2132
|
...attrs.cellMarker.info.date != null && { date: attrs.cellMarker.info.date },
|
|
2133
|
+
...attrs.cellMarker.info.utcDate != null && { utcDate: {
|
|
2134
|
+
attribute: "w16du:dateUtc",
|
|
2135
|
+
value: attrs.cellMarker.info.utcDate
|
|
2136
|
+
} },
|
|
2028
2137
|
...attrs.cellMarker.info.initials != null && { initials: attrs.cellMarker.info.initials }
|
|
2029
2138
|
};
|
|
2030
2139
|
if (attrs.cellMarker.kind === "merge") cell.structuralChange = {
|
|
@@ -2188,8 +2297,11 @@ function updateDocumentContent(originalDocument, pmDoc) {
|
|
|
2188
2297
|
* Used for converting edited header/footer PM content back to the document
|
|
2189
2298
|
* model.
|
|
2190
2299
|
*/
|
|
2191
|
-
function proseDocToBlocks(pmDoc) {
|
|
2192
|
-
|
|
2300
|
+
function proseDocToBlocks(pmDoc, baseContent) {
|
|
2301
|
+
const blocks = extractBlocks(pmDoc);
|
|
2302
|
+
const linkedSources = restoreLinkedParagraphPropertySources(blocks);
|
|
2303
|
+
if (baseContent) restoreParagraphPropertySources(blocks, baseContent, linkedSources.targets, linkedSources.sources);
|
|
2304
|
+
return blocks;
|
|
2193
2305
|
}
|
|
2194
2306
|
//#endregion
|
|
2195
2307
|
export { fromProseDoc, marksToTextFormatting, proseDocToBlocks, standaloneTableCellFromProseMirror, tableAttrsToFormatting, tableCellAttrsToFormatting, tableRowAttrsToFormatting, updateDocumentContent };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveColorValueToHex } from "../../docx/drawingUtils.js";
|
|
2
|
+
import { linkProseParagraphPropertySource, recreateProseNodeWithParagraphPropertySource } from "../../docx/paragraphPropertySource.js";
|
|
2
3
|
import { createStyleEngine } from "../../style-engine/styleEngine.js";
|
|
3
4
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
4
5
|
import { mergeParagraphFormatting, mergeParagraphTabStops } from "../../utils/paragraphFormattingMerge.js";
|
|
@@ -119,18 +120,18 @@ function toProseDoc(document, options) {
|
|
|
119
120
|
const firstConverted = converted.at(0);
|
|
120
121
|
if (pbPos === "before" && converted.length === 1 && firstConverted?.type.name === "paragraph" && firstConverted.content.size === 0 && document.package.settings?.splitPageBreakAndParagraphMark !== true) {
|
|
121
122
|
const paragraph = firstConverted;
|
|
122
|
-
converted[0] = paragraph
|
|
123
|
+
converted[0] = recreateProseNodeWithParagraphPropertySource(paragraph, { attrs: {
|
|
123
124
|
...paragraph.attrs,
|
|
124
125
|
_pageBreakCarrier: true
|
|
125
|
-
}
|
|
126
|
+
} });
|
|
126
127
|
}
|
|
127
128
|
if (pbPos === "after") {
|
|
128
129
|
const paragraphIndex = converted.findIndex((node) => node.type.name === "paragraph");
|
|
129
130
|
const trailingParagraph = paragraphIndex >= 0 ? converted.at(paragraphIndex) : void 0;
|
|
130
|
-
if (trailingParagraph) converted[paragraphIndex] = trailingParagraph
|
|
131
|
+
if (trailingParagraph) converted[paragraphIndex] = recreateProseNodeWithParagraphPropertySource(trailingParagraph, { attrs: {
|
|
131
132
|
...trailingParagraph.attrs,
|
|
132
133
|
_trailingPageBreak: true
|
|
133
|
-
}
|
|
134
|
+
} });
|
|
134
135
|
}
|
|
135
136
|
out.push(...converted);
|
|
136
137
|
if (pbPos === "after") out.push(schema.node("pageBreak"));
|
|
@@ -323,7 +324,9 @@ function convertParagraph(paragraph, styleResolver, nextHyperlinkInstanceIndex,
|
|
|
323
324
|
}
|
|
324
325
|
if (bookmarksArr) attrs.bookmarks = bookmarksArr;
|
|
325
326
|
if (emptyHyperlinks) attrs._emptyHyperlinks = emptyHyperlinks;
|
|
326
|
-
|
|
327
|
+
const proseParagraph = schema.node("paragraph", attrs, inlineNodes);
|
|
328
|
+
linkProseParagraphPropertySource(proseParagraph, paragraph);
|
|
329
|
+
return proseParagraph;
|
|
327
330
|
}
|
|
328
331
|
const resolveParagraphStyleFontFamily = (styleId, styleResolver) => {
|
|
329
332
|
let style = styleId ? styleResolver.getStyle(styleId) : styleResolver.getDefaultParagraphStyle();
|
|
@@ -402,6 +405,7 @@ function convertTrackedChange(change, markType, nextHyperlinkInstanceIndex, getI
|
|
|
402
405
|
revisionId: change.info.id,
|
|
403
406
|
author: change.info.author,
|
|
404
407
|
date: change.info.date ?? null,
|
|
408
|
+
utcDate: change.info.utcDate?.value ?? null,
|
|
405
409
|
initials: change.info.initials ?? null,
|
|
406
410
|
moveKind
|
|
407
411
|
});
|
|
@@ -466,6 +470,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
466
470
|
if (styleResolver) {
|
|
467
471
|
stylePpr = styleResolver.resolveParagraphStyleInTable(styleId, tableParagraphOverlay).paragraphFormatting;
|
|
468
472
|
set("alignment", formatting?.alignment ?? stylePpr?.alignment);
|
|
473
|
+
set("alignmentFromStyle", stylePpr?.alignment);
|
|
469
474
|
set("spaceBefore", formatting?.spaceBefore ?? stylePpr?.spaceBefore);
|
|
470
475
|
set("spaceAfter", formatting?.spaceAfter ?? stylePpr?.spaceAfter);
|
|
471
476
|
set("lineSpacing", formatting?.lineSpacing ?? stylePpr?.lineSpacing);
|
|
@@ -936,7 +941,9 @@ function convertTableRow(row, styleResolver, context, isHeaderRow, columnWidths,
|
|
|
936
941
|
trIns: {
|
|
937
942
|
revisionId: row.structuralChange.info.id,
|
|
938
943
|
author: row.structuralChange.info.author,
|
|
939
|
-
date: row.structuralChange.info.date ?? null
|
|
944
|
+
date: row.structuralChange.info.date ?? null,
|
|
945
|
+
...row.structuralChange.info.utcDate ? { utcDate: row.structuralChange.info.utcDate.value } : {},
|
|
946
|
+
...row.structuralChange.info.initials ? { initials: row.structuralChange.info.initials } : {}
|
|
940
947
|
}
|
|
941
948
|
};
|
|
942
949
|
else if (row.structuralChange?.type === "tableRowDeletion") attrs = {
|
|
@@ -944,7 +951,9 @@ function convertTableRow(row, styleResolver, context, isHeaderRow, columnWidths,
|
|
|
944
951
|
trDel: {
|
|
945
952
|
revisionId: row.structuralChange.info.id,
|
|
946
953
|
author: row.structuralChange.info.author,
|
|
947
|
-
date: row.structuralChange.info.date ?? null
|
|
954
|
+
date: row.structuralChange.info.date ?? null,
|
|
955
|
+
...row.structuralChange.info.utcDate ? { utcDate: row.structuralChange.info.utcDate.value } : {},
|
|
956
|
+
...row.structuralChange.info.initials ? { initials: row.structuralChange.info.initials } : {}
|
|
948
957
|
}
|
|
949
958
|
};
|
|
950
959
|
const numCells = row.cells.length;
|
|
@@ -1084,7 +1093,9 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
|
|
|
1084
1093
|
info: {
|
|
1085
1094
|
revisionId: cell.structuralChange.info.id,
|
|
1086
1095
|
author: cell.structuralChange.info.author,
|
|
1087
|
-
date: cell.structuralChange.info.date ?? null
|
|
1096
|
+
date: cell.structuralChange.info.date ?? null,
|
|
1097
|
+
...cell.structuralChange.info.utcDate ? { utcDate: cell.structuralChange.info.utcDate.value } : {},
|
|
1098
|
+
...cell.structuralChange.info.initials ? { initials: cell.structuralChange.info.initials } : {}
|
|
1088
1099
|
}
|
|
1089
1100
|
};
|
|
1090
1101
|
else if (cell.structuralChange?.type === "tableCellDeletion") attrs.cellMarker = {
|
|
@@ -1092,7 +1103,9 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
|
|
|
1092
1103
|
info: {
|
|
1093
1104
|
revisionId: cell.structuralChange.info.id,
|
|
1094
1105
|
author: cell.structuralChange.info.author,
|
|
1095
|
-
date: cell.structuralChange.info.date ?? null
|
|
1106
|
+
date: cell.structuralChange.info.date ?? null,
|
|
1107
|
+
...cell.structuralChange.info.utcDate ? { utcDate: cell.structuralChange.info.utcDate.value } : {},
|
|
1108
|
+
...cell.structuralChange.info.initials ? { initials: cell.structuralChange.info.initials } : {}
|
|
1096
1109
|
}
|
|
1097
1110
|
};
|
|
1098
1111
|
else if (cell.structuralChange?.type === "tableCellMerge") attrs.cellMarker = {
|
|
@@ -1100,7 +1113,9 @@ function convertTableCell({ cell, styleResolver, context, isHeader, gridWidthPer
|
|
|
1100
1113
|
info: {
|
|
1101
1114
|
revisionId: cell.structuralChange.info.id,
|
|
1102
1115
|
author: cell.structuralChange.info.author,
|
|
1103
|
-
date: cell.structuralChange.info.date ?? null
|
|
1116
|
+
date: cell.structuralChange.info.date ?? null,
|
|
1117
|
+
...cell.structuralChange.info.utcDate ? { utcDate: cell.structuralChange.info.utcDate.value } : {},
|
|
1118
|
+
...cell.structuralChange.info.initials ? { initials: cell.structuralChange.info.initials } : {}
|
|
1104
1119
|
},
|
|
1105
1120
|
...cell.structuralChange.verticalMerge !== void 0 ? { verticalMerge: cell.structuralChange.verticalMerge } : {},
|
|
1106
1121
|
...cell.structuralChange.verticalMergeOriginal !== void 0 ? { verticalMergeOriginal: cell.structuralChange.verticalMergeOriginal } : {}
|
|
@@ -1965,10 +1980,10 @@ function headerFooterToProseDoc(content, options) {
|
|
|
1965
1980
|
if (isDetachedWatermarkHost) {
|
|
1966
1981
|
const paragraphNodeIndex = paragraphNodes.findIndex(({ type }) => type.name === "paragraph");
|
|
1967
1982
|
const paragraphNode = paragraphNodes[paragraphNodeIndex];
|
|
1968
|
-
if (paragraphNode) paragraphNodes[paragraphNodeIndex] = paragraphNode
|
|
1983
|
+
if (paragraphNode) paragraphNodes[paragraphNodeIndex] = recreateProseNodeWithParagraphPropertySource(paragraphNode, { attrs: {
|
|
1969
1984
|
...paragraphNode.attrs,
|
|
1970
1985
|
_detachedWatermarkHost: true
|
|
1971
|
-
}
|
|
1986
|
+
} });
|
|
1972
1987
|
}
|
|
1973
1988
|
out.push(...paragraphNodes);
|
|
1974
1989
|
} else if (block.type === "table") out.push(convertTable(block, styleResolver, conversionContext));
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { PARAGRAPH_ALIGNMENT_VALUES } from "../../../types/documentEnumValues.js";
|
|
1
2
|
import { paragraphToStyle } from "../../../utils/formatToStyle.js";
|
|
2
3
|
import { collectHeadings } from "../../../utils/headingCollector.js";
|
|
3
4
|
import { tableOfContentsStyleLevel } from "../../../utils/tableOfContentsStyle.js";
|
|
4
5
|
import { expectParagraphAttrs } from "../../attrs/index.js";
|
|
5
6
|
import { autospacingMatchesBase } from "../../autospacingBase.js";
|
|
7
|
+
import { directParagraphAlignment } from "../../paragraphAlignment.js";
|
|
6
8
|
import { directionIsRtl } from "../../paragraphDirection.js";
|
|
7
9
|
import { listAttrsFromResolvedStyle, paragraphAttrsFromResolvedStyle } from "../../styles/resolvedStyleAttrs.js";
|
|
8
10
|
import { createNodeExtension } from "../create.js";
|
|
@@ -95,6 +97,7 @@ function cssTextAlignToAlignment(value) {
|
|
|
95
97
|
default: return;
|
|
96
98
|
}
|
|
97
99
|
}
|
|
100
|
+
const parseParagraphAlignment = (value) => PARAGRAPH_ALIGNMENT_VALUES.find((alignment) => alignment === value);
|
|
98
101
|
/**
|
|
99
102
|
* Parse CSS line-height to twips.
|
|
100
103
|
* - Unitless multiplier (e.g. "1.5"): 240 twips * multiplier (single=240)
|
|
@@ -182,6 +185,7 @@ const paragraphNodeSpec = {
|
|
|
182
185
|
paraId: { default: null },
|
|
183
186
|
textId: { default: null },
|
|
184
187
|
alignment: { default: null },
|
|
188
|
+
alignmentFromStyle: { default: void 0 },
|
|
185
189
|
kinsoku: { default: null },
|
|
186
190
|
overflowPunctuation: { default: null },
|
|
187
191
|
suppressAutoHyphens: { default: null },
|
|
@@ -249,23 +253,32 @@ const paragraphNodeSpec = {
|
|
|
249
253
|
if (!(dom instanceof HTMLElement)) return false;
|
|
250
254
|
const element = dom;
|
|
251
255
|
const paraId = element.dataset["paraId"];
|
|
252
|
-
const alignment = element.dataset["alignment"];
|
|
256
|
+
const alignment = parseParagraphAlignment(element.dataset["alignment"]);
|
|
257
|
+
const authoredAlignment = parseParagraphAlignment(element.dataset["directAlignment"]);
|
|
258
|
+
const alignmentFromStyle = parseParagraphAlignment(element.dataset["alignmentFromStyle"]);
|
|
253
259
|
const styleId = element.dataset["styleId"];
|
|
254
260
|
const tableOfContentsLevel = Number(element.dataset["tableOfContentsLevel"]);
|
|
255
261
|
const sectionBreakType = element.dataset["sectionBreak"];
|
|
256
262
|
const attrs = {
|
|
257
263
|
...paraId ? { paraId } : {},
|
|
258
264
|
...alignment ? { alignment } : {},
|
|
265
|
+
...alignmentFromStyle ? { alignmentFromStyle } : {},
|
|
259
266
|
...styleId ? { styleId } : {},
|
|
260
267
|
...Number.isSafeInteger(tableOfContentsLevel) && tableOfContentsLevel > 0 ? { _tableOfContentsLevel: tableOfContentsLevel } : {},
|
|
261
268
|
...sectionBreakType ? { sectionBreakType } : {}
|
|
262
269
|
};
|
|
263
270
|
const styleAttrs = extractParagraphAttrsFromStyle(element);
|
|
264
271
|
const mergedAlignment = attrs.alignment || styleAttrs.alignment;
|
|
272
|
+
const mergedDirectAlignment = authoredAlignment ?? (attrs.alignmentFromStyle === void 0 ? mergedAlignment : void 0);
|
|
273
|
+
const originalFormatting = {
|
|
274
|
+
...styleId ? { styleId } : {},
|
|
275
|
+
...mergedDirectAlignment ? { alignment: mergedDirectAlignment } : {}
|
|
276
|
+
};
|
|
265
277
|
return {
|
|
266
278
|
...styleAttrs,
|
|
267
279
|
...attrs,
|
|
268
|
-
...mergedAlignment !== void 0 ? { alignment: mergedAlignment } : {}
|
|
280
|
+
...mergedAlignment !== void 0 ? { alignment: mergedAlignment } : {},
|
|
281
|
+
...Object.keys(originalFormatting).length > 0 ? { _originalFormatting: originalFormatting } : {}
|
|
269
282
|
};
|
|
270
283
|
}
|
|
271
284
|
}, ...[
|
|
@@ -279,8 +292,10 @@ const paragraphNodeSpec = {
|
|
|
279
292
|
tag,
|
|
280
293
|
getAttrs(dom) {
|
|
281
294
|
const level = Number.parseInt(tag.charAt(1), 10);
|
|
295
|
+
const styleAttrs = extractParagraphAttrsFromStyle(dom);
|
|
282
296
|
return {
|
|
283
|
-
...
|
|
297
|
+
...styleAttrs,
|
|
298
|
+
...styleAttrs.alignment ? { _originalFormatting: { alignment: styleAttrs.alignment } } : {},
|
|
284
299
|
styleId: `Heading${level}`,
|
|
285
300
|
outlineLevel: level - 1
|
|
286
301
|
};
|
|
@@ -295,6 +310,9 @@ const paragraphNodeSpec = {
|
|
|
295
310
|
if (listClass) domAttrs["class"] = listClass;
|
|
296
311
|
if (attrs.paraId) domAttrs["data-para-id"] = attrs.paraId;
|
|
297
312
|
if (attrs.alignment) domAttrs["data-alignment"] = attrs.alignment;
|
|
313
|
+
const directAlignment = directParagraphAlignment(attrs);
|
|
314
|
+
if (directAlignment) domAttrs["data-direct-alignment"] = directAlignment;
|
|
315
|
+
if (attrs.alignmentFromStyle) domAttrs["data-alignment-from-style"] = attrs.alignmentFromStyle;
|
|
298
316
|
if (attrs.styleId) domAttrs["data-style-id"] = attrs.styleId;
|
|
299
317
|
if (typeof attrs._tableOfContentsLevel === "number") domAttrs["data-table-of-contents-level"] = String(attrs._tableOfContentsLevel);
|
|
300
318
|
if (attrs.listMarker) domAttrs["data-list-marker"] = attrs.listMarker;
|
|
@@ -373,7 +391,27 @@ function setParagraphAttrsCmd(attrs) {
|
|
|
373
391
|
};
|
|
374
392
|
}
|
|
375
393
|
function makeSetAlignment(alignment) {
|
|
376
|
-
return (state, dispatch) =>
|
|
394
|
+
return (state, dispatch) => {
|
|
395
|
+
const { $from, $to } = state.selection;
|
|
396
|
+
if (!dispatch) return true;
|
|
397
|
+
let tr = state.tr;
|
|
398
|
+
const seen = /* @__PURE__ */ new Set();
|
|
399
|
+
state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
|
|
400
|
+
if (node.type.name !== "paragraph" || seen.has(pos)) return;
|
|
401
|
+
seen.add(pos);
|
|
402
|
+
const attrs = expectParagraphAttrs(node);
|
|
403
|
+
tr = tr.setNodeMarkup(pos, void 0, {
|
|
404
|
+
...node.attrs,
|
|
405
|
+
alignment,
|
|
406
|
+
_originalFormatting: {
|
|
407
|
+
...attrs._originalFormatting,
|
|
408
|
+
alignment
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
dispatch(tr.scrollIntoView());
|
|
413
|
+
return true;
|
|
414
|
+
};
|
|
377
415
|
}
|
|
378
416
|
function makeSetLineSpacing(value, rule = "auto") {
|
|
379
417
|
return (state, dispatch) => setParagraphAttrsCmd({
|
|
@@ -474,6 +512,12 @@ function makeApplyStyle(schema) {
|
|
|
474
512
|
styleId,
|
|
475
513
|
...resolvedAttrs.styleName ? { styleName: resolvedAttrs.styleName } : {}
|
|
476
514
|
}));
|
|
515
|
+
const originalFormatting = expectParagraphAttrs(node)._originalFormatting;
|
|
516
|
+
if (originalFormatting?.alignment !== void 0) {
|
|
517
|
+
const formattingWithoutDirectAlignment = { ...originalFormatting };
|
|
518
|
+
Reflect.deleteProperty(formattingWithoutDirectAlignment, "alignment");
|
|
519
|
+
newAttrs["_originalFormatting"] = Object.keys(formattingWithoutDirectAlignment).length > 0 ? formattingWithoutDirectAlignment : null;
|
|
520
|
+
}
|
|
477
521
|
const listAttrs = listAttrsFromResolvedStyle(resolvedAttrs, resolvedAttrs.numbering);
|
|
478
522
|
if (listAttrs) Object.assign(newAttrs, listAttrs);
|
|
479
523
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { setProseParagraphMarkupWithPropertySource } from "../../../docx/paragraphPropertySource.js";
|
|
1
2
|
import { getTransactionDirtyRange } from "../../../paged-layout/transactionDirtyRange.js";
|
|
2
3
|
import { detectBaseDirection } from "../../../utils/baseDirection.js";
|
|
3
4
|
import { directionIsAutoManaged } from "../../paragraphDirection.js";
|
|
@@ -62,7 +63,12 @@ const collectBidiUpdatesInRange = (doc, range) => {
|
|
|
62
63
|
};
|
|
63
64
|
const applyBidiUpdates = (state, updates) => {
|
|
64
65
|
const tr = state.tr;
|
|
65
|
-
for (const update of updates)
|
|
66
|
+
for (const update of updates) setProseParagraphMarkupWithPropertySource({
|
|
67
|
+
attrs: update.attrs,
|
|
68
|
+
ownership: "preserve",
|
|
69
|
+
pos: update.pos,
|
|
70
|
+
transaction: tr
|
|
71
|
+
});
|
|
66
72
|
ignoreTrackedChanges(tr);
|
|
67
73
|
tr.setMeta(autoBidiDetectionKey, "applied");
|
|
68
74
|
tr.setMeta("addToHistory", false);
|