@stll/folio-core 0.3.1 → 0.5.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.d.ts +3 -9
- package/dist/ai-edits/apply.js +94 -14
- package/dist/ai-edits/blockRange.d.ts +33 -0
- package/dist/ai-edits/blockRange.js +58 -0
- package/dist/ai-edits/headless.d.ts +35 -5
- package/dist/ai-edits/headless.js +92 -22
- package/dist/ai-edits/index.d.ts +5 -3
- package/dist/ai-edits/index.js +3 -2
- package/dist/ai-edits/snapshot.d.ts +14 -2
- package/dist/ai-edits/snapshot.js +12 -1
- package/dist/ai-edits/types.d.ts +42 -3
- package/dist/compat/eigenpal.d.ts +3 -2
- package/dist/compat/eigenpal.js +6 -5
- package/dist/controller/layoutPipeline.d.ts +1 -0
- package/dist/controller/layoutPipeline.js +35 -115
- package/dist/controller/layoutScheduler.d.ts +2 -1
- package/dist/controller/layoutScheduler.js +6 -0
- package/dist/document-operations.d.ts +122 -0
- package/dist/document-operations.js +575 -0
- package/dist/docx/blockContentParser.js +17 -7
- package/dist/docx/encryption/agileDecryption.d.ts +6 -0
- package/dist/docx/encryption/agileDecryption.js +209 -0
- package/dist/docx/encryption/compoundFile.d.ts +20 -0
- package/dist/docx/encryption/compoundFile.js +251 -0
- package/dist/docx/encryption/containerFormat.d.ts +15 -0
- package/dist/docx/encryption/containerFormat.js +40 -0
- package/dist/docx/encryption/cryptoBytes.d.ts +11 -0
- package/dist/docx/encryption/cryptoBytes.js +55 -0
- package/dist/docx/encryption/encryptionInfo.d.ts +32 -0
- package/dist/docx/encryption/encryptionInfo.js +128 -0
- package/dist/docx/encryption/errors.d.ts +18 -0
- package/dist/docx/encryption/errors.js +13 -0
- package/dist/docx/encryption/index.d.ts +4 -0
- package/dist/docx/encryption/index.js +4 -0
- package/dist/docx/encryption/openEncryptedDocx.d.ts +28 -0
- package/dist/docx/encryption/openEncryptedDocx.js +65 -0
- package/dist/docx/footnoteParser.d.ts +1 -17
- package/dist/docx/footnoteParser.js +1 -27
- package/dist/docx/groupDrawingParser.d.ts +8 -0
- package/dist/docx/groupDrawingParser.js +131 -0
- package/dist/docx/index.d.ts +3 -1
- package/dist/docx/index.js +3 -1
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +8 -2
- package/dist/docx/paragraphParser.js +9 -3
- package/dist/docx/parser.d.ts +4 -5
- package/dist/docx/parser.js +8 -2
- package/dist/docx/runParser.js +8 -1
- package/dist/docx/selectiveXmlPatch.js +4 -10
- package/dist/docx/serializer/numberingSerializer.js +3 -1
- package/dist/docx/settingsParser.d.ts +6 -3
- package/dist/docx/settingsParser.js +2 -0
- package/dist/docx/unzip.d.ts +7 -5
- package/dist/docx/unzip.js +8 -2
- package/dist/docx/xmlParser.js +11 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.js +6 -5
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +37 -1
- package/dist/layout-bridge/convert/footnoteLayout.js +138 -14
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +6 -8
- package/dist/layout-bridge/convert/headerFooterLayout.js +21 -13
- package/dist/layout-bridge/convert/toFlowBlocks.js +58 -19
- package/dist/layout-engine/index.d.ts +6 -5
- package/dist/layout-engine/index.js +116 -27
- package/dist/layout-engine/keep-together.d.ts +13 -8
- package/dist/layout-engine/keep-together.js +40 -25
- package/dist/layout-engine/layoutInstrumentation.d.ts +11 -1
- package/dist/layout-engine/layoutInstrumentation.js +10 -1
- package/dist/layout-engine/measure/measureBlocks.js +43 -19
- package/dist/layout-engine/measure/measureParagraph.js +91 -14
- package/dist/layout-engine/paginator.d.ts +2 -1
- package/dist/layout-engine/paginator.js +9 -3
- package/dist/layout-engine/textBoxGroup.d.ts +7 -0
- package/dist/layout-engine/textBoxGroup.js +8 -0
- package/dist/layout-engine/types.d.ts +33 -9
- package/dist/layout-engine/types.js +20 -2
- package/dist/layout-painter/renderPage.d.ts +15 -1
- package/dist/layout-painter/renderPage.js +29 -12
- package/dist/layout-painter/renderParagraph.js +44 -9
- package/dist/layout-painter/renderTable.js +27 -7
- package/dist/managers/DocumentLoaderManager.d.ts +3 -1
- package/dist/managers/DocumentLoaderManager.js +13 -5
- package/dist/managers/TableSelectionManager.js +1 -1
- package/dist/model.js +1 -1
- package/dist/paged-layout/pageText.d.ts +14 -0
- package/dist/paged-layout/pageText.js +21 -0
- package/dist/prosemirror/attrs/index.js +3 -0
- package/dist/prosemirror/commands/comments.js +75 -5
- package/dist/prosemirror/commands/hyperlink.js +4 -2
- package/dist/prosemirror/commands/image.js +2 -1
- package/dist/prosemirror/commands/index.js +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +68 -0
- package/dist/prosemirror/commands/propertyChangeScope.js +242 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +21 -5
- package/dist/prosemirror/conversion/toProseDoc.js +43 -15
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +3 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +12 -11
- package/dist/prosemirror/findReplaceSelection.js +2 -1
- package/dist/prosemirror/index.js +1 -1
- package/dist/prosemirror/insertOperations.js +1 -1
- package/dist/prosemirror/schema/nodes.d.ts +14 -7
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/utils/tabCalculator.js +4 -2
- package/dist/redline.d.ts +20 -0
- package/dist/redline.js +127 -0
- package/dist/server.d.ts +7 -3
- package/dist/server.js +6 -2
- package/dist/symbols.d.ts +35 -0
- package/dist/symbols.js +512 -0
- package/dist/utils/clipboard.js +3 -3
- package/dist/utils/fontLoader.js +3 -0
- package/dist/utils/fontResolver.js +65 -1
- package/dist/utils/zoom.d.ts +21 -0
- package/dist/utils/zoom.js +21 -0
- package/dist/version-comparison.d.ts +92 -0
- package/dist/version-comparison.js +436 -0
- package/package.json +7 -3
- package/dist/paged-layout/headerFooterMargins.d.ts +0 -73
- package/dist/paged-layout/headerFooterMargins.js +0 -120
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { document_d_exports } from "../../types/document.js";
|
|
2
|
+
|
|
3
|
+
//#region src/prosemirror/commands/propertyChangeScope.d.ts
|
|
4
|
+
type AttrPatch = Record<string, unknown>;
|
|
5
|
+
/**
|
|
6
|
+
* Paragraph attrs governed by a `w:pPrChange` — the attrs
|
|
7
|
+
* `paragraphFormattingToAttrs` (conversion/toProseDoc.ts) can produce from a
|
|
8
|
+
* parsed `CT_PPrBase` (ECMA-376 §17.13.5.29). Rejecting a pPrChange restores
|
|
9
|
+
* the stored old pPr wholesale for exactly these keys: a key absent from the
|
|
10
|
+
* stored record resets to the schema default (`null`).
|
|
11
|
+
*
|
|
12
|
+
* Deliberately OUT of scope (preserved across a reject):
|
|
13
|
+
* - identity/structure: `paraId`, `textId`, `sectionBreakType`,
|
|
14
|
+
* `_sectionProperties`, `_propertyChanges`, `pPrMark`, `bookmarks`,
|
|
15
|
+
* `_emptyHyperlinks`, `renderedPageBreakBefore`
|
|
16
|
+
* - paragraph-mark run properties — `pPr/rPr` is CT_PPr-only, not part of the
|
|
17
|
+
* CT_PPrBase payload a pPrChange stores: `defaultTextFormatting`,
|
|
18
|
+
* `runInWithNext` (`w:specVanish` lives in that rPr)
|
|
19
|
+
* - load-time style/numbering bookkeeping the command layer cannot recompute
|
|
20
|
+
* without a style resolver: `numPrFromStyle`, the `list*` rendering attrs,
|
|
21
|
+
* `spacingFromDocDefaults`
|
|
22
|
+
*/
|
|
23
|
+
declare const PPR_CHANGE_SCOPED_ATTR_KEYS: readonly ["styleId", "numPr", "alignment", "spaceBefore", "spaceAfter", "lineSpacing", "lineSpacingRule", "spacingExplicit", "indentLeft", "indentRight", "indentFirstLine", "hangingIndent", "borders", "shading", "tabs", "pageBreakBefore", "keepNext", "keepLines", "widowControl", "contextualSpacing", "outlineLevel", "direction", "_autospacingBase"];
|
|
24
|
+
/**
|
|
25
|
+
* Build the attr patch that rejecting one pPrChange applies to a paragraph:
|
|
26
|
+
* every in-scope key set to the stored previous value, or reset to `null`
|
|
27
|
+
* when the stored old pPr does not carry it. Keys the record captured beyond
|
|
28
|
+
* the scoped set (editor-created list suggestions snapshot list-rendering
|
|
29
|
+
* bookkeeping attrs) merge through 1:1 so their pre-change values restore too.
|
|
30
|
+
*/
|
|
31
|
+
declare function paragraphRejectAttrPatch(previousFormatting: Record<string, unknown> | null | undefined): AttrPatch;
|
|
32
|
+
/**
|
|
33
|
+
* Rebuild the paragraph's `_originalFormatting` (the serializer's pPr source)
|
|
34
|
+
* after a reject: the stored old pPr wholesale within CT_PPrBase scope, with
|
|
35
|
+
* the paragraph-mark rPr fields (`runProperties`, `runInWithNext`) preserved
|
|
36
|
+
* from the live original — a pPrChange cannot store them, so a reject must
|
|
37
|
+
* not drop them.
|
|
38
|
+
*/
|
|
39
|
+
declare function paragraphRejectOriginalFormatting(previousFormatting: Record<string, unknown> | null | undefined, liveOriginal: unknown): document_d_exports.ParagraphFormatting | null;
|
|
40
|
+
/**
|
|
41
|
+
* Rejected section properties: the stored old sectPr wholesale, preserving
|
|
42
|
+
* the live header/footer references — `EG_HdrFtrReferences` is not part of
|
|
43
|
+
* the `CT_SectPrBase` payload a `w:sectPrChange` stores (ECMA-376
|
|
44
|
+
* §17.13.5.32), so those children survive a reject. The caller re-attaches
|
|
45
|
+
* whatever `propertyChanges` remain unresolved.
|
|
46
|
+
*/
|
|
47
|
+
declare function sectionRejectProperties(live: document_d_exports.SectionProperties, previousProperties: document_d_exports.SectionProperties | undefined): document_d_exports.SectionProperties;
|
|
48
|
+
/**
|
|
49
|
+
* Attr patch for rejecting a `w:tblPrChange`: the stored old tblPr wholesale
|
|
50
|
+
* (`w:tblPrChange` stores the complete previous tblPr, so every tblPr-derived
|
|
51
|
+
* attr resets when absent). `columnWidths` comes from `w:tblGrid`, not tblPr,
|
|
52
|
+
* and is untouched.
|
|
53
|
+
*/
|
|
54
|
+
declare function tableRejectAttrPatch(previousFormatting: document_d_exports.TableFormatting | undefined): AttrPatch;
|
|
55
|
+
/** Attr patch for rejecting a `w:trPrChange`: the stored old trPr wholesale. */
|
|
56
|
+
declare function tableRowRejectAttrPatch(previousFormatting: document_d_exports.TableRowFormatting | undefined): AttrPatch;
|
|
57
|
+
/**
|
|
58
|
+
* Attr patch for rejecting a `w:tcPrChange`: the stored old tcPr wholesale
|
|
59
|
+
* for the non-structural attrs. `gridSpan` / `vMerge` are structural in
|
|
60
|
+
* ProseMirror (`colspan` / `rowspan` shape the table grid); restoring them
|
|
61
|
+
* from the record would desync the grid without a full table restructure, so
|
|
62
|
+
* the live structure is kept and the rebuilt `_originalFormatting` inherits
|
|
63
|
+
* the live original's `gridSpan` / `vMerge` to stay consistent with it.
|
|
64
|
+
* (Word would also restore tracked merges; folio deliberately does not.)
|
|
65
|
+
*/
|
|
66
|
+
declare function tableCellRejectAttrPatch(previousFormatting: document_d_exports.TableCellFormatting | undefined, liveOriginalFormatting: document_d_exports.TableCellFormatting | null | undefined): AttrPatch;
|
|
67
|
+
//#endregion
|
|
68
|
+
export { PPR_CHANGE_SCOPED_ATTR_KEYS, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch };
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { directionFromBidi } from "../paragraphDirection.js";
|
|
2
|
+
import { setAutospacingBaseValue } from "../autospacingBase.js";
|
|
3
|
+
//#region src/prosemirror/commands/propertyChangeScope.ts
|
|
4
|
+
/**
|
|
5
|
+
* Paragraph attrs governed by a `w:pPrChange` — the attrs
|
|
6
|
+
* `paragraphFormattingToAttrs` (conversion/toProseDoc.ts) can produce from a
|
|
7
|
+
* parsed `CT_PPrBase` (ECMA-376 §17.13.5.29). Rejecting a pPrChange restores
|
|
8
|
+
* the stored old pPr wholesale for exactly these keys: a key absent from the
|
|
9
|
+
* stored record resets to the schema default (`null`).
|
|
10
|
+
*
|
|
11
|
+
* Deliberately OUT of scope (preserved across a reject):
|
|
12
|
+
* - identity/structure: `paraId`, `textId`, `sectionBreakType`,
|
|
13
|
+
* `_sectionProperties`, `_propertyChanges`, `pPrMark`, `bookmarks`,
|
|
14
|
+
* `_emptyHyperlinks`, `renderedPageBreakBefore`
|
|
15
|
+
* - paragraph-mark run properties — `pPr/rPr` is CT_PPr-only, not part of the
|
|
16
|
+
* CT_PPrBase payload a pPrChange stores: `defaultTextFormatting`,
|
|
17
|
+
* `runInWithNext` (`w:specVanish` lives in that rPr)
|
|
18
|
+
* - load-time style/numbering bookkeeping the command layer cannot recompute
|
|
19
|
+
* without a style resolver: `numPrFromStyle`, the `list*` rendering attrs,
|
|
20
|
+
* `spacingFromDocDefaults`
|
|
21
|
+
*/
|
|
22
|
+
const PPR_CHANGE_SCOPED_ATTR_KEYS = [
|
|
23
|
+
"styleId",
|
|
24
|
+
"numPr",
|
|
25
|
+
"alignment",
|
|
26
|
+
"spaceBefore",
|
|
27
|
+
"spaceAfter",
|
|
28
|
+
"lineSpacing",
|
|
29
|
+
"lineSpacingRule",
|
|
30
|
+
"spacingExplicit",
|
|
31
|
+
"indentLeft",
|
|
32
|
+
"indentRight",
|
|
33
|
+
"indentFirstLine",
|
|
34
|
+
"hangingIndent",
|
|
35
|
+
"borders",
|
|
36
|
+
"shading",
|
|
37
|
+
"tabs",
|
|
38
|
+
"pageBreakBefore",
|
|
39
|
+
"keepNext",
|
|
40
|
+
"keepLines",
|
|
41
|
+
"widowControl",
|
|
42
|
+
"contextualSpacing",
|
|
43
|
+
"outlineLevel",
|
|
44
|
+
"direction",
|
|
45
|
+
"_autospacingBase"
|
|
46
|
+
];
|
|
47
|
+
const PPR_CHANGE_SCOPED_ATTR_KEY_SET = new Set(PPR_CHANGE_SCOPED_ATTR_KEYS);
|
|
48
|
+
/**
|
|
49
|
+
* Parser-shaped `ParagraphFormatting` keys that must NOT merge through to
|
|
50
|
+
* attrs verbatim: they either normalize to a differently named attr
|
|
51
|
+
* (`bidi` → `direction`, autospacing flags → `_autospacingBase`), have no
|
|
52
|
+
* attr representation and round-trip via `_originalFormatting` only
|
|
53
|
+
* (`frame`, `suppressLineNumbers`, `suppressAutoHyphens`), or sit outside
|
|
54
|
+
* the CT_PPrBase scope entirely (`runProperties`, `runInWithNext` — the
|
|
55
|
+
* paragraph-mark rPr) and so must never overwrite the live value on reject.
|
|
56
|
+
*/
|
|
57
|
+
const PPR_PARSER_ONLY_KEYS = /* @__PURE__ */ new Set([
|
|
58
|
+
"bidi",
|
|
59
|
+
"beforeAutospacing",
|
|
60
|
+
"afterAutospacing",
|
|
61
|
+
"runProperties",
|
|
62
|
+
"runInWithNext",
|
|
63
|
+
"frame",
|
|
64
|
+
"suppressLineNumbers",
|
|
65
|
+
"suppressAutoHyphens",
|
|
66
|
+
"numPrFromStyle"
|
|
67
|
+
]);
|
|
68
|
+
/**
|
|
69
|
+
* `ParagraphFormatting` keys inside the CT_PPrBase scope, used to rebuild
|
|
70
|
+
* `_originalFormatting` after a reject (old pPr wholesale within scope,
|
|
71
|
+
* paragraph-mark rPr fields preserved from the live original).
|
|
72
|
+
*/
|
|
73
|
+
const PPR_CHANGE_SCOPED_FORMATTING_KEYS = [
|
|
74
|
+
"styleId",
|
|
75
|
+
"numPr",
|
|
76
|
+
"alignment",
|
|
77
|
+
"bidi",
|
|
78
|
+
"spaceBefore",
|
|
79
|
+
"spaceAfter",
|
|
80
|
+
"lineSpacing",
|
|
81
|
+
"lineSpacingRule",
|
|
82
|
+
"beforeAutospacing",
|
|
83
|
+
"afterAutospacing",
|
|
84
|
+
"spacingExplicit",
|
|
85
|
+
"indentLeft",
|
|
86
|
+
"indentRight",
|
|
87
|
+
"indentFirstLine",
|
|
88
|
+
"hangingIndent",
|
|
89
|
+
"borders",
|
|
90
|
+
"shading",
|
|
91
|
+
"tabs",
|
|
92
|
+
"pageBreakBefore",
|
|
93
|
+
"keepNext",
|
|
94
|
+
"keepLines",
|
|
95
|
+
"widowControl",
|
|
96
|
+
"contextualSpacing",
|
|
97
|
+
"outlineLevel",
|
|
98
|
+
"frame",
|
|
99
|
+
"suppressLineNumbers",
|
|
100
|
+
"suppressAutoHyphens"
|
|
101
|
+
];
|
|
102
|
+
/**
|
|
103
|
+
* Build the attr patch that rejecting one pPrChange applies to a paragraph:
|
|
104
|
+
* every in-scope key set to the stored previous value, or reset to `null`
|
|
105
|
+
* when the stored old pPr does not carry it. Keys the record captured beyond
|
|
106
|
+
* the scoped set (editor-created list suggestions snapshot list-rendering
|
|
107
|
+
* bookkeeping attrs) merge through 1:1 so their pre-change values restore too.
|
|
108
|
+
*/
|
|
109
|
+
function paragraphRejectAttrPatch(previousFormatting) {
|
|
110
|
+
const prev = previousFormatting ?? {};
|
|
111
|
+
const patch = {};
|
|
112
|
+
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS) patch[key] = Object.hasOwn(prev, key) ? prev[key] ?? null : null;
|
|
113
|
+
if (!Object.hasOwn(prev, "direction")) patch["direction"] = directionFromBidi(prev["bidi"]);
|
|
114
|
+
if (!Object.hasOwn(prev, "_autospacingBase")) patch["_autospacingBase"] = autospacingBaseFromFormatting(prev);
|
|
115
|
+
for (const [key, value] of Object.entries(prev)) {
|
|
116
|
+
if (PPR_CHANGE_SCOPED_ATTR_KEY_SET.has(key) || PPR_PARSER_ONLY_KEYS.has(key)) continue;
|
|
117
|
+
patch[key] = value ?? null;
|
|
118
|
+
}
|
|
119
|
+
return patch;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Rebuild the paragraph's `_originalFormatting` (the serializer's pPr source)
|
|
123
|
+
* after a reject: the stored old pPr wholesale within CT_PPrBase scope, with
|
|
124
|
+
* the paragraph-mark rPr fields (`runProperties`, `runInWithNext`) preserved
|
|
125
|
+
* from the live original — a pPrChange cannot store them, so a reject must
|
|
126
|
+
* not drop them.
|
|
127
|
+
*/
|
|
128
|
+
function paragraphRejectOriginalFormatting(previousFormatting, liveOriginal) {
|
|
129
|
+
const prev = previousFormatting ?? {};
|
|
130
|
+
const result = {};
|
|
131
|
+
for (const key of PPR_CHANGE_SCOPED_FORMATTING_KEYS) {
|
|
132
|
+
const value = Object.hasOwn(prev, key) ? prev[key] : void 0;
|
|
133
|
+
if (value != null) result[key] = value;
|
|
134
|
+
}
|
|
135
|
+
const live = isRecord(liveOriginal) ? liveOriginal : {};
|
|
136
|
+
if (live["runProperties"] != null) result["runProperties"] = live["runProperties"];
|
|
137
|
+
if (live["runInWithNext"] != null) result["runInWithNext"] = live["runInWithNext"];
|
|
138
|
+
if (Object.keys(result).length === 0) return null;
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
function autospacingBaseFromFormatting(prev) {
|
|
142
|
+
const before = prev["beforeAutospacing"] === true;
|
|
143
|
+
const after = prev["afterAutospacing"] === true;
|
|
144
|
+
if (!before && !after) return null;
|
|
145
|
+
const base = {};
|
|
146
|
+
if (before) setAutospacingBaseValue(base, "before", prev["spaceBefore"]);
|
|
147
|
+
if (after) setAutospacingBaseValue(base, "after", prev["spaceAfter"]);
|
|
148
|
+
return base;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Rejected section properties: the stored old sectPr wholesale, preserving
|
|
152
|
+
* the live header/footer references — `EG_HdrFtrReferences` is not part of
|
|
153
|
+
* the `CT_SectPrBase` payload a `w:sectPrChange` stores (ECMA-376
|
|
154
|
+
* §17.13.5.32), so those children survive a reject. The caller re-attaches
|
|
155
|
+
* whatever `propertyChanges` remain unresolved.
|
|
156
|
+
*/
|
|
157
|
+
function sectionRejectProperties(live, previousProperties) {
|
|
158
|
+
const restored = { ...previousProperties };
|
|
159
|
+
delete restored.propertyChanges;
|
|
160
|
+
if (live.headerReferences) restored.headerReferences = live.headerReferences;
|
|
161
|
+
else delete restored.headerReferences;
|
|
162
|
+
if (live.footerReferences) restored.footerReferences = live.footerReferences;
|
|
163
|
+
else delete restored.footerReferences;
|
|
164
|
+
return restored;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Attr patch for rejecting a `w:tblPrChange`: the stored old tblPr wholesale
|
|
168
|
+
* (`w:tblPrChange` stores the complete previous tblPr, so every tblPr-derived
|
|
169
|
+
* attr resets when absent). `columnWidths` comes from `w:tblGrid`, not tblPr,
|
|
170
|
+
* and is untouched.
|
|
171
|
+
*/
|
|
172
|
+
function tableRejectAttrPatch(previousFormatting) {
|
|
173
|
+
return {
|
|
174
|
+
styleId: previousFormatting?.styleId ?? null,
|
|
175
|
+
width: previousFormatting?.width?.value ?? null,
|
|
176
|
+
widthType: previousFormatting?.width?.type ?? null,
|
|
177
|
+
justification: previousFormatting?.justification ?? null,
|
|
178
|
+
floating: previousFormatting?.floating ?? null,
|
|
179
|
+
cellMargins: previousFormatting?.cellMargins ? cellMarginsToAttr(previousFormatting.cellMargins) : null,
|
|
180
|
+
look: previousFormatting?.look ?? null,
|
|
181
|
+
borders: previousFormatting?.borders ?? null,
|
|
182
|
+
_originalFormatting: previousFormatting ?? null
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/** Attr patch for rejecting a `w:trPrChange`: the stored old trPr wholesale. */
|
|
186
|
+
function tableRowRejectAttrPatch(previousFormatting) {
|
|
187
|
+
return {
|
|
188
|
+
height: previousFormatting?.height?.value ?? null,
|
|
189
|
+
heightRule: previousFormatting?.heightRule ?? null,
|
|
190
|
+
isHeader: previousFormatting?.header ?? false,
|
|
191
|
+
hidden: previousFormatting?.hidden ?? null,
|
|
192
|
+
_originalFormatting: previousFormatting ?? null
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Attr patch for rejecting a `w:tcPrChange`: the stored old tcPr wholesale
|
|
197
|
+
* for the non-structural attrs. `gridSpan` / `vMerge` are structural in
|
|
198
|
+
* ProseMirror (`colspan` / `rowspan` shape the table grid); restoring them
|
|
199
|
+
* from the record would desync the grid without a full table restructure, so
|
|
200
|
+
* the live structure is kept and the rebuilt `_originalFormatting` inherits
|
|
201
|
+
* the live original's `gridSpan` / `vMerge` to stay consistent with it.
|
|
202
|
+
* (Word would also restore tracked merges; folio deliberately does not.)
|
|
203
|
+
*/
|
|
204
|
+
function tableCellRejectAttrPatch(previousFormatting, liveOriginalFormatting) {
|
|
205
|
+
const restoredOriginal = { ...previousFormatting };
|
|
206
|
+
delete restoredOriginal.gridSpan;
|
|
207
|
+
delete restoredOriginal.vMerge;
|
|
208
|
+
if (liveOriginalFormatting?.gridSpan !== void 0) restoredOriginal.gridSpan = liveOriginalFormatting.gridSpan;
|
|
209
|
+
if (liveOriginalFormatting?.vMerge !== void 0) restoredOriginal.vMerge = liveOriginalFormatting.vMerge;
|
|
210
|
+
return {
|
|
211
|
+
width: previousFormatting?.width?.value ?? null,
|
|
212
|
+
widthType: previousFormatting?.width?.type ?? null,
|
|
213
|
+
verticalAlign: previousFormatting?.verticalAlign ?? null,
|
|
214
|
+
backgroundColor: previousFormatting?.shading?.fill?.rgb ?? null,
|
|
215
|
+
textDirection: previousFormatting?.textDirection ?? null,
|
|
216
|
+
noWrap: previousFormatting?.noWrap ?? null,
|
|
217
|
+
borders: previousFormatting?.borders ? cellBordersToAttr(previousFormatting.borders) : null,
|
|
218
|
+
margins: previousFormatting?.margins ? cellMarginsToAttr(previousFormatting.margins) : null,
|
|
219
|
+
_originalFormatting: Object.keys(restoredOriginal).length > 0 ? restoredOriginal : null
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function cellMarginsToAttr(margins) {
|
|
223
|
+
const result = {};
|
|
224
|
+
if (margins.top?.value !== void 0) result.top = margins.top.value;
|
|
225
|
+
if (margins.bottom?.value !== void 0) result.bottom = margins.bottom.value;
|
|
226
|
+
if (margins.left?.value !== void 0) result.left = margins.left.value;
|
|
227
|
+
if (margins.right?.value !== void 0) result.right = margins.right.value;
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
function cellBordersToAttr(borders) {
|
|
231
|
+
const result = {};
|
|
232
|
+
if (borders.top) result.top = borders.top;
|
|
233
|
+
if (borders.bottom) result.bottom = borders.bottom;
|
|
234
|
+
if (borders.left) result.left = borders.left;
|
|
235
|
+
if (borders.right) result.right = borders.right;
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
function isRecord(value) {
|
|
239
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
240
|
+
}
|
|
241
|
+
//#endregion
|
|
242
|
+
export { PPR_CHANGE_SCOPED_ATTR_KEYS, paragraphRejectAttrPatch, paragraphRejectOriginalFormatting, sectionRejectProperties, tableCellRejectAttrPatch, tableRejectAttrPatch, tableRowRejectAttrPatch };
|
|
@@ -341,6 +341,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
341
341
|
if (attrs.styleId !== (orig.styleId ?? void 0)) if (attrs.styleId) result.styleId = attrs.styleId;
|
|
342
342
|
else delete result.styleId;
|
|
343
343
|
assignBooleanToggle(result, attrs, orig, "pageBreakBefore");
|
|
344
|
+
assignBooleanToggle(result, attrs, orig, "widowControl");
|
|
344
345
|
if (attrs.spacingExplicit !== orig.spacingExplicit) if (attrs.spacingExplicit) result.spacingExplicit = attrs.spacingExplicit;
|
|
345
346
|
else delete result.spacingExplicit;
|
|
346
347
|
const bidi = directionToBidi(attrs.direction);
|
|
@@ -350,7 +351,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
350
351
|
}
|
|
351
352
|
const outlineLevel = Reflect.get(attrs, "outlineLevel");
|
|
352
353
|
const bidi = directionToBidi(attrs.direction);
|
|
353
|
-
if (!(attrs.alignment || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || attrs.lineSpacing || 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)) return;
|
|
354
|
+
if (!(attrs.alignment || shouldSerializeSpaceBefore || shouldSerializeSpaceAfter || beforeAutospacingEdited || afterAutospacingEdited || attrs.lineSpacing || 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)) return;
|
|
354
355
|
const f = {};
|
|
355
356
|
if (attrs.alignment) f.alignment = attrs.alignment;
|
|
356
357
|
if (shouldSerializeSpaceBefore) f.spaceBefore = spaceBefore;
|
|
@@ -373,6 +374,7 @@ function paragraphAttrsToFormatting(attrs) {
|
|
|
373
374
|
if (attrs.contextualSpacing) f.contextualSpacing = attrs.contextualSpacing;
|
|
374
375
|
if (bidi != null) f.bidi = bidi;
|
|
375
376
|
if (attrs.pageBreakBefore != null) f.pageBreakBefore = attrs.pageBreakBefore;
|
|
377
|
+
if (attrs.widowControl != null) f.widowControl = attrs.widowControl;
|
|
376
378
|
return f;
|
|
377
379
|
}
|
|
378
380
|
/**
|
|
@@ -491,13 +493,12 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks) {
|
|
|
491
493
|
}
|
|
492
494
|
if (linkMark) {
|
|
493
495
|
const linkKey = getLinkKey(linkMark);
|
|
494
|
-
if (currentHyperlink && currentHyperlinkKey === linkKey)
|
|
495
|
-
else {
|
|
496
|
+
if (currentHyperlink && currentHyperlinkKey === linkKey) {} else {
|
|
496
497
|
flushCurrentInline();
|
|
497
498
|
currentHyperlink = createHyperlink(linkMark);
|
|
498
499
|
currentHyperlinkKey = linkKey;
|
|
499
|
-
addNodeToHyperlink(currentHyperlink, node);
|
|
500
500
|
}
|
|
501
|
+
addNodeToHyperlink(currentHyperlink, node);
|
|
501
502
|
return;
|
|
502
503
|
}
|
|
503
504
|
if (currentHyperlink) flushCurrentInline();
|
|
@@ -1234,6 +1235,7 @@ function convertPMTable(node, documentCounts) {
|
|
|
1234
1235
|
rows
|
|
1235
1236
|
};
|
|
1236
1237
|
if (attrs.columnWidths) minTable.columnWidths = attrs.columnWidths;
|
|
1238
|
+
restoreTablePropertyChanges(minTable, attrs);
|
|
1237
1239
|
return minTable;
|
|
1238
1240
|
}
|
|
1239
1241
|
}
|
|
@@ -1243,8 +1245,17 @@ function convertPMTable(node, documentCounts) {
|
|
|
1243
1245
|
};
|
|
1244
1246
|
if (attrs.columnWidths) table.columnWidths = attrs.columnWidths;
|
|
1245
1247
|
if (formatting) table.formatting = formatting;
|
|
1248
|
+
restoreTablePropertyChanges(table, attrs);
|
|
1246
1249
|
return table;
|
|
1247
1250
|
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Restore `w:tblPrChange` entries that PM carried opaquely on the table attrs
|
|
1253
|
+
* (same rationale as the paragraph `_propertyChanges` attr): they must survive
|
|
1254
|
+
* an edit so the saved DOCX keeps the tracked property-change history.
|
|
1255
|
+
*/
|
|
1256
|
+
function restoreTablePropertyChanges(table, attrs) {
|
|
1257
|
+
if (Array.isArray(attrs.tblPrChange) && attrs.tblPrChange.length > 0) table.propertyChanges = [...attrs.tblPrChange];
|
|
1258
|
+
}
|
|
1248
1259
|
function convertPMTableRows(node, documentCounts) {
|
|
1249
1260
|
const rows = [];
|
|
1250
1261
|
const activeVerticalMerges = /* @__PURE__ */ new Map();
|
|
@@ -1367,6 +1378,7 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges) {
|
|
|
1367
1378
|
};
|
|
1368
1379
|
const rowFormatting = tableRowAttrsToFormatting(attrs);
|
|
1369
1380
|
if (rowFormatting) row.formatting = rowFormatting;
|
|
1381
|
+
if (Array.isArray(attrs.trPrChange) && attrs.trPrChange.length > 0) row.propertyChanges = [...attrs.trPrChange];
|
|
1370
1382
|
return row;
|
|
1371
1383
|
}
|
|
1372
1384
|
function createVerticalMergeContinuationCell(colspan) {
|
|
@@ -1397,9 +1409,11 @@ function tableRowAttrsToFormatting(attrs) {
|
|
|
1397
1409
|
else delete result.heightRule;
|
|
1398
1410
|
if (attrs.isHeader !== (orig.header ?? void 0)) if (attrs.isHeader) result.header = attrs.isHeader;
|
|
1399
1411
|
else delete result.header;
|
|
1412
|
+
if (attrs.hidden !== (orig.hidden ?? void 0)) if (attrs.hidden) result.hidden = attrs.hidden;
|
|
1413
|
+
else delete result.hidden;
|
|
1400
1414
|
return result;
|
|
1401
1415
|
}
|
|
1402
|
-
if (!(attrs.height || attrs.isHeader)) return;
|
|
1416
|
+
if (!(attrs.height || attrs.isHeader || attrs.hidden)) return;
|
|
1403
1417
|
const f = {};
|
|
1404
1418
|
if (attrs.height) f.height = {
|
|
1405
1419
|
value: attrs.height,
|
|
@@ -1407,6 +1421,7 @@ function tableRowAttrsToFormatting(attrs) {
|
|
|
1407
1421
|
};
|
|
1408
1422
|
if (attrs.heightRule) f.heightRule = attrs.heightRule;
|
|
1409
1423
|
if (attrs.isHeader) f.header = attrs.isHeader;
|
|
1424
|
+
if (attrs.hidden) f.hidden = attrs.hidden;
|
|
1410
1425
|
return f;
|
|
1411
1426
|
}
|
|
1412
1427
|
/**
|
|
@@ -1425,6 +1440,7 @@ function convertPMTableCell(node, documentCounts) {
|
|
|
1425
1440
|
};
|
|
1426
1441
|
const cellFormatting = tableCellAttrsToFormatting(attrs);
|
|
1427
1442
|
if (cellFormatting) cell.formatting = cellFormatting;
|
|
1443
|
+
if (Array.isArray(attrs.tcPrChange) && attrs.tcPrChange.length > 0) cell.propertyChanges = [...attrs.tcPrChange];
|
|
1428
1444
|
return cell;
|
|
1429
1445
|
}
|
|
1430
1446
|
/**
|
|
@@ -11,6 +11,7 @@ import { createStyleEngine } from "../../style-engine/styleEngine.js";
|
|
|
11
11
|
import { buildRunFormattingOverrideAttrs } from "../extensions/marks/RunFormattingOverrideExtension.js";
|
|
12
12
|
import { schema } from "../schema/index.js";
|
|
13
13
|
//#region src/prosemirror/conversion/toProseDoc.ts
|
|
14
|
+
const TOC_STYLE_ID = /^TOC\d*$/iu;
|
|
14
15
|
/**
|
|
15
16
|
* Convert a Document to a ProseMirror document
|
|
16
17
|
*
|
|
@@ -80,6 +81,7 @@ function convertBlockSdt(blockSdt, convertBlocks) {
|
|
|
80
81
|
*/
|
|
81
82
|
function convertParagraph(paragraph, styleResolver, activeCommentIds, extraRunFormatting, tableParagraphOverlay) {
|
|
82
83
|
const attrs = paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOverlay);
|
|
84
|
+
const isTocParagraph = TOC_STYLE_ID.test(paragraph.formatting?.styleId ?? "");
|
|
83
85
|
const inlineNodes = [];
|
|
84
86
|
let inlineOffset = 0;
|
|
85
87
|
let bookmarksArr;
|
|
@@ -98,13 +100,16 @@ function convertParagraph(paragraph, styleResolver, activeCommentIds, extraRunFo
|
|
|
98
100
|
};
|
|
99
101
|
let styleRunFormatting;
|
|
100
102
|
if (styleResolver) styleRunFormatting = styleResolver.resolveParagraphStyle(paragraph.formatting?.styleId).runFormatting;
|
|
101
|
-
const paragraphRunFormatting = paragraph.formatting?.runProperties
|
|
102
|
-
|
|
103
|
+
const paragraphRunFormatting = resolveParagraphMarkRunFormatting(paragraph.formatting?.runProperties, styleResolver);
|
|
104
|
+
let inheritableParagraphRunFormatting;
|
|
105
|
+
if (paragraphRunFormatting && !isTocParagraph) inheritableParagraphRunFormatting = stripParagraphMarkOnlyFormatting(paragraphRunFormatting);
|
|
103
106
|
const baseRunFormatting = mergeTextFormatting(styleRunFormatting, extraRunFormatting);
|
|
104
|
-
const
|
|
105
|
-
const
|
|
107
|
+
const paragraphMarkPrecedesStyle = paragraph.formatting?.styleId !== void 0;
|
|
108
|
+
const defaultRunFormatting = paragraphMarkPrecedesStyle ? mergeTextFormatting(inheritableParagraphRunFormatting, baseRunFormatting) : mergeTextFormatting(baseRunFormatting, inheritableParagraphRunFormatting);
|
|
109
|
+
const getInheritedRunFormatting = (formatting, fieldType) => {
|
|
110
|
+
if (fieldType === "TOC") return hasDirectRunFormatting(formatting) ? suppressParagraphMarkFormatting(baseRunFormatting, void 0, formatting) : baseRunFormatting;
|
|
106
111
|
if (!hasDirectRunFormatting(formatting)) return defaultRunFormatting;
|
|
107
|
-
return suppressParagraphMarkFormatting(baseRunFormatting, inheritableParagraphRunFormatting, formatting);
|
|
112
|
+
return suppressParagraphMarkFormatting(baseRunFormatting, inheritableParagraphRunFormatting, formatting, paragraphMarkPrecedesStyle);
|
|
108
113
|
};
|
|
109
114
|
const emitTrackedChange = (change, markType, moveKind) => {
|
|
110
115
|
emitInlineNodes(convertTrackedChange(change, markType, getInheritedRunFormatting, styleResolver, moveKind));
|
|
@@ -224,6 +229,10 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
224
229
|
if (paragraph.listRendering?.implicitChildLevelAdvances !== void 0) attrs.listImplicitChildLevelAdvances = paragraph.listRendering.implicitChildLevelAdvances;
|
|
225
230
|
if (paragraph.listRendering?.markerSecondSlotOffsetTwips !== void 0) attrs.listMarkerSecondSlotOffsetTwips = paragraph.listRendering.markerSecondSlotOffsetTwips;
|
|
226
231
|
if (paragraph.listRendering?.levelNumFmts) attrs.listLevelNumFmts = paragraph.listRendering.levelNumFmts;
|
|
232
|
+
if (paragraph.listRendering && "levelStarts" in paragraph.listRendering) {
|
|
233
|
+
const { levelStarts } = paragraph.listRendering;
|
|
234
|
+
if (Array.isArray(levelStarts) && levelStarts.every((value) => typeof value === "number")) attrs.listLevelStarts = levelStarts;
|
|
235
|
+
}
|
|
227
236
|
if (paragraph.listRendering?.abstractNumId !== void 0) attrs.listAbstractNumId = paragraph.listRendering.abstractNumId;
|
|
228
237
|
if (paragraph.listRendering?.startOverride !== void 0) attrs.listStartOverride = paragraph.listRendering.startOverride;
|
|
229
238
|
if (formatting) attrs._originalFormatting = formatting;
|
|
@@ -241,6 +250,12 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
241
250
|
set("lineSpacing", formatting?.lineSpacing ?? stylePpr?.lineSpacing);
|
|
242
251
|
set("lineSpacingRule", formatting?.lineSpacingRule ?? stylePpr?.lineSpacingRule);
|
|
243
252
|
set("spacingExplicit", formatting?.spacingExplicit);
|
|
253
|
+
const paragraphStyle = styleId ? styleResolver.getStyle(styleId) ?? styleResolver.getDefaultParagraphStyle() : styleResolver.getDefaultParagraphStyle();
|
|
254
|
+
const docDefaultSpacing = styleResolver.getDocDefaults()?.pPr;
|
|
255
|
+
const spacingFromDocDefaults = {};
|
|
256
|
+
if (formatting?.spaceBefore === void 0 && tableParagraphOverlay?.spaceBefore === void 0 && paragraphStyle?.pPr?.spaceBefore === void 0 && docDefaultSpacing?.spaceBefore !== void 0) spacingFromDocDefaults.before = true;
|
|
257
|
+
if (formatting?.spaceAfter === void 0 && tableParagraphOverlay?.spaceAfter === void 0 && paragraphStyle?.pPr?.spaceAfter === void 0 && docDefaultSpacing?.spaceAfter !== void 0) spacingFromDocDefaults.after = true;
|
|
258
|
+
if (spacingFromDocDefaults.before || spacingFromDocDefaults.after) attrs.spacingFromDocDefaults = spacingFromDocDefaults;
|
|
244
259
|
set("indentLeft", formatting?.indentLeft ?? stylePpr?.indentLeft);
|
|
245
260
|
set("indentRight", formatting?.indentRight ?? stylePpr?.indentRight);
|
|
246
261
|
const styleFirstLine = formatting?.numPr?.numId === 0 && stylePpr?.numPr !== void 0 && stylePpr.numPr.numId !== 0 ? void 0 : stylePpr;
|
|
@@ -252,11 +267,12 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
252
267
|
set("pageBreakBefore", formatting?.pageBreakBefore ?? stylePpr?.pageBreakBefore);
|
|
253
268
|
set("keepNext", formatting?.keepNext ?? stylePpr?.keepNext);
|
|
254
269
|
set("keepLines", formatting?.keepLines ?? stylePpr?.keepLines);
|
|
270
|
+
set("widowControl", formatting?.widowControl ?? stylePpr?.widowControl);
|
|
255
271
|
set("contextualSpacing", formatting?.contextualSpacing ?? stylePpr?.contextualSpacing);
|
|
256
272
|
set("runInWithNext", formatting?.runInWithNext ?? stylePpr?.runInWithNext);
|
|
257
273
|
set("outlineLevel", formatting?.outlineLevel ?? stylePpr?.outlineLevel);
|
|
258
274
|
set("direction", directionFromBidi(formatting?.bidi ?? stylePpr?.bidi));
|
|
259
|
-
set("defaultTextFormatting", resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver));
|
|
275
|
+
set("defaultTextFormatting", resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver, { includeParagraphMarkRunProperties: !TOC_STYLE_ID.test(styleId ?? "") }));
|
|
260
276
|
if (!formatting?.numPr && stylePpr?.numPr && stylePpr.numPr.numId !== 0) {
|
|
261
277
|
attrs.numPr = stylePpr.numPr;
|
|
262
278
|
attrs.numPrFromStyle = stylePpr.numPr;
|
|
@@ -278,6 +294,7 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
278
294
|
set("pageBreakBefore", formatting?.pageBreakBefore);
|
|
279
295
|
set("keepNext", formatting?.keepNext);
|
|
280
296
|
set("keepLines", formatting?.keepLines);
|
|
297
|
+
set("widowControl", formatting?.widowControl);
|
|
281
298
|
set("runInWithNext", formatting?.runInWithNext);
|
|
282
299
|
set("outlineLevel", formatting?.outlineLevel);
|
|
283
300
|
set("direction", directionFromBidi(formatting?.bidi));
|
|
@@ -381,12 +398,12 @@ function hasDirectRunFormatting(formatting) {
|
|
|
381
398
|
return Object.entries(formatting).some(([key, value]) => key !== "styleId" && value !== void 0);
|
|
382
399
|
}
|
|
383
400
|
function stripParagraphMarkOnlyFormatting(formatting) {
|
|
384
|
-
const { highlight: _h, shading: _s, ...rest } = formatting;
|
|
401
|
+
const { allCaps: _ac, highlight: _h, shading: _s, smallCaps: _sc, ...rest } = formatting;
|
|
385
402
|
return Object.keys(rest).length > 0 ? rest : void 0;
|
|
386
403
|
}
|
|
387
|
-
function suppressParagraphMarkFormatting(base, paragraphMark, direct) {
|
|
404
|
+
function suppressParagraphMarkFormatting(base, paragraphMark, direct, paragraphMarkPrecedesStyle = false) {
|
|
388
405
|
if (!paragraphMark) return base;
|
|
389
|
-
const result =
|
|
406
|
+
const result = (paragraphMarkPrecedesStyle ? mergeTextFormatting(paragraphMark, base) : mergeTextFormatting(base, paragraphMark)) ?? {};
|
|
390
407
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "bold");
|
|
391
408
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "italic");
|
|
392
409
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "strike");
|
|
@@ -399,7 +416,10 @@ function suppressParagraphMarkFormatting(base, paragraphMark, direct) {
|
|
|
399
416
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "shadow");
|
|
400
417
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "outline");
|
|
401
418
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "rtl");
|
|
419
|
+
if (paragraphMark.fontSize !== void 0 && direct?.fontSize === void 0 && base?.fontSize !== void 0) result.fontSize = base.fontSize;
|
|
420
|
+
if (paragraphMark.fontSizeCs !== void 0 && direct?.fontSizeCs === void 0 && base?.fontSizeCs !== void 0) result.fontSizeCs = base.fontSizeCs;
|
|
402
421
|
if (paragraphMark.underline !== void 0 && direct?.underline === void 0) result.underline = { style: "none" };
|
|
422
|
+
if (paragraphMark.spacing !== void 0 && direct?.spacing === void 0) result.spacing = 0;
|
|
403
423
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
404
424
|
}
|
|
405
425
|
function suppressBooleanParagraphMark(result, paragraphMark, direct, key) {
|
|
@@ -411,13 +431,17 @@ function resolveTextFormatting(formatting, styleResolver) {
|
|
|
411
431
|
if (!styleResolver) return formatting;
|
|
412
432
|
return mergeTextFormatting(styleResolver.resolveRunStyle(formatting.styleId), formatting);
|
|
413
433
|
}
|
|
414
|
-
function
|
|
434
|
+
function resolveParagraphMarkRunFormatting(formatting, styleResolver) {
|
|
435
|
+
if (!formatting || !styleResolver) return formatting;
|
|
436
|
+
return mergeTextFormatting(formatting.styleId ? styleResolver.getRunStyleOwnProperties(formatting.styleId) : void 0, formatting);
|
|
437
|
+
}
|
|
438
|
+
function resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver, options = {}) {
|
|
415
439
|
const style = styleId ? styleResolver.getStyle(styleId) ?? styleResolver.getDefaultParagraphStyle() : styleResolver.getDefaultParagraphStyle();
|
|
416
440
|
const paragraphStyleRpr = style?.type === "paragraph" ? style.rPr : void 0;
|
|
417
|
-
const rawParagraphMarkRpr = formatting?.runProperties;
|
|
418
|
-
const
|
|
419
|
-
const
|
|
420
|
-
return mergeTextFormatting(
|
|
441
|
+
const rawParagraphMarkRpr = options.includeParagraphMarkRunProperties === false ? void 0 : formatting?.runProperties;
|
|
442
|
+
const paragraphRunProperties = rawParagraphMarkRpr ? stripParagraphMarkOnlyFormatting(resolveParagraphMarkRunFormatting(rawParagraphMarkRpr, styleResolver) ?? {}) : void 0;
|
|
443
|
+
const bodyRunDefaults = mergeTextFormatting(mergeTextFormatting(styleResolver.getDocDefaults()?.rPr, styleResolver.getDefaultCharacterStyle()?.rPr), paragraphStyleRpr);
|
|
444
|
+
return styleId === void 0 ? mergeTextFormatting(bodyRunDefaults, paragraphRunProperties) : mergeTextFormatting(paragraphRunProperties, bodyRunDefaults);
|
|
421
445
|
}
|
|
422
446
|
function calculateRowSpans(table) {
|
|
423
447
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -543,6 +567,7 @@ function convertTable(table, styleResolver, theme) {
|
|
|
543
567
|
if (table.formatting?.look) attrs.look = table.formatting.look;
|
|
544
568
|
if (table.formatting?.borders) attrs.borders = table.formatting.borders;
|
|
545
569
|
if (table.formatting) attrs._originalFormatting = table.formatting;
|
|
570
|
+
if (table.propertyChanges && table.propertyChanges.length > 0) attrs.tblPrChange = [...table.propertyChanges];
|
|
546
571
|
const conditionalStyles = {};
|
|
547
572
|
const setCS = (key, type) => {
|
|
548
573
|
const val = resolveTableStyleConditional(styleResolver, conditionalTableStyleId, type);
|
|
@@ -599,7 +624,9 @@ function convertTableRow(row, styleResolver, isHeaderRow, columnWidths, totalWid
|
|
|
599
624
|
const attrs = { isHeader: !!row.formatting?.header };
|
|
600
625
|
if (row.formatting?.height?.value !== void 0) attrs.height = row.formatting.height.value;
|
|
601
626
|
if (row.formatting?.heightRule) attrs.heightRule = row.formatting.heightRule;
|
|
627
|
+
if (row.formatting?.hidden) attrs.hidden = true;
|
|
602
628
|
if (row.formatting) attrs._originalFormatting = row.formatting;
|
|
629
|
+
if (row.propertyChanges && row.propertyChanges.length > 0) attrs.trPrChange = [...row.propertyChanges];
|
|
603
630
|
const numCells = row.cells.length;
|
|
604
631
|
const isFirstRow = rowIndex === 0;
|
|
605
632
|
const isLastRow = rowIndex === (totalRows ?? 1) - 1;
|
|
@@ -745,6 +772,7 @@ function convertTableCell(cell, styleResolver, isHeader, gridWidthPercent, condi
|
|
|
745
772
|
else if (conditionalStyle?.tcPr?.margins) attrs.margins = buildMarginsAttr(conditionalStyle.tcPr.margins);
|
|
746
773
|
else if (defaultCellMargins) attrs.margins = defaultCellMargins;
|
|
747
774
|
if (formatting) attrs._originalFormatting = formatting;
|
|
775
|
+
if (cell.propertyChanges && cell.propertyChanges.length > 0) attrs.tcPrChange = [...cell.propertyChanges];
|
|
748
776
|
if (preserveVMergeRestart) attrs._preserveVMergeRestart = true;
|
|
749
777
|
if (vMergeContinuationCells && vMergeContinuationCells.length > 0) attrs._docxVMergeContinuationCells = vMergeContinuationCells;
|
|
750
778
|
const contentNodes = [];
|
|
@@ -769,7 +797,7 @@ function convertField(field, getInheritedRunFormatting, styleResolver) {
|
|
|
769
797
|
if (!fieldFormatting && r.formatting) fieldFormatting = r.formatting;
|
|
770
798
|
}
|
|
771
799
|
if (!fieldFormatting && field.type === "complexField" && field.fieldResult.length === 0) fieldFormatting = field.formatting;
|
|
772
|
-
const inheritedFormatting = getInheritedRunFormatting(fieldFormatting);
|
|
800
|
+
const inheritedFormatting = getInheritedRunFormatting(fieldFormatting, field.fieldType);
|
|
773
801
|
const { marks } = buildRunMarks(fieldFormatting, inheritedFormatting, styleResolver);
|
|
774
802
|
return schema.node("field", {
|
|
775
803
|
fieldType: field.fieldType,
|
|
@@ -185,6 +185,7 @@ const paragraphNodeSpec = {
|
|
|
185
185
|
lineSpacing: { default: null },
|
|
186
186
|
lineSpacingRule: { default: null },
|
|
187
187
|
spacingExplicit: { default: null },
|
|
188
|
+
spacingFromDocDefaults: { default: null },
|
|
188
189
|
indentLeft: { default: null },
|
|
189
190
|
indentRight: { default: null },
|
|
190
191
|
indentFirstLine: { default: null },
|
|
@@ -203,6 +204,7 @@ const paragraphNodeSpec = {
|
|
|
203
204
|
listImplicitChildLevelAdvances: { default: null },
|
|
204
205
|
listMarkerSecondSlotOffsetTwips: { default: null },
|
|
205
206
|
listLevelNumFmts: { default: null },
|
|
207
|
+
listLevelStarts: { default: null },
|
|
206
208
|
listAbstractNumId: { default: null },
|
|
207
209
|
listStartOverride: { default: null },
|
|
208
210
|
styleId: { default: null },
|
|
@@ -213,6 +215,7 @@ const paragraphNodeSpec = {
|
|
|
213
215
|
renderedPageBreakBefore: { default: null },
|
|
214
216
|
keepNext: { default: null },
|
|
215
217
|
keepLines: { default: null },
|
|
218
|
+
widowControl: { default: null },
|
|
216
219
|
contextualSpacing: { default: null },
|
|
217
220
|
runInWithNext: { default: null },
|
|
218
221
|
defaultTextFormatting: { default: null },
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PPR_CHANGE_SCOPED_ATTR_KEYS } from "../../commands/propertyChangeScope.js";
|
|
1
2
|
import { Priority } from "../types.js";
|
|
2
3
|
import { createExtension } from "../create.js";
|
|
3
4
|
import { SUGGESTION_META, makeRevisionInfo } from "../../plugins/suggestionMode.js";
|
|
@@ -35,11 +36,16 @@ const LIST_FORMATTING_ATTRS = [
|
|
|
35
36
|
"listMarkerFontSize",
|
|
36
37
|
"listMarkerSuffix",
|
|
37
38
|
"listLevelNumFmts",
|
|
39
|
+
"listLevelStarts",
|
|
38
40
|
"listAbstractNumId",
|
|
39
41
|
"listStartOverride"
|
|
40
42
|
];
|
|
41
43
|
function getPreviousListFormatting(attrs) {
|
|
42
44
|
const previousFormatting = {};
|
|
45
|
+
for (const key of PPR_CHANGE_SCOPED_ATTR_KEYS) {
|
|
46
|
+
const value = attrs[key];
|
|
47
|
+
if (value != null) previousFormatting[key] = value;
|
|
48
|
+
}
|
|
43
49
|
for (const key of LIST_FORMATTING_ATTRS) previousFormatting[key] = attrs[key] ?? null;
|
|
44
50
|
return previousFormatting;
|
|
45
51
|
}
|