@stll/folio-core 0.37.3 → 0.37.4
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/prosemirror/attrs/index.js +13 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +20 -4
- package/dist/prosemirror/conversion/toProseDoc.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -63
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +9 -0
- package/dist/prosemirror/schema/nodes.d.ts +11 -1
- package/dist/prosemirror/schema/nodes.js +7 -0
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { EMPHASIS_MARK_VALUES, FIELD_TYPE_VALUES, FONT_HINT_VALUES, FONT_THEME_V
|
|
|
2
2
|
import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
|
|
3
3
|
import { isParagraphDirection } from "../paragraphDirection.js";
|
|
4
4
|
import { COMPLEX_SCRIPT_RUN_PROPERTY_KEYS, RUN_FORMATTING_BOOLEAN_PROPERTIES, RUN_FORMATTING_VALUE_PROPERTIES, TRACKED_CHANGE_PROVENANCE_VALUES } from "../schema/marks.js";
|
|
5
|
+
import { TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES } from "../schema/nodes.js";
|
|
5
6
|
import { panic } from "better-result";
|
|
6
7
|
import { DRAWING_RAW_XML_MODES, isOoxmlSymbolCharacter } from "@stll/docx-core/model";
|
|
7
8
|
//#region src/prosemirror/attrs/index.ts
|
|
@@ -540,6 +541,7 @@ const readTextBoxAttrs = (node) => {
|
|
|
540
541
|
optionalOneOf(attrs, "_docxPlacement", "textBox.attrs._docxPlacement", issues, TEXT_BOX_DOCX_PLACEMENTS);
|
|
541
542
|
optionalString(attrs, "_docxGroupId", "textBox.attrs._docxGroupId", issues);
|
|
542
543
|
optionalString(attrs, "_docxAnchorId", "textBox.attrs._docxAnchorId", issues);
|
|
544
|
+
requiredTextBoxBodyContentState(attrs, issues);
|
|
543
545
|
optionalTextBoxTrackedChange(attrs, issues);
|
|
544
546
|
optionalTextBoxInlineSdts(attrs, issues);
|
|
545
547
|
return attrsResult(attrs, issues);
|
|
@@ -1203,6 +1205,17 @@ const optionalTextBoxTrackedChange = (attrs, issues) => {
|
|
|
1203
1205
|
requiredString(info, "author", "textBox.attrs._docxTrackedChange.info.author", issues);
|
|
1204
1206
|
optionalString(info, "date", "textBox.attrs._docxTrackedChange.info.date", issues);
|
|
1205
1207
|
};
|
|
1208
|
+
const requiredTextBoxBodyContentState = (attrs, issues) => {
|
|
1209
|
+
const value = attrs["_docxTextBodyContentState"];
|
|
1210
|
+
if (!isRecord(value)) {
|
|
1211
|
+
issues.push({
|
|
1212
|
+
path: "textBox.attrs._docxTextBodyContentState",
|
|
1213
|
+
message: "Expected an object."
|
|
1214
|
+
});
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1217
|
+
requiredOneOf(value, "type", "textBox.attrs._docxTextBodyContentState.type", issues, TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES);
|
|
1218
|
+
};
|
|
1206
1219
|
const optionalTextBoxInlineSdts = (attrs, issues) => {
|
|
1207
1220
|
const value = attrs["_docxInlineSdts"];
|
|
1208
1221
|
if (value === void 0 || value === null) return;
|
|
@@ -2862,6 +2862,24 @@ function tableCellAttrsToFormatting(attrs) {
|
|
|
2862
2862
|
if (attrs.margins) f.margins = buildCellMarginsFromAttrs(attrs.margins);
|
|
2863
2863
|
return f;
|
|
2864
2864
|
}
|
|
2865
|
+
const isUnchangedSourceEmptyPlaceholder = (blocks) => {
|
|
2866
|
+
const paragraph = blocks.at(0);
|
|
2867
|
+
if (blocks.length !== 1 || paragraph?.type !== "paragraph" || paragraph.content.length !== 0) return false;
|
|
2868
|
+
return Object.keys(paragraph).every((key) => key === "type" || key === "content" || key === "paraId" || key === "textId");
|
|
2869
|
+
};
|
|
2870
|
+
const projectTextBoxBodyContent = (state, blocks) => {
|
|
2871
|
+
switch (state.type) {
|
|
2872
|
+
case "source-empty": return isUnchangedSourceEmptyPlaceholder(blocks) ? { type: "source-empty" } : {
|
|
2873
|
+
type: "authored",
|
|
2874
|
+
content: blocks
|
|
2875
|
+
};
|
|
2876
|
+
case "authored": return {
|
|
2877
|
+
type: "authored",
|
|
2878
|
+
content: blocks
|
|
2879
|
+
};
|
|
2880
|
+
default: return state;
|
|
2881
|
+
}
|
|
2882
|
+
};
|
|
2865
2883
|
/**
|
|
2866
2884
|
* Convert a ProseMirror textBox node back to a Paragraph wrapping a ShapeContent run.
|
|
2867
2885
|
* The text box content becomes a Shape with textBody.
|
|
@@ -2874,6 +2892,7 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
2874
2892
|
if (child.type.name === "paragraph") childBlocks.push(convertPMParagraph(child, void 0, void 0, styleResolver));
|
|
2875
2893
|
else if (child.type.name === "table") childBlocks.push(convertPMTable(child, void 0, styleResolver));
|
|
2876
2894
|
});
|
|
2895
|
+
const textBodyContent = projectTextBoxBodyContent(attrs._docxTextBodyContentState, childBlocks);
|
|
2877
2896
|
const shape = {
|
|
2878
2897
|
type: "shape",
|
|
2879
2898
|
shapeType: "textBox",
|
|
@@ -2882,10 +2901,7 @@ function convertPMTextBox(node, styleResolver = null) {
|
|
|
2882
2901
|
height: attrs.height ? pixelsToEmu(attrs.height) : 0
|
|
2883
2902
|
},
|
|
2884
2903
|
textBody: {
|
|
2885
|
-
content:
|
|
2886
|
-
type: "paragraph",
|
|
2887
|
-
content: []
|
|
2888
|
-
}],
|
|
2904
|
+
content: textBodyContent.type === "source-empty" ? [] : textBodyContent.content,
|
|
2889
2905
|
...attrs.autoFit !== void 0 ? { autoFit: attrs.autoFit } : {},
|
|
2890
2906
|
...attrs.textWrap !== void 0 ? { textWrap: attrs.textWrap } : {},
|
|
2891
2907
|
...verticalAlign !== void 0 ? { anchor: verticalAlign } : {},
|
|
@@ -2259,6 +2259,7 @@ function convertTextBox(textBox, styleResolver, options) {
|
|
|
2259
2259
|
_docxPlacement: options.placement,
|
|
2260
2260
|
_docxGroupId: options.groupId,
|
|
2261
2261
|
_docxAnchorId: options.anchorId,
|
|
2262
|
+
_docxTextBodyContentState: textBox.content.length === 0 ? { type: "source-empty" } : { type: "authored" },
|
|
2262
2263
|
_docxTrackedChange: options.trackedChange,
|
|
2263
2264
|
_docxInlineSdts: options.inlineSdts.length > 0 ? options.inlineSdts : void 0
|
|
2264
2265
|
}, contentNodes);
|
|
@@ -1,68 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { OutlineStyleAttr } from "../../../types/documentEnumValues.js";
|
|
3
|
-
import { ImagePositionAttrs, TextBoxAttrs as TextBoxAttrs$1 } from "../../schema/nodes.js";
|
|
1
|
+
import { TextBoxAttrs as TextBoxAttrs$1 } from "../../schema/nodes.js";
|
|
4
2
|
import { NodeExtension } from "../types.js";
|
|
5
3
|
//#region src/prosemirror/extensions/nodes/TextBoxExtension.d.ts
|
|
6
|
-
type TextBoxAttrs =
|
|
7
|
-
/** Width in pixels */
|
|
8
|
-
width?: number;
|
|
9
|
-
/** Height in pixels */
|
|
10
|
-
height?: number;
|
|
11
|
-
/** Text fitting behavior */
|
|
12
|
-
autoFit?: document_d_exports.ShapeTextBody["autoFit"];
|
|
13
|
-
/** Horizontal text wrapping inside the box */
|
|
14
|
-
textWrap?: document_d_exports.ShapeTextBody["textWrap"];
|
|
15
|
-
/** Unique identifier */
|
|
16
|
-
textBoxId?: string;
|
|
17
|
-
/** Fill color as CSS color */
|
|
18
|
-
fillColor?: string;
|
|
19
|
-
/** Outline width in pixels */
|
|
20
|
-
outlineWidth?: number;
|
|
21
|
-
/** Outline color as CSS color */
|
|
22
|
-
outlineColor?: string;
|
|
23
|
-
/** Outline dash style, or `"none"` for an explicit no-outline. */
|
|
24
|
-
outlineStyle?: OutlineStyleAttr;
|
|
25
|
-
/** DrawingML rotation and/or flips, serialized as CSS transform functions. */
|
|
26
|
-
transform?: string;
|
|
27
|
-
/** Internal margin top in pixels */
|
|
28
|
-
marginTop?: number;
|
|
29
|
-
/** Internal margin bottom in pixels */
|
|
30
|
-
marginBottom?: number;
|
|
31
|
-
/** Internal margin left in pixels */
|
|
32
|
-
marginLeft?: number;
|
|
33
|
-
/** Internal margin right in pixels */
|
|
34
|
-
marginRight?: number;
|
|
35
|
-
/** Vertical text alignment */
|
|
36
|
-
verticalAlign?: string;
|
|
37
|
-
/** Display mode */
|
|
38
|
-
displayMode?: "inline" | "float" | "block";
|
|
39
|
-
/** CSS float direction */
|
|
40
|
-
cssFloat?: "left" | "right" | "none";
|
|
41
|
-
/** Wrap type */
|
|
42
|
-
wrapType?: document_d_exports.ImageWrap["type"];
|
|
43
|
-
/** OOXML wrapText direction for anchored text boxes (eigenpal #474). */
|
|
44
|
-
wrapText?: "bothSides" | "left" | "right" | "largest";
|
|
45
|
-
/** Wrap distance from top edge, in pixels (OOXML distT, EMU-converted). */
|
|
46
|
-
distTop?: number;
|
|
47
|
-
/** Wrap distance from bottom edge, in pixels. */
|
|
48
|
-
distBottom?: number;
|
|
49
|
-
/** Wrap distance from left edge, in pixels. */
|
|
50
|
-
distLeft?: number;
|
|
51
|
-
/** Wrap distance from right edge, in pixels. */
|
|
52
|
-
distRight?: number;
|
|
53
|
-
/** Position for floating/anchored text boxes. */
|
|
54
|
-
position?: ImagePositionAttrs;
|
|
55
|
-
/** Original DOCX placement hint for save-path reconstruction. */
|
|
56
|
-
_docxPlacement?: "standalone" | "inlineWithPrevious";
|
|
57
|
-
/** Original DOCX paragraph group for standalone text-box reconstruction. */
|
|
58
|
-
_docxGroupId?: string;
|
|
59
|
-
/** Inline anchor linking this block node to its source run position. */
|
|
60
|
-
_docxAnchorId?: string;
|
|
61
|
-
/** Original run-level revision wrapper for save-path reconstruction. */
|
|
62
|
-
_docxTrackedChange?: TextBoxAttrs$1["_docxTrackedChange"];
|
|
63
|
-
/** Original inline content-control ancestry for save-path reconstruction. */
|
|
64
|
-
_docxInlineSdts?: TextBoxAttrs$1["_docxInlineSdts"];
|
|
65
|
-
};
|
|
4
|
+
type TextBoxAttrs = TextBoxAttrs$1;
|
|
66
5
|
declare const TextBoxExtension: (options?: Partial<Record<string, unknown>> | undefined) => NodeExtension;
|
|
67
6
|
//#endregion
|
|
68
7
|
export { TextBoxAttrs, TextBoxExtension };
|
|
@@ -2,6 +2,13 @@ import { IMAGE_WRAP_TYPE_VALUES, normalizeShapeTextAnchor } from "../../../types
|
|
|
2
2
|
import { expectTextBoxAttrs } from "../../attrs/index.js";
|
|
3
3
|
import { createNodeExtension } from "../create.js";
|
|
4
4
|
//#region src/prosemirror/extensions/nodes/TextBoxExtension.ts
|
|
5
|
+
/**
|
|
6
|
+
* TextBox Extension — editable text box node
|
|
7
|
+
*
|
|
8
|
+
* An isolating block node that contains paragraphs (and tables).
|
|
9
|
+
* Rendered as a positioned container with optional fill, outline, and margins.
|
|
10
|
+
* Supports inline and floating positioning.
|
|
11
|
+
*/
|
|
5
12
|
function parseTextBoxPosition(raw) {
|
|
6
13
|
if (!raw) return;
|
|
7
14
|
try {
|
|
@@ -60,6 +67,7 @@ const TextBoxExtension = createNodeExtension({
|
|
|
60
67
|
_docxPlacement: { default: null },
|
|
61
68
|
_docxGroupId: { default: null },
|
|
62
69
|
_docxAnchorId: { default: null },
|
|
70
|
+
_docxTextBodyContentState: { default: { type: "authored" } },
|
|
63
71
|
_docxTrackedChange: { default: null },
|
|
64
72
|
_docxInlineSdts: { default: null }
|
|
65
73
|
},
|
|
@@ -74,6 +82,7 @@ const TextBoxExtension = createNodeExtension({
|
|
|
74
82
|
const textWrap = parseTextBoxTextWrap(d["textWrap"]);
|
|
75
83
|
const verticalAlign = parseTextBoxVerticalAlign(d["verticalAlign"]);
|
|
76
84
|
return {
|
|
85
|
+
_docxTextBodyContentState: { type: "authored" },
|
|
77
86
|
...d["width"] ? { width: Number(d["width"]) } : {},
|
|
78
87
|
...d["height"] ? { height: Number(d["height"]) } : {},
|
|
79
88
|
...autoFit ? { autoFit } : {},
|
|
@@ -488,6 +488,10 @@ type ShapeAttrs = {
|
|
|
488
488
|
/**
|
|
489
489
|
* Text box node attributes
|
|
490
490
|
*/
|
|
491
|
+
declare const TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES: readonly ["source-empty", "authored"];
|
|
492
|
+
type TextBoxTextBodyContentState = { [Type in (typeof TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES)[number]]: {
|
|
493
|
+
readonly type: Type;
|
|
494
|
+
}; }[(typeof TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES)[number]];
|
|
491
495
|
type TextBoxAttrs = {
|
|
492
496
|
/** Width in pixels */
|
|
493
497
|
width?: number;
|
|
@@ -543,6 +547,12 @@ type TextBoxAttrs = {
|
|
|
543
547
|
_docxGroupId?: string;
|
|
544
548
|
/** Inline anchor linking this block node to its source run position. */
|
|
545
549
|
_docxAnchorId?: string;
|
|
550
|
+
/**
|
|
551
|
+
* Ownership of the schema-required placeholder paragraph. A source text
|
|
552
|
+
* body with no children needs one paragraph while it is editable, but that
|
|
553
|
+
* paragraph is not authored document content.
|
|
554
|
+
*/
|
|
555
|
+
_docxTextBodyContentState: TextBoxTextBodyContentState;
|
|
546
556
|
/** Original run-level revision wrapper for save-path reconstruction. */
|
|
547
557
|
_docxTrackedChange?: {
|
|
548
558
|
type: "insertion";
|
|
@@ -770,4 +780,4 @@ type TableCellAttrs = {
|
|
|
770
780
|
_docxVMergeContinuationCells?: unknown;
|
|
771
781
|
};
|
|
772
782
|
//#endregion
|
|
773
|
-
export { BlockSdtAttrs, BookmarkBoundaryAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, ParagraphPropertyChangeAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs };
|
|
783
|
+
export { BlockSdtAttrs, BookmarkBoundaryAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, ParagraphPropertyChangeAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs, TextBoxTextBodyContentState };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.37.
|
|
3
|
+
"version": "0.37.4",
|
|
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",
|