@stll/folio-core 0.22.1 → 0.22.3
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/headless.d.ts +6 -6
- package/dist/ai-edits/headless.js +2 -2
- package/dist/content-controls/errors.d.ts +17 -17
- package/dist/content-controls/errors.js +3 -3
- package/dist/controller/layoutPipeline.js +28 -0
- package/dist/document-operations.d.ts +6 -6
- package/dist/document-operations.js +2 -2
- package/dist/docx/encryption/errors.d.ts +3 -3
- package/dist/docx/encryption/errors.js +1 -1
- package/dist/docx/ensureParaIds.d.ts +4 -4
- package/dist/docx/ensureParaIds.js +1 -1
- package/dist/docx/imageParser.js +6 -9
- package/dist/docx/metadataPrivacy.d.ts +6 -6
- package/dist/docx/metadataPrivacy.js +2 -2
- package/dist/docx/parser.d.ts +5 -5
- package/dist/docx/parser.js +1 -1
- package/dist/docx/server/applyDocxXmlPatchProposal.d.ts +6 -6
- package/dist/docx/server/applyDocxXmlPatchProposal.js +2 -2
- package/dist/docx/server/boundedArchive.d.ts +4 -4
- package/dist/docx/server/boundedArchive.js +1 -1
- package/dist/docx/server/build.d.ts +5 -5
- package/dist/docx/server/build.js +1 -1
- package/dist/docx/server/createBilingualDocument.d.ts +3 -3
- package/dist/docx/server/createBilingualDocument.js +1 -1
- package/dist/docx/server/evaluateDocxXmlPatchProposal.d.ts +6 -6
- package/dist/docx/server/evaluateDocxXmlPatchProposal.js +2 -2
- package/dist/docx/server/inspectDocxPackage.d.ts +3 -3
- package/dist/docx/server/inspectDocxPackage.js +9 -8
- package/dist/docx/styleParser.js +16 -16
- package/dist/docx/xmlParser.d.ts +7 -3
- package/dist/docx/xmlParser.js +20 -7
- package/dist/docx/xmlResourceLimits.d.ts +4 -4
- package/dist/docx/xmlResourceLimits.js +1 -1
- package/dist/layout-engine/measure/font-metrics.worker.js +1 -1
- package/dist/layout-engine/measure/measureHelpers.d.ts +2 -1
- package/dist/layout-engine/measure/measureHelpers.js +5 -2
- package/dist/layout-engine/types.d.ts +6 -0
- package/dist/layout-painter/anchoredImagePosition.d.ts +2 -1
- package/dist/layout-painter/anchoredImagePosition.js +14 -6
- package/dist/layout-painter/renderPage.js +11 -1
- package/dist/layout-painter/renderParagraph.js +3 -4
- package/dist/prosemirror/attrs/index.js +6 -5
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.js +1 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +13 -3
- package/dist/prosemirror/conversion/toProseDoc.js +1 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +30 -3
- package/dist/prosemirror/extensions/marks/UnderlineExtension.js +9 -7
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +92 -16
- package/dist/prosemirror/plugins/selectionTracker.js +10 -5
- package/dist/prosemirror/schema/nodes.d.ts +1 -0
- package/dist/prosemirror/selectionMarks.d.ts +11 -0
- package/dist/prosemirror/selectionMarks.js +19 -0
- package/dist/prosemirror/selectionState.js +8 -20
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/redline.d.ts +4 -4
- package/dist/redline.js +1 -1
- package/dist/utils/formatToStyle.js +1 -1
- package/dist/version-comparison.d.ts +3 -3
- package/dist/version-comparison.js +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
import { FONT_THEME_VALUES } from "../../../types/documentEnumValues.js";
|
|
2
|
+
import { mergeFontFamily } from "../../../utils/fontFamilyMerge.js";
|
|
3
|
+
import { expectFontFamilyMarkAttrs } from "../../attrs/index.js";
|
|
1
4
|
import { applyRunFormattingOverrideMark, buildRunFormattingOverrideAttrs } from "./RunFormattingOverrideExtension.js";
|
|
2
5
|
//#region src/prosemirror/extensions/marks/markUtils.ts
|
|
6
|
+
const isFontTheme = (value) => value !== void 0 && FONT_THEME_VALUES.some((theme) => theme === value);
|
|
7
|
+
const fontFamilyAttrsToFormatting = ({ ascii, hAnsi, eastAsia, cs, hint, asciiTheme, hAnsiTheme, eastAsiaTheme, csTheme }) => ({
|
|
8
|
+
...ascii !== void 0 ? { ascii } : {},
|
|
9
|
+
...hAnsi !== void 0 ? { hAnsi } : {},
|
|
10
|
+
...eastAsia !== void 0 ? { eastAsia } : {},
|
|
11
|
+
...cs !== void 0 ? { cs } : {},
|
|
12
|
+
...hint !== void 0 ? { hint } : {},
|
|
13
|
+
...isFontTheme(asciiTheme) ? { asciiTheme } : {},
|
|
14
|
+
...hAnsiTheme !== void 0 ? { hAnsiTheme } : {},
|
|
15
|
+
...eastAsiaTheme !== void 0 ? { eastAsiaTheme } : {},
|
|
16
|
+
...csTheme !== void 0 ? { csTheme } : {}
|
|
17
|
+
});
|
|
3
18
|
function marksToTextFormatting(marks) {
|
|
4
19
|
const formatting = {};
|
|
5
20
|
for (const mark of marks) switch (mark.type.name) {
|
|
@@ -10,7 +25,10 @@ function marksToTextFormatting(marks) {
|
|
|
10
25
|
formatting.italic = true;
|
|
11
26
|
break;
|
|
12
27
|
case "underline":
|
|
13
|
-
formatting.underline = {
|
|
28
|
+
formatting.underline = {
|
|
29
|
+
style: typeof mark.attrs["style"] === "string" ? mark.attrs["style"] : "single",
|
|
30
|
+
...mark.attrs["color"] !== null && mark.attrs["color"] !== void 0 ? { color: mark.attrs["color"] } : {}
|
|
31
|
+
};
|
|
14
32
|
break;
|
|
15
33
|
case "strike":
|
|
16
34
|
formatting.strike = true;
|
|
@@ -34,17 +52,9 @@ function marksToTextFormatting(marks) {
|
|
|
34
52
|
case "fontSize":
|
|
35
53
|
formatting.fontSize = Number(mark.attrs["size"]);
|
|
36
54
|
break;
|
|
37
|
-
case "fontFamily":
|
|
38
|
-
|
|
39
|
-
const hAnsi = mark.attrs["hAnsi"] !== null && mark.attrs["hAnsi"] !== void 0 ? String(mark.attrs["hAnsi"]) : void 0;
|
|
40
|
-
const hint = mark.attrs["hint"];
|
|
41
|
-
formatting.fontFamily = {
|
|
42
|
-
...ascii !== void 0 ? { ascii } : {},
|
|
43
|
-
...hAnsi !== void 0 ? { hAnsi } : {},
|
|
44
|
-
...hint === "default" || hint === "eastAsia" || hint === "cs" ? { hint } : {}
|
|
45
|
-
};
|
|
55
|
+
case "fontFamily":
|
|
56
|
+
formatting.fontFamily = fontFamilyAttrsToFormatting(expectFontFamilyMarkAttrs(mark));
|
|
46
57
|
break;
|
|
47
|
-
}
|
|
48
58
|
case "language": {
|
|
49
59
|
const val = mark.attrs["val"];
|
|
50
60
|
const eastAsia = mark.attrs["eastAsia"];
|
|
@@ -93,21 +103,82 @@ function dispatchStoredMarks(state, dispatch, marks) {
|
|
|
93
103
|
tr.setStoredMarks(marks);
|
|
94
104
|
dispatch(tr);
|
|
95
105
|
}
|
|
106
|
+
function compactAttrs(attrs) {
|
|
107
|
+
if (!attrs) return {};
|
|
108
|
+
const result = {};
|
|
109
|
+
for (const [key, value] of Object.entries(attrs)) if (value !== null && value !== void 0) result[key] = value;
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
function mergeMarkAttrs(markType, currentMark, nextAttrs) {
|
|
113
|
+
const next = compactAttrs(nextAttrs);
|
|
114
|
+
switch (markType.name) {
|
|
115
|
+
case "fontFamily": return mergeFontFamily(currentMark ? fontFamilyAttrsToFormatting(expectFontFamilyMarkAttrs(currentMark)) : void 0, fontFamilyAttrsToFormatting(expectFontFamilyMarkAttrs(markType.create(next))));
|
|
116
|
+
case "underline": return {
|
|
117
|
+
...compactAttrs(currentMark?.attrs),
|
|
118
|
+
...next
|
|
119
|
+
};
|
|
120
|
+
default: return nextAttrs;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function markRequiresAttrMerge(markType) {
|
|
124
|
+
return markType.name === "fontFamily" || markType.name === "underline";
|
|
125
|
+
}
|
|
126
|
+
function createMarkWithMergedAttrs(markType, currentMark, nextAttrs) {
|
|
127
|
+
if (!markRequiresAttrMerge(markType)) return markType.create(nextAttrs);
|
|
128
|
+
return markType.create(mergeMarkAttrs(markType, currentMark, nextAttrs));
|
|
129
|
+
}
|
|
96
130
|
function setMark(markType, attrs) {
|
|
97
131
|
return (state, dispatch) => {
|
|
98
132
|
const { from, to, empty } = state.selection;
|
|
99
|
-
const mark = markType.create(attrs);
|
|
100
133
|
if (empty) {
|
|
101
134
|
if (dispatch) {
|
|
102
135
|
const current = state.storedMarks ?? state.selection.$from.marks();
|
|
103
|
-
|
|
136
|
+
const currentMark = markType.isInSet(current);
|
|
137
|
+
const marks = markType.isInSet(current) ? current.filter((m) => m.type !== markType) : current;
|
|
138
|
+
const mark = createMarkWithMergedAttrs(markType, currentMark, attrs);
|
|
139
|
+
dispatchStoredMarks(state, dispatch, [...marks, mark]);
|
|
104
140
|
}
|
|
105
141
|
return true;
|
|
106
142
|
}
|
|
107
|
-
if (dispatch)
|
|
143
|
+
if (dispatch) {
|
|
144
|
+
if (!markRequiresAttrMerge(markType)) {
|
|
145
|
+
dispatch(state.tr.addMark(from, to, markType.create(attrs)).scrollIntoView());
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
let tr = state.tr;
|
|
149
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
150
|
+
if (!node.isText) return;
|
|
151
|
+
const start = Math.max(from, pos);
|
|
152
|
+
const end = Math.min(to, pos + node.nodeSize);
|
|
153
|
+
const mark = createMarkWithMergedAttrs(markType, markType.isInSet(node.marks), attrs);
|
|
154
|
+
tr = tr.addMark(start, end, mark);
|
|
155
|
+
});
|
|
156
|
+
dispatch(tr.scrollIntoView());
|
|
157
|
+
}
|
|
108
158
|
return true;
|
|
109
159
|
};
|
|
110
160
|
}
|
|
161
|
+
function selectionHasVisibleUnderline(state, markType) {
|
|
162
|
+
const { from, to, empty, $from } = state.selection;
|
|
163
|
+
if (empty) {
|
|
164
|
+
const mark = markType.isInSet(state.storedMarks ?? $from.marks());
|
|
165
|
+
return mark !== void 0 && mark.attrs["style"] !== "none";
|
|
166
|
+
}
|
|
167
|
+
let hasVisibleUnderline = false;
|
|
168
|
+
state.doc.nodesBetween(from, to, (node) => {
|
|
169
|
+
if (!node.isText) return true;
|
|
170
|
+
const mark = markType.isInSet(node.marks);
|
|
171
|
+
if (mark && mark.attrs["style"] !== "none") {
|
|
172
|
+
hasVisibleUnderline = true;
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
return true;
|
|
176
|
+
});
|
|
177
|
+
return hasVisibleUnderline;
|
|
178
|
+
}
|
|
179
|
+
function toggleUnderlineMark(markType) {
|
|
180
|
+
return (state, dispatch) => setMark(markType, { style: selectionHasVisibleUnderline(state, markType) ? "none" : "single" })(state, dispatch);
|
|
181
|
+
}
|
|
111
182
|
function removeMark(markType) {
|
|
112
183
|
return (state, dispatch) => {
|
|
113
184
|
const { from, to, empty } = state.selection;
|
|
@@ -197,8 +268,13 @@ function textFormattingToMarks(formatting, schema) {
|
|
|
197
268
|
if (formatting.fontFamily && schema.marks["fontFamily"]) marks.push(schema.marks["fontFamily"].create({
|
|
198
269
|
ascii: formatting.fontFamily.ascii,
|
|
199
270
|
hAnsi: formatting.fontFamily.hAnsi,
|
|
271
|
+
eastAsia: formatting.fontFamily.eastAsia,
|
|
272
|
+
cs: formatting.fontFamily.cs,
|
|
200
273
|
hint: formatting.fontFamily.hint,
|
|
201
|
-
asciiTheme: formatting.fontFamily.asciiTheme
|
|
274
|
+
asciiTheme: formatting.fontFamily.asciiTheme,
|
|
275
|
+
hAnsiTheme: formatting.fontFamily.hAnsiTheme,
|
|
276
|
+
eastAsiaTheme: formatting.fontFamily.eastAsiaTheme,
|
|
277
|
+
csTheme: formatting.fontFamily.csTheme
|
|
202
278
|
}));
|
|
203
279
|
if (formatting.language && schema.marks["language"]) marks.push(schema.marks["language"].create(formatting.language));
|
|
204
280
|
if (formatting.vertAlign === "superscript" && schema.marks["superscript"]) marks.push(schema.marks["superscript"].create());
|
|
@@ -245,4 +321,4 @@ function createRemoveMarkCommand(markType) {
|
|
|
245
321
|
return removeMark(markType);
|
|
246
322
|
}
|
|
247
323
|
//#endregion
|
|
248
|
-
export { clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, removeMark, setMark, textFormattingToMarks };
|
|
324
|
+
export { clearFormatting, createRemoveMarkCommand, createSetMarkCommand, getMarkAttr, isMarkActive, removeMark, setMark, textFormattingToMarks, toggleUnderlineMark };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { collectMarksInRange } from "../selectionMarks.js";
|
|
1
2
|
import { Plugin, PluginKey } from "prosemirror-state";
|
|
2
3
|
//#region src/prosemirror/plugins/selectionTracker.ts
|
|
3
4
|
/**
|
|
@@ -32,7 +33,7 @@ function extractSelectionContext(state) {
|
|
|
32
33
|
const paragraphFormatting = {};
|
|
33
34
|
if (paragraph.type.name === "paragraph") {
|
|
34
35
|
if (paragraph.attrs["alignment"]) paragraphFormatting.alignment = paragraph.attrs["alignment"];
|
|
35
|
-
if (paragraph.attrs["lineSpacing"]) {
|
|
36
|
+
if (typeof paragraph.attrs["lineSpacing"] === "number") {
|
|
36
37
|
paragraphFormatting.lineSpacing = paragraph.attrs["lineSpacing"];
|
|
37
38
|
paragraphFormatting.lineSpacingRule = paragraph.attrs["lineSpacingRule"];
|
|
38
39
|
}
|
|
@@ -79,9 +80,13 @@ function extractSelectionContext(state) {
|
|
|
79
80
|
* Extract text formatting from current selection/cursor marks
|
|
80
81
|
*/
|
|
81
82
|
function extractTextFormatting(state) {
|
|
82
|
-
const { selection } = state;
|
|
83
|
-
const { empty, $from } = selection;
|
|
84
|
-
const marks = state.storedMarks ||
|
|
83
|
+
const { selection, doc } = state;
|
|
84
|
+
const { from, to, empty, $from } = selection;
|
|
85
|
+
const marks = empty ? state.storedMarks || $from.marks() : collectMarksInRange({
|
|
86
|
+
doc,
|
|
87
|
+
from,
|
|
88
|
+
to
|
|
89
|
+
});
|
|
85
90
|
const formatting = {};
|
|
86
91
|
for (const mark of marks) switch (mark.type.name) {
|
|
87
92
|
case "bold":
|
|
@@ -91,7 +96,7 @@ function extractTextFormatting(state) {
|
|
|
91
96
|
formatting.italic = true;
|
|
92
97
|
break;
|
|
93
98
|
case "underline":
|
|
94
|
-
formatting.underline = {
|
|
99
|
+
if (mark.attrs["style"] !== "none") formatting.underline = {
|
|
95
100
|
style: mark.attrs["style"] || "single",
|
|
96
101
|
color: mark.attrs["color"]
|
|
97
102
|
};
|
|
@@ -32,6 +32,7 @@ type ParagraphAttrs = {
|
|
|
32
32
|
spaceAfter?: number;
|
|
33
33
|
lineSpacing?: number;
|
|
34
34
|
lineSpacingRule?: document_d_exports.LineSpacingRule;
|
|
35
|
+
lineSpacingExplicit?: boolean;
|
|
35
36
|
snapToGrid?: boolean;
|
|
36
37
|
spacingExplicit?: SpacingExplicit;
|
|
37
38
|
/** Layout provenance: document defaults survive on empty paragraphs. */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Mark, Node } from "prosemirror-model";
|
|
2
|
+
//#region src/prosemirror/selectionMarks.d.ts
|
|
3
|
+
type CollectMarksInRangeOptions = {
|
|
4
|
+
doc: Node;
|
|
5
|
+
from: number;
|
|
6
|
+
to: number;
|
|
7
|
+
};
|
|
8
|
+
/** Collect one representative per mark type, preferring visible underline state. */
|
|
9
|
+
declare const collectMarksInRange: ({ doc, from, to }: CollectMarksInRangeOptions) => Mark[];
|
|
10
|
+
//#endregion
|
|
11
|
+
export { collectMarksInRange };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/prosemirror/selectionMarks.ts
|
|
2
|
+
const UNDERLINE_MARK = "underline";
|
|
3
|
+
const HIDDEN_UNDERLINE_STYLE = "none";
|
|
4
|
+
const shouldReplaceMark = (current, incoming) => current.type.name === UNDERLINE_MARK && current.attrs["style"] === HIDDEN_UNDERLINE_STYLE && incoming.attrs["style"] !== HIDDEN_UNDERLINE_STYLE;
|
|
5
|
+
/** Collect one representative per mark type, preferring visible underline state. */
|
|
6
|
+
const collectMarksInRange = ({ doc, from, to }) => {
|
|
7
|
+
const seen = /* @__PURE__ */ new Map();
|
|
8
|
+
doc.nodesBetween(from, to, (node) => {
|
|
9
|
+
if (!node.isText) return;
|
|
10
|
+
for (const mark of node.marks) {
|
|
11
|
+
const name = mark.type.name;
|
|
12
|
+
const current = seen.get(name);
|
|
13
|
+
if (!current || shouldReplaceMark(current, mark)) seen.set(name, mark);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
return Array.from(seen.values());
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { collectMarksInRange };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { directionIsRtl } from "./paragraphDirection.js";
|
|
2
|
+
import { collectMarksInRange } from "./selectionMarks.js";
|
|
2
3
|
//#region src/prosemirror/selectionState.ts
|
|
3
4
|
/**
|
|
4
5
|
* Extract selection state from editor state.
|
|
@@ -18,7 +19,11 @@ function extractSelectionState(state) {
|
|
|
18
19
|
const paragraph = $from.parent;
|
|
19
20
|
const isEmptyParagraph = paragraph.type.name === "paragraph" && paragraph.textContent.length === 0;
|
|
20
21
|
const paragraphDefaultFormatting = paragraph.attrs["defaultTextFormatting"];
|
|
21
|
-
const marks = empty ? state.storedMarks || selection.$from.marks() : collectMarksInRange(
|
|
22
|
+
const marks = empty ? state.storedMarks || selection.$from.marks() : collectMarksInRange({
|
|
23
|
+
doc,
|
|
24
|
+
from,
|
|
25
|
+
to
|
|
26
|
+
});
|
|
22
27
|
if (isEmptyParagraph && marks.length === 0 && paragraphDefaultFormatting) textFormatting = { ...paragraphDefaultFormatting };
|
|
23
28
|
for (const mark of marks) switch (mark.type.name) {
|
|
24
29
|
case "bold":
|
|
@@ -28,7 +33,7 @@ function extractSelectionState(state) {
|
|
|
28
33
|
textFormatting.italic = true;
|
|
29
34
|
break;
|
|
30
35
|
case "underline":
|
|
31
|
-
textFormatting.underline = {
|
|
36
|
+
if (mark.attrs["style"] !== "none") textFormatting.underline = {
|
|
32
37
|
style: mark.attrs["style"] || "single",
|
|
33
38
|
color: mark.attrs["color"]
|
|
34
39
|
};
|
|
@@ -67,7 +72,7 @@ function extractSelectionState(state) {
|
|
|
67
72
|
let styleId = null;
|
|
68
73
|
if (paragraph.type.name === "paragraph") {
|
|
69
74
|
if (paragraph.attrs["alignment"]) paragraphFormatting.alignment = paragraph.attrs["alignment"];
|
|
70
|
-
if (paragraph.attrs["lineSpacing"]) {
|
|
75
|
+
if (typeof paragraph.attrs["lineSpacing"] === "number") {
|
|
71
76
|
paragraphFormatting.lineSpacing = paragraph.attrs["lineSpacing"];
|
|
72
77
|
paragraphFormatting.lineSpacingRule = paragraph.attrs["lineSpacingRule"];
|
|
73
78
|
}
|
|
@@ -91,22 +96,5 @@ function extractSelectionState(state) {
|
|
|
91
96
|
endParagraphIndex
|
|
92
97
|
};
|
|
93
98
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Collect the first occurrence of each mark type found on any text node within
|
|
96
|
-
* the range. Mirrors the "any inline child has this mark" semantics that
|
|
97
|
-
* prosemirror-commands' toggleMark uses to decide add-vs-remove, so the
|
|
98
|
-
* toolbar's active state stays consistent with what a toggle click will do.
|
|
99
|
-
*/
|
|
100
|
-
function collectMarksInRange(doc, from, to) {
|
|
101
|
-
const seen = /* @__PURE__ */ new Map();
|
|
102
|
-
doc.nodesBetween(from, to, (node) => {
|
|
103
|
-
if (!node.isText) return;
|
|
104
|
-
for (const mark of node.marks) {
|
|
105
|
-
const name = mark.type.name;
|
|
106
|
-
if (!seen.has(name)) seen.set(name, mark);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
return Array.from(seen.values());
|
|
110
|
-
}
|
|
111
99
|
//#endregion
|
|
112
100
|
export { extractSelectionState };
|
|
@@ -27,6 +27,7 @@ function paragraphAttrsFromResolvedStyle(resolved) {
|
|
|
27
27
|
spaceAfter: ppr?.spaceAfter ?? null,
|
|
28
28
|
lineSpacing: ppr?.lineSpacing ?? null,
|
|
29
29
|
lineSpacingRule: ppr?.lineSpacingRule ?? null,
|
|
30
|
+
lineSpacingExplicit: null,
|
|
30
31
|
snapToGrid: ppr?.snapToGrid ?? null,
|
|
31
32
|
indentLeft: ppr?.indentLeft ?? null,
|
|
32
33
|
indentRight: ppr?.indentRight ?? null,
|
package/dist/redline.d.ts
CHANGED
|
@@ -13,13 +13,13 @@ type GenerateRedlineDocxOptions = {
|
|
|
13
13
|
/** Optional output-only package-metadata privacy transforms. */
|
|
14
14
|
privacy?: FolioDocumentPrivacyOptions;
|
|
15
15
|
};
|
|
16
|
-
declare const InvalidGenerateRedlineDocxOptionsError_base: import("better-result").TaggedErrorClass<"InvalidGenerateRedlineDocxOptionsError"
|
|
16
|
+
declare const InvalidGenerateRedlineDocxOptionsError_base: import("better-result").TaggedErrorClass<"InvalidGenerateRedlineDocxOptionsError">;
|
|
17
|
+
/** Raised when a resolved input view is not `"original"` or `"final"`. */
|
|
18
|
+
declare class InvalidGenerateRedlineDocxOptionsError extends InvalidGenerateRedlineDocxOptionsError_base<{
|
|
17
19
|
message: string;
|
|
18
20
|
option: "baseView" | "revisedView";
|
|
19
21
|
receivedValue: unknown;
|
|
20
|
-
}
|
|
21
|
-
/** Raised when a resolved input view is not `"original"` or `"final"`. */
|
|
22
|
-
declare class InvalidGenerateRedlineDocxOptionsError extends InvalidGenerateRedlineDocxOptionsError_base {}
|
|
22
|
+
}> {}
|
|
23
23
|
/** A document story that could not be paired across the two input packages. */
|
|
24
24
|
type GenerateRedlineUnprocessedStory = {
|
|
25
25
|
/** Story in the base package, or `null` when it exists only in the revision. */
|
package/dist/redline.js
CHANGED
|
@@ -18,7 +18,7 @@ import { TaggedError, panic } from "better-result";
|
|
|
18
18
|
* @packageDocumentation
|
|
19
19
|
*/
|
|
20
20
|
/** Raised when a resolved input view is not `"original"` or `"final"`. */
|
|
21
|
-
var InvalidGenerateRedlineDocxOptionsError = class extends TaggedError("InvalidGenerateRedlineDocxOptionsError")
|
|
21
|
+
var InvalidGenerateRedlineDocxOptionsError = class extends TaggedError("InvalidGenerateRedlineDocxOptionsError") {};
|
|
22
22
|
const nextBaseBlockIdByIndex = (events) => {
|
|
23
23
|
const nextIds = Array.from({ length: events.length });
|
|
24
24
|
let nextId = null;
|
|
@@ -108,7 +108,7 @@ function paragraphToStyle(formatting, theme) {
|
|
|
108
108
|
}
|
|
109
109
|
if (formatting.indentLeft !== void 0) style.marginLeft = formatPx(twipsToPixels(formatting.indentLeft));
|
|
110
110
|
if (formatting.indentRight !== void 0) style.marginRight = formatPx(twipsToPixels(formatting.indentRight));
|
|
111
|
-
if (formatting.indentFirstLine !== void 0) style.textIndent = formatPx(twipsToPixels(formatting.indentFirstLine));
|
|
111
|
+
if (formatting.indentFirstLine !== void 0) style.textIndent = formatPx(twipsToPixels(formatting.hangingIndent ? -Math.abs(formatting.indentFirstLine) : formatting.indentFirstLine));
|
|
112
112
|
if (formatting.borders) {
|
|
113
113
|
if (formatting.borders.top) Object.assign(style, borderToStyle(formatting.borders.top, "Top", theme));
|
|
114
114
|
if (formatting.borders.bottom) Object.assign(style, borderToStyle(formatting.borders.bottom, "Bottom", theme));
|
|
@@ -15,12 +15,12 @@ type FolioCompareDocxVersionsOptions = {
|
|
|
15
15
|
/** Optional output-only privacy transforms. Source buffers are never mutated. */
|
|
16
16
|
privacy?: FolioVersionDiffPrivacyOptions;
|
|
17
17
|
};
|
|
18
|
-
declare const InvalidFolioVersionComparisonOptionsError_base: import("better-result").TaggedErrorClass<"InvalidFolioVersionComparisonOptionsError"
|
|
18
|
+
declare const InvalidFolioVersionComparisonOptionsError_base: import("better-result").TaggedErrorClass<"InvalidFolioVersionComparisonOptionsError">;
|
|
19
|
+
declare class InvalidFolioVersionComparisonOptionsError extends InvalidFolioVersionComparisonOptionsError_base<{
|
|
19
20
|
message: string;
|
|
20
21
|
option: "include" | "privacy.transforms";
|
|
21
22
|
receivedValue: unknown;
|
|
22
|
-
}
|
|
23
|
-
declare class InvalidFolioVersionComparisonOptionsError extends InvalidFolioVersionComparisonOptionsError_base {}
|
|
23
|
+
}> {}
|
|
24
24
|
type FolioDocumentMetadataValue = string | number | null;
|
|
25
25
|
type FolioMetadataDiff = {
|
|
26
26
|
property: FolioDocumentMetadataProperty;
|
|
@@ -86,7 +86,7 @@ const FOLIO_VERSION_COMPARISON_SCOPES = Object.freeze([
|
|
|
86
86
|
"metadata"
|
|
87
87
|
]);
|
|
88
88
|
const isFolioVersionComparisonScope = (value) => FOLIO_VERSION_COMPARISON_SCOPES.some((scope) => scope === value);
|
|
89
|
-
var InvalidFolioVersionComparisonOptionsError = class extends TaggedError("InvalidFolioVersionComparisonOptionsError")
|
|
89
|
+
var InvalidFolioVersionComparisonOptionsError = class extends TaggedError("InvalidFolioVersionComparisonOptionsError") {};
|
|
90
90
|
const FOLIO_VERSION_COMPARISON_PRIVACY_TRANSFORMS = FOLIO_DOCUMENT_PRIVACY_TRANSFORMS;
|
|
91
91
|
const isFolioVersionComparisonPrivacyTransform = (value) => isFolioDocumentPrivacyTransform(value);
|
|
92
92
|
/** Run-level formatting properties compared for `formatChanged` detection. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.3",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|
|
@@ -113,10 +113,10 @@
|
|
|
113
113
|
"perf": "bun scripts/profile-editor.ts"
|
|
114
114
|
},
|
|
115
115
|
"dependencies": {
|
|
116
|
-
"@stll/docx-core": "^0.15.
|
|
116
|
+
"@stll/docx-core": "^0.15.1",
|
|
117
117
|
"@stll/docx-utils": "^0.1.0",
|
|
118
118
|
"@stll/template-conditions": "^0.1.0",
|
|
119
|
-
"better-result": "
|
|
119
|
+
"better-result": "3.0.1",
|
|
120
120
|
"csstype": "^3.1.3",
|
|
121
121
|
"dompurify": "^3.4.13",
|
|
122
122
|
"fast-xml-parser": "^5.9.3",
|