@office-open/core 0.10.15 → 0.12.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/README.md +2 -1
- package/dist/chart/index.d.mts +2 -2
- package/dist/chart/index.mjs +2 -2
- package/dist/chart-DED4tXC9.mjs +2325 -0
- package/dist/chart-DED4tXC9.mjs.map +1 -0
- package/dist/color-mapping-CFF0vRSe.mjs +117 -0
- package/dist/color-mapping-CFF0vRSe.mjs.map +1 -0
- package/dist/data-type-CZMKVaaT.d.mts.map +1 -1
- package/dist/descriptor/index.d.mts +2 -2
- package/dist/descriptor/index.mjs +1 -1
- package/dist/{descriptor-BjNkn5jo.mjs → descriptor-BqaNZrrZ.mjs} +43 -11
- package/dist/{descriptor-BjNkn5jo.mjs.map → descriptor-BqaNZrrZ.mjs.map} +1 -1
- package/dist/drawing/index.d.mts +2 -0
- package/dist/drawing/index.mjs +2 -0
- package/dist/{drawingml-sj1J3lb0.mjs → drawing-BCAyrCCw.mjs} +4456 -3452
- package/dist/drawing-BCAyrCCw.mjs.map +1 -0
- package/dist/{converters-C_Y2QX1w.mjs → ext-uri-BHBcIrW7.mjs} +742 -45
- package/dist/ext-uri-BHBcIrW7.mjs.map +1 -0
- package/dist/index-BAxlDUQ1.d.mts +590 -0
- package/dist/index-BAxlDUQ1.d.mts.map +1 -0
- package/dist/index-BP541uS-.d.mts +489 -0
- package/dist/index-BP541uS-.d.mts.map +1 -0
- package/dist/{index-BVK2dv6C.d.mts → index-BQLIofaF.d.mts} +10 -4
- package/dist/index-BQLIofaF.d.mts.map +1 -0
- package/dist/{index-k8WKLXnA.d.mts → index-CaNwM5_e.d.mts} +19 -20
- package/dist/index-CaNwM5_e.d.mts.map +1 -0
- package/dist/index-DPkf_CtG.d.mts +1578 -0
- package/dist/index-DPkf_CtG.d.mts.map +1 -0
- package/dist/index-DcukVskh.d.mts +31 -0
- package/dist/index-DcukVskh.d.mts.map +1 -0
- package/dist/index-Di6XPdGl.d.mts +322 -0
- package/dist/index-Di6XPdGl.d.mts.map +1 -0
- package/dist/index-L6AXewfV.d.mts +872 -0
- package/dist/index-L6AXewfV.d.mts.map +1 -0
- package/dist/index.d.mts +294 -30
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1327 -112
- package/dist/index.mjs.map +1 -1
- package/dist/{output-D_G_JR_8.d.mts → output-yyxdkG0C.d.mts} +2 -3
- package/dist/output-yyxdkG0C.d.mts.map +1 -0
- package/dist/patch/index.d.mts +2 -2
- package/dist/patch/index.mjs +2 -2
- package/dist/{patch-BmRfghOo.mjs → patch-AkQY17CD.mjs} +73 -28
- package/dist/patch-AkQY17CD.mjs.map +1 -0
- package/dist/smartart/index.d.mts +2 -2
- package/dist/smartart/index.mjs +2 -2
- package/dist/smartart-n1kYJ6Jg.mjs +1650 -0
- package/dist/smartart-n1kYJ6Jg.mjs.map +1 -0
- package/dist/style-matrix-B6jhPAT3.mjs +123 -0
- package/dist/style-matrix-B6jhPAT3.mjs.map +1 -0
- package/dist/theme/index.d.mts +4 -2
- package/dist/theme/index.mjs +4 -2
- package/dist/theme-BKnXRmvn.mjs +426 -0
- package/dist/theme-BKnXRmvn.mjs.map +1 -0
- package/dist/theme-options-kO89NUEX.d.mts +109 -0
- package/dist/theme-options-kO89NUEX.d.mts.map +1 -0
- package/dist/util/index.d.mts +3 -3
- package/dist/util/index.mjs +3 -3
- package/dist/{util-Tq9PSjK0.mjs → util-ptE16MEk.mjs} +237 -459
- package/dist/util-ptE16MEk.mjs.map +1 -0
- package/dist/{values-8di32lIe.d.mts → values-BECDm4zr.d.mts} +17 -31
- package/dist/values-BECDm4zr.d.mts.map +1 -0
- package/dist/vector/index.d.mts +2 -0
- package/dist/vector/index.mjs +2 -0
- package/dist/vector-DhLGZjP5.mjs +3049 -0
- package/dist/vector-DhLGZjP5.mjs.map +1 -0
- package/package.json +16 -8
- package/dist/chart-DIGJna_6.mjs +0 -582
- package/dist/chart-DIGJna_6.mjs.map +0 -1
- package/dist/converters-C_Y2QX1w.mjs.map +0 -1
- package/dist/drawingml/index.d.mts +0 -2
- package/dist/drawingml/index.mjs +0 -2
- package/dist/drawingml-sj1J3lb0.mjs.map +0 -1
- package/dist/index-BVK2dv6C.d.mts.map +0 -1
- package/dist/index-BfHfKuKy.d.mts +0 -275
- package/dist/index-BfHfKuKy.d.mts.map +0 -1
- package/dist/index-CE53SwpZ.d.mts +0 -1463
- package/dist/index-CE53SwpZ.d.mts.map +0 -1
- package/dist/index-D6VE-MnJ.d.mts +0 -43
- package/dist/index-D6VE-MnJ.d.mts.map +0 -1
- package/dist/index-DE4CLElr.d.mts +0 -145
- package/dist/index-DE4CLElr.d.mts.map +0 -1
- package/dist/index-DlPA26cw.d.mts +0 -91
- package/dist/index-DlPA26cw.d.mts.map +0 -1
- package/dist/index-k8WKLXnA.d.mts.map +0 -1
- package/dist/output-D_G_JR_8.d.mts.map +0 -1
- package/dist/patch-BmRfghOo.mjs.map +0 -1
- package/dist/smartart-B7ukZ-Tw.mjs +0 -305
- package/dist/smartart-B7ukZ-Tw.mjs.map +0 -1
- package/dist/theme-CiNzdl-9.mjs +0 -177
- package/dist/theme-CiNzdl-9.mjs.map +0 -1
- package/dist/util-Tq9PSjK0.mjs.map +0 -1
- package/dist/values-8di32lIe.d.mts.map +0 -1
|
@@ -0,0 +1,3049 @@
|
|
|
1
|
+
import { escapeXml, stringifyElement } from "@office-open/xml";
|
|
2
|
+
//#region src/vector/style.ts
|
|
3
|
+
/**
|
|
4
|
+
* Maps VmlShapeStyle property names to their corresponding CSS-style property names.
|
|
5
|
+
* Used internally for converting TypeScript-friendly property names to VML style attributes.
|
|
6
|
+
*/
|
|
7
|
+
const styleToKeyMap = {
|
|
8
|
+
flip: "flip",
|
|
9
|
+
height: "height",
|
|
10
|
+
left: "left",
|
|
11
|
+
marginBottom: "margin-bottom",
|
|
12
|
+
marginLeft: "margin-left",
|
|
13
|
+
marginRight: "margin-right",
|
|
14
|
+
marginTop: "margin-top",
|
|
15
|
+
position: "position",
|
|
16
|
+
positionHorizontal: "mso-position-horizontal",
|
|
17
|
+
positionHorizontalRelative: "mso-position-horizontal-relative",
|
|
18
|
+
positionVertical: "mso-position-vertical",
|
|
19
|
+
positionVerticalRelative: "mso-position-vertical-relative",
|
|
20
|
+
rotation: "rotation",
|
|
21
|
+
top: "top",
|
|
22
|
+
visibility: "visibility",
|
|
23
|
+
width: "width",
|
|
24
|
+
wrapDistanceBottom: "mso-wrap-distance-bottom",
|
|
25
|
+
wrapDistanceLeft: "mso-wrap-distance-left",
|
|
26
|
+
wrapDistanceRight: "mso-wrap-distance-right",
|
|
27
|
+
wrapDistanceTop: "mso-wrap-distance-top",
|
|
28
|
+
wrapEdited: "mso-wrap-edited",
|
|
29
|
+
wrapStyle: "mso-wrap-style",
|
|
30
|
+
fitShapeToText: "mso-fit-shape-to-text",
|
|
31
|
+
directionAlt: "mso-direction-alt",
|
|
32
|
+
zIndex: "z-index"
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Serialize a VmlShapeStyle object to the VML style attribute value
|
|
36
|
+
* (`"width:100pt;height:50pt"`), translating property names via
|
|
37
|
+
* {@link styleToKeyMap}.
|
|
38
|
+
*/
|
|
39
|
+
function stringifyVmlStyle(style) {
|
|
40
|
+
return Object.entries(style).map(([key, value]) => {
|
|
41
|
+
const text = typeof value === "boolean" ? value ? "t" : "f" : String(value);
|
|
42
|
+
return `${styleToKeyMap[key]}:${text}`;
|
|
43
|
+
}).join(";");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse a VML style attribute value into a CSS-name-keyed record
|
|
47
|
+
* (`{ "mso-position-horizontal": "absolute", … }`). Keys stay in VML/CSS form;
|
|
48
|
+
* callers read the entries they understand (width/height, wrap distances, …).
|
|
49
|
+
*/
|
|
50
|
+
function parseVmlStyle(styleStr) {
|
|
51
|
+
const style = {};
|
|
52
|
+
for (const part of styleStr.split(";")) {
|
|
53
|
+
const [key, val] = part.split(":").map((s) => s.trim());
|
|
54
|
+
if (key && val) style[key] = val;
|
|
55
|
+
}
|
|
56
|
+
return style;
|
|
57
|
+
}
|
|
58
|
+
/** Reverse of {@link styleToKeyMap} — CSS-style property name → VmlShapeStyle field. */
|
|
59
|
+
const keyToStyleMap = Object.fromEntries(Object.entries(styleToKeyMap).map(([field, key]) => [key, field]));
|
|
60
|
+
const NUMERIC = /^-?\d+(\.\d+)?$/;
|
|
61
|
+
/**
|
|
62
|
+
* Parse a CSS-name-keyed style record into a VmlShapeStyle object (camelCase
|
|
63
|
+
* fields, numeric and boolean literals coerced) — the inverse of
|
|
64
|
+
* {@link stringifyVmlStyle}. Keys outside the map are dropped.
|
|
65
|
+
*/
|
|
66
|
+
function parseVmlShapeStyle(record) {
|
|
67
|
+
const style = {};
|
|
68
|
+
for (const [key, value] of Object.entries(record)) {
|
|
69
|
+
const field = keyToStyleMap[key];
|
|
70
|
+
if (!field) continue;
|
|
71
|
+
if (field === "wrapEdited" || field === "fitShapeToText") style[field] = value === "t" || value === "true";
|
|
72
|
+
else if (NUMERIC.test(value)) style[field] = Number(value);
|
|
73
|
+
else style[field] = value;
|
|
74
|
+
}
|
|
75
|
+
return style;
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/vector/attributes.ts
|
|
79
|
+
/** AG_CoreAttributes — `style` is special-cased (mini-language), not tabulated. */
|
|
80
|
+
const VML_CORE_ATTRS = [
|
|
81
|
+
{
|
|
82
|
+
field: "id",
|
|
83
|
+
attr: "id",
|
|
84
|
+
kind: "string"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
field: "href",
|
|
88
|
+
attr: "href",
|
|
89
|
+
kind: "string"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
field: "target",
|
|
93
|
+
attr: "target",
|
|
94
|
+
kind: "string"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
field: "class",
|
|
98
|
+
attr: "class",
|
|
99
|
+
kind: "string"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
field: "title",
|
|
103
|
+
attr: "title",
|
|
104
|
+
kind: "string"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
field: "alt",
|
|
108
|
+
attr: "alt",
|
|
109
|
+
kind: "string"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
field: "coordsize",
|
|
113
|
+
attr: "coordsize",
|
|
114
|
+
kind: "string"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
field: "coordorigin",
|
|
118
|
+
attr: "coordorigin",
|
|
119
|
+
kind: "string"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
field: "wrapcoords",
|
|
123
|
+
attr: "wrapcoords",
|
|
124
|
+
kind: "string"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
field: "print",
|
|
128
|
+
attr: "print",
|
|
129
|
+
kind: "trueFalse"
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
/** AG_ShapeAttributes. */
|
|
133
|
+
const VML_SHAPE_ATTRS = [
|
|
134
|
+
{
|
|
135
|
+
field: "chromakey",
|
|
136
|
+
attr: "chromakey",
|
|
137
|
+
kind: "string"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
field: "filled",
|
|
141
|
+
attr: "filled",
|
|
142
|
+
kind: "trueFalse"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
field: "fillcolor",
|
|
146
|
+
attr: "fillcolor",
|
|
147
|
+
kind: "string"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
field: "opacity",
|
|
151
|
+
attr: "opacity",
|
|
152
|
+
kind: "string"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
field: "stroked",
|
|
156
|
+
attr: "stroked",
|
|
157
|
+
kind: "trueFalse"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
field: "strokecolor",
|
|
161
|
+
attr: "strokecolor",
|
|
162
|
+
kind: "string"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
field: "strokeweight",
|
|
166
|
+
attr: "strokeweight",
|
|
167
|
+
kind: "string"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
field: "insetpen",
|
|
171
|
+
attr: "insetpen",
|
|
172
|
+
kind: "trueFalse"
|
|
173
|
+
}
|
|
174
|
+
];
|
|
175
|
+
/** AG_OfficeCoreAttributes — field names mirror the o: attribute names. */
|
|
176
|
+
const VML_OFFICE_CORE_ATTRS = [
|
|
177
|
+
{
|
|
178
|
+
field: "spid",
|
|
179
|
+
attr: "o:spid",
|
|
180
|
+
kind: "string"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
field: "oned",
|
|
184
|
+
attr: "o:oned",
|
|
185
|
+
kind: "trueFalse"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
field: "regroupid",
|
|
189
|
+
attr: "o:regroupid",
|
|
190
|
+
kind: "number"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
field: "doubleclicknotify",
|
|
194
|
+
attr: "o:doubleclicknotify",
|
|
195
|
+
kind: "trueFalse"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
field: "button",
|
|
199
|
+
attr: "o:button",
|
|
200
|
+
kind: "trueFalse"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
field: "userhidden",
|
|
204
|
+
attr: "o:userhidden",
|
|
205
|
+
kind: "trueFalse"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
field: "bullet",
|
|
209
|
+
attr: "o:bullet",
|
|
210
|
+
kind: "trueFalse"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
field: "hr",
|
|
214
|
+
attr: "o:hr",
|
|
215
|
+
kind: "trueFalse"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
field: "hrstd",
|
|
219
|
+
attr: "o:hrstd",
|
|
220
|
+
kind: "trueFalse"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
field: "hrnoshade",
|
|
224
|
+
attr: "o:hrnoshade",
|
|
225
|
+
kind: "trueFalse"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
field: "hrpct",
|
|
229
|
+
attr: "o:hrpct",
|
|
230
|
+
kind: "number"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
field: "hralign",
|
|
234
|
+
attr: "o:hralign",
|
|
235
|
+
kind: "string"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
field: "allowincell",
|
|
239
|
+
attr: "o:allowincell",
|
|
240
|
+
kind: "trueFalse"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
field: "allowoverlap",
|
|
244
|
+
attr: "o:allowoverlap",
|
|
245
|
+
kind: "trueFalse"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
field: "userdrawn",
|
|
249
|
+
attr: "o:userdrawn",
|
|
250
|
+
kind: "trueFalse"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
field: "bordertopcolor",
|
|
254
|
+
attr: "o:bordertopcolor",
|
|
255
|
+
kind: "string"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
field: "borderleftcolor",
|
|
259
|
+
attr: "o:borderleftcolor",
|
|
260
|
+
kind: "string"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
field: "borderbottomcolor",
|
|
264
|
+
attr: "o:borderbottomcolor",
|
|
265
|
+
kind: "string"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
field: "borderrightcolor",
|
|
269
|
+
attr: "o:borderrightcolor",
|
|
270
|
+
kind: "string"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
field: "dgmlayout",
|
|
274
|
+
attr: "o:dgmlayout",
|
|
275
|
+
kind: "string"
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
field: "dgmnodekind",
|
|
279
|
+
attr: "o:dgmnodekind",
|
|
280
|
+
kind: "number"
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
field: "dgmlayoutmru",
|
|
284
|
+
attr: "o:dgmlayoutmru",
|
|
285
|
+
kind: "string"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
field: "insetmode",
|
|
289
|
+
attr: "o:insetmode",
|
|
290
|
+
kind: "string"
|
|
291
|
+
}
|
|
292
|
+
];
|
|
293
|
+
/** AG_OfficeShapeAttributes. */
|
|
294
|
+
const VML_OFFICE_SHAPE_ATTRS = [
|
|
295
|
+
{
|
|
296
|
+
field: "spt",
|
|
297
|
+
attr: "o:spt",
|
|
298
|
+
kind: "number"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
field: "connectortype",
|
|
302
|
+
attr: "o:connectortype",
|
|
303
|
+
kind: "string"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
field: "bwmode",
|
|
307
|
+
attr: "o:bwmode",
|
|
308
|
+
kind: "string"
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
field: "bwpure",
|
|
312
|
+
attr: "o:bwpure",
|
|
313
|
+
kind: "string"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
field: "bwnormal",
|
|
317
|
+
attr: "o:bwnormal",
|
|
318
|
+
kind: "string"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
field: "forcedash",
|
|
322
|
+
attr: "o:forcedash",
|
|
323
|
+
kind: "trueFalse"
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
field: "oleicon",
|
|
327
|
+
attr: "o:oleicon",
|
|
328
|
+
kind: "trueFalse"
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
field: "ole",
|
|
332
|
+
attr: "o:ole",
|
|
333
|
+
kind: "string"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
field: "preferrelative",
|
|
337
|
+
attr: "o:preferrelative",
|
|
338
|
+
kind: "trueFalse"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
field: "cliptowrap",
|
|
342
|
+
attr: "o:cliptowrap",
|
|
343
|
+
kind: "trueFalse"
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
field: "clip",
|
|
347
|
+
attr: "o:clip",
|
|
348
|
+
kind: "trueFalse"
|
|
349
|
+
}
|
|
350
|
+
];
|
|
351
|
+
/** s:ST_TrueFalse output form — "t"/"f", the spelling Office itself writes. */
|
|
352
|
+
function stringifyVmlTrueFalse(value) {
|
|
353
|
+
return value ? "t" : "f";
|
|
354
|
+
}
|
|
355
|
+
/** Accepts every ST_TrueFalse input spelling. */
|
|
356
|
+
function parseVmlTrueFalse(value) {
|
|
357
|
+
return value === "t" || value === "true" || value === "1";
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Serialize the tabulated fields of `opts` into one attribute string (leading
|
|
361
|
+
* space included when non-empty). The `style` field of
|
|
362
|
+
* {@link VmlCoreAttributes} joins here so callers need a single call.
|
|
363
|
+
*/
|
|
364
|
+
function stringifyVmlAttributes(opts, specs) {
|
|
365
|
+
const parts = [];
|
|
366
|
+
for (const spec of specs) {
|
|
367
|
+
const value = opts[spec.field];
|
|
368
|
+
if (value === void 0) continue;
|
|
369
|
+
const text = spec.kind === "trueFalse" ? stringifyVmlTrueFalse(value) : spec.kind === "trueFalseBlank" ? stringifyVmlTrueFalseBlank(value) : spec.kind === "number" ? String(value) : escapeXml(String(value));
|
|
370
|
+
parts.push(`${spec.attr}="${text}"`);
|
|
371
|
+
}
|
|
372
|
+
return parts.length > 0 ? ` ${parts.join(" ")}` : "";
|
|
373
|
+
}
|
|
374
|
+
/** Serialize a boolean-or-empty ST_TrueFalseBlank ("t"/"f"/""). */
|
|
375
|
+
function stringifyVmlTrueFalseBlank(value) {
|
|
376
|
+
return value === "" ? "" : stringifyVmlTrueFalse(value);
|
|
377
|
+
}
|
|
378
|
+
/** Parse a boolean-or-empty ST_TrueFalseBlank. */
|
|
379
|
+
function parseVmlTrueFalseBlank(value) {
|
|
380
|
+
return value === "" ? "" : parseVmlTrueFalse(value);
|
|
381
|
+
}
|
|
382
|
+
/** Inverse of {@link stringifyVmlAttributes} — fills the tabulated fields onto `out`. */
|
|
383
|
+
function parseVmlAttributes(el, specs, out) {
|
|
384
|
+
for (const spec of specs) {
|
|
385
|
+
const raw = el.attributes?.[spec.attr];
|
|
386
|
+
if (raw === void 0) continue;
|
|
387
|
+
out[spec.field] = spec.kind === "trueFalse" ? parseVmlTrueFalse(String(raw)) : spec.kind === "trueFalseBlank" ? parseVmlTrueFalseBlank(String(raw)) : spec.kind === "number" ? Number(raw) : String(raw);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/vector/shape-elements/office-elements.ts
|
|
392
|
+
/** AG_Ext as a spec entry — prepend to every o: element's spec list. */
|
|
393
|
+
const EXT_ATTR = [{
|
|
394
|
+
field: "ext",
|
|
395
|
+
attr: "v:ext",
|
|
396
|
+
kind: "string"
|
|
397
|
+
}];
|
|
398
|
+
const SKEW_ATTRS = [
|
|
399
|
+
{
|
|
400
|
+
field: "id",
|
|
401
|
+
attr: "id",
|
|
402
|
+
kind: "string"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
field: "on",
|
|
406
|
+
attr: "on",
|
|
407
|
+
kind: "trueFalse"
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
field: "offset",
|
|
411
|
+
attr: "offset",
|
|
412
|
+
kind: "string"
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
field: "origin",
|
|
416
|
+
attr: "origin",
|
|
417
|
+
kind: "string"
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
field: "matrix",
|
|
421
|
+
attr: "matrix",
|
|
422
|
+
kind: "string"
|
|
423
|
+
}
|
|
424
|
+
];
|
|
425
|
+
/** Serialize o:skew. */
|
|
426
|
+
function stringifyVmlSkew(opts) {
|
|
427
|
+
return `<o:skew${stringifyVmlAttributes(opts, [...EXT_ATTR, ...SKEW_ATTRS])}/>`;
|
|
428
|
+
}
|
|
429
|
+
/** Parse an o:skew element. */
|
|
430
|
+
function parseVmlSkew(el) {
|
|
431
|
+
const out = {};
|
|
432
|
+
parseVmlAttributes(el, [...EXT_ATTR, ...SKEW_ATTRS], out);
|
|
433
|
+
return out;
|
|
434
|
+
}
|
|
435
|
+
const EXTRUSION_ATTRS = [
|
|
436
|
+
{
|
|
437
|
+
field: "on",
|
|
438
|
+
attr: "on",
|
|
439
|
+
kind: "trueFalse"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
field: "type",
|
|
443
|
+
attr: "type",
|
|
444
|
+
kind: "string"
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
field: "render",
|
|
448
|
+
attr: "render",
|
|
449
|
+
kind: "string"
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
field: "viewpointorigin",
|
|
453
|
+
attr: "viewpointorigin",
|
|
454
|
+
kind: "string"
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
field: "viewpoint",
|
|
458
|
+
attr: "viewpoint",
|
|
459
|
+
kind: "string"
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
field: "plane",
|
|
463
|
+
attr: "plane",
|
|
464
|
+
kind: "string"
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
field: "skewangle",
|
|
468
|
+
attr: "skewangle",
|
|
469
|
+
kind: "number"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
field: "skewamt",
|
|
473
|
+
attr: "skewamt",
|
|
474
|
+
kind: "string"
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
field: "foredepth",
|
|
478
|
+
attr: "foredepth",
|
|
479
|
+
kind: "string"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
field: "backdepth",
|
|
483
|
+
attr: "backdepth",
|
|
484
|
+
kind: "string"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
field: "orientation",
|
|
488
|
+
attr: "orientation",
|
|
489
|
+
kind: "string"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
field: "orientationangle",
|
|
493
|
+
attr: "orientationangle",
|
|
494
|
+
kind: "number"
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
field: "lockrotationcenter",
|
|
498
|
+
attr: "lockrotationcenter",
|
|
499
|
+
kind: "trueFalse"
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
field: "autorotationcenter",
|
|
503
|
+
attr: "autorotationcenter",
|
|
504
|
+
kind: "trueFalse"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
field: "rotationcenter",
|
|
508
|
+
attr: "rotationcenter",
|
|
509
|
+
kind: "string"
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
field: "rotationangle",
|
|
513
|
+
attr: "rotationangle",
|
|
514
|
+
kind: "string"
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
field: "colormode",
|
|
518
|
+
attr: "colormode",
|
|
519
|
+
kind: "string"
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
field: "color",
|
|
523
|
+
attr: "color",
|
|
524
|
+
kind: "string"
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
field: "shininess",
|
|
528
|
+
attr: "shininess",
|
|
529
|
+
kind: "number"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
field: "specularity",
|
|
533
|
+
attr: "specularity",
|
|
534
|
+
kind: "string"
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
field: "diffusity",
|
|
538
|
+
attr: "diffusity",
|
|
539
|
+
kind: "string"
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
field: "metal",
|
|
543
|
+
attr: "metal",
|
|
544
|
+
kind: "trueFalse"
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
field: "edge",
|
|
548
|
+
attr: "edge",
|
|
549
|
+
kind: "string"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
field: "facet",
|
|
553
|
+
attr: "facet",
|
|
554
|
+
kind: "string"
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
field: "lightface",
|
|
558
|
+
attr: "lightface",
|
|
559
|
+
kind: "trueFalse"
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
field: "brightness",
|
|
563
|
+
attr: "brightness",
|
|
564
|
+
kind: "string"
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
field: "lightposition",
|
|
568
|
+
attr: "lightposition",
|
|
569
|
+
kind: "string"
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
field: "lightlevel",
|
|
573
|
+
attr: "lightlevel",
|
|
574
|
+
kind: "string"
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
field: "lightharsh",
|
|
578
|
+
attr: "lightharsh",
|
|
579
|
+
kind: "trueFalse"
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
field: "lightposition2",
|
|
583
|
+
attr: "lightposition2",
|
|
584
|
+
kind: "string"
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
field: "lightlevel2",
|
|
588
|
+
attr: "lightlevel2",
|
|
589
|
+
kind: "string"
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
field: "lightharsh2",
|
|
593
|
+
attr: "lightharsh2",
|
|
594
|
+
kind: "trueFalse"
|
|
595
|
+
}
|
|
596
|
+
];
|
|
597
|
+
/** Serialize o:extrusion. */
|
|
598
|
+
function stringifyVmlExtrusion(opts) {
|
|
599
|
+
return `<o:extrusion${stringifyVmlAttributes(opts, [...EXT_ATTR, ...EXTRUSION_ATTRS])}/>`;
|
|
600
|
+
}
|
|
601
|
+
/** Parse an o:extrusion element. */
|
|
602
|
+
function parseVmlExtrusion(el) {
|
|
603
|
+
const out = {};
|
|
604
|
+
parseVmlAttributes(el, [...EXT_ATTR, ...EXTRUSION_ATTRS], out);
|
|
605
|
+
return out;
|
|
606
|
+
}
|
|
607
|
+
const CALLOUT_ATTRS = [
|
|
608
|
+
{
|
|
609
|
+
field: "on",
|
|
610
|
+
attr: "on",
|
|
611
|
+
kind: "trueFalse"
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
field: "type",
|
|
615
|
+
attr: "type",
|
|
616
|
+
kind: "string"
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
field: "gap",
|
|
620
|
+
attr: "gap",
|
|
621
|
+
kind: "string"
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
field: "angle",
|
|
625
|
+
attr: "angle",
|
|
626
|
+
kind: "string"
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
field: "dropauto",
|
|
630
|
+
attr: "dropauto",
|
|
631
|
+
kind: "trueFalse"
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
field: "drop",
|
|
635
|
+
attr: "drop",
|
|
636
|
+
kind: "string"
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
field: "distance",
|
|
640
|
+
attr: "distance",
|
|
641
|
+
kind: "string"
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
field: "lengthspecified",
|
|
645
|
+
attr: "lengthspecified",
|
|
646
|
+
kind: "trueFalse"
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
field: "length",
|
|
650
|
+
attr: "length",
|
|
651
|
+
kind: "string"
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
field: "accentbar",
|
|
655
|
+
attr: "accentbar",
|
|
656
|
+
kind: "trueFalse"
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
field: "textborder",
|
|
660
|
+
attr: "textborder",
|
|
661
|
+
kind: "trueFalse"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
field: "minusx",
|
|
665
|
+
attr: "minusx",
|
|
666
|
+
kind: "trueFalse"
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
field: "minusy",
|
|
670
|
+
attr: "minusy",
|
|
671
|
+
kind: "trueFalse"
|
|
672
|
+
}
|
|
673
|
+
];
|
|
674
|
+
/** Serialize o:callout. */
|
|
675
|
+
function stringifyVmlCallout(opts) {
|
|
676
|
+
return `<o:callout${stringifyVmlAttributes(opts, [...EXT_ATTR, ...CALLOUT_ATTRS])}/>`;
|
|
677
|
+
}
|
|
678
|
+
/** Parse an o:callout element. */
|
|
679
|
+
function parseVmlCallout(el) {
|
|
680
|
+
const out = {};
|
|
681
|
+
parseVmlAttributes(el, [...EXT_ATTR, ...CALLOUT_ATTRS], out);
|
|
682
|
+
return out;
|
|
683
|
+
}
|
|
684
|
+
const LOCK_ATTRS = [
|
|
685
|
+
{
|
|
686
|
+
field: "position",
|
|
687
|
+
attr: "position",
|
|
688
|
+
kind: "trueFalse"
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
field: "selection",
|
|
692
|
+
attr: "selection",
|
|
693
|
+
kind: "trueFalse"
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
field: "grouping",
|
|
697
|
+
attr: "grouping",
|
|
698
|
+
kind: "trueFalse"
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
field: "ungrouping",
|
|
702
|
+
attr: "ungrouping",
|
|
703
|
+
kind: "trueFalse"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
field: "rotation",
|
|
707
|
+
attr: "rotation",
|
|
708
|
+
kind: "trueFalse"
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
field: "cropping",
|
|
712
|
+
attr: "cropping",
|
|
713
|
+
kind: "trueFalse"
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
field: "verticies",
|
|
717
|
+
attr: "verticies",
|
|
718
|
+
kind: "trueFalse"
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
field: "adjusthandles",
|
|
722
|
+
attr: "adjusthandles",
|
|
723
|
+
kind: "trueFalse"
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
field: "text",
|
|
727
|
+
attr: "text",
|
|
728
|
+
kind: "trueFalse"
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
field: "aspectratio",
|
|
732
|
+
attr: "aspectratio",
|
|
733
|
+
kind: "trueFalse"
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
field: "shapetype",
|
|
737
|
+
attr: "shapetype",
|
|
738
|
+
kind: "trueFalse"
|
|
739
|
+
}
|
|
740
|
+
];
|
|
741
|
+
/** Serialize o:lock. */
|
|
742
|
+
function stringifyVmlLock(opts) {
|
|
743
|
+
return `<o:lock${stringifyVmlAttributes(opts, [...EXT_ATTR, ...LOCK_ATTRS])}/>`;
|
|
744
|
+
}
|
|
745
|
+
/** Parse an o:lock element. */
|
|
746
|
+
function parseVmlLock(el) {
|
|
747
|
+
const out = {};
|
|
748
|
+
parseVmlAttributes(el, [...EXT_ATTR, ...LOCK_ATTRS], out);
|
|
749
|
+
return out;
|
|
750
|
+
}
|
|
751
|
+
/** Serialize o:clippath. */
|
|
752
|
+
function stringifyVmlClipPath(opts) {
|
|
753
|
+
return `<o:clippath v:v="${escapeXml(opts.v)}"/>`;
|
|
754
|
+
}
|
|
755
|
+
/** Parse an o:clippath element. */
|
|
756
|
+
function parseVmlClipPath(el) {
|
|
757
|
+
return { v: String(el.attributes?.["v:v"] ?? "") };
|
|
758
|
+
}
|
|
759
|
+
const SIGNATURE_ATTRS = [
|
|
760
|
+
{
|
|
761
|
+
field: "issignatureline",
|
|
762
|
+
attr: "issignatureline",
|
|
763
|
+
kind: "trueFalse"
|
|
764
|
+
},
|
|
765
|
+
{
|
|
766
|
+
field: "id",
|
|
767
|
+
attr: "id",
|
|
768
|
+
kind: "string"
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
field: "provid",
|
|
772
|
+
attr: "provid",
|
|
773
|
+
kind: "string"
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
field: "signinginstructionsset",
|
|
777
|
+
attr: "signinginstructionsset",
|
|
778
|
+
kind: "trueFalse"
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
field: "allowcomments",
|
|
782
|
+
attr: "allowcomments",
|
|
783
|
+
kind: "trueFalse"
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
field: "showsigndate",
|
|
787
|
+
attr: "showsigndate",
|
|
788
|
+
kind: "trueFalse"
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
field: "suggestedsigner",
|
|
792
|
+
attr: "o:suggestedsigner",
|
|
793
|
+
kind: "string"
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
field: "suggestedsigner2",
|
|
797
|
+
attr: "o:suggestedsigner2",
|
|
798
|
+
kind: "string"
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
field: "suggestedsigneremail",
|
|
802
|
+
attr: "o:suggestedsigneremail",
|
|
803
|
+
kind: "string"
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
field: "signinginstructions",
|
|
807
|
+
attr: "signinginstructions",
|
|
808
|
+
kind: "string"
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
field: "addlxml",
|
|
812
|
+
attr: "addlxml",
|
|
813
|
+
kind: "string"
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
field: "sigprovurl",
|
|
817
|
+
attr: "sigprovurl",
|
|
818
|
+
kind: "string"
|
|
819
|
+
}
|
|
820
|
+
];
|
|
821
|
+
/** Serialize o:signatureline. */
|
|
822
|
+
function stringifyVmlSignatureLine(opts) {
|
|
823
|
+
return `<o:signatureline${stringifyVmlAttributes(opts, [...EXT_ATTR, ...SIGNATURE_ATTRS])}/>`;
|
|
824
|
+
}
|
|
825
|
+
/** Parse an o:signatureline element. */
|
|
826
|
+
function parseVmlSignatureLine(el) {
|
|
827
|
+
const out = {};
|
|
828
|
+
parseVmlAttributes(el, [...EXT_ATTR, ...SIGNATURE_ATTRS], out);
|
|
829
|
+
return out;
|
|
830
|
+
}
|
|
831
|
+
/** Serialize o:ink (hand-written — `i` is required, so no table-driven cast). */
|
|
832
|
+
function stringifyVmlInk(opts) {
|
|
833
|
+
const attrs = [`i="${escapeXml(opts.i)}"`];
|
|
834
|
+
if (opts.annotation !== void 0) attrs.push(`annotation="${stringifyVmlTrueFalse(opts.annotation)}"`);
|
|
835
|
+
if (opts.contentType !== void 0) attrs.push(`contentType="${escapeXml(opts.contentType)}"`);
|
|
836
|
+
return `<o:ink ${attrs.join(" ")}/>`;
|
|
837
|
+
}
|
|
838
|
+
/** Parse an o:ink element. */
|
|
839
|
+
function parseVmlInk(el) {
|
|
840
|
+
const out = { i: String(el.attributes?.i ?? "") };
|
|
841
|
+
if (el.attributes?.annotation !== void 0) out.annotation = parseVmlTrueFalse(String(el.attributes.annotation));
|
|
842
|
+
if (el.attributes?.contentType !== void 0) out.contentType = String(el.attributes.contentType);
|
|
843
|
+
return out;
|
|
844
|
+
}
|
|
845
|
+
/** Serialize o:equationxml. */
|
|
846
|
+
function stringifyVmlEquationXml(opts) {
|
|
847
|
+
return `<o:equationxml${opts.contentType !== void 0 ? ` contentType="${escapeXml(opts.contentType)}"` : ""}>${opts.content ?? ""}</o:equationxml>`;
|
|
848
|
+
}
|
|
849
|
+
/** Parse an o:equationxml element. */
|
|
850
|
+
function parseVmlEquationXml(el) {
|
|
851
|
+
const out = {};
|
|
852
|
+
const contentType = el.attributes?.contentType;
|
|
853
|
+
if (contentType !== void 0) out.contentType = String(contentType);
|
|
854
|
+
if ((el.elements ?? []).length > 0) {
|
|
855
|
+
const child = el.elements.find((c) => c.type === "element");
|
|
856
|
+
if (child) out.content = stringifyElement(child);
|
|
857
|
+
}
|
|
858
|
+
return out;
|
|
859
|
+
}
|
|
860
|
+
const RELATION_ATTRS = [
|
|
861
|
+
{
|
|
862
|
+
field: "idsrc",
|
|
863
|
+
attr: "idsrc",
|
|
864
|
+
kind: "string"
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
field: "iddest",
|
|
868
|
+
attr: "iddest",
|
|
869
|
+
kind: "string"
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
field: "idcntr",
|
|
873
|
+
attr: "idcntr",
|
|
874
|
+
kind: "string"
|
|
875
|
+
}
|
|
876
|
+
];
|
|
877
|
+
const DIAGRAM_ATTRS = [
|
|
878
|
+
{
|
|
879
|
+
field: "dgmstyle",
|
|
880
|
+
attr: "dgmstyle",
|
|
881
|
+
kind: "number"
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
field: "autoformat",
|
|
885
|
+
attr: "autoformat",
|
|
886
|
+
kind: "trueFalse"
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
field: "reverse",
|
|
890
|
+
attr: "reverse",
|
|
891
|
+
kind: "trueFalse"
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
field: "autolayout",
|
|
895
|
+
attr: "autolayout",
|
|
896
|
+
kind: "trueFalse"
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
field: "dgmscalex",
|
|
900
|
+
attr: "dgmscalex",
|
|
901
|
+
kind: "number"
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
field: "dgmscaley",
|
|
905
|
+
attr: "dgmscaley",
|
|
906
|
+
kind: "number"
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
field: "dgmfontsize",
|
|
910
|
+
attr: "dgmfontsize",
|
|
911
|
+
kind: "number"
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
field: "constrainbounds",
|
|
915
|
+
attr: "constrainbounds",
|
|
916
|
+
kind: "string"
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
field: "dgmbasetextscale",
|
|
920
|
+
attr: "dgmbasetextscale",
|
|
921
|
+
kind: "number"
|
|
922
|
+
}
|
|
923
|
+
];
|
|
924
|
+
/** Serialize o:diagram. */
|
|
925
|
+
function stringifyVmlDiagram(opts) {
|
|
926
|
+
const relations = (opts.relations ?? []).map((rel) => `<o:rel${stringifyVmlAttributes(rel, [...EXT_ATTR, ...RELATION_ATTRS])}/>`).join("");
|
|
927
|
+
const children = relations !== "" ? `<o:relationtable>${relations}</o:relationtable>` : "";
|
|
928
|
+
return `<o:diagram${stringifyVmlAttributes(opts, [...EXT_ATTR, ...DIAGRAM_ATTRS])}>${children}</o:diagram>`;
|
|
929
|
+
}
|
|
930
|
+
/** Parse an o:diagram element. */
|
|
931
|
+
function parseVmlDiagram(el) {
|
|
932
|
+
const out = {};
|
|
933
|
+
parseVmlAttributes(el, [...EXT_ATTR, ...DIAGRAM_ATTRS], out);
|
|
934
|
+
const relationTable = (el.elements ?? []).find((c) => c.type === "element" && c.name === "o:relationtable");
|
|
935
|
+
if (relationTable) {
|
|
936
|
+
const relations = [];
|
|
937
|
+
for (const child of relationTable.elements ?? []) if (child.type === "element" && child.name === "o:rel") {
|
|
938
|
+
const rel = {};
|
|
939
|
+
parseVmlAttributes(child, [...EXT_ATTR, ...RELATION_ATTRS], rel);
|
|
940
|
+
relations.push(rel);
|
|
941
|
+
}
|
|
942
|
+
if (relations.length > 0) out.relations = relations;
|
|
943
|
+
}
|
|
944
|
+
return out;
|
|
945
|
+
}
|
|
946
|
+
/** Serialize o:complex. */
|
|
947
|
+
function stringifyVmlComplex(opts) {
|
|
948
|
+
return `<o:complex${stringifyVmlAttributes(opts, EXT_ATTR)}/>`;
|
|
949
|
+
}
|
|
950
|
+
/** Parse an o:complex element. */
|
|
951
|
+
function parseVmlComplex(el) {
|
|
952
|
+
const out = {};
|
|
953
|
+
parseVmlAttributes(el, EXT_ATTR, out);
|
|
954
|
+
return out;
|
|
955
|
+
}
|
|
956
|
+
/** Serialize o:fill. */
|
|
957
|
+
function stringifyVmlOfficeFill(opts) {
|
|
958
|
+
return `<o:fill${stringifyVmlAttributes(opts, EXT_ATTR)}${opts.type !== void 0 ? ` type="${opts.type}"` : ""}/>`;
|
|
959
|
+
}
|
|
960
|
+
/** Parse an o:fill element. */
|
|
961
|
+
function parseVmlOfficeFill(el) {
|
|
962
|
+
const out = {};
|
|
963
|
+
parseVmlAttributes(el, EXT_ATTR, out);
|
|
964
|
+
if (el.attributes?.type !== void 0) out.type = String(el.attributes.type);
|
|
965
|
+
return out;
|
|
966
|
+
}
|
|
967
|
+
const OLE_OBJECT_ATTRS = [
|
|
968
|
+
{
|
|
969
|
+
field: "Type",
|
|
970
|
+
attr: "Type",
|
|
971
|
+
kind: "string"
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
field: "ProgID",
|
|
975
|
+
attr: "ProgID",
|
|
976
|
+
kind: "string"
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
field: "ShapeID",
|
|
980
|
+
attr: "ShapeID",
|
|
981
|
+
kind: "string"
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
field: "DrawAspect",
|
|
985
|
+
attr: "DrawAspect",
|
|
986
|
+
kind: "string"
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
field: "ObjectID",
|
|
990
|
+
attr: "ObjectID",
|
|
991
|
+
kind: "string"
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
field: "relationshipId",
|
|
995
|
+
attr: "r:id",
|
|
996
|
+
kind: "string"
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
field: "UpdateMode",
|
|
1000
|
+
attr: "UpdateMode",
|
|
1001
|
+
kind: "string"
|
|
1002
|
+
}
|
|
1003
|
+
];
|
|
1004
|
+
/** Serialize o:OLEObject. */
|
|
1005
|
+
function stringifyVmlOleObject(opts) {
|
|
1006
|
+
const children = [];
|
|
1007
|
+
if (opts.linkType !== void 0) children.push(`<o:LinkType>${escapeXml(opts.linkType)}</o:LinkType>`);
|
|
1008
|
+
if (opts.lockedField !== void 0) children.push(`<o:LockedField>${stringifyVmlTrueFalseBlank(opts.lockedField)}</o:LockedField>`);
|
|
1009
|
+
if (opts.fieldCodes !== void 0) children.push(`<o:FieldCodes>${escapeXml(opts.fieldCodes)}</o:FieldCodes>`);
|
|
1010
|
+
const attrStr = stringifyVmlAttributes(opts, OLE_OBJECT_ATTRS);
|
|
1011
|
+
return children.length > 0 ? `<o:OLEObject${attrStr}>${children.join("")}</o:OLEObject>` : `<o:OLEObject${attrStr}/>`;
|
|
1012
|
+
}
|
|
1013
|
+
/** Read the concatenated text content of an element (LinkType/FieldCodes children). */
|
|
1014
|
+
function elementText(el) {
|
|
1015
|
+
return (el.elements ?? []).map((child) => String(child.text ?? "")).join("");
|
|
1016
|
+
}
|
|
1017
|
+
/** Parse an o:OLEObject element. */
|
|
1018
|
+
function parseVmlOleObject(el) {
|
|
1019
|
+
const out = {};
|
|
1020
|
+
parseVmlAttributes(el, OLE_OBJECT_ATTRS, out);
|
|
1021
|
+
for (const child of el.elements ?? []) {
|
|
1022
|
+
if (child.type !== "element") continue;
|
|
1023
|
+
if (child.name === "o:LinkType") out.linkType = elementText(child);
|
|
1024
|
+
else if (child.name === "o:LockedField") out.lockedField = parseVmlTrueFalseBlank(elementText(child));
|
|
1025
|
+
else if (child.name === "o:FieldCodes") out.fieldCodes = elementText(child);
|
|
1026
|
+
}
|
|
1027
|
+
return out;
|
|
1028
|
+
}
|
|
1029
|
+
//#endregion
|
|
1030
|
+
//#region src/vector/shape-elements/client-data.ts
|
|
1031
|
+
const TRUE_FALSE_BLANK_FIELDS = [
|
|
1032
|
+
"MoveWithCells",
|
|
1033
|
+
"SizeWithCells",
|
|
1034
|
+
"Locked",
|
|
1035
|
+
"DefaultSize",
|
|
1036
|
+
"PrintObject",
|
|
1037
|
+
"Disabled",
|
|
1038
|
+
"AutoFill",
|
|
1039
|
+
"AutoLine",
|
|
1040
|
+
"AutoPict",
|
|
1041
|
+
"LockText",
|
|
1042
|
+
"JustLastX",
|
|
1043
|
+
"SecretEdit",
|
|
1044
|
+
"Default",
|
|
1045
|
+
"Help",
|
|
1046
|
+
"Cancel",
|
|
1047
|
+
"Dismiss",
|
|
1048
|
+
"Visible",
|
|
1049
|
+
"RowHidden",
|
|
1050
|
+
"ColHidden",
|
|
1051
|
+
"MultiLine",
|
|
1052
|
+
"VScroll",
|
|
1053
|
+
"ValidIds",
|
|
1054
|
+
"NoThreeD2",
|
|
1055
|
+
"Colored",
|
|
1056
|
+
"NoThreeD",
|
|
1057
|
+
"FirstButton",
|
|
1058
|
+
"Horiz",
|
|
1059
|
+
"MapOCX",
|
|
1060
|
+
"Camera",
|
|
1061
|
+
"RecalcAlways",
|
|
1062
|
+
"AutoScale",
|
|
1063
|
+
"DDE",
|
|
1064
|
+
"UIObj"
|
|
1065
|
+
];
|
|
1066
|
+
const INTEGER_FIELDS = [
|
|
1067
|
+
"Accel",
|
|
1068
|
+
"Accel2",
|
|
1069
|
+
"Row",
|
|
1070
|
+
"Column",
|
|
1071
|
+
"VTEdit",
|
|
1072
|
+
"WidthMin",
|
|
1073
|
+
"Sel",
|
|
1074
|
+
"DropLines",
|
|
1075
|
+
"Checked",
|
|
1076
|
+
"Val",
|
|
1077
|
+
"Min",
|
|
1078
|
+
"Max",
|
|
1079
|
+
"Inc",
|
|
1080
|
+
"Page",
|
|
1081
|
+
"Dx",
|
|
1082
|
+
"ScriptLanguage",
|
|
1083
|
+
"ScriptLocation"
|
|
1084
|
+
];
|
|
1085
|
+
const STRING_FIELDS = [
|
|
1086
|
+
"Anchor",
|
|
1087
|
+
"FmlaMacro",
|
|
1088
|
+
"TextHAlign",
|
|
1089
|
+
"TextVAlign",
|
|
1090
|
+
"FmlaRange",
|
|
1091
|
+
"SelType",
|
|
1092
|
+
"MultiSel",
|
|
1093
|
+
"LCT",
|
|
1094
|
+
"ListItem",
|
|
1095
|
+
"DropStyle",
|
|
1096
|
+
"FmlaLink",
|
|
1097
|
+
"FmlaPict",
|
|
1098
|
+
"FmlaGroup",
|
|
1099
|
+
"ScriptText",
|
|
1100
|
+
"ScriptExtended",
|
|
1101
|
+
"FmlaTxbx",
|
|
1102
|
+
"CF"
|
|
1103
|
+
];
|
|
1104
|
+
const TRUE_FALSE_BLANK_FIELD_SET = new Set(TRUE_FALSE_BLANK_FIELDS);
|
|
1105
|
+
const INTEGER_FIELD_SET = new Set(INTEGER_FIELDS);
|
|
1106
|
+
const STRING_FIELD_SET = new Set(STRING_FIELDS);
|
|
1107
|
+
/** Serialize x:ClientData. */
|
|
1108
|
+
function stringifyVmlClientData(opts) {
|
|
1109
|
+
const children = [];
|
|
1110
|
+
for (const field of TRUE_FALSE_BLANK_FIELDS) {
|
|
1111
|
+
const value = opts[field];
|
|
1112
|
+
if (value !== void 0) children.push(`<x:${field}>${stringifyVmlTrueFalseBlank(value)}</x:${field}>`);
|
|
1113
|
+
}
|
|
1114
|
+
for (const field of INTEGER_FIELDS) {
|
|
1115
|
+
const value = opts[field];
|
|
1116
|
+
if (value !== void 0) children.push(`<x:${field}>${value}</x:${field}>`);
|
|
1117
|
+
}
|
|
1118
|
+
for (const field of STRING_FIELDS) {
|
|
1119
|
+
const value = opts[field];
|
|
1120
|
+
if (value !== void 0) children.push(`<x:${field}>${escapeXml(value)}</x:${field}>`);
|
|
1121
|
+
}
|
|
1122
|
+
return `<x:ClientData ObjectType="${opts.objectType}">${children.join("")}</x:ClientData>`;
|
|
1123
|
+
}
|
|
1124
|
+
/** Parse an x:ClientData element. */
|
|
1125
|
+
function parseVmlClientData(el) {
|
|
1126
|
+
const out = { objectType: String(el.attributes?.ObjectType ?? "") };
|
|
1127
|
+
const extras = {};
|
|
1128
|
+
for (const child of el.elements ?? []) {
|
|
1129
|
+
if (child.type !== "element") continue;
|
|
1130
|
+
const local = child.name?.startsWith("x:") ? child.name.slice(2) : null;
|
|
1131
|
+
if (local === null) continue;
|
|
1132
|
+
const text = (child.elements ?? []).map((c) => String(c.text ?? "")).join("");
|
|
1133
|
+
if (TRUE_FALSE_BLANK_FIELD_SET.has(local)) extras[local] = parseVmlTrueFalseBlank(text);
|
|
1134
|
+
else if (INTEGER_FIELD_SET.has(local)) extras[local] = Number(text);
|
|
1135
|
+
else if (STRING_FIELD_SET.has(local)) extras[local] = text;
|
|
1136
|
+
}
|
|
1137
|
+
return Object.assign(out, extras);
|
|
1138
|
+
}
|
|
1139
|
+
//#endregion
|
|
1140
|
+
//#region src/vector/shape-elements/fill.ts
|
|
1141
|
+
const FILL_ATTRS = [
|
|
1142
|
+
{
|
|
1143
|
+
field: "id",
|
|
1144
|
+
attr: "id",
|
|
1145
|
+
kind: "string"
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
field: "type",
|
|
1149
|
+
attr: "type",
|
|
1150
|
+
kind: "string"
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
field: "on",
|
|
1154
|
+
attr: "on",
|
|
1155
|
+
kind: "trueFalse"
|
|
1156
|
+
},
|
|
1157
|
+
{
|
|
1158
|
+
field: "color",
|
|
1159
|
+
attr: "color",
|
|
1160
|
+
kind: "string"
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
field: "opacity",
|
|
1164
|
+
attr: "opacity",
|
|
1165
|
+
kind: "string"
|
|
1166
|
+
},
|
|
1167
|
+
{
|
|
1168
|
+
field: "color2",
|
|
1169
|
+
attr: "color2",
|
|
1170
|
+
kind: "string"
|
|
1171
|
+
},
|
|
1172
|
+
{
|
|
1173
|
+
field: "src",
|
|
1174
|
+
attr: "src",
|
|
1175
|
+
kind: "string"
|
|
1176
|
+
},
|
|
1177
|
+
{
|
|
1178
|
+
field: "size",
|
|
1179
|
+
attr: "size",
|
|
1180
|
+
kind: "string"
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
field: "origin",
|
|
1184
|
+
attr: "origin",
|
|
1185
|
+
kind: "string"
|
|
1186
|
+
},
|
|
1187
|
+
{
|
|
1188
|
+
field: "position",
|
|
1189
|
+
attr: "position",
|
|
1190
|
+
kind: "string"
|
|
1191
|
+
},
|
|
1192
|
+
{
|
|
1193
|
+
field: "aspect",
|
|
1194
|
+
attr: "aspect",
|
|
1195
|
+
kind: "string"
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
field: "colors",
|
|
1199
|
+
attr: "colors",
|
|
1200
|
+
kind: "string"
|
|
1201
|
+
},
|
|
1202
|
+
{
|
|
1203
|
+
field: "angle",
|
|
1204
|
+
attr: "angle",
|
|
1205
|
+
kind: "number"
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
field: "alignshape",
|
|
1209
|
+
attr: "alignshape",
|
|
1210
|
+
kind: "trueFalse"
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
field: "focus",
|
|
1214
|
+
attr: "focus",
|
|
1215
|
+
kind: "string"
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
field: "focussize",
|
|
1219
|
+
attr: "focussize",
|
|
1220
|
+
kind: "string"
|
|
1221
|
+
},
|
|
1222
|
+
{
|
|
1223
|
+
field: "focusposition",
|
|
1224
|
+
attr: "focusposition",
|
|
1225
|
+
kind: "string"
|
|
1226
|
+
},
|
|
1227
|
+
{
|
|
1228
|
+
field: "method",
|
|
1229
|
+
attr: "method",
|
|
1230
|
+
kind: "string"
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
field: "recolor",
|
|
1234
|
+
attr: "recolor",
|
|
1235
|
+
kind: "trueFalse"
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
field: "rotate",
|
|
1239
|
+
attr: "rotate",
|
|
1240
|
+
kind: "trueFalse"
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
field: "relationshipId",
|
|
1244
|
+
attr: "r:id",
|
|
1245
|
+
kind: "string"
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
field: "officeHref",
|
|
1249
|
+
attr: "o:href",
|
|
1250
|
+
kind: "string"
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
field: "officeAltHref",
|
|
1254
|
+
attr: "o:althref",
|
|
1255
|
+
kind: "string"
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
field: "detectmouseclick",
|
|
1259
|
+
attr: "o:detectmouseclick",
|
|
1260
|
+
kind: "trueFalse"
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
field: "officeTitle",
|
|
1264
|
+
attr: "o:title",
|
|
1265
|
+
kind: "string"
|
|
1266
|
+
},
|
|
1267
|
+
{
|
|
1268
|
+
field: "opacity2",
|
|
1269
|
+
attr: "o:opacity2",
|
|
1270
|
+
kind: "string"
|
|
1271
|
+
},
|
|
1272
|
+
{
|
|
1273
|
+
field: "officeRelationshipId",
|
|
1274
|
+
attr: "o:relid",
|
|
1275
|
+
kind: "string"
|
|
1276
|
+
}
|
|
1277
|
+
];
|
|
1278
|
+
/** Serialize v:fill. */
|
|
1279
|
+
function stringifyVmlFill(opts) {
|
|
1280
|
+
const child = opts.officeFill !== void 0 ? stringifyVmlOfficeFill(opts.officeFill) : "";
|
|
1281
|
+
const attrStr = stringifyVmlAttributes(opts, FILL_ATTRS);
|
|
1282
|
+
return child !== "" ? `<v:fill${attrStr}>${child}</v:fill>` : `<v:fill${attrStr}/>`;
|
|
1283
|
+
}
|
|
1284
|
+
/** Parse a v:fill element. */
|
|
1285
|
+
function parseVmlFill(el) {
|
|
1286
|
+
const out = {};
|
|
1287
|
+
parseVmlAttributes(el, FILL_ATTRS, out);
|
|
1288
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "o:fill") {
|
|
1289
|
+
out.officeFill = parseVmlOfficeFill(child);
|
|
1290
|
+
break;
|
|
1291
|
+
}
|
|
1292
|
+
return out;
|
|
1293
|
+
}
|
|
1294
|
+
//#endregion
|
|
1295
|
+
//#region src/vector/shape-elements/formulas.ts
|
|
1296
|
+
/** Serialize v:formulas. */
|
|
1297
|
+
function stringifyVmlFormulas(opts) {
|
|
1298
|
+
return `<v:formulas>${(opts.equations ?? []).map((eqn) => `<v:f eqn="${escapeXml(eqn)}"/>`).join("")}</v:formulas>`;
|
|
1299
|
+
}
|
|
1300
|
+
/** Parse a v:formulas element. */
|
|
1301
|
+
function parseVmlFormulas(el) {
|
|
1302
|
+
const equations = [];
|
|
1303
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "v:f") {
|
|
1304
|
+
const eqn = child.attributes?.eqn;
|
|
1305
|
+
if (eqn !== void 0) equations.push(String(eqn));
|
|
1306
|
+
}
|
|
1307
|
+
return equations.length > 0 ? { equations } : {};
|
|
1308
|
+
}
|
|
1309
|
+
//#endregion
|
|
1310
|
+
//#region src/vector/shape-elements/handles.ts
|
|
1311
|
+
const HANDLE_STRING_FIELDS = [
|
|
1312
|
+
"position",
|
|
1313
|
+
"polar",
|
|
1314
|
+
"map",
|
|
1315
|
+
"xrange",
|
|
1316
|
+
"yrange",
|
|
1317
|
+
"radiusrange"
|
|
1318
|
+
];
|
|
1319
|
+
const HANDLE_BOOLEAN_FIELDS = [
|
|
1320
|
+
"invx",
|
|
1321
|
+
"invy",
|
|
1322
|
+
"switch"
|
|
1323
|
+
];
|
|
1324
|
+
/** Serialize v:handles. */
|
|
1325
|
+
function stringifyVmlHandles(opts) {
|
|
1326
|
+
return `<v:handles>${(opts.handles ?? []).map((handle) => {
|
|
1327
|
+
const attrs = [];
|
|
1328
|
+
for (const field of HANDLE_STRING_FIELDS) {
|
|
1329
|
+
const value = handle[field];
|
|
1330
|
+
if (value !== void 0) attrs.push(`${field}="${escapeXml(value)}"`);
|
|
1331
|
+
}
|
|
1332
|
+
for (const field of HANDLE_BOOLEAN_FIELDS) {
|
|
1333
|
+
const value = handle[field];
|
|
1334
|
+
if (value !== void 0) attrs.push(`${field}="${stringifyVmlTrueFalse(value)}"`);
|
|
1335
|
+
}
|
|
1336
|
+
return `<v:h${attrs.length > 0 ? ` ${attrs.join(" ")}` : ""}/>`;
|
|
1337
|
+
}).join("")}</v:handles>`;
|
|
1338
|
+
}
|
|
1339
|
+
/** Parse a v:handles element. */
|
|
1340
|
+
function parseVmlHandles(el) {
|
|
1341
|
+
const handles = [];
|
|
1342
|
+
for (const child of el.elements ?? []) {
|
|
1343
|
+
if (child.type !== "element" || child.name !== "v:h") continue;
|
|
1344
|
+
const handle = {};
|
|
1345
|
+
const attrs = child.attributes ?? {};
|
|
1346
|
+
for (const field of HANDLE_STRING_FIELDS) {
|
|
1347
|
+
const raw = attrs[field];
|
|
1348
|
+
if (raw !== void 0) handle[field] = String(raw);
|
|
1349
|
+
}
|
|
1350
|
+
for (const field of HANDLE_BOOLEAN_FIELDS) {
|
|
1351
|
+
const raw = attrs[field];
|
|
1352
|
+
if (raw !== void 0) handle[field] = parseVmlTrueFalse(String(raw));
|
|
1353
|
+
}
|
|
1354
|
+
handles.push(handle);
|
|
1355
|
+
}
|
|
1356
|
+
return handles.length > 0 ? { handles } : {};
|
|
1357
|
+
}
|
|
1358
|
+
//#endregion
|
|
1359
|
+
//#region src/vector/shape-elements/imagedata.ts
|
|
1360
|
+
const IMAGEDATA_ATTRS = [
|
|
1361
|
+
{
|
|
1362
|
+
field: "id",
|
|
1363
|
+
attr: "id",
|
|
1364
|
+
kind: "string"
|
|
1365
|
+
},
|
|
1366
|
+
{
|
|
1367
|
+
field: "src",
|
|
1368
|
+
attr: "src",
|
|
1369
|
+
kind: "string"
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
field: "cropleft",
|
|
1373
|
+
attr: "cropleft",
|
|
1374
|
+
kind: "string"
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
field: "croptop",
|
|
1378
|
+
attr: "croptop",
|
|
1379
|
+
kind: "string"
|
|
1380
|
+
},
|
|
1381
|
+
{
|
|
1382
|
+
field: "cropright",
|
|
1383
|
+
attr: "cropright",
|
|
1384
|
+
kind: "string"
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
field: "cropbottom",
|
|
1388
|
+
attr: "cropbottom",
|
|
1389
|
+
kind: "string"
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
field: "gain",
|
|
1393
|
+
attr: "gain",
|
|
1394
|
+
kind: "string"
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
field: "blacklevel",
|
|
1398
|
+
attr: "blacklevel",
|
|
1399
|
+
kind: "string"
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
field: "gamma",
|
|
1403
|
+
attr: "gamma",
|
|
1404
|
+
kind: "string"
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
field: "grayscale",
|
|
1408
|
+
attr: "grayscale",
|
|
1409
|
+
kind: "trueFalse"
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
field: "bilevel",
|
|
1413
|
+
attr: "bilevel",
|
|
1414
|
+
kind: "trueFalse"
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
field: "chromakey",
|
|
1418
|
+
attr: "chromakey",
|
|
1419
|
+
kind: "string"
|
|
1420
|
+
},
|
|
1421
|
+
{
|
|
1422
|
+
field: "embosscolor",
|
|
1423
|
+
attr: "embosscolor",
|
|
1424
|
+
kind: "string"
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
field: "recolortarget",
|
|
1428
|
+
attr: "recolortarget",
|
|
1429
|
+
kind: "string"
|
|
1430
|
+
},
|
|
1431
|
+
{
|
|
1432
|
+
field: "relationshipId",
|
|
1433
|
+
attr: "r:id",
|
|
1434
|
+
kind: "string"
|
|
1435
|
+
},
|
|
1436
|
+
{
|
|
1437
|
+
field: "pictRelationshipId",
|
|
1438
|
+
attr: "r:pict",
|
|
1439
|
+
kind: "string"
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
field: "hrefRelationshipId",
|
|
1443
|
+
attr: "r:href",
|
|
1444
|
+
kind: "string"
|
|
1445
|
+
},
|
|
1446
|
+
{
|
|
1447
|
+
field: "officeHref",
|
|
1448
|
+
attr: "o:href",
|
|
1449
|
+
kind: "string"
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
field: "officeAltHref",
|
|
1453
|
+
attr: "o:althref",
|
|
1454
|
+
kind: "string"
|
|
1455
|
+
},
|
|
1456
|
+
{
|
|
1457
|
+
field: "officeTitle",
|
|
1458
|
+
attr: "o:title",
|
|
1459
|
+
kind: "string"
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
field: "oleid",
|
|
1463
|
+
attr: "o:oleid",
|
|
1464
|
+
kind: "number"
|
|
1465
|
+
},
|
|
1466
|
+
{
|
|
1467
|
+
field: "detectmouseclick",
|
|
1468
|
+
attr: "o:detectmouseclick",
|
|
1469
|
+
kind: "trueFalse"
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
field: "movie",
|
|
1473
|
+
attr: "o:movie",
|
|
1474
|
+
kind: "number"
|
|
1475
|
+
},
|
|
1476
|
+
{
|
|
1477
|
+
field: "officeRelationshipId",
|
|
1478
|
+
attr: "o:relid",
|
|
1479
|
+
kind: "string"
|
|
1480
|
+
}
|
|
1481
|
+
];
|
|
1482
|
+
/** Serialize v:imagedata. */
|
|
1483
|
+
function stringifyVmlImageData(opts) {
|
|
1484
|
+
return `<v:imagedata${stringifyVmlAttributes(opts, IMAGEDATA_ATTRS)}/>`;
|
|
1485
|
+
}
|
|
1486
|
+
/** Parse a v:imagedata element. */
|
|
1487
|
+
function parseVmlImageData(el) {
|
|
1488
|
+
const out = {};
|
|
1489
|
+
parseVmlAttributes(el, IMAGEDATA_ATTRS, out);
|
|
1490
|
+
return out;
|
|
1491
|
+
}
|
|
1492
|
+
//#endregion
|
|
1493
|
+
//#region src/vector/shape-elements/path.ts
|
|
1494
|
+
const PATH_ATTRS = [
|
|
1495
|
+
{
|
|
1496
|
+
field: "id",
|
|
1497
|
+
attr: "id",
|
|
1498
|
+
kind: "string"
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
field: "v",
|
|
1502
|
+
attr: "v",
|
|
1503
|
+
kind: "string"
|
|
1504
|
+
},
|
|
1505
|
+
{
|
|
1506
|
+
field: "limo",
|
|
1507
|
+
attr: "limo",
|
|
1508
|
+
kind: "string"
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
field: "textboxrect",
|
|
1512
|
+
attr: "textboxrect",
|
|
1513
|
+
kind: "string"
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
field: "fillok",
|
|
1517
|
+
attr: "fillok",
|
|
1518
|
+
kind: "trueFalse"
|
|
1519
|
+
},
|
|
1520
|
+
{
|
|
1521
|
+
field: "strokeok",
|
|
1522
|
+
attr: "strokeok",
|
|
1523
|
+
kind: "trueFalse"
|
|
1524
|
+
},
|
|
1525
|
+
{
|
|
1526
|
+
field: "shadowok",
|
|
1527
|
+
attr: "shadowok",
|
|
1528
|
+
kind: "trueFalse"
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
field: "arrowok",
|
|
1532
|
+
attr: "arrowok",
|
|
1533
|
+
kind: "trueFalse"
|
|
1534
|
+
},
|
|
1535
|
+
{
|
|
1536
|
+
field: "gradientshapeok",
|
|
1537
|
+
attr: "gradientshapeok",
|
|
1538
|
+
kind: "trueFalse"
|
|
1539
|
+
},
|
|
1540
|
+
{
|
|
1541
|
+
field: "textpathok",
|
|
1542
|
+
attr: "textpathok",
|
|
1543
|
+
kind: "trueFalse"
|
|
1544
|
+
},
|
|
1545
|
+
{
|
|
1546
|
+
field: "insetpenok",
|
|
1547
|
+
attr: "insetpenok",
|
|
1548
|
+
kind: "trueFalse"
|
|
1549
|
+
},
|
|
1550
|
+
{
|
|
1551
|
+
field: "connecttype",
|
|
1552
|
+
attr: "o:connecttype",
|
|
1553
|
+
kind: "string"
|
|
1554
|
+
},
|
|
1555
|
+
{
|
|
1556
|
+
field: "connectlocs",
|
|
1557
|
+
attr: "o:connectlocs",
|
|
1558
|
+
kind: "string"
|
|
1559
|
+
},
|
|
1560
|
+
{
|
|
1561
|
+
field: "connectangles",
|
|
1562
|
+
attr: "o:connectangles",
|
|
1563
|
+
kind: "string"
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
field: "extrusionok",
|
|
1567
|
+
attr: "o:extrusionok",
|
|
1568
|
+
kind: "trueFalse"
|
|
1569
|
+
}
|
|
1570
|
+
];
|
|
1571
|
+
/** Serialize v:path. */
|
|
1572
|
+
function stringifyVmlPath(opts) {
|
|
1573
|
+
return `<v:path${stringifyVmlAttributes(opts, PATH_ATTRS)}/>`;
|
|
1574
|
+
}
|
|
1575
|
+
/** Parse a v:path element. */
|
|
1576
|
+
function parseVmlPath(el) {
|
|
1577
|
+
const out = {};
|
|
1578
|
+
parseVmlAttributes(el, PATH_ATTRS, out);
|
|
1579
|
+
return out;
|
|
1580
|
+
}
|
|
1581
|
+
//#endregion
|
|
1582
|
+
//#region src/vector/shape-elements/presentation-elements.ts
|
|
1583
|
+
/** Serialize pvml:iscomment. */
|
|
1584
|
+
function stringifyVmlIsComment(_opts) {
|
|
1585
|
+
return "<pvml:iscomment/>";
|
|
1586
|
+
}
|
|
1587
|
+
/** Parse a pvml:iscomment element. */
|
|
1588
|
+
function parseVmlIsComment(_el) {
|
|
1589
|
+
return {};
|
|
1590
|
+
}
|
|
1591
|
+
/** Serialize pvml:textdata. */
|
|
1592
|
+
function stringifyVmlTextData(opts) {
|
|
1593
|
+
return opts.id !== void 0 ? `<pvml:textdata id="${opts.id}"/>` : "<pvml:textdata/>";
|
|
1594
|
+
}
|
|
1595
|
+
/** Parse a pvml:textdata element. */
|
|
1596
|
+
function parseVmlTextData(el) {
|
|
1597
|
+
const id = el.attributes?.id;
|
|
1598
|
+
return id !== void 0 ? { id: String(id) } : {};
|
|
1599
|
+
}
|
|
1600
|
+
//#endregion
|
|
1601
|
+
//#region src/vector/shape-elements/shadow.ts
|
|
1602
|
+
const SHADOW_ATTRS = [
|
|
1603
|
+
{
|
|
1604
|
+
field: "id",
|
|
1605
|
+
attr: "id",
|
|
1606
|
+
kind: "string"
|
|
1607
|
+
},
|
|
1608
|
+
{
|
|
1609
|
+
field: "on",
|
|
1610
|
+
attr: "on",
|
|
1611
|
+
kind: "trueFalse"
|
|
1612
|
+
},
|
|
1613
|
+
{
|
|
1614
|
+
field: "type",
|
|
1615
|
+
attr: "type",
|
|
1616
|
+
kind: "string"
|
|
1617
|
+
},
|
|
1618
|
+
{
|
|
1619
|
+
field: "obscured",
|
|
1620
|
+
attr: "obscured",
|
|
1621
|
+
kind: "trueFalse"
|
|
1622
|
+
},
|
|
1623
|
+
{
|
|
1624
|
+
field: "color",
|
|
1625
|
+
attr: "color",
|
|
1626
|
+
kind: "string"
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
field: "opacity",
|
|
1630
|
+
attr: "opacity",
|
|
1631
|
+
kind: "string"
|
|
1632
|
+
},
|
|
1633
|
+
{
|
|
1634
|
+
field: "offset",
|
|
1635
|
+
attr: "offset",
|
|
1636
|
+
kind: "string"
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
field: "color2",
|
|
1640
|
+
attr: "color2",
|
|
1641
|
+
kind: "string"
|
|
1642
|
+
},
|
|
1643
|
+
{
|
|
1644
|
+
field: "offset2",
|
|
1645
|
+
attr: "offset2",
|
|
1646
|
+
kind: "string"
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
field: "origin",
|
|
1650
|
+
attr: "origin",
|
|
1651
|
+
kind: "string"
|
|
1652
|
+
},
|
|
1653
|
+
{
|
|
1654
|
+
field: "matrix",
|
|
1655
|
+
attr: "matrix",
|
|
1656
|
+
kind: "string"
|
|
1657
|
+
}
|
|
1658
|
+
];
|
|
1659
|
+
/** Serialize v:shadow. */
|
|
1660
|
+
function stringifyVmlShadow(opts) {
|
|
1661
|
+
return `<v:shadow${stringifyVmlAttributes(opts, SHADOW_ATTRS)}/>`;
|
|
1662
|
+
}
|
|
1663
|
+
/** Parse a v:shadow element. */
|
|
1664
|
+
function parseVmlShadow(el) {
|
|
1665
|
+
const out = {};
|
|
1666
|
+
parseVmlAttributes(el, SHADOW_ATTRS, out);
|
|
1667
|
+
return out;
|
|
1668
|
+
}
|
|
1669
|
+
//#endregion
|
|
1670
|
+
//#region src/vector/shape-elements/stroke.ts
|
|
1671
|
+
const STROKE_ATTRS = [
|
|
1672
|
+
{
|
|
1673
|
+
field: "id",
|
|
1674
|
+
attr: "id",
|
|
1675
|
+
kind: "string"
|
|
1676
|
+
},
|
|
1677
|
+
{
|
|
1678
|
+
field: "on",
|
|
1679
|
+
attr: "on",
|
|
1680
|
+
kind: "trueFalse"
|
|
1681
|
+
},
|
|
1682
|
+
{
|
|
1683
|
+
field: "weight",
|
|
1684
|
+
attr: "weight",
|
|
1685
|
+
kind: "string"
|
|
1686
|
+
},
|
|
1687
|
+
{
|
|
1688
|
+
field: "color",
|
|
1689
|
+
attr: "color",
|
|
1690
|
+
kind: "string"
|
|
1691
|
+
},
|
|
1692
|
+
{
|
|
1693
|
+
field: "opacity",
|
|
1694
|
+
attr: "opacity",
|
|
1695
|
+
kind: "string"
|
|
1696
|
+
},
|
|
1697
|
+
{
|
|
1698
|
+
field: "linestyle",
|
|
1699
|
+
attr: "linestyle",
|
|
1700
|
+
kind: "string"
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
field: "miterlimit",
|
|
1704
|
+
attr: "miterlimit",
|
|
1705
|
+
kind: "number"
|
|
1706
|
+
},
|
|
1707
|
+
{
|
|
1708
|
+
field: "joinstyle",
|
|
1709
|
+
attr: "joinstyle",
|
|
1710
|
+
kind: "string"
|
|
1711
|
+
},
|
|
1712
|
+
{
|
|
1713
|
+
field: "endcap",
|
|
1714
|
+
attr: "endcap",
|
|
1715
|
+
kind: "string"
|
|
1716
|
+
},
|
|
1717
|
+
{
|
|
1718
|
+
field: "dashstyle",
|
|
1719
|
+
attr: "dashstyle",
|
|
1720
|
+
kind: "string"
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
field: "filltype",
|
|
1724
|
+
attr: "filltype",
|
|
1725
|
+
kind: "string"
|
|
1726
|
+
},
|
|
1727
|
+
{
|
|
1728
|
+
field: "src",
|
|
1729
|
+
attr: "src",
|
|
1730
|
+
kind: "string"
|
|
1731
|
+
},
|
|
1732
|
+
{
|
|
1733
|
+
field: "imageaspect",
|
|
1734
|
+
attr: "imageaspect",
|
|
1735
|
+
kind: "string"
|
|
1736
|
+
},
|
|
1737
|
+
{
|
|
1738
|
+
field: "imagesize",
|
|
1739
|
+
attr: "imagesize",
|
|
1740
|
+
kind: "string"
|
|
1741
|
+
},
|
|
1742
|
+
{
|
|
1743
|
+
field: "imagealignshape",
|
|
1744
|
+
attr: "imagealignshape",
|
|
1745
|
+
kind: "trueFalse"
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1748
|
+
field: "color2",
|
|
1749
|
+
attr: "color2",
|
|
1750
|
+
kind: "string"
|
|
1751
|
+
},
|
|
1752
|
+
{
|
|
1753
|
+
field: "startarrow",
|
|
1754
|
+
attr: "startarrow",
|
|
1755
|
+
kind: "string"
|
|
1756
|
+
},
|
|
1757
|
+
{
|
|
1758
|
+
field: "startarrowwidth",
|
|
1759
|
+
attr: "startarrowwidth",
|
|
1760
|
+
kind: "string"
|
|
1761
|
+
},
|
|
1762
|
+
{
|
|
1763
|
+
field: "startarrowlength",
|
|
1764
|
+
attr: "startarrowlength",
|
|
1765
|
+
kind: "string"
|
|
1766
|
+
},
|
|
1767
|
+
{
|
|
1768
|
+
field: "endarrow",
|
|
1769
|
+
attr: "endarrow",
|
|
1770
|
+
kind: "string"
|
|
1771
|
+
},
|
|
1772
|
+
{
|
|
1773
|
+
field: "endarrowwidth",
|
|
1774
|
+
attr: "endarrowwidth",
|
|
1775
|
+
kind: "string"
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
field: "endarrowlength",
|
|
1779
|
+
attr: "endarrowlength",
|
|
1780
|
+
kind: "string"
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
field: "relationshipId",
|
|
1784
|
+
attr: "r:id",
|
|
1785
|
+
kind: "string"
|
|
1786
|
+
},
|
|
1787
|
+
{
|
|
1788
|
+
field: "insetpen",
|
|
1789
|
+
attr: "insetpen",
|
|
1790
|
+
kind: "trueFalse"
|
|
1791
|
+
},
|
|
1792
|
+
{
|
|
1793
|
+
field: "officeHref",
|
|
1794
|
+
attr: "o:href",
|
|
1795
|
+
kind: "string"
|
|
1796
|
+
},
|
|
1797
|
+
{
|
|
1798
|
+
field: "officeAltHref",
|
|
1799
|
+
attr: "o:althref",
|
|
1800
|
+
kind: "string"
|
|
1801
|
+
},
|
|
1802
|
+
{
|
|
1803
|
+
field: "officeTitle",
|
|
1804
|
+
attr: "o:title",
|
|
1805
|
+
kind: "string"
|
|
1806
|
+
},
|
|
1807
|
+
{
|
|
1808
|
+
field: "forcedash",
|
|
1809
|
+
attr: "o:forcedash",
|
|
1810
|
+
kind: "trueFalse"
|
|
1811
|
+
},
|
|
1812
|
+
{
|
|
1813
|
+
field: "officeRelationshipId",
|
|
1814
|
+
attr: "o:relid",
|
|
1815
|
+
kind: "string"
|
|
1816
|
+
}
|
|
1817
|
+
];
|
|
1818
|
+
const STROKE_CHILD_ATTRS = [
|
|
1819
|
+
{
|
|
1820
|
+
field: "ext",
|
|
1821
|
+
attr: "v:ext",
|
|
1822
|
+
kind: "string"
|
|
1823
|
+
},
|
|
1824
|
+
{
|
|
1825
|
+
field: "on",
|
|
1826
|
+
attr: "on",
|
|
1827
|
+
kind: "trueFalse"
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
field: "weight",
|
|
1831
|
+
attr: "weight",
|
|
1832
|
+
kind: "string"
|
|
1833
|
+
},
|
|
1834
|
+
{
|
|
1835
|
+
field: "color",
|
|
1836
|
+
attr: "color",
|
|
1837
|
+
kind: "string"
|
|
1838
|
+
},
|
|
1839
|
+
{
|
|
1840
|
+
field: "color2",
|
|
1841
|
+
attr: "color2",
|
|
1842
|
+
kind: "string"
|
|
1843
|
+
},
|
|
1844
|
+
{
|
|
1845
|
+
field: "opacity",
|
|
1846
|
+
attr: "opacity",
|
|
1847
|
+
kind: "string"
|
|
1848
|
+
},
|
|
1849
|
+
{
|
|
1850
|
+
field: "linestyle",
|
|
1851
|
+
attr: "linestyle",
|
|
1852
|
+
kind: "string"
|
|
1853
|
+
},
|
|
1854
|
+
{
|
|
1855
|
+
field: "miterlimit",
|
|
1856
|
+
attr: "miterlimit",
|
|
1857
|
+
kind: "number"
|
|
1858
|
+
},
|
|
1859
|
+
{
|
|
1860
|
+
field: "joinstyle",
|
|
1861
|
+
attr: "joinstyle",
|
|
1862
|
+
kind: "string"
|
|
1863
|
+
},
|
|
1864
|
+
{
|
|
1865
|
+
field: "endcap",
|
|
1866
|
+
attr: "endcap",
|
|
1867
|
+
kind: "string"
|
|
1868
|
+
},
|
|
1869
|
+
{
|
|
1870
|
+
field: "dashstyle",
|
|
1871
|
+
attr: "dashstyle",
|
|
1872
|
+
kind: "string"
|
|
1873
|
+
},
|
|
1874
|
+
{
|
|
1875
|
+
field: "insetpen",
|
|
1876
|
+
attr: "insetpen",
|
|
1877
|
+
kind: "trueFalse"
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
field: "filltype",
|
|
1881
|
+
attr: "filltype",
|
|
1882
|
+
kind: "string"
|
|
1883
|
+
},
|
|
1884
|
+
{
|
|
1885
|
+
field: "src",
|
|
1886
|
+
attr: "src",
|
|
1887
|
+
kind: "string"
|
|
1888
|
+
},
|
|
1889
|
+
{
|
|
1890
|
+
field: "imageaspect",
|
|
1891
|
+
attr: "imageaspect",
|
|
1892
|
+
kind: "string"
|
|
1893
|
+
},
|
|
1894
|
+
{
|
|
1895
|
+
field: "imagesize",
|
|
1896
|
+
attr: "imagesize",
|
|
1897
|
+
kind: "string"
|
|
1898
|
+
},
|
|
1899
|
+
{
|
|
1900
|
+
field: "imagealignshape",
|
|
1901
|
+
attr: "imagealignshape",
|
|
1902
|
+
kind: "trueFalse"
|
|
1903
|
+
},
|
|
1904
|
+
{
|
|
1905
|
+
field: "startarrow",
|
|
1906
|
+
attr: "startarrow",
|
|
1907
|
+
kind: "string"
|
|
1908
|
+
},
|
|
1909
|
+
{
|
|
1910
|
+
field: "startarrowwidth",
|
|
1911
|
+
attr: "startarrowwidth",
|
|
1912
|
+
kind: "string"
|
|
1913
|
+
},
|
|
1914
|
+
{
|
|
1915
|
+
field: "startarrowlength",
|
|
1916
|
+
attr: "startarrowlength",
|
|
1917
|
+
kind: "string"
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
field: "endarrow",
|
|
1921
|
+
attr: "endarrow",
|
|
1922
|
+
kind: "string"
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
field: "endarrowwidth",
|
|
1926
|
+
attr: "endarrowwidth",
|
|
1927
|
+
kind: "string"
|
|
1928
|
+
},
|
|
1929
|
+
{
|
|
1930
|
+
field: "endarrowlength",
|
|
1931
|
+
attr: "endarrowlength",
|
|
1932
|
+
kind: "string"
|
|
1933
|
+
},
|
|
1934
|
+
{
|
|
1935
|
+
field: "officeHref",
|
|
1936
|
+
attr: "o:href",
|
|
1937
|
+
kind: "string"
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
field: "officeAltHref",
|
|
1941
|
+
attr: "o:althref",
|
|
1942
|
+
kind: "string"
|
|
1943
|
+
},
|
|
1944
|
+
{
|
|
1945
|
+
field: "officeTitle",
|
|
1946
|
+
attr: "o:title",
|
|
1947
|
+
kind: "string"
|
|
1948
|
+
},
|
|
1949
|
+
{
|
|
1950
|
+
field: "forcedash",
|
|
1951
|
+
attr: "o:forcedash",
|
|
1952
|
+
kind: "trueFalse"
|
|
1953
|
+
}
|
|
1954
|
+
];
|
|
1955
|
+
/** Serialize an o:left/top/right/bottom/column sub-stroke. */
|
|
1956
|
+
function stringifyVmlStrokeChild(tag, opts) {
|
|
1957
|
+
return `<${tag}${stringifyVmlAttributes(opts, STROKE_CHILD_ATTRS)}/>`;
|
|
1958
|
+
}
|
|
1959
|
+
/** Parse an o: sub-stroke child of v:stroke. */
|
|
1960
|
+
function parseVmlStrokeChild(el) {
|
|
1961
|
+
const out = {};
|
|
1962
|
+
parseVmlAttributes(el, STROKE_CHILD_ATTRS, out);
|
|
1963
|
+
return out;
|
|
1964
|
+
}
|
|
1965
|
+
/** Serialize v:stroke. */
|
|
1966
|
+
function stringifyVmlStroke(opts) {
|
|
1967
|
+
const children = [];
|
|
1968
|
+
if (opts.leftStroke !== void 0) children.push(stringifyVmlStrokeChild("o:left", opts.leftStroke));
|
|
1969
|
+
if (opts.topStroke !== void 0) children.push(stringifyVmlStrokeChild("o:top", opts.topStroke));
|
|
1970
|
+
if (opts.rightStroke !== void 0) children.push(stringifyVmlStrokeChild("o:right", opts.rightStroke));
|
|
1971
|
+
if (opts.bottomStroke !== void 0) children.push(stringifyVmlStrokeChild("o:bottom", opts.bottomStroke));
|
|
1972
|
+
if (opts.columnStroke !== void 0) children.push(stringifyVmlStrokeChild("o:column", opts.columnStroke));
|
|
1973
|
+
const attrStr = stringifyVmlAttributes(opts, STROKE_ATTRS);
|
|
1974
|
+
return children.length > 0 ? `<v:stroke${attrStr}>${children.join("")}</v:stroke>` : `<v:stroke${attrStr}/>`;
|
|
1975
|
+
}
|
|
1976
|
+
/** Parse a v:stroke element. */
|
|
1977
|
+
function parseVmlStroke(el) {
|
|
1978
|
+
const out = {};
|
|
1979
|
+
parseVmlAttributes(el, STROKE_ATTRS, out);
|
|
1980
|
+
for (const child of el.elements ?? []) {
|
|
1981
|
+
if (child.type !== "element") continue;
|
|
1982
|
+
switch (child.name) {
|
|
1983
|
+
case "o:left":
|
|
1984
|
+
out.leftStroke = parseVmlStrokeChild(child);
|
|
1985
|
+
break;
|
|
1986
|
+
case "o:top":
|
|
1987
|
+
out.topStroke = parseVmlStrokeChild(child);
|
|
1988
|
+
break;
|
|
1989
|
+
case "o:right":
|
|
1990
|
+
out.rightStroke = parseVmlStrokeChild(child);
|
|
1991
|
+
break;
|
|
1992
|
+
case "o:bottom":
|
|
1993
|
+
out.bottomStroke = parseVmlStrokeChild(child);
|
|
1994
|
+
break;
|
|
1995
|
+
case "o:column": out.columnStroke = parseVmlStrokeChild(child);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
return out;
|
|
1999
|
+
}
|
|
2000
|
+
//#endregion
|
|
2001
|
+
//#region src/vector/shape-elements/textbox.ts
|
|
2002
|
+
/**
|
|
2003
|
+
* Serialize v:textbox. Exactly one content form is emitted when present
|
|
2004
|
+
* (txbxContent wins if both are set, matching the XSD choice).
|
|
2005
|
+
*/
|
|
2006
|
+
function stringifyVmlTextbox(opts) {
|
|
2007
|
+
const attrs = [];
|
|
2008
|
+
if (opts.id !== void 0) attrs.push(`id="${escapeXml(opts.id)}"`);
|
|
2009
|
+
if (opts.style !== void 0) attrs.push(`style="${escapeXml(stringifyVmlStyle(opts.style))}"`);
|
|
2010
|
+
if (opts.inset !== void 0) attrs.push(`inset="${escapeXml(opts.inset)}"`);
|
|
2011
|
+
if (opts.singleclick !== void 0) attrs.push(`o:singleclick="${stringifyVmlTrueFalse(opts.singleclick)}"`);
|
|
2012
|
+
if (opts.insetmode !== void 0) attrs.push(`o:insetmode="${opts.insetmode}"`);
|
|
2013
|
+
const attrStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
|
|
2014
|
+
if (opts.txbxContent !== void 0) return `<v:textbox${attrStr}><w:txbxContent>${opts.txbxContent}</w:txbxContent></v:textbox>`;
|
|
2015
|
+
if (opts.content !== void 0) return `<v:textbox${attrStr}>${opts.content}</v:textbox>`;
|
|
2016
|
+
return `<v:textbox${attrStr}/>`;
|
|
2017
|
+
}
|
|
2018
|
+
/** Parse a v:textbox element. */
|
|
2019
|
+
function parseVmlTextbox(el) {
|
|
2020
|
+
const out = {};
|
|
2021
|
+
const attrs = el.attributes ?? {};
|
|
2022
|
+
if (attrs.id !== void 0) out.id = String(attrs.id);
|
|
2023
|
+
if (attrs.style !== void 0) out.style = parseVmlShapeStyle(parseVmlStyle(String(attrs.style)));
|
|
2024
|
+
if (attrs.inset !== void 0) out.inset = String(attrs.inset);
|
|
2025
|
+
if (attrs["o:singleclick"] !== void 0) out.singleclick = parseVmlTrueFalse(String(attrs["o:singleclick"]));
|
|
2026
|
+
if (attrs["o:insetmode"] !== void 0) out.insetmode = String(attrs["o:insetmode"]);
|
|
2027
|
+
for (const child of el.elements ?? []) {
|
|
2028
|
+
if (child.type !== "element") continue;
|
|
2029
|
+
if (child.name === "w:txbxContent") {
|
|
2030
|
+
out.txbxContent = (child.elements ?? []).map((e) => stringifyElement(e)).join("");
|
|
2031
|
+
break;
|
|
2032
|
+
}
|
|
2033
|
+
if (!child.name?.includes(":")) {
|
|
2034
|
+
out.content = stringifyElement(child);
|
|
2035
|
+
break;
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
return out;
|
|
2039
|
+
}
|
|
2040
|
+
//#endregion
|
|
2041
|
+
//#region src/vector/shape-elements/textpath.ts
|
|
2042
|
+
const TEXT_PATH_STYLE_MAP = {
|
|
2043
|
+
fontFamily: "font-family",
|
|
2044
|
+
fontSize: "font-size",
|
|
2045
|
+
fontWeight: "font-weight",
|
|
2046
|
+
fontStyle: "font-style",
|
|
2047
|
+
fontVariant: "font-variant",
|
|
2048
|
+
textTransform: "text-transform",
|
|
2049
|
+
textDecoration: "text-decoration",
|
|
2050
|
+
letterSpacing: "letter-spacing",
|
|
2051
|
+
vTextAlign: "v-text-align",
|
|
2052
|
+
vTextKern: "v-text-kern",
|
|
2053
|
+
vTextSpacing: "v-text-spacing",
|
|
2054
|
+
vTextSpacingMode: "v-text-spacing-mode"
|
|
2055
|
+
};
|
|
2056
|
+
const KEY_TO_TEXT_PATH_FIELD = Object.fromEntries(Object.entries(TEXT_PATH_STYLE_MAP).map(([field, key]) => [key, field]));
|
|
2057
|
+
/** Serialize a VmlTextPathStyle to its CSS-stream form. */
|
|
2058
|
+
function stringifyVmlTextPathStyle(style) {
|
|
2059
|
+
return Object.entries(style).map(([key, value]) => `${TEXT_PATH_STYLE_MAP[key]}:${value}`).join(";");
|
|
2060
|
+
}
|
|
2061
|
+
/** Parse a CSS stream into a VmlTextPathStyle; unmapped keys drop. */
|
|
2062
|
+
function parseVmlTextPathStyle(styleStr) {
|
|
2063
|
+
const style = {};
|
|
2064
|
+
for (const part of styleStr.split(";")) {
|
|
2065
|
+
const [key, val] = part.split(":").map((s) => s.trim());
|
|
2066
|
+
if (!key || !val) continue;
|
|
2067
|
+
const field = KEY_TO_TEXT_PATH_FIELD[key];
|
|
2068
|
+
if (field) style[field] = val;
|
|
2069
|
+
}
|
|
2070
|
+
return style;
|
|
2071
|
+
}
|
|
2072
|
+
const TEXT_PATH_ATTRS = [
|
|
2073
|
+
{
|
|
2074
|
+
field: "id",
|
|
2075
|
+
attr: "id",
|
|
2076
|
+
kind: "string"
|
|
2077
|
+
},
|
|
2078
|
+
{
|
|
2079
|
+
field: "on",
|
|
2080
|
+
attr: "on",
|
|
2081
|
+
kind: "trueFalse"
|
|
2082
|
+
},
|
|
2083
|
+
{
|
|
2084
|
+
field: "fitshape",
|
|
2085
|
+
attr: "fitshape",
|
|
2086
|
+
kind: "trueFalse"
|
|
2087
|
+
},
|
|
2088
|
+
{
|
|
2089
|
+
field: "fitpath",
|
|
2090
|
+
attr: "fitpath",
|
|
2091
|
+
kind: "trueFalse"
|
|
2092
|
+
},
|
|
2093
|
+
{
|
|
2094
|
+
field: "trim",
|
|
2095
|
+
attr: "trim",
|
|
2096
|
+
kind: "trueFalse"
|
|
2097
|
+
},
|
|
2098
|
+
{
|
|
2099
|
+
field: "xscale",
|
|
2100
|
+
attr: "xscale",
|
|
2101
|
+
kind: "trueFalse"
|
|
2102
|
+
},
|
|
2103
|
+
{
|
|
2104
|
+
field: "string",
|
|
2105
|
+
attr: "string",
|
|
2106
|
+
kind: "string"
|
|
2107
|
+
}
|
|
2108
|
+
];
|
|
2109
|
+
/** Serialize v:textpath. */
|
|
2110
|
+
function stringifyVmlTextPath(opts) {
|
|
2111
|
+
const attrStr = stringifyVmlAttributes(opts, TEXT_PATH_ATTRS);
|
|
2112
|
+
if (opts.style !== void 0) return `<v:textpath${attrStr} style="${escapeXml(stringifyVmlTextPathStyle(opts.style))}"/>`;
|
|
2113
|
+
return `<v:textpath${attrStr}/>`;
|
|
2114
|
+
}
|
|
2115
|
+
/** Parse a v:textpath element. */
|
|
2116
|
+
function parseVmlTextPath(el) {
|
|
2117
|
+
const out = {};
|
|
2118
|
+
parseVmlAttributes(el, TEXT_PATH_ATTRS, out);
|
|
2119
|
+
if (el.attributes?.style !== void 0) out.style = parseVmlTextPathStyle(String(el.attributes.style));
|
|
2120
|
+
return out;
|
|
2121
|
+
}
|
|
2122
|
+
//#endregion
|
|
2123
|
+
//#region src/vector/shape-elements/word-elements.ts
|
|
2124
|
+
const WRAP_ATTRS = [
|
|
2125
|
+
{
|
|
2126
|
+
field: "type",
|
|
2127
|
+
attr: "type",
|
|
2128
|
+
kind: "string"
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
field: "side",
|
|
2132
|
+
attr: "side",
|
|
2133
|
+
kind: "string"
|
|
2134
|
+
},
|
|
2135
|
+
{
|
|
2136
|
+
field: "anchorx",
|
|
2137
|
+
attr: "anchorx",
|
|
2138
|
+
kind: "string"
|
|
2139
|
+
},
|
|
2140
|
+
{
|
|
2141
|
+
field: "anchory",
|
|
2142
|
+
attr: "anchory",
|
|
2143
|
+
kind: "string"
|
|
2144
|
+
}
|
|
2145
|
+
];
|
|
2146
|
+
/** Serialize w10:wrap. */
|
|
2147
|
+
function stringifyVmlWrap(opts) {
|
|
2148
|
+
return `<w10:wrap${stringifyVmlAttributes(opts, WRAP_ATTRS)}/>`;
|
|
2149
|
+
}
|
|
2150
|
+
/** Parse a w10:wrap element. */
|
|
2151
|
+
function parseVmlWrap(el) {
|
|
2152
|
+
const out = {};
|
|
2153
|
+
parseVmlAttributes(el, WRAP_ATTRS, out);
|
|
2154
|
+
return out;
|
|
2155
|
+
}
|
|
2156
|
+
/** Serialize w10:anchorlock. */
|
|
2157
|
+
function stringifyVmlAnchorLock(_opts) {
|
|
2158
|
+
return "<w10:anchorlock/>";
|
|
2159
|
+
}
|
|
2160
|
+
/** Parse a w10:anchorlock element. */
|
|
2161
|
+
function parseVmlAnchorLock(_el) {
|
|
2162
|
+
return {};
|
|
2163
|
+
}
|
|
2164
|
+
const BORDER_ATTRS = [
|
|
2165
|
+
{
|
|
2166
|
+
field: "type",
|
|
2167
|
+
attr: "type",
|
|
2168
|
+
kind: "string"
|
|
2169
|
+
},
|
|
2170
|
+
{
|
|
2171
|
+
field: "width",
|
|
2172
|
+
attr: "width",
|
|
2173
|
+
kind: "number"
|
|
2174
|
+
},
|
|
2175
|
+
{
|
|
2176
|
+
field: "shadow",
|
|
2177
|
+
attr: "shadow",
|
|
2178
|
+
kind: "trueFalseBlank"
|
|
2179
|
+
}
|
|
2180
|
+
];
|
|
2181
|
+
/** The four w10: border element names. */
|
|
2182
|
+
const VML_BORDER_TAGS = [
|
|
2183
|
+
"w10:bordertop",
|
|
2184
|
+
"w10:borderleft",
|
|
2185
|
+
"w10:borderright",
|
|
2186
|
+
"w10:borderbottom"
|
|
2187
|
+
];
|
|
2188
|
+
/** Serialize a w10: border element. */
|
|
2189
|
+
function stringifyVmlBorder(tag, opts) {
|
|
2190
|
+
return `<${tag}${stringifyVmlAttributes(opts, BORDER_ATTRS)}/>`;
|
|
2191
|
+
}
|
|
2192
|
+
/** Parse a w10: border element. */
|
|
2193
|
+
function parseVmlBorder(el) {
|
|
2194
|
+
const out = {};
|
|
2195
|
+
parseVmlAttributes(el, BORDER_ATTRS, out);
|
|
2196
|
+
return out;
|
|
2197
|
+
}
|
|
2198
|
+
//#endregion
|
|
2199
|
+
//#region src/vector/shapes.ts
|
|
2200
|
+
/** Next spid in the `_x0000_s` segment (Word hands out shape ids from 1025). */
|
|
2201
|
+
let nextSpid = 1024;
|
|
2202
|
+
/**
|
|
2203
|
+
* Allocate the next VML shape id (`_x0000_s1025`, `_x0000_s1026`, …).
|
|
2204
|
+
* Ids only need to be unique within a document; the counter is process-global
|
|
2205
|
+
* so concurrent generations never collide.
|
|
2206
|
+
*/
|
|
2207
|
+
function nextVmlShapeId() {
|
|
2208
|
+
return `_x0000_s${++nextSpid}`;
|
|
2209
|
+
}
|
|
2210
|
+
const GROUP_FILL_ATTRS = [{
|
|
2211
|
+
field: "filled",
|
|
2212
|
+
attr: "filled",
|
|
2213
|
+
kind: "trueFalse"
|
|
2214
|
+
}, {
|
|
2215
|
+
field: "fillcolor",
|
|
2216
|
+
attr: "fillcolor",
|
|
2217
|
+
kind: "string"
|
|
2218
|
+
}];
|
|
2219
|
+
const ARC_ATTRS = [{
|
|
2220
|
+
field: "startAngle",
|
|
2221
|
+
attr: "startAngle",
|
|
2222
|
+
kind: "number"
|
|
2223
|
+
}, {
|
|
2224
|
+
field: "endAngle",
|
|
2225
|
+
attr: "endAngle",
|
|
2226
|
+
kind: "number"
|
|
2227
|
+
}];
|
|
2228
|
+
const CURVE_ATTRS = [
|
|
2229
|
+
{
|
|
2230
|
+
field: "from",
|
|
2231
|
+
attr: "from",
|
|
2232
|
+
kind: "string"
|
|
2233
|
+
},
|
|
2234
|
+
{
|
|
2235
|
+
field: "control1",
|
|
2236
|
+
attr: "control1",
|
|
2237
|
+
kind: "string"
|
|
2238
|
+
},
|
|
2239
|
+
{
|
|
2240
|
+
field: "control2",
|
|
2241
|
+
attr: "control2",
|
|
2242
|
+
kind: "string"
|
|
2243
|
+
},
|
|
2244
|
+
{
|
|
2245
|
+
field: "to",
|
|
2246
|
+
attr: "to",
|
|
2247
|
+
kind: "string"
|
|
2248
|
+
}
|
|
2249
|
+
];
|
|
2250
|
+
const IMAGE_ATTRS = [
|
|
2251
|
+
{
|
|
2252
|
+
field: "src",
|
|
2253
|
+
attr: "src",
|
|
2254
|
+
kind: "string"
|
|
2255
|
+
},
|
|
2256
|
+
{
|
|
2257
|
+
field: "cropleft",
|
|
2258
|
+
attr: "cropleft",
|
|
2259
|
+
kind: "string"
|
|
2260
|
+
},
|
|
2261
|
+
{
|
|
2262
|
+
field: "croptop",
|
|
2263
|
+
attr: "croptop",
|
|
2264
|
+
kind: "string"
|
|
2265
|
+
},
|
|
2266
|
+
{
|
|
2267
|
+
field: "cropright",
|
|
2268
|
+
attr: "cropright",
|
|
2269
|
+
kind: "string"
|
|
2270
|
+
},
|
|
2271
|
+
{
|
|
2272
|
+
field: "cropbottom",
|
|
2273
|
+
attr: "cropbottom",
|
|
2274
|
+
kind: "string"
|
|
2275
|
+
},
|
|
2276
|
+
{
|
|
2277
|
+
field: "gain",
|
|
2278
|
+
attr: "gain",
|
|
2279
|
+
kind: "string"
|
|
2280
|
+
},
|
|
2281
|
+
{
|
|
2282
|
+
field: "blacklevel",
|
|
2283
|
+
attr: "blacklevel",
|
|
2284
|
+
kind: "string"
|
|
2285
|
+
},
|
|
2286
|
+
{
|
|
2287
|
+
field: "gamma",
|
|
2288
|
+
attr: "gamma",
|
|
2289
|
+
kind: "string"
|
|
2290
|
+
},
|
|
2291
|
+
{
|
|
2292
|
+
field: "grayscale",
|
|
2293
|
+
attr: "grayscale",
|
|
2294
|
+
kind: "trueFalse"
|
|
2295
|
+
},
|
|
2296
|
+
{
|
|
2297
|
+
field: "bilevel",
|
|
2298
|
+
attr: "bilevel",
|
|
2299
|
+
kind: "trueFalse"
|
|
2300
|
+
}
|
|
2301
|
+
];
|
|
2302
|
+
const LINE_ATTRS = [{
|
|
2303
|
+
field: "from",
|
|
2304
|
+
attr: "from",
|
|
2305
|
+
kind: "string"
|
|
2306
|
+
}, {
|
|
2307
|
+
field: "to",
|
|
2308
|
+
attr: "to",
|
|
2309
|
+
kind: "string"
|
|
2310
|
+
}];
|
|
2311
|
+
const POLYLINE_ATTRS = [{
|
|
2312
|
+
field: "points",
|
|
2313
|
+
attr: "points",
|
|
2314
|
+
kind: "string"
|
|
2315
|
+
}];
|
|
2316
|
+
const ROUNDRECT_ATTRS = [{
|
|
2317
|
+
field: "arcsize",
|
|
2318
|
+
attr: "arcsize",
|
|
2319
|
+
kind: "string"
|
|
2320
|
+
}];
|
|
2321
|
+
/** The full AG_AllCoreAttributes + AG_AllShapeAttributes table. */
|
|
2322
|
+
const ALL_SHAPE_ATTRS = [
|
|
2323
|
+
...VML_CORE_ATTRS,
|
|
2324
|
+
...VML_OFFICE_CORE_ATTRS,
|
|
2325
|
+
...VML_SHAPE_ATTRS,
|
|
2326
|
+
...VML_OFFICE_SHAPE_ATTRS
|
|
2327
|
+
];
|
|
2328
|
+
/** The AG_Path attribute — always emitted after the shared vocabulary. */
|
|
2329
|
+
const PATH_ATTR = [{
|
|
2330
|
+
field: "path",
|
|
2331
|
+
attr: "path",
|
|
2332
|
+
kind: "string"
|
|
2333
|
+
}];
|
|
2334
|
+
/** Serialize the shared attribute vocabulary (style special-cased) plus extras. */
|
|
2335
|
+
function stringifyShapeAttrs(opts, extraSpecs = []) {
|
|
2336
|
+
let attrStr = stringifyVmlAttributes(opts, [
|
|
2337
|
+
...ALL_SHAPE_ATTRS,
|
|
2338
|
+
...extraSpecs,
|
|
2339
|
+
...PATH_ATTR
|
|
2340
|
+
]);
|
|
2341
|
+
const style = opts.style;
|
|
2342
|
+
if (style !== void 0) attrStr += ` style="${escapeXml(stringifyVmlStyle(style))}"`;
|
|
2343
|
+
return attrStr;
|
|
2344
|
+
}
|
|
2345
|
+
/** Serialize the EG_ShapeElements children present on `opts`, in declaration order. */
|
|
2346
|
+
function stringifyShapeElements(opts) {
|
|
2347
|
+
const parts = [];
|
|
2348
|
+
if (opts.pathElement !== void 0) parts.push(stringifyVmlPath(opts.pathElement));
|
|
2349
|
+
if (opts.formulas !== void 0) parts.push(stringifyVmlFormulas(opts.formulas));
|
|
2350
|
+
if (opts.handles !== void 0) parts.push(stringifyVmlHandles(opts.handles));
|
|
2351
|
+
if (opts.fill !== void 0) parts.push(stringifyVmlFill(opts.fill));
|
|
2352
|
+
if (opts.stroke !== void 0) parts.push(stringifyVmlStroke(opts.stroke));
|
|
2353
|
+
if (opts.shadow !== void 0) parts.push(stringifyVmlShadow(opts.shadow));
|
|
2354
|
+
if (opts.textbox !== void 0) parts.push(stringifyVmlTextbox(opts.textbox));
|
|
2355
|
+
if (opts.textpath !== void 0) parts.push(stringifyVmlTextPath(opts.textpath));
|
|
2356
|
+
if (opts.imagedata !== void 0) parts.push(stringifyVmlImageData(opts.imagedata));
|
|
2357
|
+
if (opts.skew !== void 0) parts.push(stringifyVmlSkew(opts.skew));
|
|
2358
|
+
if (opts.extrusion !== void 0) parts.push(stringifyVmlExtrusion(opts.extrusion));
|
|
2359
|
+
if (opts.callout !== void 0) parts.push(stringifyVmlCallout(opts.callout));
|
|
2360
|
+
if (opts.lock !== void 0) parts.push(stringifyVmlLock(opts.lock));
|
|
2361
|
+
if (opts.clippath !== void 0) parts.push(stringifyVmlClipPath(opts.clippath));
|
|
2362
|
+
if (opts.signatureline !== void 0) parts.push(stringifyVmlSignatureLine(opts.signatureline));
|
|
2363
|
+
if (opts.wrap !== void 0) parts.push(stringifyVmlWrap(opts.wrap));
|
|
2364
|
+
if (opts.anchorlock !== void 0) parts.push(stringifyVmlAnchorLock(opts.anchorlock));
|
|
2365
|
+
if (opts.bordertop !== void 0) parts.push(stringifyVmlBorder("w10:bordertop", opts.bordertop));
|
|
2366
|
+
if (opts.borderbottom !== void 0) parts.push(stringifyVmlBorder("w10:borderbottom", opts.borderbottom));
|
|
2367
|
+
if (opts.borderleft !== void 0) parts.push(stringifyVmlBorder("w10:borderleft", opts.borderleft));
|
|
2368
|
+
if (opts.borderright !== void 0) parts.push(stringifyVmlBorder("w10:borderright", opts.borderright));
|
|
2369
|
+
if (opts.clientData !== void 0) parts.push(stringifyVmlClientData(opts.clientData));
|
|
2370
|
+
if (opts.textdata !== void 0) parts.push(stringifyVmlTextData(opts.textdata));
|
|
2371
|
+
if (opts.rawChildrenXml) parts.push(opts.rawChildrenXml);
|
|
2372
|
+
return parts.join("");
|
|
2373
|
+
}
|
|
2374
|
+
/** Parse the shared attribute vocabulary plus extras onto `out`. */
|
|
2375
|
+
function parseShapeAttrs(el, out, extraSpecs = []) {
|
|
2376
|
+
parseVmlAttributes(el, [
|
|
2377
|
+
...ALL_SHAPE_ATTRS,
|
|
2378
|
+
...extraSpecs,
|
|
2379
|
+
...PATH_ATTR
|
|
2380
|
+
], out);
|
|
2381
|
+
if (el.attributes?.style !== void 0) out.style = parseVmlShapeStyle(parseVmlStyle(String(el.attributes.style)));
|
|
2382
|
+
}
|
|
2383
|
+
/** Child shape element names — collected by the group child loop, never by
|
|
2384
|
+
* the EG_ShapeElements switch (their slots are group members, not shared
|
|
2385
|
+
* shape-element children). */
|
|
2386
|
+
const NESTED_SHAPE_NAMES = /* @__PURE__ */ new Set([
|
|
2387
|
+
"v:shape",
|
|
2388
|
+
"v:shapetype",
|
|
2389
|
+
"v:group",
|
|
2390
|
+
"v:rect",
|
|
2391
|
+
"v:roundrect",
|
|
2392
|
+
"v:oval",
|
|
2393
|
+
"v:line",
|
|
2394
|
+
"v:image",
|
|
2395
|
+
"v:arc",
|
|
2396
|
+
"v:curve",
|
|
2397
|
+
"v:polyline"
|
|
2398
|
+
]);
|
|
2399
|
+
/** Parse the EG_ShapeElements children from `el` onto `out`. */
|
|
2400
|
+
function parseShapeElements(el, out) {
|
|
2401
|
+
for (const child of el.elements ?? []) {
|
|
2402
|
+
if (child.type !== "element") continue;
|
|
2403
|
+
switch (child.name) {
|
|
2404
|
+
case "v:path":
|
|
2405
|
+
out.pathElement = parseVmlPath(child);
|
|
2406
|
+
break;
|
|
2407
|
+
case "v:formulas":
|
|
2408
|
+
out.formulas = parseVmlFormulas(child);
|
|
2409
|
+
break;
|
|
2410
|
+
case "v:handles":
|
|
2411
|
+
out.handles = parseVmlHandles(child);
|
|
2412
|
+
break;
|
|
2413
|
+
case "v:fill":
|
|
2414
|
+
out.fill = parseVmlFill(child);
|
|
2415
|
+
break;
|
|
2416
|
+
case "v:stroke":
|
|
2417
|
+
out.stroke = parseVmlStroke(child);
|
|
2418
|
+
break;
|
|
2419
|
+
case "v:shadow":
|
|
2420
|
+
out.shadow = parseVmlShadow(child);
|
|
2421
|
+
break;
|
|
2422
|
+
case "v:textbox":
|
|
2423
|
+
out.textbox = parseVmlTextbox(child);
|
|
2424
|
+
break;
|
|
2425
|
+
case "v:textpath":
|
|
2426
|
+
out.textpath = parseVmlTextPath(child);
|
|
2427
|
+
break;
|
|
2428
|
+
case "v:imagedata":
|
|
2429
|
+
out.imagedata = parseVmlImageData(child);
|
|
2430
|
+
break;
|
|
2431
|
+
case "o:skew":
|
|
2432
|
+
out.skew = parseVmlSkew(child);
|
|
2433
|
+
break;
|
|
2434
|
+
case "o:extrusion":
|
|
2435
|
+
out.extrusion = parseVmlExtrusion(child);
|
|
2436
|
+
break;
|
|
2437
|
+
case "o:callout":
|
|
2438
|
+
out.callout = parseVmlCallout(child);
|
|
2439
|
+
break;
|
|
2440
|
+
case "o:lock":
|
|
2441
|
+
out.lock = parseVmlLock(child);
|
|
2442
|
+
break;
|
|
2443
|
+
case "o:clippath":
|
|
2444
|
+
out.clippath = parseVmlClipPath(child);
|
|
2445
|
+
break;
|
|
2446
|
+
case "o:signatureline":
|
|
2447
|
+
out.signatureline = parseVmlSignatureLine(child);
|
|
2448
|
+
break;
|
|
2449
|
+
case "w10:wrap":
|
|
2450
|
+
out.wrap = parseVmlWrap(child);
|
|
2451
|
+
break;
|
|
2452
|
+
case "w10:anchorlock":
|
|
2453
|
+
out.anchorlock = parseVmlAnchorLock(child);
|
|
2454
|
+
break;
|
|
2455
|
+
case "w10:bordertop":
|
|
2456
|
+
out.bordertop = parseVmlBorder(child);
|
|
2457
|
+
break;
|
|
2458
|
+
case "w10:borderbottom":
|
|
2459
|
+
out.borderbottom = parseVmlBorder(child);
|
|
2460
|
+
break;
|
|
2461
|
+
case "w10:borderleft":
|
|
2462
|
+
out.borderleft = parseVmlBorder(child);
|
|
2463
|
+
break;
|
|
2464
|
+
case "w10:borderright":
|
|
2465
|
+
out.borderright = parseVmlBorder(child);
|
|
2466
|
+
break;
|
|
2467
|
+
case "x:ClientData":
|
|
2468
|
+
out.clientData = parseVmlClientData(child);
|
|
2469
|
+
break;
|
|
2470
|
+
case "pvml:textdata":
|
|
2471
|
+
out.textdata = parseVmlTextData(child);
|
|
2472
|
+
break;
|
|
2473
|
+
case "pvml:iscomment":
|
|
2474
|
+
out.iscomment = parseVmlIsComment(child);
|
|
2475
|
+
break;
|
|
2476
|
+
default:
|
|
2477
|
+
if (child.name === "o:complex" || child.name === "o:ink" || child.name === "o:equationxml" || child.name !== void 0 && NESTED_SHAPE_NAMES.has(child.name)) break;
|
|
2478
|
+
out.rawChildrenXml = (typeof out.rawChildrenXml === "string" ? out.rawChildrenXml : "") + stringifyElement(child);
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
/** Generic shape element serializer: tag + shared/extra attrs + children. */
|
|
2483
|
+
function stringifyShapeElement(tag, opts, extraSpecs = [], childrenXml = "") {
|
|
2484
|
+
const attrStr = stringifyShapeAttrs(opts, extraSpecs);
|
|
2485
|
+
return childrenXml !== "" ? `<${tag}${attrStr}>${childrenXml}</${tag}>` : `<${tag}${attrStr}/>`;
|
|
2486
|
+
}
|
|
2487
|
+
const SHAPE_EXTRA_ATTRS = [
|
|
2488
|
+
{
|
|
2489
|
+
field: "type",
|
|
2490
|
+
attr: "type",
|
|
2491
|
+
kind: "string"
|
|
2492
|
+
},
|
|
2493
|
+
{
|
|
2494
|
+
field: "adj",
|
|
2495
|
+
attr: "adj",
|
|
2496
|
+
kind: "string"
|
|
2497
|
+
},
|
|
2498
|
+
{
|
|
2499
|
+
field: "gfxdata",
|
|
2500
|
+
attr: "o:gfxdata",
|
|
2501
|
+
kind: "string"
|
|
2502
|
+
},
|
|
2503
|
+
{
|
|
2504
|
+
field: "equationxml",
|
|
2505
|
+
attr: "equationxml",
|
|
2506
|
+
kind: "string"
|
|
2507
|
+
}
|
|
2508
|
+
];
|
|
2509
|
+
/** Serialize v:shape. */
|
|
2510
|
+
function stringifyVmlShape(opts) {
|
|
2511
|
+
let children = stringifyShapeElements(opts);
|
|
2512
|
+
if (opts.ink !== void 0) children += stringifyVmlInk(opts.ink);
|
|
2513
|
+
if (opts.equationxmlElement !== void 0) children += stringifyVmlEquationXml(opts.equationxmlElement);
|
|
2514
|
+
if (opts.iscomment !== void 0) children += stringifyVmlIsComment(opts.iscomment);
|
|
2515
|
+
return stringifyShapeElement("v:shape", opts, SHAPE_EXTRA_ATTRS, children);
|
|
2516
|
+
}
|
|
2517
|
+
/** Parse a v:shape element. */
|
|
2518
|
+
function parseVmlShape(el) {
|
|
2519
|
+
const out = {};
|
|
2520
|
+
parseShapeAttrs(el, out, SHAPE_EXTRA_ATTRS);
|
|
2521
|
+
parseShapeElements(el, out);
|
|
2522
|
+
for (const child of el.elements ?? []) {
|
|
2523
|
+
if (child.type !== "element") continue;
|
|
2524
|
+
if (child.name === "o:ink") out.ink = parseVmlInk(child);
|
|
2525
|
+
else if (child.name === "o:equationxml") out.equationxmlElement = parseVmlEquationXml(child);
|
|
2526
|
+
}
|
|
2527
|
+
return out;
|
|
2528
|
+
}
|
|
2529
|
+
const SHAPETYPE_EXTRA_ATTRS = [{
|
|
2530
|
+
field: "adj",
|
|
2531
|
+
attr: "adj",
|
|
2532
|
+
kind: "string"
|
|
2533
|
+
}, {
|
|
2534
|
+
field: "master",
|
|
2535
|
+
attr: "o:master",
|
|
2536
|
+
kind: "string"
|
|
2537
|
+
}];
|
|
2538
|
+
/** Serialize v:shapetype. */
|
|
2539
|
+
function stringifyVmlShapetype(opts) {
|
|
2540
|
+
let children = stringifyShapeElements(opts);
|
|
2541
|
+
if (opts.complex !== void 0) children += stringifyVmlComplex(opts.complex);
|
|
2542
|
+
return stringifyShapeElement("v:shapetype", opts, SHAPETYPE_EXTRA_ATTRS, children);
|
|
2543
|
+
}
|
|
2544
|
+
/** Parse a v:shapetype element. */
|
|
2545
|
+
function parseVmlShapetype(el) {
|
|
2546
|
+
const out = {};
|
|
2547
|
+
parseShapeAttrs(el, out, SHAPETYPE_EXTRA_ATTRS);
|
|
2548
|
+
parseShapeElements(el, out);
|
|
2549
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "o:complex") {
|
|
2550
|
+
out.complex = parseVmlComplex(child);
|
|
2551
|
+
break;
|
|
2552
|
+
}
|
|
2553
|
+
return out;
|
|
2554
|
+
}
|
|
2555
|
+
/** Serialize one VmlShapeChild. */
|
|
2556
|
+
function stringifyVmlShapeChild(child) {
|
|
2557
|
+
if ("shape" in child) return stringifyVmlShape(child.shape);
|
|
2558
|
+
if ("shapetype" in child) return stringifyVmlShapetype(child.shapetype);
|
|
2559
|
+
if ("group" in child) return stringifyVmlGroup(child.group);
|
|
2560
|
+
if ("arc" in child) return stringifyVmlArc(child.arc);
|
|
2561
|
+
if ("curve" in child) return stringifyVmlCurve(child.curve);
|
|
2562
|
+
if ("image" in child) return stringifyVmlImage(child.image);
|
|
2563
|
+
if ("line" in child) return stringifyVmlLine(child.line);
|
|
2564
|
+
if ("oval" in child) return stringifyVmlOval(child.oval);
|
|
2565
|
+
if ("polyline" in child) return stringifyVmlPolyline(child.polyline);
|
|
2566
|
+
if ("rect" in child) return stringifyVmlRect(child.rect);
|
|
2567
|
+
return stringifyVmlRoundRect(child.roundrect);
|
|
2568
|
+
}
|
|
2569
|
+
/** CT_Group attribute table — AG_AllCoreAttributes + AG_Fill + editas + table props. */
|
|
2570
|
+
const GROUP_ATTRS = [
|
|
2571
|
+
...VML_CORE_ATTRS,
|
|
2572
|
+
...VML_OFFICE_CORE_ATTRS,
|
|
2573
|
+
...GROUP_FILL_ATTRS,
|
|
2574
|
+
{
|
|
2575
|
+
field: "editas",
|
|
2576
|
+
attr: "editas",
|
|
2577
|
+
kind: "string"
|
|
2578
|
+
},
|
|
2579
|
+
{
|
|
2580
|
+
field: "tableproperties",
|
|
2581
|
+
attr: "o:tableproperties",
|
|
2582
|
+
kind: "string"
|
|
2583
|
+
},
|
|
2584
|
+
{
|
|
2585
|
+
field: "tablelimits",
|
|
2586
|
+
attr: "o:tablelimits",
|
|
2587
|
+
kind: "string"
|
|
2588
|
+
},
|
|
2589
|
+
...PATH_ATTR
|
|
2590
|
+
];
|
|
2591
|
+
/** Parse one shape element into its VmlShapeChild wrapper, or undefined when
|
|
2592
|
+
* the element is not part of the shape vocabulary. */
|
|
2593
|
+
function parseVmlShapeChild(el) {
|
|
2594
|
+
switch (el.name) {
|
|
2595
|
+
case "v:shape": return { shape: parseVmlShape(el) };
|
|
2596
|
+
case "v:shapetype": return { shapetype: parseVmlShapetype(el) };
|
|
2597
|
+
case "v:group": return { group: parseVmlGroup(el) };
|
|
2598
|
+
case "v:arc": return { arc: parseVmlArc(el) };
|
|
2599
|
+
case "v:curve": return { curve: parseVmlCurve(el) };
|
|
2600
|
+
case "v:image": return { image: parseVmlImage(el) };
|
|
2601
|
+
case "v:line": return { line: parseVmlLine(el) };
|
|
2602
|
+
case "v:oval": return { oval: parseVmlOval(el) };
|
|
2603
|
+
case "v:polyline": return { polyline: parseVmlPolyline(el) };
|
|
2604
|
+
case "v:rect": return { rect: parseVmlRect(el) };
|
|
2605
|
+
case "v:roundrect": return { roundrect: parseVmlRoundRect(el) };
|
|
2606
|
+
default: return;
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
/** Serialize v:group. */
|
|
2610
|
+
function stringifyVmlGroup(opts) {
|
|
2611
|
+
let children = (opts.children ?? []).map(stringifyVmlShapeChild).join("") + stringifyShapeElements(opts);
|
|
2612
|
+
if (opts.diagram !== void 0) children += stringifyVmlDiagram(opts.diagram);
|
|
2613
|
+
const attrStr = stringifyVmlAttributes(opts, GROUP_ATTRS);
|
|
2614
|
+
const style = opts.style;
|
|
2615
|
+
const styleStr = style !== void 0 ? ` style="${escapeXml(stringifyVmlStyle(style))}"` : "";
|
|
2616
|
+
return children !== "" ? `<v:group${attrStr}${styleStr}>${children}</v:group>` : `<v:group${attrStr}${styleStr}/>`;
|
|
2617
|
+
}
|
|
2618
|
+
/** Parse a v:group element. */
|
|
2619
|
+
function parseVmlGroup(el) {
|
|
2620
|
+
const out = {};
|
|
2621
|
+
parseVmlAttributes(el, GROUP_ATTRS, out);
|
|
2622
|
+
if (el.attributes?.style !== void 0) out.style = parseVmlShapeStyle(parseVmlStyle(String(el.attributes.style)));
|
|
2623
|
+
parseShapeElements(el, out);
|
|
2624
|
+
const children = [];
|
|
2625
|
+
for (const child of el.elements ?? []) {
|
|
2626
|
+
if (child.type !== "element") continue;
|
|
2627
|
+
const shapeChild = parseVmlShapeChild(child);
|
|
2628
|
+
if (shapeChild !== void 0) children.push(shapeChild);
|
|
2629
|
+
else if (child.name === "o:diagram") out.diagram = parseVmlDiagram(child);
|
|
2630
|
+
}
|
|
2631
|
+
if (children.length > 0) out.children = children;
|
|
2632
|
+
return out;
|
|
2633
|
+
}
|
|
2634
|
+
const BACKGROUND_ATTRS = [
|
|
2635
|
+
{
|
|
2636
|
+
field: "id",
|
|
2637
|
+
attr: "id",
|
|
2638
|
+
kind: "string"
|
|
2639
|
+
},
|
|
2640
|
+
{
|
|
2641
|
+
field: "filled",
|
|
2642
|
+
attr: "filled",
|
|
2643
|
+
kind: "trueFalse"
|
|
2644
|
+
},
|
|
2645
|
+
{
|
|
2646
|
+
field: "fillcolor",
|
|
2647
|
+
attr: "fillcolor",
|
|
2648
|
+
kind: "string"
|
|
2649
|
+
},
|
|
2650
|
+
{
|
|
2651
|
+
field: "bwmode",
|
|
2652
|
+
attr: "o:bwmode",
|
|
2653
|
+
kind: "string"
|
|
2654
|
+
},
|
|
2655
|
+
{
|
|
2656
|
+
field: "bwpure",
|
|
2657
|
+
attr: "o:bwpure",
|
|
2658
|
+
kind: "string"
|
|
2659
|
+
},
|
|
2660
|
+
{
|
|
2661
|
+
field: "bwnormal",
|
|
2662
|
+
attr: "o:bwnormal",
|
|
2663
|
+
kind: "string"
|
|
2664
|
+
},
|
|
2665
|
+
{
|
|
2666
|
+
field: "targetscreensize",
|
|
2667
|
+
attr: "o:targetscreensize",
|
|
2668
|
+
kind: "string"
|
|
2669
|
+
}
|
|
2670
|
+
];
|
|
2671
|
+
/** Serialize v:background. */
|
|
2672
|
+
function stringifyVmlBackground(opts) {
|
|
2673
|
+
const attrStr = stringifyVmlAttributes(opts, BACKGROUND_ATTRS);
|
|
2674
|
+
const fillXml = opts.fill !== void 0 ? stringifyVmlFill(opts.fill) : "";
|
|
2675
|
+
return fillXml !== "" ? `<v:background${attrStr}>${fillXml}</v:background>` : `<v:background${attrStr}/>`;
|
|
2676
|
+
}
|
|
2677
|
+
/** Parse a v:background element. */
|
|
2678
|
+
function parseVmlBackground(el) {
|
|
2679
|
+
const out = {};
|
|
2680
|
+
parseVmlAttributes(el, BACKGROUND_ATTRS, out);
|
|
2681
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "v:fill") {
|
|
2682
|
+
out.fill = parseVmlFill(child);
|
|
2683
|
+
break;
|
|
2684
|
+
}
|
|
2685
|
+
return out;
|
|
2686
|
+
}
|
|
2687
|
+
/** Serialize v:arc. */
|
|
2688
|
+
function stringifyVmlArc(opts) {
|
|
2689
|
+
return stringifyShapeElement("v:arc", opts, ARC_ATTRS, stringifyShapeElements(opts));
|
|
2690
|
+
}
|
|
2691
|
+
/** Parse a v:arc element. */
|
|
2692
|
+
function parseVmlArc(el) {
|
|
2693
|
+
const out = {};
|
|
2694
|
+
parseShapeAttrs(el, out, ARC_ATTRS);
|
|
2695
|
+
parseShapeElements(el, out);
|
|
2696
|
+
return out;
|
|
2697
|
+
}
|
|
2698
|
+
/** Serialize v:curve. */
|
|
2699
|
+
function stringifyVmlCurve(opts) {
|
|
2700
|
+
return stringifyShapeElement("v:curve", opts, CURVE_ATTRS, stringifyShapeElements(opts));
|
|
2701
|
+
}
|
|
2702
|
+
/** Parse a v:curve element. */
|
|
2703
|
+
function parseVmlCurve(el) {
|
|
2704
|
+
const out = {};
|
|
2705
|
+
parseShapeAttrs(el, out, CURVE_ATTRS);
|
|
2706
|
+
parseShapeElements(el, out);
|
|
2707
|
+
return out;
|
|
2708
|
+
}
|
|
2709
|
+
/** Serialize v:image. */
|
|
2710
|
+
function stringifyVmlImage(opts) {
|
|
2711
|
+
return stringifyShapeElement("v:image", opts, IMAGE_ATTRS, stringifyShapeElements(opts));
|
|
2712
|
+
}
|
|
2713
|
+
/** Parse a v:image element. */
|
|
2714
|
+
function parseVmlImage(el) {
|
|
2715
|
+
const out = {};
|
|
2716
|
+
parseShapeAttrs(el, out, IMAGE_ATTRS);
|
|
2717
|
+
parseShapeElements(el, out);
|
|
2718
|
+
return out;
|
|
2719
|
+
}
|
|
2720
|
+
/** Serialize v:line. */
|
|
2721
|
+
function stringifyVmlLine(opts) {
|
|
2722
|
+
return stringifyShapeElement("v:line", opts, LINE_ATTRS, stringifyShapeElements(opts));
|
|
2723
|
+
}
|
|
2724
|
+
/** Parse a v:line element. */
|
|
2725
|
+
function parseVmlLine(el) {
|
|
2726
|
+
const out = {};
|
|
2727
|
+
parseShapeAttrs(el, out, LINE_ATTRS);
|
|
2728
|
+
parseShapeElements(el, out);
|
|
2729
|
+
return out;
|
|
2730
|
+
}
|
|
2731
|
+
/** Serialize v:oval. */
|
|
2732
|
+
function stringifyVmlOval(opts) {
|
|
2733
|
+
return stringifyShapeElement("v:oval", opts, [], stringifyShapeElements(opts));
|
|
2734
|
+
}
|
|
2735
|
+
/** Parse a v:oval element. */
|
|
2736
|
+
function parseVmlOval(el) {
|
|
2737
|
+
const out = {};
|
|
2738
|
+
parseShapeAttrs(el, out);
|
|
2739
|
+
parseShapeElements(el, out);
|
|
2740
|
+
return out;
|
|
2741
|
+
}
|
|
2742
|
+
/** Serialize v:polyline. */
|
|
2743
|
+
function stringifyVmlPolyline(opts) {
|
|
2744
|
+
const children = stringifyShapeElements(opts) + (opts.ink !== void 0 ? stringifyVmlInk(opts.ink) : "");
|
|
2745
|
+
return stringifyShapeElement("v:polyline", opts, POLYLINE_ATTRS, children);
|
|
2746
|
+
}
|
|
2747
|
+
/** Parse a v:polyline element. */
|
|
2748
|
+
function parseVmlPolyline(el) {
|
|
2749
|
+
const out = {};
|
|
2750
|
+
parseShapeAttrs(el, out, POLYLINE_ATTRS);
|
|
2751
|
+
parseShapeElements(el, out);
|
|
2752
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "o:ink") {
|
|
2753
|
+
out.ink = parseVmlInk(child);
|
|
2754
|
+
break;
|
|
2755
|
+
}
|
|
2756
|
+
return out;
|
|
2757
|
+
}
|
|
2758
|
+
/** Serialize v:rect. */
|
|
2759
|
+
function stringifyVmlRect(opts) {
|
|
2760
|
+
return stringifyShapeElement("v:rect", opts, [], stringifyShapeElements(opts));
|
|
2761
|
+
}
|
|
2762
|
+
/** Parse a v:rect element. */
|
|
2763
|
+
function parseVmlRect(el) {
|
|
2764
|
+
const out = {};
|
|
2765
|
+
parseShapeAttrs(el, out);
|
|
2766
|
+
parseShapeElements(el, out);
|
|
2767
|
+
return out;
|
|
2768
|
+
}
|
|
2769
|
+
/** Serialize v:roundrect. */
|
|
2770
|
+
function stringifyVmlRoundRect(opts) {
|
|
2771
|
+
return stringifyShapeElement("v:roundrect", opts, ROUNDRECT_ATTRS, stringifyShapeElements(opts));
|
|
2772
|
+
}
|
|
2773
|
+
/** Parse a v:roundrect element. */
|
|
2774
|
+
function parseVmlRoundRect(el) {
|
|
2775
|
+
const out = {};
|
|
2776
|
+
parseShapeAttrs(el, out, ROUNDRECT_ATTRS);
|
|
2777
|
+
parseShapeElements(el, out);
|
|
2778
|
+
return out;
|
|
2779
|
+
}
|
|
2780
|
+
//#endregion
|
|
2781
|
+
//#region src/vector/office-shape-defaults.ts
|
|
2782
|
+
const SHAPEDEFAULTS_ATTRS = [
|
|
2783
|
+
...EXT_ATTR,
|
|
2784
|
+
{
|
|
2785
|
+
field: "spidmax",
|
|
2786
|
+
attr: "spidmax",
|
|
2787
|
+
kind: "number"
|
|
2788
|
+
},
|
|
2789
|
+
{
|
|
2790
|
+
field: "style",
|
|
2791
|
+
attr: "style",
|
|
2792
|
+
kind: "string"
|
|
2793
|
+
},
|
|
2794
|
+
{
|
|
2795
|
+
field: "fill",
|
|
2796
|
+
attr: "fill",
|
|
2797
|
+
kind: "trueFalse"
|
|
2798
|
+
},
|
|
2799
|
+
{
|
|
2800
|
+
field: "fillcolor",
|
|
2801
|
+
attr: "fillcolor",
|
|
2802
|
+
kind: "string"
|
|
2803
|
+
},
|
|
2804
|
+
{
|
|
2805
|
+
field: "stroke",
|
|
2806
|
+
attr: "stroke",
|
|
2807
|
+
kind: "trueFalse"
|
|
2808
|
+
},
|
|
2809
|
+
{
|
|
2810
|
+
field: "strokecolor",
|
|
2811
|
+
attr: "strokecolor",
|
|
2812
|
+
kind: "string"
|
|
2813
|
+
},
|
|
2814
|
+
{
|
|
2815
|
+
field: "allowincell",
|
|
2816
|
+
attr: "o:allowincell",
|
|
2817
|
+
kind: "trueFalse"
|
|
2818
|
+
}
|
|
2819
|
+
];
|
|
2820
|
+
/** Serialize o:shapedefaults. */
|
|
2821
|
+
function stringifyVmlShapeDefaults(opts) {
|
|
2822
|
+
const children = [];
|
|
2823
|
+
if (opts.fillElement !== void 0) children.push(stringifyVmlFill(opts.fillElement));
|
|
2824
|
+
if (opts.strokeElement !== void 0) children.push(stringifyVmlStroke(opts.strokeElement));
|
|
2825
|
+
if (opts.textbox !== void 0) children.push(stringifyVmlTextbox(opts.textbox));
|
|
2826
|
+
if (opts.shadow !== void 0) children.push(stringifyVmlShadow(opts.shadow));
|
|
2827
|
+
if (opts.skew !== void 0) children.push(stringifyVmlSkew(opts.skew));
|
|
2828
|
+
if (opts.extrusion !== void 0) children.push(stringifyVmlExtrusion(opts.extrusion));
|
|
2829
|
+
if (opts.callout !== void 0) children.push(stringifyVmlCallout(opts.callout));
|
|
2830
|
+
if (opts.lock !== void 0) children.push(stringifyVmlLock(opts.lock));
|
|
2831
|
+
if (opts.colormru !== void 0) children.push(stringifyVmlColorMru(opts.colormru));
|
|
2832
|
+
if (opts.colormenu !== void 0) children.push(stringifyVmlColorMenu(opts.colormenu));
|
|
2833
|
+
const attrStr = stringifyVmlAttributes(opts, SHAPEDEFAULTS_ATTRS);
|
|
2834
|
+
return children.length > 0 ? `<o:shapedefaults${attrStr}>${children.join("")}</o:shapedefaults>` : `<o:shapedefaults${attrStr}/>`;
|
|
2835
|
+
}
|
|
2836
|
+
/** Parse an o:shapedefaults element. */
|
|
2837
|
+
function parseVmlShapeDefaults(el) {
|
|
2838
|
+
const out = {};
|
|
2839
|
+
parseVmlAttributes(el, SHAPEDEFAULTS_ATTRS, out);
|
|
2840
|
+
for (const child of el.elements ?? []) {
|
|
2841
|
+
if (child.type !== "element") continue;
|
|
2842
|
+
switch (child.name) {
|
|
2843
|
+
case "v:fill":
|
|
2844
|
+
out.fillElement = parseVmlFill(child);
|
|
2845
|
+
break;
|
|
2846
|
+
case "v:stroke":
|
|
2847
|
+
out.strokeElement = parseVmlStroke(child);
|
|
2848
|
+
break;
|
|
2849
|
+
case "v:textbox":
|
|
2850
|
+
out.textbox = parseVmlTextbox(child);
|
|
2851
|
+
break;
|
|
2852
|
+
case "v:shadow":
|
|
2853
|
+
out.shadow = parseVmlShadow(child);
|
|
2854
|
+
break;
|
|
2855
|
+
case "o:skew":
|
|
2856
|
+
out.skew = parseVmlSkew(child);
|
|
2857
|
+
break;
|
|
2858
|
+
case "o:extrusion":
|
|
2859
|
+
out.extrusion = parseVmlExtrusion(child);
|
|
2860
|
+
break;
|
|
2861
|
+
case "o:callout":
|
|
2862
|
+
out.callout = parseVmlCallout(child);
|
|
2863
|
+
break;
|
|
2864
|
+
case "o:lock":
|
|
2865
|
+
out.lock = parseVmlLock(child);
|
|
2866
|
+
break;
|
|
2867
|
+
case "o:colormru":
|
|
2868
|
+
out.colormru = parseVmlColorMru(child);
|
|
2869
|
+
break;
|
|
2870
|
+
case "o:colormenu": out.colormenu = parseVmlColorMenu(child);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
return out;
|
|
2874
|
+
}
|
|
2875
|
+
/** Serialize o:colormru. */
|
|
2876
|
+
function stringifyVmlColorMru(opts) {
|
|
2877
|
+
return `<o:colormru${stringifyVmlAttributes(opts, [...EXT_ATTR, {
|
|
2878
|
+
field: "colors",
|
|
2879
|
+
attr: "colors",
|
|
2880
|
+
kind: "string"
|
|
2881
|
+
}])}/>`;
|
|
2882
|
+
}
|
|
2883
|
+
/** Parse an o:colormru element. */
|
|
2884
|
+
function parseVmlColorMru(el) {
|
|
2885
|
+
const out = {};
|
|
2886
|
+
parseVmlAttributes(el, [...EXT_ATTR, {
|
|
2887
|
+
field: "colors",
|
|
2888
|
+
attr: "colors",
|
|
2889
|
+
kind: "string"
|
|
2890
|
+
}], out);
|
|
2891
|
+
return out;
|
|
2892
|
+
}
|
|
2893
|
+
const COLORMENU_ATTRS = [
|
|
2894
|
+
...EXT_ATTR,
|
|
2895
|
+
{
|
|
2896
|
+
field: "strokecolor",
|
|
2897
|
+
attr: "strokecolor",
|
|
2898
|
+
kind: "string"
|
|
2899
|
+
},
|
|
2900
|
+
{
|
|
2901
|
+
field: "fillcolor",
|
|
2902
|
+
attr: "fillcolor",
|
|
2903
|
+
kind: "string"
|
|
2904
|
+
},
|
|
2905
|
+
{
|
|
2906
|
+
field: "shadowcolor",
|
|
2907
|
+
attr: "shadowcolor",
|
|
2908
|
+
kind: "string"
|
|
2909
|
+
},
|
|
2910
|
+
{
|
|
2911
|
+
field: "extrusioncolor",
|
|
2912
|
+
attr: "extrusioncolor",
|
|
2913
|
+
kind: "string"
|
|
2914
|
+
}
|
|
2915
|
+
];
|
|
2916
|
+
/** Serialize o:colormenu. */
|
|
2917
|
+
function stringifyVmlColorMenu(opts) {
|
|
2918
|
+
return `<o:colormenu${stringifyVmlAttributes(opts, COLORMENU_ATTRS)}/>`;
|
|
2919
|
+
}
|
|
2920
|
+
/** Parse an o:colormenu element. */
|
|
2921
|
+
function parseVmlColorMenu(el) {
|
|
2922
|
+
const out = {};
|
|
2923
|
+
parseVmlAttributes(el, COLORMENU_ATTRS, out);
|
|
2924
|
+
return out;
|
|
2925
|
+
}
|
|
2926
|
+
const ENTRY_ATTRS = [{
|
|
2927
|
+
field: "new",
|
|
2928
|
+
attr: "new",
|
|
2929
|
+
kind: "number"
|
|
2930
|
+
}, {
|
|
2931
|
+
field: "old",
|
|
2932
|
+
attr: "old",
|
|
2933
|
+
kind: "number"
|
|
2934
|
+
}];
|
|
2935
|
+
/** Serialize an o:idmap. */
|
|
2936
|
+
function stringifyVmlIdMap(opts) {
|
|
2937
|
+
return `<o:idmap${stringifyVmlAttributes(opts, [...EXT_ATTR, {
|
|
2938
|
+
field: "data",
|
|
2939
|
+
attr: "data",
|
|
2940
|
+
kind: "string"
|
|
2941
|
+
}])}/>`;
|
|
2942
|
+
}
|
|
2943
|
+
/** Parse an o:idmap element. */
|
|
2944
|
+
function parseVmlIdMap(el) {
|
|
2945
|
+
const out = {};
|
|
2946
|
+
parseVmlAttributes(el, [...EXT_ATTR, {
|
|
2947
|
+
field: "data",
|
|
2948
|
+
attr: "data",
|
|
2949
|
+
kind: "string"
|
|
2950
|
+
}], out);
|
|
2951
|
+
return out;
|
|
2952
|
+
}
|
|
2953
|
+
/** Serialize an o:regrouptable. */
|
|
2954
|
+
function stringifyVmlRegroupTable(opts) {
|
|
2955
|
+
const entries = (opts.entries ?? []).map((entry) => `<o:entry${stringifyVmlAttributes(entry, ENTRY_ATTRS)}/>`).join("");
|
|
2956
|
+
return `<o:regrouptable${stringifyVmlAttributes(opts, EXT_ATTR)}>${entries}</o:regrouptable>`;
|
|
2957
|
+
}
|
|
2958
|
+
/** Parse an o:regrouptable element. */
|
|
2959
|
+
function parseVmlRegroupTable(el) {
|
|
2960
|
+
const out = {};
|
|
2961
|
+
parseVmlAttributes(el, EXT_ATTR, out);
|
|
2962
|
+
const entries = [];
|
|
2963
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "o:entry") {
|
|
2964
|
+
const entry = {};
|
|
2965
|
+
parseVmlAttributes(child, ENTRY_ATTRS, entry);
|
|
2966
|
+
entries.push(entry);
|
|
2967
|
+
}
|
|
2968
|
+
if (entries.length > 0) out.entries = entries;
|
|
2969
|
+
return out;
|
|
2970
|
+
}
|
|
2971
|
+
/** Serialize a proxy child inside an o:r. */
|
|
2972
|
+
function stringifyVmlRuleProxy(proxy) {
|
|
2973
|
+
const attrs = [];
|
|
2974
|
+
if (proxy.start !== void 0) attrs.push(`start="${stringifyVmlTrueFalseBlank(proxy.start)}"`);
|
|
2975
|
+
if (proxy.end !== void 0) attrs.push(`end="${stringifyVmlTrueFalseBlank(proxy.end)}"`);
|
|
2976
|
+
if (proxy.idref !== void 0) attrs.push(`idref="${proxy.idref}"`);
|
|
2977
|
+
if (proxy.connectloc !== void 0) attrs.push(`connectloc="${proxy.connectloc}"`);
|
|
2978
|
+
return `<o:proxy${attrs.length > 0 ? " " + attrs.join(" ") : ""}/>`;
|
|
2979
|
+
}
|
|
2980
|
+
/** Parse an o:proxy element. */
|
|
2981
|
+
function parseVmlRuleProxy(el) {
|
|
2982
|
+
const out = {};
|
|
2983
|
+
const attrs = el.attributes ?? {};
|
|
2984
|
+
if (attrs.start !== void 0) out.start = parseVmlTrueFalseBlank(String(attrs.start));
|
|
2985
|
+
if (attrs.end !== void 0) out.end = parseVmlTrueFalseBlank(String(attrs.end));
|
|
2986
|
+
if (attrs.idref !== void 0) out.idref = String(attrs.idref);
|
|
2987
|
+
if (attrs.connectloc !== void 0) out.connectloc = Number(attrs.connectloc);
|
|
2988
|
+
return out;
|
|
2989
|
+
}
|
|
2990
|
+
/** Serialize an o:r (hand-written — `id` is required, so no table-driven cast). */
|
|
2991
|
+
function stringifyVmlRule(rule) {
|
|
2992
|
+
const attrs = [`id="${rule.id}"`];
|
|
2993
|
+
if (rule.type !== void 0) attrs.push(`type="${rule.type}"`);
|
|
2994
|
+
if (rule.how !== void 0) attrs.push(`how="${rule.how}"`);
|
|
2995
|
+
if (rule.idref !== void 0) attrs.push(`idref="${rule.idref}"`);
|
|
2996
|
+
const proxies = (rule.proxies ?? []).map(stringifyVmlRuleProxy).join("");
|
|
2997
|
+
return `<o:r${attrs.length > 0 ? " " + attrs.join(" ") : ""}>${proxies}</o:r>`;
|
|
2998
|
+
}
|
|
2999
|
+
/** Parse an o:r element. */
|
|
3000
|
+
function parseVmlRule(el) {
|
|
3001
|
+
const attrs = el.attributes ?? {};
|
|
3002
|
+
const out = { id: String(attrs.id ?? "") };
|
|
3003
|
+
if (attrs.type !== void 0) out.type = String(attrs.type);
|
|
3004
|
+
if (attrs.how !== void 0) out.how = String(attrs.how);
|
|
3005
|
+
if (attrs.idref !== void 0) out.idref = String(attrs.idref);
|
|
3006
|
+
const proxies = [];
|
|
3007
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "o:proxy") proxies.push(parseVmlRuleProxy(child));
|
|
3008
|
+
if (proxies.length > 0) out.proxies = proxies;
|
|
3009
|
+
return out;
|
|
3010
|
+
}
|
|
3011
|
+
/** Serialize an o:rules block. */
|
|
3012
|
+
function stringifyVmlRulesBlock(opts) {
|
|
3013
|
+
const rules = (opts.rules ?? []).map(stringifyVmlRule).join("");
|
|
3014
|
+
return `<o:rules${stringifyVmlAttributes(opts, EXT_ATTR)}>${rules}</o:rules>`;
|
|
3015
|
+
}
|
|
3016
|
+
/** Parse an o:rules element. */
|
|
3017
|
+
function parseVmlRulesBlock(el) {
|
|
3018
|
+
const out = {};
|
|
3019
|
+
parseVmlAttributes(el, EXT_ATTR, out);
|
|
3020
|
+
const rules = [];
|
|
3021
|
+
for (const child of el.elements ?? []) if (child.type === "element" && child.name === "o:r") rules.push(parseVmlRule(child));
|
|
3022
|
+
if (rules.length > 0) out.rules = rules;
|
|
3023
|
+
return out;
|
|
3024
|
+
}
|
|
3025
|
+
/** Serialize o:shapelayout. */
|
|
3026
|
+
function stringifyVmlShapeLayout(opts) {
|
|
3027
|
+
const children = [];
|
|
3028
|
+
if (opts.idmap !== void 0) children.push(stringifyVmlIdMap(opts.idmap));
|
|
3029
|
+
if (opts.regrouptable !== void 0) children.push(stringifyVmlRegroupTable(opts.regrouptable));
|
|
3030
|
+
if (opts.rules !== void 0) children.push(stringifyVmlRulesBlock(opts.rules));
|
|
3031
|
+
const attrStr = stringifyVmlAttributes(opts, EXT_ATTR);
|
|
3032
|
+
return children.length > 0 ? `<o:shapelayout${attrStr}>${children.join("")}</o:shapelayout>` : `<o:shapelayout${attrStr}/>`;
|
|
3033
|
+
}
|
|
3034
|
+
/** Parse an o:shapelayout element. */
|
|
3035
|
+
function parseVmlShapeLayout(el) {
|
|
3036
|
+
const out = {};
|
|
3037
|
+
parseVmlAttributes(el, EXT_ATTR, out);
|
|
3038
|
+
for (const child of el.elements ?? []) {
|
|
3039
|
+
if (child.type !== "element") continue;
|
|
3040
|
+
if (child.name === "o:idmap") out.idmap = parseVmlIdMap(child);
|
|
3041
|
+
else if (child.name === "o:regrouptable") out.regrouptable = parseVmlRegroupTable(child);
|
|
3042
|
+
else if (child.name === "o:rules") out.rules = parseVmlRulesBlock(child);
|
|
3043
|
+
}
|
|
3044
|
+
return out;
|
|
3045
|
+
}
|
|
3046
|
+
//#endregion
|
|
3047
|
+
export { stringifyVmlIsComment as $, stringifyVmlPolyline as A, stringifyVmlEquationXml as At, stringifyVmlAnchorLock as B, VML_OFFICE_SHAPE_ATTRS as Bt, stringifyVmlArc as C, parseVmlOleObject as Ct, stringifyVmlImage as D, stringifyVmlClipPath as Dt, stringifyVmlGroup as E, stringifyVmlCallout as Et, stringifyVmlShapetype as F, stringifyVmlOleObject as Ft, parseVmlTextbox as G, stringifyVmlAttributes as Gt, stringifyVmlWrap as H, parseVmlAttributes as Ht, VML_BORDER_TAGS as I, stringifyVmlSignatureLine as It, stringifyVmlStroke as J, parseVmlShapeStyle as Jt, stringifyVmlTextbox as K, stringifyVmlTrueFalse as Kt, parseVmlAnchorLock as L, stringifyVmlSkew as Lt, stringifyVmlRoundRect as M, stringifyVmlInk as Mt, stringifyVmlShape as N, stringifyVmlLock as Nt, stringifyVmlLine as O, stringifyVmlComplex as Ot, stringifyVmlShapeChild as P, stringifyVmlOfficeFill as Pt, parseVmlTextData as Q, parseVmlBorder as R, VML_CORE_ATTRS as Rt, parseVmlShapetype as S, parseVmlOfficeFill as St, stringifyVmlCurve as T, parseVmlSkew as Tt, parseVmlTextPath as U, parseVmlTrueFalse as Ut, stringifyVmlBorder as V, VML_SHAPE_ATTRS as Vt, stringifyVmlTextPath as W, parseVmlTrueFalseBlank as Wt, stringifyVmlShadow as X, stringifyVmlStyle as Xt, parseVmlShadow as Y, parseVmlStyle as Yt, parseVmlIsComment as Z, styleToKeyMap as Zt, parseVmlPolyline as _, parseVmlDiagram as _t, stringifyVmlColorMenu as a, parseVmlHandles as at, parseVmlShape as b, parseVmlInk as bt, stringifyVmlShapeLayout as c, stringifyVmlFormulas as ct, parseVmlBackground as d, parseVmlClientData as dt, stringifyVmlTextData as et, parseVmlCurve as f, stringifyVmlClientData as ft, parseVmlOval as g, parseVmlComplex as gt, parseVmlLine as h, parseVmlClipPath as ht, parseVmlShapeLayout as i, stringifyVmlImageData as it, stringifyVmlRect as j, stringifyVmlExtrusion as jt, stringifyVmlOval as k, stringifyVmlDiagram as kt, nextVmlShapeId as l, parseVmlFill as lt, parseVmlImage as m, parseVmlCallout as mt, parseVmlColorMru as n, stringifyVmlPath as nt, stringifyVmlColorMru as o, stringifyVmlHandles as ot, parseVmlGroup as p, EXT_ATTR as pt, parseVmlStroke as q, stringifyVmlTrueFalseBlank as qt, parseVmlShapeDefaults as r, parseVmlImageData as rt, stringifyVmlShapeDefaults as s, parseVmlFormulas as st, parseVmlColorMenu as t, parseVmlPath as tt, parseVmlArc as u, stringifyVmlFill as ut, parseVmlRect as v, parseVmlEquationXml as vt, stringifyVmlBackground as w, parseVmlSignatureLine as wt, parseVmlShapeChild as x, parseVmlLock as xt, parseVmlRoundRect as y, parseVmlExtrusion as yt, parseVmlWrap as z, VML_OFFICE_CORE_ATTRS as zt };
|
|
3048
|
+
|
|
3049
|
+
//# sourceMappingURL=vector-DhLGZjP5.mjs.map
|