@windoc/core 0.3.26 → 0.3.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +986 -1195
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +983 -1194
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var version = "0.3.
|
|
2
|
+
var version = "0.3.28";
|
|
3
3
|
|
|
4
4
|
// src/dataset/enum/Common.ts
|
|
5
5
|
var MaxHeightRatio = /* @__PURE__ */ ((MaxHeightRatio2) => {
|
|
@@ -18995,10 +18995,11 @@ var ListParticle = class {
|
|
|
18995
18995
|
const curIndex = isSetCursor ? endIndex : startIndex;
|
|
18996
18996
|
this.draw.render({ curIndex, isSetCursor });
|
|
18997
18997
|
}
|
|
18998
|
-
|
|
18999
|
-
|
|
18998
|
+
// Each level indents by the list's marker column, so a nested marker starts
|
|
18999
|
+
// exactly where its parent's text starts
|
|
19000
|
+
getListIndentWidth(element, markerWidth) {
|
|
19000
19001
|
const level = element.listLevel ?? 0;
|
|
19001
|
-
return level *
|
|
19002
|
+
return level * markerWidth;
|
|
19002
19003
|
}
|
|
19003
19004
|
_getListMarkerStyleElement(elementList, startIndex = 0) {
|
|
19004
19005
|
const startElement = elementList[startIndex];
|
|
@@ -19111,10 +19112,11 @@ var ListParticle = class {
|
|
|
19111
19112
|
if (!cycle) return "\u25CF";
|
|
19112
19113
|
return cycle[level % cycle.length];
|
|
19113
19114
|
}
|
|
19114
|
-
|
|
19115
|
-
|
|
19115
|
+
// Marker x for a list row's first line (shared by canvas drawing and export)
|
|
19116
|
+
getListMarkerX(row, position) {
|
|
19117
|
+
const { elementList, offsetX } = row;
|
|
19116
19118
|
const startElement = elementList[0];
|
|
19117
|
-
if (startElement.value !== ZERO || startElement.listWrap) return;
|
|
19119
|
+
if (startElement.value !== ZERO || startElement.listWrap) return null;
|
|
19118
19120
|
let tabWidth = 0;
|
|
19119
19121
|
const { defaultTabWidth, scale } = this.options;
|
|
19120
19122
|
for (let i = 1; i < elementList.length; i++) {
|
|
@@ -19124,12 +19126,30 @@ var ListParticle = class {
|
|
|
19124
19126
|
}
|
|
19125
19127
|
const {
|
|
19126
19128
|
coordinate: {
|
|
19127
|
-
leftTop: [startX
|
|
19129
|
+
leftTop: [startX]
|
|
19128
19130
|
}
|
|
19129
19131
|
} = position;
|
|
19130
|
-
const
|
|
19131
|
-
const
|
|
19132
|
-
|
|
19132
|
+
const level = startElement.listLevel ?? 0;
|
|
19133
|
+
const markerWidth = offsetX / (level + 1);
|
|
19134
|
+
return startX - markerWidth + tabWidth;
|
|
19135
|
+
}
|
|
19136
|
+
getListMarker(row) {
|
|
19137
|
+
const startElement = row.elementList[0];
|
|
19138
|
+
if (startElement.listStyle === "checkbox" /* CHECKBOX */) return null;
|
|
19139
|
+
const text = this._getListMarkerText(startElement, row.listIndex);
|
|
19140
|
+
if (!text) return null;
|
|
19141
|
+
return {
|
|
19142
|
+
text,
|
|
19143
|
+
styleElement: this._getListMarkerStyleElement(row.elementList)
|
|
19144
|
+
};
|
|
19145
|
+
}
|
|
19146
|
+
drawListStyle(ctx, row, position) {
|
|
19147
|
+
const { elementList, ascent } = row;
|
|
19148
|
+
const startElement = elementList[0];
|
|
19149
|
+
const x = this.getListMarkerX(row, position);
|
|
19150
|
+
if (x === null) return;
|
|
19151
|
+
const { scale } = this.options;
|
|
19152
|
+
const y = position.coordinate.leftTop[1] + ascent;
|
|
19133
19153
|
if (startElement.listStyle === "checkbox" /* CHECKBOX */) {
|
|
19134
19154
|
const { width, height, gap } = this.options.checkbox;
|
|
19135
19155
|
const checkboxRowElement = {
|
|
@@ -19154,12 +19174,11 @@ var ListParticle = class {
|
|
|
19154
19174
|
}
|
|
19155
19175
|
});
|
|
19156
19176
|
} else {
|
|
19157
|
-
const
|
|
19158
|
-
if (!
|
|
19159
|
-
const markerStyleElement = this._getListMarkerStyleElement(elementList);
|
|
19177
|
+
const marker = this.getListMarker(row);
|
|
19178
|
+
if (!marker) return;
|
|
19160
19179
|
ctx.save();
|
|
19161
|
-
ctx.font = this.draw.getElementFont(
|
|
19162
|
-
ctx.fillText(text, x, y);
|
|
19180
|
+
ctx.font = this.draw.getElementFont(marker.styleElement, scale);
|
|
19181
|
+
ctx.fillText(marker.text, x, y);
|
|
19163
19182
|
ctx.restore();
|
|
19164
19183
|
}
|
|
19165
19184
|
}
|
|
@@ -22395,8 +22414,9 @@ var Draw = class {
|
|
|
22395
22414
|
boundingBoxAscent: 0,
|
|
22396
22415
|
boundingBoxDescent: 0
|
|
22397
22416
|
};
|
|
22398
|
-
const
|
|
22399
|
-
const
|
|
22417
|
+
const listMarkerWidth = element.listId && listStyleMap.get(element.listId) || 0;
|
|
22418
|
+
const listIndentWidth = element.listId ? this.listParticle.getListIndentWidth(element, listMarkerWidth) : 0;
|
|
22419
|
+
const offsetX = curRow.offsetX || listMarkerWidth + listIndentWidth || 0;
|
|
22400
22420
|
const availableWidth = innerWidth - offsetX;
|
|
22401
22421
|
const isStartElement = curRow.elementList.length === 1;
|
|
22402
22422
|
x += isStartElement ? offsetX : 0;
|
|
@@ -23144,7 +23164,10 @@ var Draw = class {
|
|
|
23144
23164
|
if (element.listId) {
|
|
23145
23165
|
row.isList = true;
|
|
23146
23166
|
const baseListOffset = listStyleMap.get(element.listId) || 0;
|
|
23147
|
-
const rowListIndent = this.listParticle.getListIndentWidth(
|
|
23167
|
+
const rowListIndent = this.listParticle.getListIndentWidth(
|
|
23168
|
+
element,
|
|
23169
|
+
baseListOffset
|
|
23170
|
+
);
|
|
23148
23171
|
row.offsetX = baseListOffset + rowListIndent;
|
|
23149
23172
|
row.listIndex = listState.listIndex;
|
|
23150
23173
|
}
|
|
@@ -24347,1273 +24370,1039 @@ var Command = class {
|
|
|
24347
24370
|
}
|
|
24348
24371
|
};
|
|
24349
24372
|
|
|
24350
|
-
// src/utils/
|
|
24373
|
+
// src/utils/docxLayout.ts
|
|
24351
24374
|
import {
|
|
24352
|
-
AlignmentType,
|
|
24353
24375
|
BorderStyle,
|
|
24354
|
-
ColumnBreak,
|
|
24355
24376
|
Document as Document2,
|
|
24356
24377
|
ExternalHyperlink,
|
|
24357
24378
|
Footer as Footer2,
|
|
24358
24379
|
Header as Header2,
|
|
24359
|
-
|
|
24380
|
+
HeightRule,
|
|
24360
24381
|
ImageRun,
|
|
24361
|
-
LevelFormat,
|
|
24362
24382
|
LineRuleType,
|
|
24363
24383
|
Packer,
|
|
24364
|
-
PageBreak,
|
|
24365
|
-
PageNumber as PageNumber2,
|
|
24366
24384
|
PageOrientation,
|
|
24367
24385
|
Paragraph,
|
|
24368
24386
|
ShadingType,
|
|
24387
|
+
Tab,
|
|
24388
|
+
TabStopType,
|
|
24369
24389
|
Table,
|
|
24370
24390
|
TableCell,
|
|
24371
24391
|
TableLayoutType,
|
|
24372
24392
|
TableRow,
|
|
24373
24393
|
TextRun,
|
|
24374
|
-
UnderlineType,
|
|
24375
24394
|
VerticalAlign as DocxVerticalAlign,
|
|
24376
|
-
WidthType
|
|
24395
|
+
WidthType,
|
|
24396
|
+
XmlAttributeComponent,
|
|
24397
|
+
XmlComponent
|
|
24377
24398
|
} from "docx";
|
|
24399
|
+
|
|
24400
|
+
// src/utils/docx.ts
|
|
24401
|
+
import { UnderlineType } from "docx";
|
|
24378
24402
|
var DEFAULT_DOCX_FILE_NAME = "document.docx";
|
|
24379
24403
|
var DEFAULT_IMAGE_WIDTH = 320;
|
|
24380
24404
|
var DEFAULT_IMAGE_HEIGHT = 180;
|
|
24381
|
-
|
|
24382
|
-
|
|
24383
|
-
|
|
24384
|
-
|
|
24385
|
-
|
|
24386
|
-
|
|
24387
|
-
|
|
24388
|
-
};
|
|
24389
|
-
|
|
24390
|
-
|
|
24391
|
-
|
|
24392
|
-
|
|
24393
|
-
|
|
24394
|
-
|
|
24395
|
-
["
|
|
24396
|
-
|
|
24397
|
-
|
|
24398
|
-
|
|
24399
|
-
|
|
24400
|
-
|
|
24401
|
-
|
|
24402
|
-
|
|
24403
|
-
|
|
24404
|
-
|
|
24405
|
-
|
|
24406
|
-
|
|
24407
|
-
|
|
24408
|
-
|
|
24409
|
-
|
|
24410
|
-
|
|
24411
|
-
|
|
24412
|
-
|
|
24405
|
+
async function loadImagePayload(src) {
|
|
24406
|
+
const source = src.trim();
|
|
24407
|
+
if (source.startsWith("data:")) {
|
|
24408
|
+
return getImagePayloadFromDataUrl(source);
|
|
24409
|
+
}
|
|
24410
|
+
const response = await fetch(source);
|
|
24411
|
+
if (!response.ok) {
|
|
24412
|
+
throw new Error(`Image request failed: ${response.status}`);
|
|
24413
|
+
}
|
|
24414
|
+
const contentType = response.headers.get("content-type") || "";
|
|
24415
|
+
const data2 = await response.arrayBuffer();
|
|
24416
|
+
return normalizeImagePayload(data2, contentType);
|
|
24417
|
+
}
|
|
24418
|
+
async function getImagePayloadFromDataUrl(src) {
|
|
24419
|
+
const [, meta = "", encoded = ""] = src.match(/^data:([^,]*),(.*)$/) || [];
|
|
24420
|
+
const mime = meta.split(";")[0] || "";
|
|
24421
|
+
const isBase64 = meta.includes(";base64");
|
|
24422
|
+
const text = isBase64 ? atob(encoded) : decodeURIComponent(encoded);
|
|
24423
|
+
const bytes = new Uint8Array(text.length);
|
|
24424
|
+
for (let i = 0; i < text.length; i++) {
|
|
24425
|
+
bytes[i] = text.charCodeAt(i);
|
|
24426
|
+
}
|
|
24427
|
+
return normalizeImagePayload(bytes.buffer, mime);
|
|
24428
|
+
}
|
|
24429
|
+
async function normalizeImagePayload(data2, mime) {
|
|
24430
|
+
const type = getRegularImageType(mime);
|
|
24431
|
+
if (type) {
|
|
24432
|
+
return {
|
|
24433
|
+
type,
|
|
24434
|
+
data: data2
|
|
24435
|
+
};
|
|
24436
|
+
}
|
|
24437
|
+
if (mime.includes("svg")) {
|
|
24438
|
+
return {
|
|
24439
|
+
type: "svg",
|
|
24440
|
+
data: data2,
|
|
24441
|
+
fallbackPng: await rasterizeSvgToPng(data2)
|
|
24442
|
+
};
|
|
24443
|
+
}
|
|
24444
|
+
const fallbackPng = await rasterizeImageToPng(data2, mime);
|
|
24413
24445
|
return {
|
|
24414
|
-
|
|
24415
|
-
|
|
24446
|
+
type: "png",
|
|
24447
|
+
data: fallbackPng
|
|
24416
24448
|
};
|
|
24417
24449
|
}
|
|
24418
|
-
async function
|
|
24419
|
-
|
|
24420
|
-
|
|
24421
|
-
|
|
24422
|
-
const
|
|
24423
|
-
|
|
24424
|
-
|
|
24425
|
-
|
|
24426
|
-
|
|
24427
|
-
|
|
24428
|
-
|
|
24429
|
-
|
|
24430
|
-
|
|
24431
|
-
|
|
24432
|
-
|
|
24450
|
+
async function rasterizeSvgToPng(data2) {
|
|
24451
|
+
return rasterizeImageToPng(data2, "image/svg+xml");
|
|
24452
|
+
}
|
|
24453
|
+
async function rasterizeImageToPng(data2, mime) {
|
|
24454
|
+
const blob = new Blob([data2], {
|
|
24455
|
+
type: mime || "image/png"
|
|
24456
|
+
});
|
|
24457
|
+
const url = URL.createObjectURL(blob);
|
|
24458
|
+
try {
|
|
24459
|
+
const image = await loadHtmlImage(url);
|
|
24460
|
+
const canvas = document.createElement("canvas");
|
|
24461
|
+
canvas.width = image.naturalWidth || DEFAULT_IMAGE_WIDTH;
|
|
24462
|
+
canvas.height = image.naturalHeight || DEFAULT_IMAGE_HEIGHT;
|
|
24463
|
+
const context = canvas.getContext("2d");
|
|
24464
|
+
if (!context) {
|
|
24465
|
+
throw new Error("Canvas context is unavailable");
|
|
24433
24466
|
}
|
|
24434
|
-
|
|
24435
|
-
|
|
24436
|
-
|
|
24467
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
24468
|
+
const pngBlob = await new Promise((resolve, reject) => {
|
|
24469
|
+
canvas.toBlob((output) => {
|
|
24470
|
+
if (output) {
|
|
24471
|
+
resolve(output);
|
|
24472
|
+
} else {
|
|
24473
|
+
reject(new Error("Failed to create PNG blob"));
|
|
24474
|
+
}
|
|
24475
|
+
}, "image/png");
|
|
24476
|
+
});
|
|
24477
|
+
return await pngBlob.arrayBuffer();
|
|
24478
|
+
} finally {
|
|
24479
|
+
URL.revokeObjectURL(url);
|
|
24437
24480
|
}
|
|
24438
|
-
|
|
24439
|
-
|
|
24440
|
-
|
|
24441
|
-
|
|
24442
|
-
|
|
24443
|
-
|
|
24444
|
-
|
|
24445
|
-
|
|
24481
|
+
}
|
|
24482
|
+
function loadHtmlImage(src) {
|
|
24483
|
+
return new Promise((resolve, reject) => {
|
|
24484
|
+
const image = new Image();
|
|
24485
|
+
image.onload = () => resolve(image);
|
|
24486
|
+
image.onerror = () => reject(new Error("Failed to load image"));
|
|
24487
|
+
image.src = src;
|
|
24488
|
+
});
|
|
24489
|
+
}
|
|
24490
|
+
function mapUnderlineType(style) {
|
|
24491
|
+
switch (style) {
|
|
24492
|
+
case "double" /* DOUBLE */:
|
|
24493
|
+
return UnderlineType.DOUBLE;
|
|
24494
|
+
case "dashed" /* DASHED */:
|
|
24495
|
+
return UnderlineType.DASH;
|
|
24496
|
+
case "dotted" /* DOTTED */:
|
|
24497
|
+
return UnderlineType.DOTTED;
|
|
24498
|
+
case "wavy" /* WAVY */:
|
|
24499
|
+
return UnderlineType.WAVE;
|
|
24500
|
+
default:
|
|
24501
|
+
return UnderlineType.SINGLE;
|
|
24502
|
+
}
|
|
24503
|
+
}
|
|
24504
|
+
function normalizeHexColor(color, fallback) {
|
|
24505
|
+
const normalized = normalizeHexLiteral(color) || normalizeRgbColor(color) || normalizeBrowserColor(color);
|
|
24506
|
+
if (normalized) {
|
|
24507
|
+
return normalized;
|
|
24508
|
+
}
|
|
24509
|
+
return fallback ? normalizeHexLiteral(fallback) || void 0 : void 0;
|
|
24510
|
+
}
|
|
24511
|
+
function normalizeHexLiteral(color) {
|
|
24512
|
+
const value = color.trim().replace(/^#/, "");
|
|
24513
|
+
if (/^[\da-f]{3}$/i.test(value)) {
|
|
24514
|
+
return value.split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
24515
|
+
}
|
|
24516
|
+
if (/^[\da-f]{4}$/i.test(value)) {
|
|
24517
|
+
return value.slice(0, 3).split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
24518
|
+
}
|
|
24519
|
+
if (/^[\da-f]{6}$/i.test(value)) {
|
|
24520
|
+
return value.toUpperCase();
|
|
24521
|
+
}
|
|
24522
|
+
if (/^[\da-f]{8}$/i.test(value)) {
|
|
24523
|
+
return value.slice(0, 6).toUpperCase();
|
|
24524
|
+
}
|
|
24525
|
+
return void 0;
|
|
24526
|
+
}
|
|
24527
|
+
function normalizeRgbColor(color) {
|
|
24528
|
+
const match = color.trim().match(/^rgba?\((.+)\)$/i);
|
|
24529
|
+
if (!match) {
|
|
24530
|
+
return void 0;
|
|
24531
|
+
}
|
|
24532
|
+
const parts = match[1].replace(/\s*\/\s*/g, ",").split(/\s*,\s*|\s+/).filter(Boolean);
|
|
24533
|
+
if (parts.length < 3) {
|
|
24534
|
+
return void 0;
|
|
24535
|
+
}
|
|
24536
|
+
const red = parseRgbChannel(parts[0]);
|
|
24537
|
+
const green = parseRgbChannel(parts[1]);
|
|
24538
|
+
const blue = parseRgbChannel(parts[2]);
|
|
24539
|
+
if (red === null || green === null || blue === null) {
|
|
24540
|
+
return void 0;
|
|
24541
|
+
}
|
|
24542
|
+
const alpha = parts[3] !== void 0 ? parseAlphaChannel(parts[3]) : 1;
|
|
24543
|
+
if (alpha === null || alpha <= 0) {
|
|
24544
|
+
return void 0;
|
|
24545
|
+
}
|
|
24546
|
+
const flattened = alpha >= 1 ? [red, green, blue] : [
|
|
24547
|
+
flattenChannel(red, alpha),
|
|
24548
|
+
flattenChannel(green, alpha),
|
|
24549
|
+
flattenChannel(blue, alpha)
|
|
24550
|
+
];
|
|
24551
|
+
return flattened.map(toHexChannel).join("");
|
|
24552
|
+
}
|
|
24553
|
+
function normalizeBrowserColor(color) {
|
|
24554
|
+
if (typeof document === "undefined") {
|
|
24555
|
+
return void 0;
|
|
24556
|
+
}
|
|
24557
|
+
const canvas = document.createElement("canvas");
|
|
24558
|
+
const context = canvas.getContext("2d");
|
|
24559
|
+
if (!context) {
|
|
24560
|
+
return void 0;
|
|
24561
|
+
}
|
|
24562
|
+
context.fillStyle = "#000000";
|
|
24563
|
+
context.fillStyle = color;
|
|
24564
|
+
const normalized = context.fillStyle;
|
|
24565
|
+
if (typeof normalized !== "string") {
|
|
24566
|
+
return void 0;
|
|
24567
|
+
}
|
|
24568
|
+
return normalizeHexLiteral(normalized) || normalizeRgbColor(normalized);
|
|
24569
|
+
}
|
|
24570
|
+
function parseRgbChannel(value) {
|
|
24571
|
+
if (value.endsWith("%")) {
|
|
24572
|
+
const percent = Number(value.slice(0, -1));
|
|
24573
|
+
if (!Number.isFinite(percent)) {
|
|
24574
|
+
return null;
|
|
24575
|
+
}
|
|
24576
|
+
return clampColorChannel(Math.round(percent / 100 * 255));
|
|
24577
|
+
}
|
|
24578
|
+
const channel = Number(value);
|
|
24579
|
+
if (!Number.isFinite(channel)) {
|
|
24580
|
+
return null;
|
|
24581
|
+
}
|
|
24582
|
+
return clampColorChannel(Math.round(channel));
|
|
24583
|
+
}
|
|
24584
|
+
function parseAlphaChannel(value) {
|
|
24585
|
+
if (value.endsWith("%")) {
|
|
24586
|
+
const percent = Number(value.slice(0, -1));
|
|
24587
|
+
if (!Number.isFinite(percent)) {
|
|
24588
|
+
return null;
|
|
24589
|
+
}
|
|
24590
|
+
return Math.min(Math.max(percent / 100, 0), 1);
|
|
24591
|
+
}
|
|
24592
|
+
const alpha = Number(value);
|
|
24593
|
+
if (!Number.isFinite(alpha)) {
|
|
24594
|
+
return null;
|
|
24595
|
+
}
|
|
24596
|
+
return Math.min(Math.max(alpha, 0), 1);
|
|
24597
|
+
}
|
|
24598
|
+
function clampColorChannel(value) {
|
|
24599
|
+
return Math.min(Math.max(value, 0), 255);
|
|
24600
|
+
}
|
|
24601
|
+
function flattenChannel(value, alpha) {
|
|
24602
|
+
return clampColorChannel(Math.round(255 * (1 - alpha) + value * alpha));
|
|
24603
|
+
}
|
|
24604
|
+
function toHexChannel(value) {
|
|
24605
|
+
return value.toString(16).padStart(2, "0").toUpperCase();
|
|
24606
|
+
}
|
|
24607
|
+
function getRegularImageType(mime) {
|
|
24608
|
+
if (mime.includes("png")) return "png";
|
|
24609
|
+
if (mime.includes("jpeg") || mime.includes("jpg")) return "jpg";
|
|
24610
|
+
if (mime.includes("gif")) return "gif";
|
|
24611
|
+
if (mime.includes("bmp")) return "bmp";
|
|
24612
|
+
return null;
|
|
24613
|
+
}
|
|
24614
|
+
function normalizeDocxFileName(fileName) {
|
|
24615
|
+
const trimmed = fileName?.trim();
|
|
24616
|
+
if (!trimmed) {
|
|
24617
|
+
return DEFAULT_DOCX_FILE_NAME;
|
|
24618
|
+
}
|
|
24619
|
+
return trimmed.toLowerCase().endsWith(".docx") ? trimmed : `${trimmed}.docx`;
|
|
24620
|
+
}
|
|
24621
|
+
|
|
24622
|
+
// src/utils/docxLayout.ts
|
|
24623
|
+
var PX_TO_TWIP = 15;
|
|
24624
|
+
var ANCHOR_EPS = 0.5;
|
|
24625
|
+
var RIGHT_SLACK_TWIP = -14400;
|
|
24626
|
+
var TINY_TWIP = 1;
|
|
24627
|
+
var tw = (ctx, layoutPx) => Math.round(layoutPx / ctx.scale * PX_TO_TWIP);
|
|
24628
|
+
var pxTw = (px) => Math.round(px * PX_TO_TWIP);
|
|
24629
|
+
async function exportDrawToDocx(draw, options = {}) {
|
|
24630
|
+
const canvas = document.createElement("canvas");
|
|
24631
|
+
const measureCtx = canvas.getContext("2d");
|
|
24632
|
+
const ctx = {
|
|
24633
|
+
draw,
|
|
24634
|
+
scale: draw.getOptions().scale,
|
|
24635
|
+
measureCtx
|
|
24636
|
+
};
|
|
24637
|
+
const file = await createDocument(ctx);
|
|
24638
|
+
const blob = await Packer.toBlob(file);
|
|
24639
|
+
return { blob, fileName: normalizeDocxFileName(options.fileName) };
|
|
24640
|
+
}
|
|
24641
|
+
async function createDocument(ctx) {
|
|
24642
|
+
const { draw, scale } = ctx;
|
|
24643
|
+
const opts = draw.getOptions();
|
|
24644
|
+
const width = draw.getOriginalWidth();
|
|
24645
|
+
const height = draw.getOriginalHeight();
|
|
24646
|
+
const margins = draw.getOriginalMargins();
|
|
24647
|
+
const header = draw.getHeader();
|
|
24648
|
+
const footer = draw.getFooter();
|
|
24649
|
+
const headerTop = header.getHeaderTop() / scale;
|
|
24650
|
+
const headerExtra = header.getExtraHeight() / scale;
|
|
24651
|
+
const footerExtra = footer.getExtraHeight() / scale;
|
|
24652
|
+
const layoutMargins = draw.getMargins();
|
|
24653
|
+
const body = await serializeMain(ctx, layoutMargins[3]);
|
|
24654
|
+
const headerChildren = opts.header.disabled ? [] : await serializeRows(ctx, header.getRowList(), {
|
|
24655
|
+
startX: layoutMargins[3],
|
|
24656
|
+
width: draw.getInnerWidth(),
|
|
24657
|
+
positionList: header.getPositionList()
|
|
24658
|
+
});
|
|
24659
|
+
const footerChildren = opts.footer.disabled ? [] : await serializeFooter(ctx, width, height, margins);
|
|
24660
|
+
const { pageNumber } = draw.getOptions();
|
|
24661
|
+
endWithParagraph(headerChildren);
|
|
24662
|
+
endWithParagraph(footerChildren);
|
|
24446
24663
|
return new Document2({
|
|
24447
|
-
|
|
24448
|
-
|
|
24449
|
-
|
|
24450
|
-
|
|
24451
|
-
|
|
24664
|
+
compatabilityModeVersion: 15,
|
|
24665
|
+
// LibreOffice formats PAGE/NUMPAGES results from the paragraph style
|
|
24666
|
+
styles: {
|
|
24667
|
+
paragraphStyles: [
|
|
24668
|
+
{
|
|
24669
|
+
id: PAGE_NUMBER_STYLE,
|
|
24670
|
+
name: "Windoc Page Number",
|
|
24671
|
+
run: pageNumberRunStyle(pageNumber)
|
|
24672
|
+
}
|
|
24673
|
+
]
|
|
24452
24674
|
},
|
|
24675
|
+
defaultTabStop: pxTw(width),
|
|
24453
24676
|
sections: [
|
|
24454
24677
|
{
|
|
24455
24678
|
properties: {
|
|
24456
24679
|
page: {
|
|
24457
24680
|
size: {
|
|
24458
|
-
width:
|
|
24459
|
-
height:
|
|
24460
|
-
orientation: paperDirection === "horizontal" /* HORIZONTAL */ ? PageOrientation.LANDSCAPE : PageOrientation.PORTRAIT
|
|
24681
|
+
width: pxTw(width),
|
|
24682
|
+
height: pxTw(height),
|
|
24683
|
+
orientation: opts.paperDirection === "horizontal" /* HORIZONTAL */ ? PageOrientation.LANDSCAPE : PageOrientation.PORTRAIT
|
|
24461
24684
|
},
|
|
24462
24685
|
margin: {
|
|
24463
|
-
top:
|
|
24464
|
-
right:
|
|
24465
|
-
bottom:
|
|
24466
|
-
left:
|
|
24467
|
-
header:
|
|
24468
|
-
footer:
|
|
24469
|
-
|
|
24470
|
-
|
|
24471
|
-
start: editorOptions.pageNumber.startPageNo
|
|
24472
|
-
} : void 0
|
|
24686
|
+
top: pxTw(margins[0] + headerExtra),
|
|
24687
|
+
right: pxTw(margins[1]),
|
|
24688
|
+
bottom: pxTw(margins[2] + footerExtra),
|
|
24689
|
+
left: pxTw(margins[3]),
|
|
24690
|
+
header: pxTw(headerTop),
|
|
24691
|
+
footer: pxTw(footer.getFooterBottom() / scale),
|
|
24692
|
+
gutter: 0
|
|
24693
|
+
}
|
|
24473
24694
|
}
|
|
24474
24695
|
},
|
|
24475
|
-
headers: headerChildren.length
|
|
24476
|
-
|
|
24477
|
-
|
|
24478
|
-
})
|
|
24479
|
-
} : void 0,
|
|
24480
|
-
footers: footerChildren.length > 0 ? {
|
|
24481
|
-
default: new Footer2({
|
|
24482
|
-
children: footerChildren
|
|
24483
|
-
})
|
|
24484
|
-
} : void 0,
|
|
24485
|
-
children: sectionChildren.length ? sectionChildren : [new Paragraph({})]
|
|
24696
|
+
headers: headerChildren.length ? { default: new Header2({ children: headerChildren }) } : void 0,
|
|
24697
|
+
footers: footerChildren.length ? { default: new Footer2({ children: footerChildren }) } : void 0,
|
|
24698
|
+
children: body.length ? body : [new Paragraph({})]
|
|
24486
24699
|
}
|
|
24487
24700
|
]
|
|
24488
24701
|
});
|
|
24489
24702
|
}
|
|
24490
|
-
async function
|
|
24491
|
-
const
|
|
24492
|
-
|
|
24493
|
-
|
|
24494
|
-
|
|
24495
|
-
|
|
24496
|
-
...await serializeInlineElements(inlineBuffer, options, context)
|
|
24497
|
-
);
|
|
24498
|
-
inlineBuffer = [];
|
|
24703
|
+
async function serializeMain(ctx, startX) {
|
|
24704
|
+
const { draw } = ctx;
|
|
24705
|
+
const zone = {
|
|
24706
|
+
startX,
|
|
24707
|
+
width: draw.getInnerWidth(),
|
|
24708
|
+
positionList: draw.getPosition().getOriginalMainPositionList()
|
|
24499
24709
|
};
|
|
24500
|
-
|
|
24501
|
-
|
|
24502
|
-
|
|
24503
|
-
|
|
24504
|
-
|
|
24505
|
-
|
|
24506
|
-
)
|
|
24507
|
-
|
|
24508
|
-
|
|
24509
|
-
|
|
24510
|
-
|
|
24511
|
-
|
|
24512
|
-
|
|
24513
|
-
|
|
24514
|
-
|
|
24515
|
-
|
|
24516
|
-
|
|
24517
|
-
|
|
24518
|
-
|
|
24519
|
-
|
|
24520
|
-
|
|
24521
|
-
|
|
24522
|
-
|
|
24523
|
-
|
|
24524
|
-
|
|
24525
|
-
blocks.push(await serializeTableElement(element, options, context));
|
|
24526
|
-
continue;
|
|
24527
|
-
}
|
|
24528
|
-
if (element.type === "pageBreak" /* PAGE_BREAK */) {
|
|
24529
|
-
await flushInlineBuffer();
|
|
24530
|
-
blocks.push(
|
|
24531
|
-
new Paragraph({
|
|
24532
|
-
children: [new PageBreak()]
|
|
24533
|
-
})
|
|
24534
|
-
);
|
|
24535
|
-
continue;
|
|
24536
|
-
}
|
|
24537
|
-
if (element.type === "separator" /* SEPARATOR */) {
|
|
24538
|
-
await flushInlineBuffer();
|
|
24539
|
-
blocks.push(
|
|
24540
|
-
new Paragraph({
|
|
24541
|
-
thematicBreak: true
|
|
24542
|
-
})
|
|
24543
|
-
);
|
|
24544
|
-
continue;
|
|
24545
|
-
}
|
|
24546
|
-
if (element.type === "image" /* IMAGE */ && element.imgDisplay && element.imgDisplay !== "inline") {
|
|
24547
|
-
await flushInlineBuffer();
|
|
24548
|
-
blocks.push(...await serializeInlineElements([element], options));
|
|
24549
|
-
continue;
|
|
24550
|
-
}
|
|
24551
|
-
if (element.type === "block" /* BLOCK */) {
|
|
24552
|
-
await flushInlineBuffer();
|
|
24553
|
-
const blockText = getBlockFallbackText(element);
|
|
24554
|
-
if (blockText) {
|
|
24555
|
-
blocks.push(
|
|
24556
|
-
...await serializeInlineElements(
|
|
24557
|
-
[{ value: blockText }],
|
|
24558
|
-
options,
|
|
24559
|
-
context
|
|
24710
|
+
const children = [];
|
|
24711
|
+
const pageRowList = draw.getPageRowList();
|
|
24712
|
+
for (let p = 0; p < pageRowList.length; p++) {
|
|
24713
|
+
children.push(
|
|
24714
|
+
...await serializeRows(ctx, pageRowList[p], zone, {
|
|
24715
|
+
pageBreakBefore: p > 0
|
|
24716
|
+
})
|
|
24717
|
+
);
|
|
24718
|
+
}
|
|
24719
|
+
return children;
|
|
24720
|
+
}
|
|
24721
|
+
async function serializeRows(ctx, rowList, zone, options = {}) {
|
|
24722
|
+
const { pageBreakBefore = false, padTop = 0, padBottom = 0 } = options;
|
|
24723
|
+
const children = [];
|
|
24724
|
+
for (let r = 0; r < rowList.length; r++) {
|
|
24725
|
+
const row = rowList[r];
|
|
24726
|
+
const isFirst = r === 0;
|
|
24727
|
+
const isLast = r === rowList.length - 1;
|
|
24728
|
+
const table = row.elementList.find((el) => el.type === "table" /* TABLE */);
|
|
24729
|
+
if (table) {
|
|
24730
|
+
if (isFirst && (pageBreakBefore || padTop) || row.offsetY) {
|
|
24731
|
+
children.push(
|
|
24732
|
+
createSpacerParagraph(
|
|
24733
|
+
isFirst && pageBreakBefore,
|
|
24734
|
+
(isFirst ? padTop : 0) + (row.offsetY || 0) / ctx.scale
|
|
24560
24735
|
)
|
|
24561
24736
|
);
|
|
24562
24737
|
}
|
|
24738
|
+
const position = zone.positionList[row.startIndex + row.elementList.indexOf(table)];
|
|
24739
|
+
children.push(await serializeTable(ctx, table, position, zone));
|
|
24740
|
+
const rest = (row.height + (row.spaceBelow || 0)) / ctx.scale - table.height + (isLast ? padBottom : 0);
|
|
24741
|
+
if (rest * PX_TO_TWIP >= 1) {
|
|
24742
|
+
children.push(createSpacerParagraph(false, rest));
|
|
24743
|
+
}
|
|
24563
24744
|
continue;
|
|
24564
24745
|
}
|
|
24565
|
-
|
|
24746
|
+
const rowOptions = {
|
|
24747
|
+
pageBreakBefore: isFirst && pageBreakBefore,
|
|
24748
|
+
padTop: isFirst ? padTop : 0,
|
|
24749
|
+
padBottom: isLast ? padBottom : 0
|
|
24750
|
+
};
|
|
24751
|
+
if (!isFirst && isTextRow(rowList[r - 1])) rowOptions.skipLead = true;
|
|
24752
|
+
rowOptions.rowY = rowY(zone, row);
|
|
24753
|
+
if (!isLast && isTextRow(rowList[r + 1])) {
|
|
24754
|
+
rowOptions.extraAfter = rowLead(ctx, rowList[r + 1], {
|
|
24755
|
+
rowY: rowY(zone, rowList[r + 1])
|
|
24756
|
+
});
|
|
24757
|
+
}
|
|
24758
|
+
const lead = rowOptions.pageBreakBefore ? rowLead(ctx, row, rowOptions) : 0;
|
|
24759
|
+
if (lead) {
|
|
24760
|
+
children.push(createSpacerParagraph(true, lead / PX_TO_TWIP));
|
|
24761
|
+
rowOptions.pageBreakBefore = false;
|
|
24762
|
+
rowOptions.skipLead = true;
|
|
24763
|
+
}
|
|
24764
|
+
children.push(await serializeRow(ctx, row, zone, rowOptions));
|
|
24566
24765
|
}
|
|
24567
|
-
|
|
24568
|
-
return blocks;
|
|
24766
|
+
return children;
|
|
24569
24767
|
}
|
|
24570
|
-
|
|
24571
|
-
|
|
24572
|
-
|
|
24573
|
-
|
|
24574
|
-
|
|
24575
|
-
|
|
24576
|
-
|
|
24577
|
-
|
|
24578
|
-
}
|
|
24579
|
-
const
|
|
24580
|
-
|
|
24581
|
-
|
|
24582
|
-
|
|
24768
|
+
function rowY(zone, row) {
|
|
24769
|
+
return zone.positionList[row.startIndex]?.coordinate.leftTop[1];
|
|
24770
|
+
}
|
|
24771
|
+
function isTextRow(row) {
|
|
24772
|
+
return !row.elementList.some((el) => el.type === "table" /* TABLE */);
|
|
24773
|
+
}
|
|
24774
|
+
async function serializeRow(ctx, row, zone, options, suffix) {
|
|
24775
|
+
const { pageBreakBefore = false } = options;
|
|
24776
|
+
const { draw, scale } = ctx;
|
|
24777
|
+
const positions = zone.positionList;
|
|
24778
|
+
const children = [];
|
|
24779
|
+
const tabStops = [];
|
|
24780
|
+
const firstPosition = positions[row.startIndex];
|
|
24781
|
+
let pen = 0;
|
|
24782
|
+
let indent = firstPosition ? (firstPosition.coordinate.leftTop[0] - zone.startX) / scale : 0;
|
|
24783
|
+
let started = false;
|
|
24784
|
+
const anchorTo = (layoutX) => {
|
|
24785
|
+
const target = (layoutX - zone.startX) / scale;
|
|
24786
|
+
if (!started) {
|
|
24787
|
+
indent = target;
|
|
24788
|
+
pen = target;
|
|
24789
|
+
started = true;
|
|
24583
24790
|
return;
|
|
24584
24791
|
}
|
|
24585
|
-
|
|
24586
|
-
|
|
24587
|
-
|
|
24588
|
-
|
|
24589
|
-
options.defaultRowMargin
|
|
24590
|
-
)
|
|
24591
|
-
);
|
|
24592
|
-
current = null;
|
|
24593
|
-
};
|
|
24594
|
-
const ensureParagraph = (element) => {
|
|
24595
|
-
if (!current) {
|
|
24596
|
-
current = {
|
|
24597
|
-
children: [],
|
|
24598
|
-
context: getParagraphContext(element)
|
|
24599
|
-
};
|
|
24792
|
+
if (target - pen > ANCHOR_EPS) {
|
|
24793
|
+
tabStops.push(pxTw(target));
|
|
24794
|
+
children.push(new TextRun({ children: [new Tab()] }));
|
|
24795
|
+
pen = target;
|
|
24600
24796
|
}
|
|
24601
|
-
return current;
|
|
24602
24797
|
};
|
|
24603
|
-
|
|
24604
|
-
const
|
|
24605
|
-
const
|
|
24606
|
-
|
|
24607
|
-
|
|
24608
|
-
|
|
24609
|
-
|
|
24610
|
-
|
|
24611
|
-
|
|
24612
|
-
|
|
24613
|
-
|
|
24614
|
-
|
|
24615
|
-
|
|
24616
|
-
|
|
24617
|
-
|
|
24618
|
-
|
|
24619
|
-
|
|
24620
|
-
|
|
24621
|
-
|
|
24622
|
-
|
|
24623
|
-
|
|
24624
|
-
|
|
24625
|
-
|
|
24626
|
-
|
|
24627
|
-
|
|
24628
|
-
|
|
24629
|
-
|
|
24630
|
-
|
|
24631
|
-
|
|
24632
|
-
|
|
24633
|
-
|
|
24634
|
-
)
|
|
24798
|
+
if (row.isList && firstPosition) {
|
|
24799
|
+
const listParticle = draw.getListParticle();
|
|
24800
|
+
const markerX = listParticle.getListMarkerX(row, firstPosition);
|
|
24801
|
+
const marker = markerX === null ? null : listParticle.getListMarker(row);
|
|
24802
|
+
if (markerX !== null && marker) {
|
|
24803
|
+
anchorTo(markerX);
|
|
24804
|
+
children.push(createTextRun(ctx, marker.text, marker.styleElement));
|
|
24805
|
+
pen += measure(ctx, marker.text, marker.styleElement);
|
|
24806
|
+
}
|
|
24807
|
+
}
|
|
24808
|
+
let run = null;
|
|
24809
|
+
const flush = () => {
|
|
24810
|
+
if (!run) return;
|
|
24811
|
+
children.push(createTextRun(ctx, run.text, run.element));
|
|
24812
|
+
run = null;
|
|
24813
|
+
};
|
|
24814
|
+
for (let j = 0; j < row.elementList.length; j++) {
|
|
24815
|
+
const element = row.elementList[j];
|
|
24816
|
+
const position = positions[row.startIndex + j];
|
|
24817
|
+
if (!position) continue;
|
|
24818
|
+
if (element.hide || element.control?.hide || element.area?.hide) continue;
|
|
24819
|
+
if (element.type === "separator" /* SEPARATOR */) {
|
|
24820
|
+
flush();
|
|
24821
|
+
return createSeparatorParagraph(
|
|
24822
|
+
ctx,
|
|
24823
|
+
row,
|
|
24824
|
+
element,
|
|
24825
|
+
position.coordinate.leftTop[0],
|
|
24826
|
+
position.coordinate.leftTop[1],
|
|
24827
|
+
zone,
|
|
24828
|
+
options
|
|
24635
24829
|
);
|
|
24636
24830
|
}
|
|
24637
|
-
|
|
24638
|
-
for (let i = 0; i < elementList.length; i++) {
|
|
24639
|
-
const element = elementList[i];
|
|
24640
|
-
if (element.type === "hyperlink" /* HYPERLINK */ && element.valueList?.length) {
|
|
24641
|
-
const hyperlink = await createHyperlinkChild(element, options);
|
|
24642
|
-
if (hyperlink) {
|
|
24643
|
-
ensureParagraph(element).children.push(hyperlink);
|
|
24644
|
-
}
|
|
24831
|
+
if (element.value === ZERO || element.type === "tab" /* TAB */ || element.type === "pageBreak" /* PAGE_BREAK */ || element.type === "columnBreak" /* COLUMN_BREAK */) {
|
|
24645
24832
|
continue;
|
|
24646
24833
|
}
|
|
24834
|
+
const x = position.coordinate.leftTop[0];
|
|
24835
|
+
const layoutWidth = element.metrics.width / scale;
|
|
24647
24836
|
if (element.type === "image" /* IMAGE */) {
|
|
24648
|
-
|
|
24649
|
-
|
|
24650
|
-
|
|
24651
|
-
|
|
24652
|
-
|
|
24653
|
-
(segment) => createTextRun(
|
|
24654
|
-
segment,
|
|
24655
|
-
element,
|
|
24656
|
-
options.defaultSize,
|
|
24657
|
-
options.defaultFont
|
|
24658
|
-
),
|
|
24659
|
-
i === elementList.length - 1
|
|
24660
|
-
);
|
|
24661
|
-
continue;
|
|
24662
|
-
}
|
|
24663
|
-
ensureParagraph(element).children.push(imageChild);
|
|
24664
|
-
continue;
|
|
24665
|
-
}
|
|
24666
|
-
if (element.type === "columnBreak" /* COLUMN_BREAK */) {
|
|
24667
|
-
ensureParagraph(element).children.push(new ColumnBreak());
|
|
24837
|
+
flush();
|
|
24838
|
+
anchorTo(x);
|
|
24839
|
+
const image = await createImageRun(element);
|
|
24840
|
+
if (image) children.push(image);
|
|
24841
|
+
pen += layoutWidth;
|
|
24668
24842
|
continue;
|
|
24669
24843
|
}
|
|
24670
|
-
if (element.type === "
|
|
24671
|
-
|
|
24672
|
-
|
|
24673
|
-
|
|
24674
|
-
|
|
24675
|
-
|
|
24676
|
-
element,
|
|
24677
|
-
options.defaultSize,
|
|
24678
|
-
options.defaultFont
|
|
24679
|
-
),
|
|
24680
|
-
i === elementList.length - 1
|
|
24844
|
+
if (element.type === "label" /* LABEL */) {
|
|
24845
|
+
flush();
|
|
24846
|
+
const padding = element.label?.padding || draw.getOptions().label.defaultPadding;
|
|
24847
|
+
anchorTo(x + padding[3] * scale);
|
|
24848
|
+
children.push(
|
|
24849
|
+
createTextRun(ctx, element.value, element, labelShading(ctx, element))
|
|
24681
24850
|
);
|
|
24851
|
+
pen += measure(ctx, element.value, element);
|
|
24682
24852
|
continue;
|
|
24683
24853
|
}
|
|
24684
|
-
const
|
|
24685
|
-
if (!
|
|
24686
|
-
|
|
24687
|
-
|
|
24688
|
-
|
|
24689
|
-
|
|
24690
|
-
|
|
24691
|
-
|
|
24692
|
-
|
|
24693
|
-
|
|
24694
|
-
|
|
24695
|
-
|
|
24696
|
-
)
|
|
24697
|
-
|
|
24698
|
-
|
|
24699
|
-
|
|
24700
|
-
|
|
24701
|
-
|
|
24702
|
-
|
|
24703
|
-
return paragraphs.length ? paragraphs : [createParagraph([], overrides, options.defaultRowMargin)];
|
|
24704
|
-
}
|
|
24705
|
-
async function serializeListElement(element, options, context) {
|
|
24706
|
-
const zipList = zipElementList(element.valueList || []);
|
|
24707
|
-
const listItemMap = splitListElement(zipList);
|
|
24708
|
-
const paragraphs = [];
|
|
24709
|
-
const listInstance = createListInstance(context);
|
|
24710
|
-
for (const listItemElements of listItemMap.values()) {
|
|
24711
|
-
const numbering = getListNumbering(
|
|
24712
|
-
getListItemNumberingElement(listItemElements, element),
|
|
24713
|
-
listInstance
|
|
24714
|
-
);
|
|
24715
|
-
paragraphs.push(
|
|
24716
|
-
...await serializeInlineElements(listItemElements, options, context, {
|
|
24717
|
-
numbering
|
|
24718
|
-
})
|
|
24719
|
-
);
|
|
24720
|
-
}
|
|
24721
|
-
return paragraphs;
|
|
24722
|
-
}
|
|
24723
|
-
async function serializeTableElement(element, options, context) {
|
|
24724
|
-
const rows = [];
|
|
24725
|
-
const trList = element.trList || [];
|
|
24726
|
-
const tableContext = createTableSerializeContext(element);
|
|
24727
|
-
for (let i = 0; i < trList.length; i++) {
|
|
24728
|
-
rows.push(
|
|
24729
|
-
await serializeTableRow(trList[i], options, context, tableContext)
|
|
24730
|
-
);
|
|
24731
|
-
}
|
|
24732
|
-
const tableWidth = getTableWidthFromColgroup(element.colgroup);
|
|
24733
|
-
return new Table({
|
|
24734
|
-
rows,
|
|
24735
|
-
width: tableWidth ? {
|
|
24736
|
-
size: pxToTwips(tableWidth),
|
|
24737
|
-
type: WidthType.DXA
|
|
24738
|
-
} : {
|
|
24739
|
-
size: 100,
|
|
24740
|
-
type: WidthType.PERCENTAGE
|
|
24741
|
-
},
|
|
24742
|
-
columnWidths: element.colgroup?.map((col) => pxToTwips(col.width)),
|
|
24743
|
-
layout: TableLayoutType.FIXED,
|
|
24744
|
-
borders: createTableBorders(element)
|
|
24745
|
-
});
|
|
24746
|
-
}
|
|
24747
|
-
async function serializeTableRow(tr, options, context, tableContext) {
|
|
24748
|
-
const children = [];
|
|
24749
|
-
for (let i = 0; i < tr.tdList.length; i++) {
|
|
24750
|
-
children.push(
|
|
24751
|
-
await serializeTableCell(tr.tdList[i], options, context, tableContext)
|
|
24752
|
-
);
|
|
24753
|
-
}
|
|
24754
|
-
return new TableRow({
|
|
24755
|
-
children
|
|
24756
|
-
});
|
|
24757
|
-
}
|
|
24758
|
-
async function serializeTableCell(td, options, context, tableContext) {
|
|
24759
|
-
const children = await serializeElementList(td.value, options, context);
|
|
24760
|
-
const shadingFill = td.backgroundColor ? normalizeHexColor(td.backgroundColor) : void 0;
|
|
24761
|
-
const cellWidth = tableContext.cellLayoutMap.get(td)?.width || td.width;
|
|
24762
|
-
return new TableCell({
|
|
24763
|
-
children: children.length ? children : [new Paragraph({})],
|
|
24764
|
-
columnSpan: td.colspan > 1 ? td.colspan : void 0,
|
|
24765
|
-
rowSpan: td.rowspan > 1 ? td.rowspan : void 0,
|
|
24766
|
-
verticalAlign: mapCellVerticalAlign(td.verticalAlign),
|
|
24767
|
-
width: cellWidth ? {
|
|
24768
|
-
size: pxToTwips(cellWidth),
|
|
24769
|
-
type: WidthType.DXA
|
|
24770
|
-
} : void 0,
|
|
24771
|
-
shading: shadingFill ? {
|
|
24772
|
-
fill: shadingFill,
|
|
24773
|
-
type: ShadingType.CLEAR
|
|
24774
|
-
} : void 0,
|
|
24775
|
-
margins: mapPaddingToTableMargins(td.padding),
|
|
24776
|
-
borders: createTableCellBorders(
|
|
24777
|
-
td,
|
|
24778
|
-
tableContext.borderColor,
|
|
24779
|
-
tableContext.borderWidth
|
|
24780
|
-
)
|
|
24781
|
-
});
|
|
24782
|
-
}
|
|
24783
|
-
function createParagraph(children, context, defaultRowMargin) {
|
|
24784
|
-
return new Paragraph({
|
|
24785
|
-
children,
|
|
24786
|
-
heading: context.heading,
|
|
24787
|
-
numbering: context.numbering,
|
|
24788
|
-
alignment: context.alignment,
|
|
24789
|
-
spacing: {
|
|
24790
|
-
line: Math.round(
|
|
24791
|
-
240 * (context.rowMargin || defaultRowMargin || DEFAULT_LINE_HEIGHT)
|
|
24792
|
-
),
|
|
24793
|
-
lineRule: LineRuleType.AUTO
|
|
24794
|
-
}
|
|
24795
|
-
});
|
|
24796
|
-
}
|
|
24797
|
-
function createTextRun(text, element, defaultSize, defaultFont) {
|
|
24798
|
-
const color = element.color ? normalizeHexColor(element.color, "000000") : void 0;
|
|
24799
|
-
const highlightFill = element.highlight ? normalizeHexColor(element.highlight) : void 0;
|
|
24800
|
-
return new TextRun({
|
|
24801
|
-
text,
|
|
24802
|
-
bold: !!element.bold,
|
|
24803
|
-
italics: !!element.italic,
|
|
24804
|
-
strike: !!element.strikeout,
|
|
24805
|
-
subScript: element.type === "subscript" /* SUBSCRIPT */,
|
|
24806
|
-
superScript: element.type === "superscript" /* SUPERSCRIPT */,
|
|
24807
|
-
color,
|
|
24808
|
-
shading: highlightFill ? {
|
|
24809
|
-
fill: highlightFill,
|
|
24810
|
-
type: ShadingType.CLEAR
|
|
24811
|
-
} : void 0,
|
|
24812
|
-
underline: element.underline ? {
|
|
24813
|
-
type: mapUnderlineType(element.textDecoration?.style)
|
|
24814
|
-
} : void 0,
|
|
24815
|
-
font: element.font || defaultFont,
|
|
24816
|
-
size: Math.round((element.size || defaultSize) * 2)
|
|
24817
|
-
});
|
|
24818
|
-
}
|
|
24819
|
-
async function createHyperlinkChild(element, options) {
|
|
24820
|
-
if (!element.url) {
|
|
24821
|
-
const fallbackText = getTextFromElementList(element.valueList || []);
|
|
24822
|
-
return fallbackText ? createTextRun(
|
|
24823
|
-
fallbackText,
|
|
24824
|
-
element.valueList?.[0] || element,
|
|
24825
|
-
options.defaultSize,
|
|
24826
|
-
options.defaultFont
|
|
24827
|
-
) : null;
|
|
24828
|
-
}
|
|
24829
|
-
const children = await createHyperlinkRuns(
|
|
24830
|
-
element.valueList || [],
|
|
24831
|
-
options.defaultSize,
|
|
24832
|
-
options.defaultFont
|
|
24833
|
-
);
|
|
24834
|
-
if (!children.length) {
|
|
24835
|
-
return null;
|
|
24836
|
-
}
|
|
24837
|
-
return new ExternalHyperlink({
|
|
24838
|
-
link: element.url,
|
|
24839
|
-
children
|
|
24840
|
-
});
|
|
24841
|
-
}
|
|
24842
|
-
async function createHyperlinkRuns(valueList, defaultSize, defaultFont) {
|
|
24843
|
-
const children = [];
|
|
24844
|
-
for (let i = 0; i < valueList.length; i++) {
|
|
24845
|
-
const element = valueList[i];
|
|
24846
|
-
if (element.type === "tab" /* TAB */) {
|
|
24847
|
-
children.push(createTextRun(" ", element, defaultSize, defaultFont));
|
|
24848
|
-
continue;
|
|
24849
|
-
}
|
|
24850
|
-
const text = normalizeText(getInlineElementText(element)).replace(
|
|
24851
|
-
/\n/g,
|
|
24852
|
-
" "
|
|
24853
|
-
);
|
|
24854
|
-
if (text) {
|
|
24855
|
-
children.push(createTextRun(text, element, defaultSize, defaultFont));
|
|
24856
|
-
}
|
|
24857
|
-
}
|
|
24858
|
-
return children;
|
|
24859
|
-
}
|
|
24860
|
-
async function createImageChild(element) {
|
|
24861
|
-
try {
|
|
24862
|
-
const image = await loadImagePayload(element.value);
|
|
24863
|
-
const width = Math.max(1, Math.round(element.width || DEFAULT_IMAGE_WIDTH));
|
|
24864
|
-
const height = Math.max(
|
|
24865
|
-
1,
|
|
24866
|
-
Math.round(element.height || DEFAULT_IMAGE_HEIGHT)
|
|
24867
|
-
);
|
|
24868
|
-
if (image.type === "svg" && image.fallbackPng) {
|
|
24869
|
-
return new ImageRun({
|
|
24870
|
-
type: "svg",
|
|
24871
|
-
data: image.data,
|
|
24872
|
-
fallback: {
|
|
24873
|
-
type: "png",
|
|
24874
|
-
data: image.fallbackPng
|
|
24875
|
-
},
|
|
24876
|
-
transformation: {
|
|
24877
|
-
width,
|
|
24878
|
-
height
|
|
24879
|
-
}
|
|
24880
|
-
});
|
|
24881
|
-
}
|
|
24882
|
-
return new ImageRun({
|
|
24883
|
-
type: image.type,
|
|
24884
|
-
data: image.data,
|
|
24885
|
-
transformation: {
|
|
24886
|
-
width,
|
|
24887
|
-
height
|
|
24854
|
+
const text = getElementText(element);
|
|
24855
|
+
if (!text) continue;
|
|
24856
|
+
const natural = measure(ctx, text, element);
|
|
24857
|
+
const target = (x - zone.startX) / scale;
|
|
24858
|
+
const isDrift = !started || target - pen > ANCHOR_EPS;
|
|
24859
|
+
const extra = layoutWidth - natural;
|
|
24860
|
+
const needsSpacing = Math.abs(extra) * PX_TO_TWIP >= 1;
|
|
24861
|
+
const canJoin = run && !isDrift && !needsSpacing && isSameRunStyle(run.element, element);
|
|
24862
|
+
if (canJoin) {
|
|
24863
|
+
run.text += text;
|
|
24864
|
+
} else {
|
|
24865
|
+
flush();
|
|
24866
|
+
anchorTo(x);
|
|
24867
|
+
if (needsSpacing) {
|
|
24868
|
+
children.push(
|
|
24869
|
+
createTextRun(ctx, text, element, void 0, pxTw(extra))
|
|
24870
|
+
);
|
|
24871
|
+
} else {
|
|
24872
|
+
run = { text, element };
|
|
24888
24873
|
}
|
|
24889
|
-
});
|
|
24890
|
-
} catch {
|
|
24891
|
-
return null;
|
|
24892
|
-
}
|
|
24893
|
-
}
|
|
24894
|
-
async function loadImagePayload(src) {
|
|
24895
|
-
const source = src.trim();
|
|
24896
|
-
if (source.startsWith("data:")) {
|
|
24897
|
-
return getImagePayloadFromDataUrl(source);
|
|
24898
|
-
}
|
|
24899
|
-
const response = await fetch(source);
|
|
24900
|
-
if (!response.ok) {
|
|
24901
|
-
throw new Error(`Image request failed: ${response.status}`);
|
|
24902
|
-
}
|
|
24903
|
-
const contentType = response.headers.get("content-type") || "";
|
|
24904
|
-
const data2 = await response.arrayBuffer();
|
|
24905
|
-
return normalizeImagePayload(data2, contentType);
|
|
24906
|
-
}
|
|
24907
|
-
async function getImagePayloadFromDataUrl(src) {
|
|
24908
|
-
const [, meta = "", encoded = ""] = src.match(/^data:([^,]*),(.*)$/) || [];
|
|
24909
|
-
const mime = meta.split(";")[0] || "";
|
|
24910
|
-
const isBase64 = meta.includes(";base64");
|
|
24911
|
-
const text = isBase64 ? atob(encoded) : decodeURIComponent(encoded);
|
|
24912
|
-
const bytes = new Uint8Array(text.length);
|
|
24913
|
-
for (let i = 0; i < text.length; i++) {
|
|
24914
|
-
bytes[i] = text.charCodeAt(i);
|
|
24915
|
-
}
|
|
24916
|
-
return normalizeImagePayload(bytes.buffer, mime);
|
|
24917
|
-
}
|
|
24918
|
-
async function normalizeImagePayload(data2, mime) {
|
|
24919
|
-
const type = getRegularImageType(mime);
|
|
24920
|
-
if (type) {
|
|
24921
|
-
return {
|
|
24922
|
-
type,
|
|
24923
|
-
data: data2
|
|
24924
|
-
};
|
|
24925
|
-
}
|
|
24926
|
-
if (mime.includes("svg")) {
|
|
24927
|
-
return {
|
|
24928
|
-
type: "svg",
|
|
24929
|
-
data: data2,
|
|
24930
|
-
fallbackPng: await rasterizeSvgToPng(data2)
|
|
24931
|
-
};
|
|
24932
|
-
}
|
|
24933
|
-
const fallbackPng = await rasterizeImageToPng(data2, mime);
|
|
24934
|
-
return {
|
|
24935
|
-
type: "png",
|
|
24936
|
-
data: fallbackPng
|
|
24937
|
-
};
|
|
24938
|
-
}
|
|
24939
|
-
async function rasterizeSvgToPng(data2) {
|
|
24940
|
-
return rasterizeImageToPng(data2, "image/svg+xml");
|
|
24941
|
-
}
|
|
24942
|
-
async function rasterizeImageToPng(data2, mime) {
|
|
24943
|
-
const blob = new Blob([data2], {
|
|
24944
|
-
type: mime || "image/png"
|
|
24945
|
-
});
|
|
24946
|
-
const url = URL.createObjectURL(blob);
|
|
24947
|
-
try {
|
|
24948
|
-
const image = await loadHtmlImage(url);
|
|
24949
|
-
const canvas = document.createElement("canvas");
|
|
24950
|
-
canvas.width = image.naturalWidth || DEFAULT_IMAGE_WIDTH;
|
|
24951
|
-
canvas.height = image.naturalHeight || DEFAULT_IMAGE_HEIGHT;
|
|
24952
|
-
const context = canvas.getContext("2d");
|
|
24953
|
-
if (!context) {
|
|
24954
|
-
throw new Error("Canvas context is unavailable");
|
|
24955
24874
|
}
|
|
24956
|
-
|
|
24957
|
-
const pngBlob = await new Promise((resolve, reject) => {
|
|
24958
|
-
canvas.toBlob((output) => {
|
|
24959
|
-
if (output) {
|
|
24960
|
-
resolve(output);
|
|
24961
|
-
} else {
|
|
24962
|
-
reject(new Error("Failed to create PNG blob"));
|
|
24963
|
-
}
|
|
24964
|
-
}, "image/png");
|
|
24965
|
-
});
|
|
24966
|
-
return await pngBlob.arrayBuffer();
|
|
24967
|
-
} finally {
|
|
24968
|
-
URL.revokeObjectURL(url);
|
|
24875
|
+
pen = target + layoutWidth;
|
|
24969
24876
|
}
|
|
24970
|
-
|
|
24971
|
-
|
|
24972
|
-
|
|
24973
|
-
|
|
24974
|
-
image.onload = () => resolve(image);
|
|
24975
|
-
image.onerror = () => reject(new Error("Failed to load image"));
|
|
24976
|
-
image.src = src;
|
|
24977
|
-
});
|
|
24978
|
-
}
|
|
24979
|
-
function createPageNumberParagraph(pageNumber) {
|
|
24980
|
-
if (pageNumber.disabled || pageNumber.fromPageNo > 0) {
|
|
24981
|
-
return null;
|
|
24877
|
+
flush();
|
|
24878
|
+
if (!children.length && !suffix) {
|
|
24879
|
+
const total = (options.skipLead ? 0 : rowLead(ctx, row, options)) + rowLine(ctx, row).lineTw + rowSpacing(ctx, row, options).after;
|
|
24880
|
+
return createSpacerParagraph(pageBreakBefore, total / PX_TO_TWIP);
|
|
24982
24881
|
}
|
|
24983
|
-
const
|
|
24984
|
-
|
|
24985
|
-
|
|
24986
|
-
|
|
24987
|
-
const token = tokens[i];
|
|
24988
|
-
if (!token) continue;
|
|
24989
|
-
const runChildren = token === FORMAT_PLACEHOLDER.PAGE_NO ? [PageNumber2.CURRENT] : token === FORMAT_PLACEHOLDER.PAGE_COUNT ? [PageNumber2.TOTAL_PAGES] : void 0;
|
|
24990
|
-
children.push(
|
|
24991
|
-
new TextRun({
|
|
24992
|
-
text: runChildren ? void 0 : token,
|
|
24993
|
-
children: runChildren,
|
|
24994
|
-
color: normalizeHexColor(pageNumber.color || "#000000", "000000"),
|
|
24995
|
-
font: pageNumber.font,
|
|
24996
|
-
size: Math.round((pageNumber.size || 12) * 2)
|
|
24997
|
-
})
|
|
24998
|
-
);
|
|
24882
|
+
const stops = tabStops.map((position) => ({ type: TabStopType.LEFT, position }));
|
|
24883
|
+
if (suffix) {
|
|
24884
|
+
stops.push({ type: suffix.tabType, position: suffix.tabStop });
|
|
24885
|
+
children.push(new TextRun({ children: [new Tab()] }), ...suffix.children);
|
|
24999
24886
|
}
|
|
25000
24887
|
return new Paragraph({
|
|
25001
24888
|
children,
|
|
25002
|
-
|
|
24889
|
+
run: hasInlineImage(row) ? { size: IMAGE_MARK_HALF_POINTS } : void 0,
|
|
24890
|
+
style: suffix?.style,
|
|
24891
|
+
pageBreakBefore,
|
|
24892
|
+
widowControl: false,
|
|
24893
|
+
tabStops: stops,
|
|
24894
|
+
indent: { left: pxTw(indent), right: RIGHT_SLACK_TWIP },
|
|
24895
|
+
spacing: rowSpacing(ctx, row, options)
|
|
25003
24896
|
});
|
|
25004
24897
|
}
|
|
25005
|
-
|
|
25006
|
-
|
|
25007
|
-
|
|
25008
|
-
|
|
25009
|
-
|
|
25010
|
-
|
|
25011
|
-
|
|
25012
|
-
|
|
25013
|
-
|
|
25014
|
-
if (
|
|
25015
|
-
|
|
25016
|
-
forceColorValue(value[i]);
|
|
25017
|
-
}
|
|
25018
|
-
return;
|
|
25019
|
-
}
|
|
25020
|
-
const record = value;
|
|
25021
|
-
if ("color" in record) {
|
|
25022
|
-
record.color = DOCX_FOOTER_TEXT_COLOR;
|
|
25023
|
-
}
|
|
25024
|
-
const keys = Object.keys(record);
|
|
25025
|
-
for (let i = 0; i < keys.length; i++) {
|
|
25026
|
-
forceColorValue(record[keys[i]]);
|
|
25027
|
-
}
|
|
25028
|
-
}
|
|
25029
|
-
function createNumberingConfig() {
|
|
25030
|
-
const config = [
|
|
25031
|
-
createOrderedReference("windoc-ol-decimal", Array(9).fill("decimal" /* DECIMAL */)),
|
|
25032
|
-
createOrderedReference(
|
|
25033
|
-
"windoc-ol-lower-alpha",
|
|
25034
|
-
Array(9).fill("lowerAlpha" /* LOWER_ALPHA */)
|
|
25035
|
-
),
|
|
25036
|
-
createOrderedReference(
|
|
25037
|
-
"windoc-ol-upper-alpha",
|
|
25038
|
-
Array(9).fill("upperAlpha" /* UPPER_ALPHA */)
|
|
25039
|
-
),
|
|
25040
|
-
createOrderedReference(
|
|
25041
|
-
"windoc-ol-lower-roman",
|
|
25042
|
-
Array(9).fill("lowerRoman" /* LOWER_ROMAN */)
|
|
25043
|
-
),
|
|
25044
|
-
createOrderedReference(
|
|
25045
|
-
"windoc-ol-upper-roman",
|
|
25046
|
-
Array(9).fill("upperRoman" /* UPPER_ROMAN */)
|
|
25047
|
-
),
|
|
25048
|
-
createOrderedReference(
|
|
25049
|
-
"windoc-ol-decimal-paren",
|
|
25050
|
-
Array(9).fill("decimalParen" /* DECIMAL_PAREN */)
|
|
25051
|
-
),
|
|
25052
|
-
createOrderedReference(
|
|
25053
|
-
`windoc-ol-${"olDefault" /* DEFAULT */}`,
|
|
25054
|
-
createCycleList(olPresetCycles["olDefault" /* DEFAULT */], 9)
|
|
25055
|
-
),
|
|
25056
|
-
createOrderedReference(
|
|
25057
|
-
`windoc-ol-${"olParen" /* PARENTHESIS */}`,
|
|
25058
|
-
createCycleList(olPresetCycles["olParen" /* PARENTHESIS */], 9)
|
|
25059
|
-
),
|
|
25060
|
-
createOrderedReference(
|
|
25061
|
-
`windoc-ol-${"olOutline" /* OUTLINE */}`,
|
|
25062
|
-
createCycleList(olPresetCycles["olOutline" /* OUTLINE */], 9)
|
|
25063
|
-
),
|
|
25064
|
-
createOrderedReference(
|
|
25065
|
-
`windoc-ol-${"olUpperA" /* UPPER_ALPHA */}`,
|
|
25066
|
-
createCycleList(olPresetCycles["olUpperA" /* UPPER_ALPHA */], 9)
|
|
25067
|
-
),
|
|
25068
|
-
createOrderedReference(
|
|
25069
|
-
`windoc-ol-${"olRoman" /* ROMAN */}`,
|
|
25070
|
-
createCycleList(olPresetCycles["olRoman" /* ROMAN */], 9)
|
|
25071
|
-
),
|
|
25072
|
-
createOrderedReference(
|
|
25073
|
-
`windoc-ol-${"olZeroPad" /* ZERO_PAD */}`,
|
|
25074
|
-
createCycleList(olPresetCycles["olZeroPad" /* ZERO_PAD */], 9)
|
|
25075
|
-
),
|
|
25076
|
-
createBulletReference(
|
|
25077
|
-
"windoc-ul-disc",
|
|
25078
|
-
Array(9).fill(docxBulletCharMap["disc" /* DISC */])
|
|
25079
|
-
),
|
|
25080
|
-
createBulletReference(
|
|
25081
|
-
"windoc-ul-circle",
|
|
25082
|
-
Array(9).fill(docxBulletCharMap["circle" /* CIRCLE */])
|
|
25083
|
-
),
|
|
25084
|
-
createBulletReference(
|
|
25085
|
-
"windoc-ul-square",
|
|
25086
|
-
Array(9).fill(docxBulletCharMap["square" /* SQUARE */])
|
|
25087
|
-
),
|
|
25088
|
-
createBulletReference(
|
|
25089
|
-
"windoc-ul-checkbox",
|
|
25090
|
-
Array(9).fill(docxBulletCharMap["checkbox" /* CHECKBOX */])
|
|
25091
|
-
),
|
|
25092
|
-
createBulletReference(
|
|
25093
|
-
`windoc-ul-${"ulDefault" /* DEFAULT */}`,
|
|
25094
|
-
createCycleList(ulPresetCycles["ulDefault" /* DEFAULT */], 9)
|
|
25095
|
-
),
|
|
25096
|
-
createBulletReference(
|
|
25097
|
-
`windoc-ul-${"ulDiamond" /* DIAMOND */}`,
|
|
25098
|
-
createCycleList(ulPresetCycles["ulDiamond" /* DIAMOND */], 9)
|
|
25099
|
-
),
|
|
25100
|
-
createBulletReference(
|
|
25101
|
-
`windoc-ul-${"ulHollowSq" /* HOLLOW_SQ */}`,
|
|
25102
|
-
createCycleList(ulPresetCycles["ulHollowSq" /* HOLLOW_SQ */], 9)
|
|
25103
|
-
),
|
|
25104
|
-
createBulletReference(
|
|
25105
|
-
`windoc-ul-${"ulArrow" /* ARROW */}`,
|
|
25106
|
-
createCycleList(ulPresetCycles["ulArrow" /* ARROW */], 9)
|
|
25107
|
-
),
|
|
25108
|
-
createBulletReference(
|
|
25109
|
-
`windoc-ul-${"ulStar" /* STAR */}`,
|
|
25110
|
-
createCycleList(ulPresetCycles["ulStar" /* STAR */], 9)
|
|
25111
|
-
),
|
|
25112
|
-
createBulletReference(
|
|
25113
|
-
`windoc-ul-${"ulCheckArr" /* CHECK_ARROW */}`,
|
|
25114
|
-
createCycleList(ulPresetCycles["ulCheckArr" /* CHECK_ARROW */], 9)
|
|
25115
|
-
)
|
|
25116
|
-
];
|
|
25117
|
-
return config;
|
|
25118
|
-
}
|
|
25119
|
-
function createOrderedReference(reference, styles) {
|
|
25120
|
-
return {
|
|
25121
|
-
reference,
|
|
25122
|
-
levels: styles.map((style, level) => ({
|
|
25123
|
-
level,
|
|
25124
|
-
format: orderedStyleFormatMap[style] || LevelFormat.DECIMAL,
|
|
25125
|
-
text: getOrderedLevelText(style, level),
|
|
25126
|
-
alignment: AlignmentType.START,
|
|
25127
|
-
style: {
|
|
25128
|
-
paragraph: {
|
|
25129
|
-
indent: {
|
|
25130
|
-
left: 720 * (level + 1),
|
|
25131
|
-
hanging: 360
|
|
25132
|
-
}
|
|
25133
|
-
}
|
|
25134
|
-
}
|
|
25135
|
-
}))
|
|
25136
|
-
};
|
|
25137
|
-
}
|
|
25138
|
-
function createBulletReference(reference, bullets) {
|
|
25139
|
-
return {
|
|
25140
|
-
reference,
|
|
25141
|
-
levels: bullets.map((bullet, level) => ({
|
|
25142
|
-
level,
|
|
25143
|
-
format: LevelFormat.BULLET,
|
|
25144
|
-
text: bullet,
|
|
25145
|
-
alignment: AlignmentType.START,
|
|
25146
|
-
style: {
|
|
25147
|
-
paragraph: {
|
|
25148
|
-
indent: {
|
|
25149
|
-
left: 720 * (level + 1),
|
|
25150
|
-
hanging: 360
|
|
25151
|
-
}
|
|
25152
|
-
}
|
|
25153
|
-
}
|
|
25154
|
-
}))
|
|
25155
|
-
};
|
|
25156
|
-
}
|
|
25157
|
-
function getOrderedLevelText(style, level) {
|
|
25158
|
-
const placeholder = `%${level + 1}`;
|
|
25159
|
-
if (style === "outline") {
|
|
25160
|
-
return Array.from({ length: level + 1 }, (_, index) => `%${index + 1}`).join(
|
|
25161
|
-
"."
|
|
25162
|
-
) + ".";
|
|
25163
|
-
}
|
|
25164
|
-
if (style.endsWith("Paren") || style === "decimalParen" /* DECIMAL_PAREN */) {
|
|
25165
|
-
return `${placeholder})`;
|
|
25166
|
-
}
|
|
25167
|
-
return `${placeholder}.`;
|
|
25168
|
-
}
|
|
25169
|
-
function createCycleList(source = [], size) {
|
|
25170
|
-
const result = [];
|
|
25171
|
-
for (let i = 0; i < size; i++) {
|
|
25172
|
-
result.push(source[i % source.length]);
|
|
25173
|
-
}
|
|
25174
|
-
return result;
|
|
25175
|
-
}
|
|
25176
|
-
function getListNumbering(element, instance) {
|
|
25177
|
-
const level = Math.max(0, Math.min(element.listLevel || 0, 8));
|
|
25178
|
-
if (element.listType === "ul" /* UL */) {
|
|
25179
|
-
const reference2 = element.listPreset ? `windoc-ul-${element.listPreset}` : `windoc-ul-${element.listStyle || "disc" /* DISC */}`;
|
|
24898
|
+
var EXACT_BASELINE_RATIO = 0.8;
|
|
24899
|
+
var IMAGE_MARK_HALF_POINTS = 2;
|
|
24900
|
+
var IMAGE_MARK_DESCENT_PX = 0.3;
|
|
24901
|
+
function hasInlineImage(row) {
|
|
24902
|
+
return row.elementList.some((el) => el.type === "image" /* IMAGE */);
|
|
24903
|
+
}
|
|
24904
|
+
function rowLine(ctx, row, baseline = row.ascent / ctx.scale) {
|
|
24905
|
+
const { scale } = ctx;
|
|
24906
|
+
const height = row.height / scale;
|
|
24907
|
+
if (hasInlineImage(row)) {
|
|
24908
|
+
const lineTw2 = pxTw(Math.min(baseline, height) + IMAGE_MARK_DESCENT_PX);
|
|
25180
24909
|
return {
|
|
25181
|
-
|
|
25182
|
-
|
|
25183
|
-
|
|
24910
|
+
lineTw: lineTw2,
|
|
24911
|
+
beforeTw: 0,
|
|
24912
|
+
afterTw: Math.max(0, pxTw(height) - lineTw2),
|
|
24913
|
+
atLeast: true
|
|
25184
24914
|
};
|
|
25185
24915
|
}
|
|
25186
|
-
const
|
|
25187
|
-
|
|
25188
|
-
|
|
25189
|
-
|
|
25190
|
-
instance
|
|
25191
|
-
};
|
|
25192
|
-
}
|
|
25193
|
-
function getOrderedReferenceFromStyle(style) {
|
|
25194
|
-
switch (style) {
|
|
25195
|
-
case "lowerAlpha" /* LOWER_ALPHA */:
|
|
25196
|
-
return "windoc-ol-lower-alpha";
|
|
25197
|
-
case "upperAlpha" /* UPPER_ALPHA */:
|
|
25198
|
-
return "windoc-ol-upper-alpha";
|
|
25199
|
-
case "lowerRoman" /* LOWER_ROMAN */:
|
|
25200
|
-
return "windoc-ol-lower-roman";
|
|
25201
|
-
case "upperRoman" /* UPPER_ROMAN */:
|
|
25202
|
-
return "windoc-ol-upper-roman";
|
|
25203
|
-
case "decimalParen" /* DECIMAL_PAREN */:
|
|
25204
|
-
return "windoc-ol-decimal-paren";
|
|
25205
|
-
default:
|
|
25206
|
-
return "windoc-ol-decimal";
|
|
25207
|
-
}
|
|
25208
|
-
}
|
|
25209
|
-
function createTableBorders(element) {
|
|
25210
|
-
const outerBorder = createBorder(
|
|
25211
|
-
element.borderColor,
|
|
25212
|
-
BorderStyle.SINGLE,
|
|
25213
|
-
element.borderExternalWidth || element.borderWidth
|
|
24916
|
+
const ascent = Math.min(baseline, height);
|
|
24917
|
+
const line = Math.min(
|
|
24918
|
+
ascent / EXACT_BASELINE_RATIO,
|
|
24919
|
+
(height - ascent) / (1 - EXACT_BASELINE_RATIO)
|
|
25214
24920
|
);
|
|
25215
|
-
const
|
|
25216
|
-
|
|
25217
|
-
|
|
25218
|
-
|
|
24921
|
+
const lineTw = Math.max(TINY_TWIP, pxTw(line));
|
|
24922
|
+
const beforeTw = Math.max(
|
|
24923
|
+
0,
|
|
24924
|
+
pxTw(ascent) - Math.round(lineTw * EXACT_BASELINE_RATIO)
|
|
25219
24925
|
);
|
|
25220
|
-
|
|
25221
|
-
|
|
25222
|
-
return {
|
|
25223
|
-
top: noneBorder(),
|
|
25224
|
-
bottom: noneBorder(),
|
|
25225
|
-
left: noneBorder(),
|
|
25226
|
-
right: noneBorder(),
|
|
25227
|
-
insideHorizontal: noneBorder(),
|
|
25228
|
-
insideVertical: noneBorder()
|
|
25229
|
-
};
|
|
25230
|
-
case "external" /* EXTERNAL */:
|
|
25231
|
-
return {
|
|
25232
|
-
top: outerBorder,
|
|
25233
|
-
bottom: outerBorder,
|
|
25234
|
-
left: outerBorder,
|
|
25235
|
-
right: outerBorder,
|
|
25236
|
-
insideHorizontal: noneBorder(),
|
|
25237
|
-
insideVertical: noneBorder()
|
|
25238
|
-
};
|
|
25239
|
-
case "internal" /* INTERNAL */:
|
|
25240
|
-
return {
|
|
25241
|
-
top: noneBorder(),
|
|
25242
|
-
bottom: noneBorder(),
|
|
25243
|
-
left: noneBorder(),
|
|
25244
|
-
right: noneBorder(),
|
|
25245
|
-
insideHorizontal: innerBorder,
|
|
25246
|
-
insideVertical: innerBorder
|
|
25247
|
-
};
|
|
25248
|
-
case "dash" /* DASH */:
|
|
25249
|
-
return {
|
|
25250
|
-
top: createBorder(
|
|
25251
|
-
element.borderColor,
|
|
25252
|
-
BorderStyle.DASHED,
|
|
25253
|
-
element.borderExternalWidth || element.borderWidth
|
|
25254
|
-
),
|
|
25255
|
-
bottom: createBorder(
|
|
25256
|
-
element.borderColor,
|
|
25257
|
-
BorderStyle.DASHED,
|
|
25258
|
-
element.borderExternalWidth || element.borderWidth
|
|
25259
|
-
),
|
|
25260
|
-
left: createBorder(
|
|
25261
|
-
element.borderColor,
|
|
25262
|
-
BorderStyle.DASHED,
|
|
25263
|
-
element.borderExternalWidth || element.borderWidth
|
|
25264
|
-
),
|
|
25265
|
-
right: createBorder(
|
|
25266
|
-
element.borderColor,
|
|
25267
|
-
BorderStyle.DASHED,
|
|
25268
|
-
element.borderExternalWidth || element.borderWidth
|
|
25269
|
-
),
|
|
25270
|
-
insideHorizontal: createBorder(
|
|
25271
|
-
element.borderColor,
|
|
25272
|
-
BorderStyle.DASHED,
|
|
25273
|
-
element.borderWidth
|
|
25274
|
-
),
|
|
25275
|
-
insideVertical: createBorder(
|
|
25276
|
-
element.borderColor,
|
|
25277
|
-
BorderStyle.DASHED,
|
|
25278
|
-
element.borderWidth
|
|
25279
|
-
)
|
|
25280
|
-
};
|
|
25281
|
-
default:
|
|
25282
|
-
return {
|
|
25283
|
-
top: outerBorder,
|
|
25284
|
-
bottom: outerBorder,
|
|
25285
|
-
left: outerBorder,
|
|
25286
|
-
right: outerBorder,
|
|
25287
|
-
insideHorizontal: innerBorder,
|
|
25288
|
-
insideVertical: innerBorder
|
|
25289
|
-
};
|
|
25290
|
-
}
|
|
25291
|
-
}
|
|
25292
|
-
function createTableCellBorders(td, inheritedColor, inheritedWidth) {
|
|
25293
|
-
if (!td.borderTypes?.length && !td.borderColor) {
|
|
25294
|
-
return void 0;
|
|
25295
|
-
}
|
|
25296
|
-
const color = td.borderColor || inheritedColor;
|
|
25297
|
-
const createCellBorder = () => createBorder(color, BorderStyle.SINGLE, inheritedWidth);
|
|
25298
|
-
if (td.borderColor && !td.borderTypes?.length) {
|
|
25299
|
-
return {
|
|
25300
|
-
top: createCellBorder(),
|
|
25301
|
-
right: createCellBorder(),
|
|
25302
|
-
bottom: createCellBorder(),
|
|
25303
|
-
left: createCellBorder()
|
|
25304
|
-
};
|
|
25305
|
-
}
|
|
25306
|
-
const top = td.borderTypes?.includes("top" /* TOP */) ? createCellBorder() : noneBorder();
|
|
25307
|
-
const right2 = td.borderTypes?.includes("right" /* RIGHT */) ? createCellBorder() : noneBorder();
|
|
25308
|
-
const bottom = td.borderTypes?.includes("bottom" /* BOTTOM */) ? createCellBorder() : noneBorder();
|
|
25309
|
-
const left2 = td.borderTypes?.includes("left" /* LEFT */) ? createCellBorder() : noneBorder();
|
|
25310
|
-
return {
|
|
25311
|
-
top,
|
|
25312
|
-
right: right2,
|
|
25313
|
-
bottom,
|
|
25314
|
-
left: left2
|
|
25315
|
-
};
|
|
25316
|
-
}
|
|
25317
|
-
function createBorder(color = "#000000", style = BorderStyle.SINGLE, width = 1) {
|
|
25318
|
-
return {
|
|
25319
|
-
style,
|
|
25320
|
-
color: normalizeHexColor(color, "000000") || "000000",
|
|
25321
|
-
size: pxBorderToDocxSize(width)
|
|
25322
|
-
};
|
|
25323
|
-
}
|
|
25324
|
-
function noneBorder() {
|
|
25325
|
-
return {
|
|
25326
|
-
style: BorderStyle.NONE,
|
|
25327
|
-
size: 0,
|
|
25328
|
-
color: "FFFFFF"
|
|
25329
|
-
};
|
|
25330
|
-
}
|
|
25331
|
-
function mapPaddingToTableMargins(padding) {
|
|
25332
|
-
if (!padding) return void 0;
|
|
25333
|
-
return {
|
|
25334
|
-
top: pxToTwips(padding[0]),
|
|
25335
|
-
right: pxToTwips(padding[1]),
|
|
25336
|
-
bottom: pxToTwips(padding[2]),
|
|
25337
|
-
left: pxToTwips(padding[3]),
|
|
25338
|
-
marginUnitType: WidthType.DXA
|
|
25339
|
-
};
|
|
25340
|
-
}
|
|
25341
|
-
function mapCellVerticalAlign(verticalAlign) {
|
|
25342
|
-
switch (verticalAlign) {
|
|
25343
|
-
case VerticalAlign.CENTER:
|
|
25344
|
-
return DocxVerticalAlign.CENTER;
|
|
25345
|
-
case "bottom" /* BOTTOM */:
|
|
25346
|
-
return DocxVerticalAlign.BOTTOM;
|
|
25347
|
-
default:
|
|
25348
|
-
return DocxVerticalAlign.TOP;
|
|
25349
|
-
}
|
|
25350
|
-
}
|
|
25351
|
-
function mapRowFlexToAlignment(rowFlex) {
|
|
25352
|
-
switch (rowFlex) {
|
|
25353
|
-
case "center" /* CENTER */:
|
|
25354
|
-
return AlignmentType.CENTER;
|
|
25355
|
-
case "right" /* RIGHT */:
|
|
25356
|
-
return AlignmentType.RIGHT;
|
|
25357
|
-
case "alignment" /* ALIGNMENT */:
|
|
25358
|
-
case "justify" /* JUSTIFY */:
|
|
25359
|
-
return AlignmentType.JUSTIFIED;
|
|
25360
|
-
default:
|
|
25361
|
-
return AlignmentType.LEFT;
|
|
25362
|
-
}
|
|
25363
|
-
}
|
|
25364
|
-
function mapUnderlineType(style) {
|
|
25365
|
-
switch (style) {
|
|
25366
|
-
case "double" /* DOUBLE */:
|
|
25367
|
-
return UnderlineType.DOUBLE;
|
|
25368
|
-
case "dashed" /* DASHED */:
|
|
25369
|
-
return UnderlineType.DASH;
|
|
25370
|
-
case "dotted" /* DOTTED */:
|
|
25371
|
-
return UnderlineType.DOTTED;
|
|
25372
|
-
case "wavy" /* WAVY */:
|
|
25373
|
-
return UnderlineType.WAVE;
|
|
25374
|
-
default:
|
|
25375
|
-
return UnderlineType.SINGLE;
|
|
25376
|
-
}
|
|
25377
|
-
}
|
|
25378
|
-
function getInlineElementText(element) {
|
|
25379
|
-
switch (element.type) {
|
|
25380
|
-
case "control" /* CONTROL */:
|
|
25381
|
-
return getControlText(element.control);
|
|
25382
|
-
case "date" /* DATE */:
|
|
25383
|
-
return element.valueList?.length ? getTextFromElementList(element.valueList) : element.value;
|
|
25384
|
-
case "checkbox" /* CHECKBOX */:
|
|
25385
|
-
return element.checkbox?.value ? "\u2611" : "\u2610";
|
|
25386
|
-
case "radio" /* RADIO */:
|
|
25387
|
-
return element.radio?.value ? "\u25C9" : "\u25CB";
|
|
25388
|
-
case "label" /* LABEL */:
|
|
25389
|
-
case "latex" /* LATEX */:
|
|
25390
|
-
case "subscript" /* SUBSCRIPT */:
|
|
25391
|
-
case "superscript" /* SUPERSCRIPT */:
|
|
25392
|
-
return element.value;
|
|
25393
|
-
default:
|
|
25394
|
-
return element.value;
|
|
25395
|
-
}
|
|
25396
|
-
}
|
|
25397
|
-
function getControlText(control) {
|
|
25398
|
-
if (!control) return "";
|
|
25399
|
-
if (control.type === "text" /* TEXT */ || control.type === "date" /* DATE */ || control.type === "number" /* NUMBER */) {
|
|
25400
|
-
const value = control.value?.length ? getTextFromElementList(control.value) : "";
|
|
25401
|
-
const content = value || control.placeholder || "";
|
|
25402
|
-
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
25403
|
-
}
|
|
25404
|
-
if (control.type === "select" /* SELECT */) {
|
|
25405
|
-
const labels = getSelectedControlLabels(control.code, control.valueSets);
|
|
25406
|
-
const content = labels.length ? labels.join(control.multiSelectDelimiter || ", ") : control.placeholder || "";
|
|
25407
|
-
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
25408
|
-
}
|
|
25409
|
-
if (control.type === "checkbox" /* CHECKBOX */ || control.type === "radio" /* RADIO */) {
|
|
25410
|
-
const isRadio = control.type === "radio" /* RADIO */;
|
|
25411
|
-
return (control.valueSets || []).map((valueSet) => {
|
|
25412
|
-
const checked = control.code?.split(",").includes(valueSet.code) || false;
|
|
25413
|
-
return `${checked ? isRadio ? "\u25C9" : "\u2611" : isRadio ? "\u25CB" : "\u2610"} ${valueSet.value}`;
|
|
25414
|
-
}).join(" ");
|
|
25415
|
-
}
|
|
25416
|
-
return "";
|
|
25417
|
-
}
|
|
25418
|
-
function getSelectedControlLabels(code, valueSets) {
|
|
25419
|
-
if (!code || !valueSets?.length) return [];
|
|
25420
|
-
return code.split(",").map(
|
|
25421
|
-
(selectCode) => valueSets.find((valueSet) => valueSet.code === selectCode)?.value
|
|
25422
|
-
).filter((value) => !!value);
|
|
25423
|
-
}
|
|
25424
|
-
function getBlockFallbackText(element) {
|
|
25425
|
-
if (element.block?.iframeBlock?.src) {
|
|
25426
|
-
return element.block.iframeBlock.src;
|
|
25427
|
-
}
|
|
25428
|
-
if (element.block?.videoBlock?.src) {
|
|
25429
|
-
return element.block.videoBlock.src;
|
|
25430
|
-
}
|
|
25431
|
-
return "";
|
|
25432
|
-
}
|
|
25433
|
-
function normalizeText(text = "") {
|
|
25434
|
-
return text.replace(new RegExp(ZERO, "g"), "").replace(/\r\n/g, "\n");
|
|
24926
|
+
const afterTw = Math.max(0, pxTw(height) - lineTw - beforeTw);
|
|
24927
|
+
return { lineTw, beforeTw, afterTw, atLeast: false };
|
|
25435
24928
|
}
|
|
25436
|
-
function
|
|
24929
|
+
function rowLead(ctx, row, options) {
|
|
24930
|
+
const separator = row.elementList.find(
|
|
24931
|
+
(el) => el.type === "separator" /* SEPARATOR */
|
|
24932
|
+
);
|
|
24933
|
+
const baseline = separator && options.rowY !== void 0 ? separatorBaseline(
|
|
24934
|
+
ctx,
|
|
24935
|
+
row,
|
|
24936
|
+
options.rowY,
|
|
24937
|
+
separator.lineWidth || ctx.draw.getOptions().separator.lineWidth
|
|
24938
|
+
) : void 0;
|
|
24939
|
+
return rowLine(ctx, row, baseline).beforeTw + tw(ctx, (row.offsetY || 0) + (row.spaceAbove || 0)) + pxTw(options.padTop || 0);
|
|
24940
|
+
}
|
|
24941
|
+
function rowSpacing(ctx, row, options) {
|
|
24942
|
+
const { lineTw, afterTw, atLeast } = rowLine(ctx, row);
|
|
25437
24943
|
return {
|
|
25438
|
-
|
|
24944
|
+
before: options.skipLead ? 0 : rowLead(ctx, row, options),
|
|
24945
|
+
after: afterTw + tw(ctx, row.spaceBelow || 0) + pxTw(options.padBottom || 0) + (options.extraAfter || 0),
|
|
24946
|
+
line: lineTw,
|
|
24947
|
+
lineRule: atLeast ? LineRuleType.AT_LEAST : LineRuleType.EXACT
|
|
25439
24948
|
};
|
|
25440
24949
|
}
|
|
25441
|
-
function
|
|
25442
|
-
|
|
25443
|
-
|
|
25444
|
-
|
|
25445
|
-
|
|
25446
|
-
|
|
25447
|
-
|
|
24950
|
+
function createSeparatorParagraph(ctx, row, element, x, rowY2, zone, options) {
|
|
24951
|
+
const { scale } = ctx;
|
|
24952
|
+
const opts = ctx.draw.getOptions();
|
|
24953
|
+
const lineWidth = element.lineWidth || opts.separator.lineWidth;
|
|
24954
|
+
const sideGap = 4;
|
|
24955
|
+
const left2 = (x - zone.startX) / scale + sideGap;
|
|
24956
|
+
const width = Math.max(1, (element.width || 0) - sideGap * 2);
|
|
24957
|
+
const color = element.color || opts.separator.strokeStyle;
|
|
24958
|
+
const line = rowLine(ctx, row, separatorBaseline(ctx, row, rowY2, lineWidth));
|
|
24959
|
+
return new Paragraph({
|
|
24960
|
+
pageBreakBefore: options.pageBreakBefore,
|
|
24961
|
+
widowControl: false,
|
|
24962
|
+
indent: { left: pxTw(left2), right: RIGHT_SLACK_TWIP },
|
|
24963
|
+
children: [
|
|
24964
|
+
new ImageRun({
|
|
24965
|
+
type: "png",
|
|
24966
|
+
data: createLineImage(width, lineWidth, color, element.dashArray),
|
|
24967
|
+
transformation: { width, height: lineWidth }
|
|
24968
|
+
})
|
|
24969
|
+
],
|
|
24970
|
+
spacing: {
|
|
24971
|
+
before: options.skipLead ? 0 : rowLead(ctx, row, options),
|
|
24972
|
+
after: line.afterTw + tw(ctx, row.spaceBelow || 0) + pxTw(options.padBottom || 0) + (options.extraAfter || 0),
|
|
24973
|
+
line: line.lineTw,
|
|
24974
|
+
lineRule: LineRuleType.EXACT
|
|
24975
|
+
}
|
|
24976
|
+
});
|
|
25448
24977
|
}
|
|
25449
|
-
function
|
|
25450
|
-
return
|
|
25451
|
-
cellLayoutMap: computeTableCellLayout(
|
|
25452
|
-
element.trList || [],
|
|
25453
|
-
element.colgroup || []
|
|
25454
|
-
),
|
|
25455
|
-
borderColor: element.borderColor,
|
|
25456
|
-
borderWidth: element.borderWidth,
|
|
25457
|
-
borderExternalWidth: element.borderExternalWidth
|
|
25458
|
-
};
|
|
24978
|
+
function separatorBaseline(ctx, row, rowY2, lineWidth) {
|
|
24979
|
+
return (Math.round(rowY2 + row.ascent) - rowY2) / ctx.scale + lineWidth;
|
|
25459
24980
|
}
|
|
25460
|
-
function
|
|
25461
|
-
const
|
|
25462
|
-
|
|
25463
|
-
|
|
24981
|
+
function createLineImage(width, height, color, dashArray) {
|
|
24982
|
+
const ratio = 4;
|
|
24983
|
+
const canvas = document.createElement("canvas");
|
|
24984
|
+
canvas.width = Math.max(1, Math.round(width * ratio));
|
|
24985
|
+
canvas.height = Math.max(1, Math.round(height * ratio));
|
|
24986
|
+
const ctx = canvas.getContext("2d");
|
|
24987
|
+
ctx.strokeStyle = color;
|
|
24988
|
+
ctx.lineWidth = canvas.height;
|
|
24989
|
+
if (dashArray?.length) ctx.setLineDash(dashArray.map((v) => v * ratio));
|
|
24990
|
+
ctx.beginPath();
|
|
24991
|
+
ctx.moveTo(0, canvas.height / 2);
|
|
24992
|
+
ctx.lineTo(canvas.width, canvas.height / 2);
|
|
24993
|
+
ctx.stroke();
|
|
24994
|
+
const binary = atob(canvas.toDataURL("image/png").split(",")[1]);
|
|
24995
|
+
const bytes = new Uint8Array(binary.length);
|
|
24996
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
24997
|
+
return bytes;
|
|
24998
|
+
}
|
|
24999
|
+
function endWithParagraph(children) {
|
|
25000
|
+
if (children[children.length - 1] instanceof Table) {
|
|
25001
|
+
children.push(createSpacerParagraph(false));
|
|
25464
25002
|
}
|
|
25465
|
-
|
|
25466
|
-
|
|
25467
|
-
|
|
25468
|
-
|
|
25469
|
-
|
|
25470
|
-
|
|
25471
|
-
|
|
25472
|
-
|
|
25473
|
-
|
|
25474
|
-
|
|
25475
|
-
|
|
25476
|
-
|
|
25477
|
-
occupiedUntilRow[currentCol] = Math.max(
|
|
25478
|
-
occupiedUntilRow[currentCol],
|
|
25479
|
-
rowIndex + td.rowspan
|
|
25480
|
-
);
|
|
25481
|
-
}
|
|
25482
|
-
cellLayoutMap.set(td, { width });
|
|
25483
|
-
colIndex += td.colspan;
|
|
25003
|
+
return children;
|
|
25004
|
+
}
|
|
25005
|
+
function createSpacerParagraph(pageBreakBefore, height = 0) {
|
|
25006
|
+
return new Paragraph({
|
|
25007
|
+
pageBreakBefore,
|
|
25008
|
+
widowControl: false,
|
|
25009
|
+
children: [new TextRun({ text: "", size: 2 })],
|
|
25010
|
+
spacing: {
|
|
25011
|
+
before: 0,
|
|
25012
|
+
after: 0,
|
|
25013
|
+
line: Math.max(TINY_TWIP, pxTw(height)),
|
|
25014
|
+
lineRule: LineRuleType.EXACT
|
|
25484
25015
|
}
|
|
25485
|
-
}
|
|
25486
|
-
return cellLayoutMap;
|
|
25016
|
+
});
|
|
25487
25017
|
}
|
|
25488
|
-
function
|
|
25489
|
-
|
|
25490
|
-
|
|
25018
|
+
async function serializeTable(ctx, element, position, zone) {
|
|
25019
|
+
const { draw, scale } = ctx;
|
|
25020
|
+
const opts = draw.getOptions();
|
|
25021
|
+
const tableX = position.coordinate.leftTop[0];
|
|
25022
|
+
const trList = element.trList || [];
|
|
25023
|
+
const colgroup = element.colgroup || [];
|
|
25024
|
+
const rows = [];
|
|
25025
|
+
for (let t = 0; t < trList.length; t++) {
|
|
25026
|
+
const tr = trList[t];
|
|
25027
|
+
const cells = [];
|
|
25028
|
+
let rowTopBorder = 0;
|
|
25029
|
+
for (let d = 0; d < tr.tdList.length; d++) {
|
|
25030
|
+
const td = tr.tdList[d];
|
|
25031
|
+
const padding = td.padding || opts.table.tdPadding;
|
|
25032
|
+
const borders = createCellBorders(ctx, element, td);
|
|
25033
|
+
const topBorder = t === 0 ? borderPx(borders.top) : 0;
|
|
25034
|
+
rowTopBorder = Math.max(rowTopBorder, topBorder);
|
|
25035
|
+
const cellChildren = await serializeRows(
|
|
25036
|
+
ctx,
|
|
25037
|
+
td.rowList || [],
|
|
25038
|
+
{
|
|
25039
|
+
startX: (td.x + padding[3]) * scale + tableX,
|
|
25040
|
+
width: (td.width - padding[1] - padding[3]) * scale,
|
|
25041
|
+
positionList: td.positionList || []
|
|
25042
|
+
},
|
|
25043
|
+
{ padTop: Math.max(0, padding[0] - topBorder), padBottom: padding[2] }
|
|
25044
|
+
);
|
|
25045
|
+
cells.push(
|
|
25046
|
+
new TableCell({
|
|
25047
|
+
children: cellChildren.length ? endWithParagraph(cellChildren) : [createSpacerParagraph(false)],
|
|
25048
|
+
columnSpan: td.colspan > 1 ? td.colspan : void 0,
|
|
25049
|
+
rowSpan: td.rowspan > 1 ? td.rowspan : void 0,
|
|
25050
|
+
width: { size: pxTw(td.width), type: WidthType.DXA },
|
|
25051
|
+
verticalAlign: mapVerticalAlign(td.verticalAlign),
|
|
25052
|
+
margins: {
|
|
25053
|
+
top: 0,
|
|
25054
|
+
right: pxTw(padding[1]),
|
|
25055
|
+
bottom: 0,
|
|
25056
|
+
left: pxTw(Math.max(0, padding[3] - borderPx(borders.left) / 2)),
|
|
25057
|
+
marginUnitType: WidthType.DXA
|
|
25058
|
+
},
|
|
25059
|
+
shading: td.backgroundColor ? {
|
|
25060
|
+
fill: normalizeHexColor(td.backgroundColor, "FFFFFF"),
|
|
25061
|
+
type: ShadingType.CLEAR,
|
|
25062
|
+
color: "auto"
|
|
25063
|
+
} : void 0,
|
|
25064
|
+
borders
|
|
25065
|
+
})
|
|
25066
|
+
);
|
|
25067
|
+
}
|
|
25068
|
+
rows.push(
|
|
25069
|
+
new TableRow({
|
|
25070
|
+
children: cells,
|
|
25071
|
+
cantSplit: true,
|
|
25072
|
+
height: {
|
|
25073
|
+
value: pxTw(tr.height - rowTopBorder),
|
|
25074
|
+
rule: HeightRule.EXACT
|
|
25075
|
+
}
|
|
25076
|
+
})
|
|
25077
|
+
);
|
|
25491
25078
|
}
|
|
25492
|
-
return
|
|
25079
|
+
return new Table({
|
|
25080
|
+
rows,
|
|
25081
|
+
layout: TableLayoutType.FIXED,
|
|
25082
|
+
width: { size: pxTw(element.width), type: WidthType.DXA },
|
|
25083
|
+
columnWidths: colgroup.map((col) => pxTw(col.width)),
|
|
25084
|
+
indent: { size: tw(ctx, tableX - zone.startX), type: WidthType.DXA },
|
|
25085
|
+
borders: noTableBorders()
|
|
25086
|
+
});
|
|
25493
25087
|
}
|
|
25494
|
-
function
|
|
25495
|
-
const
|
|
25496
|
-
|
|
25497
|
-
|
|
25498
|
-
|
|
25499
|
-
|
|
25088
|
+
function createCellBorders(ctx, table, td) {
|
|
25089
|
+
const opts = ctx.draw.getOptions();
|
|
25090
|
+
const color = normalizeHexColor(
|
|
25091
|
+
td.borderColor || table.borderColor || opts.table.defaultBorderColor,
|
|
25092
|
+
"000000"
|
|
25093
|
+
);
|
|
25094
|
+
const width = table.borderWidth || 1;
|
|
25095
|
+
const externalWidth = table.borderExternalWidth || width;
|
|
25096
|
+
const isDash = table.borderType === "dash" /* DASH */;
|
|
25097
|
+
const line = (w) => ({
|
|
25098
|
+
style: isDash ? BorderStyle.DASHED : BorderStyle.SINGLE,
|
|
25099
|
+
size: Math.max(2, Math.round(w * 6)),
|
|
25100
|
+
color
|
|
25101
|
+
});
|
|
25102
|
+
const none = { style: BorderStyle.NONE, size: 0, color: "auto" };
|
|
25103
|
+
const isTop = td.rowIndex === 0;
|
|
25104
|
+
const isLeft = td.colIndex === 0;
|
|
25105
|
+
const isBottom = td.rowIndex + td.rowspan === table.trList.length;
|
|
25106
|
+
const isRight = td.colIndex + td.colspan === table.colgroup.length;
|
|
25107
|
+
const edge = (outer) => outer ? line(externalWidth) : line(width);
|
|
25108
|
+
let top = none;
|
|
25109
|
+
let right2 = none;
|
|
25110
|
+
let bottom = none;
|
|
25111
|
+
let left2 = none;
|
|
25112
|
+
switch (table.borderType) {
|
|
25113
|
+
case "empty" /* EMPTY */:
|
|
25114
|
+
break;
|
|
25115
|
+
case "external" /* EXTERNAL */:
|
|
25116
|
+
if (isTop) top = edge(true);
|
|
25117
|
+
if (isBottom) bottom = edge(true);
|
|
25118
|
+
if (isLeft) left2 = edge(true);
|
|
25119
|
+
if (isRight) right2 = edge(true);
|
|
25120
|
+
break;
|
|
25121
|
+
case "internal" /* INTERNAL */:
|
|
25122
|
+
if (!isTop) top = edge(false);
|
|
25123
|
+
if (!isBottom) bottom = edge(false);
|
|
25124
|
+
if (!isLeft) left2 = edge(false);
|
|
25125
|
+
if (!isRight) right2 = edge(false);
|
|
25126
|
+
break;
|
|
25127
|
+
default:
|
|
25128
|
+
top = edge(isTop);
|
|
25129
|
+
bottom = edge(isBottom);
|
|
25130
|
+
left2 = edge(isLeft);
|
|
25131
|
+
right2 = edge(isRight);
|
|
25132
|
+
}
|
|
25133
|
+
if (td.borderTypes?.includes("top" /* TOP */)) top = line(width);
|
|
25134
|
+
if (td.borderTypes?.includes("right" /* RIGHT */)) right2 = line(width);
|
|
25135
|
+
if (td.borderTypes?.includes("bottom" /* BOTTOM */)) bottom = line(width);
|
|
25136
|
+
if (td.borderTypes?.includes("left" /* LEFT */)) left2 = line(width);
|
|
25137
|
+
return { top, right: right2, bottom, left: left2 };
|
|
25138
|
+
}
|
|
25139
|
+
function borderPx(border) {
|
|
25140
|
+
return border.style === BorderStyle.NONE ? 0 : border.size / 8 * (4 / 3);
|
|
25141
|
+
}
|
|
25142
|
+
function noTableBorders() {
|
|
25143
|
+
const none = { style: BorderStyle.NONE, size: 0, color: "auto" };
|
|
25144
|
+
return {
|
|
25145
|
+
top: none,
|
|
25146
|
+
bottom: none,
|
|
25147
|
+
left: none,
|
|
25148
|
+
right: none,
|
|
25149
|
+
insideHorizontal: none,
|
|
25150
|
+
insideVertical: none
|
|
25151
|
+
};
|
|
25500
25152
|
}
|
|
25501
|
-
function
|
|
25502
|
-
|
|
25503
|
-
|
|
25504
|
-
|
|
25505
|
-
|
|
25506
|
-
|
|
25507
|
-
|
|
25153
|
+
function mapVerticalAlign(verticalAlign) {
|
|
25154
|
+
switch (verticalAlign) {
|
|
25155
|
+
case "middle" /* MIDDLE */:
|
|
25156
|
+
return DocxVerticalAlign.CENTER;
|
|
25157
|
+
case "bottom" /* BOTTOM */:
|
|
25158
|
+
return DocxVerticalAlign.BOTTOM;
|
|
25159
|
+
default:
|
|
25160
|
+
return DocxVerticalAlign.TOP;
|
|
25508
25161
|
}
|
|
25509
|
-
|
|
25510
|
-
|
|
25162
|
+
}
|
|
25163
|
+
async function serializeFooter(ctx, pageWidth, pageHeight, margins) {
|
|
25164
|
+
const { draw, scale } = ctx;
|
|
25165
|
+
const footer = draw.getFooter();
|
|
25166
|
+
const opts = draw.getOptions();
|
|
25167
|
+
const barHeight = footer.getHeight() / scale;
|
|
25168
|
+
const contentHeight = footer.getRowHeight() / scale;
|
|
25169
|
+
const paddingTop = Math.floor(Math.max(0, (barHeight - contentHeight) / 2) * scale) / scale;
|
|
25170
|
+
const zone = {
|
|
25171
|
+
startX: draw.getMargins()[3],
|
|
25172
|
+
width: draw.getInnerWidth(),
|
|
25173
|
+
positionList: footer.getPositionList()
|
|
25174
|
+
};
|
|
25175
|
+
const rowList = footer.getRowList();
|
|
25176
|
+
const textWidth = pageWidth - margins[1] - margins[3];
|
|
25177
|
+
const pageNumber = createPageNumberRuns(ctx, pageHeight, textWidth);
|
|
25178
|
+
let pageNumberRow = -1;
|
|
25179
|
+
if (pageNumber) {
|
|
25180
|
+
pageNumberRow = rowList.length - 1;
|
|
25181
|
+
for (let r = 0; r < rowList.length; r++) {
|
|
25182
|
+
const top = zone.positionList[rowList[r].startIndex].coordinate.leftTop[1] / scale;
|
|
25183
|
+
if (pageNumber.baseline <= top + rowList[r].height / scale) {
|
|
25184
|
+
pageNumberRow = r;
|
|
25185
|
+
break;
|
|
25186
|
+
}
|
|
25187
|
+
}
|
|
25511
25188
|
}
|
|
25512
|
-
|
|
25513
|
-
|
|
25189
|
+
const children = [];
|
|
25190
|
+
for (let r = 0; r < rowList.length; r++) {
|
|
25191
|
+
const row = rowList[r];
|
|
25192
|
+
const rowOptions = { padTop: r === 0 ? paddingTop : 0 };
|
|
25193
|
+
if (r !== pageNumberRow) {
|
|
25194
|
+
children.push(...await serializeRows(ctx, [row], zone, rowOptions));
|
|
25195
|
+
continue;
|
|
25196
|
+
}
|
|
25197
|
+
const top = zone.positionList[row.startIndex].coordinate.leftTop[1] / scale;
|
|
25198
|
+
const shift = pageNumber.baseline - (top + row.ascent / scale);
|
|
25199
|
+
children.push(
|
|
25200
|
+
await serializeRow(ctx, row, zone, rowOptions, {
|
|
25201
|
+
tabStop: pageNumber.tabStop,
|
|
25202
|
+
tabType: pageNumber.tabType,
|
|
25203
|
+
children: pageNumber.runs(shift),
|
|
25204
|
+
style: PAGE_NUMBER_STYLE
|
|
25205
|
+
})
|
|
25206
|
+
);
|
|
25514
25207
|
}
|
|
25515
|
-
|
|
25208
|
+
const fill = opts.footer.backgroundColor ? normalizeHexColor(opts.footer.backgroundColor, "FFFFFF") : void 0;
|
|
25209
|
+
const none = { style: BorderStyle.NONE, size: 0, color: "auto" };
|
|
25210
|
+
const band = new Table({
|
|
25211
|
+
layout: TableLayoutType.FIXED,
|
|
25212
|
+
width: { size: pxTw(pageWidth), type: WidthType.DXA },
|
|
25213
|
+
columnWidths: [pxTw(pageWidth)],
|
|
25214
|
+
indent: { size: -pxTw(margins[3]), type: WidthType.DXA },
|
|
25215
|
+
borders: noTableBorders(),
|
|
25216
|
+
rows: [
|
|
25217
|
+
new TableRow({
|
|
25218
|
+
cantSplit: true,
|
|
25219
|
+
height: { value: pxTw(barHeight), rule: HeightRule.EXACT },
|
|
25220
|
+
children: [
|
|
25221
|
+
new TableCell({
|
|
25222
|
+
width: { size: pxTw(pageWidth), type: WidthType.DXA },
|
|
25223
|
+
margins: {
|
|
25224
|
+
top: 0,
|
|
25225
|
+
bottom: 0,
|
|
25226
|
+
left: pxTw(margins[3]),
|
|
25227
|
+
right: pxTw(margins[1]),
|
|
25228
|
+
marginUnitType: WidthType.DXA
|
|
25229
|
+
},
|
|
25230
|
+
shading: fill ? { fill, type: ShadingType.CLEAR, color: "auto" } : void 0,
|
|
25231
|
+
borders: { top: none, right: none, bottom: none, left: none },
|
|
25232
|
+
children: children.length ? children : [createSpacerParagraph(false)]
|
|
25233
|
+
})
|
|
25234
|
+
]
|
|
25235
|
+
})
|
|
25236
|
+
]
|
|
25237
|
+
});
|
|
25238
|
+
return [band];
|
|
25516
25239
|
}
|
|
25517
|
-
|
|
25518
|
-
|
|
25519
|
-
|
|
25520
|
-
|
|
25240
|
+
var PAGE_NUMBER_STYLE = "WindocPageNumber";
|
|
25241
|
+
var FieldCharAttributes = class extends XmlAttributeComponent {
|
|
25242
|
+
constructor() {
|
|
25243
|
+
super(...arguments);
|
|
25244
|
+
this.xmlKeys = { type: "w:fldCharType" };
|
|
25521
25245
|
}
|
|
25522
|
-
|
|
25523
|
-
|
|
25524
|
-
|
|
25246
|
+
};
|
|
25247
|
+
var FieldChar = class extends XmlComponent {
|
|
25248
|
+
constructor(type) {
|
|
25249
|
+
super("w:fldChar");
|
|
25250
|
+
this.root.push(new FieldCharAttributes({ type }));
|
|
25525
25251
|
}
|
|
25526
|
-
|
|
25527
|
-
|
|
25528
|
-
|
|
25529
|
-
|
|
25530
|
-
|
|
25252
|
+
};
|
|
25253
|
+
var InstrTextAttributes = class extends XmlAttributeComponent {
|
|
25254
|
+
constructor() {
|
|
25255
|
+
super(...arguments);
|
|
25256
|
+
this.xmlKeys = { space: "xml:space" };
|
|
25531
25257
|
}
|
|
25532
|
-
|
|
25533
|
-
|
|
25534
|
-
|
|
25258
|
+
};
|
|
25259
|
+
var InstrText = class extends XmlComponent {
|
|
25260
|
+
constructor(instruction) {
|
|
25261
|
+
super("w:instrText");
|
|
25262
|
+
this.root.push(new InstrTextAttributes({ space: "preserve" }));
|
|
25263
|
+
this.root.push(` ${instruction} `);
|
|
25535
25264
|
}
|
|
25536
|
-
|
|
25537
|
-
|
|
25538
|
-
|
|
25539
|
-
|
|
25265
|
+
};
|
|
25266
|
+
function createFieldRuns(instruction, cached, style) {
|
|
25267
|
+
return [
|
|
25268
|
+
new TextRun({ ...style, children: [new FieldChar("begin")] }),
|
|
25269
|
+
new TextRun({ ...style, children: [new InstrText(instruction)] }),
|
|
25270
|
+
new TextRun({ ...style, children: [new FieldChar("separate")] }),
|
|
25271
|
+
new TextRun({ ...style, text: cached }),
|
|
25272
|
+
new TextRun({ ...style, children: [new FieldChar("end")] })
|
|
25540
25273
|
];
|
|
25541
|
-
return flattened.map(toHexChannel).join("");
|
|
25542
25274
|
}
|
|
25543
|
-
function
|
|
25544
|
-
|
|
25545
|
-
|
|
25546
|
-
|
|
25547
|
-
|
|
25548
|
-
|
|
25549
|
-
|
|
25550
|
-
return void 0;
|
|
25551
|
-
}
|
|
25552
|
-
context.fillStyle = "#000000";
|
|
25553
|
-
context.fillStyle = color;
|
|
25554
|
-
const normalized = context.fillStyle;
|
|
25555
|
-
if (typeof normalized !== "string") {
|
|
25556
|
-
return void 0;
|
|
25557
|
-
}
|
|
25558
|
-
return normalizeHexLiteral(normalized) || normalizeRgbColor(normalized);
|
|
25275
|
+
function pageNumberRunStyle(pageNumber) {
|
|
25276
|
+
return {
|
|
25277
|
+
font: mapFont(pageNumber?.font || "sans-serif"),
|
|
25278
|
+
// PageNumber draws `${size}px`; half-points = px * 0.75 * 2
|
|
25279
|
+
size: Math.round((pageNumber?.size || 12) * 1.5),
|
|
25280
|
+
color: normalizeHexColor(pageNumber?.color || "#000000", "000000")
|
|
25281
|
+
};
|
|
25559
25282
|
}
|
|
25560
|
-
function
|
|
25561
|
-
|
|
25562
|
-
|
|
25563
|
-
|
|
25564
|
-
|
|
25565
|
-
}
|
|
25566
|
-
|
|
25567
|
-
|
|
25568
|
-
const
|
|
25569
|
-
|
|
25570
|
-
|
|
25283
|
+
function createPageNumberRuns(ctx, pageHeight, textWidth) {
|
|
25284
|
+
const { pageNumber } = ctx.draw.getOptions();
|
|
25285
|
+
if (pageNumber.disabled || pageNumber.fromPageNo > 0) return null;
|
|
25286
|
+
const pageCount = ctx.draw.getPageCount();
|
|
25287
|
+
const tokens = (pageNumber.format || FORMAT_PLACEHOLDER.PAGE_NO).split(
|
|
25288
|
+
/(\{pageNo\}|\{pageCount\})/
|
|
25289
|
+
);
|
|
25290
|
+
const tabType = pageNumber.rowFlex === "center" /* CENTER */ ? TabStopType.CENTER : pageNumber.rowFlex === "right" /* RIGHT */ ? TabStopType.RIGHT : TabStopType.LEFT;
|
|
25291
|
+
const tabStop = tabType === TabStopType.CENTER ? pxTw(textWidth / 2) : tabType === TabStopType.RIGHT ? pxTw(textWidth) : 0;
|
|
25292
|
+
const position = (shift) => {
|
|
25293
|
+
const halfPoints = Math.round(-shift * 0.75 * 2);
|
|
25294
|
+
return halfPoints ? `${halfPoints}` : void 0;
|
|
25295
|
+
};
|
|
25296
|
+
return {
|
|
25297
|
+
baseline: pageHeight - pageNumber.bottom,
|
|
25298
|
+
tabType,
|
|
25299
|
+
tabStop,
|
|
25300
|
+
// shift > 0 means the number sits lower than the row baseline
|
|
25301
|
+
runs: (shift) => tokens.filter(Boolean).map((token) => {
|
|
25302
|
+
const style = {
|
|
25303
|
+
...pageNumberRunStyle(pageNumber),
|
|
25304
|
+
position: position(shift)
|
|
25305
|
+
};
|
|
25306
|
+
const field = token === FORMAT_PLACEHOLDER.PAGE_NO ? { instruction: "PAGE", cached: "1" } : token === FORMAT_PLACEHOLDER.PAGE_COUNT ? { instruction: "NUMPAGES", cached: `${pageCount}` } : null;
|
|
25307
|
+
if (!field) return [new TextRun({ text: token, ...style })];
|
|
25308
|
+
return createFieldRuns(field.instruction, field.cached, style);
|
|
25309
|
+
}).flat()
|
|
25310
|
+
};
|
|
25311
|
+
}
|
|
25312
|
+
function createTextRun(ctx, text, element, shading, characterSpacing) {
|
|
25313
|
+
const opts = ctx.draw.getOptions();
|
|
25314
|
+
const isLink = element.type === "hyperlink" /* HYPERLINK */;
|
|
25315
|
+
const color = normalizeHexColor(
|
|
25316
|
+
element.color || (isLink ? opts.defaultHyperlinkColor : opts.defaultColor),
|
|
25317
|
+
"000000"
|
|
25318
|
+
);
|
|
25319
|
+
const highlight = element.highlight ? normalizeHexColor(element.highlight) : void 0;
|
|
25320
|
+
const textRun = new TextRun({
|
|
25321
|
+
text,
|
|
25322
|
+
font: mapFont(element.font || opts.defaultFont),
|
|
25323
|
+
size: Math.round(getSize(ctx, element) * 2),
|
|
25324
|
+
bold: !!element.bold,
|
|
25325
|
+
italics: !!element.italic,
|
|
25326
|
+
strike: !!element.strikeout,
|
|
25327
|
+
superScript: element.type === "superscript" /* SUPERSCRIPT */,
|
|
25328
|
+
subScript: element.type === "subscript" /* SUBSCRIPT */,
|
|
25329
|
+
underline: element.underline || isLink ? { type: mapUnderlineType(element.textDecoration?.style) } : void 0,
|
|
25330
|
+
color,
|
|
25331
|
+
shading: shading || (highlight ? { fill: highlight, type: ShadingType.CLEAR, color: "auto" } : void 0),
|
|
25332
|
+
characterSpacing
|
|
25333
|
+
});
|
|
25334
|
+
if (isLink && element.url) {
|
|
25335
|
+
return new ExternalHyperlink({ link: element.url, children: [textRun] });
|
|
25571
25336
|
}
|
|
25572
|
-
return
|
|
25337
|
+
return textRun;
|
|
25573
25338
|
}
|
|
25574
|
-
function
|
|
25575
|
-
|
|
25576
|
-
|
|
25577
|
-
|
|
25578
|
-
|
|
25339
|
+
function labelShading(ctx, element) {
|
|
25340
|
+
const { defaultBackgroundColor } = ctx.draw.getOptions().label;
|
|
25341
|
+
return {
|
|
25342
|
+
fill: normalizeHexColor(
|
|
25343
|
+
element.label?.backgroundColor || defaultBackgroundColor,
|
|
25344
|
+
"FFFFFF"
|
|
25345
|
+
),
|
|
25346
|
+
type: ShadingType.CLEAR,
|
|
25347
|
+
color: "auto"
|
|
25348
|
+
};
|
|
25349
|
+
}
|
|
25350
|
+
async function createImageRun(element) {
|
|
25351
|
+
try {
|
|
25352
|
+
const image = await loadImagePayload(element.value);
|
|
25353
|
+
const transformation = {
|
|
25354
|
+
width: Math.max(1, element.width || 1),
|
|
25355
|
+
height: Math.max(1, element.height || 1)
|
|
25356
|
+
};
|
|
25357
|
+
if (image.type === "svg" && image.fallbackPng) {
|
|
25358
|
+
return new ImageRun({
|
|
25359
|
+
type: "svg",
|
|
25360
|
+
data: image.data,
|
|
25361
|
+
fallback: { type: "png", data: image.fallbackPng },
|
|
25362
|
+
transformation
|
|
25363
|
+
});
|
|
25579
25364
|
}
|
|
25580
|
-
return
|
|
25581
|
-
|
|
25582
|
-
|
|
25583
|
-
|
|
25365
|
+
return new ImageRun({
|
|
25366
|
+
type: image.type,
|
|
25367
|
+
data: image.data,
|
|
25368
|
+
transformation
|
|
25369
|
+
});
|
|
25370
|
+
} catch {
|
|
25584
25371
|
return null;
|
|
25585
25372
|
}
|
|
25586
|
-
return Math.min(Math.max(alpha, 0), 1);
|
|
25587
|
-
}
|
|
25588
|
-
function clampColorChannel(value) {
|
|
25589
|
-
return Math.min(Math.max(value, 0), 255);
|
|
25590
25373
|
}
|
|
25591
|
-
function
|
|
25592
|
-
|
|
25374
|
+
function getElementText(element) {
|
|
25375
|
+
switch (element.type) {
|
|
25376
|
+
case "checkbox" /* CHECKBOX */:
|
|
25377
|
+
return element.checkbox?.value ? "\u2611" : "\u2610";
|
|
25378
|
+
case "radio" /* RADIO */:
|
|
25379
|
+
return element.radio?.value ? "\u25C9" : "\u25CB";
|
|
25380
|
+
default:
|
|
25381
|
+
return (element.value || "").replace(new RegExp(ZERO, "g"), "");
|
|
25382
|
+
}
|
|
25593
25383
|
}
|
|
25594
|
-
function
|
|
25595
|
-
return
|
|
25384
|
+
function getSize(ctx, element) {
|
|
25385
|
+
return element.actualSize || element.size || ctx.draw.getOptions().defaultSize;
|
|
25596
25386
|
}
|
|
25597
|
-
function
|
|
25598
|
-
|
|
25599
|
-
return
|
|
25387
|
+
function measure(ctx, text, element) {
|
|
25388
|
+
ctx.measureCtx.font = ctx.draw.getElementFont(element, 1);
|
|
25389
|
+
return ctx.measureCtx.measureText(text).width;
|
|
25600
25390
|
}
|
|
25601
|
-
function
|
|
25602
|
-
|
|
25603
|
-
if (mime.includes("jpeg") || mime.includes("jpg")) return "jpg";
|
|
25604
|
-
if (mime.includes("gif")) return "gif";
|
|
25605
|
-
if (mime.includes("bmp")) return "bmp";
|
|
25606
|
-
return null;
|
|
25391
|
+
function isSameRunStyle(a, b) {
|
|
25392
|
+
return a.type === b.type && a.font === b.font && a.size === b.size && a.actualSize === b.actualSize && !!a.bold === !!b.bold && !!a.italic === !!b.italic && !!a.underline === !!b.underline && !!a.strikeout === !!b.strikeout && a.color === b.color && a.highlight === b.highlight && a.url === b.url;
|
|
25607
25393
|
}
|
|
25608
|
-
function
|
|
25609
|
-
const
|
|
25610
|
-
|
|
25611
|
-
|
|
25394
|
+
function mapFont(font) {
|
|
25395
|
+
const name = font.trim().replace(/^['"]|['"]$/g, "");
|
|
25396
|
+
switch (name.toLowerCase()) {
|
|
25397
|
+
case "sans-serif":
|
|
25398
|
+
return "Arial";
|
|
25399
|
+
case "serif":
|
|
25400
|
+
return "Times New Roman";
|
|
25401
|
+
case "monospace":
|
|
25402
|
+
return "Courier New";
|
|
25403
|
+
default:
|
|
25404
|
+
return name;
|
|
25612
25405
|
}
|
|
25613
|
-
return trimmed.toLowerCase().endsWith(".docx") ? trimmed : `${trimmed}.docx`;
|
|
25614
|
-
}
|
|
25615
|
-
function pxToTwips(px) {
|
|
25616
|
-
return Math.round(px * 15);
|
|
25617
25406
|
}
|
|
25618
25407
|
|
|
25619
25408
|
// src/utils/pdf.ts
|
|
@@ -25625,7 +25414,7 @@ import {
|
|
|
25625
25414
|
var DEFAULT_PDF_FILE_NAME = "document.pdf";
|
|
25626
25415
|
var DEFAULT_IMAGE_WIDTH2 = 320;
|
|
25627
25416
|
var DEFAULT_IMAGE_HEIGHT2 = 180;
|
|
25628
|
-
var
|
|
25417
|
+
var DEFAULT_LINE_HEIGHT = 1.15;
|
|
25629
25418
|
var PAGE_REGION_GAP = 12;
|
|
25630
25419
|
var SEPARATOR_HEIGHT = 12;
|
|
25631
25420
|
var LIST_GAP = 8;
|
|
@@ -25820,7 +25609,7 @@ async function parseElementList(elementList, context, options) {
|
|
|
25820
25609
|
}
|
|
25821
25610
|
if (element.type === "block" /* BLOCK */) {
|
|
25822
25611
|
await flushInlineBuffer();
|
|
25823
|
-
const blockText =
|
|
25612
|
+
const blockText = getBlockFallbackText(element);
|
|
25824
25613
|
if (blockText) {
|
|
25825
25614
|
blocks.push(
|
|
25826
25615
|
...await parseInlineElements(
|
|
@@ -25872,7 +25661,7 @@ async function parseInlineElements(elementList, context, options, overrides = {}
|
|
|
25872
25661
|
current = null;
|
|
25873
25662
|
};
|
|
25874
25663
|
const appendText = (element, text, factory, preserveTrailingBreak = false) => {
|
|
25875
|
-
const normalized =
|
|
25664
|
+
const normalized = normalizeText(text);
|
|
25876
25665
|
const parts = normalized.split("\n");
|
|
25877
25666
|
let lastSeparatorFlushedContent = false;
|
|
25878
25667
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -25908,7 +25697,7 @@ async function parseInlineElements(elementList, context, options, overrides = {}
|
|
|
25908
25697
|
const children = element.valueList || [];
|
|
25909
25698
|
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
25910
25699
|
const child = children[childIndex];
|
|
25911
|
-
const text =
|
|
25700
|
+
const text = normalizeText(getInlineElementText(child));
|
|
25912
25701
|
if (!text) continue;
|
|
25913
25702
|
appendText(
|
|
25914
25703
|
element,
|
|
@@ -25957,7 +25746,7 @@ async function parseInlineElements(elementList, context, options, overrides = {}
|
|
|
25957
25746
|
ensureParagraph(element).runs.push(badgeRun);
|
|
25958
25747
|
continue;
|
|
25959
25748
|
}
|
|
25960
|
-
const textValue =
|
|
25749
|
+
const textValue = getInlineElementText(element);
|
|
25961
25750
|
if (!textValue) {
|
|
25962
25751
|
continue;
|
|
25963
25752
|
}
|
|
@@ -25985,7 +25774,7 @@ async function parseListBlock(element, context, options) {
|
|
|
25985
25774
|
const blocks = [];
|
|
25986
25775
|
const orderedCounts = Array(9).fill(0);
|
|
25987
25776
|
for (const listItemElements of listItemMap.values()) {
|
|
25988
|
-
const itemElement =
|
|
25777
|
+
const itemElement = getListItemNumberingElement(listItemElements, element);
|
|
25989
25778
|
const marker = getListMarker(itemElement, orderedCounts);
|
|
25990
25779
|
blocks.push(
|
|
25991
25780
|
...await parseInlineElements(listItemElements, context, options, {
|
|
@@ -26544,10 +26333,11 @@ function layoutParagraph(block, width, context) {
|
|
|
26544
26333
|
}
|
|
26545
26334
|
if (token.width > availableWidth && token.kind === "text" && token.run.type === "text") {
|
|
26546
26335
|
const segments = splitTextToken(token, availableWidth, context);
|
|
26547
|
-
|
|
26548
|
-
tokens.splice(i
|
|
26336
|
+
if (segments.length > 1) {
|
|
26337
|
+
tokens.splice(i, 1, ...segments);
|
|
26338
|
+
i--;
|
|
26339
|
+
continue;
|
|
26549
26340
|
}
|
|
26550
|
-
continue;
|
|
26551
26341
|
}
|
|
26552
26342
|
if (line.width + token.width > availableWidth && line.fragments.length) {
|
|
26553
26343
|
commitLine();
|
|
@@ -26906,7 +26696,7 @@ function getEmptyLineHeight(block, context) {
|
|
|
26906
26696
|
block.context.rowMargin || context.options.defaultRowMargin
|
|
26907
26697
|
);
|
|
26908
26698
|
}
|
|
26909
|
-
function getRunHeight(run, rowMargin =
|
|
26699
|
+
function getRunHeight(run, rowMargin = DEFAULT_LINE_HEIGHT) {
|
|
26910
26700
|
return run.size * rowMargin;
|
|
26911
26701
|
}
|
|
26912
26702
|
function resolveTextMetrics(run, context) {
|
|
@@ -27115,10 +26905,10 @@ function loadHtmlImage2(src) {
|
|
|
27115
26905
|
image.src = src;
|
|
27116
26906
|
});
|
|
27117
26907
|
}
|
|
27118
|
-
function
|
|
26908
|
+
function getInlineElementText(element) {
|
|
27119
26909
|
switch (element.type) {
|
|
27120
26910
|
case "control" /* CONTROL */:
|
|
27121
|
-
return
|
|
26911
|
+
return getControlText(element.control);
|
|
27122
26912
|
case "date" /* DATE */:
|
|
27123
26913
|
return element.valueList?.length ? getTextFromElementList(element.valueList) : element.value;
|
|
27124
26914
|
case "checkbox" /* CHECKBOX */:
|
|
@@ -27134,7 +26924,7 @@ function getInlineElementText2(element) {
|
|
|
27134
26924
|
return element.value;
|
|
27135
26925
|
}
|
|
27136
26926
|
}
|
|
27137
|
-
function
|
|
26927
|
+
function getControlText(control) {
|
|
27138
26928
|
if (!control) return "";
|
|
27139
26929
|
if (control.type === "text" /* TEXT */ || control.type === "date" /* DATE */ || control.type === "number" /* NUMBER */) {
|
|
27140
26930
|
const value = control.value?.length ? getTextFromElementList(control.value) : "";
|
|
@@ -27142,7 +26932,7 @@ function getControlText2(control) {
|
|
|
27142
26932
|
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
27143
26933
|
}
|
|
27144
26934
|
if (control.type === "select" /* SELECT */) {
|
|
27145
|
-
const labels =
|
|
26935
|
+
const labels = getSelectedControlLabels(control.code, control.valueSets);
|
|
27146
26936
|
const content = labels.length ? labels.join(control.multiSelectDelimiter || ", ") : control.placeholder || "";
|
|
27147
26937
|
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
27148
26938
|
}
|
|
@@ -27155,13 +26945,13 @@ function getControlText2(control) {
|
|
|
27155
26945
|
}
|
|
27156
26946
|
return "";
|
|
27157
26947
|
}
|
|
27158
|
-
function
|
|
26948
|
+
function getSelectedControlLabels(code, valueSets) {
|
|
27159
26949
|
if (!code || !valueSets?.length) return [];
|
|
27160
26950
|
return code.split(",").map(
|
|
27161
26951
|
(selectCode) => valueSets.find((valueSet) => valueSet.code === selectCode)?.value
|
|
27162
26952
|
).filter((value) => !!value);
|
|
27163
26953
|
}
|
|
27164
|
-
function
|
|
26954
|
+
function getBlockFallbackText(element) {
|
|
27165
26955
|
if (element.block?.iframeBlock?.src) {
|
|
27166
26956
|
return element.block.iframeBlock.src;
|
|
27167
26957
|
}
|
|
@@ -27170,7 +26960,7 @@ function getBlockFallbackText2(element) {
|
|
|
27170
26960
|
}
|
|
27171
26961
|
return "";
|
|
27172
26962
|
}
|
|
27173
|
-
function
|
|
26963
|
+
function getListItemNumberingElement(listItemElements, fallback) {
|
|
27174
26964
|
return listItemElements.find(
|
|
27175
26965
|
(listItem) => listItem.listId || listItem.listLevel !== void 0 || !!listItem.listPreset || !!listItem.listStyle || !!listItem.listType
|
|
27176
26966
|
) || fallback;
|
|
@@ -27392,7 +27182,7 @@ function getReservedPageNumberBottom(pageNumber, pageNumberHeight) {
|
|
|
27392
27182
|
}
|
|
27393
27183
|
return pxToPt(pageNumber.bottom + 4) + pageNumberHeight;
|
|
27394
27184
|
}
|
|
27395
|
-
function
|
|
27185
|
+
function normalizeText(text = "") {
|
|
27396
27186
|
return text.replace(new RegExp(ZERO, "g"), "").replace(/\r\n/g, "\n");
|
|
27397
27187
|
}
|
|
27398
27188
|
function normalizePdfFileName(fileName) {
|
|
@@ -28732,8 +28522,7 @@ var CommandAdapt = class {
|
|
|
28732
28522
|
}
|
|
28733
28523
|
}
|
|
28734
28524
|
async exportDocx(payload = {}) {
|
|
28735
|
-
const
|
|
28736
|
-
const { blob, fileName } = await exportEditorDataToDocx(result, payload);
|
|
28525
|
+
const { blob, fileName } = await exportDrawToDocx(this.draw, payload);
|
|
28737
28526
|
downloadBlob(blob, fileName);
|
|
28738
28527
|
}
|
|
28739
28528
|
async exportPdf(payload = {}) {
|