@stll/folio-core 0.4.0 → 0.6.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 +37 -4
- package/dist/ai-edits/headless.js +134 -16
- 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 -137
- package/dist/controller/layoutScheduler.d.ts +2 -1
- package/dist/controller/layoutScheduler.js +6 -0
- package/dist/document-operations.d.ts +139 -0
- package/dist/document-operations.js +578 -0
- package/dist/docx/blockContentParser.js +17 -7
- package/dist/docx/encryption/agileDecryption.js +2 -1
- package/dist/docx/encryption/compoundFile.js +4 -2
- 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/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +8 -2
- package/dist/docx/paragraphParser.js +9 -3
- 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/xmlParser.js +11 -4
- package/dist/i18n/messages/catalogs.gen.d.ts +1054 -34
- package/dist/i18n/messages/catalogs.gen.js +1122 -68
- package/dist/i18n/messages/messages.gen.d.ts +62 -2
- 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 +5 -7
- package/dist/layout-bridge/convert/headerFooterLayout.js +5 -7
- package/dist/layout-bridge/convert/toFlowBlocks.js +56 -19
- package/dist/layout-engine/index.d.ts +6 -5
- package/dist/layout-engine/index.js +143 -30
- 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 +50 -18
- package/dist/layout-engine/measure/measureParagraph.js +61 -15
- 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 +30 -9
- package/dist/layout-engine/types.js +20 -2
- package/dist/layout-painter/renderPage.d.ts +15 -1
- package/dist/layout-painter/renderPage.js +27 -11
- package/dist/layout-painter/renderParagraph.js +18 -8
- package/dist/layout-painter/renderTable.js +10 -7
- package/dist/managers/DocumentLoaderManager.js +12 -5
- 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 +2 -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/propertyChangeScope.d.ts +68 -0
- package/dist/prosemirror/commands/propertyChangeScope.js +242 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +14 -3
- package/dist/prosemirror/conversion/toProseDoc.js +29 -8
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +10 -11
- package/dist/prosemirror/findReplaceSelection.js +2 -1
- package/dist/prosemirror/schema/nodes.d.ts +10 -5
- 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 +48 -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 +3 -3
- package/dist/paged-layout/headerFooterMargins.d.ts +0 -75
- package/dist/paged-layout/headerFooterMargins.js +0 -122
|
@@ -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 };
|
|
@@ -493,13 +493,12 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks) {
|
|
|
493
493
|
}
|
|
494
494
|
if (linkMark) {
|
|
495
495
|
const linkKey = getLinkKey(linkMark);
|
|
496
|
-
if (currentHyperlink && currentHyperlinkKey === linkKey)
|
|
497
|
-
else {
|
|
496
|
+
if (currentHyperlink && currentHyperlinkKey === linkKey) {} else {
|
|
498
497
|
flushCurrentInline();
|
|
499
498
|
currentHyperlink = createHyperlink(linkMark);
|
|
500
499
|
currentHyperlinkKey = linkKey;
|
|
501
|
-
addNodeToHyperlink(currentHyperlink, node);
|
|
502
500
|
}
|
|
501
|
+
addNodeToHyperlink(currentHyperlink, node);
|
|
503
502
|
return;
|
|
504
503
|
}
|
|
505
504
|
if (currentHyperlink) flushCurrentInline();
|
|
@@ -1236,6 +1235,7 @@ function convertPMTable(node, documentCounts) {
|
|
|
1236
1235
|
rows
|
|
1237
1236
|
};
|
|
1238
1237
|
if (attrs.columnWidths) minTable.columnWidths = attrs.columnWidths;
|
|
1238
|
+
restoreTablePropertyChanges(minTable, attrs);
|
|
1239
1239
|
return minTable;
|
|
1240
1240
|
}
|
|
1241
1241
|
}
|
|
@@ -1245,8 +1245,17 @@ function convertPMTable(node, documentCounts) {
|
|
|
1245
1245
|
};
|
|
1246
1246
|
if (attrs.columnWidths) table.columnWidths = attrs.columnWidths;
|
|
1247
1247
|
if (formatting) table.formatting = formatting;
|
|
1248
|
+
restoreTablePropertyChanges(table, attrs);
|
|
1248
1249
|
return table;
|
|
1249
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
|
+
}
|
|
1250
1259
|
function convertPMTableRows(node, documentCounts) {
|
|
1251
1260
|
const rows = [];
|
|
1252
1261
|
const activeVerticalMerges = /* @__PURE__ */ new Map();
|
|
@@ -1369,6 +1378,7 @@ function convertPMTableRow(node, documentCounts, activeVerticalMerges) {
|
|
|
1369
1378
|
};
|
|
1370
1379
|
const rowFormatting = tableRowAttrsToFormatting(attrs);
|
|
1371
1380
|
if (rowFormatting) row.formatting = rowFormatting;
|
|
1381
|
+
if (Array.isArray(attrs.trPrChange) && attrs.trPrChange.length > 0) row.propertyChanges = [...attrs.trPrChange];
|
|
1372
1382
|
return row;
|
|
1373
1383
|
}
|
|
1374
1384
|
function createVerticalMergeContinuationCell(colspan) {
|
|
@@ -1430,6 +1440,7 @@ function convertPMTableCell(node, documentCounts) {
|
|
|
1430
1440
|
};
|
|
1431
1441
|
const cellFormatting = tableCellAttrsToFormatting(attrs);
|
|
1432
1442
|
if (cellFormatting) cell.formatting = cellFormatting;
|
|
1443
|
+
if (Array.isArray(attrs.tcPrChange) && attrs.tcPrChange.length > 0) cell.propertyChanges = [...attrs.tcPrChange];
|
|
1433
1444
|
return cell;
|
|
1434
1445
|
}
|
|
1435
1446
|
/**
|
|
@@ -100,15 +100,16 @@ function convertParagraph(paragraph, styleResolver, activeCommentIds, extraRunFo
|
|
|
100
100
|
};
|
|
101
101
|
let styleRunFormatting;
|
|
102
102
|
if (styleResolver) styleRunFormatting = styleResolver.resolveParagraphStyle(paragraph.formatting?.styleId).runFormatting;
|
|
103
|
-
const paragraphRunFormatting = paragraph.formatting?.runProperties
|
|
103
|
+
const paragraphRunFormatting = resolveParagraphMarkRunFormatting(paragraph.formatting?.runProperties, styleResolver);
|
|
104
104
|
let inheritableParagraphRunFormatting;
|
|
105
105
|
if (paragraphRunFormatting && !isTocParagraph) inheritableParagraphRunFormatting = stripParagraphMarkOnlyFormatting(paragraphRunFormatting);
|
|
106
106
|
const baseRunFormatting = mergeTextFormatting(styleRunFormatting, extraRunFormatting);
|
|
107
|
-
const
|
|
107
|
+
const paragraphMarkPrecedesStyle = paragraph.formatting?.styleId !== void 0;
|
|
108
|
+
const defaultRunFormatting = paragraphMarkPrecedesStyle ? mergeTextFormatting(inheritableParagraphRunFormatting, baseRunFormatting) : mergeTextFormatting(baseRunFormatting, inheritableParagraphRunFormatting);
|
|
108
109
|
const getInheritedRunFormatting = (formatting, fieldType) => {
|
|
109
110
|
if (fieldType === "TOC") return hasDirectRunFormatting(formatting) ? suppressParagraphMarkFormatting(baseRunFormatting, void 0, formatting) : baseRunFormatting;
|
|
110
111
|
if (!hasDirectRunFormatting(formatting)) return defaultRunFormatting;
|
|
111
|
-
return suppressParagraphMarkFormatting(baseRunFormatting, inheritableParagraphRunFormatting, formatting);
|
|
112
|
+
return suppressParagraphMarkFormatting(baseRunFormatting, inheritableParagraphRunFormatting, formatting, paragraphMarkPrecedesStyle);
|
|
112
113
|
};
|
|
113
114
|
const emitTrackedChange = (change, markType, moveKind) => {
|
|
114
115
|
emitInlineNodes(convertTrackedChange(change, markType, getInheritedRunFormatting, styleResolver, moveKind));
|
|
@@ -228,6 +229,10 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
228
229
|
if (paragraph.listRendering?.implicitChildLevelAdvances !== void 0) attrs.listImplicitChildLevelAdvances = paragraph.listRendering.implicitChildLevelAdvances;
|
|
229
230
|
if (paragraph.listRendering?.markerSecondSlotOffsetTwips !== void 0) attrs.listMarkerSecondSlotOffsetTwips = paragraph.listRendering.markerSecondSlotOffsetTwips;
|
|
230
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
|
+
}
|
|
231
236
|
if (paragraph.listRendering?.abstractNumId !== void 0) attrs.listAbstractNumId = paragraph.listRendering.abstractNumId;
|
|
232
237
|
if (paragraph.listRendering?.startOverride !== void 0) attrs.listStartOverride = paragraph.listRendering.startOverride;
|
|
233
238
|
if (formatting) attrs._originalFormatting = formatting;
|
|
@@ -245,6 +250,12 @@ function paragraphFormattingToAttrs(paragraph, styleResolver, tableParagraphOver
|
|
|
245
250
|
set("lineSpacing", formatting?.lineSpacing ?? stylePpr?.lineSpacing);
|
|
246
251
|
set("lineSpacingRule", formatting?.lineSpacingRule ?? stylePpr?.lineSpacingRule);
|
|
247
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;
|
|
248
259
|
set("indentLeft", formatting?.indentLeft ?? stylePpr?.indentLeft);
|
|
249
260
|
set("indentRight", formatting?.indentRight ?? stylePpr?.indentRight);
|
|
250
261
|
const styleFirstLine = formatting?.numPr?.numId === 0 && stylePpr?.numPr !== void 0 && stylePpr.numPr.numId !== 0 ? void 0 : stylePpr;
|
|
@@ -390,9 +401,9 @@ function stripParagraphMarkOnlyFormatting(formatting) {
|
|
|
390
401
|
const { allCaps: _ac, highlight: _h, shading: _s, smallCaps: _sc, ...rest } = formatting;
|
|
391
402
|
return Object.keys(rest).length > 0 ? rest : void 0;
|
|
392
403
|
}
|
|
393
|
-
function suppressParagraphMarkFormatting(base, paragraphMark, direct) {
|
|
404
|
+
function suppressParagraphMarkFormatting(base, paragraphMark, direct, paragraphMarkPrecedesStyle = false) {
|
|
394
405
|
if (!paragraphMark) return base;
|
|
395
|
-
const result =
|
|
406
|
+
const result = (paragraphMarkPrecedesStyle ? mergeTextFormatting(paragraphMark, base) : mergeTextFormatting(base, paragraphMark)) ?? {};
|
|
396
407
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "bold");
|
|
397
408
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "italic");
|
|
398
409
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "strike");
|
|
@@ -405,7 +416,10 @@ function suppressParagraphMarkFormatting(base, paragraphMark, direct) {
|
|
|
405
416
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "shadow");
|
|
406
417
|
suppressBooleanParagraphMark(result, paragraphMark, direct, "outline");
|
|
407
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;
|
|
408
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;
|
|
409
423
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
410
424
|
}
|
|
411
425
|
function suppressBooleanParagraphMark(result, paragraphMark, direct, key) {
|
|
@@ -417,13 +431,17 @@ function resolveTextFormatting(formatting, styleResolver) {
|
|
|
417
431
|
if (!styleResolver) return formatting;
|
|
418
432
|
return mergeTextFormatting(styleResolver.resolveRunStyle(formatting.styleId), formatting);
|
|
419
433
|
}
|
|
434
|
+
function resolveParagraphMarkRunFormatting(formatting, styleResolver) {
|
|
435
|
+
if (!formatting || !styleResolver) return formatting;
|
|
436
|
+
return mergeTextFormatting(formatting.styleId ? styleResolver.getRunStyleOwnProperties(formatting.styleId) : void 0, formatting);
|
|
437
|
+
}
|
|
420
438
|
function resolveParagraphDefaultTextFormatting(styleId, formatting, styleResolver, options = {}) {
|
|
421
439
|
const style = styleId ? styleResolver.getStyle(styleId) ?? styleResolver.getDefaultParagraphStyle() : styleResolver.getDefaultParagraphStyle();
|
|
422
440
|
const paragraphStyleRpr = style?.type === "paragraph" ? style.rPr : void 0;
|
|
423
441
|
const rawParagraphMarkRpr = options.includeParagraphMarkRunProperties === false ? void 0 : formatting?.runProperties;
|
|
424
|
-
const
|
|
425
|
-
const
|
|
426
|
-
return mergeTextFormatting(
|
|
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);
|
|
427
445
|
}
|
|
428
446
|
function calculateRowSpans(table) {
|
|
429
447
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -549,6 +567,7 @@ function convertTable(table, styleResolver, theme) {
|
|
|
549
567
|
if (table.formatting?.look) attrs.look = table.formatting.look;
|
|
550
568
|
if (table.formatting?.borders) attrs.borders = table.formatting.borders;
|
|
551
569
|
if (table.formatting) attrs._originalFormatting = table.formatting;
|
|
570
|
+
if (table.propertyChanges && table.propertyChanges.length > 0) attrs.tblPrChange = [...table.propertyChanges];
|
|
552
571
|
const conditionalStyles = {};
|
|
553
572
|
const setCS = (key, type) => {
|
|
554
573
|
const val = resolveTableStyleConditional(styleResolver, conditionalTableStyleId, type);
|
|
@@ -607,6 +626,7 @@ function convertTableRow(row, styleResolver, isHeaderRow, columnWidths, totalWid
|
|
|
607
626
|
if (row.formatting?.heightRule) attrs.heightRule = row.formatting.heightRule;
|
|
608
627
|
if (row.formatting?.hidden) attrs.hidden = true;
|
|
609
628
|
if (row.formatting) attrs._originalFormatting = row.formatting;
|
|
629
|
+
if (row.propertyChanges && row.propertyChanges.length > 0) attrs.trPrChange = [...row.propertyChanges];
|
|
610
630
|
const numCells = row.cells.length;
|
|
611
631
|
const isFirstRow = rowIndex === 0;
|
|
612
632
|
const isLastRow = rowIndex === (totalRows ?? 1) - 1;
|
|
@@ -752,6 +772,7 @@ function convertTableCell(cell, styleResolver, isHeader, gridWidthPercent, condi
|
|
|
752
772
|
else if (conditionalStyle?.tcPr?.margins) attrs.margins = buildMarginsAttr(conditionalStyle.tcPr.margins);
|
|
753
773
|
else if (defaultCellMargins) attrs.margins = defaultCellMargins;
|
|
754
774
|
if (formatting) attrs._originalFormatting = formatting;
|
|
775
|
+
if (cell.propertyChanges && cell.propertyChanges.length > 0) attrs.tcPrChange = [...cell.propertyChanges];
|
|
755
776
|
if (preserveVMergeRestart) attrs._preserveVMergeRestart = true;
|
|
756
777
|
if (vMergeContinuationCells && vMergeContinuationCells.length > 0) attrs._docxVMergeContinuationCells = vMergeContinuationCells;
|
|
757
778
|
const contentNodes = [];
|
|
@@ -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 },
|
|
@@ -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
|
}
|
|
@@ -152,7 +152,8 @@ const tableSpec = {
|
|
|
152
152
|
cellMargins: { default: null },
|
|
153
153
|
look: { default: null },
|
|
154
154
|
borders: { default: null },
|
|
155
|
-
_originalFormatting: { default: null }
|
|
155
|
+
_originalFormatting: { default: null },
|
|
156
|
+
tblPrChange: { default: null }
|
|
156
157
|
},
|
|
157
158
|
parseDOM: [{
|
|
158
159
|
tag: "table",
|
|
@@ -171,17 +172,12 @@ const tableSpec = {
|
|
|
171
172
|
const domAttrs = { class: "docx-table" };
|
|
172
173
|
if (attrs.styleId) domAttrs["data-style-id"] = attrs.styleId;
|
|
173
174
|
const styles = ["border-collapse: collapse"];
|
|
174
|
-
if (attrs.width !== void 0 && attrs.widthType === "pct") {
|
|
175
|
-
|
|
176
|
-
styles.push("table-layout: fixed");
|
|
177
|
-
} else if (attrs.width !== void 0 && attrs.widthType === "dxa") {
|
|
175
|
+
if (attrs.width !== void 0 && attrs.widthType === "pct") styles.push(`width: ${attrs.width / 50}%`);
|
|
176
|
+
else if (attrs.width !== void 0 && attrs.widthType === "dxa") {
|
|
178
177
|
const widthPx = Math.round(attrs.width / 20 * 1.333);
|
|
179
178
|
styles.push(`width: ${widthPx}px`);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
styles.push("width: 100%");
|
|
183
|
-
styles.push("table-layout: fixed");
|
|
184
|
-
}
|
|
179
|
+
} else styles.push("width: 100%");
|
|
180
|
+
styles.push("table-layout: fixed");
|
|
185
181
|
if (attrs.justification === "center") styles.push("margin-left: auto", "margin-right: auto");
|
|
186
182
|
else if (attrs.justification === "right") styles.push("margin-left: auto");
|
|
187
183
|
domAttrs["style"] = styles.join("; ");
|
|
@@ -200,7 +196,8 @@ const tableRowSpec = {
|
|
|
200
196
|
heightRule: { default: null },
|
|
201
197
|
isHeader: { default: false },
|
|
202
198
|
hidden: { default: false },
|
|
203
|
-
_originalFormatting: { default: null }
|
|
199
|
+
_originalFormatting: { default: null },
|
|
200
|
+
trPrChange: { default: null }
|
|
204
201
|
},
|
|
205
202
|
parseDOM: [{ tag: "tr" }],
|
|
206
203
|
toDOM(node) {
|
|
@@ -317,6 +314,7 @@ const tableCellSpec = {
|
|
|
317
314
|
textDirection: { default: null },
|
|
318
315
|
noWrap: { default: false },
|
|
319
316
|
_originalFormatting: { default: null },
|
|
317
|
+
tcPrChange: { default: null },
|
|
320
318
|
_preserveVMergeRestart: { default: null },
|
|
321
319
|
_docxVMergeContinuationCells: { default: null }
|
|
322
320
|
},
|
|
@@ -369,6 +367,7 @@ const tableHeaderSpec = {
|
|
|
369
367
|
textDirection: { default: null },
|
|
370
368
|
noWrap: { default: false },
|
|
371
369
|
_originalFormatting: { default: null },
|
|
370
|
+
tcPrChange: { default: null },
|
|
372
371
|
_preserveVMergeRestart: { default: null },
|
|
373
372
|
_docxVMergeContinuationCells: { default: null }
|
|
374
373
|
},
|
|
@@ -44,7 +44,8 @@ function resolveFindMatchRange(doc, match) {
|
|
|
44
44
|
cellOffset += cell.nodeSize;
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
const cellPos = rowPos + 1 + cellOffset;
|
|
48
|
+
if (!walkBlocks(cell, cellPos + 1)) return false;
|
|
48
49
|
cellOffset += cell.nodeSize;
|
|
49
50
|
}
|
|
50
51
|
rowOffset += row.nodeSize;
|
|
@@ -18,7 +18,8 @@ type ParagraphAttrs = {
|
|
|
18
18
|
spaceAfter?: number;
|
|
19
19
|
lineSpacing?: number;
|
|
20
20
|
lineSpacingRule?: document_d_exports.LineSpacingRule;
|
|
21
|
-
spacingExplicit?: SpacingExplicit;
|
|
21
|
+
spacingExplicit?: SpacingExplicit; /** Layout provenance: document defaults survive on empty paragraphs. */
|
|
22
|
+
spacingFromDocDefaults?: SpacingExplicit;
|
|
22
23
|
indentLeft?: number;
|
|
23
24
|
indentRight?: number;
|
|
24
25
|
indentFirstLine?: number;
|
|
@@ -65,7 +66,8 @@ type ParagraphAttrs = {
|
|
|
65
66
|
* inline LISTNUM "(a)" with the deeper level's marker column.
|
|
66
67
|
*/
|
|
67
68
|
listMarkerSecondSlotOffsetTwips?: number; /** Number format for each level used by multi-level marker templates. */
|
|
68
|
-
listLevelNumFmts?: document_d_exports.NumberFormat[]; /**
|
|
69
|
+
listLevelNumFmts?: document_d_exports.NumberFormat[]; /** Initial counter for each level used by multi-level marker templates. */
|
|
70
|
+
listLevelStarts?: number[]; /** Abstract numbering ID shared by numbering instances. */
|
|
69
71
|
listAbstractNumId?: number; /** Numbering start override for this numId/level. */
|
|
70
72
|
listStartOverride?: number;
|
|
71
73
|
styleId?: string;
|
|
@@ -346,7 +348,8 @@ type TableAttrs = {
|
|
|
346
348
|
}; /** Table look flags for conditional formatting (w:tblLook) */
|
|
347
349
|
look?: document_d_exports.TableLook; /** Table-level borders (w:tblBorders) — full BorderSpec per side */
|
|
348
350
|
borders?: document_d_exports.TableBorders; /** Original table formatting from DOCX for lossless round-trip serialization */
|
|
349
|
-
_originalFormatting?: document_d_exports.TableFormatting;
|
|
351
|
+
_originalFormatting?: document_d_exports.TableFormatting; /** Tracked table property changes (w:tblPrChange) for round-trip + accept/reject */
|
|
352
|
+
tblPrChange?: document_d_exports.TablePropertyChange[];
|
|
350
353
|
};
|
|
351
354
|
/**
|
|
352
355
|
* Table row attributes
|
|
@@ -356,7 +359,8 @@ type TableRowAttrs = {
|
|
|
356
359
|
heightRule?: NonNullable<document_d_exports.TableRowFormatting["heightRule"]>; /** Is header row */
|
|
357
360
|
isHeader?: boolean; /** Whether the row is hidden (`w:hidden`) */
|
|
358
361
|
hidden?: boolean; /** Original row formatting from DOCX for lossless round-trip serialization */
|
|
359
|
-
_originalFormatting?: document_d_exports.TableRowFormatting;
|
|
362
|
+
_originalFormatting?: document_d_exports.TableRowFormatting; /** Tracked row property changes (w:trPrChange) for round-trip + accept/reject */
|
|
363
|
+
trPrChange?: document_d_exports.TableRowPropertyChange[];
|
|
360
364
|
};
|
|
361
365
|
/**
|
|
362
366
|
* Table cell attributes
|
|
@@ -383,7 +387,8 @@ type TableCellAttrs = {
|
|
|
383
387
|
left?: number;
|
|
384
388
|
right?: number;
|
|
385
389
|
}; /** Original cell formatting from DOCX for lossless round-trip serialization */
|
|
386
|
-
_originalFormatting?: document_d_exports.TableCellFormatting; /**
|
|
390
|
+
_originalFormatting?: document_d_exports.TableCellFormatting; /** Tracked cell property changes (w:tcPrChange) for round-trip + accept/reject */
|
|
391
|
+
tcPrChange?: document_d_exports.TableCellPropertyChange[]; /** Preserve a DOCX vMerge restart even when PM cannot model it as a rowspan. */
|
|
387
392
|
_preserveVMergeRestart?: boolean; /** Original DOCX vMerge continuation cells skipped into this PM rowspan. */
|
|
388
393
|
_docxVMergeContinuationCells?: document_d_exports.TableCell[];
|
|
389
394
|
};
|
|
@@ -91,6 +91,7 @@ function listAttrsFromResolvedStyle(resolved, numbering) {
|
|
|
91
91
|
listImplicitChildLevelAdvances: null,
|
|
92
92
|
listMarkerSecondSlotOffsetTwips: null,
|
|
93
93
|
listLevelNumFmts: rendering?.levelNumFmts ?? null,
|
|
94
|
+
listLevelStarts: rendering?.levelStarts ?? null,
|
|
94
95
|
listAbstractNumId: rendering?.abstractNumId ?? null,
|
|
95
96
|
listStartOverride: rendering?.startOverride ?? null
|
|
96
97
|
};
|