@windoc/core 0.3.23 → 0.3.25
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 +33 -5
- package/dist/index.d.ts +33 -5
- package/dist/index.js +3706 -187
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3736 -187
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -78,7 +78,7 @@ __export(index_exports, {
|
|
|
78
78
|
module.exports = __toCommonJS(index_exports);
|
|
79
79
|
|
|
80
80
|
// src/version.ts
|
|
81
|
-
var version = "0.3.
|
|
81
|
+
var version = "0.3.25";
|
|
82
82
|
|
|
83
83
|
// src/dataset/enum/Common.ts
|
|
84
84
|
var MaxHeightRatio = /* @__PURE__ */ ((MaxHeightRatio2) => {
|
|
@@ -185,21 +185,6 @@ function debounce(func, delay) {
|
|
|
185
185
|
}, delay);
|
|
186
186
|
};
|
|
187
187
|
}
|
|
188
|
-
function deepCloneOmitKeys(obj, omitKeys) {
|
|
189
|
-
if (!obj || typeof obj !== "object") {
|
|
190
|
-
return obj;
|
|
191
|
-
}
|
|
192
|
-
let newObj = {};
|
|
193
|
-
if (Array.isArray(obj)) {
|
|
194
|
-
newObj = obj.map((item) => deepCloneOmitKeys(item, omitKeys));
|
|
195
|
-
} else {
|
|
196
|
-
Object.keys(obj).forEach((key) => {
|
|
197
|
-
if (omitKeys.includes(key)) return;
|
|
198
|
-
newObj[key] = deepCloneOmitKeys(obj[key], omitKeys);
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
return newObj;
|
|
202
|
-
}
|
|
203
188
|
function deepClone(obj) {
|
|
204
189
|
if (typeof structuredClone === "function") {
|
|
205
190
|
return structuredClone(obj);
|
|
@@ -271,6 +256,13 @@ function downloadFile(href, fileName) {
|
|
|
271
256
|
a.download = fileName;
|
|
272
257
|
a.click();
|
|
273
258
|
}
|
|
259
|
+
function downloadBlob(blob, fileName) {
|
|
260
|
+
const href = URL.createObjectURL(blob);
|
|
261
|
+
downloadFile(href, fileName);
|
|
262
|
+
window.setTimeout(() => {
|
|
263
|
+
URL.revokeObjectURL(href);
|
|
264
|
+
}, 0);
|
|
265
|
+
}
|
|
274
266
|
function threeClick(dom, fn) {
|
|
275
267
|
nClickEvent(3, dom, fn);
|
|
276
268
|
}
|
|
@@ -3896,23 +3888,23 @@ var ListStyle = /* @__PURE__ */ ((ListStyle3) => {
|
|
|
3896
3888
|
ListStyle3["CHECKBOX"] = "checkbox" /* CHECKBOX */;
|
|
3897
3889
|
return ListStyle3;
|
|
3898
3890
|
})(ListStyle || {});
|
|
3899
|
-
var OlPreset = /* @__PURE__ */ ((
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
return
|
|
3891
|
+
var OlPreset = /* @__PURE__ */ ((OlPreset3) => {
|
|
3892
|
+
OlPreset3["DEFAULT"] = "olDefault";
|
|
3893
|
+
OlPreset3["PARENTHESIS"] = "olParen";
|
|
3894
|
+
OlPreset3["OUTLINE"] = "olOutline";
|
|
3895
|
+
OlPreset3["UPPER_ALPHA"] = "olUpperA";
|
|
3896
|
+
OlPreset3["ROMAN"] = "olRoman";
|
|
3897
|
+
OlPreset3["ZERO_PAD"] = "olZeroPad";
|
|
3898
|
+
return OlPreset3;
|
|
3907
3899
|
})(OlPreset || {});
|
|
3908
|
-
var UlPreset = /* @__PURE__ */ ((
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
return
|
|
3900
|
+
var UlPreset = /* @__PURE__ */ ((UlPreset3) => {
|
|
3901
|
+
UlPreset3["DEFAULT"] = "ulDefault";
|
|
3902
|
+
UlPreset3["DIAMOND"] = "ulDiamond";
|
|
3903
|
+
UlPreset3["HOLLOW_SQ"] = "ulHollowSq";
|
|
3904
|
+
UlPreset3["ARROW"] = "ulArrow";
|
|
3905
|
+
UlPreset3["STAR"] = "ulStar";
|
|
3906
|
+
UlPreset3["CHECK_ARROW"] = "ulCheckArr";
|
|
3907
|
+
return UlPreset3;
|
|
3916
3908
|
})(UlPreset || {});
|
|
3917
3909
|
|
|
3918
3910
|
// src/dataset/constant/List.ts
|
|
@@ -5023,9 +5015,7 @@ function mergeSplitTableRowsForZip(trList) {
|
|
|
5023
5015
|
for (let t = trList.length - 1; t >= 0; t--) {
|
|
5024
5016
|
const splitTr = trList[t];
|
|
5025
5017
|
if (!splitTr.splitParentId) continue;
|
|
5026
|
-
const parentTrIdx = trList.findIndex(
|
|
5027
|
-
(tr) => tr.id === splitTr.splitParentId
|
|
5028
|
-
);
|
|
5018
|
+
const parentTrIdx = trList.findIndex((tr) => tr.id === splitTr.splitParentId);
|
|
5029
5019
|
if (!~parentTrIdx) continue;
|
|
5030
5020
|
const parentTr = trList[parentTrIdx];
|
|
5031
5021
|
parentTr.height += splitTr.height;
|
|
@@ -6071,10 +6061,184 @@ ${ulListStyleText || `${listIndex + 1}.`}${buildText(
|
|
|
6071
6061
|
return buildText(zipElementList(elementList));
|
|
6072
6062
|
}
|
|
6073
6063
|
function getSlimCloneElementList(elementList) {
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6064
|
+
const snapshotElementList = [];
|
|
6065
|
+
let preSourceElement = null;
|
|
6066
|
+
let preSnapshotElement = null;
|
|
6067
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
6068
|
+
const element = elementList[i];
|
|
6069
|
+
if (preSourceElement && preSnapshotElement && isHistoryTextSnapshotMergeable(preSourceElement, element)) {
|
|
6070
|
+
preSnapshotElement.value += element.value;
|
|
6071
|
+
preSourceElement = element;
|
|
6072
|
+
continue;
|
|
6073
|
+
}
|
|
6074
|
+
const snapshotElement = cloneHistorySnapshotElement(element);
|
|
6075
|
+
snapshotElementList.push(snapshotElement);
|
|
6076
|
+
preSourceElement = element;
|
|
6077
|
+
preSnapshotElement = snapshotElement;
|
|
6078
|
+
}
|
|
6079
|
+
return snapshotElementList;
|
|
6080
|
+
}
|
|
6081
|
+
var HISTORY_SNAPSHOT_OMIT_ATTR = /* @__PURE__ */ new Set([
|
|
6082
|
+
"metrics",
|
|
6083
|
+
"style",
|
|
6084
|
+
"rowList",
|
|
6085
|
+
"positionList",
|
|
6086
|
+
"x",
|
|
6087
|
+
"y",
|
|
6088
|
+
"trIndex",
|
|
6089
|
+
"tdIndex",
|
|
6090
|
+
"isLastRowTd",
|
|
6091
|
+
"isLastColTd",
|
|
6092
|
+
"isLastTd",
|
|
6093
|
+
"rowIndex",
|
|
6094
|
+
"colIndex",
|
|
6095
|
+
"mainHeight",
|
|
6096
|
+
"realHeight",
|
|
6097
|
+
"realMinHeight",
|
|
6098
|
+
"splitBoundaryTop",
|
|
6099
|
+
"splitBoundaryBottom",
|
|
6100
|
+
"actualSize"
|
|
6101
|
+
]);
|
|
6102
|
+
function cloneHistorySnapshotValue(payload) {
|
|
6103
|
+
if (!payload || typeof payload !== "object") {
|
|
6104
|
+
return payload;
|
|
6105
|
+
}
|
|
6106
|
+
if (Array.isArray(payload)) {
|
|
6107
|
+
return payload.map((item) => cloneHistorySnapshotValue(item));
|
|
6108
|
+
}
|
|
6109
|
+
const snapshot = {};
|
|
6110
|
+
for (const key of Object.keys(payload)) {
|
|
6111
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6112
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(
|
|
6113
|
+
payload[key]
|
|
6114
|
+
);
|
|
6115
|
+
}
|
|
6116
|
+
return snapshot;
|
|
6117
|
+
}
|
|
6118
|
+
function cloneHistorySnapshotTd(td) {
|
|
6119
|
+
const snapshot = {};
|
|
6120
|
+
for (const key of Object.keys(td)) {
|
|
6121
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6122
|
+
const value = td[key];
|
|
6123
|
+
if (key === "value") {
|
|
6124
|
+
snapshot.value = getSlimCloneElementList(value);
|
|
6125
|
+
continue;
|
|
6126
|
+
}
|
|
6127
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6128
|
+
}
|
|
6129
|
+
return snapshot;
|
|
6130
|
+
}
|
|
6131
|
+
function cloneHistorySnapshotTr(tr) {
|
|
6132
|
+
const snapshot = {};
|
|
6133
|
+
for (const key of Object.keys(tr)) {
|
|
6134
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6135
|
+
const value = tr[key];
|
|
6136
|
+
if (key === "tdList") {
|
|
6137
|
+
snapshot.tdList = value.map((td) => cloneHistorySnapshotTd(td));
|
|
6138
|
+
continue;
|
|
6139
|
+
}
|
|
6140
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6141
|
+
}
|
|
6142
|
+
return snapshot;
|
|
6143
|
+
}
|
|
6144
|
+
function cloneHistorySnapshotElement(element) {
|
|
6145
|
+
const snapshot = {};
|
|
6146
|
+
for (const key of Object.keys(element)) {
|
|
6147
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6148
|
+
const value = element[key];
|
|
6149
|
+
if (key === "trList" && Array.isArray(value)) {
|
|
6150
|
+
snapshot.trList = value.map((tr) => cloneHistorySnapshotTr(tr));
|
|
6151
|
+
continue;
|
|
6152
|
+
}
|
|
6153
|
+
if (key === "valueList" && Array.isArray(value)) {
|
|
6154
|
+
snapshot.valueList = getSlimCloneElementList(value);
|
|
6155
|
+
continue;
|
|
6156
|
+
}
|
|
6157
|
+
if (key === "control" && value && typeof value === "object") {
|
|
6158
|
+
snapshot.control = cloneHistorySnapshotControl(
|
|
6159
|
+
value
|
|
6160
|
+
);
|
|
6161
|
+
continue;
|
|
6162
|
+
}
|
|
6163
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6164
|
+
}
|
|
6165
|
+
return snapshot;
|
|
6166
|
+
}
|
|
6167
|
+
function cloneHistorySnapshotControl(control) {
|
|
6168
|
+
const snapshot = {};
|
|
6169
|
+
for (const key of Object.keys(control)) {
|
|
6170
|
+
const value = control[key];
|
|
6171
|
+
if (key === "value" && Array.isArray(value)) {
|
|
6172
|
+
snapshot.value = getSlimCloneElementList(value);
|
|
6173
|
+
continue;
|
|
6174
|
+
}
|
|
6175
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6176
|
+
}
|
|
6177
|
+
return snapshot;
|
|
6178
|
+
}
|
|
6179
|
+
function isHistoryTextSnapshotElement(element) {
|
|
6180
|
+
return !element.type || TEXTLIKE_ELEMENT_TYPE.includes(element.type);
|
|
6181
|
+
}
|
|
6182
|
+
function isHistoryTextSnapshotMergeable(source, target) {
|
|
6183
|
+
if (!isHistoryTextSnapshotElement(source) || !isHistoryTextSnapshotElement(target)) {
|
|
6184
|
+
return false;
|
|
6185
|
+
}
|
|
6186
|
+
return isSameHistoryElementExceptValue(source, target);
|
|
6187
|
+
}
|
|
6188
|
+
function isSameHistoryElementExceptValue(source, target) {
|
|
6189
|
+
const sourceKeys = Object.keys(source).filter(
|
|
6190
|
+
(key) => !HISTORY_SNAPSHOT_OMIT_ATTR.has(key)
|
|
6191
|
+
);
|
|
6192
|
+
const targetKeys = Object.keys(target).filter(
|
|
6193
|
+
(key) => !HISTORY_SNAPSHOT_OMIT_ATTR.has(key)
|
|
6194
|
+
);
|
|
6195
|
+
if (sourceKeys.length !== targetKeys.length) return false;
|
|
6196
|
+
for (let s = 0; s < sourceKeys.length; s++) {
|
|
6197
|
+
const key = sourceKeys[s];
|
|
6198
|
+
if (key === "value") continue;
|
|
6199
|
+
if (key === "groupIds" && Array.isArray(source[key]) && Array.isArray(target[key]) && isArrayEqual(source[key], target[key])) {
|
|
6200
|
+
continue;
|
|
6201
|
+
}
|
|
6202
|
+
if (source[key] !== target[key]) {
|
|
6203
|
+
return false;
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6206
|
+
return true;
|
|
6207
|
+
}
|
|
6208
|
+
function inflateElementList(elementList) {
|
|
6209
|
+
let i = 0;
|
|
6210
|
+
while (i < elementList.length) {
|
|
6211
|
+
const element = elementList[i];
|
|
6212
|
+
if (element.trList?.length) {
|
|
6213
|
+
for (let t = 0; t < element.trList.length; t++) {
|
|
6214
|
+
const tr = element.trList[t];
|
|
6215
|
+
for (let d = 0; d < tr.tdList.length; d++) {
|
|
6216
|
+
inflateElementList(tr.tdList[d].value);
|
|
6217
|
+
}
|
|
6218
|
+
}
|
|
6219
|
+
}
|
|
6220
|
+
if (element.valueList?.length) {
|
|
6221
|
+
inflateElementList(element.valueList);
|
|
6222
|
+
}
|
|
6223
|
+
if (element.control?.value?.length) {
|
|
6224
|
+
inflateElementList(element.control.value);
|
|
6225
|
+
}
|
|
6226
|
+
if (isHistoryTextSnapshotElement(element) && element.value?.length > 1) {
|
|
6227
|
+
const textList = splitText(element.value);
|
|
6228
|
+
elementList.splice(
|
|
6229
|
+
i,
|
|
6230
|
+
1,
|
|
6231
|
+
...textList.map((value) => ({
|
|
6232
|
+
...element,
|
|
6233
|
+
value
|
|
6234
|
+
}))
|
|
6235
|
+
);
|
|
6236
|
+
i += textList.length;
|
|
6237
|
+
continue;
|
|
6238
|
+
}
|
|
6239
|
+
i++;
|
|
6240
|
+
}
|
|
6241
|
+
return elementList;
|
|
6078
6242
|
}
|
|
6079
6243
|
function getIsBlockElement(element) {
|
|
6080
6244
|
return !!element?.type && (BLOCK_ELEMENT_TYPE.includes(element.type) || element.imgDisplay === "inline" /* INLINE */);
|
|
@@ -7747,7 +7911,8 @@ function backspace(evt, host) {
|
|
|
7747
7911
|
} else {
|
|
7748
7912
|
rangeManager.setRange(curIndex, curIndex);
|
|
7749
7913
|
draw.render({
|
|
7750
|
-
curIndex
|
|
7914
|
+
curIndex,
|
|
7915
|
+
dirtyStartIndex: curIndex + 1
|
|
7751
7916
|
});
|
|
7752
7917
|
}
|
|
7753
7918
|
}
|
|
@@ -7889,7 +8054,8 @@ function del(evt, host) {
|
|
|
7889
8054
|
} else {
|
|
7890
8055
|
rangeManager.setRange(curIndex, curIndex);
|
|
7891
8056
|
draw.render({
|
|
7892
|
-
curIndex
|
|
8057
|
+
curIndex,
|
|
8058
|
+
dirtyStartIndex: curIndex + 1
|
|
7893
8059
|
});
|
|
7894
8060
|
}
|
|
7895
8061
|
}
|
|
@@ -8731,10 +8897,12 @@ function input(data2, host) {
|
|
|
8731
8897
|
if (~curIndex) {
|
|
8732
8898
|
rangeManager.setRange(curIndex, curIndex);
|
|
8733
8899
|
const isWordBoundary = !isComposing && /[\s\p{P}]/u.test(data2);
|
|
8900
|
+
const dirtyStartIndex = startIndex + 1;
|
|
8734
8901
|
draw.render({
|
|
8735
8902
|
curIndex,
|
|
8736
8903
|
isSubmitHistory: !isComposing,
|
|
8737
|
-
isInputHistory: !isComposing && !isWordBoundary
|
|
8904
|
+
isInputHistory: !isComposing && !isWordBoundary,
|
|
8905
|
+
dirtyStartIndex
|
|
8738
8906
|
});
|
|
8739
8907
|
}
|
|
8740
8908
|
if (isComposing && ~curIndex) {
|
|
@@ -9418,7 +9586,7 @@ var HistoryManager = class {
|
|
|
9418
9586
|
const pop = this.undoStack.pop();
|
|
9419
9587
|
this.redoStack.push(pop);
|
|
9420
9588
|
if (this.undoStack.length) {
|
|
9421
|
-
this.undoStack[this.undoStack.length - 1]();
|
|
9589
|
+
this.undoStack[this.undoStack.length - 1].restore();
|
|
9422
9590
|
}
|
|
9423
9591
|
}
|
|
9424
9592
|
}
|
|
@@ -9426,11 +9594,11 @@ var HistoryManager = class {
|
|
|
9426
9594
|
if (this.redoStack.length) {
|
|
9427
9595
|
const pop = this.redoStack.pop();
|
|
9428
9596
|
this.undoStack.push(pop);
|
|
9429
|
-
pop();
|
|
9597
|
+
pop.restore();
|
|
9430
9598
|
}
|
|
9431
9599
|
}
|
|
9432
|
-
execute(
|
|
9433
|
-
this.undoStack.push(
|
|
9600
|
+
execute(entry) {
|
|
9601
|
+
this.undoStack.push(this._normalizeEntry(entry));
|
|
9434
9602
|
if (this.redoStack.length) {
|
|
9435
9603
|
this.redoStack = [];
|
|
9436
9604
|
}
|
|
@@ -9438,11 +9606,12 @@ var HistoryManager = class {
|
|
|
9438
9606
|
this.undoStack.shift();
|
|
9439
9607
|
}
|
|
9440
9608
|
}
|
|
9441
|
-
replaceLatest(
|
|
9609
|
+
replaceLatest(entry) {
|
|
9610
|
+
const normalizedEntry = this._normalizeEntry(entry);
|
|
9442
9611
|
if (this.undoStack.length > 0) {
|
|
9443
|
-
this.undoStack[this.undoStack.length - 1] =
|
|
9612
|
+
this.undoStack[this.undoStack.length - 1] = normalizedEntry;
|
|
9444
9613
|
} else {
|
|
9445
|
-
this.execute(
|
|
9614
|
+
this.execute(normalizedEntry);
|
|
9446
9615
|
}
|
|
9447
9616
|
if (this.redoStack.length) {
|
|
9448
9617
|
this.redoStack = [];
|
|
@@ -9473,6 +9642,14 @@ var HistoryManager = class {
|
|
|
9473
9642
|
popUndo() {
|
|
9474
9643
|
return this.undoStack.pop();
|
|
9475
9644
|
}
|
|
9645
|
+
_normalizeEntry(entry) {
|
|
9646
|
+
if (typeof entry === "function") {
|
|
9647
|
+
return {
|
|
9648
|
+
restore: entry
|
|
9649
|
+
};
|
|
9650
|
+
}
|
|
9651
|
+
return entry;
|
|
9652
|
+
}
|
|
9476
9653
|
};
|
|
9477
9654
|
|
|
9478
9655
|
// src/core/position/Position.ts
|
|
@@ -11680,6 +11857,7 @@ var ScrollObserver = class {
|
|
|
11680
11857
|
const { intersectionPageNo, visiblePageNoList } = this.getPageVisibleInfo();
|
|
11681
11858
|
this.draw.setIntersectionPageNo(intersectionPageNo);
|
|
11682
11859
|
this.draw.setVisiblePageNoList(visiblePageNoList);
|
|
11860
|
+
this.draw.renderVisiblePages(visiblePageNoList);
|
|
11683
11861
|
}, 150);
|
|
11684
11862
|
this.draw = draw;
|
|
11685
11863
|
this.options = draw.getOptions();
|
|
@@ -20487,6 +20665,9 @@ var Area = class {
|
|
|
20487
20665
|
getAreaInfo() {
|
|
20488
20666
|
return this.areaInfoMap;
|
|
20489
20667
|
}
|
|
20668
|
+
clear() {
|
|
20669
|
+
this.areaInfoMap.clear();
|
|
20670
|
+
}
|
|
20490
20671
|
getActiveAreaId() {
|
|
20491
20672
|
if (!this.areaInfoMap.size) return null;
|
|
20492
20673
|
const { startIndex } = this.range.getRange();
|
|
@@ -20878,6 +21059,7 @@ var Draw = class {
|
|
|
20878
21059
|
this.container = this._wrapContainer(rootContainer);
|
|
20879
21060
|
this.pageList = [];
|
|
20880
21061
|
this.ctxList = [];
|
|
21062
|
+
this.pageRenderVersionList = [];
|
|
20881
21063
|
this.pageNo = 0;
|
|
20882
21064
|
this.renderCount = 0;
|
|
20883
21065
|
this.pagePixelRatio = null;
|
|
@@ -20890,6 +21072,7 @@ var Draw = class {
|
|
|
20890
21072
|
this._formatContainer();
|
|
20891
21073
|
this.pageContainer = this._createPageContainer();
|
|
20892
21074
|
this._createPage(0);
|
|
21075
|
+
this.measureCtx = this._createMeasureContext();
|
|
20893
21076
|
this.i18n = new I18n(options.locale);
|
|
20894
21077
|
this.historyManager = new HistoryManager(this);
|
|
20895
21078
|
this.position = new Position(this);
|
|
@@ -20954,6 +21137,8 @@ var Draw = class {
|
|
|
20954
21137
|
this.pageRowList = [];
|
|
20955
21138
|
this.painterStyle = null;
|
|
20956
21139
|
this.painterOptions = null;
|
|
21140
|
+
this.elementFontCache = /* @__PURE__ */ new WeakMap();
|
|
21141
|
+
this.elementRowMarginCache = /* @__PURE__ */ new WeakMap();
|
|
20957
21142
|
this.visiblePageNoList = [];
|
|
20958
21143
|
this.intersectionPageNo = 0;
|
|
20959
21144
|
this.lazyRenderIntersectionObserver = null;
|
|
@@ -21120,7 +21305,9 @@ var Draw = class {
|
|
|
21120
21305
|
getContextInnerWidth() {
|
|
21121
21306
|
const positionContext = this.position.getPositionContext();
|
|
21122
21307
|
if (positionContext.isTable) {
|
|
21123
|
-
const td = this.resolveTableCellContext(
|
|
21308
|
+
const td = this.resolveTableCellContext(
|
|
21309
|
+
this.getOriginalElementList()
|
|
21310
|
+
)?.td;
|
|
21124
21311
|
if (!td) return this.getColumnWidth() / this.options.scale;
|
|
21125
21312
|
const tdPadding = this.getTdPadding();
|
|
21126
21313
|
return td.width - tdPadding[1] - tdPadding[3];
|
|
@@ -21173,6 +21360,7 @@ var Draw = class {
|
|
|
21173
21360
|
return this.visiblePageNoList;
|
|
21174
21361
|
}
|
|
21175
21362
|
setVisiblePageNoList(payload) {
|
|
21363
|
+
if (isArrayEqual(this.visiblePageNoList, payload)) return;
|
|
21176
21364
|
this.visiblePageNoList = payload;
|
|
21177
21365
|
if (this.listener.visiblePageNoListChange) {
|
|
21178
21366
|
this.listener.visiblePageNoListChange(this.visiblePageNoList);
|
|
@@ -21185,6 +21373,7 @@ var Draw = class {
|
|
|
21185
21373
|
return this.intersectionPageNo;
|
|
21186
21374
|
}
|
|
21187
21375
|
setIntersectionPageNo(payload) {
|
|
21376
|
+
if (this.intersectionPageNo === payload) return;
|
|
21188
21377
|
this.intersectionPageNo = payload;
|
|
21189
21378
|
if (this.listener.intersectionPageNoChange) {
|
|
21190
21379
|
this.listener.intersectionPageNoChange(this.intersectionPageNo);
|
|
@@ -21212,7 +21401,9 @@ var Draw = class {
|
|
|
21212
21401
|
candidateIndexes.push(context.index);
|
|
21213
21402
|
}
|
|
21214
21403
|
if (context.tableId) {
|
|
21215
|
-
const tableIndex = sourceElementList.findIndex(
|
|
21404
|
+
const tableIndex = sourceElementList.findIndex(
|
|
21405
|
+
(el) => el.id === context.tableId
|
|
21406
|
+
);
|
|
21216
21407
|
if (~tableIndex && !candidateIndexes.includes(tableIndex)) {
|
|
21217
21408
|
candidateIndexes.push(tableIndex);
|
|
21218
21409
|
}
|
|
@@ -21321,9 +21512,7 @@ var Draw = class {
|
|
|
21321
21512
|
return this.header.getElementList();
|
|
21322
21513
|
}
|
|
21323
21514
|
getTableElementList(sourceElementList) {
|
|
21324
|
-
const splitCellSelectionContext = this.getSplitCellSelectionContext(
|
|
21325
|
-
sourceElementList
|
|
21326
|
-
);
|
|
21515
|
+
const splitCellSelectionContext = this.getSplitCellSelectionContext(sourceElementList);
|
|
21327
21516
|
if (splitCellSelectionContext) {
|
|
21328
21517
|
return splitCellSelectionContext.value;
|
|
21329
21518
|
}
|
|
@@ -21447,10 +21636,7 @@ var Draw = class {
|
|
|
21447
21636
|
positionContext.trId = continuationTr.id;
|
|
21448
21637
|
positionContext.tableId = tableId;
|
|
21449
21638
|
this.position.setPositionContext(positionContext);
|
|
21450
|
-
this.range.setRange(
|
|
21451
|
-
continuationCursorIndex,
|
|
21452
|
-
continuationCursorIndex
|
|
21453
|
-
);
|
|
21639
|
+
this.range.setRange(continuationCursorIndex, continuationCursorIndex);
|
|
21454
21640
|
this.pendingTableCursorIndex = continuationCursorIndex;
|
|
21455
21641
|
return true;
|
|
21456
21642
|
}
|
|
@@ -21510,7 +21696,10 @@ var Draw = class {
|
|
|
21510
21696
|
});
|
|
21511
21697
|
const splitCellSelection = this.range.getSplitCellSelection();
|
|
21512
21698
|
if (splitCellSelection) {
|
|
21513
|
-
const curIndex2 = this.replaceSplitCellSelection(
|
|
21699
|
+
const curIndex2 = this.replaceSplitCellSelection(
|
|
21700
|
+
payload,
|
|
21701
|
+
splitCellSelection
|
|
21702
|
+
);
|
|
21514
21703
|
if (~curIndex2) {
|
|
21515
21704
|
this.range.setRange(curIndex2, curIndex2);
|
|
21516
21705
|
this.render({
|
|
@@ -21640,12 +21829,7 @@ var Draw = class {
|
|
|
21640
21829
|
trId: rootCellContext.tr.id,
|
|
21641
21830
|
tdId: rootTd.id
|
|
21642
21831
|
});
|
|
21643
|
-
this.spliceElementList(
|
|
21644
|
-
rootTd.value,
|
|
21645
|
-
1,
|
|
21646
|
-
rootTd.value.length - 1,
|
|
21647
|
-
payload
|
|
21648
|
-
);
|
|
21832
|
+
this.spliceElementList(rootTd.value, 1, rootTd.value.length - 1, payload);
|
|
21649
21833
|
rootTd.rowList = void 0;
|
|
21650
21834
|
rootTd.positionList = void 0;
|
|
21651
21835
|
rootTd.mainHeight = void 0;
|
|
@@ -22065,6 +22249,15 @@ var Draw = class {
|
|
|
22065
22249
|
this._initPageContext(ctx);
|
|
22066
22250
|
this.pageList.push(canvas);
|
|
22067
22251
|
this.ctxList.push(ctx);
|
|
22252
|
+
this.pageRenderVersionList.push(0);
|
|
22253
|
+
}
|
|
22254
|
+
_createMeasureContext() {
|
|
22255
|
+
const canvas = document.createElement("canvas");
|
|
22256
|
+
const ctx = canvas.getContext("2d");
|
|
22257
|
+
ctx.letterSpacing = "0px";
|
|
22258
|
+
ctx.wordSpacing = "0px";
|
|
22259
|
+
ctx.direction = "ltr";
|
|
22260
|
+
return ctx;
|
|
22068
22261
|
}
|
|
22069
22262
|
_initPageContext(ctx) {
|
|
22070
22263
|
const dpr = this.getPagePixelRatio();
|
|
@@ -22077,8 +22270,22 @@ var Draw = class {
|
|
|
22077
22270
|
const { defaultSize, defaultFont } = this.options;
|
|
22078
22271
|
const font = el.font || defaultFont;
|
|
22079
22272
|
const size = el.actualSize || el.size || defaultSize;
|
|
22273
|
+
const cache = this.elementFontCache.get(el);
|
|
22274
|
+
if (cache && cache.scale === scale && cache.font === font && cache.size === size && cache.actualSize === el.actualSize && cache.bold === el.bold && cache.italic === el.italic) {
|
|
22275
|
+
return cache.style;
|
|
22276
|
+
}
|
|
22080
22277
|
const sizePx = size * (96 / 72) * scale;
|
|
22081
|
-
|
|
22278
|
+
const style = `${el.italic ? "italic " : ""}${el.bold ? "bold " : ""}${sizePx}px ${font}`;
|
|
22279
|
+
this.elementFontCache.set(el, {
|
|
22280
|
+
scale,
|
|
22281
|
+
font,
|
|
22282
|
+
size,
|
|
22283
|
+
actualSize: el.actualSize,
|
|
22284
|
+
bold: el.bold,
|
|
22285
|
+
italic: el.italic,
|
|
22286
|
+
style
|
|
22287
|
+
});
|
|
22288
|
+
return style;
|
|
22082
22289
|
}
|
|
22083
22290
|
getElementSize(el) {
|
|
22084
22291
|
return el.actualSize || el.size || this.options.defaultSize;
|
|
@@ -22091,13 +22298,25 @@ var Draw = class {
|
|
|
22091
22298
|
scale
|
|
22092
22299
|
} = this.options;
|
|
22093
22300
|
const fontSize = el.size || defaultSize;
|
|
22301
|
+
const rowMarginValue = el.rowMargin ?? defaultRowMargin;
|
|
22302
|
+
const cache = this.elementRowMarginCache.get(el);
|
|
22303
|
+
if (cache && cache.scale === scale && cache.size === fontSize && cache.rowMargin === rowMarginValue) {
|
|
22304
|
+
return cache.value;
|
|
22305
|
+
}
|
|
22094
22306
|
let ratio = 1;
|
|
22095
22307
|
if (fontSize < 12) {
|
|
22096
22308
|
ratio = fontSize / 12;
|
|
22097
22309
|
} else if (fontSize > 30) {
|
|
22098
22310
|
ratio = 1 + (fontSize - 30) / 30;
|
|
22099
22311
|
}
|
|
22100
|
-
|
|
22312
|
+
const value = defaultBasicRowMarginHeight * ratio * rowMarginValue * scale;
|
|
22313
|
+
this.elementRowMarginCache.set(el, {
|
|
22314
|
+
scale,
|
|
22315
|
+
size: fontSize,
|
|
22316
|
+
rowMargin: rowMarginValue,
|
|
22317
|
+
value
|
|
22318
|
+
});
|
|
22319
|
+
return value;
|
|
22101
22320
|
}
|
|
22102
22321
|
createListStateSeed(initialListState) {
|
|
22103
22322
|
const listLevelIndex = /* @__PURE__ */ new Map();
|
|
@@ -22176,7 +22395,12 @@ var Draw = class {
|
|
|
22176
22395
|
pageHeight = 0,
|
|
22177
22396
|
mainOuterHeight = 0,
|
|
22178
22397
|
surroundElementList = [],
|
|
22179
|
-
initialListState
|
|
22398
|
+
initialListState,
|
|
22399
|
+
hasListElement = true,
|
|
22400
|
+
fromIndex = 0,
|
|
22401
|
+
initialY = startY,
|
|
22402
|
+
initialPageNo = 0,
|
|
22403
|
+
initialRowIndex = 0
|
|
22180
22404
|
} = payload;
|
|
22181
22405
|
const {
|
|
22182
22406
|
defaultSize,
|
|
@@ -22185,27 +22409,62 @@ var Draw = class {
|
|
|
22185
22409
|
defaultTabWidth
|
|
22186
22410
|
} = this.options;
|
|
22187
22411
|
const defaultBasicRowMarginHeight = this.getDefaultBasicRowMarginHeight();
|
|
22188
|
-
const
|
|
22189
|
-
|
|
22190
|
-
|
|
22412
|
+
const ctx = this.measureCtx;
|
|
22413
|
+
ctx.save();
|
|
22414
|
+
ctx.font = "10px sans-serif";
|
|
22415
|
+
ctx.textAlign = "start";
|
|
22416
|
+
ctx.textBaseline = "alphabetic";
|
|
22417
|
+
const listStyleMap = hasListElement ? this.listParticle.computeListStyle(ctx, elementList) : /* @__PURE__ */ new Map();
|
|
22418
|
+
const wordMeasureCache = /* @__PURE__ */ new Map();
|
|
22419
|
+
const getWordMeasure = (curIndex, elementFont) => {
|
|
22420
|
+
const cache = wordMeasureCache.get(curIndex);
|
|
22421
|
+
if (cache) return cache;
|
|
22422
|
+
let endIndex = curIndex;
|
|
22423
|
+
while (endIndex < elementList.length) {
|
|
22424
|
+
const measureElement = elementList[endIndex];
|
|
22425
|
+
if (measureElement.type && measureElement.type !== "text" /* TEXT */ || !this.LETTER_REG.test(measureElement.value)) {
|
|
22426
|
+
break;
|
|
22427
|
+
}
|
|
22428
|
+
if (this.getElementFont(measureElement) !== elementFont) {
|
|
22429
|
+
const fallbackWord = this.textParticle.measureWord(
|
|
22430
|
+
ctx,
|
|
22431
|
+
elementList,
|
|
22432
|
+
curIndex
|
|
22433
|
+
);
|
|
22434
|
+
wordMeasureCache.set(curIndex, fallbackWord);
|
|
22435
|
+
return fallbackWord;
|
|
22436
|
+
}
|
|
22437
|
+
endIndex++;
|
|
22438
|
+
}
|
|
22439
|
+
const endElement = elementList[endIndex] || null;
|
|
22440
|
+
let suffixWidth = 0;
|
|
22441
|
+
for (let i = endIndex - 1; i >= curIndex; i--) {
|
|
22442
|
+
suffixWidth += this.textParticle.measureText(ctx, elementList[i]).width;
|
|
22443
|
+
wordMeasureCache.set(i, {
|
|
22444
|
+
width: suffixWidth,
|
|
22445
|
+
endElement
|
|
22446
|
+
});
|
|
22447
|
+
}
|
|
22448
|
+
return wordMeasureCache.get(curIndex);
|
|
22449
|
+
};
|
|
22191
22450
|
const rowList = [];
|
|
22192
|
-
if (elementList.length) {
|
|
22451
|
+
if (elementList.length && fromIndex < elementList.length) {
|
|
22193
22452
|
rowList.push({
|
|
22194
22453
|
width: 0,
|
|
22195
22454
|
height: 0,
|
|
22196
22455
|
ascent: 0,
|
|
22197
22456
|
elementList: [],
|
|
22198
|
-
startIndex:
|
|
22199
|
-
rowIndex:
|
|
22200
|
-
rowFlex: elementList?.[
|
|
22457
|
+
startIndex: fromIndex,
|
|
22458
|
+
rowIndex: initialRowIndex,
|
|
22459
|
+
rowFlex: elementList?.[fromIndex]?.rowFlex || elementList?.[fromIndex + 1]?.rowFlex
|
|
22201
22460
|
});
|
|
22202
22461
|
}
|
|
22203
22462
|
let x = startX;
|
|
22204
|
-
let y =
|
|
22205
|
-
let pageNo =
|
|
22463
|
+
let y = initialY;
|
|
22464
|
+
let pageNo = initialPageNo;
|
|
22206
22465
|
const listState = this.createListStateSeed(initialListState);
|
|
22207
22466
|
let controlRealWidth = 0;
|
|
22208
|
-
for (let i =
|
|
22467
|
+
for (let i = fromIndex; i < elementList.length; i++) {
|
|
22209
22468
|
const curRow = rowList[rowList.length - 1];
|
|
22210
22469
|
const element = elementList[i];
|
|
22211
22470
|
const rowMargin = this.getElementRowMargin(element);
|
|
@@ -22251,9 +22510,7 @@ var Draw = class {
|
|
|
22251
22510
|
} else if (element.type === "table" /* TABLE */) {
|
|
22252
22511
|
let activeSplitRange;
|
|
22253
22512
|
let mergedSplitFallback;
|
|
22254
|
-
const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(
|
|
22255
|
-
element
|
|
22256
|
-
);
|
|
22513
|
+
const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(element);
|
|
22257
22514
|
if (element.pagingId) {
|
|
22258
22515
|
let tableIndex = i + 1;
|
|
22259
22516
|
let combineCount = 0;
|
|
@@ -22858,16 +23115,14 @@ var Draw = class {
|
|
|
22858
23115
|
element.actualSize = Math.ceil(size * 0.6);
|
|
22859
23116
|
}
|
|
22860
23117
|
metrics.height = (element.actualSize || size) * scale;
|
|
22861
|
-
|
|
23118
|
+
const elementFont = this.getElementFont(element);
|
|
23119
|
+
ctx.font = elementFont;
|
|
22862
23120
|
const fontMetrics = this.textParticle.measureText(ctx, element);
|
|
22863
23121
|
metrics.width = fontMetrics.width * scale;
|
|
22864
23122
|
if (element.letterSpacing) {
|
|
22865
23123
|
metrics.width += element.letterSpacing * scale;
|
|
22866
23124
|
}
|
|
22867
|
-
const basisMetrics = this.textParticle.measureBasisWord(
|
|
22868
|
-
ctx,
|
|
22869
|
-
element.font
|
|
22870
|
-
);
|
|
23125
|
+
const basisMetrics = this.textParticle.measureBasisWord(ctx, elementFont);
|
|
22871
23126
|
metrics.boundingBoxAscent = basisMetrics.fontBoundingBoxAscent * scale;
|
|
22872
23127
|
metrics.boundingBoxDescent = basisMetrics.fontBoundingBoxDescent * scale;
|
|
22873
23128
|
if (element.type === "superscript" /* SUPERSCRIPT */) {
|
|
@@ -22904,11 +23159,7 @@ var Draw = class {
|
|
|
22904
23159
|
if ((!preElement?.type || preElement?.type === "text" /* TEXT */) && (!element.type || element.type === "text" /* TEXT */)) {
|
|
22905
23160
|
const word = `${preElement?.value || ""}${element.value}`;
|
|
22906
23161
|
if (this.WORD_LIKE_REG.test(word)) {
|
|
22907
|
-
const { width, endElement } =
|
|
22908
|
-
ctx,
|
|
22909
|
-
elementList,
|
|
22910
|
-
i
|
|
22911
|
-
);
|
|
23162
|
+
const { width, endElement } = getWordMeasure(i, ctx.font);
|
|
22912
23163
|
const wordWidth = width * scale;
|
|
22913
23164
|
if (endElement && wordWidth <= availableWidth) {
|
|
22914
23165
|
curRowWidth += wordWidth;
|
|
@@ -23041,6 +23292,7 @@ var Draw = class {
|
|
|
23041
23292
|
x += metrics.width;
|
|
23042
23293
|
}
|
|
23043
23294
|
}
|
|
23295
|
+
ctx.restore();
|
|
23044
23296
|
return rowList;
|
|
23045
23297
|
}
|
|
23046
23298
|
_applyRowSpacing() {
|
|
@@ -23633,30 +23885,11 @@ var Draw = class {
|
|
|
23633
23885
|
if (this.isGraffitiMode()) {
|
|
23634
23886
|
this.graffiti.render(ctx, pageNo);
|
|
23635
23887
|
}
|
|
23888
|
+
this.pageRenderVersionList[pageNo] = this.renderCount;
|
|
23636
23889
|
}
|
|
23637
23890
|
_disconnectLazyRender() {
|
|
23638
23891
|
this.lazyRenderIntersectionObserver?.disconnect();
|
|
23639
|
-
|
|
23640
|
-
_lazyRender() {
|
|
23641
|
-
const positionList = this.position.getOriginalMainPositionList();
|
|
23642
|
-
const elementList = this.getOriginalMainElementList();
|
|
23643
|
-
this._disconnectLazyRender();
|
|
23644
|
-
this.lazyRenderIntersectionObserver = new IntersectionObserver((entries) => {
|
|
23645
|
-
entries.forEach((entry) => {
|
|
23646
|
-
if (entry.isIntersecting) {
|
|
23647
|
-
const index = Number(entry.target.dataset.index);
|
|
23648
|
-
this._drawPage({
|
|
23649
|
-
elementList,
|
|
23650
|
-
positionList,
|
|
23651
|
-
rowList: this.pageRowList[index],
|
|
23652
|
-
pageNo: index
|
|
23653
|
-
});
|
|
23654
|
-
}
|
|
23655
|
-
});
|
|
23656
|
-
});
|
|
23657
|
-
this.pageList.forEach((el) => {
|
|
23658
|
-
this.lazyRenderIntersectionObserver.observe(el);
|
|
23659
|
-
});
|
|
23892
|
+
this.lazyRenderIntersectionObserver = null;
|
|
23660
23893
|
}
|
|
23661
23894
|
_immediateRender() {
|
|
23662
23895
|
const positionList = this.position.getOriginalMainPositionList();
|
|
@@ -23670,6 +23903,100 @@ var Draw = class {
|
|
|
23670
23903
|
});
|
|
23671
23904
|
}
|
|
23672
23905
|
}
|
|
23906
|
+
_collectMainRenderMeta() {
|
|
23907
|
+
const surroundElementList = [];
|
|
23908
|
+
let hasAreaElement = false;
|
|
23909
|
+
let hasListElement = false;
|
|
23910
|
+
let hasStructuralElement = false;
|
|
23911
|
+
for (let i = 0; i < this.elementList.length; i++) {
|
|
23912
|
+
const element = this.elementList[i];
|
|
23913
|
+
if (!hasAreaElement && element.areaId) {
|
|
23914
|
+
hasAreaElement = true;
|
|
23915
|
+
}
|
|
23916
|
+
if (!hasListElement && element.listId) {
|
|
23917
|
+
hasListElement = true;
|
|
23918
|
+
}
|
|
23919
|
+
if (!hasStructuralElement && (element.type === "table" /* TABLE */ || element.type === "block" /* BLOCK */ || element.type === "pageBreak" /* PAGE_BREAK */ || element.type === "columnBreak" /* COLUMN_BREAK */ || element.type === "image" /* IMAGE */ || element.type === "latex" /* LATEX */ || element.type === "separator" /* SEPARATOR */)) {
|
|
23920
|
+
hasStructuralElement = true;
|
|
23921
|
+
}
|
|
23922
|
+
if (element.imgDisplay === "surround" /* SURROUND */) {
|
|
23923
|
+
surroundElementList.push(element);
|
|
23924
|
+
}
|
|
23925
|
+
}
|
|
23926
|
+
return {
|
|
23927
|
+
hasAreaElement,
|
|
23928
|
+
hasListElement,
|
|
23929
|
+
hasStructuralElement,
|
|
23930
|
+
surroundElementList
|
|
23931
|
+
};
|
|
23932
|
+
}
|
|
23933
|
+
_getIncrementalRestartState(dirtyStartIndex, rowList, pageRowList, startY) {
|
|
23934
|
+
if (!rowList.length || !pageRowList.length) return null;
|
|
23935
|
+
const searchIndex = Math.max(dirtyStartIndex - 1, 0);
|
|
23936
|
+
let restartRowIndex = -1;
|
|
23937
|
+
for (let i = 0; i < rowList.length; i++) {
|
|
23938
|
+
if (rowList[i].startIndex <= searchIndex) {
|
|
23939
|
+
restartRowIndex = i;
|
|
23940
|
+
} else {
|
|
23941
|
+
break;
|
|
23942
|
+
}
|
|
23943
|
+
}
|
|
23944
|
+
if (restartRowIndex < 0) return null;
|
|
23945
|
+
if (restartRowIndex > 0 && this.elementList[rowList[restartRowIndex].startIndex]?.value === ZERO && !this.elementList[rowList[restartRowIndex].startIndex]?.listWrap) {
|
|
23946
|
+
restartRowIndex -= 1;
|
|
23947
|
+
}
|
|
23948
|
+
const restartRow = rowList[restartRowIndex];
|
|
23949
|
+
const fromIndex = Math.min(restartRow.startIndex, this.elementList.length);
|
|
23950
|
+
let initialPageNo = 0;
|
|
23951
|
+
let initialY = startY;
|
|
23952
|
+
let absoluteRowIndex = 0;
|
|
23953
|
+
let isFound = false;
|
|
23954
|
+
for (let pageNo = 0; pageNo < pageRowList.length; pageNo++) {
|
|
23955
|
+
const rows = pageRowList[pageNo];
|
|
23956
|
+
let y = startY;
|
|
23957
|
+
for (let rowNo = 0; rowNo < rows.length; rowNo++) {
|
|
23958
|
+
if (absoluteRowIndex === restartRowIndex) {
|
|
23959
|
+
initialPageNo = pageNo;
|
|
23960
|
+
initialY = y;
|
|
23961
|
+
isFound = true;
|
|
23962
|
+
break;
|
|
23963
|
+
}
|
|
23964
|
+
const row = rows[rowNo];
|
|
23965
|
+
y += (row.offsetY || 0) + (row.spaceAbove || 0) + row.height + (row.spaceBelow || 0);
|
|
23966
|
+
absoluteRowIndex++;
|
|
23967
|
+
}
|
|
23968
|
+
if (isFound) break;
|
|
23969
|
+
}
|
|
23970
|
+
if (!isFound) return null;
|
|
23971
|
+
return {
|
|
23972
|
+
fromIndex,
|
|
23973
|
+
initialY,
|
|
23974
|
+
initialPageNo,
|
|
23975
|
+
initialRowIndex: restartRow.rowIndex,
|
|
23976
|
+
initialListState: this.getListStateBeforeIndex(this.elementList, fromIndex),
|
|
23977
|
+
prefixRows: rowList.slice(0, restartRowIndex)
|
|
23978
|
+
};
|
|
23979
|
+
}
|
|
23980
|
+
renderVisiblePages(pageNoList) {
|
|
23981
|
+
const positionList = this.position.getOriginalMainPositionList();
|
|
23982
|
+
const elementList = this.getOriginalMainElementList();
|
|
23983
|
+
const targetPageNoList = pageNoList ?? this.visiblePageNoList;
|
|
23984
|
+
if (!targetPageNoList?.length) return;
|
|
23985
|
+
const renderedPageNoSet = /* @__PURE__ */ new Set();
|
|
23986
|
+
for (let i = 0; i < targetPageNoList.length; i++) {
|
|
23987
|
+
const pageNo = targetPageNoList[i];
|
|
23988
|
+
if (renderedPageNoSet.has(pageNo) || pageNo < 0 || pageNo >= this.pageRowList.length || this.pageRenderVersionList[pageNo] === this.renderCount) {
|
|
23989
|
+
continue;
|
|
23990
|
+
}
|
|
23991
|
+
renderedPageNoSet.add(pageNo);
|
|
23992
|
+
this._drawPage({
|
|
23993
|
+
elementList,
|
|
23994
|
+
positionList,
|
|
23995
|
+
rowList: this.pageRowList[pageNo],
|
|
23996
|
+
pageNo
|
|
23997
|
+
});
|
|
23998
|
+
}
|
|
23999
|
+
}
|
|
23673
24000
|
render(payload) {
|
|
23674
24001
|
this.renderCount++;
|
|
23675
24002
|
const { header, footer } = this.options;
|
|
@@ -23681,15 +24008,19 @@ var Draw = class {
|
|
|
23681
24008
|
isLazy = true,
|
|
23682
24009
|
isInit = false,
|
|
23683
24010
|
isSourceHistory = false,
|
|
23684
|
-
isFirstRender = false
|
|
24011
|
+
isFirstRender = false,
|
|
24012
|
+
dirtyStartIndex
|
|
23685
24013
|
} = payload || {};
|
|
23686
24014
|
let { curIndex } = payload || {};
|
|
23687
24015
|
this.pendingTableCursorIndex = void 0;
|
|
23688
24016
|
const innerWidth = this.getInnerWidth();
|
|
23689
24017
|
const columnWidth = this.getColumnWidth();
|
|
23690
24018
|
const isPagingMode = this.getIsPagingMode();
|
|
24019
|
+
const columnCount = this.getColumnCount();
|
|
23691
24020
|
const oldPageSize = this.pageRowList.length;
|
|
23692
24021
|
if (isCompute) {
|
|
24022
|
+
const oldRowList = this.rowList;
|
|
24023
|
+
const oldPageRowList = this.pageRowList;
|
|
23693
24024
|
this.position.setFloatPositionList([]);
|
|
23694
24025
|
if (isPagingMode) {
|
|
23695
24026
|
if (!header.disabled) {
|
|
@@ -23705,8 +24036,13 @@ var Draw = class {
|
|
|
23705
24036
|
const mainOuterHeight = this.getMainOuterHeight();
|
|
23706
24037
|
const startX = margins[3];
|
|
23707
24038
|
const startY = margins[0] + extraHeight;
|
|
23708
|
-
const
|
|
23709
|
-
|
|
24039
|
+
const {
|
|
24040
|
+
hasAreaElement,
|
|
24041
|
+
hasListElement,
|
|
24042
|
+
hasStructuralElement,
|
|
24043
|
+
surroundElementList
|
|
24044
|
+
} = this._collectMainRenderMeta();
|
|
24045
|
+
const rowListPayload = {
|
|
23710
24046
|
startX,
|
|
23711
24047
|
startY,
|
|
23712
24048
|
pageHeight,
|
|
@@ -23714,12 +24050,41 @@ var Draw = class {
|
|
|
23714
24050
|
isPagingMode,
|
|
23715
24051
|
innerWidth: columnWidth,
|
|
23716
24052
|
surroundElementList,
|
|
24053
|
+
hasListElement,
|
|
23717
24054
|
elementList: this.elementList
|
|
23718
|
-
}
|
|
24055
|
+
};
|
|
24056
|
+
const canUseIncrementalMainRows = dirtyStartIndex !== void 0 && dirtyStartIndex >= 0 && !isInit && !isSourceHistory && isPagingMode && columnCount === 1 && !hasAreaElement && !hasStructuralElement && surroundElementList.length === 0 && oldRowList.length > 0 && oldPageRowList.length > 0;
|
|
24057
|
+
if (canUseIncrementalMainRows) {
|
|
24058
|
+
const restartState = this._getIncrementalRestartState(
|
|
24059
|
+
dirtyStartIndex,
|
|
24060
|
+
oldRowList,
|
|
24061
|
+
oldPageRowList,
|
|
24062
|
+
startY
|
|
24063
|
+
);
|
|
24064
|
+
if (restartState) {
|
|
24065
|
+
const suffixRows = this.computeRowList({
|
|
24066
|
+
...rowListPayload,
|
|
24067
|
+
fromIndex: restartState.fromIndex,
|
|
24068
|
+
initialY: restartState.initialY,
|
|
24069
|
+
initialPageNo: restartState.initialPageNo,
|
|
24070
|
+
initialRowIndex: restartState.initialRowIndex,
|
|
24071
|
+
initialListState: restartState.initialListState
|
|
24072
|
+
});
|
|
24073
|
+
this.rowList = restartState.prefixRows.concat(suffixRows);
|
|
24074
|
+
} else {
|
|
24075
|
+
this.rowList = this.computeRowList(rowListPayload);
|
|
24076
|
+
}
|
|
24077
|
+
} else {
|
|
24078
|
+
this.rowList = this.computeRowList(rowListPayload);
|
|
24079
|
+
}
|
|
23719
24080
|
this._applyRowSpacing();
|
|
23720
24081
|
this.pageRowList = this._computePageList();
|
|
23721
24082
|
this.position.computePositionList();
|
|
23722
|
-
|
|
24083
|
+
if (hasAreaElement) {
|
|
24084
|
+
this.area.compute();
|
|
24085
|
+
} else {
|
|
24086
|
+
this.area.clear();
|
|
24087
|
+
}
|
|
23723
24088
|
if (!this.isPrintMode()) {
|
|
23724
24089
|
const searchKeyword = this.search.getSearchKeyword();
|
|
23725
24090
|
if (searchKeyword) {
|
|
@@ -23743,10 +24108,26 @@ var Draw = class {
|
|
|
23743
24108
|
if (prePageCount > curPageCount) {
|
|
23744
24109
|
const deleteCount = prePageCount - curPageCount;
|
|
23745
24110
|
this.ctxList.splice(curPageCount, deleteCount);
|
|
24111
|
+
this.pageRenderVersionList.splice(curPageCount, deleteCount);
|
|
23746
24112
|
this.pageList.splice(curPageCount, deleteCount).forEach((page) => page.remove());
|
|
23747
24113
|
}
|
|
23748
24114
|
if (isLazy && isPagingMode) {
|
|
23749
|
-
this.
|
|
24115
|
+
let visiblePageNoList = this.visiblePageNoList.filter(
|
|
24116
|
+
(pageNo) => pageNo >= 0 && pageNo < curPageCount
|
|
24117
|
+
);
|
|
24118
|
+
let intersectionPageNo = Math.min(
|
|
24119
|
+
this.intersectionPageNo,
|
|
24120
|
+
Math.max(curPageCount - 1, 0)
|
|
24121
|
+
);
|
|
24122
|
+
if (!visiblePageNoList.length || oldPageSize !== curPageCount || intersectionPageNo >= curPageCount) {
|
|
24123
|
+
const visibleInfo = this.scrollObserver.getPageVisibleInfo();
|
|
24124
|
+
intersectionPageNo = visibleInfo.intersectionPageNo;
|
|
24125
|
+
visiblePageNoList = visibleInfo.visiblePageNoList;
|
|
24126
|
+
this.setIntersectionPageNo(intersectionPageNo);
|
|
24127
|
+
this.setVisiblePageNoList(visiblePageNoList);
|
|
24128
|
+
}
|
|
24129
|
+
const renderPageNoList = visiblePageNoList.length ? visiblePageNoList : [intersectionPageNo];
|
|
24130
|
+
this.renderVisiblePages(renderPageNoList);
|
|
23750
24131
|
} else {
|
|
23751
24132
|
this._immediateRender();
|
|
23752
24133
|
}
|
|
@@ -23795,7 +24176,9 @@ var Draw = class {
|
|
|
23795
24176
|
const positionContext = this.position.getPositionContext();
|
|
23796
24177
|
const positionList = this.position.getPositionList();
|
|
23797
24178
|
if (positionContext.isTable) {
|
|
23798
|
-
const tablePositionList = this.resolveTableCellContext(
|
|
24179
|
+
const tablePositionList = this.resolveTableCellContext(
|
|
24180
|
+
this.getOriginalElementList()
|
|
24181
|
+
)?.td.positionList;
|
|
23799
24182
|
if (curIndex === void 0 && tablePositionList) {
|
|
23800
24183
|
curIndex = tablePositionList.length - 1;
|
|
23801
24184
|
}
|
|
@@ -23822,36 +24205,51 @@ var Draw = class {
|
|
|
23822
24205
|
return curIndex;
|
|
23823
24206
|
}
|
|
23824
24207
|
submitHistory(curIndex, isInput = false) {
|
|
23825
|
-
const
|
|
23826
|
-
|
|
23827
|
-
|
|
23828
|
-
this.
|
|
23829
|
-
|
|
23830
|
-
|
|
23831
|
-
this.
|
|
23832
|
-
|
|
23833
|
-
|
|
23834
|
-
const
|
|
23835
|
-
|
|
23836
|
-
|
|
23837
|
-
|
|
23838
|
-
|
|
23839
|
-
|
|
23840
|
-
|
|
23841
|
-
|
|
23842
|
-
|
|
23843
|
-
|
|
23844
|
-
|
|
23845
|
-
|
|
23846
|
-
|
|
23847
|
-
|
|
23848
|
-
|
|
23849
|
-
|
|
24208
|
+
const snapshot = {
|
|
24209
|
+
elementList: getSlimCloneElementList(this.elementList),
|
|
24210
|
+
headerElementList: getSlimCloneElementList(this.header.getElementList()),
|
|
24211
|
+
footerElementList: getSlimCloneElementList(this.footer.getElementList()),
|
|
24212
|
+
range: deepClone(this.range.getRange()),
|
|
24213
|
+
pageNo: this.pageNo,
|
|
24214
|
+
positionContext: deepClone(this.position.getPositionContext()),
|
|
24215
|
+
zone: this.zone.getZone()
|
|
24216
|
+
};
|
|
24217
|
+
const entry = {
|
|
24218
|
+
restore: () => {
|
|
24219
|
+
const {
|
|
24220
|
+
elementList,
|
|
24221
|
+
headerElementList,
|
|
24222
|
+
footerElementList,
|
|
24223
|
+
range,
|
|
24224
|
+
pageNo,
|
|
24225
|
+
positionContext,
|
|
24226
|
+
zone
|
|
24227
|
+
} = snapshot;
|
|
24228
|
+
const restoredHeaderElementList = inflateElementList(
|
|
24229
|
+
deepClone(headerElementList)
|
|
24230
|
+
);
|
|
24231
|
+
const restoredFooterElementList = inflateElementList(
|
|
24232
|
+
deepClone(footerElementList)
|
|
24233
|
+
);
|
|
24234
|
+
const restoredMainElementList = inflateElementList(deepClone(elementList));
|
|
24235
|
+
this.zone.setZone(zone);
|
|
24236
|
+
this.setPageNo(pageNo);
|
|
24237
|
+
this.position.setPositionContext(deepClone(positionContext));
|
|
24238
|
+
this.header.setElementList(restoredHeaderElementList);
|
|
24239
|
+
this.footer.setElementList(restoredFooterElementList);
|
|
24240
|
+
this.elementList = restoredMainElementList;
|
|
24241
|
+
this.range.replaceRange(deepClone(range));
|
|
24242
|
+
this.render({
|
|
24243
|
+
curIndex,
|
|
24244
|
+
isSubmitHistory: false,
|
|
24245
|
+
isSourceHistory: true
|
|
24246
|
+
});
|
|
24247
|
+
}
|
|
23850
24248
|
};
|
|
23851
24249
|
if (isInput && this.historyManager.isInputGroupable()) {
|
|
23852
|
-
this.historyManager.replaceLatest(
|
|
24250
|
+
this.historyManager.replaceLatest(entry);
|
|
23853
24251
|
} else {
|
|
23854
|
-
this.historyManager.execute(
|
|
24252
|
+
this.historyManager.execute(entry);
|
|
23855
24253
|
}
|
|
23856
24254
|
if (isInput) {
|
|
23857
24255
|
this.historyManager.recordInputTime();
|
|
@@ -23946,6 +24344,8 @@ var Command = class {
|
|
|
23946
24344
|
this.executeSearchNavigateNext = adapt.searchNavigateNext.bind(adapt);
|
|
23947
24345
|
this.executeReplace = adapt.replace.bind(adapt);
|
|
23948
24346
|
this.executePrint = adapt.print.bind(adapt);
|
|
24347
|
+
this.executeExportDocx = adapt.exportDocx.bind(adapt);
|
|
24348
|
+
this.executeExportPdf = adapt.exportPdf.bind(adapt);
|
|
23949
24349
|
this.executeReplaceImageElement = adapt.replaceImageElement.bind(adapt);
|
|
23950
24350
|
this.executeSaveAsImageElement = adapt.saveAsImageElement.bind(adapt);
|
|
23951
24351
|
this.executeSetImageCrop = adapt.setImageCrop.bind(adapt);
|
|
@@ -24026,50 +24426,3159 @@ var Command = class {
|
|
|
24026
24426
|
}
|
|
24027
24427
|
};
|
|
24028
24428
|
|
|
24029
|
-
// src/utils/
|
|
24030
|
-
|
|
24031
|
-
|
|
24032
|
-
|
|
24033
|
-
|
|
24034
|
-
|
|
24035
|
-
|
|
24036
|
-
|
|
24037
|
-
|
|
24038
|
-
|
|
24039
|
-
|
|
24040
|
-
|
|
24041
|
-
|
|
24042
|
-
|
|
24043
|
-
|
|
24044
|
-
|
|
24045
|
-
|
|
24046
|
-
|
|
24047
|
-
|
|
24048
|
-
|
|
24049
|
-
|
|
24050
|
-
|
|
24051
|
-
|
|
24429
|
+
// src/utils/docx.ts
|
|
24430
|
+
var import_docx = require("docx");
|
|
24431
|
+
var DEFAULT_DOCX_FILE_NAME = "document.docx";
|
|
24432
|
+
var DEFAULT_IMAGE_WIDTH = 320;
|
|
24433
|
+
var DEFAULT_IMAGE_HEIGHT = 180;
|
|
24434
|
+
var DEFAULT_LINE_HEIGHT = 1.15;
|
|
24435
|
+
var docxBulletCharMap = {
|
|
24436
|
+
["disc" /* DISC */]: "\u2022",
|
|
24437
|
+
["circle" /* CIRCLE */]: "\u25E6",
|
|
24438
|
+
["square" /* SQUARE */]: "\u25A0",
|
|
24439
|
+
["checkbox" /* CHECKBOX */]: "\u2611"
|
|
24440
|
+
};
|
|
24441
|
+
var titleHeadingMap = {
|
|
24442
|
+
["first" /* FIRST */]: import_docx.HeadingLevel.HEADING_1,
|
|
24443
|
+
["second" /* SECOND */]: import_docx.HeadingLevel.HEADING_2,
|
|
24444
|
+
["third" /* THIRD */]: import_docx.HeadingLevel.HEADING_3,
|
|
24445
|
+
["fourth" /* FOURTH */]: import_docx.HeadingLevel.HEADING_4,
|
|
24446
|
+
["fifth" /* FIFTH */]: import_docx.HeadingLevel.HEADING_5,
|
|
24447
|
+
["sixth" /* SIXTH */]: import_docx.HeadingLevel.HEADING_6
|
|
24448
|
+
};
|
|
24449
|
+
var orderedStyleFormatMap = {
|
|
24450
|
+
["decimal" /* DECIMAL */]: import_docx.LevelFormat.DECIMAL,
|
|
24451
|
+
["lowerAlpha" /* LOWER_ALPHA */]: import_docx.LevelFormat.LOWER_LETTER,
|
|
24452
|
+
["upperAlpha" /* UPPER_ALPHA */]: import_docx.LevelFormat.UPPER_LETTER,
|
|
24453
|
+
["lowerRoman" /* LOWER_ROMAN */]: import_docx.LevelFormat.LOWER_ROMAN,
|
|
24454
|
+
["upperRoman" /* UPPER_ROMAN */]: import_docx.LevelFormat.UPPER_ROMAN,
|
|
24455
|
+
["decimalParen" /* DECIMAL_PAREN */]: import_docx.LevelFormat.DECIMAL,
|
|
24456
|
+
decimalZero: import_docx.LevelFormat.DECIMAL_ZERO,
|
|
24457
|
+
lowerAlphaParen: import_docx.LevelFormat.LOWER_LETTER,
|
|
24458
|
+
lowerRomanParen: import_docx.LevelFormat.LOWER_ROMAN,
|
|
24459
|
+
outline: import_docx.LevelFormat.DECIMAL
|
|
24460
|
+
};
|
|
24461
|
+
async function exportEditorDataToDocx(payload, options = {}) {
|
|
24462
|
+
const fileName = normalizeDocxFileName(options.fileName);
|
|
24463
|
+
const file = await createDocxDocument(payload);
|
|
24464
|
+
const blob = await import_docx.Packer.toBlob(file);
|
|
24052
24465
|
return {
|
|
24053
|
-
|
|
24054
|
-
|
|
24055
|
-
height: `${height}px`
|
|
24466
|
+
blob,
|
|
24467
|
+
fileName
|
|
24056
24468
|
};
|
|
24057
24469
|
}
|
|
24058
|
-
function
|
|
24059
|
-
const {
|
|
24060
|
-
const
|
|
24061
|
-
|
|
24062
|
-
|
|
24063
|
-
|
|
24064
|
-
|
|
24065
|
-
|
|
24066
|
-
|
|
24067
|
-
|
|
24068
|
-
|
|
24069
|
-
|
|
24070
|
-
const
|
|
24071
|
-
|
|
24072
|
-
|
|
24470
|
+
async function createDocxDocument(payload) {
|
|
24471
|
+
const { data: data2, options } = payload;
|
|
24472
|
+
const editorOptions = options;
|
|
24473
|
+
const context = createSerializeContext();
|
|
24474
|
+
const headerChildren = editorOptions.header.disabled ? [] : await serializeElementList(data2.header || [], editorOptions, context);
|
|
24475
|
+
const footerChildren = editorOptions.footer.disabled ? [] : await serializeElementList(data2.footer || [], editorOptions, context);
|
|
24476
|
+
const pageNumberParagraph = createPageNumberParagraph(
|
|
24477
|
+
editorOptions.pageNumber
|
|
24478
|
+
);
|
|
24479
|
+
if (pageNumberParagraph) {
|
|
24480
|
+
footerChildren.push(pageNumberParagraph);
|
|
24481
|
+
}
|
|
24482
|
+
const sectionChildren = await serializeElementList(
|
|
24483
|
+
data2.main,
|
|
24484
|
+
editorOptions,
|
|
24485
|
+
context
|
|
24486
|
+
);
|
|
24487
|
+
const { width, height, paperDirection } = editorOptions;
|
|
24488
|
+
const pageWidth = paperDirection === "horizontal" /* HORIZONTAL */ ? height : width;
|
|
24489
|
+
const pageHeight = paperDirection === "horizontal" /* HORIZONTAL */ ? width : height;
|
|
24490
|
+
return new import_docx.Document({
|
|
24491
|
+
features: {
|
|
24492
|
+
updateFields: true
|
|
24493
|
+
},
|
|
24494
|
+
numbering: {
|
|
24495
|
+
config: createNumberingConfig()
|
|
24496
|
+
},
|
|
24497
|
+
sections: [
|
|
24498
|
+
{
|
|
24499
|
+
properties: {
|
|
24500
|
+
page: {
|
|
24501
|
+
size: {
|
|
24502
|
+
width: pxToTwips(pageWidth),
|
|
24503
|
+
height: pxToTwips(pageHeight),
|
|
24504
|
+
orientation: paperDirection === "horizontal" /* HORIZONTAL */ ? import_docx.PageOrientation.LANDSCAPE : import_docx.PageOrientation.PORTRAIT
|
|
24505
|
+
},
|
|
24506
|
+
margin: {
|
|
24507
|
+
top: pxToTwips(editorOptions.margins[0]),
|
|
24508
|
+
right: pxToTwips(editorOptions.margins[1]),
|
|
24509
|
+
bottom: pxToTwips(editorOptions.margins[2]),
|
|
24510
|
+
left: pxToTwips(editorOptions.margins[3]),
|
|
24511
|
+
header: pxToTwips(editorOptions.header.top),
|
|
24512
|
+
footer: pxToTwips(editorOptions.footer.bottom)
|
|
24513
|
+
},
|
|
24514
|
+
pageNumbers: !editorOptions.pageNumber.disabled && editorOptions.pageNumber.fromPageNo === 0 ? {
|
|
24515
|
+
start: editorOptions.pageNumber.startPageNo
|
|
24516
|
+
} : void 0
|
|
24517
|
+
}
|
|
24518
|
+
},
|
|
24519
|
+
headers: headerChildren.length > 0 ? {
|
|
24520
|
+
default: new import_docx.Header({
|
|
24521
|
+
children: headerChildren
|
|
24522
|
+
})
|
|
24523
|
+
} : void 0,
|
|
24524
|
+
footers: footerChildren.length > 0 ? {
|
|
24525
|
+
default: new import_docx.Footer({
|
|
24526
|
+
children: footerChildren
|
|
24527
|
+
})
|
|
24528
|
+
} : void 0,
|
|
24529
|
+
children: sectionChildren.length ? sectionChildren : [new import_docx.Paragraph({})]
|
|
24530
|
+
}
|
|
24531
|
+
]
|
|
24532
|
+
});
|
|
24533
|
+
}
|
|
24534
|
+
async function serializeElementList(elementList, options, context) {
|
|
24535
|
+
const blocks = [];
|
|
24536
|
+
let inlineBuffer = [];
|
|
24537
|
+
const flushInlineBuffer = async () => {
|
|
24538
|
+
if (!inlineBuffer.length) return;
|
|
24539
|
+
blocks.push(
|
|
24540
|
+
...await serializeInlineElements(inlineBuffer, options, context)
|
|
24541
|
+
);
|
|
24542
|
+
inlineBuffer = [];
|
|
24543
|
+
};
|
|
24544
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
24545
|
+
const element = elementList[i];
|
|
24546
|
+
if (element.type === "area" /* AREA */ && element.valueList?.length) {
|
|
24547
|
+
await flushInlineBuffer();
|
|
24548
|
+
blocks.push(
|
|
24549
|
+
...await serializeElementList(element.valueList, options, context)
|
|
24550
|
+
);
|
|
24551
|
+
continue;
|
|
24552
|
+
}
|
|
24553
|
+
if (element.type === "title" /* TITLE */ && element.valueList?.length) {
|
|
24554
|
+
await flushInlineBuffer();
|
|
24555
|
+
blocks.push(
|
|
24556
|
+
...await serializeInlineElements(element.valueList, options, context, {
|
|
24557
|
+
heading: titleHeadingMap[element.level || "first" /* FIRST */]
|
|
24558
|
+
})
|
|
24559
|
+
);
|
|
24560
|
+
continue;
|
|
24561
|
+
}
|
|
24562
|
+
if (element.type === "list" /* LIST */ && element.valueList?.length) {
|
|
24563
|
+
await flushInlineBuffer();
|
|
24564
|
+
blocks.push(...await serializeListElement(element, options, context));
|
|
24565
|
+
continue;
|
|
24566
|
+
}
|
|
24567
|
+
if (element.type === "table" /* TABLE */ && element.trList?.length) {
|
|
24568
|
+
await flushInlineBuffer();
|
|
24569
|
+
blocks.push(await serializeTableElement(element, options, context));
|
|
24570
|
+
continue;
|
|
24571
|
+
}
|
|
24572
|
+
if (element.type === "pageBreak" /* PAGE_BREAK */) {
|
|
24573
|
+
await flushInlineBuffer();
|
|
24574
|
+
blocks.push(
|
|
24575
|
+
new import_docx.Paragraph({
|
|
24576
|
+
children: [new import_docx.PageBreak()]
|
|
24577
|
+
})
|
|
24578
|
+
);
|
|
24579
|
+
continue;
|
|
24580
|
+
}
|
|
24581
|
+
if (element.type === "separator" /* SEPARATOR */) {
|
|
24582
|
+
await flushInlineBuffer();
|
|
24583
|
+
blocks.push(
|
|
24584
|
+
new import_docx.Paragraph({
|
|
24585
|
+
thematicBreak: true
|
|
24586
|
+
})
|
|
24587
|
+
);
|
|
24588
|
+
continue;
|
|
24589
|
+
}
|
|
24590
|
+
if (element.type === "image" /* IMAGE */ && element.imgDisplay && element.imgDisplay !== "inline") {
|
|
24591
|
+
await flushInlineBuffer();
|
|
24592
|
+
blocks.push(...await serializeInlineElements([element], options));
|
|
24593
|
+
continue;
|
|
24594
|
+
}
|
|
24595
|
+
if (element.type === "block" /* BLOCK */) {
|
|
24596
|
+
await flushInlineBuffer();
|
|
24597
|
+
const blockText = getBlockFallbackText(element);
|
|
24598
|
+
if (blockText) {
|
|
24599
|
+
blocks.push(
|
|
24600
|
+
...await serializeInlineElements(
|
|
24601
|
+
[{ value: blockText }],
|
|
24602
|
+
options,
|
|
24603
|
+
context
|
|
24604
|
+
)
|
|
24605
|
+
);
|
|
24606
|
+
}
|
|
24607
|
+
continue;
|
|
24608
|
+
}
|
|
24609
|
+
inlineBuffer.push(element);
|
|
24610
|
+
}
|
|
24611
|
+
await flushInlineBuffer();
|
|
24612
|
+
return blocks;
|
|
24613
|
+
}
|
|
24614
|
+
async function serializeInlineElements(elementList, options, _context, overrides = {}) {
|
|
24615
|
+
const paragraphs = [];
|
|
24616
|
+
let current = null;
|
|
24617
|
+
const getParagraphContext = (element) => ({
|
|
24618
|
+
heading: overrides.heading,
|
|
24619
|
+
numbering: overrides.numbering,
|
|
24620
|
+
alignment: overrides.alignment !== void 0 ? overrides.alignment : mapRowFlexToAlignment(element?.rowFlex),
|
|
24621
|
+
rowMargin: overrides.rowMargin !== void 0 ? overrides.rowMargin : element?.rowMargin
|
|
24622
|
+
});
|
|
24623
|
+
const flushParagraph = (context) => {
|
|
24624
|
+
if (!current) {
|
|
24625
|
+
if (!context) return;
|
|
24626
|
+
paragraphs.push(createParagraph([], context, options.defaultRowMargin));
|
|
24627
|
+
return;
|
|
24628
|
+
}
|
|
24629
|
+
paragraphs.push(
|
|
24630
|
+
createParagraph(
|
|
24631
|
+
current.children,
|
|
24632
|
+
current.context,
|
|
24633
|
+
options.defaultRowMargin
|
|
24634
|
+
)
|
|
24635
|
+
);
|
|
24636
|
+
current = null;
|
|
24637
|
+
};
|
|
24638
|
+
const ensureParagraph = (element) => {
|
|
24639
|
+
if (!current) {
|
|
24640
|
+
current = {
|
|
24641
|
+
children: [],
|
|
24642
|
+
context: getParagraphContext(element)
|
|
24643
|
+
};
|
|
24644
|
+
}
|
|
24645
|
+
return current;
|
|
24646
|
+
};
|
|
24647
|
+
const appendText = (element, text, childFactory, preserveTrailingBreak = false) => {
|
|
24648
|
+
const normalized = normalizeText(text);
|
|
24649
|
+
const parts = normalized.split("\n");
|
|
24650
|
+
let lastSeparatorFlushedContent = false;
|
|
24651
|
+
for (let i = 0; i < parts.length; i++) {
|
|
24652
|
+
const segment = parts[i];
|
|
24653
|
+
if (segment) {
|
|
24654
|
+
ensureParagraph(element).children.push(childFactory(segment));
|
|
24655
|
+
}
|
|
24656
|
+
if (i < parts.length - 1) {
|
|
24657
|
+
if (!current) {
|
|
24658
|
+
paragraphs.push(
|
|
24659
|
+
createParagraph(
|
|
24660
|
+
[],
|
|
24661
|
+
getParagraphContext(element),
|
|
24662
|
+
options.defaultRowMargin
|
|
24663
|
+
)
|
|
24664
|
+
);
|
|
24665
|
+
lastSeparatorFlushedContent = false;
|
|
24666
|
+
} else {
|
|
24667
|
+
flushParagraph();
|
|
24668
|
+
lastSeparatorFlushedContent = true;
|
|
24669
|
+
}
|
|
24670
|
+
}
|
|
24671
|
+
}
|
|
24672
|
+
if (preserveTrailingBreak && normalized.endsWith("\n") && lastSeparatorFlushedContent) {
|
|
24673
|
+
paragraphs.push(
|
|
24674
|
+
createParagraph(
|
|
24675
|
+
[],
|
|
24676
|
+
getParagraphContext(element),
|
|
24677
|
+
options.defaultRowMargin
|
|
24678
|
+
)
|
|
24679
|
+
);
|
|
24680
|
+
}
|
|
24681
|
+
};
|
|
24682
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
24683
|
+
const element = elementList[i];
|
|
24684
|
+
if (element.type === "hyperlink" /* HYPERLINK */ && element.valueList?.length) {
|
|
24685
|
+
const hyperlink = await createHyperlinkChild(element, options);
|
|
24686
|
+
if (hyperlink) {
|
|
24687
|
+
ensureParagraph(element).children.push(hyperlink);
|
|
24688
|
+
}
|
|
24689
|
+
continue;
|
|
24690
|
+
}
|
|
24691
|
+
if (element.type === "image" /* IMAGE */) {
|
|
24692
|
+
const imageChild = await createImageChild(element);
|
|
24693
|
+
if (!imageChild) {
|
|
24694
|
+
appendText(
|
|
24695
|
+
element,
|
|
24696
|
+
"[Image unavailable]",
|
|
24697
|
+
(segment) => createTextRun(
|
|
24698
|
+
segment,
|
|
24699
|
+
element,
|
|
24700
|
+
options.defaultSize,
|
|
24701
|
+
options.defaultFont
|
|
24702
|
+
),
|
|
24703
|
+
i === elementList.length - 1
|
|
24704
|
+
);
|
|
24705
|
+
continue;
|
|
24706
|
+
}
|
|
24707
|
+
ensureParagraph(element).children.push(imageChild);
|
|
24708
|
+
continue;
|
|
24709
|
+
}
|
|
24710
|
+
if (element.type === "columnBreak" /* COLUMN_BREAK */) {
|
|
24711
|
+
ensureParagraph(element).children.push(new import_docx.ColumnBreak());
|
|
24712
|
+
continue;
|
|
24713
|
+
}
|
|
24714
|
+
if (element.type === "tab" /* TAB */) {
|
|
24715
|
+
appendText(
|
|
24716
|
+
element,
|
|
24717
|
+
" ",
|
|
24718
|
+
(segment) => createTextRun(
|
|
24719
|
+
segment,
|
|
24720
|
+
element,
|
|
24721
|
+
options.defaultSize,
|
|
24722
|
+
options.defaultFont
|
|
24723
|
+
),
|
|
24724
|
+
i === elementList.length - 1
|
|
24725
|
+
);
|
|
24726
|
+
continue;
|
|
24727
|
+
}
|
|
24728
|
+
const textValue = getInlineElementText(element);
|
|
24729
|
+
if (!textValue) {
|
|
24730
|
+
continue;
|
|
24731
|
+
}
|
|
24732
|
+
appendText(
|
|
24733
|
+
element,
|
|
24734
|
+
textValue,
|
|
24735
|
+
(segment) => createTextRun(
|
|
24736
|
+
segment,
|
|
24737
|
+
element,
|
|
24738
|
+
options.defaultSize,
|
|
24739
|
+
options.defaultFont
|
|
24740
|
+
),
|
|
24741
|
+
i === elementList.length - 1
|
|
24742
|
+
);
|
|
24743
|
+
}
|
|
24744
|
+
if (current) {
|
|
24745
|
+
flushParagraph();
|
|
24746
|
+
}
|
|
24747
|
+
return paragraphs.length ? paragraphs : [createParagraph([], overrides, options.defaultRowMargin)];
|
|
24748
|
+
}
|
|
24749
|
+
async function serializeListElement(element, options, context) {
|
|
24750
|
+
const zipList = zipElementList(element.valueList || []);
|
|
24751
|
+
const listItemMap = splitListElement(zipList);
|
|
24752
|
+
const paragraphs = [];
|
|
24753
|
+
const listInstance = createListInstance(context);
|
|
24754
|
+
for (const listItemElements of listItemMap.values()) {
|
|
24755
|
+
const numbering = getListNumbering(
|
|
24756
|
+
getListItemNumberingElement(listItemElements, element),
|
|
24757
|
+
listInstance
|
|
24758
|
+
);
|
|
24759
|
+
paragraphs.push(
|
|
24760
|
+
...await serializeInlineElements(listItemElements, options, context, {
|
|
24761
|
+
numbering
|
|
24762
|
+
})
|
|
24763
|
+
);
|
|
24764
|
+
}
|
|
24765
|
+
return paragraphs;
|
|
24766
|
+
}
|
|
24767
|
+
async function serializeTableElement(element, options, context) {
|
|
24768
|
+
const rows = [];
|
|
24769
|
+
const trList = element.trList || [];
|
|
24770
|
+
const tableContext = createTableSerializeContext(element);
|
|
24771
|
+
for (let i = 0; i < trList.length; i++) {
|
|
24772
|
+
rows.push(
|
|
24773
|
+
await serializeTableRow(trList[i], options, context, tableContext)
|
|
24774
|
+
);
|
|
24775
|
+
}
|
|
24776
|
+
const tableWidth = getTableWidthFromColgroup(element.colgroup);
|
|
24777
|
+
return new import_docx.Table({
|
|
24778
|
+
rows,
|
|
24779
|
+
width: tableWidth ? {
|
|
24780
|
+
size: pxToTwips(tableWidth),
|
|
24781
|
+
type: import_docx.WidthType.DXA
|
|
24782
|
+
} : {
|
|
24783
|
+
size: 100,
|
|
24784
|
+
type: import_docx.WidthType.PERCENTAGE
|
|
24785
|
+
},
|
|
24786
|
+
columnWidths: element.colgroup?.map((col) => pxToTwips(col.width)),
|
|
24787
|
+
layout: import_docx.TableLayoutType.FIXED,
|
|
24788
|
+
borders: createTableBorders(element)
|
|
24789
|
+
});
|
|
24790
|
+
}
|
|
24791
|
+
async function serializeTableRow(tr, options, context, tableContext) {
|
|
24792
|
+
const children = [];
|
|
24793
|
+
for (let i = 0; i < tr.tdList.length; i++) {
|
|
24794
|
+
children.push(
|
|
24795
|
+
await serializeTableCell(tr.tdList[i], options, context, tableContext)
|
|
24796
|
+
);
|
|
24797
|
+
}
|
|
24798
|
+
return new import_docx.TableRow({
|
|
24799
|
+
children
|
|
24800
|
+
});
|
|
24801
|
+
}
|
|
24802
|
+
async function serializeTableCell(td, options, context, tableContext) {
|
|
24803
|
+
const children = await serializeElementList(td.value, options, context);
|
|
24804
|
+
const shadingFill = td.backgroundColor ? normalizeHexColor(td.backgroundColor) : void 0;
|
|
24805
|
+
const cellWidth = tableContext.cellLayoutMap.get(td)?.width || td.width;
|
|
24806
|
+
return new import_docx.TableCell({
|
|
24807
|
+
children: children.length ? children : [new import_docx.Paragraph({})],
|
|
24808
|
+
columnSpan: td.colspan > 1 ? td.colspan : void 0,
|
|
24809
|
+
rowSpan: td.rowspan > 1 ? td.rowspan : void 0,
|
|
24810
|
+
verticalAlign: mapCellVerticalAlign(td.verticalAlign),
|
|
24811
|
+
width: cellWidth ? {
|
|
24812
|
+
size: pxToTwips(cellWidth),
|
|
24813
|
+
type: import_docx.WidthType.DXA
|
|
24814
|
+
} : void 0,
|
|
24815
|
+
shading: shadingFill ? {
|
|
24816
|
+
fill: shadingFill,
|
|
24817
|
+
type: import_docx.ShadingType.CLEAR
|
|
24818
|
+
} : void 0,
|
|
24819
|
+
margins: mapPaddingToTableMargins(td.padding),
|
|
24820
|
+
borders: createTableCellBorders(
|
|
24821
|
+
td,
|
|
24822
|
+
tableContext.borderColor,
|
|
24823
|
+
tableContext.borderWidth
|
|
24824
|
+
)
|
|
24825
|
+
});
|
|
24826
|
+
}
|
|
24827
|
+
function createParagraph(children, context, defaultRowMargin) {
|
|
24828
|
+
return new import_docx.Paragraph({
|
|
24829
|
+
children,
|
|
24830
|
+
heading: context.heading,
|
|
24831
|
+
numbering: context.numbering,
|
|
24832
|
+
alignment: context.alignment,
|
|
24833
|
+
spacing: {
|
|
24834
|
+
line: Math.round(
|
|
24835
|
+
240 * (context.rowMargin || defaultRowMargin || DEFAULT_LINE_HEIGHT)
|
|
24836
|
+
),
|
|
24837
|
+
lineRule: import_docx.LineRuleType.AUTO
|
|
24838
|
+
}
|
|
24839
|
+
});
|
|
24840
|
+
}
|
|
24841
|
+
function createTextRun(text, element, defaultSize, defaultFont) {
|
|
24842
|
+
const color = element.color ? normalizeHexColor(element.color, "000000") : void 0;
|
|
24843
|
+
const highlightFill = element.highlight ? normalizeHexColor(element.highlight) : void 0;
|
|
24844
|
+
return new import_docx.TextRun({
|
|
24845
|
+
text,
|
|
24846
|
+
bold: !!element.bold,
|
|
24847
|
+
italics: !!element.italic,
|
|
24848
|
+
strike: !!element.strikeout,
|
|
24849
|
+
subScript: element.type === "subscript" /* SUBSCRIPT */,
|
|
24850
|
+
superScript: element.type === "superscript" /* SUPERSCRIPT */,
|
|
24851
|
+
color,
|
|
24852
|
+
shading: highlightFill ? {
|
|
24853
|
+
fill: highlightFill,
|
|
24854
|
+
type: import_docx.ShadingType.CLEAR
|
|
24855
|
+
} : void 0,
|
|
24856
|
+
underline: element.underline ? {
|
|
24857
|
+
type: mapUnderlineType(element.textDecoration?.style)
|
|
24858
|
+
} : void 0,
|
|
24859
|
+
font: element.font || defaultFont,
|
|
24860
|
+
size: Math.round((element.size || defaultSize) * 2)
|
|
24861
|
+
});
|
|
24862
|
+
}
|
|
24863
|
+
async function createHyperlinkChild(element, options) {
|
|
24864
|
+
if (!element.url) {
|
|
24865
|
+
const fallbackText = getTextFromElementList(element.valueList || []);
|
|
24866
|
+
return fallbackText ? createTextRun(
|
|
24867
|
+
fallbackText,
|
|
24868
|
+
element.valueList?.[0] || element,
|
|
24869
|
+
options.defaultSize,
|
|
24870
|
+
options.defaultFont
|
|
24871
|
+
) : null;
|
|
24872
|
+
}
|
|
24873
|
+
const children = await createHyperlinkRuns(
|
|
24874
|
+
element.valueList || [],
|
|
24875
|
+
options.defaultSize,
|
|
24876
|
+
options.defaultFont
|
|
24877
|
+
);
|
|
24878
|
+
if (!children.length) {
|
|
24879
|
+
return null;
|
|
24880
|
+
}
|
|
24881
|
+
return new import_docx.ExternalHyperlink({
|
|
24882
|
+
link: element.url,
|
|
24883
|
+
children
|
|
24884
|
+
});
|
|
24885
|
+
}
|
|
24886
|
+
async function createHyperlinkRuns(valueList, defaultSize, defaultFont) {
|
|
24887
|
+
const children = [];
|
|
24888
|
+
for (let i = 0; i < valueList.length; i++) {
|
|
24889
|
+
const element = valueList[i];
|
|
24890
|
+
if (element.type === "tab" /* TAB */) {
|
|
24891
|
+
children.push(createTextRun(" ", element, defaultSize, defaultFont));
|
|
24892
|
+
continue;
|
|
24893
|
+
}
|
|
24894
|
+
const text = normalizeText(getInlineElementText(element)).replace(
|
|
24895
|
+
/\n/g,
|
|
24896
|
+
" "
|
|
24897
|
+
);
|
|
24898
|
+
if (text) {
|
|
24899
|
+
children.push(createTextRun(text, element, defaultSize, defaultFont));
|
|
24900
|
+
}
|
|
24901
|
+
}
|
|
24902
|
+
return children;
|
|
24903
|
+
}
|
|
24904
|
+
async function createImageChild(element) {
|
|
24905
|
+
try {
|
|
24906
|
+
const image = await loadImagePayload(element.value);
|
|
24907
|
+
const width = Math.max(1, Math.round(element.width || DEFAULT_IMAGE_WIDTH));
|
|
24908
|
+
const height = Math.max(
|
|
24909
|
+
1,
|
|
24910
|
+
Math.round(element.height || DEFAULT_IMAGE_HEIGHT)
|
|
24911
|
+
);
|
|
24912
|
+
if (image.type === "svg" && image.fallbackPng) {
|
|
24913
|
+
return new import_docx.ImageRun({
|
|
24914
|
+
type: "svg",
|
|
24915
|
+
data: image.data,
|
|
24916
|
+
fallback: {
|
|
24917
|
+
type: "png",
|
|
24918
|
+
data: image.fallbackPng
|
|
24919
|
+
},
|
|
24920
|
+
transformation: {
|
|
24921
|
+
width,
|
|
24922
|
+
height
|
|
24923
|
+
}
|
|
24924
|
+
});
|
|
24925
|
+
}
|
|
24926
|
+
return new import_docx.ImageRun({
|
|
24927
|
+
type: image.type,
|
|
24928
|
+
data: image.data,
|
|
24929
|
+
transformation: {
|
|
24930
|
+
width,
|
|
24931
|
+
height
|
|
24932
|
+
}
|
|
24933
|
+
});
|
|
24934
|
+
} catch {
|
|
24935
|
+
return null;
|
|
24936
|
+
}
|
|
24937
|
+
}
|
|
24938
|
+
async function loadImagePayload(src) {
|
|
24939
|
+
const source = src.trim();
|
|
24940
|
+
if (source.startsWith("data:")) {
|
|
24941
|
+
return getImagePayloadFromDataUrl(source);
|
|
24942
|
+
}
|
|
24943
|
+
const response = await fetch(source);
|
|
24944
|
+
if (!response.ok) {
|
|
24945
|
+
throw new Error(`Image request failed: ${response.status}`);
|
|
24946
|
+
}
|
|
24947
|
+
const contentType = response.headers.get("content-type") || "";
|
|
24948
|
+
const data2 = await response.arrayBuffer();
|
|
24949
|
+
return normalizeImagePayload(data2, contentType);
|
|
24950
|
+
}
|
|
24951
|
+
async function getImagePayloadFromDataUrl(src) {
|
|
24952
|
+
const [, meta = "", encoded = ""] = src.match(/^data:([^,]*),(.*)$/) || [];
|
|
24953
|
+
const mime = meta.split(";")[0] || "";
|
|
24954
|
+
const isBase64 = meta.includes(";base64");
|
|
24955
|
+
const text = isBase64 ? atob(encoded) : decodeURIComponent(encoded);
|
|
24956
|
+
const bytes = new Uint8Array(text.length);
|
|
24957
|
+
for (let i = 0; i < text.length; i++) {
|
|
24958
|
+
bytes[i] = text.charCodeAt(i);
|
|
24959
|
+
}
|
|
24960
|
+
return normalizeImagePayload(bytes.buffer, mime);
|
|
24961
|
+
}
|
|
24962
|
+
async function normalizeImagePayload(data2, mime) {
|
|
24963
|
+
const type = getRegularImageType(mime);
|
|
24964
|
+
if (type) {
|
|
24965
|
+
return {
|
|
24966
|
+
type,
|
|
24967
|
+
data: data2
|
|
24968
|
+
};
|
|
24969
|
+
}
|
|
24970
|
+
if (mime.includes("svg")) {
|
|
24971
|
+
return {
|
|
24972
|
+
type: "svg",
|
|
24973
|
+
data: data2,
|
|
24974
|
+
fallbackPng: await rasterizeSvgToPng(data2)
|
|
24975
|
+
};
|
|
24976
|
+
}
|
|
24977
|
+
const fallbackPng = await rasterizeImageToPng(data2, mime);
|
|
24978
|
+
return {
|
|
24979
|
+
type: "png",
|
|
24980
|
+
data: fallbackPng
|
|
24981
|
+
};
|
|
24982
|
+
}
|
|
24983
|
+
async function rasterizeSvgToPng(data2) {
|
|
24984
|
+
return rasterizeImageToPng(data2, "image/svg+xml");
|
|
24985
|
+
}
|
|
24986
|
+
async function rasterizeImageToPng(data2, mime) {
|
|
24987
|
+
const blob = new Blob([data2], {
|
|
24988
|
+
type: mime || "image/png"
|
|
24989
|
+
});
|
|
24990
|
+
const url = URL.createObjectURL(blob);
|
|
24991
|
+
try {
|
|
24992
|
+
const image = await loadHtmlImage(url);
|
|
24993
|
+
const canvas = document.createElement("canvas");
|
|
24994
|
+
canvas.width = image.naturalWidth || DEFAULT_IMAGE_WIDTH;
|
|
24995
|
+
canvas.height = image.naturalHeight || DEFAULT_IMAGE_HEIGHT;
|
|
24996
|
+
const context = canvas.getContext("2d");
|
|
24997
|
+
if (!context) {
|
|
24998
|
+
throw new Error("Canvas context is unavailable");
|
|
24999
|
+
}
|
|
25000
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
25001
|
+
const pngBlob = await new Promise((resolve, reject) => {
|
|
25002
|
+
canvas.toBlob((output) => {
|
|
25003
|
+
if (output) {
|
|
25004
|
+
resolve(output);
|
|
25005
|
+
} else {
|
|
25006
|
+
reject(new Error("Failed to create PNG blob"));
|
|
25007
|
+
}
|
|
25008
|
+
}, "image/png");
|
|
25009
|
+
});
|
|
25010
|
+
return await pngBlob.arrayBuffer();
|
|
25011
|
+
} finally {
|
|
25012
|
+
URL.revokeObjectURL(url);
|
|
25013
|
+
}
|
|
25014
|
+
}
|
|
25015
|
+
function loadHtmlImage(src) {
|
|
25016
|
+
return new Promise((resolve, reject) => {
|
|
25017
|
+
const image = new Image();
|
|
25018
|
+
image.onload = () => resolve(image);
|
|
25019
|
+
image.onerror = () => reject(new Error("Failed to load image"));
|
|
25020
|
+
image.src = src;
|
|
25021
|
+
});
|
|
25022
|
+
}
|
|
25023
|
+
function createPageNumberParagraph(pageNumber) {
|
|
25024
|
+
if (pageNumber.disabled || pageNumber.fromPageNo > 0) {
|
|
25025
|
+
return null;
|
|
25026
|
+
}
|
|
25027
|
+
const children = [];
|
|
25028
|
+
const format = pageNumber.format || FORMAT_PLACEHOLDER.PAGE_NO;
|
|
25029
|
+
const tokens = format.split(/(\{pageNo\}|\{pageCount\})/);
|
|
25030
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
25031
|
+
const token = tokens[i];
|
|
25032
|
+
if (!token) continue;
|
|
25033
|
+
const runChildren = token === FORMAT_PLACEHOLDER.PAGE_NO ? [import_docx.PageNumber.CURRENT] : token === FORMAT_PLACEHOLDER.PAGE_COUNT ? [import_docx.PageNumber.TOTAL_PAGES] : void 0;
|
|
25034
|
+
children.push(
|
|
25035
|
+
new import_docx.TextRun({
|
|
25036
|
+
text: runChildren ? void 0 : token,
|
|
25037
|
+
children: runChildren,
|
|
25038
|
+
color: normalizeHexColor(pageNumber.color || "#000000", "000000"),
|
|
25039
|
+
font: pageNumber.font,
|
|
25040
|
+
size: Math.round((pageNumber.size || 12) * 2)
|
|
25041
|
+
})
|
|
25042
|
+
);
|
|
25043
|
+
}
|
|
25044
|
+
return new import_docx.Paragraph({
|
|
25045
|
+
children,
|
|
25046
|
+
alignment: mapRowFlexToAlignment(pageNumber.rowFlex)
|
|
25047
|
+
});
|
|
25048
|
+
}
|
|
25049
|
+
function createNumberingConfig() {
|
|
25050
|
+
const config = [
|
|
25051
|
+
createOrderedReference("windoc-ol-decimal", Array(9).fill("decimal" /* DECIMAL */)),
|
|
25052
|
+
createOrderedReference(
|
|
25053
|
+
"windoc-ol-lower-alpha",
|
|
25054
|
+
Array(9).fill("lowerAlpha" /* LOWER_ALPHA */)
|
|
25055
|
+
),
|
|
25056
|
+
createOrderedReference(
|
|
25057
|
+
"windoc-ol-upper-alpha",
|
|
25058
|
+
Array(9).fill("upperAlpha" /* UPPER_ALPHA */)
|
|
25059
|
+
),
|
|
25060
|
+
createOrderedReference(
|
|
25061
|
+
"windoc-ol-lower-roman",
|
|
25062
|
+
Array(9).fill("lowerRoman" /* LOWER_ROMAN */)
|
|
25063
|
+
),
|
|
25064
|
+
createOrderedReference(
|
|
25065
|
+
"windoc-ol-upper-roman",
|
|
25066
|
+
Array(9).fill("upperRoman" /* UPPER_ROMAN */)
|
|
25067
|
+
),
|
|
25068
|
+
createOrderedReference(
|
|
25069
|
+
"windoc-ol-decimal-paren",
|
|
25070
|
+
Array(9).fill("decimalParen" /* DECIMAL_PAREN */)
|
|
25071
|
+
),
|
|
25072
|
+
createOrderedReference(
|
|
25073
|
+
`windoc-ol-${"olDefault" /* DEFAULT */}`,
|
|
25074
|
+
createCycleList(olPresetCycles["olDefault" /* DEFAULT */], 9)
|
|
25075
|
+
),
|
|
25076
|
+
createOrderedReference(
|
|
25077
|
+
`windoc-ol-${"olParen" /* PARENTHESIS */}`,
|
|
25078
|
+
createCycleList(olPresetCycles["olParen" /* PARENTHESIS */], 9)
|
|
25079
|
+
),
|
|
25080
|
+
createOrderedReference(
|
|
25081
|
+
`windoc-ol-${"olOutline" /* OUTLINE */}`,
|
|
25082
|
+
createCycleList(olPresetCycles["olOutline" /* OUTLINE */], 9)
|
|
25083
|
+
),
|
|
25084
|
+
createOrderedReference(
|
|
25085
|
+
`windoc-ol-${"olUpperA" /* UPPER_ALPHA */}`,
|
|
25086
|
+
createCycleList(olPresetCycles["olUpperA" /* UPPER_ALPHA */], 9)
|
|
25087
|
+
),
|
|
25088
|
+
createOrderedReference(
|
|
25089
|
+
`windoc-ol-${"olRoman" /* ROMAN */}`,
|
|
25090
|
+
createCycleList(olPresetCycles["olRoman" /* ROMAN */], 9)
|
|
25091
|
+
),
|
|
25092
|
+
createOrderedReference(
|
|
25093
|
+
`windoc-ol-${"olZeroPad" /* ZERO_PAD */}`,
|
|
25094
|
+
createCycleList(olPresetCycles["olZeroPad" /* ZERO_PAD */], 9)
|
|
25095
|
+
),
|
|
25096
|
+
createBulletReference(
|
|
25097
|
+
"windoc-ul-disc",
|
|
25098
|
+
Array(9).fill(docxBulletCharMap["disc" /* DISC */])
|
|
25099
|
+
),
|
|
25100
|
+
createBulletReference(
|
|
25101
|
+
"windoc-ul-circle",
|
|
25102
|
+
Array(9).fill(docxBulletCharMap["circle" /* CIRCLE */])
|
|
25103
|
+
),
|
|
25104
|
+
createBulletReference(
|
|
25105
|
+
"windoc-ul-square",
|
|
25106
|
+
Array(9).fill(docxBulletCharMap["square" /* SQUARE */])
|
|
25107
|
+
),
|
|
25108
|
+
createBulletReference(
|
|
25109
|
+
"windoc-ul-checkbox",
|
|
25110
|
+
Array(9).fill(docxBulletCharMap["checkbox" /* CHECKBOX */])
|
|
25111
|
+
),
|
|
25112
|
+
createBulletReference(
|
|
25113
|
+
`windoc-ul-${"ulDefault" /* DEFAULT */}`,
|
|
25114
|
+
createCycleList(ulPresetCycles["ulDefault" /* DEFAULT */], 9)
|
|
25115
|
+
),
|
|
25116
|
+
createBulletReference(
|
|
25117
|
+
`windoc-ul-${"ulDiamond" /* DIAMOND */}`,
|
|
25118
|
+
createCycleList(ulPresetCycles["ulDiamond" /* DIAMOND */], 9)
|
|
25119
|
+
),
|
|
25120
|
+
createBulletReference(
|
|
25121
|
+
`windoc-ul-${"ulHollowSq" /* HOLLOW_SQ */}`,
|
|
25122
|
+
createCycleList(ulPresetCycles["ulHollowSq" /* HOLLOW_SQ */], 9)
|
|
25123
|
+
),
|
|
25124
|
+
createBulletReference(
|
|
25125
|
+
`windoc-ul-${"ulArrow" /* ARROW */}`,
|
|
25126
|
+
createCycleList(ulPresetCycles["ulArrow" /* ARROW */], 9)
|
|
25127
|
+
),
|
|
25128
|
+
createBulletReference(
|
|
25129
|
+
`windoc-ul-${"ulStar" /* STAR */}`,
|
|
25130
|
+
createCycleList(ulPresetCycles["ulStar" /* STAR */], 9)
|
|
25131
|
+
),
|
|
25132
|
+
createBulletReference(
|
|
25133
|
+
`windoc-ul-${"ulCheckArr" /* CHECK_ARROW */}`,
|
|
25134
|
+
createCycleList(ulPresetCycles["ulCheckArr" /* CHECK_ARROW */], 9)
|
|
25135
|
+
)
|
|
25136
|
+
];
|
|
25137
|
+
return config;
|
|
25138
|
+
}
|
|
25139
|
+
function createOrderedReference(reference, styles) {
|
|
25140
|
+
return {
|
|
25141
|
+
reference,
|
|
25142
|
+
levels: styles.map((style, level) => ({
|
|
25143
|
+
level,
|
|
25144
|
+
format: orderedStyleFormatMap[style] || import_docx.LevelFormat.DECIMAL,
|
|
25145
|
+
text: getOrderedLevelText(style, level),
|
|
25146
|
+
alignment: import_docx.AlignmentType.START,
|
|
25147
|
+
style: {
|
|
25148
|
+
paragraph: {
|
|
25149
|
+
indent: {
|
|
25150
|
+
left: 720 * (level + 1),
|
|
25151
|
+
hanging: 360
|
|
25152
|
+
}
|
|
25153
|
+
}
|
|
25154
|
+
}
|
|
25155
|
+
}))
|
|
25156
|
+
};
|
|
25157
|
+
}
|
|
25158
|
+
function createBulletReference(reference, bullets) {
|
|
25159
|
+
return {
|
|
25160
|
+
reference,
|
|
25161
|
+
levels: bullets.map((bullet, level) => ({
|
|
25162
|
+
level,
|
|
25163
|
+
format: import_docx.LevelFormat.BULLET,
|
|
25164
|
+
text: bullet,
|
|
25165
|
+
alignment: import_docx.AlignmentType.START,
|
|
25166
|
+
style: {
|
|
25167
|
+
paragraph: {
|
|
25168
|
+
indent: {
|
|
25169
|
+
left: 720 * (level + 1),
|
|
25170
|
+
hanging: 360
|
|
25171
|
+
}
|
|
25172
|
+
}
|
|
25173
|
+
}
|
|
25174
|
+
}))
|
|
25175
|
+
};
|
|
25176
|
+
}
|
|
25177
|
+
function getOrderedLevelText(style, level) {
|
|
25178
|
+
const placeholder = `%${level + 1}`;
|
|
25179
|
+
if (style === "outline") {
|
|
25180
|
+
return Array.from({ length: level + 1 }, (_, index) => `%${index + 1}`).join(
|
|
25181
|
+
"."
|
|
25182
|
+
) + ".";
|
|
25183
|
+
}
|
|
25184
|
+
if (style.endsWith("Paren") || style === "decimalParen" /* DECIMAL_PAREN */) {
|
|
25185
|
+
return `${placeholder})`;
|
|
25186
|
+
}
|
|
25187
|
+
return `${placeholder}.`;
|
|
25188
|
+
}
|
|
25189
|
+
function createCycleList(source = [], size) {
|
|
25190
|
+
const result = [];
|
|
25191
|
+
for (let i = 0; i < size; i++) {
|
|
25192
|
+
result.push(source[i % source.length]);
|
|
25193
|
+
}
|
|
25194
|
+
return result;
|
|
25195
|
+
}
|
|
25196
|
+
function getListNumbering(element, instance) {
|
|
25197
|
+
const level = Math.max(0, Math.min(element.listLevel || 0, 8));
|
|
25198
|
+
if (element.listType === "ul" /* UL */) {
|
|
25199
|
+
const reference2 = element.listPreset ? `windoc-ul-${element.listPreset}` : `windoc-ul-${element.listStyle || "disc" /* DISC */}`;
|
|
25200
|
+
return {
|
|
25201
|
+
reference: reference2,
|
|
25202
|
+
level,
|
|
25203
|
+
instance
|
|
25204
|
+
};
|
|
25205
|
+
}
|
|
25206
|
+
const reference = element.listPreset ? `windoc-ol-${element.listPreset}` : getOrderedReferenceFromStyle(element.listStyle);
|
|
25207
|
+
return {
|
|
25208
|
+
reference,
|
|
25209
|
+
level,
|
|
25210
|
+
instance
|
|
25211
|
+
};
|
|
25212
|
+
}
|
|
25213
|
+
function getOrderedReferenceFromStyle(style) {
|
|
25214
|
+
switch (style) {
|
|
25215
|
+
case "lowerAlpha" /* LOWER_ALPHA */:
|
|
25216
|
+
return "windoc-ol-lower-alpha";
|
|
25217
|
+
case "upperAlpha" /* UPPER_ALPHA */:
|
|
25218
|
+
return "windoc-ol-upper-alpha";
|
|
25219
|
+
case "lowerRoman" /* LOWER_ROMAN */:
|
|
25220
|
+
return "windoc-ol-lower-roman";
|
|
25221
|
+
case "upperRoman" /* UPPER_ROMAN */:
|
|
25222
|
+
return "windoc-ol-upper-roman";
|
|
25223
|
+
case "decimalParen" /* DECIMAL_PAREN */:
|
|
25224
|
+
return "windoc-ol-decimal-paren";
|
|
25225
|
+
default:
|
|
25226
|
+
return "windoc-ol-decimal";
|
|
25227
|
+
}
|
|
25228
|
+
}
|
|
25229
|
+
function createTableBorders(element) {
|
|
25230
|
+
const outerBorder = createBorder(
|
|
25231
|
+
element.borderColor,
|
|
25232
|
+
import_docx.BorderStyle.SINGLE,
|
|
25233
|
+
element.borderExternalWidth || element.borderWidth
|
|
25234
|
+
);
|
|
25235
|
+
const innerBorder = createBorder(
|
|
25236
|
+
element.borderColor,
|
|
25237
|
+
import_docx.BorderStyle.SINGLE,
|
|
25238
|
+
element.borderWidth
|
|
25239
|
+
);
|
|
25240
|
+
switch (element.borderType) {
|
|
25241
|
+
case "empty" /* EMPTY */:
|
|
25242
|
+
return {
|
|
25243
|
+
top: noneBorder(),
|
|
25244
|
+
bottom: noneBorder(),
|
|
25245
|
+
left: noneBorder(),
|
|
25246
|
+
right: noneBorder(),
|
|
25247
|
+
insideHorizontal: noneBorder(),
|
|
25248
|
+
insideVertical: noneBorder()
|
|
25249
|
+
};
|
|
25250
|
+
case "external" /* EXTERNAL */:
|
|
25251
|
+
return {
|
|
25252
|
+
top: outerBorder,
|
|
25253
|
+
bottom: outerBorder,
|
|
25254
|
+
left: outerBorder,
|
|
25255
|
+
right: outerBorder,
|
|
25256
|
+
insideHorizontal: noneBorder(),
|
|
25257
|
+
insideVertical: noneBorder()
|
|
25258
|
+
};
|
|
25259
|
+
case "internal" /* INTERNAL */:
|
|
25260
|
+
return {
|
|
25261
|
+
top: noneBorder(),
|
|
25262
|
+
bottom: noneBorder(),
|
|
25263
|
+
left: noneBorder(),
|
|
25264
|
+
right: noneBorder(),
|
|
25265
|
+
insideHorizontal: innerBorder,
|
|
25266
|
+
insideVertical: innerBorder
|
|
25267
|
+
};
|
|
25268
|
+
case "dash" /* DASH */:
|
|
25269
|
+
return {
|
|
25270
|
+
top: createBorder(
|
|
25271
|
+
element.borderColor,
|
|
25272
|
+
import_docx.BorderStyle.DASHED,
|
|
25273
|
+
element.borderExternalWidth || element.borderWidth
|
|
25274
|
+
),
|
|
25275
|
+
bottom: createBorder(
|
|
25276
|
+
element.borderColor,
|
|
25277
|
+
import_docx.BorderStyle.DASHED,
|
|
25278
|
+
element.borderExternalWidth || element.borderWidth
|
|
25279
|
+
),
|
|
25280
|
+
left: createBorder(
|
|
25281
|
+
element.borderColor,
|
|
25282
|
+
import_docx.BorderStyle.DASHED,
|
|
25283
|
+
element.borderExternalWidth || element.borderWidth
|
|
25284
|
+
),
|
|
25285
|
+
right: createBorder(
|
|
25286
|
+
element.borderColor,
|
|
25287
|
+
import_docx.BorderStyle.DASHED,
|
|
25288
|
+
element.borderExternalWidth || element.borderWidth
|
|
25289
|
+
),
|
|
25290
|
+
insideHorizontal: createBorder(
|
|
25291
|
+
element.borderColor,
|
|
25292
|
+
import_docx.BorderStyle.DASHED,
|
|
25293
|
+
element.borderWidth
|
|
25294
|
+
),
|
|
25295
|
+
insideVertical: createBorder(
|
|
25296
|
+
element.borderColor,
|
|
25297
|
+
import_docx.BorderStyle.DASHED,
|
|
25298
|
+
element.borderWidth
|
|
25299
|
+
)
|
|
25300
|
+
};
|
|
25301
|
+
default:
|
|
25302
|
+
return {
|
|
25303
|
+
top: outerBorder,
|
|
25304
|
+
bottom: outerBorder,
|
|
25305
|
+
left: outerBorder,
|
|
25306
|
+
right: outerBorder,
|
|
25307
|
+
insideHorizontal: innerBorder,
|
|
25308
|
+
insideVertical: innerBorder
|
|
25309
|
+
};
|
|
25310
|
+
}
|
|
25311
|
+
}
|
|
25312
|
+
function createTableCellBorders(td, inheritedColor, inheritedWidth) {
|
|
25313
|
+
if (!td.borderTypes?.length && !td.borderColor) {
|
|
25314
|
+
return void 0;
|
|
25315
|
+
}
|
|
25316
|
+
const color = td.borderColor || inheritedColor;
|
|
25317
|
+
const createCellBorder = () => createBorder(color, import_docx.BorderStyle.SINGLE, inheritedWidth);
|
|
25318
|
+
if (td.borderColor && !td.borderTypes?.length) {
|
|
25319
|
+
return {
|
|
25320
|
+
top: createCellBorder(),
|
|
25321
|
+
right: createCellBorder(),
|
|
25322
|
+
bottom: createCellBorder(),
|
|
25323
|
+
left: createCellBorder()
|
|
25324
|
+
};
|
|
25325
|
+
}
|
|
25326
|
+
const top = td.borderTypes?.includes("top" /* TOP */) ? createCellBorder() : noneBorder();
|
|
25327
|
+
const right2 = td.borderTypes?.includes("right" /* RIGHT */) ? createCellBorder() : noneBorder();
|
|
25328
|
+
const bottom = td.borderTypes?.includes("bottom" /* BOTTOM */) ? createCellBorder() : noneBorder();
|
|
25329
|
+
const left2 = td.borderTypes?.includes("left" /* LEFT */) ? createCellBorder() : noneBorder();
|
|
25330
|
+
return {
|
|
25331
|
+
top,
|
|
25332
|
+
right: right2,
|
|
25333
|
+
bottom,
|
|
25334
|
+
left: left2
|
|
25335
|
+
};
|
|
25336
|
+
}
|
|
25337
|
+
function createBorder(color = "#000000", style = import_docx.BorderStyle.SINGLE, width = 1) {
|
|
25338
|
+
return {
|
|
25339
|
+
style,
|
|
25340
|
+
color: normalizeHexColor(color, "000000") || "000000",
|
|
25341
|
+
size: pxBorderToDocxSize(width)
|
|
25342
|
+
};
|
|
25343
|
+
}
|
|
25344
|
+
function noneBorder() {
|
|
25345
|
+
return {
|
|
25346
|
+
style: import_docx.BorderStyle.NONE,
|
|
25347
|
+
size: 0,
|
|
25348
|
+
color: "FFFFFF"
|
|
25349
|
+
};
|
|
25350
|
+
}
|
|
25351
|
+
function mapPaddingToTableMargins(padding) {
|
|
25352
|
+
if (!padding) return void 0;
|
|
25353
|
+
return {
|
|
25354
|
+
top: pxToTwips(padding[0]),
|
|
25355
|
+
right: pxToTwips(padding[1]),
|
|
25356
|
+
bottom: pxToTwips(padding[2]),
|
|
25357
|
+
left: pxToTwips(padding[3]),
|
|
25358
|
+
marginUnitType: import_docx.WidthType.DXA
|
|
25359
|
+
};
|
|
25360
|
+
}
|
|
25361
|
+
function mapCellVerticalAlign(verticalAlign) {
|
|
25362
|
+
switch (verticalAlign) {
|
|
25363
|
+
case VerticalAlign.CENTER:
|
|
25364
|
+
return import_docx.VerticalAlign.CENTER;
|
|
25365
|
+
case "bottom" /* BOTTOM */:
|
|
25366
|
+
return import_docx.VerticalAlign.BOTTOM;
|
|
25367
|
+
default:
|
|
25368
|
+
return import_docx.VerticalAlign.TOP;
|
|
25369
|
+
}
|
|
25370
|
+
}
|
|
25371
|
+
function mapRowFlexToAlignment(rowFlex) {
|
|
25372
|
+
switch (rowFlex) {
|
|
25373
|
+
case "center" /* CENTER */:
|
|
25374
|
+
return import_docx.AlignmentType.CENTER;
|
|
25375
|
+
case "right" /* RIGHT */:
|
|
25376
|
+
return import_docx.AlignmentType.RIGHT;
|
|
25377
|
+
case "alignment" /* ALIGNMENT */:
|
|
25378
|
+
case "justify" /* JUSTIFY */:
|
|
25379
|
+
return import_docx.AlignmentType.JUSTIFIED;
|
|
25380
|
+
default:
|
|
25381
|
+
return import_docx.AlignmentType.LEFT;
|
|
25382
|
+
}
|
|
25383
|
+
}
|
|
25384
|
+
function mapUnderlineType(style) {
|
|
25385
|
+
switch (style) {
|
|
25386
|
+
case "double" /* DOUBLE */:
|
|
25387
|
+
return import_docx.UnderlineType.DOUBLE;
|
|
25388
|
+
case "dashed" /* DASHED */:
|
|
25389
|
+
return import_docx.UnderlineType.DASH;
|
|
25390
|
+
case "dotted" /* DOTTED */:
|
|
25391
|
+
return import_docx.UnderlineType.DOTTED;
|
|
25392
|
+
case "wavy" /* WAVY */:
|
|
25393
|
+
return import_docx.UnderlineType.WAVE;
|
|
25394
|
+
default:
|
|
25395
|
+
return import_docx.UnderlineType.SINGLE;
|
|
25396
|
+
}
|
|
25397
|
+
}
|
|
25398
|
+
function getInlineElementText(element) {
|
|
25399
|
+
switch (element.type) {
|
|
25400
|
+
case "control" /* CONTROL */:
|
|
25401
|
+
return getControlText(element.control);
|
|
25402
|
+
case "date" /* DATE */:
|
|
25403
|
+
return element.valueList?.length ? getTextFromElementList(element.valueList) : element.value;
|
|
25404
|
+
case "checkbox" /* CHECKBOX */:
|
|
25405
|
+
return element.checkbox?.value ? "\u2611" : "\u2610";
|
|
25406
|
+
case "radio" /* RADIO */:
|
|
25407
|
+
return element.radio?.value ? "\u25C9" : "\u25CB";
|
|
25408
|
+
case "label" /* LABEL */:
|
|
25409
|
+
case "latex" /* LATEX */:
|
|
25410
|
+
case "subscript" /* SUBSCRIPT */:
|
|
25411
|
+
case "superscript" /* SUPERSCRIPT */:
|
|
25412
|
+
return element.value;
|
|
25413
|
+
default:
|
|
25414
|
+
return element.value;
|
|
25415
|
+
}
|
|
25416
|
+
}
|
|
25417
|
+
function getControlText(control) {
|
|
25418
|
+
if (!control) return "";
|
|
25419
|
+
if (control.type === "text" /* TEXT */ || control.type === "date" /* DATE */ || control.type === "number" /* NUMBER */) {
|
|
25420
|
+
const value = control.value?.length ? getTextFromElementList(control.value) : "";
|
|
25421
|
+
const content = value || control.placeholder || "";
|
|
25422
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
25423
|
+
}
|
|
25424
|
+
if (control.type === "select" /* SELECT */) {
|
|
25425
|
+
const labels = getSelectedControlLabels(control.code, control.valueSets);
|
|
25426
|
+
const content = labels.length ? labels.join(control.multiSelectDelimiter || ", ") : control.placeholder || "";
|
|
25427
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
25428
|
+
}
|
|
25429
|
+
if (control.type === "checkbox" /* CHECKBOX */ || control.type === "radio" /* RADIO */) {
|
|
25430
|
+
const isRadio = control.type === "radio" /* RADIO */;
|
|
25431
|
+
return (control.valueSets || []).map((valueSet) => {
|
|
25432
|
+
const checked = control.code?.split(",").includes(valueSet.code) || false;
|
|
25433
|
+
return `${checked ? isRadio ? "\u25C9" : "\u2611" : isRadio ? "\u25CB" : "\u2610"} ${valueSet.value}`;
|
|
25434
|
+
}).join(" ");
|
|
25435
|
+
}
|
|
25436
|
+
return "";
|
|
25437
|
+
}
|
|
25438
|
+
function getSelectedControlLabels(code, valueSets) {
|
|
25439
|
+
if (!code || !valueSets?.length) return [];
|
|
25440
|
+
return code.split(",").map(
|
|
25441
|
+
(selectCode) => valueSets.find((valueSet) => valueSet.code === selectCode)?.value
|
|
25442
|
+
).filter((value) => !!value);
|
|
25443
|
+
}
|
|
25444
|
+
function getBlockFallbackText(element) {
|
|
25445
|
+
if (element.block?.iframeBlock?.src) {
|
|
25446
|
+
return element.block.iframeBlock.src;
|
|
25447
|
+
}
|
|
25448
|
+
if (element.block?.videoBlock?.src) {
|
|
25449
|
+
return element.block.videoBlock.src;
|
|
25450
|
+
}
|
|
25451
|
+
return "";
|
|
25452
|
+
}
|
|
25453
|
+
function normalizeText(text = "") {
|
|
25454
|
+
return text.replace(new RegExp(ZERO, "g"), "").replace(/\r\n/g, "\n");
|
|
25455
|
+
}
|
|
25456
|
+
function createSerializeContext() {
|
|
25457
|
+
return {
|
|
25458
|
+
nextListInstance: 1
|
|
25459
|
+
};
|
|
25460
|
+
}
|
|
25461
|
+
function getListItemNumberingElement(listItemElements, fallback) {
|
|
25462
|
+
return listItemElements.find(
|
|
25463
|
+
(listItem) => listItem.listId || listItem.listLevel !== void 0 || !!listItem.listPreset || !!listItem.listStyle || !!listItem.listType
|
|
25464
|
+
) || fallback;
|
|
25465
|
+
}
|
|
25466
|
+
function createListInstance(context) {
|
|
25467
|
+
return context.nextListInstance++;
|
|
25468
|
+
}
|
|
25469
|
+
function createTableSerializeContext(element) {
|
|
25470
|
+
return {
|
|
25471
|
+
cellLayoutMap: computeTableCellLayout(
|
|
25472
|
+
element.trList || [],
|
|
25473
|
+
element.colgroup || []
|
|
25474
|
+
),
|
|
25475
|
+
borderColor: element.borderColor,
|
|
25476
|
+
borderWidth: element.borderWidth,
|
|
25477
|
+
borderExternalWidth: element.borderExternalWidth
|
|
25478
|
+
};
|
|
25479
|
+
}
|
|
25480
|
+
function computeTableCellLayout(trList, colgroup) {
|
|
25481
|
+
const cellLayoutMap = /* @__PURE__ */ new WeakMap();
|
|
25482
|
+
if (!trList.length || !colgroup.length) {
|
|
25483
|
+
return cellLayoutMap;
|
|
25484
|
+
}
|
|
25485
|
+
const occupiedUntilRow = Array(colgroup.length).fill(0);
|
|
25486
|
+
for (let rowIndex = 0; rowIndex < trList.length; rowIndex++) {
|
|
25487
|
+
const tr = trList[rowIndex];
|
|
25488
|
+
let colIndex = 0;
|
|
25489
|
+
for (let tdIndex = 0; tdIndex < tr.tdList.length; tdIndex++) {
|
|
25490
|
+
while (colIndex < colgroup.length && occupiedUntilRow[colIndex] > rowIndex) {
|
|
25491
|
+
colIndex += 1;
|
|
25492
|
+
}
|
|
25493
|
+
const td = tr.tdList[tdIndex];
|
|
25494
|
+
let width = 0;
|
|
25495
|
+
for (let currentCol = colIndex; currentCol < colIndex + td.colspan && currentCol < colgroup.length; currentCol++) {
|
|
25496
|
+
width += colgroup[currentCol].width;
|
|
25497
|
+
occupiedUntilRow[currentCol] = Math.max(
|
|
25498
|
+
occupiedUntilRow[currentCol],
|
|
25499
|
+
rowIndex + td.rowspan
|
|
25500
|
+
);
|
|
25501
|
+
}
|
|
25502
|
+
cellLayoutMap.set(td, { width });
|
|
25503
|
+
colIndex += td.colspan;
|
|
25504
|
+
}
|
|
25505
|
+
}
|
|
25506
|
+
return cellLayoutMap;
|
|
25507
|
+
}
|
|
25508
|
+
function getTableWidthFromColgroup(colgroup) {
|
|
25509
|
+
if (!colgroup?.length) {
|
|
25510
|
+
return void 0;
|
|
25511
|
+
}
|
|
25512
|
+
return colgroup.reduce((sum, col) => sum + col.width, 0);
|
|
25513
|
+
}
|
|
25514
|
+
function normalizeHexColor(color, fallback) {
|
|
25515
|
+
const normalized = normalizeHexLiteral(color) || normalizeRgbColor(color) || normalizeBrowserColor(color);
|
|
25516
|
+
if (normalized) {
|
|
25517
|
+
return normalized;
|
|
25518
|
+
}
|
|
25519
|
+
return fallback ? normalizeHexLiteral(fallback) || void 0 : void 0;
|
|
25520
|
+
}
|
|
25521
|
+
function normalizeHexLiteral(color) {
|
|
25522
|
+
const value = color.trim().replace(/^#/, "");
|
|
25523
|
+
if (/^[\da-f]{3}$/i.test(value)) {
|
|
25524
|
+
return value.split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
25525
|
+
}
|
|
25526
|
+
if (/^[\da-f]{4}$/i.test(value)) {
|
|
25527
|
+
return value.slice(0, 3).split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
25528
|
+
}
|
|
25529
|
+
if (/^[\da-f]{6}$/i.test(value)) {
|
|
25530
|
+
return value.toUpperCase();
|
|
25531
|
+
}
|
|
25532
|
+
if (/^[\da-f]{8}$/i.test(value)) {
|
|
25533
|
+
return value.slice(0, 6).toUpperCase();
|
|
25534
|
+
}
|
|
25535
|
+
return void 0;
|
|
25536
|
+
}
|
|
25537
|
+
function normalizeRgbColor(color) {
|
|
25538
|
+
const match = color.trim().match(/^rgba?\((.+)\)$/i);
|
|
25539
|
+
if (!match) {
|
|
25540
|
+
return void 0;
|
|
25541
|
+
}
|
|
25542
|
+
const parts = match[1].replace(/\s*\/\s*/g, ",").split(/\s*,\s*|\s+/).filter(Boolean);
|
|
25543
|
+
if (parts.length < 3) {
|
|
25544
|
+
return void 0;
|
|
25545
|
+
}
|
|
25546
|
+
const red = parseRgbChannel(parts[0]);
|
|
25547
|
+
const green = parseRgbChannel(parts[1]);
|
|
25548
|
+
const blue = parseRgbChannel(parts[2]);
|
|
25549
|
+
if (red === null || green === null || blue === null) {
|
|
25550
|
+
return void 0;
|
|
25551
|
+
}
|
|
25552
|
+
const alpha = parts[3] !== void 0 ? parseAlphaChannel(parts[3]) : 1;
|
|
25553
|
+
if (alpha === null || alpha <= 0) {
|
|
25554
|
+
return void 0;
|
|
25555
|
+
}
|
|
25556
|
+
const flattened = alpha >= 1 ? [red, green, blue] : [
|
|
25557
|
+
flattenChannel(red, alpha),
|
|
25558
|
+
flattenChannel(green, alpha),
|
|
25559
|
+
flattenChannel(blue, alpha)
|
|
25560
|
+
];
|
|
25561
|
+
return flattened.map(toHexChannel).join("");
|
|
25562
|
+
}
|
|
25563
|
+
function normalizeBrowserColor(color) {
|
|
25564
|
+
if (typeof document === "undefined") {
|
|
25565
|
+
return void 0;
|
|
25566
|
+
}
|
|
25567
|
+
const canvas = document.createElement("canvas");
|
|
25568
|
+
const context = canvas.getContext("2d");
|
|
25569
|
+
if (!context) {
|
|
25570
|
+
return void 0;
|
|
25571
|
+
}
|
|
25572
|
+
context.fillStyle = "#000000";
|
|
25573
|
+
context.fillStyle = color;
|
|
25574
|
+
const normalized = context.fillStyle;
|
|
25575
|
+
if (typeof normalized !== "string") {
|
|
25576
|
+
return void 0;
|
|
25577
|
+
}
|
|
25578
|
+
return normalizeHexLiteral(normalized) || normalizeRgbColor(normalized);
|
|
25579
|
+
}
|
|
25580
|
+
function parseRgbChannel(value) {
|
|
25581
|
+
if (value.endsWith("%")) {
|
|
25582
|
+
const percent = Number(value.slice(0, -1));
|
|
25583
|
+
if (!Number.isFinite(percent)) {
|
|
25584
|
+
return null;
|
|
25585
|
+
}
|
|
25586
|
+
return clampColorChannel(Math.round(percent / 100 * 255));
|
|
25587
|
+
}
|
|
25588
|
+
const channel = Number(value);
|
|
25589
|
+
if (!Number.isFinite(channel)) {
|
|
25590
|
+
return null;
|
|
25591
|
+
}
|
|
25592
|
+
return clampColorChannel(Math.round(channel));
|
|
25593
|
+
}
|
|
25594
|
+
function parseAlphaChannel(value) {
|
|
25595
|
+
if (value.endsWith("%")) {
|
|
25596
|
+
const percent = Number(value.slice(0, -1));
|
|
25597
|
+
if (!Number.isFinite(percent)) {
|
|
25598
|
+
return null;
|
|
25599
|
+
}
|
|
25600
|
+
return Math.min(Math.max(percent / 100, 0), 1);
|
|
25601
|
+
}
|
|
25602
|
+
const alpha = Number(value);
|
|
25603
|
+
if (!Number.isFinite(alpha)) {
|
|
25604
|
+
return null;
|
|
25605
|
+
}
|
|
25606
|
+
return Math.min(Math.max(alpha, 0), 1);
|
|
25607
|
+
}
|
|
25608
|
+
function clampColorChannel(value) {
|
|
25609
|
+
return Math.min(Math.max(value, 0), 255);
|
|
25610
|
+
}
|
|
25611
|
+
function flattenChannel(value, alpha) {
|
|
25612
|
+
return clampColorChannel(Math.round(255 * (1 - alpha) + value * alpha));
|
|
25613
|
+
}
|
|
25614
|
+
function toHexChannel(value) {
|
|
25615
|
+
return value.toString(16).padStart(2, "0").toUpperCase();
|
|
25616
|
+
}
|
|
25617
|
+
function pxBorderToDocxSize(width) {
|
|
25618
|
+
const safeWidth = Number.isFinite(width) && width > 0 ? width : 1;
|
|
25619
|
+
return Math.max(2, Math.round(safeWidth * 6));
|
|
25620
|
+
}
|
|
25621
|
+
function getRegularImageType(mime) {
|
|
25622
|
+
if (mime.includes("png")) return "png";
|
|
25623
|
+
if (mime.includes("jpeg") || mime.includes("jpg")) return "jpg";
|
|
25624
|
+
if (mime.includes("gif")) return "gif";
|
|
25625
|
+
if (mime.includes("bmp")) return "bmp";
|
|
25626
|
+
return null;
|
|
25627
|
+
}
|
|
25628
|
+
function normalizeDocxFileName(fileName) {
|
|
25629
|
+
const trimmed = fileName?.trim();
|
|
25630
|
+
if (!trimmed) {
|
|
25631
|
+
return DEFAULT_DOCX_FILE_NAME;
|
|
25632
|
+
}
|
|
25633
|
+
return trimmed.toLowerCase().endsWith(".docx") ? trimmed : `${trimmed}.docx`;
|
|
25634
|
+
}
|
|
25635
|
+
function pxToTwips(px) {
|
|
25636
|
+
return Math.round(px * 15);
|
|
25637
|
+
}
|
|
25638
|
+
|
|
25639
|
+
// src/utils/pdf.ts
|
|
25640
|
+
var import_pdf_lib = require("pdf-lib");
|
|
25641
|
+
var DEFAULT_PDF_FILE_NAME = "document.pdf";
|
|
25642
|
+
var DEFAULT_IMAGE_WIDTH2 = 320;
|
|
25643
|
+
var DEFAULT_IMAGE_HEIGHT2 = 180;
|
|
25644
|
+
var DEFAULT_LINE_HEIGHT2 = 1.15;
|
|
25645
|
+
var PAGE_REGION_GAP = 12;
|
|
25646
|
+
var SEPARATOR_HEIGHT = 12;
|
|
25647
|
+
var LIST_GAP = 8;
|
|
25648
|
+
var FOOTER_MIN_BAR_HEIGHT = 29;
|
|
25649
|
+
var PDF_TEXT_FALLBACKS = {
|
|
25650
|
+
"\u2297": "x",
|
|
25651
|
+
"\u2611": "[x]",
|
|
25652
|
+
"\u2612": "[x]",
|
|
25653
|
+
"\u2610": "[]",
|
|
25654
|
+
"\u2713": "v",
|
|
25655
|
+
"\u2714": "v",
|
|
25656
|
+
"\u2717": "x",
|
|
25657
|
+
"\u2715": "x",
|
|
25658
|
+
"\u25E6": "o",
|
|
25659
|
+
"\u25AA": "*",
|
|
25660
|
+
"\u25A0": "*"
|
|
25661
|
+
};
|
|
25662
|
+
var pdfTextCache = /* @__PURE__ */ new WeakMap();
|
|
25663
|
+
var bulletCharMap = {
|
|
25664
|
+
["disc" /* DISC */]: "\u2022",
|
|
25665
|
+
["circle" /* CIRCLE */]: "\u25E6",
|
|
25666
|
+
["square" /* SQUARE */]: "\u25A0",
|
|
25667
|
+
["checkbox" /* CHECKBOX */]: "\u2611"
|
|
25668
|
+
};
|
|
25669
|
+
async function exportEditorDataToPdf(payload, options = {}) {
|
|
25670
|
+
const editorOptions = payload.options;
|
|
25671
|
+
const pdfDoc = await import_pdf_lib.PDFDocument.create();
|
|
25672
|
+
const context = await createPdfContext(pdfDoc, editorOptions);
|
|
25673
|
+
const headerBlocks = editorOptions.header.disabled ? [] : await parseElementList(payload.data.header || [], context, editorOptions);
|
|
25674
|
+
const footerBlocks = editorOptions.footer.disabled ? [] : await parseElementList(payload.data.footer || [], context, editorOptions);
|
|
25675
|
+
const mainBlocks = await parseElementList(
|
|
25676
|
+
payload.data.main,
|
|
25677
|
+
context,
|
|
25678
|
+
editorOptions
|
|
25679
|
+
);
|
|
25680
|
+
const headerHeight = measureBlocksHeight(
|
|
25681
|
+
headerBlocks,
|
|
25682
|
+
context.contentWidth,
|
|
25683
|
+
context
|
|
25684
|
+
);
|
|
25685
|
+
const footerHeight = measureBlocksHeight(
|
|
25686
|
+
footerBlocks,
|
|
25687
|
+
context.contentWidth,
|
|
25688
|
+
context
|
|
25689
|
+
);
|
|
25690
|
+
const footerBarHeight = getFooterBarHeight(footerHeight, context);
|
|
25691
|
+
const pageNumberHeight = getPageNumberHeight(editorOptions.pageNumber);
|
|
25692
|
+
const contentTop = Math.max(
|
|
25693
|
+
context.margins[0],
|
|
25694
|
+
context.headerTop + headerHeight + (headerBlocks.length ? context.headerGap : 0)
|
|
25695
|
+
);
|
|
25696
|
+
const contentBottom = Math.max(
|
|
25697
|
+
context.margins[2],
|
|
25698
|
+
context.footerBottom + footerBarHeight,
|
|
25699
|
+
getReservedPageNumberBottom(editorOptions.pageNumber, pageNumberHeight)
|
|
25700
|
+
);
|
|
25701
|
+
const pages = renderMainBlocks(
|
|
25702
|
+
mainBlocks,
|
|
25703
|
+
context,
|
|
25704
|
+
contentTop,
|
|
25705
|
+
contentBottom
|
|
25706
|
+
);
|
|
25707
|
+
renderPageDecorations(
|
|
25708
|
+
pages,
|
|
25709
|
+
context,
|
|
25710
|
+
headerBlocks,
|
|
25711
|
+
footerBlocks,
|
|
25712
|
+
headerHeight,
|
|
25713
|
+
footerHeight,
|
|
25714
|
+
footerBarHeight,
|
|
25715
|
+
editorOptions.pageNumber
|
|
25716
|
+
);
|
|
25717
|
+
const bytes = await pdfDoc.save();
|
|
25718
|
+
return {
|
|
25719
|
+
blob: new Blob([bytes], { type: "application/pdf" }),
|
|
25720
|
+
fileName: normalizePdfFileName(options.fileName)
|
|
25721
|
+
};
|
|
25722
|
+
}
|
|
25723
|
+
async function createPdfContext(pdfDoc, options) {
|
|
25724
|
+
const [sans, sansBold, sansItalic, sansBoldItalic] = await Promise.all([
|
|
25725
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.Helvetica),
|
|
25726
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.HelveticaBold),
|
|
25727
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.HelveticaOblique),
|
|
25728
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.HelveticaBoldOblique)
|
|
25729
|
+
]);
|
|
25730
|
+
const [serif, serifBold, serifItalic, serifBoldItalic] = await Promise.all([
|
|
25731
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.TimesRoman),
|
|
25732
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.TimesRomanBold),
|
|
25733
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.TimesRomanItalic),
|
|
25734
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.TimesRomanBoldItalic)
|
|
25735
|
+
]);
|
|
25736
|
+
const [mono, monoBold, monoItalic, monoBoldItalic] = await Promise.all([
|
|
25737
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.Courier),
|
|
25738
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.CourierBold),
|
|
25739
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.CourierOblique),
|
|
25740
|
+
pdfDoc.embedFont(import_pdf_lib.StandardFonts.CourierBoldOblique)
|
|
25741
|
+
]);
|
|
25742
|
+
const pageWidth = options.paperDirection === "horizontal" /* HORIZONTAL */ ? pxToPt(options.height) : pxToPt(options.width);
|
|
25743
|
+
const pageHeight = options.paperDirection === "horizontal" /* HORIZONTAL */ ? pxToPt(options.width) : pxToPt(options.height);
|
|
25744
|
+
const margins = options.margins.map(pxToPt);
|
|
25745
|
+
return {
|
|
25746
|
+
pdfDoc,
|
|
25747
|
+
options,
|
|
25748
|
+
fonts: {
|
|
25749
|
+
sans: {
|
|
25750
|
+
regular: sans,
|
|
25751
|
+
bold: sansBold,
|
|
25752
|
+
italic: sansItalic,
|
|
25753
|
+
boldItalic: sansBoldItalic
|
|
25754
|
+
},
|
|
25755
|
+
serif: {
|
|
25756
|
+
regular: serif,
|
|
25757
|
+
bold: serifBold,
|
|
25758
|
+
italic: serifItalic,
|
|
25759
|
+
boldItalic: serifBoldItalic
|
|
25760
|
+
},
|
|
25761
|
+
mono: {
|
|
25762
|
+
regular: mono,
|
|
25763
|
+
bold: monoBold,
|
|
25764
|
+
italic: monoItalic,
|
|
25765
|
+
boldItalic: monoBoldItalic
|
|
25766
|
+
}
|
|
25767
|
+
},
|
|
25768
|
+
pageWidth,
|
|
25769
|
+
pageHeight,
|
|
25770
|
+
margins,
|
|
25771
|
+
contentWidth: pageWidth - margins[1] - margins[3],
|
|
25772
|
+
headerTop: pxToPt(options.header.top),
|
|
25773
|
+
footerBottom: pxToPt(options.footer.bottom),
|
|
25774
|
+
headerGap: PAGE_REGION_GAP,
|
|
25775
|
+
footerGap: PAGE_REGION_GAP,
|
|
25776
|
+
separatorGap: SEPARATOR_HEIGHT,
|
|
25777
|
+
imageCache: /* @__PURE__ */ new Map()
|
|
25778
|
+
};
|
|
25779
|
+
}
|
|
25780
|
+
async function parseElementList(elementList, context, options) {
|
|
25781
|
+
const blocks = [];
|
|
25782
|
+
let inlineBuffer = [];
|
|
25783
|
+
const flushInlineBuffer = async () => {
|
|
25784
|
+
if (!inlineBuffer.length) return;
|
|
25785
|
+
blocks.push(...await parseInlineElements(inlineBuffer, context, options));
|
|
25786
|
+
inlineBuffer = [];
|
|
25787
|
+
};
|
|
25788
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
25789
|
+
const element = elementList[i];
|
|
25790
|
+
if (element.type === "area" /* AREA */ && element.valueList?.length) {
|
|
25791
|
+
await flushInlineBuffer();
|
|
25792
|
+
blocks.push(
|
|
25793
|
+
...await parseElementList(element.valueList, context, options)
|
|
25794
|
+
);
|
|
25795
|
+
continue;
|
|
25796
|
+
}
|
|
25797
|
+
if (element.type === "title" /* TITLE */ && element.valueList?.length) {
|
|
25798
|
+
await flushInlineBuffer();
|
|
25799
|
+
blocks.push(
|
|
25800
|
+
...await parseInlineElements(element.valueList, context, options, {
|
|
25801
|
+
alignment: element.rowFlex,
|
|
25802
|
+
rowMargin: element.rowMargin,
|
|
25803
|
+
listMarker: void 0,
|
|
25804
|
+
titleLevel: element.level || "first" /* FIRST */
|
|
25805
|
+
})
|
|
25806
|
+
);
|
|
25807
|
+
continue;
|
|
25808
|
+
}
|
|
25809
|
+
if (element.type === "list" /* LIST */ && element.valueList?.length) {
|
|
25810
|
+
await flushInlineBuffer();
|
|
25811
|
+
blocks.push(...await parseListBlock(element, context, options));
|
|
25812
|
+
continue;
|
|
25813
|
+
}
|
|
25814
|
+
if (element.type === "table" /* TABLE */ && element.trList?.length) {
|
|
25815
|
+
await flushInlineBuffer();
|
|
25816
|
+
blocks.push(await parseTableBlock(element, context, options));
|
|
25817
|
+
continue;
|
|
25818
|
+
}
|
|
25819
|
+
if (element.type === "pageBreak" /* PAGE_BREAK */) {
|
|
25820
|
+
await flushInlineBuffer();
|
|
25821
|
+
blocks.push({ type: "pageBreak" });
|
|
25822
|
+
continue;
|
|
25823
|
+
}
|
|
25824
|
+
if (element.type === "separator" /* SEPARATOR */) {
|
|
25825
|
+
await flushInlineBuffer();
|
|
25826
|
+
blocks.push({ type: "separator" });
|
|
25827
|
+
continue;
|
|
25828
|
+
}
|
|
25829
|
+
if (element.type === "image" /* IMAGE */ && element.imgDisplay && element.imgDisplay !== "inline") {
|
|
25830
|
+
await flushInlineBuffer();
|
|
25831
|
+
const imageBlock = await createImageBlock(element, context);
|
|
25832
|
+
if (imageBlock) {
|
|
25833
|
+
blocks.push(imageBlock);
|
|
25834
|
+
}
|
|
25835
|
+
continue;
|
|
25836
|
+
}
|
|
25837
|
+
if (element.type === "block" /* BLOCK */) {
|
|
25838
|
+
await flushInlineBuffer();
|
|
25839
|
+
const blockText = getBlockFallbackText2(element);
|
|
25840
|
+
if (blockText) {
|
|
25841
|
+
blocks.push(
|
|
25842
|
+
...await parseInlineElements(
|
|
25843
|
+
[{ value: blockText }],
|
|
25844
|
+
context,
|
|
25845
|
+
options
|
|
25846
|
+
)
|
|
25847
|
+
);
|
|
25848
|
+
}
|
|
25849
|
+
continue;
|
|
25850
|
+
}
|
|
25851
|
+
inlineBuffer.push(element);
|
|
25852
|
+
}
|
|
25853
|
+
await flushInlineBuffer();
|
|
25854
|
+
return blocks;
|
|
25855
|
+
}
|
|
25856
|
+
async function parseInlineElements(elementList, context, options, overrides = {}) {
|
|
25857
|
+
const paragraphs = [];
|
|
25858
|
+
let current = null;
|
|
25859
|
+
const getParagraphContext = (element) => ({
|
|
25860
|
+
alignment: overrides.alignment !== void 0 ? overrides.alignment : element?.rowFlex,
|
|
25861
|
+
rowMargin: overrides.rowMargin !== void 0 ? overrides.rowMargin : element?.rowMargin,
|
|
25862
|
+
listMarker: overrides.listMarker
|
|
25863
|
+
});
|
|
25864
|
+
const ensureParagraph = (element) => {
|
|
25865
|
+
if (!current) {
|
|
25866
|
+
current = {
|
|
25867
|
+
runs: [],
|
|
25868
|
+
context: getParagraphContext(element)
|
|
25869
|
+
};
|
|
25870
|
+
}
|
|
25871
|
+
return current;
|
|
25872
|
+
};
|
|
25873
|
+
const flushParagraph = (contextValue) => {
|
|
25874
|
+
if (!current) {
|
|
25875
|
+
if (!contextValue) return;
|
|
25876
|
+
paragraphs.push({
|
|
25877
|
+
type: "paragraph",
|
|
25878
|
+
runs: [],
|
|
25879
|
+
context: contextValue
|
|
25880
|
+
});
|
|
25881
|
+
return;
|
|
25882
|
+
}
|
|
25883
|
+
paragraphs.push({
|
|
25884
|
+
type: "paragraph",
|
|
25885
|
+
runs: current.runs,
|
|
25886
|
+
context: current.context
|
|
25887
|
+
});
|
|
25888
|
+
current = null;
|
|
25889
|
+
};
|
|
25890
|
+
const appendText = (element, text, factory, preserveTrailingBreak = false) => {
|
|
25891
|
+
const normalized = normalizeText2(text);
|
|
25892
|
+
const parts = normalized.split("\n");
|
|
25893
|
+
let lastSeparatorFlushedContent = false;
|
|
25894
|
+
for (let i = 0; i < parts.length; i++) {
|
|
25895
|
+
const segment = parts[i];
|
|
25896
|
+
if (segment) {
|
|
25897
|
+
ensureParagraph(element).runs.push(factory(segment));
|
|
25898
|
+
}
|
|
25899
|
+
if (i < parts.length - 1) {
|
|
25900
|
+
if (!current) {
|
|
25901
|
+
paragraphs.push({
|
|
25902
|
+
type: "paragraph",
|
|
25903
|
+
runs: [],
|
|
25904
|
+
context: getParagraphContext(element)
|
|
25905
|
+
});
|
|
25906
|
+
lastSeparatorFlushedContent = false;
|
|
25907
|
+
} else {
|
|
25908
|
+
flushParagraph();
|
|
25909
|
+
lastSeparatorFlushedContent = true;
|
|
25910
|
+
}
|
|
25911
|
+
}
|
|
25912
|
+
}
|
|
25913
|
+
if (preserveTrailingBreak && normalized.endsWith("\n") && lastSeparatorFlushedContent) {
|
|
25914
|
+
paragraphs.push({
|
|
25915
|
+
type: "paragraph",
|
|
25916
|
+
runs: [],
|
|
25917
|
+
context: getParagraphContext(element)
|
|
25918
|
+
});
|
|
25919
|
+
}
|
|
25920
|
+
};
|
|
25921
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
25922
|
+
const element = elementList[i];
|
|
25923
|
+
if (element.type === "hyperlink" /* HYPERLINK */ && element.valueList?.length) {
|
|
25924
|
+
const children = element.valueList || [];
|
|
25925
|
+
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
25926
|
+
const child = children[childIndex];
|
|
25927
|
+
const text = normalizeText2(getInlineElementText2(child));
|
|
25928
|
+
if (!text) continue;
|
|
25929
|
+
appendText(
|
|
25930
|
+
element,
|
|
25931
|
+
text,
|
|
25932
|
+
(segment) => {
|
|
25933
|
+
const run = createTextRun2(
|
|
25934
|
+
child,
|
|
25935
|
+
options,
|
|
25936
|
+
overrides.titleLevel,
|
|
25937
|
+
segment
|
|
25938
|
+
);
|
|
25939
|
+
run.color = run.color || options.defaultHyperlinkColor;
|
|
25940
|
+
run.underline = true;
|
|
25941
|
+
return run;
|
|
25942
|
+
},
|
|
25943
|
+
i === elementList.length - 1 && childIndex === children.length - 1
|
|
25944
|
+
);
|
|
25945
|
+
}
|
|
25946
|
+
continue;
|
|
25947
|
+
}
|
|
25948
|
+
if (element.type === "image" /* IMAGE */) {
|
|
25949
|
+
const imageRun = await createInlineImageRun(element, context);
|
|
25950
|
+
if (imageRun) {
|
|
25951
|
+
ensureParagraph(element).runs.push(imageRun);
|
|
25952
|
+
}
|
|
25953
|
+
continue;
|
|
25954
|
+
}
|
|
25955
|
+
if (element.type === "columnBreak" /* COLUMN_BREAK */) {
|
|
25956
|
+
flushParagraph(getParagraphContext(element));
|
|
25957
|
+
continue;
|
|
25958
|
+
}
|
|
25959
|
+
if (element.type === "pageBreak" /* PAGE_BREAK */) {
|
|
25960
|
+
flushParagraph();
|
|
25961
|
+
paragraphs.push({ type: "pageBreak" });
|
|
25962
|
+
continue;
|
|
25963
|
+
}
|
|
25964
|
+
if (element.type === "tab" /* TAB */) {
|
|
25965
|
+
ensureParagraph(element).runs.push({
|
|
25966
|
+
type: "tab",
|
|
25967
|
+
width: pxToPt(options.defaultTabWidth)
|
|
25968
|
+
});
|
|
25969
|
+
continue;
|
|
25970
|
+
}
|
|
25971
|
+
if (element.type === "label" /* LABEL */) {
|
|
25972
|
+
const badgeRun = createBadgeRun(element, options, overrides.titleLevel);
|
|
25973
|
+
ensureParagraph(element).runs.push(badgeRun);
|
|
25974
|
+
continue;
|
|
25975
|
+
}
|
|
25976
|
+
const textValue = getInlineElementText2(element);
|
|
25977
|
+
if (!textValue) {
|
|
25978
|
+
continue;
|
|
25979
|
+
}
|
|
25980
|
+
appendText(
|
|
25981
|
+
element,
|
|
25982
|
+
textValue,
|
|
25983
|
+
(segment) => createTextRun2(element, options, overrides.titleLevel, segment),
|
|
25984
|
+
i === elementList.length - 1
|
|
25985
|
+
);
|
|
25986
|
+
}
|
|
25987
|
+
if (current) {
|
|
25988
|
+
flushParagraph();
|
|
25989
|
+
}
|
|
25990
|
+
return paragraphs.length ? paragraphs : [
|
|
25991
|
+
{
|
|
25992
|
+
type: "paragraph",
|
|
25993
|
+
runs: [],
|
|
25994
|
+
context: getParagraphContext()
|
|
25995
|
+
}
|
|
25996
|
+
];
|
|
25997
|
+
}
|
|
25998
|
+
async function parseListBlock(element, context, options) {
|
|
25999
|
+
const zipList = zipElementList(element.valueList || []);
|
|
26000
|
+
const listItemMap = splitListElement(zipList);
|
|
26001
|
+
const blocks = [];
|
|
26002
|
+
const orderedCounts = Array(9).fill(0);
|
|
26003
|
+
for (const listItemElements of listItemMap.values()) {
|
|
26004
|
+
const itemElement = getListItemNumberingElement2(listItemElements, element);
|
|
26005
|
+
const marker = getListMarker(itemElement, orderedCounts);
|
|
26006
|
+
blocks.push(
|
|
26007
|
+
...await parseInlineElements(listItemElements, context, options, {
|
|
26008
|
+
alignment: itemElement.rowFlex,
|
|
26009
|
+
rowMargin: itemElement.rowMargin,
|
|
26010
|
+
listMarker: marker
|
|
26011
|
+
})
|
|
26012
|
+
);
|
|
26013
|
+
}
|
|
26014
|
+
return blocks;
|
|
26015
|
+
}
|
|
26016
|
+
async function parseTableBlock(element, context, options) {
|
|
26017
|
+
const placements = computeTableCellPlacement(
|
|
26018
|
+
element.trList || [],
|
|
26019
|
+
element.colgroup || []
|
|
26020
|
+
);
|
|
26021
|
+
const rows = [];
|
|
26022
|
+
for (let rowIndex = 0; rowIndex < (element.trList || []).length; rowIndex++) {
|
|
26023
|
+
const tr = element.trList[rowIndex];
|
|
26024
|
+
const cells = [];
|
|
26025
|
+
for (let cellIndex = 0; cellIndex < tr.tdList.length; cellIndex++) {
|
|
26026
|
+
const td = tr.tdList[cellIndex];
|
|
26027
|
+
const placement = placements.get(td);
|
|
26028
|
+
cells.push({
|
|
26029
|
+
colspan: td.colspan,
|
|
26030
|
+
rowspan: td.rowspan,
|
|
26031
|
+
blocks: await parseElementList(td.value, context, options),
|
|
26032
|
+
colIndex: placement?.colIndex || 0,
|
|
26033
|
+
width: placement?.width || td.width || 0,
|
|
26034
|
+
padding: td.padding || options.table.tdPadding,
|
|
26035
|
+
verticalAlign: td.verticalAlign,
|
|
26036
|
+
backgroundColor: td.backgroundColor,
|
|
26037
|
+
borderColor: td.borderColor,
|
|
26038
|
+
borderTypes: td.borderTypes
|
|
26039
|
+
});
|
|
26040
|
+
}
|
|
26041
|
+
rows.push({
|
|
26042
|
+
height: Math.max(tr.height || 0, options.table.defaultTrMinHeight),
|
|
26043
|
+
cells
|
|
26044
|
+
});
|
|
26045
|
+
}
|
|
26046
|
+
return {
|
|
26047
|
+
type: "table",
|
|
26048
|
+
rows,
|
|
26049
|
+
colWidths: (element.colgroup || []).map((col) => col.width),
|
|
26050
|
+
borderType: element.borderType,
|
|
26051
|
+
borderColor: element.borderColor || options.table.defaultBorderColor,
|
|
26052
|
+
borderWidth: element.borderWidth || 1,
|
|
26053
|
+
borderExternalWidth: element.borderExternalWidth
|
|
26054
|
+
};
|
|
26055
|
+
}
|
|
26056
|
+
async function createImageBlock(element, context) {
|
|
26057
|
+
const image = await loadPdfImage(element.value, context);
|
|
26058
|
+
if (!image) {
|
|
26059
|
+
return null;
|
|
26060
|
+
}
|
|
26061
|
+
return {
|
|
26062
|
+
type: "image",
|
|
26063
|
+
image,
|
|
26064
|
+
width: pxToPt(
|
|
26065
|
+
Math.max(1, Math.round(element.width || DEFAULT_IMAGE_WIDTH2))
|
|
26066
|
+
),
|
|
26067
|
+
height: pxToPt(
|
|
26068
|
+
Math.max(1, Math.round(element.height || DEFAULT_IMAGE_HEIGHT2))
|
|
26069
|
+
),
|
|
26070
|
+
alignment: element.rowFlex
|
|
26071
|
+
};
|
|
26072
|
+
}
|
|
26073
|
+
async function createInlineImageRun(element, context) {
|
|
26074
|
+
const image = await loadPdfImage(element.value, context);
|
|
26075
|
+
if (!image) {
|
|
26076
|
+
return null;
|
|
26077
|
+
}
|
|
26078
|
+
return {
|
|
26079
|
+
type: "image",
|
|
26080
|
+
image,
|
|
26081
|
+
width: pxToPt(
|
|
26082
|
+
Math.max(1, Math.round(element.width || DEFAULT_IMAGE_WIDTH2))
|
|
26083
|
+
),
|
|
26084
|
+
height: pxToPt(
|
|
26085
|
+
Math.max(1, Math.round(element.height || DEFAULT_IMAGE_HEIGHT2))
|
|
26086
|
+
)
|
|
26087
|
+
};
|
|
26088
|
+
}
|
|
26089
|
+
function createTextRun2(element, options, titleLevel, text) {
|
|
26090
|
+
const titleSize = getTitleSize(titleLevel, options);
|
|
26091
|
+
const size = element.size || titleSize || options.defaultSize;
|
|
26092
|
+
const isTitle = !!titleLevel;
|
|
26093
|
+
return {
|
|
26094
|
+
type: "text",
|
|
26095
|
+
text,
|
|
26096
|
+
size,
|
|
26097
|
+
font: element.font || options.defaultFont,
|
|
26098
|
+
bold: isTitle ? true : !!element.bold,
|
|
26099
|
+
italic: !!element.italic,
|
|
26100
|
+
underline: !!element.underline,
|
|
26101
|
+
strikeout: !!element.strikeout,
|
|
26102
|
+
color: element.color || (isTitle ? "#000000" : void 0),
|
|
26103
|
+
highlight: element.highlight,
|
|
26104
|
+
superscript: element.type === "superscript" /* SUPERSCRIPT */,
|
|
26105
|
+
subscript: element.type === "subscript" /* SUBSCRIPT */
|
|
26106
|
+
};
|
|
26107
|
+
}
|
|
26108
|
+
function createBadgeRun(element, options, titleLevel) {
|
|
26109
|
+
const titleSize = getTitleSize(titleLevel, options);
|
|
26110
|
+
return {
|
|
26111
|
+
type: "badge",
|
|
26112
|
+
text: element.value,
|
|
26113
|
+
size: element.size || titleSize || options.defaultSize,
|
|
26114
|
+
font: element.font || options.defaultFont,
|
|
26115
|
+
bold: titleLevel ? true : !!element.bold,
|
|
26116
|
+
italic: !!element.italic,
|
|
26117
|
+
underline: !!element.underline,
|
|
26118
|
+
strikeout: !!element.strikeout,
|
|
26119
|
+
color: element.label?.color || element.color,
|
|
26120
|
+
backgroundColor: element.label?.backgroundColor,
|
|
26121
|
+
borderColor: element.label?.borderColor,
|
|
26122
|
+
padding: element.label?.padding || [2, 4, 2, 4]
|
|
26123
|
+
};
|
|
26124
|
+
}
|
|
26125
|
+
function renderMainBlocks(blocks, context, contentTop, contentBottom) {
|
|
26126
|
+
const pages = [];
|
|
26127
|
+
const contentEnd = context.pageHeight - contentBottom;
|
|
26128
|
+
const createPage = () => {
|
|
26129
|
+
const page = context.pdfDoc.addPage([
|
|
26130
|
+
context.pageWidth,
|
|
26131
|
+
context.pageHeight
|
|
26132
|
+
]);
|
|
26133
|
+
const state = {
|
|
26134
|
+
page,
|
|
26135
|
+
cursorY: contentTop,
|
|
26136
|
+
isEmpty: true
|
|
26137
|
+
};
|
|
26138
|
+
pages.push(state);
|
|
26139
|
+
return state;
|
|
26140
|
+
};
|
|
26141
|
+
let currentPage = createPage();
|
|
26142
|
+
const ensureSpace = (height) => {
|
|
26143
|
+
if (currentPage.cursorY + height <= contentEnd || currentPage.isEmpty) {
|
|
26144
|
+
return;
|
|
26145
|
+
}
|
|
26146
|
+
currentPage = createPage();
|
|
26147
|
+
};
|
|
26148
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
26149
|
+
const block = blocks[i];
|
|
26150
|
+
if (block.type === "pageBreak") {
|
|
26151
|
+
currentPage = createPage();
|
|
26152
|
+
continue;
|
|
26153
|
+
}
|
|
26154
|
+
if (block.type === "paragraph") {
|
|
26155
|
+
currentPage = renderParagraphAcrossPages(
|
|
26156
|
+
block,
|
|
26157
|
+
currentPage,
|
|
26158
|
+
pages,
|
|
26159
|
+
context,
|
|
26160
|
+
contentTop,
|
|
26161
|
+
contentEnd
|
|
26162
|
+
);
|
|
26163
|
+
continue;
|
|
26164
|
+
}
|
|
26165
|
+
if (block.type === "separator") {
|
|
26166
|
+
ensureSpace(context.separatorGap);
|
|
26167
|
+
renderSeparator(
|
|
26168
|
+
currentPage.page,
|
|
26169
|
+
context,
|
|
26170
|
+
currentPage.cursorY,
|
|
26171
|
+
context.margins[3],
|
|
26172
|
+
context.contentWidth
|
|
26173
|
+
);
|
|
26174
|
+
currentPage.cursorY += context.separatorGap;
|
|
26175
|
+
currentPage.isEmpty = false;
|
|
26176
|
+
continue;
|
|
26177
|
+
}
|
|
26178
|
+
if (block.type === "image") {
|
|
26179
|
+
ensureSpace(block.height);
|
|
26180
|
+
renderImageBlock(currentPage.page, block, context, currentPage.cursorY);
|
|
26181
|
+
currentPage.cursorY += block.height;
|
|
26182
|
+
currentPage.isEmpty = false;
|
|
26183
|
+
continue;
|
|
26184
|
+
}
|
|
26185
|
+
const tableLayout = layoutTable(block, context.contentWidth, context);
|
|
26186
|
+
currentPage = renderTableAcrossPages(
|
|
26187
|
+
block,
|
|
26188
|
+
tableLayout,
|
|
26189
|
+
currentPage,
|
|
26190
|
+
pages,
|
|
26191
|
+
context,
|
|
26192
|
+
contentTop,
|
|
26193
|
+
contentEnd
|
|
26194
|
+
);
|
|
26195
|
+
}
|
|
26196
|
+
return pages;
|
|
26197
|
+
}
|
|
26198
|
+
function renderParagraphAcrossPages(block, currentPage, pages, context, contentTop, contentEnd) {
|
|
26199
|
+
const layout = layoutParagraph(block, context.contentWidth, context);
|
|
26200
|
+
for (let lineIndex = 0; lineIndex < layout.lines.length; lineIndex++) {
|
|
26201
|
+
const line = layout.lines[lineIndex];
|
|
26202
|
+
if (currentPage.cursorY + line.height > contentEnd && !currentPage.isEmpty) {
|
|
26203
|
+
const page = context.pdfDoc.addPage([
|
|
26204
|
+
context.pageWidth,
|
|
26205
|
+
context.pageHeight
|
|
26206
|
+
]);
|
|
26207
|
+
currentPage = {
|
|
26208
|
+
page,
|
|
26209
|
+
cursorY: contentTop,
|
|
26210
|
+
isEmpty: true
|
|
26211
|
+
};
|
|
26212
|
+
pages.push(currentPage);
|
|
26213
|
+
}
|
|
26214
|
+
renderParagraphLine(
|
|
26215
|
+
currentPage.page,
|
|
26216
|
+
block,
|
|
26217
|
+
line,
|
|
26218
|
+
lineIndex === 0,
|
|
26219
|
+
layout,
|
|
26220
|
+
context,
|
|
26221
|
+
currentPage.cursorY,
|
|
26222
|
+
context.margins[3],
|
|
26223
|
+
context.contentWidth
|
|
26224
|
+
);
|
|
26225
|
+
currentPage.cursorY += line.height;
|
|
26226
|
+
currentPage.isEmpty = false;
|
|
26227
|
+
}
|
|
26228
|
+
return currentPage;
|
|
26229
|
+
}
|
|
26230
|
+
function renderTableAcrossPages(block, tableLayout, currentPage, pages, context, contentTop, contentEnd) {
|
|
26231
|
+
const scaledColWidths = scaleColumnWidths(
|
|
26232
|
+
block.colWidths,
|
|
26233
|
+
context.contentWidth
|
|
26234
|
+
);
|
|
26235
|
+
let tableTop = currentPage.cursorY;
|
|
26236
|
+
for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex++) {
|
|
26237
|
+
const row = block.rows[rowIndex];
|
|
26238
|
+
const rowHeight = tableLayout.rowHeights[rowIndex];
|
|
26239
|
+
const spanHeight = getSpanningRowHeight(
|
|
26240
|
+
block.rows,
|
|
26241
|
+
tableLayout.rowHeights,
|
|
26242
|
+
rowIndex
|
|
26243
|
+
);
|
|
26244
|
+
if (currentPage.cursorY + spanHeight > contentEnd && !currentPage.isEmpty) {
|
|
26245
|
+
const page = context.pdfDoc.addPage([
|
|
26246
|
+
context.pageWidth,
|
|
26247
|
+
context.pageHeight
|
|
26248
|
+
]);
|
|
26249
|
+
currentPage = {
|
|
26250
|
+
page,
|
|
26251
|
+
cursorY: contentTop,
|
|
26252
|
+
isEmpty: true
|
|
26253
|
+
};
|
|
26254
|
+
pages.push(currentPage);
|
|
26255
|
+
tableTop = currentPage.cursorY;
|
|
26256
|
+
}
|
|
26257
|
+
const rowTop = currentPage.cursorY;
|
|
26258
|
+
for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
|
|
26259
|
+
const cell = row.cells[cellIndex];
|
|
26260
|
+
const cellX = context.margins[3] + getColumnOffset(scaledColWidths, cell.colIndex);
|
|
26261
|
+
const cellWidth = getColumnSpanWidth(
|
|
26262
|
+
scaledColWidths,
|
|
26263
|
+
cell.colIndex,
|
|
26264
|
+
cell.colspan
|
|
26265
|
+
);
|
|
26266
|
+
const cellHeight = getRowSpanHeight(
|
|
26267
|
+
tableLayout.rowHeights,
|
|
26268
|
+
rowIndex,
|
|
26269
|
+
cell.rowspan
|
|
26270
|
+
);
|
|
26271
|
+
renderTableCell(
|
|
26272
|
+
currentPage.page,
|
|
26273
|
+
cell,
|
|
26274
|
+
context,
|
|
26275
|
+
block,
|
|
26276
|
+
cellX,
|
|
26277
|
+
rowTop,
|
|
26278
|
+
cellWidth,
|
|
26279
|
+
cellHeight
|
|
26280
|
+
);
|
|
26281
|
+
}
|
|
26282
|
+
currentPage.cursorY += rowHeight;
|
|
26283
|
+
currentPage.isEmpty = false;
|
|
26284
|
+
}
|
|
26285
|
+
return currentPage;
|
|
26286
|
+
}
|
|
26287
|
+
function renderPageDecorations(pages, context, headerBlocks, footerBlocks, headerHeight, footerHeight, footerBarHeight, pageNumber) {
|
|
26288
|
+
const totalPages = pages.length;
|
|
26289
|
+
for (let index = 0; index < pages.length; index++) {
|
|
26290
|
+
const pageState = pages[index];
|
|
26291
|
+
if (headerBlocks.length) {
|
|
26292
|
+
renderBlocksInRegion(
|
|
26293
|
+
pageState.page,
|
|
26294
|
+
headerBlocks,
|
|
26295
|
+
context,
|
|
26296
|
+
context.margins[3],
|
|
26297
|
+
context.headerTop,
|
|
26298
|
+
context.contentWidth
|
|
26299
|
+
);
|
|
26300
|
+
}
|
|
26301
|
+
if (footerBarHeight > 0) {
|
|
26302
|
+
if (context.options.footer.backgroundColor) {
|
|
26303
|
+
pageState.page.drawRectangle({
|
|
26304
|
+
x: 0,
|
|
26305
|
+
y: context.footerBottom,
|
|
26306
|
+
width: context.pageWidth,
|
|
26307
|
+
height: footerBarHeight,
|
|
26308
|
+
color: toPdfColor(context.options.footer.backgroundColor, "#FFFFFF")
|
|
26309
|
+
});
|
|
26310
|
+
}
|
|
26311
|
+
if (footerBlocks.length) {
|
|
26312
|
+
const footerTop = context.pageHeight - context.footerBottom - footerBarHeight;
|
|
26313
|
+
const footerContentTop = footerTop + Math.max(0, (footerBarHeight - footerHeight) / 2);
|
|
26314
|
+
renderBlocksInRegion(
|
|
26315
|
+
pageState.page,
|
|
26316
|
+
footerBlocks,
|
|
26317
|
+
context,
|
|
26318
|
+
context.margins[3],
|
|
26319
|
+
footerContentTop,
|
|
26320
|
+
context.contentWidth
|
|
26321
|
+
);
|
|
26322
|
+
}
|
|
26323
|
+
}
|
|
26324
|
+
renderPageNumber(pageState.page, context, pageNumber, index, totalPages);
|
|
26325
|
+
}
|
|
26326
|
+
}
|
|
26327
|
+
function renderBlocksInRegion(page, blocks, context, x, top, width) {
|
|
26328
|
+
let cursorY = top;
|
|
26329
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
26330
|
+
const block = blocks[i];
|
|
26331
|
+
if (block.type === "pageBreak") {
|
|
26332
|
+
continue;
|
|
26333
|
+
}
|
|
26334
|
+
if (block.type === "paragraph") {
|
|
26335
|
+
const layout = layoutParagraph(block, width, context);
|
|
26336
|
+
for (let lineIndex = 0; lineIndex < layout.lines.length; lineIndex++) {
|
|
26337
|
+
const line = layout.lines[lineIndex];
|
|
26338
|
+
renderParagraphLine(
|
|
26339
|
+
page,
|
|
26340
|
+
block,
|
|
26341
|
+
line,
|
|
26342
|
+
lineIndex === 0,
|
|
26343
|
+
layout,
|
|
26344
|
+
context,
|
|
26345
|
+
cursorY,
|
|
26346
|
+
x,
|
|
26347
|
+
width
|
|
26348
|
+
);
|
|
26349
|
+
cursorY += line.height;
|
|
26350
|
+
}
|
|
26351
|
+
continue;
|
|
26352
|
+
}
|
|
26353
|
+
if (block.type === "separator") {
|
|
26354
|
+
renderSeparator(page, context, cursorY, x, width);
|
|
26355
|
+
cursorY += context.separatorGap;
|
|
26356
|
+
continue;
|
|
26357
|
+
}
|
|
26358
|
+
if (block.type === "image") {
|
|
26359
|
+
renderImageBlock(page, block, context, cursorY, x, width);
|
|
26360
|
+
cursorY += block.height;
|
|
26361
|
+
continue;
|
|
26362
|
+
}
|
|
26363
|
+
const tableLayout = layoutTable(block, width, context);
|
|
26364
|
+
const scaledColWidths = scaleColumnWidths(block.colWidths, width);
|
|
26365
|
+
for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex++) {
|
|
26366
|
+
const row = block.rows[rowIndex];
|
|
26367
|
+
const rowTop = cursorY;
|
|
26368
|
+
for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
|
|
26369
|
+
const cell = row.cells[cellIndex];
|
|
26370
|
+
const cellX = x + getColumnOffset(scaledColWidths, cell.colIndex);
|
|
26371
|
+
const cellWidth = getColumnSpanWidth(
|
|
26372
|
+
scaledColWidths,
|
|
26373
|
+
cell.colIndex,
|
|
26374
|
+
cell.colspan
|
|
26375
|
+
);
|
|
26376
|
+
const cellHeight = getRowSpanHeight(
|
|
26377
|
+
tableLayout.rowHeights,
|
|
26378
|
+
rowIndex,
|
|
26379
|
+
cell.rowspan
|
|
26380
|
+
);
|
|
26381
|
+
renderTableCell(
|
|
26382
|
+
page,
|
|
26383
|
+
cell,
|
|
26384
|
+
context,
|
|
26385
|
+
block,
|
|
26386
|
+
cellX,
|
|
26387
|
+
rowTop,
|
|
26388
|
+
cellWidth,
|
|
26389
|
+
cellHeight
|
|
26390
|
+
);
|
|
26391
|
+
}
|
|
26392
|
+
cursorY += tableLayout.rowHeights[rowIndex];
|
|
26393
|
+
}
|
|
26394
|
+
}
|
|
26395
|
+
}
|
|
26396
|
+
function renderParagraphLine(page, block, line, isFirstLine, layout, context, top, baseX, regionWidth) {
|
|
26397
|
+
const alignment = normalizeAlignment(block.context.alignment);
|
|
26398
|
+
const lineWidth = line.width;
|
|
26399
|
+
const availableWidth = Math.max(
|
|
26400
|
+
1,
|
|
26401
|
+
regionWidth - layout.listIndent - layout.markerWidth
|
|
26402
|
+
);
|
|
26403
|
+
const justifyExtra = alignment === "justify" /* JUSTIFY */ && !isLastParagraphLine(layout, line) ? getJustifyExtra(line, availableWidth) : 0;
|
|
26404
|
+
let offsetX = 0;
|
|
26405
|
+
if (alignment === "center" /* CENTER */) {
|
|
26406
|
+
offsetX = (availableWidth - lineWidth) / 2;
|
|
26407
|
+
} else if (alignment === "right" /* RIGHT */) {
|
|
26408
|
+
offsetX = availableWidth - lineWidth;
|
|
26409
|
+
}
|
|
26410
|
+
const lineStart = baseX + layout.listIndent + layout.markerWidth + Math.max(0, offsetX);
|
|
26411
|
+
if (isFirstLine && block.context.listMarker) {
|
|
26412
|
+
const markerRun = getMarkerRun(block, context);
|
|
26413
|
+
const markerText = block.context.listMarker.text;
|
|
26414
|
+
drawTextRun(
|
|
26415
|
+
page,
|
|
26416
|
+
markerRun,
|
|
26417
|
+
markerText,
|
|
26418
|
+
baseX + layout.listIndent,
|
|
26419
|
+
top,
|
|
26420
|
+
line.height,
|
|
26421
|
+
context
|
|
26422
|
+
);
|
|
26423
|
+
}
|
|
26424
|
+
let cursorX = lineStart;
|
|
26425
|
+
for (let index = 0; index < line.fragments.length; index++) {
|
|
26426
|
+
const fragment = line.fragments[index];
|
|
26427
|
+
if (fragment.kind === "space" && justifyExtra > 0) {
|
|
26428
|
+
cursorX += justifyExtra;
|
|
26429
|
+
}
|
|
26430
|
+
drawLineFragment(page, fragment, cursorX, top, line.height, context);
|
|
26431
|
+
cursorX += fragment.width;
|
|
26432
|
+
}
|
|
26433
|
+
}
|
|
26434
|
+
function renderSeparator(page, context, top, x, width) {
|
|
26435
|
+
const lineY = toPdfY(context.pageHeight, top + SEPARATOR_HEIGHT / 2);
|
|
26436
|
+
page.drawLine({
|
|
26437
|
+
start: { x, y: lineY },
|
|
26438
|
+
end: { x: x + width, y: lineY },
|
|
26439
|
+
thickness: 1,
|
|
26440
|
+
color: (0, import_pdf_lib.rgb)(0.6, 0.6, 0.6)
|
|
26441
|
+
});
|
|
26442
|
+
}
|
|
26443
|
+
function renderImageBlock(page, block, context, top, baseX = context.margins[3], width = context.contentWidth) {
|
|
26444
|
+
const alignment = normalizeAlignment(block.alignment);
|
|
26445
|
+
let x = baseX;
|
|
26446
|
+
if (alignment === "center" /* CENTER */) {
|
|
26447
|
+
x += Math.max(0, (width - block.width) / 2);
|
|
26448
|
+
} else if (alignment === "right" /* RIGHT */) {
|
|
26449
|
+
x += Math.max(0, width - block.width);
|
|
26450
|
+
}
|
|
26451
|
+
page.drawImage(block.image, {
|
|
26452
|
+
x,
|
|
26453
|
+
y: toPdfY(context.pageHeight, top, block.height),
|
|
26454
|
+
width: block.width,
|
|
26455
|
+
height: block.height
|
|
26456
|
+
});
|
|
26457
|
+
}
|
|
26458
|
+
function renderTableCell(page, cell, context, table, x, top, width, height) {
|
|
26459
|
+
if (cell.backgroundColor) {
|
|
26460
|
+
page.drawRectangle({
|
|
26461
|
+
x,
|
|
26462
|
+
y: toPdfY(context.pageHeight, top, height),
|
|
26463
|
+
width,
|
|
26464
|
+
height,
|
|
26465
|
+
color: toPdfColor(cell.backgroundColor)
|
|
26466
|
+
});
|
|
26467
|
+
}
|
|
26468
|
+
drawTableCellBorders(page, cell, context, table, x, top, width, height);
|
|
26469
|
+
const padding = getPadding(cell.padding || defaultTableOption.tdPadding).map(
|
|
26470
|
+
pxToPt
|
|
26471
|
+
);
|
|
26472
|
+
const contentWidth = Math.max(1, width - padding[1] - padding[3]);
|
|
26473
|
+
const contentHeight = measureBlocksHeight(cell.blocks, contentWidth, context);
|
|
26474
|
+
let contentTop = top + padding[0];
|
|
26475
|
+
if (cell.verticalAlign === VerticalAlign.CENTER) {
|
|
26476
|
+
contentTop = top + (height - contentHeight) / 2;
|
|
26477
|
+
} else if (cell.verticalAlign === "bottom" /* BOTTOM */) {
|
|
26478
|
+
contentTop = top + height - contentHeight - padding[2];
|
|
26479
|
+
}
|
|
26480
|
+
renderBlocksInRegion(
|
|
26481
|
+
page,
|
|
26482
|
+
cell.blocks,
|
|
26483
|
+
context,
|
|
26484
|
+
x + padding[3],
|
|
26485
|
+
contentTop,
|
|
26486
|
+
contentWidth
|
|
26487
|
+
);
|
|
26488
|
+
}
|
|
26489
|
+
function renderPageNumber(page, context, pageNumber, pageIndex, totalPages) {
|
|
26490
|
+
if (pageNumber.disabled || pageIndex < pageNumber.fromPageNo || Number.isInteger(pageNumber.maxPageNo) && pageIndex >= pageNumber.maxPageNo) {
|
|
26491
|
+
return;
|
|
26492
|
+
}
|
|
26493
|
+
let text = pageNumber.format || FORMAT_PLACEHOLDER.PAGE_NO;
|
|
26494
|
+
const currentValue = pageIndex + pageNumber.startPageNo - pageNumber.fromPageNo;
|
|
26495
|
+
const totalValue = totalPages - pageNumber.fromPageNo;
|
|
26496
|
+
text = text.replace(
|
|
26497
|
+
new RegExp(FORMAT_PLACEHOLDER.PAGE_NO, "g"),
|
|
26498
|
+
`${currentValue}`
|
|
26499
|
+
);
|
|
26500
|
+
text = text.replace(
|
|
26501
|
+
new RegExp(FORMAT_PLACEHOLDER.PAGE_COUNT, "g"),
|
|
26502
|
+
`${Math.max(0, totalValue)}`
|
|
26503
|
+
);
|
|
26504
|
+
const font = getFont(
|
|
26505
|
+
pageNumber.font || context.options.defaultFont,
|
|
26506
|
+
false,
|
|
26507
|
+
false,
|
|
26508
|
+
context
|
|
26509
|
+
);
|
|
26510
|
+
const size = pageNumber.size || 12;
|
|
26511
|
+
const bottom = pxToPt(pageNumber.bottom || 0);
|
|
26512
|
+
const safeText = sanitizeTextForPdf(text, font);
|
|
26513
|
+
const width = font.widthOfTextAtSize(safeText, size);
|
|
26514
|
+
const descenderHeight = Math.max(
|
|
26515
|
+
0,
|
|
26516
|
+
font.heightAtSize(size) - font.heightAtSize(size, { descender: false })
|
|
26517
|
+
);
|
|
26518
|
+
let x = context.margins[3];
|
|
26519
|
+
const alignment = normalizeAlignment(pageNumber.rowFlex);
|
|
26520
|
+
if (alignment === "center" /* CENTER */) {
|
|
26521
|
+
x = (context.pageWidth - width) / 2;
|
|
26522
|
+
} else if (alignment === "right" /* RIGHT */) {
|
|
26523
|
+
x = context.pageWidth - context.margins[1] - width;
|
|
26524
|
+
}
|
|
26525
|
+
page.drawText(safeText, {
|
|
26526
|
+
x,
|
|
26527
|
+
// Canvas draw uses the alphabetic baseline at `pageHeight - bottom`.
|
|
26528
|
+
// pdf-lib positions text from the text box bottom, so compensate by the
|
|
26529
|
+
// descender height to keep the baseline aligned.
|
|
26530
|
+
y: bottom - descenderHeight,
|
|
26531
|
+
size,
|
|
26532
|
+
font,
|
|
26533
|
+
color: toPdfColor(pageNumber.color, "#000000")
|
|
26534
|
+
});
|
|
26535
|
+
}
|
|
26536
|
+
function layoutParagraph(block, width, context) {
|
|
26537
|
+
const markerWidth = getMarkerWidth(block, context);
|
|
26538
|
+
const listIndent = block.context.listMarker ? pxToPt(block.context.listMarker.level * INDENT_PER_LEVEL) : 0;
|
|
26539
|
+
const availableWidth = Math.max(1, width - listIndent - markerWidth);
|
|
26540
|
+
const tokens = tokenizeParagraphRuns(block.runs, context);
|
|
26541
|
+
const lines = [];
|
|
26542
|
+
let line = {
|
|
26543
|
+
fragments: [],
|
|
26544
|
+
width: 0,
|
|
26545
|
+
height: getEmptyLineHeight(block, context)
|
|
26546
|
+
};
|
|
26547
|
+
const commitLine = () => {
|
|
26548
|
+
trimTrailingSpaces(line);
|
|
26549
|
+
lines.push(line);
|
|
26550
|
+
line = {
|
|
26551
|
+
fragments: [],
|
|
26552
|
+
width: 0,
|
|
26553
|
+
height: getEmptyLineHeight(block, context)
|
|
26554
|
+
};
|
|
26555
|
+
};
|
|
26556
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
26557
|
+
let token = tokens[i];
|
|
26558
|
+
if (token.kind === "space" && !line.fragments.length) {
|
|
26559
|
+
continue;
|
|
26560
|
+
}
|
|
26561
|
+
if (token.width > availableWidth && token.kind === "text" && token.run.type === "text") {
|
|
26562
|
+
const segments = splitTextToken(token, availableWidth, context);
|
|
26563
|
+
for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
|
|
26564
|
+
tokens.splice(i + segmentIndex, 0, segments[segmentIndex]);
|
|
26565
|
+
}
|
|
26566
|
+
continue;
|
|
26567
|
+
}
|
|
26568
|
+
if (line.width + token.width > availableWidth && line.fragments.length) {
|
|
26569
|
+
commitLine();
|
|
26570
|
+
i--;
|
|
26571
|
+
continue;
|
|
26572
|
+
}
|
|
26573
|
+
line.fragments.push(token);
|
|
26574
|
+
line.width += token.width;
|
|
26575
|
+
line.height = Math.max(line.height, token.height);
|
|
26576
|
+
}
|
|
26577
|
+
if (line.fragments.length || !lines.length) {
|
|
26578
|
+
commitLine();
|
|
26579
|
+
}
|
|
26580
|
+
return {
|
|
26581
|
+
lines,
|
|
26582
|
+
height: lines.reduce((sum, current) => sum + current.height, 0),
|
|
26583
|
+
markerWidth,
|
|
26584
|
+
listIndent
|
|
26585
|
+
};
|
|
26586
|
+
}
|
|
26587
|
+
function tokenizeParagraphRuns(runs, context) {
|
|
26588
|
+
const fragments = [];
|
|
26589
|
+
for (let index = 0; index < runs.length; index++) {
|
|
26590
|
+
const run = runs[index];
|
|
26591
|
+
if (run.type === "tab") {
|
|
26592
|
+
fragments.push({
|
|
26593
|
+
kind: "tab",
|
|
26594
|
+
width: run.width,
|
|
26595
|
+
height: 0,
|
|
26596
|
+
run
|
|
26597
|
+
});
|
|
26598
|
+
continue;
|
|
26599
|
+
}
|
|
26600
|
+
if (run.type === "image") {
|
|
26601
|
+
fragments.push({
|
|
26602
|
+
kind: "image",
|
|
26603
|
+
width: run.width,
|
|
26604
|
+
height: run.height,
|
|
26605
|
+
run
|
|
26606
|
+
});
|
|
26607
|
+
continue;
|
|
26608
|
+
}
|
|
26609
|
+
if (run.type === "badge") {
|
|
26610
|
+
const badgeWidth = measureBadgeWidth(run, context);
|
|
26611
|
+
const badgeHeight = measureBadgeHeight(run);
|
|
26612
|
+
fragments.push({
|
|
26613
|
+
kind: "badge",
|
|
26614
|
+
width: badgeWidth,
|
|
26615
|
+
height: badgeHeight,
|
|
26616
|
+
run
|
|
26617
|
+
});
|
|
26618
|
+
continue;
|
|
26619
|
+
}
|
|
26620
|
+
const parts = run.text.split(/(\s+)/);
|
|
26621
|
+
for (let partIndex = 0; partIndex < parts.length; partIndex++) {
|
|
26622
|
+
const part = parts[partIndex];
|
|
26623
|
+
if (!part) continue;
|
|
26624
|
+
const isWhitespace = /^\s+$/.test(part);
|
|
26625
|
+
fragments.push({
|
|
26626
|
+
kind: isWhitespace ? "space" : "text",
|
|
26627
|
+
width: measureTextWidth(part, run, context),
|
|
26628
|
+
height: getRunHeight(run),
|
|
26629
|
+
run: { ...run, text: part }
|
|
26630
|
+
});
|
|
26631
|
+
}
|
|
26632
|
+
}
|
|
26633
|
+
return fragments;
|
|
26634
|
+
}
|
|
26635
|
+
function splitTextToken(token, availableWidth, context) {
|
|
26636
|
+
if (token.run.type !== "text") {
|
|
26637
|
+
return [token];
|
|
26638
|
+
}
|
|
26639
|
+
const chars = splitText(token.run.text);
|
|
26640
|
+
const result = [];
|
|
26641
|
+
let current = "";
|
|
26642
|
+
for (let i = 0; i < chars.length; i++) {
|
|
26643
|
+
const next = current + chars[i];
|
|
26644
|
+
const width = measureTextWidth(next, token.run, context);
|
|
26645
|
+
if (width > availableWidth && current) {
|
|
26646
|
+
result.push({
|
|
26647
|
+
kind: "text",
|
|
26648
|
+
width: measureTextWidth(current, token.run, context),
|
|
26649
|
+
height: getRunHeight(token.run),
|
|
26650
|
+
run: { ...token.run, text: current }
|
|
26651
|
+
});
|
|
26652
|
+
current = chars[i];
|
|
26653
|
+
} else {
|
|
26654
|
+
current = next;
|
|
26655
|
+
}
|
|
26656
|
+
}
|
|
26657
|
+
if (current) {
|
|
26658
|
+
result.push({
|
|
26659
|
+
kind: /^\s+$/.test(current) ? "space" : "text",
|
|
26660
|
+
width: measureTextWidth(current, token.run, context),
|
|
26661
|
+
height: getRunHeight(token.run),
|
|
26662
|
+
run: { ...token.run, text: current }
|
|
26663
|
+
});
|
|
26664
|
+
}
|
|
26665
|
+
return result.length ? result : [token];
|
|
26666
|
+
}
|
|
26667
|
+
function trimTrailingSpaces(line) {
|
|
26668
|
+
while (line.fragments.length && line.fragments[line.fragments.length - 1].kind === "space") {
|
|
26669
|
+
const fragment = line.fragments.pop();
|
|
26670
|
+
line.width -= fragment.width;
|
|
26671
|
+
}
|
|
26672
|
+
}
|
|
26673
|
+
function layoutTable(table, width, context) {
|
|
26674
|
+
const rowHeights = table.rows.map(
|
|
26675
|
+
(row) => Math.max(
|
|
26676
|
+
pxToPt(row.height),
|
|
26677
|
+
pxToPt(context.options.table.defaultTrMinHeight)
|
|
26678
|
+
)
|
|
26679
|
+
);
|
|
26680
|
+
const scaledColWidths = scaleColumnWidths(table.colWidths, width);
|
|
26681
|
+
for (let rowIndex = 0; rowIndex < table.rows.length; rowIndex++) {
|
|
26682
|
+
const row = table.rows[rowIndex];
|
|
26683
|
+
for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
|
|
26684
|
+
const cell = row.cells[cellIndex];
|
|
26685
|
+
const cellWidth = getColumnSpanWidth(
|
|
26686
|
+
scaledColWidths,
|
|
26687
|
+
cell.colIndex,
|
|
26688
|
+
cell.colspan
|
|
26689
|
+
);
|
|
26690
|
+
const padding = getPadding(
|
|
26691
|
+
cell.padding || defaultTableOption.tdPadding
|
|
26692
|
+
).map(pxToPt);
|
|
26693
|
+
const contentWidth = Math.max(1, cellWidth - padding[1] - padding[3]);
|
|
26694
|
+
const contentHeight = measureBlocksHeight(cell.blocks, contentWidth, context) + padding[0] + padding[2];
|
|
26695
|
+
const spanHeight = getRowSpanHeight(rowHeights, rowIndex, cell.rowspan);
|
|
26696
|
+
if (contentHeight > spanHeight) {
|
|
26697
|
+
rowHeights[rowIndex + cell.rowspan - 1] += contentHeight - spanHeight;
|
|
26698
|
+
}
|
|
26699
|
+
}
|
|
26700
|
+
}
|
|
26701
|
+
return {
|
|
26702
|
+
rowHeights,
|
|
26703
|
+
totalHeight: rowHeights.reduce((sum, height) => sum + height, 0)
|
|
26704
|
+
};
|
|
26705
|
+
}
|
|
26706
|
+
function measureBlocksHeight(blocks, width, context) {
|
|
26707
|
+
let height = 0;
|
|
26708
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
26709
|
+
const block = blocks[i];
|
|
26710
|
+
if (block.type === "pageBreak") {
|
|
26711
|
+
continue;
|
|
26712
|
+
}
|
|
26713
|
+
if (block.type === "paragraph") {
|
|
26714
|
+
height += layoutParagraph(block, width, context).height;
|
|
26715
|
+
continue;
|
|
26716
|
+
}
|
|
26717
|
+
if (block.type === "separator") {
|
|
26718
|
+
height += context.separatorGap;
|
|
26719
|
+
continue;
|
|
26720
|
+
}
|
|
26721
|
+
if (block.type === "image") {
|
|
26722
|
+
height += block.height;
|
|
26723
|
+
continue;
|
|
26724
|
+
}
|
|
26725
|
+
height += layoutTable(block, width, context).totalHeight;
|
|
26726
|
+
}
|
|
26727
|
+
return height;
|
|
26728
|
+
}
|
|
26729
|
+
function drawLineFragment(page, fragment, x, top, lineHeight, context) {
|
|
26730
|
+
if (fragment.run.type === "tab") {
|
|
26731
|
+
return;
|
|
26732
|
+
}
|
|
26733
|
+
if (fragment.run.type === "image") {
|
|
26734
|
+
const imageTop = top + (lineHeight - fragment.run.height) / 2;
|
|
26735
|
+
page.drawImage(fragment.run.image, {
|
|
26736
|
+
x,
|
|
26737
|
+
y: toPdfY(context.pageHeight, imageTop, fragment.run.height),
|
|
26738
|
+
width: fragment.run.width,
|
|
26739
|
+
height: fragment.run.height
|
|
26740
|
+
});
|
|
26741
|
+
return;
|
|
26742
|
+
}
|
|
26743
|
+
if (fragment.run.type === "badge") {
|
|
26744
|
+
const badgeHeight = measureBadgeHeight(fragment.run);
|
|
26745
|
+
const badgeTop = top + (lineHeight - badgeHeight) / 2;
|
|
26746
|
+
const padding = getPadding(fragment.run.padding || [2, 4, 2, 4]).map(
|
|
26747
|
+
pxToPt
|
|
26748
|
+
);
|
|
26749
|
+
page.drawRectangle({
|
|
26750
|
+
x,
|
|
26751
|
+
y: toPdfY(context.pageHeight, badgeTop, badgeHeight),
|
|
26752
|
+
width: fragment.width,
|
|
26753
|
+
height: badgeHeight,
|
|
26754
|
+
color: toPdfColor(fragment.run.backgroundColor, "#FFFFFF"),
|
|
26755
|
+
borderColor: fragment.run.borderColor ? toPdfColor(fragment.run.borderColor) : void 0,
|
|
26756
|
+
borderWidth: fragment.run.borderColor ? 0.75 : void 0
|
|
26757
|
+
});
|
|
26758
|
+
drawTextRun(
|
|
26759
|
+
page,
|
|
26760
|
+
fragment.run,
|
|
26761
|
+
fragment.run.text,
|
|
26762
|
+
x + padding[3],
|
|
26763
|
+
badgeTop + padding[0],
|
|
26764
|
+
badgeHeight - padding[0] - padding[2],
|
|
26765
|
+
context
|
|
26766
|
+
);
|
|
26767
|
+
return;
|
|
26768
|
+
}
|
|
26769
|
+
if (fragment.run.type !== "text") {
|
|
26770
|
+
return;
|
|
26771
|
+
}
|
|
26772
|
+
drawTextRun(
|
|
26773
|
+
page,
|
|
26774
|
+
fragment.run,
|
|
26775
|
+
fragment.run.text,
|
|
26776
|
+
x,
|
|
26777
|
+
top,
|
|
26778
|
+
lineHeight,
|
|
26779
|
+
context
|
|
26780
|
+
);
|
|
26781
|
+
}
|
|
26782
|
+
function drawTextRun(page, run, text, x, top, lineHeight, context) {
|
|
26783
|
+
const resolved = resolveTextMetrics(run, context);
|
|
26784
|
+
const safeText = sanitizeTextForPdf(text, resolved.font);
|
|
26785
|
+
let textTop = top + (lineHeight - resolved.size) / 2;
|
|
26786
|
+
if (run.type === "text" && run.superscript) {
|
|
26787
|
+
textTop -= resolved.size * 0.25;
|
|
26788
|
+
}
|
|
26789
|
+
if (run.type === "text" && run.subscript) {
|
|
26790
|
+
textTop += resolved.size * 0.2;
|
|
26791
|
+
}
|
|
26792
|
+
const textY = toPdfY(context.pageHeight, textTop, resolved.size);
|
|
26793
|
+
if ("highlight" in run && run.highlight) {
|
|
26794
|
+
page.drawRectangle({
|
|
26795
|
+
x,
|
|
26796
|
+
y: textY,
|
|
26797
|
+
width: resolved.font.widthOfTextAtSize(safeText, resolved.size),
|
|
26798
|
+
height: resolved.size * 1.05,
|
|
26799
|
+
color: toPdfColor(run.highlight)
|
|
26800
|
+
});
|
|
26801
|
+
}
|
|
26802
|
+
page.drawText(safeText, {
|
|
26803
|
+
x,
|
|
26804
|
+
y: textY,
|
|
26805
|
+
size: resolved.size,
|
|
26806
|
+
font: resolved.font,
|
|
26807
|
+
color: toPdfColor(run.color, "#000000")
|
|
26808
|
+
});
|
|
26809
|
+
const textWidth = resolved.font.widthOfTextAtSize(safeText, resolved.size);
|
|
26810
|
+
if (run.underline) {
|
|
26811
|
+
const underlineY = textY - 1;
|
|
26812
|
+
page.drawLine({
|
|
26813
|
+
start: { x, y: underlineY },
|
|
26814
|
+
end: { x: x + textWidth, y: underlineY },
|
|
26815
|
+
thickness: 0.75,
|
|
26816
|
+
color: toPdfColor(run.color, "#000000")
|
|
26817
|
+
});
|
|
26818
|
+
}
|
|
26819
|
+
if (run.strikeout) {
|
|
26820
|
+
const strikeY = textY + resolved.size * 0.35;
|
|
26821
|
+
page.drawLine({
|
|
26822
|
+
start: { x, y: strikeY },
|
|
26823
|
+
end: { x: x + textWidth, y: strikeY },
|
|
26824
|
+
thickness: 0.75,
|
|
26825
|
+
color: toPdfColor(run.color, "#000000")
|
|
26826
|
+
});
|
|
26827
|
+
}
|
|
26828
|
+
}
|
|
26829
|
+
function drawTableCellBorders(page, cell, context, table, x, top, width, height) {
|
|
26830
|
+
const tableColor = table.borderColor || context.options.table.defaultBorderColor;
|
|
26831
|
+
const innerWidth = table.borderWidth || 1;
|
|
26832
|
+
const outerWidth = table.borderExternalWidth || innerWidth;
|
|
26833
|
+
const color = cell.borderColor || tableColor;
|
|
26834
|
+
const isEmpty = table.borderType === "empty" /* EMPTY */;
|
|
26835
|
+
const isExternal = table.borderType === "external" /* EXTERNAL */;
|
|
26836
|
+
const isInternal = table.borderType === "internal" /* INTERNAL */;
|
|
26837
|
+
const isDash = table.borderType === "dash" /* DASH */;
|
|
26838
|
+
const dashArray = isDash ? [3, 3] : void 0;
|
|
26839
|
+
const lineColor = toPdfColor(color, "#000000");
|
|
26840
|
+
const bottomY = toPdfY(context.pageHeight, top, height);
|
|
26841
|
+
const topY = toPdfY(context.pageHeight, top);
|
|
26842
|
+
const rightX = x + width;
|
|
26843
|
+
const drawEdge = (startX, startY, endX, endY, thickness) => {
|
|
26844
|
+
page.drawLine({
|
|
26845
|
+
start: { x: startX, y: startY },
|
|
26846
|
+
end: { x: endX, y: endY },
|
|
26847
|
+
thickness,
|
|
26848
|
+
color: lineColor,
|
|
26849
|
+
dashArray
|
|
26850
|
+
});
|
|
26851
|
+
};
|
|
26852
|
+
if (cell.borderTypes?.length) {
|
|
26853
|
+
if (cell.borderTypes.includes("top" /* TOP */)) {
|
|
26854
|
+
drawEdge(x, topY, rightX, topY, innerWidth);
|
|
26855
|
+
}
|
|
26856
|
+
if (cell.borderTypes.includes("right" /* RIGHT */)) {
|
|
26857
|
+
drawEdge(rightX, topY, rightX, bottomY, innerWidth);
|
|
26858
|
+
}
|
|
26859
|
+
if (cell.borderTypes.includes("bottom" /* BOTTOM */)) {
|
|
26860
|
+
drawEdge(x, bottomY, rightX, bottomY, innerWidth);
|
|
26861
|
+
}
|
|
26862
|
+
if (cell.borderTypes.includes("left" /* LEFT */)) {
|
|
26863
|
+
drawEdge(x, topY, x, bottomY, innerWidth);
|
|
26864
|
+
}
|
|
26865
|
+
}
|
|
26866
|
+
if (cell.borderColor && !cell.borderTypes?.length) {
|
|
26867
|
+
drawEdge(x, topY, rightX, topY, innerWidth);
|
|
26868
|
+
drawEdge(rightX, topY, rightX, bottomY, innerWidth);
|
|
26869
|
+
drawEdge(x, bottomY, rightX, bottomY, innerWidth);
|
|
26870
|
+
drawEdge(x, topY, x, bottomY, innerWidth);
|
|
26871
|
+
return;
|
|
26872
|
+
}
|
|
26873
|
+
if (isEmpty) {
|
|
26874
|
+
return;
|
|
26875
|
+
}
|
|
26876
|
+
if (!isInternal) {
|
|
26877
|
+
drawEdge(x, topY, rightX, topY, outerWidth);
|
|
26878
|
+
drawEdge(x, topY, x, bottomY, outerWidth);
|
|
26879
|
+
drawEdge(rightX, topY, rightX, bottomY, outerWidth);
|
|
26880
|
+
drawEdge(x, bottomY, rightX, bottomY, outerWidth);
|
|
26881
|
+
if (isExternal) {
|
|
26882
|
+
return;
|
|
26883
|
+
}
|
|
26884
|
+
}
|
|
26885
|
+
drawEdge(rightX, topY, rightX, bottomY, innerWidth);
|
|
26886
|
+
drawEdge(x, bottomY, rightX, bottomY, innerWidth);
|
|
26887
|
+
}
|
|
26888
|
+
function getMarkerWidth(block, context) {
|
|
26889
|
+
if (!block.context.listMarker) {
|
|
26890
|
+
return 0;
|
|
26891
|
+
}
|
|
26892
|
+
const markerRun = getMarkerRun(block, context);
|
|
26893
|
+
return measureTextWidth(block.context.listMarker.text, markerRun, context) + pxToPt(LIST_GAP);
|
|
26894
|
+
}
|
|
26895
|
+
function getMarkerRun(block, context) {
|
|
26896
|
+
const firstTextRun = block.runs.find((run) => run.type === "text" || run.type === "badge") || null;
|
|
26897
|
+
if (!firstTextRun) {
|
|
26898
|
+
return {
|
|
26899
|
+
type: "text",
|
|
26900
|
+
text: "",
|
|
26901
|
+
size: context.options.defaultSize,
|
|
26902
|
+
font: context.options.defaultFont
|
|
26903
|
+
};
|
|
26904
|
+
}
|
|
26905
|
+
if (firstTextRun.type === "badge") {
|
|
26906
|
+
return {
|
|
26907
|
+
type: "text",
|
|
26908
|
+
text: firstTextRun.text,
|
|
26909
|
+
size: firstTextRun.size,
|
|
26910
|
+
font: firstTextRun.font,
|
|
26911
|
+
bold: firstTextRun.bold,
|
|
26912
|
+
italic: firstTextRun.italic,
|
|
26913
|
+
color: firstTextRun.color
|
|
26914
|
+
};
|
|
26915
|
+
}
|
|
26916
|
+
return firstTextRun;
|
|
26917
|
+
}
|
|
26918
|
+
function getEmptyLineHeight(block, context) {
|
|
26919
|
+
const markerRun = getMarkerRun(block, context);
|
|
26920
|
+
return getRunHeight(
|
|
26921
|
+
markerRun,
|
|
26922
|
+
block.context.rowMargin || context.options.defaultRowMargin
|
|
26923
|
+
);
|
|
26924
|
+
}
|
|
26925
|
+
function getRunHeight(run, rowMargin = DEFAULT_LINE_HEIGHT2) {
|
|
26926
|
+
return run.size * rowMargin;
|
|
26927
|
+
}
|
|
26928
|
+
function resolveTextMetrics(run, context) {
|
|
26929
|
+
let size = run.size || context.options.defaultSize;
|
|
26930
|
+
if ("superscript" in run && run.superscript) {
|
|
26931
|
+
size *= 0.65;
|
|
26932
|
+
}
|
|
26933
|
+
if ("subscript" in run && run.subscript) {
|
|
26934
|
+
size *= 0.65;
|
|
26935
|
+
}
|
|
26936
|
+
return {
|
|
26937
|
+
size,
|
|
26938
|
+
font: getFont(
|
|
26939
|
+
run.font || context.options.defaultFont,
|
|
26940
|
+
!!run.bold,
|
|
26941
|
+
!!run.italic,
|
|
26942
|
+
context
|
|
26943
|
+
)
|
|
26944
|
+
};
|
|
26945
|
+
}
|
|
26946
|
+
function measureTextWidth(text, run, context) {
|
|
26947
|
+
const resolved = resolveTextMetrics(run, context);
|
|
26948
|
+
const safeText = sanitizeTextForPdf(text, resolved.font);
|
|
26949
|
+
return resolved.font.widthOfTextAtSize(safeText, resolved.size);
|
|
26950
|
+
}
|
|
26951
|
+
function measureBadgeWidth(run, context) {
|
|
26952
|
+
const padding = getPadding(run.padding || [2, 4, 2, 4]).map(pxToPt);
|
|
26953
|
+
return measureTextWidth(run.text, run, context) + padding[1] + padding[3];
|
|
26954
|
+
}
|
|
26955
|
+
function measureBadgeHeight(run) {
|
|
26956
|
+
const padding = getPadding(run.padding || [2, 4, 2, 4]).map(pxToPt);
|
|
26957
|
+
return run.size + padding[0] + padding[2];
|
|
26958
|
+
}
|
|
26959
|
+
function getJustifyExtra(line, availableWidth) {
|
|
26960
|
+
const spaceCount = line.fragments.filter(
|
|
26961
|
+
(fragment) => fragment.kind === "space"
|
|
26962
|
+
).length;
|
|
26963
|
+
if (!spaceCount || line.width >= availableWidth) {
|
|
26964
|
+
return 0;
|
|
26965
|
+
}
|
|
26966
|
+
return (availableWidth - line.width) / spaceCount;
|
|
26967
|
+
}
|
|
26968
|
+
function isLastParagraphLine(layout, line) {
|
|
26969
|
+
return layout.lines[layout.lines.length - 1] === line;
|
|
26970
|
+
}
|
|
26971
|
+
function getSpanningRowHeight(rows, rowHeights, rowIndex) {
|
|
26972
|
+
const row = rows[rowIndex];
|
|
26973
|
+
let maxHeight = rowHeights[rowIndex];
|
|
26974
|
+
for (let i = 0; i < row.cells.length; i++) {
|
|
26975
|
+
const cell = row.cells[i];
|
|
26976
|
+
maxHeight = Math.max(
|
|
26977
|
+
maxHeight,
|
|
26978
|
+
getRowSpanHeight(rowHeights, rowIndex, cell.rowspan)
|
|
26979
|
+
);
|
|
26980
|
+
}
|
|
26981
|
+
return maxHeight;
|
|
26982
|
+
}
|
|
26983
|
+
function getRowSpanHeight(rowHeights, rowIndex, rowSpan) {
|
|
26984
|
+
let height = 0;
|
|
26985
|
+
for (let i = rowIndex; i < rowIndex + rowSpan; i++) {
|
|
26986
|
+
height += rowHeights[i] || 0;
|
|
26987
|
+
}
|
|
26988
|
+
return height;
|
|
26989
|
+
}
|
|
26990
|
+
function scaleColumnWidths(widths, maxWidth) {
|
|
26991
|
+
const ptWidths = widths.map(pxToPt);
|
|
26992
|
+
const total = ptWidths.reduce((sum, width) => sum + width, 0);
|
|
26993
|
+
if (!total || total <= maxWidth) {
|
|
26994
|
+
return ptWidths;
|
|
26995
|
+
}
|
|
26996
|
+
const ratio = maxWidth / total;
|
|
26997
|
+
return ptWidths.map((width) => width * ratio);
|
|
26998
|
+
}
|
|
26999
|
+
function getColumnOffset(widths, colIndex) {
|
|
27000
|
+
let offset = 0;
|
|
27001
|
+
for (let i = 0; i < colIndex; i++) {
|
|
27002
|
+
offset += widths[i] || 0;
|
|
27003
|
+
}
|
|
27004
|
+
return offset;
|
|
27005
|
+
}
|
|
27006
|
+
function getColumnSpanWidth(widths, colIndex, span) {
|
|
27007
|
+
let width = 0;
|
|
27008
|
+
for (let i = colIndex; i < colIndex + span; i++) {
|
|
27009
|
+
width += widths[i] || 0;
|
|
27010
|
+
}
|
|
27011
|
+
return width;
|
|
27012
|
+
}
|
|
27013
|
+
function computeTableCellPlacement(trList, colgroup) {
|
|
27014
|
+
const placementMap = /* @__PURE__ */ new WeakMap();
|
|
27015
|
+
if (!trList.length || !colgroup.length) {
|
|
27016
|
+
return placementMap;
|
|
27017
|
+
}
|
|
27018
|
+
const occupiedUntilRow = Array(colgroup.length).fill(0);
|
|
27019
|
+
for (let rowIndex = 0; rowIndex < trList.length; rowIndex++) {
|
|
27020
|
+
const tr = trList[rowIndex];
|
|
27021
|
+
let colIndex = 0;
|
|
27022
|
+
for (let tdIndex = 0; tdIndex < tr.tdList.length; tdIndex++) {
|
|
27023
|
+
while (colIndex < colgroup.length && occupiedUntilRow[colIndex] > rowIndex) {
|
|
27024
|
+
colIndex += 1;
|
|
27025
|
+
}
|
|
27026
|
+
const td = tr.tdList[tdIndex];
|
|
27027
|
+
let width = 0;
|
|
27028
|
+
for (let currentCol = colIndex; currentCol < colIndex + td.colspan; currentCol++) {
|
|
27029
|
+
width += colgroup[currentCol]?.width || 0;
|
|
27030
|
+
occupiedUntilRow[currentCol] = Math.max(
|
|
27031
|
+
occupiedUntilRow[currentCol],
|
|
27032
|
+
rowIndex + td.rowspan
|
|
27033
|
+
);
|
|
27034
|
+
}
|
|
27035
|
+
placementMap.set(td, { colIndex, width });
|
|
27036
|
+
colIndex += td.colspan;
|
|
27037
|
+
}
|
|
27038
|
+
}
|
|
27039
|
+
return placementMap;
|
|
27040
|
+
}
|
|
27041
|
+
async function loadPdfImage(src, context) {
|
|
27042
|
+
if (context.imageCache.has(src)) {
|
|
27043
|
+
return context.imageCache.get(src);
|
|
27044
|
+
}
|
|
27045
|
+
try {
|
|
27046
|
+
const payload = await loadPdfImagePayload(src);
|
|
27047
|
+
const image = payload.type === "jpg" ? await context.pdfDoc.embedJpg(payload.data) : await context.pdfDoc.embedPng(payload.data);
|
|
27048
|
+
context.imageCache.set(src, image);
|
|
27049
|
+
return image;
|
|
27050
|
+
} catch {
|
|
27051
|
+
return null;
|
|
27052
|
+
}
|
|
27053
|
+
}
|
|
27054
|
+
async function loadPdfImagePayload(src) {
|
|
27055
|
+
const source = src.trim();
|
|
27056
|
+
if (source.startsWith("data:")) {
|
|
27057
|
+
return getPdfImagePayloadFromDataUrl(source);
|
|
27058
|
+
}
|
|
27059
|
+
const response = await fetch(source);
|
|
27060
|
+
if (!response.ok) {
|
|
27061
|
+
throw new Error(`Image request failed: ${response.status}`);
|
|
27062
|
+
}
|
|
27063
|
+
const contentType = response.headers.get("content-type") || "";
|
|
27064
|
+
const data2 = await response.arrayBuffer();
|
|
27065
|
+
return normalizePdfImagePayload(data2, contentType);
|
|
27066
|
+
}
|
|
27067
|
+
async function getPdfImagePayloadFromDataUrl(src) {
|
|
27068
|
+
const [, meta = "", encoded = ""] = src.match(/^data:([^,]*),(.*)$/) || [];
|
|
27069
|
+
const mime = meta.split(";")[0] || "";
|
|
27070
|
+
const isBase64 = meta.includes(";base64");
|
|
27071
|
+
const text = isBase64 ? atob(encoded) : decodeURIComponent(encoded);
|
|
27072
|
+
const bytes = new Uint8Array(text.length);
|
|
27073
|
+
for (let i = 0; i < text.length; i++) {
|
|
27074
|
+
bytes[i] = text.charCodeAt(i);
|
|
27075
|
+
}
|
|
27076
|
+
return normalizePdfImagePayload(bytes.buffer, mime);
|
|
27077
|
+
}
|
|
27078
|
+
async function normalizePdfImagePayload(data2, mime) {
|
|
27079
|
+
const lower = mime.toLowerCase();
|
|
27080
|
+
if (lower.includes("jpeg") || lower.includes("jpg")) {
|
|
27081
|
+
return {
|
|
27082
|
+
type: "jpg",
|
|
27083
|
+
data: data2
|
|
27084
|
+
};
|
|
27085
|
+
}
|
|
27086
|
+
if (lower.includes("png")) {
|
|
27087
|
+
return {
|
|
27088
|
+
type: "png",
|
|
27089
|
+
data: data2
|
|
27090
|
+
};
|
|
27091
|
+
}
|
|
27092
|
+
return {
|
|
27093
|
+
type: "png",
|
|
27094
|
+
data: await rasterizeImageToPng2(data2, mime)
|
|
27095
|
+
};
|
|
27096
|
+
}
|
|
27097
|
+
async function rasterizeImageToPng2(data2, mime) {
|
|
27098
|
+
const blob = new Blob([data2], {
|
|
27099
|
+
type: mime || "image/png"
|
|
27100
|
+
});
|
|
27101
|
+
const url = URL.createObjectURL(blob);
|
|
27102
|
+
try {
|
|
27103
|
+
const image = await loadHtmlImage2(url);
|
|
27104
|
+
const canvas = document.createElement("canvas");
|
|
27105
|
+
canvas.width = image.naturalWidth || DEFAULT_IMAGE_WIDTH2;
|
|
27106
|
+
canvas.height = image.naturalHeight || DEFAULT_IMAGE_HEIGHT2;
|
|
27107
|
+
const context = canvas.getContext("2d");
|
|
27108
|
+
if (!context) {
|
|
27109
|
+
throw new Error("Canvas context is unavailable");
|
|
27110
|
+
}
|
|
27111
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
27112
|
+
const pngBlob = await new Promise((resolve, reject) => {
|
|
27113
|
+
canvas.toBlob((output) => {
|
|
27114
|
+
if (output) {
|
|
27115
|
+
resolve(output);
|
|
27116
|
+
} else {
|
|
27117
|
+
reject(new Error("Failed to create PNG blob"));
|
|
27118
|
+
}
|
|
27119
|
+
}, "image/png");
|
|
27120
|
+
});
|
|
27121
|
+
return await pngBlob.arrayBuffer();
|
|
27122
|
+
} finally {
|
|
27123
|
+
URL.revokeObjectURL(url);
|
|
27124
|
+
}
|
|
27125
|
+
}
|
|
27126
|
+
function loadHtmlImage2(src) {
|
|
27127
|
+
return new Promise((resolve, reject) => {
|
|
27128
|
+
const image = new Image();
|
|
27129
|
+
image.onload = () => resolve(image);
|
|
27130
|
+
image.onerror = () => reject(new Error("Failed to load image"));
|
|
27131
|
+
image.src = src;
|
|
27132
|
+
});
|
|
27133
|
+
}
|
|
27134
|
+
function getInlineElementText2(element) {
|
|
27135
|
+
switch (element.type) {
|
|
27136
|
+
case "control" /* CONTROL */:
|
|
27137
|
+
return getControlText2(element.control);
|
|
27138
|
+
case "date" /* DATE */:
|
|
27139
|
+
return element.valueList?.length ? getTextFromElementList(element.valueList) : element.value;
|
|
27140
|
+
case "checkbox" /* CHECKBOX */:
|
|
27141
|
+
return element.checkbox?.value ? "\u2611" : "\u2610";
|
|
27142
|
+
case "radio" /* RADIO */:
|
|
27143
|
+
return element.radio?.value ? "\u25C9" : "\u25CB";
|
|
27144
|
+
case "label" /* LABEL */:
|
|
27145
|
+
case "latex" /* LATEX */:
|
|
27146
|
+
case "subscript" /* SUBSCRIPT */:
|
|
27147
|
+
case "superscript" /* SUPERSCRIPT */:
|
|
27148
|
+
return element.value;
|
|
27149
|
+
default:
|
|
27150
|
+
return element.value;
|
|
27151
|
+
}
|
|
27152
|
+
}
|
|
27153
|
+
function getControlText2(control) {
|
|
27154
|
+
if (!control) return "";
|
|
27155
|
+
if (control.type === "text" /* TEXT */ || control.type === "date" /* DATE */ || control.type === "number" /* NUMBER */) {
|
|
27156
|
+
const value = control.value?.length ? getTextFromElementList(control.value) : "";
|
|
27157
|
+
const content = value || control.placeholder || "";
|
|
27158
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
27159
|
+
}
|
|
27160
|
+
if (control.type === "select" /* SELECT */) {
|
|
27161
|
+
const labels = getSelectedControlLabels2(control.code, control.valueSets);
|
|
27162
|
+
const content = labels.length ? labels.join(control.multiSelectDelimiter || ", ") : control.placeholder || "";
|
|
27163
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
27164
|
+
}
|
|
27165
|
+
if (control.type === "checkbox" /* CHECKBOX */ || control.type === "radio" /* RADIO */) {
|
|
27166
|
+
const isRadio = control.type === "radio" /* RADIO */;
|
|
27167
|
+
return (control.valueSets || []).map((valueSet) => {
|
|
27168
|
+
const checked = control.code?.split(",").includes(valueSet.code) || false;
|
|
27169
|
+
return `${checked ? isRadio ? "\u25C9" : "\u2611" : isRadio ? "\u25CB" : "\u2610"} ${valueSet.value}`;
|
|
27170
|
+
}).join(" ");
|
|
27171
|
+
}
|
|
27172
|
+
return "";
|
|
27173
|
+
}
|
|
27174
|
+
function getSelectedControlLabels2(code, valueSets) {
|
|
27175
|
+
if (!code || !valueSets?.length) return [];
|
|
27176
|
+
return code.split(",").map(
|
|
27177
|
+
(selectCode) => valueSets.find((valueSet) => valueSet.code === selectCode)?.value
|
|
27178
|
+
).filter((value) => !!value);
|
|
27179
|
+
}
|
|
27180
|
+
function getBlockFallbackText2(element) {
|
|
27181
|
+
if (element.block?.iframeBlock?.src) {
|
|
27182
|
+
return element.block.iframeBlock.src;
|
|
27183
|
+
}
|
|
27184
|
+
if (element.block?.videoBlock?.src) {
|
|
27185
|
+
return element.block.videoBlock.src;
|
|
27186
|
+
}
|
|
27187
|
+
return "";
|
|
27188
|
+
}
|
|
27189
|
+
function getListItemNumberingElement2(listItemElements, fallback) {
|
|
27190
|
+
return listItemElements.find(
|
|
27191
|
+
(listItem) => listItem.listId || listItem.listLevel !== void 0 || !!listItem.listPreset || !!listItem.listStyle || !!listItem.listType
|
|
27192
|
+
) || fallback;
|
|
27193
|
+
}
|
|
27194
|
+
function getListMarker(element, orderedCounts) {
|
|
27195
|
+
const level = Math.max(0, Math.min(element.listLevel || 0, 8));
|
|
27196
|
+
if (element.listType === "ul" /* UL */) {
|
|
27197
|
+
return {
|
|
27198
|
+
text: getUnorderedMarkerText(element, level),
|
|
27199
|
+
level
|
|
27200
|
+
};
|
|
27201
|
+
}
|
|
27202
|
+
while (orderedCounts.length <= level) {
|
|
27203
|
+
orderedCounts.push(0);
|
|
27204
|
+
}
|
|
27205
|
+
orderedCounts[level] += 1;
|
|
27206
|
+
orderedCounts.length = level + 1;
|
|
27207
|
+
const style = element.listPreset ? getOrderedPresetStyle(element.listPreset, level) : getOrderedStyle(element.listStyle);
|
|
27208
|
+
const outlinePrefix = style === "outline" ? orderedCounts.slice(0, level + 1).join(".") : void 0;
|
|
27209
|
+
return {
|
|
27210
|
+
text: formatOlNumber2(orderedCounts[level] - 1, style, outlinePrefix),
|
|
27211
|
+
level
|
|
27212
|
+
};
|
|
27213
|
+
}
|
|
27214
|
+
function getOrderedPresetStyle(preset, level = 0) {
|
|
27215
|
+
const cycle = preset ? olPresetCycles[preset] : void 0;
|
|
27216
|
+
if (!cycle?.length) {
|
|
27217
|
+
return "decimal";
|
|
27218
|
+
}
|
|
27219
|
+
return cycle[level % cycle.length];
|
|
27220
|
+
}
|
|
27221
|
+
function getOrderedStyle(style) {
|
|
27222
|
+
switch (style) {
|
|
27223
|
+
case "lowerAlpha" /* LOWER_ALPHA */:
|
|
27224
|
+
return "lowerAlpha";
|
|
27225
|
+
case "upperAlpha" /* UPPER_ALPHA */:
|
|
27226
|
+
return "upperAlpha";
|
|
27227
|
+
case "lowerRoman" /* LOWER_ROMAN */:
|
|
27228
|
+
return "lowerRoman";
|
|
27229
|
+
case "upperRoman" /* UPPER_ROMAN */:
|
|
27230
|
+
return "upperRoman";
|
|
27231
|
+
case "decimalParen" /* DECIMAL_PAREN */:
|
|
27232
|
+
return "decimalParen";
|
|
27233
|
+
default:
|
|
27234
|
+
return "decimal";
|
|
27235
|
+
}
|
|
27236
|
+
}
|
|
27237
|
+
function getUnorderedMarkerText(element, level) {
|
|
27238
|
+
if (element.listPreset) {
|
|
27239
|
+
const cycle = ulPresetCycles[element.listPreset];
|
|
27240
|
+
if (cycle?.length) {
|
|
27241
|
+
return cycle[level % cycle.length];
|
|
27242
|
+
}
|
|
27243
|
+
}
|
|
27244
|
+
return bulletCharMap[element.listStyle || "disc" /* DISC */] || bulletCharMap["disc" /* DISC */];
|
|
27245
|
+
}
|
|
27246
|
+
function toAlpha2(n, upper) {
|
|
27247
|
+
let result = "";
|
|
27248
|
+
let num = n + 1;
|
|
27249
|
+
while (num > 0) {
|
|
27250
|
+
num--;
|
|
27251
|
+
result = String.fromCharCode((upper ? 65 : 97) + num % 26) + result;
|
|
27252
|
+
num = Math.floor(num / 26);
|
|
27253
|
+
}
|
|
27254
|
+
return result;
|
|
27255
|
+
}
|
|
27256
|
+
function toRoman2(n, upper) {
|
|
27257
|
+
const num = n + 1;
|
|
27258
|
+
const vals = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
|
|
27259
|
+
const syms = [
|
|
27260
|
+
"M",
|
|
27261
|
+
"CM",
|
|
27262
|
+
"D",
|
|
27263
|
+
"CD",
|
|
27264
|
+
"C",
|
|
27265
|
+
"XC",
|
|
27266
|
+
"L",
|
|
27267
|
+
"XL",
|
|
27268
|
+
"X",
|
|
27269
|
+
"IX",
|
|
27270
|
+
"V",
|
|
27271
|
+
"IV",
|
|
27272
|
+
"I"
|
|
27273
|
+
];
|
|
27274
|
+
let result = "";
|
|
27275
|
+
let remaining = num;
|
|
27276
|
+
for (let i = 0; i < vals.length; i++) {
|
|
27277
|
+
while (remaining >= vals[i]) {
|
|
27278
|
+
result += syms[i];
|
|
27279
|
+
remaining -= vals[i];
|
|
27280
|
+
}
|
|
27281
|
+
}
|
|
27282
|
+
return upper ? result : result.toLowerCase();
|
|
27283
|
+
}
|
|
27284
|
+
function formatOlNumber2(index, style, outlinePrefix) {
|
|
27285
|
+
switch (style) {
|
|
27286
|
+
case "decimal":
|
|
27287
|
+
return `${index + 1}.`;
|
|
27288
|
+
case "decimalParen":
|
|
27289
|
+
return `${index + 1})`;
|
|
27290
|
+
case "decimalZero":
|
|
27291
|
+
return `${String(index + 1).padStart(2, "0")}.`;
|
|
27292
|
+
case "lowerAlpha":
|
|
27293
|
+
return `${toAlpha2(index, false)}.`;
|
|
27294
|
+
case "lowerAlphaParen":
|
|
27295
|
+
return `${toAlpha2(index, false)})`;
|
|
27296
|
+
case "upperAlpha":
|
|
27297
|
+
return `${toAlpha2(index, true)}.`;
|
|
27298
|
+
case "lowerRoman":
|
|
27299
|
+
return `${toRoman2(index, false)}.`;
|
|
27300
|
+
case "lowerRomanParen":
|
|
27301
|
+
return `${toRoman2(index, false)})`;
|
|
27302
|
+
case "upperRoman":
|
|
27303
|
+
return `${toRoman2(index, true)}.`;
|
|
27304
|
+
case "outline":
|
|
27305
|
+
return outlinePrefix ? `${outlinePrefix}.` : `${index + 1}.`;
|
|
27306
|
+
default:
|
|
27307
|
+
return `${index + 1}.`;
|
|
27308
|
+
}
|
|
27309
|
+
}
|
|
27310
|
+
function normalizeAlignment(rowFlex) {
|
|
27311
|
+
if (rowFlex === "alignment" /* ALIGNMENT */) {
|
|
27312
|
+
return "justify" /* JUSTIFY */;
|
|
27313
|
+
}
|
|
27314
|
+
return rowFlex || "left" /* LEFT */;
|
|
27315
|
+
}
|
|
27316
|
+
function getFont(family, bold, italic, context) {
|
|
27317
|
+
const fontSet = context.fonts[resolveFontFamily(family)];
|
|
27318
|
+
if (bold && italic) {
|
|
27319
|
+
return fontSet.boldItalic;
|
|
27320
|
+
}
|
|
27321
|
+
if (bold) {
|
|
27322
|
+
return fontSet.bold;
|
|
27323
|
+
}
|
|
27324
|
+
if (italic) {
|
|
27325
|
+
return fontSet.italic;
|
|
27326
|
+
}
|
|
27327
|
+
return fontSet.regular;
|
|
27328
|
+
}
|
|
27329
|
+
function resolveFontFamily(font) {
|
|
27330
|
+
const normalized = (font || "").trim().toLowerCase();
|
|
27331
|
+
if (normalized.includes("sans-serif") || normalized.includes("arial") || normalized.includes("helvetica") || normalized.includes("yahei") || normalized.includes("microsoft") || normalized.includes("inter") || normalized.includes("roboto")) {
|
|
27332
|
+
return "sans";
|
|
27333
|
+
}
|
|
27334
|
+
if (normalized.includes("times") || normalized === "serif" || normalized.endsWith(", serif")) {
|
|
27335
|
+
return "serif";
|
|
27336
|
+
}
|
|
27337
|
+
if (normalized.includes("courier") || normalized.includes("mono") || normalized.includes("code")) {
|
|
27338
|
+
return "mono";
|
|
27339
|
+
}
|
|
27340
|
+
return "sans";
|
|
27341
|
+
}
|
|
27342
|
+
function sanitizeTextForPdf(text, font) {
|
|
27343
|
+
let fontCache = pdfTextCache.get(font);
|
|
27344
|
+
if (!fontCache) {
|
|
27345
|
+
fontCache = /* @__PURE__ */ new Map();
|
|
27346
|
+
pdfTextCache.set(font, fontCache);
|
|
27347
|
+
}
|
|
27348
|
+
if (fontCache.has(text)) {
|
|
27349
|
+
return fontCache.get(text);
|
|
27350
|
+
}
|
|
27351
|
+
let safeText = text;
|
|
27352
|
+
try {
|
|
27353
|
+
font.encodeText(text);
|
|
27354
|
+
} catch {
|
|
27355
|
+
safeText = Array.from(text).map((char) => sanitizePdfChar(char, font)).join("");
|
|
27356
|
+
}
|
|
27357
|
+
fontCache.set(text, safeText);
|
|
27358
|
+
return safeText;
|
|
27359
|
+
}
|
|
27360
|
+
function sanitizePdfChar(char, font) {
|
|
27361
|
+
try {
|
|
27362
|
+
font.encodeText(char);
|
|
27363
|
+
return char;
|
|
27364
|
+
} catch {
|
|
27365
|
+
const directFallback = PDF_TEXT_FALLBACKS[char];
|
|
27366
|
+
if (directFallback) {
|
|
27367
|
+
return directFallback;
|
|
27368
|
+
}
|
|
27369
|
+
if (/^\s$/u.test(char)) {
|
|
27370
|
+
return " ";
|
|
27371
|
+
}
|
|
27372
|
+
const normalized = char.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^\x20-\x7E]/g, "");
|
|
27373
|
+
if (normalized) {
|
|
27374
|
+
try {
|
|
27375
|
+
font.encodeText(normalized);
|
|
27376
|
+
return normalized;
|
|
27377
|
+
} catch {
|
|
27378
|
+
return "?";
|
|
27379
|
+
}
|
|
27380
|
+
}
|
|
27381
|
+
return "?";
|
|
27382
|
+
}
|
|
27383
|
+
}
|
|
27384
|
+
function getPadding(padding) {
|
|
27385
|
+
return [padding[0] ?? 0, padding[1] ?? 0, padding[2] ?? 0, padding[3] ?? 0];
|
|
27386
|
+
}
|
|
27387
|
+
function getTitleSize(titleLevel, options) {
|
|
27388
|
+
if (!titleLevel) {
|
|
27389
|
+
return void 0;
|
|
27390
|
+
}
|
|
27391
|
+
return options.title[titleSizeMapping[titleLevel]];
|
|
27392
|
+
}
|
|
27393
|
+
function getPageNumberHeight(pageNumber) {
|
|
27394
|
+
if (pageNumber.disabled) {
|
|
27395
|
+
return 0;
|
|
27396
|
+
}
|
|
27397
|
+
return pageNumber.size || 12;
|
|
27398
|
+
}
|
|
27399
|
+
function getFooterBarHeight(footerHeight, context) {
|
|
27400
|
+
if (context.options.footer.disabled) {
|
|
27401
|
+
return 0;
|
|
27402
|
+
}
|
|
27403
|
+
return Math.max(footerHeight, pxToPt(FOOTER_MIN_BAR_HEIGHT));
|
|
27404
|
+
}
|
|
27405
|
+
function getReservedPageNumberBottom(pageNumber, pageNumberHeight) {
|
|
27406
|
+
if (pageNumber.disabled) {
|
|
27407
|
+
return 0;
|
|
27408
|
+
}
|
|
27409
|
+
return pxToPt(pageNumber.bottom + 4) + pageNumberHeight;
|
|
27410
|
+
}
|
|
27411
|
+
function normalizeText2(text = "") {
|
|
27412
|
+
return text.replace(new RegExp(ZERO, "g"), "").replace(/\r\n/g, "\n");
|
|
27413
|
+
}
|
|
27414
|
+
function normalizePdfFileName(fileName) {
|
|
27415
|
+
const trimmed = fileName?.trim();
|
|
27416
|
+
if (!trimmed) {
|
|
27417
|
+
return DEFAULT_PDF_FILE_NAME;
|
|
27418
|
+
}
|
|
27419
|
+
return trimmed.toLowerCase().endsWith(".pdf") ? trimmed : `${trimmed}.pdf`;
|
|
27420
|
+
}
|
|
27421
|
+
function pxToPt(px) {
|
|
27422
|
+
return px * (72 / 96);
|
|
27423
|
+
}
|
|
27424
|
+
function toPdfY(pageHeight, top, height = 0) {
|
|
27425
|
+
return pageHeight - top - height;
|
|
27426
|
+
}
|
|
27427
|
+
function toPdfColor(color, fallback = "#000000") {
|
|
27428
|
+
const hex = normalizeHexColor2(color || fallback, "000000") || "000000";
|
|
27429
|
+
const red = parseInt(hex.slice(0, 2), 16) / 255;
|
|
27430
|
+
const green = parseInt(hex.slice(2, 4), 16) / 255;
|
|
27431
|
+
const blue = parseInt(hex.slice(4, 6), 16) / 255;
|
|
27432
|
+
return (0, import_pdf_lib.rgb)(red, green, blue);
|
|
27433
|
+
}
|
|
27434
|
+
function normalizeHexColor2(color, fallback) {
|
|
27435
|
+
const normalized = normalizeHexLiteral2(color) || normalizeRgbColor2(color) || normalizeBrowserColor2(color);
|
|
27436
|
+
if (normalized) {
|
|
27437
|
+
return normalized;
|
|
27438
|
+
}
|
|
27439
|
+
return fallback ? normalizeHexLiteral2(fallback) || void 0 : void 0;
|
|
27440
|
+
}
|
|
27441
|
+
function normalizeHexLiteral2(color) {
|
|
27442
|
+
const value = color.trim().replace(/^#/, "");
|
|
27443
|
+
if (/^[\da-f]{3}$/i.test(value)) {
|
|
27444
|
+
return value.split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
27445
|
+
}
|
|
27446
|
+
if (/^[\da-f]{4}$/i.test(value)) {
|
|
27447
|
+
return value.slice(0, 3).split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
27448
|
+
}
|
|
27449
|
+
if (/^[\da-f]{6}$/i.test(value)) {
|
|
27450
|
+
return value.toUpperCase();
|
|
27451
|
+
}
|
|
27452
|
+
if (/^[\da-f]{8}$/i.test(value)) {
|
|
27453
|
+
return value.slice(0, 6).toUpperCase();
|
|
27454
|
+
}
|
|
27455
|
+
return void 0;
|
|
27456
|
+
}
|
|
27457
|
+
function normalizeRgbColor2(color) {
|
|
27458
|
+
const match = color.trim().match(/^rgba?\((.+)\)$/i);
|
|
27459
|
+
if (!match) {
|
|
27460
|
+
return void 0;
|
|
27461
|
+
}
|
|
27462
|
+
const parts = match[1].replace(/\s*\/\s*/g, ",").split(/\s*,\s*|\s+/).filter(Boolean);
|
|
27463
|
+
if (parts.length < 3) {
|
|
27464
|
+
return void 0;
|
|
27465
|
+
}
|
|
27466
|
+
const red = parseRgbChannel2(parts[0]);
|
|
27467
|
+
const green = parseRgbChannel2(parts[1]);
|
|
27468
|
+
const blue = parseRgbChannel2(parts[2]);
|
|
27469
|
+
if (red === null || green === null || blue === null) {
|
|
27470
|
+
return void 0;
|
|
27471
|
+
}
|
|
27472
|
+
const alpha = parts[3] !== void 0 ? parseAlphaChannel2(parts[3]) : 1;
|
|
27473
|
+
if (alpha === null || alpha <= 0) {
|
|
27474
|
+
return void 0;
|
|
27475
|
+
}
|
|
27476
|
+
const flattened = alpha >= 1 ? [red, green, blue] : [
|
|
27477
|
+
flattenChannel2(red, alpha),
|
|
27478
|
+
flattenChannel2(green, alpha),
|
|
27479
|
+
flattenChannel2(blue, alpha)
|
|
27480
|
+
];
|
|
27481
|
+
return flattened.map(toHexChannel2).join("");
|
|
27482
|
+
}
|
|
27483
|
+
function normalizeBrowserColor2(color) {
|
|
27484
|
+
if (typeof document === "undefined") {
|
|
27485
|
+
return void 0;
|
|
27486
|
+
}
|
|
27487
|
+
const canvas = document.createElement("canvas");
|
|
27488
|
+
const context = canvas.getContext("2d");
|
|
27489
|
+
if (!context) {
|
|
27490
|
+
return void 0;
|
|
27491
|
+
}
|
|
27492
|
+
context.fillStyle = "#000000";
|
|
27493
|
+
context.fillStyle = color;
|
|
27494
|
+
const normalized = context.fillStyle;
|
|
27495
|
+
if (typeof normalized !== "string") {
|
|
27496
|
+
return void 0;
|
|
27497
|
+
}
|
|
27498
|
+
return normalizeHexLiteral2(normalized) || normalizeRgbColor2(normalized);
|
|
27499
|
+
}
|
|
27500
|
+
function parseRgbChannel2(value) {
|
|
27501
|
+
if (value.endsWith("%")) {
|
|
27502
|
+
const percent = Number(value.slice(0, -1));
|
|
27503
|
+
if (!Number.isFinite(percent)) {
|
|
27504
|
+
return null;
|
|
27505
|
+
}
|
|
27506
|
+
return clampColorChannel2(Math.round(percent / 100 * 255));
|
|
27507
|
+
}
|
|
27508
|
+
const channel = Number(value);
|
|
27509
|
+
if (!Number.isFinite(channel)) {
|
|
27510
|
+
return null;
|
|
27511
|
+
}
|
|
27512
|
+
return clampColorChannel2(Math.round(channel));
|
|
27513
|
+
}
|
|
27514
|
+
function parseAlphaChannel2(value) {
|
|
27515
|
+
if (value.endsWith("%")) {
|
|
27516
|
+
const percent = Number(value.slice(0, -1));
|
|
27517
|
+
if (!Number.isFinite(percent)) {
|
|
27518
|
+
return null;
|
|
27519
|
+
}
|
|
27520
|
+
return Math.min(Math.max(percent / 100, 0), 1);
|
|
27521
|
+
}
|
|
27522
|
+
const alpha = Number(value);
|
|
27523
|
+
if (!Number.isFinite(alpha)) {
|
|
27524
|
+
return null;
|
|
27525
|
+
}
|
|
27526
|
+
return Math.min(Math.max(alpha, 0), 1);
|
|
27527
|
+
}
|
|
27528
|
+
function clampColorChannel2(value) {
|
|
27529
|
+
return Math.min(Math.max(value, 0), 255);
|
|
27530
|
+
}
|
|
27531
|
+
function flattenChannel2(value, alpha) {
|
|
27532
|
+
return clampColorChannel2(Math.round(255 * (1 - alpha) + value * alpha));
|
|
27533
|
+
}
|
|
27534
|
+
function toHexChannel2(value) {
|
|
27535
|
+
return value.toString(16).padStart(2, "0").toUpperCase();
|
|
27536
|
+
}
|
|
27537
|
+
|
|
27538
|
+
// src/utils/print.ts
|
|
27539
|
+
function convertPxToPaperSize(width, height) {
|
|
27540
|
+
if (width === 1125 && height === 1593) {
|
|
27541
|
+
return {
|
|
27542
|
+
size: "a3",
|
|
27543
|
+
width: "297mm",
|
|
27544
|
+
height: "420mm"
|
|
27545
|
+
};
|
|
27546
|
+
}
|
|
27547
|
+
if (width === 794 && height === 1123) {
|
|
27548
|
+
return {
|
|
27549
|
+
size: "a4",
|
|
27550
|
+
width: "210mm",
|
|
27551
|
+
height: "297mm"
|
|
27552
|
+
};
|
|
27553
|
+
}
|
|
27554
|
+
if (width === 565 && height === 796) {
|
|
27555
|
+
return {
|
|
27556
|
+
size: "a5",
|
|
27557
|
+
width: "148mm",
|
|
27558
|
+
height: "210mm"
|
|
27559
|
+
};
|
|
27560
|
+
}
|
|
27561
|
+
return {
|
|
27562
|
+
size: "",
|
|
27563
|
+
width: `${width}px`,
|
|
27564
|
+
height: `${height}px`
|
|
27565
|
+
};
|
|
27566
|
+
}
|
|
27567
|
+
function printImageBase64(base64List, options) {
|
|
27568
|
+
const { width, height, direction = "vertical" /* VERTICAL */ } = options;
|
|
27569
|
+
const iframe = document.createElement("iframe");
|
|
27570
|
+
iframe.style.visibility = "hidden";
|
|
27571
|
+
iframe.style.position = "absolute";
|
|
27572
|
+
iframe.style.left = "0";
|
|
27573
|
+
iframe.style.top = "0";
|
|
27574
|
+
iframe.style.width = "0";
|
|
27575
|
+
iframe.style.height = "0";
|
|
27576
|
+
iframe.style.border = "none";
|
|
27577
|
+
document.body.append(iframe);
|
|
27578
|
+
const contentWindow = iframe.contentWindow;
|
|
27579
|
+
const doc = contentWindow.document;
|
|
27580
|
+
doc.open();
|
|
27581
|
+
const container = document.createElement("div");
|
|
24073
27582
|
const paperSize = convertPxToPaperSize(width, height);
|
|
24074
27583
|
base64List.forEach((base64) => {
|
|
24075
27584
|
const image = document.createElement("img");
|
|
@@ -25238,6 +28747,16 @@ var CommandAdapt = class {
|
|
|
25238
28747
|
this.draw.setPageScale(scale);
|
|
25239
28748
|
}
|
|
25240
28749
|
}
|
|
28750
|
+
async exportDocx(payload = {}) {
|
|
28751
|
+
const result = this.draw.getValue();
|
|
28752
|
+
const { blob, fileName } = await exportEditorDataToDocx(result, payload);
|
|
28753
|
+
downloadBlob(blob, fileName);
|
|
28754
|
+
}
|
|
28755
|
+
async exportPdf(payload = {}) {
|
|
28756
|
+
const result = this.draw.getValue();
|
|
28757
|
+
const { blob, fileName } = await exportEditorDataToPdf(result, payload);
|
|
28758
|
+
downloadBlob(blob, fileName);
|
|
28759
|
+
}
|
|
25241
28760
|
replaceImageElement(payload) {
|
|
25242
28761
|
const { startIndex } = this.range.getRange();
|
|
25243
28762
|
const elementList = this.draw.getElementList();
|