@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.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var version = "0.3.
|
|
2
|
+
var version = "0.3.25";
|
|
3
3
|
|
|
4
4
|
// src/dataset/enum/Common.ts
|
|
5
5
|
var MaxHeightRatio = /* @__PURE__ */ ((MaxHeightRatio2) => {
|
|
@@ -106,21 +106,6 @@ function debounce(func, delay) {
|
|
|
106
106
|
}, delay);
|
|
107
107
|
};
|
|
108
108
|
}
|
|
109
|
-
function deepCloneOmitKeys(obj, omitKeys) {
|
|
110
|
-
if (!obj || typeof obj !== "object") {
|
|
111
|
-
return obj;
|
|
112
|
-
}
|
|
113
|
-
let newObj = {};
|
|
114
|
-
if (Array.isArray(obj)) {
|
|
115
|
-
newObj = obj.map((item) => deepCloneOmitKeys(item, omitKeys));
|
|
116
|
-
} else {
|
|
117
|
-
Object.keys(obj).forEach((key) => {
|
|
118
|
-
if (omitKeys.includes(key)) return;
|
|
119
|
-
newObj[key] = deepCloneOmitKeys(obj[key], omitKeys);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
return newObj;
|
|
123
|
-
}
|
|
124
109
|
function deepClone(obj) {
|
|
125
110
|
if (typeof structuredClone === "function") {
|
|
126
111
|
return structuredClone(obj);
|
|
@@ -192,6 +177,13 @@ function downloadFile(href, fileName) {
|
|
|
192
177
|
a.download = fileName;
|
|
193
178
|
a.click();
|
|
194
179
|
}
|
|
180
|
+
function downloadBlob(blob, fileName) {
|
|
181
|
+
const href = URL.createObjectURL(blob);
|
|
182
|
+
downloadFile(href, fileName);
|
|
183
|
+
window.setTimeout(() => {
|
|
184
|
+
URL.revokeObjectURL(href);
|
|
185
|
+
}, 0);
|
|
186
|
+
}
|
|
195
187
|
function threeClick(dom, fn) {
|
|
196
188
|
nClickEvent(3, dom, fn);
|
|
197
189
|
}
|
|
@@ -3817,23 +3809,23 @@ var ListStyle = /* @__PURE__ */ ((ListStyle3) => {
|
|
|
3817
3809
|
ListStyle3["CHECKBOX"] = "checkbox" /* CHECKBOX */;
|
|
3818
3810
|
return ListStyle3;
|
|
3819
3811
|
})(ListStyle || {});
|
|
3820
|
-
var OlPreset = /* @__PURE__ */ ((
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
return
|
|
3812
|
+
var OlPreset = /* @__PURE__ */ ((OlPreset3) => {
|
|
3813
|
+
OlPreset3["DEFAULT"] = "olDefault";
|
|
3814
|
+
OlPreset3["PARENTHESIS"] = "olParen";
|
|
3815
|
+
OlPreset3["OUTLINE"] = "olOutline";
|
|
3816
|
+
OlPreset3["UPPER_ALPHA"] = "olUpperA";
|
|
3817
|
+
OlPreset3["ROMAN"] = "olRoman";
|
|
3818
|
+
OlPreset3["ZERO_PAD"] = "olZeroPad";
|
|
3819
|
+
return OlPreset3;
|
|
3828
3820
|
})(OlPreset || {});
|
|
3829
|
-
var UlPreset = /* @__PURE__ */ ((
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
return
|
|
3821
|
+
var UlPreset = /* @__PURE__ */ ((UlPreset3) => {
|
|
3822
|
+
UlPreset3["DEFAULT"] = "ulDefault";
|
|
3823
|
+
UlPreset3["DIAMOND"] = "ulDiamond";
|
|
3824
|
+
UlPreset3["HOLLOW_SQ"] = "ulHollowSq";
|
|
3825
|
+
UlPreset3["ARROW"] = "ulArrow";
|
|
3826
|
+
UlPreset3["STAR"] = "ulStar";
|
|
3827
|
+
UlPreset3["CHECK_ARROW"] = "ulCheckArr";
|
|
3828
|
+
return UlPreset3;
|
|
3837
3829
|
})(UlPreset || {});
|
|
3838
3830
|
|
|
3839
3831
|
// src/dataset/constant/List.ts
|
|
@@ -4944,9 +4936,7 @@ function mergeSplitTableRowsForZip(trList) {
|
|
|
4944
4936
|
for (let t = trList.length - 1; t >= 0; t--) {
|
|
4945
4937
|
const splitTr = trList[t];
|
|
4946
4938
|
if (!splitTr.splitParentId) continue;
|
|
4947
|
-
const parentTrIdx = trList.findIndex(
|
|
4948
|
-
(tr) => tr.id === splitTr.splitParentId
|
|
4949
|
-
);
|
|
4939
|
+
const parentTrIdx = trList.findIndex((tr) => tr.id === splitTr.splitParentId);
|
|
4950
4940
|
if (!~parentTrIdx) continue;
|
|
4951
4941
|
const parentTr = trList[parentTrIdx];
|
|
4952
4942
|
parentTr.height += splitTr.height;
|
|
@@ -5992,10 +5982,184 @@ ${ulListStyleText || `${listIndex + 1}.`}${buildText(
|
|
|
5992
5982
|
return buildText(zipElementList(elementList));
|
|
5993
5983
|
}
|
|
5994
5984
|
function getSlimCloneElementList(elementList) {
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5985
|
+
const snapshotElementList = [];
|
|
5986
|
+
let preSourceElement = null;
|
|
5987
|
+
let preSnapshotElement = null;
|
|
5988
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
5989
|
+
const element = elementList[i];
|
|
5990
|
+
if (preSourceElement && preSnapshotElement && isHistoryTextSnapshotMergeable(preSourceElement, element)) {
|
|
5991
|
+
preSnapshotElement.value += element.value;
|
|
5992
|
+
preSourceElement = element;
|
|
5993
|
+
continue;
|
|
5994
|
+
}
|
|
5995
|
+
const snapshotElement = cloneHistorySnapshotElement(element);
|
|
5996
|
+
snapshotElementList.push(snapshotElement);
|
|
5997
|
+
preSourceElement = element;
|
|
5998
|
+
preSnapshotElement = snapshotElement;
|
|
5999
|
+
}
|
|
6000
|
+
return snapshotElementList;
|
|
6001
|
+
}
|
|
6002
|
+
var HISTORY_SNAPSHOT_OMIT_ATTR = /* @__PURE__ */ new Set([
|
|
6003
|
+
"metrics",
|
|
6004
|
+
"style",
|
|
6005
|
+
"rowList",
|
|
6006
|
+
"positionList",
|
|
6007
|
+
"x",
|
|
6008
|
+
"y",
|
|
6009
|
+
"trIndex",
|
|
6010
|
+
"tdIndex",
|
|
6011
|
+
"isLastRowTd",
|
|
6012
|
+
"isLastColTd",
|
|
6013
|
+
"isLastTd",
|
|
6014
|
+
"rowIndex",
|
|
6015
|
+
"colIndex",
|
|
6016
|
+
"mainHeight",
|
|
6017
|
+
"realHeight",
|
|
6018
|
+
"realMinHeight",
|
|
6019
|
+
"splitBoundaryTop",
|
|
6020
|
+
"splitBoundaryBottom",
|
|
6021
|
+
"actualSize"
|
|
6022
|
+
]);
|
|
6023
|
+
function cloneHistorySnapshotValue(payload) {
|
|
6024
|
+
if (!payload || typeof payload !== "object") {
|
|
6025
|
+
return payload;
|
|
6026
|
+
}
|
|
6027
|
+
if (Array.isArray(payload)) {
|
|
6028
|
+
return payload.map((item) => cloneHistorySnapshotValue(item));
|
|
6029
|
+
}
|
|
6030
|
+
const snapshot = {};
|
|
6031
|
+
for (const key of Object.keys(payload)) {
|
|
6032
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6033
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(
|
|
6034
|
+
payload[key]
|
|
6035
|
+
);
|
|
6036
|
+
}
|
|
6037
|
+
return snapshot;
|
|
6038
|
+
}
|
|
6039
|
+
function cloneHistorySnapshotTd(td) {
|
|
6040
|
+
const snapshot = {};
|
|
6041
|
+
for (const key of Object.keys(td)) {
|
|
6042
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6043
|
+
const value = td[key];
|
|
6044
|
+
if (key === "value") {
|
|
6045
|
+
snapshot.value = getSlimCloneElementList(value);
|
|
6046
|
+
continue;
|
|
6047
|
+
}
|
|
6048
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6049
|
+
}
|
|
6050
|
+
return snapshot;
|
|
6051
|
+
}
|
|
6052
|
+
function cloneHistorySnapshotTr(tr) {
|
|
6053
|
+
const snapshot = {};
|
|
6054
|
+
for (const key of Object.keys(tr)) {
|
|
6055
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6056
|
+
const value = tr[key];
|
|
6057
|
+
if (key === "tdList") {
|
|
6058
|
+
snapshot.tdList = value.map((td) => cloneHistorySnapshotTd(td));
|
|
6059
|
+
continue;
|
|
6060
|
+
}
|
|
6061
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6062
|
+
}
|
|
6063
|
+
return snapshot;
|
|
6064
|
+
}
|
|
6065
|
+
function cloneHistorySnapshotElement(element) {
|
|
6066
|
+
const snapshot = {};
|
|
6067
|
+
for (const key of Object.keys(element)) {
|
|
6068
|
+
if (HISTORY_SNAPSHOT_OMIT_ATTR.has(String(key))) continue;
|
|
6069
|
+
const value = element[key];
|
|
6070
|
+
if (key === "trList" && Array.isArray(value)) {
|
|
6071
|
+
snapshot.trList = value.map((tr) => cloneHistorySnapshotTr(tr));
|
|
6072
|
+
continue;
|
|
6073
|
+
}
|
|
6074
|
+
if (key === "valueList" && Array.isArray(value)) {
|
|
6075
|
+
snapshot.valueList = getSlimCloneElementList(value);
|
|
6076
|
+
continue;
|
|
6077
|
+
}
|
|
6078
|
+
if (key === "control" && value && typeof value === "object") {
|
|
6079
|
+
snapshot.control = cloneHistorySnapshotControl(
|
|
6080
|
+
value
|
|
6081
|
+
);
|
|
6082
|
+
continue;
|
|
6083
|
+
}
|
|
6084
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6085
|
+
}
|
|
6086
|
+
return snapshot;
|
|
6087
|
+
}
|
|
6088
|
+
function cloneHistorySnapshotControl(control) {
|
|
6089
|
+
const snapshot = {};
|
|
6090
|
+
for (const key of Object.keys(control)) {
|
|
6091
|
+
const value = control[key];
|
|
6092
|
+
if (key === "value" && Array.isArray(value)) {
|
|
6093
|
+
snapshot.value = getSlimCloneElementList(value);
|
|
6094
|
+
continue;
|
|
6095
|
+
}
|
|
6096
|
+
snapshot[String(key)] = cloneHistorySnapshotValue(value);
|
|
6097
|
+
}
|
|
6098
|
+
return snapshot;
|
|
6099
|
+
}
|
|
6100
|
+
function isHistoryTextSnapshotElement(element) {
|
|
6101
|
+
return !element.type || TEXTLIKE_ELEMENT_TYPE.includes(element.type);
|
|
6102
|
+
}
|
|
6103
|
+
function isHistoryTextSnapshotMergeable(source, target) {
|
|
6104
|
+
if (!isHistoryTextSnapshotElement(source) || !isHistoryTextSnapshotElement(target)) {
|
|
6105
|
+
return false;
|
|
6106
|
+
}
|
|
6107
|
+
return isSameHistoryElementExceptValue(source, target);
|
|
6108
|
+
}
|
|
6109
|
+
function isSameHistoryElementExceptValue(source, target) {
|
|
6110
|
+
const sourceKeys = Object.keys(source).filter(
|
|
6111
|
+
(key) => !HISTORY_SNAPSHOT_OMIT_ATTR.has(key)
|
|
6112
|
+
);
|
|
6113
|
+
const targetKeys = Object.keys(target).filter(
|
|
6114
|
+
(key) => !HISTORY_SNAPSHOT_OMIT_ATTR.has(key)
|
|
6115
|
+
);
|
|
6116
|
+
if (sourceKeys.length !== targetKeys.length) return false;
|
|
6117
|
+
for (let s = 0; s < sourceKeys.length; s++) {
|
|
6118
|
+
const key = sourceKeys[s];
|
|
6119
|
+
if (key === "value") continue;
|
|
6120
|
+
if (key === "groupIds" && Array.isArray(source[key]) && Array.isArray(target[key]) && isArrayEqual(source[key], target[key])) {
|
|
6121
|
+
continue;
|
|
6122
|
+
}
|
|
6123
|
+
if (source[key] !== target[key]) {
|
|
6124
|
+
return false;
|
|
6125
|
+
}
|
|
6126
|
+
}
|
|
6127
|
+
return true;
|
|
6128
|
+
}
|
|
6129
|
+
function inflateElementList(elementList) {
|
|
6130
|
+
let i = 0;
|
|
6131
|
+
while (i < elementList.length) {
|
|
6132
|
+
const element = elementList[i];
|
|
6133
|
+
if (element.trList?.length) {
|
|
6134
|
+
for (let t = 0; t < element.trList.length; t++) {
|
|
6135
|
+
const tr = element.trList[t];
|
|
6136
|
+
for (let d = 0; d < tr.tdList.length; d++) {
|
|
6137
|
+
inflateElementList(tr.tdList[d].value);
|
|
6138
|
+
}
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
if (element.valueList?.length) {
|
|
6142
|
+
inflateElementList(element.valueList);
|
|
6143
|
+
}
|
|
6144
|
+
if (element.control?.value?.length) {
|
|
6145
|
+
inflateElementList(element.control.value);
|
|
6146
|
+
}
|
|
6147
|
+
if (isHistoryTextSnapshotElement(element) && element.value?.length > 1) {
|
|
6148
|
+
const textList = splitText(element.value);
|
|
6149
|
+
elementList.splice(
|
|
6150
|
+
i,
|
|
6151
|
+
1,
|
|
6152
|
+
...textList.map((value) => ({
|
|
6153
|
+
...element,
|
|
6154
|
+
value
|
|
6155
|
+
}))
|
|
6156
|
+
);
|
|
6157
|
+
i += textList.length;
|
|
6158
|
+
continue;
|
|
6159
|
+
}
|
|
6160
|
+
i++;
|
|
6161
|
+
}
|
|
6162
|
+
return elementList;
|
|
5999
6163
|
}
|
|
6000
6164
|
function getIsBlockElement(element) {
|
|
6001
6165
|
return !!element?.type && (BLOCK_ELEMENT_TYPE.includes(element.type) || element.imgDisplay === "inline" /* INLINE */);
|
|
@@ -7668,7 +7832,8 @@ function backspace(evt, host) {
|
|
|
7668
7832
|
} else {
|
|
7669
7833
|
rangeManager.setRange(curIndex, curIndex);
|
|
7670
7834
|
draw.render({
|
|
7671
|
-
curIndex
|
|
7835
|
+
curIndex,
|
|
7836
|
+
dirtyStartIndex: curIndex + 1
|
|
7672
7837
|
});
|
|
7673
7838
|
}
|
|
7674
7839
|
}
|
|
@@ -7810,7 +7975,8 @@ function del(evt, host) {
|
|
|
7810
7975
|
} else {
|
|
7811
7976
|
rangeManager.setRange(curIndex, curIndex);
|
|
7812
7977
|
draw.render({
|
|
7813
|
-
curIndex
|
|
7978
|
+
curIndex,
|
|
7979
|
+
dirtyStartIndex: curIndex + 1
|
|
7814
7980
|
});
|
|
7815
7981
|
}
|
|
7816
7982
|
}
|
|
@@ -8652,10 +8818,12 @@ function input(data2, host) {
|
|
|
8652
8818
|
if (~curIndex) {
|
|
8653
8819
|
rangeManager.setRange(curIndex, curIndex);
|
|
8654
8820
|
const isWordBoundary = !isComposing && /[\s\p{P}]/u.test(data2);
|
|
8821
|
+
const dirtyStartIndex = startIndex + 1;
|
|
8655
8822
|
draw.render({
|
|
8656
8823
|
curIndex,
|
|
8657
8824
|
isSubmitHistory: !isComposing,
|
|
8658
|
-
isInputHistory: !isComposing && !isWordBoundary
|
|
8825
|
+
isInputHistory: !isComposing && !isWordBoundary,
|
|
8826
|
+
dirtyStartIndex
|
|
8659
8827
|
});
|
|
8660
8828
|
}
|
|
8661
8829
|
if (isComposing && ~curIndex) {
|
|
@@ -9339,7 +9507,7 @@ var HistoryManager = class {
|
|
|
9339
9507
|
const pop = this.undoStack.pop();
|
|
9340
9508
|
this.redoStack.push(pop);
|
|
9341
9509
|
if (this.undoStack.length) {
|
|
9342
|
-
this.undoStack[this.undoStack.length - 1]();
|
|
9510
|
+
this.undoStack[this.undoStack.length - 1].restore();
|
|
9343
9511
|
}
|
|
9344
9512
|
}
|
|
9345
9513
|
}
|
|
@@ -9347,11 +9515,11 @@ var HistoryManager = class {
|
|
|
9347
9515
|
if (this.redoStack.length) {
|
|
9348
9516
|
const pop = this.redoStack.pop();
|
|
9349
9517
|
this.undoStack.push(pop);
|
|
9350
|
-
pop();
|
|
9518
|
+
pop.restore();
|
|
9351
9519
|
}
|
|
9352
9520
|
}
|
|
9353
|
-
execute(
|
|
9354
|
-
this.undoStack.push(
|
|
9521
|
+
execute(entry) {
|
|
9522
|
+
this.undoStack.push(this._normalizeEntry(entry));
|
|
9355
9523
|
if (this.redoStack.length) {
|
|
9356
9524
|
this.redoStack = [];
|
|
9357
9525
|
}
|
|
@@ -9359,11 +9527,12 @@ var HistoryManager = class {
|
|
|
9359
9527
|
this.undoStack.shift();
|
|
9360
9528
|
}
|
|
9361
9529
|
}
|
|
9362
|
-
replaceLatest(
|
|
9530
|
+
replaceLatest(entry) {
|
|
9531
|
+
const normalizedEntry = this._normalizeEntry(entry);
|
|
9363
9532
|
if (this.undoStack.length > 0) {
|
|
9364
|
-
this.undoStack[this.undoStack.length - 1] =
|
|
9533
|
+
this.undoStack[this.undoStack.length - 1] = normalizedEntry;
|
|
9365
9534
|
} else {
|
|
9366
|
-
this.execute(
|
|
9535
|
+
this.execute(normalizedEntry);
|
|
9367
9536
|
}
|
|
9368
9537
|
if (this.redoStack.length) {
|
|
9369
9538
|
this.redoStack = [];
|
|
@@ -9394,6 +9563,14 @@ var HistoryManager = class {
|
|
|
9394
9563
|
popUndo() {
|
|
9395
9564
|
return this.undoStack.pop();
|
|
9396
9565
|
}
|
|
9566
|
+
_normalizeEntry(entry) {
|
|
9567
|
+
if (typeof entry === "function") {
|
|
9568
|
+
return {
|
|
9569
|
+
restore: entry
|
|
9570
|
+
};
|
|
9571
|
+
}
|
|
9572
|
+
return entry;
|
|
9573
|
+
}
|
|
9397
9574
|
};
|
|
9398
9575
|
|
|
9399
9576
|
// src/core/position/Position.ts
|
|
@@ -11601,6 +11778,7 @@ var ScrollObserver = class {
|
|
|
11601
11778
|
const { intersectionPageNo, visiblePageNoList } = this.getPageVisibleInfo();
|
|
11602
11779
|
this.draw.setIntersectionPageNo(intersectionPageNo);
|
|
11603
11780
|
this.draw.setVisiblePageNoList(visiblePageNoList);
|
|
11781
|
+
this.draw.renderVisiblePages(visiblePageNoList);
|
|
11604
11782
|
}, 150);
|
|
11605
11783
|
this.draw = draw;
|
|
11606
11784
|
this.options = draw.getOptions();
|
|
@@ -20408,6 +20586,9 @@ var Area = class {
|
|
|
20408
20586
|
getAreaInfo() {
|
|
20409
20587
|
return this.areaInfoMap;
|
|
20410
20588
|
}
|
|
20589
|
+
clear() {
|
|
20590
|
+
this.areaInfoMap.clear();
|
|
20591
|
+
}
|
|
20411
20592
|
getActiveAreaId() {
|
|
20412
20593
|
if (!this.areaInfoMap.size) return null;
|
|
20413
20594
|
const { startIndex } = this.range.getRange();
|
|
@@ -20799,6 +20980,7 @@ var Draw = class {
|
|
|
20799
20980
|
this.container = this._wrapContainer(rootContainer);
|
|
20800
20981
|
this.pageList = [];
|
|
20801
20982
|
this.ctxList = [];
|
|
20983
|
+
this.pageRenderVersionList = [];
|
|
20802
20984
|
this.pageNo = 0;
|
|
20803
20985
|
this.renderCount = 0;
|
|
20804
20986
|
this.pagePixelRatio = null;
|
|
@@ -20811,6 +20993,7 @@ var Draw = class {
|
|
|
20811
20993
|
this._formatContainer();
|
|
20812
20994
|
this.pageContainer = this._createPageContainer();
|
|
20813
20995
|
this._createPage(0);
|
|
20996
|
+
this.measureCtx = this._createMeasureContext();
|
|
20814
20997
|
this.i18n = new I18n(options.locale);
|
|
20815
20998
|
this.historyManager = new HistoryManager(this);
|
|
20816
20999
|
this.position = new Position(this);
|
|
@@ -20875,6 +21058,8 @@ var Draw = class {
|
|
|
20875
21058
|
this.pageRowList = [];
|
|
20876
21059
|
this.painterStyle = null;
|
|
20877
21060
|
this.painterOptions = null;
|
|
21061
|
+
this.elementFontCache = /* @__PURE__ */ new WeakMap();
|
|
21062
|
+
this.elementRowMarginCache = /* @__PURE__ */ new WeakMap();
|
|
20878
21063
|
this.visiblePageNoList = [];
|
|
20879
21064
|
this.intersectionPageNo = 0;
|
|
20880
21065
|
this.lazyRenderIntersectionObserver = null;
|
|
@@ -21041,7 +21226,9 @@ var Draw = class {
|
|
|
21041
21226
|
getContextInnerWidth() {
|
|
21042
21227
|
const positionContext = this.position.getPositionContext();
|
|
21043
21228
|
if (positionContext.isTable) {
|
|
21044
|
-
const td = this.resolveTableCellContext(
|
|
21229
|
+
const td = this.resolveTableCellContext(
|
|
21230
|
+
this.getOriginalElementList()
|
|
21231
|
+
)?.td;
|
|
21045
21232
|
if (!td) return this.getColumnWidth() / this.options.scale;
|
|
21046
21233
|
const tdPadding = this.getTdPadding();
|
|
21047
21234
|
return td.width - tdPadding[1] - tdPadding[3];
|
|
@@ -21094,6 +21281,7 @@ var Draw = class {
|
|
|
21094
21281
|
return this.visiblePageNoList;
|
|
21095
21282
|
}
|
|
21096
21283
|
setVisiblePageNoList(payload) {
|
|
21284
|
+
if (isArrayEqual(this.visiblePageNoList, payload)) return;
|
|
21097
21285
|
this.visiblePageNoList = payload;
|
|
21098
21286
|
if (this.listener.visiblePageNoListChange) {
|
|
21099
21287
|
this.listener.visiblePageNoListChange(this.visiblePageNoList);
|
|
@@ -21106,6 +21294,7 @@ var Draw = class {
|
|
|
21106
21294
|
return this.intersectionPageNo;
|
|
21107
21295
|
}
|
|
21108
21296
|
setIntersectionPageNo(payload) {
|
|
21297
|
+
if (this.intersectionPageNo === payload) return;
|
|
21109
21298
|
this.intersectionPageNo = payload;
|
|
21110
21299
|
if (this.listener.intersectionPageNoChange) {
|
|
21111
21300
|
this.listener.intersectionPageNoChange(this.intersectionPageNo);
|
|
@@ -21133,7 +21322,9 @@ var Draw = class {
|
|
|
21133
21322
|
candidateIndexes.push(context.index);
|
|
21134
21323
|
}
|
|
21135
21324
|
if (context.tableId) {
|
|
21136
|
-
const tableIndex = sourceElementList.findIndex(
|
|
21325
|
+
const tableIndex = sourceElementList.findIndex(
|
|
21326
|
+
(el) => el.id === context.tableId
|
|
21327
|
+
);
|
|
21137
21328
|
if (~tableIndex && !candidateIndexes.includes(tableIndex)) {
|
|
21138
21329
|
candidateIndexes.push(tableIndex);
|
|
21139
21330
|
}
|
|
@@ -21242,9 +21433,7 @@ var Draw = class {
|
|
|
21242
21433
|
return this.header.getElementList();
|
|
21243
21434
|
}
|
|
21244
21435
|
getTableElementList(sourceElementList) {
|
|
21245
|
-
const splitCellSelectionContext = this.getSplitCellSelectionContext(
|
|
21246
|
-
sourceElementList
|
|
21247
|
-
);
|
|
21436
|
+
const splitCellSelectionContext = this.getSplitCellSelectionContext(sourceElementList);
|
|
21248
21437
|
if (splitCellSelectionContext) {
|
|
21249
21438
|
return splitCellSelectionContext.value;
|
|
21250
21439
|
}
|
|
@@ -21368,10 +21557,7 @@ var Draw = class {
|
|
|
21368
21557
|
positionContext.trId = continuationTr.id;
|
|
21369
21558
|
positionContext.tableId = tableId;
|
|
21370
21559
|
this.position.setPositionContext(positionContext);
|
|
21371
|
-
this.range.setRange(
|
|
21372
|
-
continuationCursorIndex,
|
|
21373
|
-
continuationCursorIndex
|
|
21374
|
-
);
|
|
21560
|
+
this.range.setRange(continuationCursorIndex, continuationCursorIndex);
|
|
21375
21561
|
this.pendingTableCursorIndex = continuationCursorIndex;
|
|
21376
21562
|
return true;
|
|
21377
21563
|
}
|
|
@@ -21431,7 +21617,10 @@ var Draw = class {
|
|
|
21431
21617
|
});
|
|
21432
21618
|
const splitCellSelection = this.range.getSplitCellSelection();
|
|
21433
21619
|
if (splitCellSelection) {
|
|
21434
|
-
const curIndex2 = this.replaceSplitCellSelection(
|
|
21620
|
+
const curIndex2 = this.replaceSplitCellSelection(
|
|
21621
|
+
payload,
|
|
21622
|
+
splitCellSelection
|
|
21623
|
+
);
|
|
21435
21624
|
if (~curIndex2) {
|
|
21436
21625
|
this.range.setRange(curIndex2, curIndex2);
|
|
21437
21626
|
this.render({
|
|
@@ -21561,12 +21750,7 @@ var Draw = class {
|
|
|
21561
21750
|
trId: rootCellContext.tr.id,
|
|
21562
21751
|
tdId: rootTd.id
|
|
21563
21752
|
});
|
|
21564
|
-
this.spliceElementList(
|
|
21565
|
-
rootTd.value,
|
|
21566
|
-
1,
|
|
21567
|
-
rootTd.value.length - 1,
|
|
21568
|
-
payload
|
|
21569
|
-
);
|
|
21753
|
+
this.spliceElementList(rootTd.value, 1, rootTd.value.length - 1, payload);
|
|
21570
21754
|
rootTd.rowList = void 0;
|
|
21571
21755
|
rootTd.positionList = void 0;
|
|
21572
21756
|
rootTd.mainHeight = void 0;
|
|
@@ -21986,6 +22170,15 @@ var Draw = class {
|
|
|
21986
22170
|
this._initPageContext(ctx);
|
|
21987
22171
|
this.pageList.push(canvas);
|
|
21988
22172
|
this.ctxList.push(ctx);
|
|
22173
|
+
this.pageRenderVersionList.push(0);
|
|
22174
|
+
}
|
|
22175
|
+
_createMeasureContext() {
|
|
22176
|
+
const canvas = document.createElement("canvas");
|
|
22177
|
+
const ctx = canvas.getContext("2d");
|
|
22178
|
+
ctx.letterSpacing = "0px";
|
|
22179
|
+
ctx.wordSpacing = "0px";
|
|
22180
|
+
ctx.direction = "ltr";
|
|
22181
|
+
return ctx;
|
|
21989
22182
|
}
|
|
21990
22183
|
_initPageContext(ctx) {
|
|
21991
22184
|
const dpr = this.getPagePixelRatio();
|
|
@@ -21998,8 +22191,22 @@ var Draw = class {
|
|
|
21998
22191
|
const { defaultSize, defaultFont } = this.options;
|
|
21999
22192
|
const font = el.font || defaultFont;
|
|
22000
22193
|
const size = el.actualSize || el.size || defaultSize;
|
|
22194
|
+
const cache = this.elementFontCache.get(el);
|
|
22195
|
+
if (cache && cache.scale === scale && cache.font === font && cache.size === size && cache.actualSize === el.actualSize && cache.bold === el.bold && cache.italic === el.italic) {
|
|
22196
|
+
return cache.style;
|
|
22197
|
+
}
|
|
22001
22198
|
const sizePx = size * (96 / 72) * scale;
|
|
22002
|
-
|
|
22199
|
+
const style = `${el.italic ? "italic " : ""}${el.bold ? "bold " : ""}${sizePx}px ${font}`;
|
|
22200
|
+
this.elementFontCache.set(el, {
|
|
22201
|
+
scale,
|
|
22202
|
+
font,
|
|
22203
|
+
size,
|
|
22204
|
+
actualSize: el.actualSize,
|
|
22205
|
+
bold: el.bold,
|
|
22206
|
+
italic: el.italic,
|
|
22207
|
+
style
|
|
22208
|
+
});
|
|
22209
|
+
return style;
|
|
22003
22210
|
}
|
|
22004
22211
|
getElementSize(el) {
|
|
22005
22212
|
return el.actualSize || el.size || this.options.defaultSize;
|
|
@@ -22012,13 +22219,25 @@ var Draw = class {
|
|
|
22012
22219
|
scale
|
|
22013
22220
|
} = this.options;
|
|
22014
22221
|
const fontSize = el.size || defaultSize;
|
|
22222
|
+
const rowMarginValue = el.rowMargin ?? defaultRowMargin;
|
|
22223
|
+
const cache = this.elementRowMarginCache.get(el);
|
|
22224
|
+
if (cache && cache.scale === scale && cache.size === fontSize && cache.rowMargin === rowMarginValue) {
|
|
22225
|
+
return cache.value;
|
|
22226
|
+
}
|
|
22015
22227
|
let ratio = 1;
|
|
22016
22228
|
if (fontSize < 12) {
|
|
22017
22229
|
ratio = fontSize / 12;
|
|
22018
22230
|
} else if (fontSize > 30) {
|
|
22019
22231
|
ratio = 1 + (fontSize - 30) / 30;
|
|
22020
22232
|
}
|
|
22021
|
-
|
|
22233
|
+
const value = defaultBasicRowMarginHeight * ratio * rowMarginValue * scale;
|
|
22234
|
+
this.elementRowMarginCache.set(el, {
|
|
22235
|
+
scale,
|
|
22236
|
+
size: fontSize,
|
|
22237
|
+
rowMargin: rowMarginValue,
|
|
22238
|
+
value
|
|
22239
|
+
});
|
|
22240
|
+
return value;
|
|
22022
22241
|
}
|
|
22023
22242
|
createListStateSeed(initialListState) {
|
|
22024
22243
|
const listLevelIndex = /* @__PURE__ */ new Map();
|
|
@@ -22097,7 +22316,12 @@ var Draw = class {
|
|
|
22097
22316
|
pageHeight = 0,
|
|
22098
22317
|
mainOuterHeight = 0,
|
|
22099
22318
|
surroundElementList = [],
|
|
22100
|
-
initialListState
|
|
22319
|
+
initialListState,
|
|
22320
|
+
hasListElement = true,
|
|
22321
|
+
fromIndex = 0,
|
|
22322
|
+
initialY = startY,
|
|
22323
|
+
initialPageNo = 0,
|
|
22324
|
+
initialRowIndex = 0
|
|
22101
22325
|
} = payload;
|
|
22102
22326
|
const {
|
|
22103
22327
|
defaultSize,
|
|
@@ -22106,27 +22330,62 @@ var Draw = class {
|
|
|
22106
22330
|
defaultTabWidth
|
|
22107
22331
|
} = this.options;
|
|
22108
22332
|
const defaultBasicRowMarginHeight = this.getDefaultBasicRowMarginHeight();
|
|
22109
|
-
const
|
|
22110
|
-
|
|
22111
|
-
|
|
22333
|
+
const ctx = this.measureCtx;
|
|
22334
|
+
ctx.save();
|
|
22335
|
+
ctx.font = "10px sans-serif";
|
|
22336
|
+
ctx.textAlign = "start";
|
|
22337
|
+
ctx.textBaseline = "alphabetic";
|
|
22338
|
+
const listStyleMap = hasListElement ? this.listParticle.computeListStyle(ctx, elementList) : /* @__PURE__ */ new Map();
|
|
22339
|
+
const wordMeasureCache = /* @__PURE__ */ new Map();
|
|
22340
|
+
const getWordMeasure = (curIndex, elementFont) => {
|
|
22341
|
+
const cache = wordMeasureCache.get(curIndex);
|
|
22342
|
+
if (cache) return cache;
|
|
22343
|
+
let endIndex = curIndex;
|
|
22344
|
+
while (endIndex < elementList.length) {
|
|
22345
|
+
const measureElement = elementList[endIndex];
|
|
22346
|
+
if (measureElement.type && measureElement.type !== "text" /* TEXT */ || !this.LETTER_REG.test(measureElement.value)) {
|
|
22347
|
+
break;
|
|
22348
|
+
}
|
|
22349
|
+
if (this.getElementFont(measureElement) !== elementFont) {
|
|
22350
|
+
const fallbackWord = this.textParticle.measureWord(
|
|
22351
|
+
ctx,
|
|
22352
|
+
elementList,
|
|
22353
|
+
curIndex
|
|
22354
|
+
);
|
|
22355
|
+
wordMeasureCache.set(curIndex, fallbackWord);
|
|
22356
|
+
return fallbackWord;
|
|
22357
|
+
}
|
|
22358
|
+
endIndex++;
|
|
22359
|
+
}
|
|
22360
|
+
const endElement = elementList[endIndex] || null;
|
|
22361
|
+
let suffixWidth = 0;
|
|
22362
|
+
for (let i = endIndex - 1; i >= curIndex; i--) {
|
|
22363
|
+
suffixWidth += this.textParticle.measureText(ctx, elementList[i]).width;
|
|
22364
|
+
wordMeasureCache.set(i, {
|
|
22365
|
+
width: suffixWidth,
|
|
22366
|
+
endElement
|
|
22367
|
+
});
|
|
22368
|
+
}
|
|
22369
|
+
return wordMeasureCache.get(curIndex);
|
|
22370
|
+
};
|
|
22112
22371
|
const rowList = [];
|
|
22113
|
-
if (elementList.length) {
|
|
22372
|
+
if (elementList.length && fromIndex < elementList.length) {
|
|
22114
22373
|
rowList.push({
|
|
22115
22374
|
width: 0,
|
|
22116
22375
|
height: 0,
|
|
22117
22376
|
ascent: 0,
|
|
22118
22377
|
elementList: [],
|
|
22119
|
-
startIndex:
|
|
22120
|
-
rowIndex:
|
|
22121
|
-
rowFlex: elementList?.[
|
|
22378
|
+
startIndex: fromIndex,
|
|
22379
|
+
rowIndex: initialRowIndex,
|
|
22380
|
+
rowFlex: elementList?.[fromIndex]?.rowFlex || elementList?.[fromIndex + 1]?.rowFlex
|
|
22122
22381
|
});
|
|
22123
22382
|
}
|
|
22124
22383
|
let x = startX;
|
|
22125
|
-
let y =
|
|
22126
|
-
let pageNo =
|
|
22384
|
+
let y = initialY;
|
|
22385
|
+
let pageNo = initialPageNo;
|
|
22127
22386
|
const listState = this.createListStateSeed(initialListState);
|
|
22128
22387
|
let controlRealWidth = 0;
|
|
22129
|
-
for (let i =
|
|
22388
|
+
for (let i = fromIndex; i < elementList.length; i++) {
|
|
22130
22389
|
const curRow = rowList[rowList.length - 1];
|
|
22131
22390
|
const element = elementList[i];
|
|
22132
22391
|
const rowMargin = this.getElementRowMargin(element);
|
|
@@ -22172,9 +22431,7 @@ var Draw = class {
|
|
|
22172
22431
|
} else if (element.type === "table" /* TABLE */) {
|
|
22173
22432
|
let activeSplitRange;
|
|
22174
22433
|
let mergedSplitFallback;
|
|
22175
|
-
const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(
|
|
22176
|
-
element
|
|
22177
|
-
);
|
|
22434
|
+
const logicalSplitCursor = this.getCollapsedSplitTableCursorContext(element);
|
|
22178
22435
|
if (element.pagingId) {
|
|
22179
22436
|
let tableIndex = i + 1;
|
|
22180
22437
|
let combineCount = 0;
|
|
@@ -22779,16 +23036,14 @@ var Draw = class {
|
|
|
22779
23036
|
element.actualSize = Math.ceil(size * 0.6);
|
|
22780
23037
|
}
|
|
22781
23038
|
metrics.height = (element.actualSize || size) * scale;
|
|
22782
|
-
|
|
23039
|
+
const elementFont = this.getElementFont(element);
|
|
23040
|
+
ctx.font = elementFont;
|
|
22783
23041
|
const fontMetrics = this.textParticle.measureText(ctx, element);
|
|
22784
23042
|
metrics.width = fontMetrics.width * scale;
|
|
22785
23043
|
if (element.letterSpacing) {
|
|
22786
23044
|
metrics.width += element.letterSpacing * scale;
|
|
22787
23045
|
}
|
|
22788
|
-
const basisMetrics = this.textParticle.measureBasisWord(
|
|
22789
|
-
ctx,
|
|
22790
|
-
element.font
|
|
22791
|
-
);
|
|
23046
|
+
const basisMetrics = this.textParticle.measureBasisWord(ctx, elementFont);
|
|
22792
23047
|
metrics.boundingBoxAscent = basisMetrics.fontBoundingBoxAscent * scale;
|
|
22793
23048
|
metrics.boundingBoxDescent = basisMetrics.fontBoundingBoxDescent * scale;
|
|
22794
23049
|
if (element.type === "superscript" /* SUPERSCRIPT */) {
|
|
@@ -22825,11 +23080,7 @@ var Draw = class {
|
|
|
22825
23080
|
if ((!preElement?.type || preElement?.type === "text" /* TEXT */) && (!element.type || element.type === "text" /* TEXT */)) {
|
|
22826
23081
|
const word = `${preElement?.value || ""}${element.value}`;
|
|
22827
23082
|
if (this.WORD_LIKE_REG.test(word)) {
|
|
22828
|
-
const { width, endElement } =
|
|
22829
|
-
ctx,
|
|
22830
|
-
elementList,
|
|
22831
|
-
i
|
|
22832
|
-
);
|
|
23083
|
+
const { width, endElement } = getWordMeasure(i, ctx.font);
|
|
22833
23084
|
const wordWidth = width * scale;
|
|
22834
23085
|
if (endElement && wordWidth <= availableWidth) {
|
|
22835
23086
|
curRowWidth += wordWidth;
|
|
@@ -22962,6 +23213,7 @@ var Draw = class {
|
|
|
22962
23213
|
x += metrics.width;
|
|
22963
23214
|
}
|
|
22964
23215
|
}
|
|
23216
|
+
ctx.restore();
|
|
22965
23217
|
return rowList;
|
|
22966
23218
|
}
|
|
22967
23219
|
_applyRowSpacing() {
|
|
@@ -23554,30 +23806,11 @@ var Draw = class {
|
|
|
23554
23806
|
if (this.isGraffitiMode()) {
|
|
23555
23807
|
this.graffiti.render(ctx, pageNo);
|
|
23556
23808
|
}
|
|
23809
|
+
this.pageRenderVersionList[pageNo] = this.renderCount;
|
|
23557
23810
|
}
|
|
23558
23811
|
_disconnectLazyRender() {
|
|
23559
23812
|
this.lazyRenderIntersectionObserver?.disconnect();
|
|
23560
|
-
|
|
23561
|
-
_lazyRender() {
|
|
23562
|
-
const positionList = this.position.getOriginalMainPositionList();
|
|
23563
|
-
const elementList = this.getOriginalMainElementList();
|
|
23564
|
-
this._disconnectLazyRender();
|
|
23565
|
-
this.lazyRenderIntersectionObserver = new IntersectionObserver((entries) => {
|
|
23566
|
-
entries.forEach((entry) => {
|
|
23567
|
-
if (entry.isIntersecting) {
|
|
23568
|
-
const index = Number(entry.target.dataset.index);
|
|
23569
|
-
this._drawPage({
|
|
23570
|
-
elementList,
|
|
23571
|
-
positionList,
|
|
23572
|
-
rowList: this.pageRowList[index],
|
|
23573
|
-
pageNo: index
|
|
23574
|
-
});
|
|
23575
|
-
}
|
|
23576
|
-
});
|
|
23577
|
-
});
|
|
23578
|
-
this.pageList.forEach((el) => {
|
|
23579
|
-
this.lazyRenderIntersectionObserver.observe(el);
|
|
23580
|
-
});
|
|
23813
|
+
this.lazyRenderIntersectionObserver = null;
|
|
23581
23814
|
}
|
|
23582
23815
|
_immediateRender() {
|
|
23583
23816
|
const positionList = this.position.getOriginalMainPositionList();
|
|
@@ -23591,6 +23824,100 @@ var Draw = class {
|
|
|
23591
23824
|
});
|
|
23592
23825
|
}
|
|
23593
23826
|
}
|
|
23827
|
+
_collectMainRenderMeta() {
|
|
23828
|
+
const surroundElementList = [];
|
|
23829
|
+
let hasAreaElement = false;
|
|
23830
|
+
let hasListElement = false;
|
|
23831
|
+
let hasStructuralElement = false;
|
|
23832
|
+
for (let i = 0; i < this.elementList.length; i++) {
|
|
23833
|
+
const element = this.elementList[i];
|
|
23834
|
+
if (!hasAreaElement && element.areaId) {
|
|
23835
|
+
hasAreaElement = true;
|
|
23836
|
+
}
|
|
23837
|
+
if (!hasListElement && element.listId) {
|
|
23838
|
+
hasListElement = true;
|
|
23839
|
+
}
|
|
23840
|
+
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 */)) {
|
|
23841
|
+
hasStructuralElement = true;
|
|
23842
|
+
}
|
|
23843
|
+
if (element.imgDisplay === "surround" /* SURROUND */) {
|
|
23844
|
+
surroundElementList.push(element);
|
|
23845
|
+
}
|
|
23846
|
+
}
|
|
23847
|
+
return {
|
|
23848
|
+
hasAreaElement,
|
|
23849
|
+
hasListElement,
|
|
23850
|
+
hasStructuralElement,
|
|
23851
|
+
surroundElementList
|
|
23852
|
+
};
|
|
23853
|
+
}
|
|
23854
|
+
_getIncrementalRestartState(dirtyStartIndex, rowList, pageRowList, startY) {
|
|
23855
|
+
if (!rowList.length || !pageRowList.length) return null;
|
|
23856
|
+
const searchIndex = Math.max(dirtyStartIndex - 1, 0);
|
|
23857
|
+
let restartRowIndex = -1;
|
|
23858
|
+
for (let i = 0; i < rowList.length; i++) {
|
|
23859
|
+
if (rowList[i].startIndex <= searchIndex) {
|
|
23860
|
+
restartRowIndex = i;
|
|
23861
|
+
} else {
|
|
23862
|
+
break;
|
|
23863
|
+
}
|
|
23864
|
+
}
|
|
23865
|
+
if (restartRowIndex < 0) return null;
|
|
23866
|
+
if (restartRowIndex > 0 && this.elementList[rowList[restartRowIndex].startIndex]?.value === ZERO && !this.elementList[rowList[restartRowIndex].startIndex]?.listWrap) {
|
|
23867
|
+
restartRowIndex -= 1;
|
|
23868
|
+
}
|
|
23869
|
+
const restartRow = rowList[restartRowIndex];
|
|
23870
|
+
const fromIndex = Math.min(restartRow.startIndex, this.elementList.length);
|
|
23871
|
+
let initialPageNo = 0;
|
|
23872
|
+
let initialY = startY;
|
|
23873
|
+
let absoluteRowIndex = 0;
|
|
23874
|
+
let isFound = false;
|
|
23875
|
+
for (let pageNo = 0; pageNo < pageRowList.length; pageNo++) {
|
|
23876
|
+
const rows = pageRowList[pageNo];
|
|
23877
|
+
let y = startY;
|
|
23878
|
+
for (let rowNo = 0; rowNo < rows.length; rowNo++) {
|
|
23879
|
+
if (absoluteRowIndex === restartRowIndex) {
|
|
23880
|
+
initialPageNo = pageNo;
|
|
23881
|
+
initialY = y;
|
|
23882
|
+
isFound = true;
|
|
23883
|
+
break;
|
|
23884
|
+
}
|
|
23885
|
+
const row = rows[rowNo];
|
|
23886
|
+
y += (row.offsetY || 0) + (row.spaceAbove || 0) + row.height + (row.spaceBelow || 0);
|
|
23887
|
+
absoluteRowIndex++;
|
|
23888
|
+
}
|
|
23889
|
+
if (isFound) break;
|
|
23890
|
+
}
|
|
23891
|
+
if (!isFound) return null;
|
|
23892
|
+
return {
|
|
23893
|
+
fromIndex,
|
|
23894
|
+
initialY,
|
|
23895
|
+
initialPageNo,
|
|
23896
|
+
initialRowIndex: restartRow.rowIndex,
|
|
23897
|
+
initialListState: this.getListStateBeforeIndex(this.elementList, fromIndex),
|
|
23898
|
+
prefixRows: rowList.slice(0, restartRowIndex)
|
|
23899
|
+
};
|
|
23900
|
+
}
|
|
23901
|
+
renderVisiblePages(pageNoList) {
|
|
23902
|
+
const positionList = this.position.getOriginalMainPositionList();
|
|
23903
|
+
const elementList = this.getOriginalMainElementList();
|
|
23904
|
+
const targetPageNoList = pageNoList ?? this.visiblePageNoList;
|
|
23905
|
+
if (!targetPageNoList?.length) return;
|
|
23906
|
+
const renderedPageNoSet = /* @__PURE__ */ new Set();
|
|
23907
|
+
for (let i = 0; i < targetPageNoList.length; i++) {
|
|
23908
|
+
const pageNo = targetPageNoList[i];
|
|
23909
|
+
if (renderedPageNoSet.has(pageNo) || pageNo < 0 || pageNo >= this.pageRowList.length || this.pageRenderVersionList[pageNo] === this.renderCount) {
|
|
23910
|
+
continue;
|
|
23911
|
+
}
|
|
23912
|
+
renderedPageNoSet.add(pageNo);
|
|
23913
|
+
this._drawPage({
|
|
23914
|
+
elementList,
|
|
23915
|
+
positionList,
|
|
23916
|
+
rowList: this.pageRowList[pageNo],
|
|
23917
|
+
pageNo
|
|
23918
|
+
});
|
|
23919
|
+
}
|
|
23920
|
+
}
|
|
23594
23921
|
render(payload) {
|
|
23595
23922
|
this.renderCount++;
|
|
23596
23923
|
const { header, footer } = this.options;
|
|
@@ -23602,15 +23929,19 @@ var Draw = class {
|
|
|
23602
23929
|
isLazy = true,
|
|
23603
23930
|
isInit = false,
|
|
23604
23931
|
isSourceHistory = false,
|
|
23605
|
-
isFirstRender = false
|
|
23932
|
+
isFirstRender = false,
|
|
23933
|
+
dirtyStartIndex
|
|
23606
23934
|
} = payload || {};
|
|
23607
23935
|
let { curIndex } = payload || {};
|
|
23608
23936
|
this.pendingTableCursorIndex = void 0;
|
|
23609
23937
|
const innerWidth = this.getInnerWidth();
|
|
23610
23938
|
const columnWidth = this.getColumnWidth();
|
|
23611
23939
|
const isPagingMode = this.getIsPagingMode();
|
|
23940
|
+
const columnCount = this.getColumnCount();
|
|
23612
23941
|
const oldPageSize = this.pageRowList.length;
|
|
23613
23942
|
if (isCompute) {
|
|
23943
|
+
const oldRowList = this.rowList;
|
|
23944
|
+
const oldPageRowList = this.pageRowList;
|
|
23614
23945
|
this.position.setFloatPositionList([]);
|
|
23615
23946
|
if (isPagingMode) {
|
|
23616
23947
|
if (!header.disabled) {
|
|
@@ -23626,8 +23957,13 @@ var Draw = class {
|
|
|
23626
23957
|
const mainOuterHeight = this.getMainOuterHeight();
|
|
23627
23958
|
const startX = margins[3];
|
|
23628
23959
|
const startY = margins[0] + extraHeight;
|
|
23629
|
-
const
|
|
23630
|
-
|
|
23960
|
+
const {
|
|
23961
|
+
hasAreaElement,
|
|
23962
|
+
hasListElement,
|
|
23963
|
+
hasStructuralElement,
|
|
23964
|
+
surroundElementList
|
|
23965
|
+
} = this._collectMainRenderMeta();
|
|
23966
|
+
const rowListPayload = {
|
|
23631
23967
|
startX,
|
|
23632
23968
|
startY,
|
|
23633
23969
|
pageHeight,
|
|
@@ -23635,12 +23971,41 @@ var Draw = class {
|
|
|
23635
23971
|
isPagingMode,
|
|
23636
23972
|
innerWidth: columnWidth,
|
|
23637
23973
|
surroundElementList,
|
|
23974
|
+
hasListElement,
|
|
23638
23975
|
elementList: this.elementList
|
|
23639
|
-
}
|
|
23976
|
+
};
|
|
23977
|
+
const canUseIncrementalMainRows = dirtyStartIndex !== void 0 && dirtyStartIndex >= 0 && !isInit && !isSourceHistory && isPagingMode && columnCount === 1 && !hasAreaElement && !hasStructuralElement && surroundElementList.length === 0 && oldRowList.length > 0 && oldPageRowList.length > 0;
|
|
23978
|
+
if (canUseIncrementalMainRows) {
|
|
23979
|
+
const restartState = this._getIncrementalRestartState(
|
|
23980
|
+
dirtyStartIndex,
|
|
23981
|
+
oldRowList,
|
|
23982
|
+
oldPageRowList,
|
|
23983
|
+
startY
|
|
23984
|
+
);
|
|
23985
|
+
if (restartState) {
|
|
23986
|
+
const suffixRows = this.computeRowList({
|
|
23987
|
+
...rowListPayload,
|
|
23988
|
+
fromIndex: restartState.fromIndex,
|
|
23989
|
+
initialY: restartState.initialY,
|
|
23990
|
+
initialPageNo: restartState.initialPageNo,
|
|
23991
|
+
initialRowIndex: restartState.initialRowIndex,
|
|
23992
|
+
initialListState: restartState.initialListState
|
|
23993
|
+
});
|
|
23994
|
+
this.rowList = restartState.prefixRows.concat(suffixRows);
|
|
23995
|
+
} else {
|
|
23996
|
+
this.rowList = this.computeRowList(rowListPayload);
|
|
23997
|
+
}
|
|
23998
|
+
} else {
|
|
23999
|
+
this.rowList = this.computeRowList(rowListPayload);
|
|
24000
|
+
}
|
|
23640
24001
|
this._applyRowSpacing();
|
|
23641
24002
|
this.pageRowList = this._computePageList();
|
|
23642
24003
|
this.position.computePositionList();
|
|
23643
|
-
|
|
24004
|
+
if (hasAreaElement) {
|
|
24005
|
+
this.area.compute();
|
|
24006
|
+
} else {
|
|
24007
|
+
this.area.clear();
|
|
24008
|
+
}
|
|
23644
24009
|
if (!this.isPrintMode()) {
|
|
23645
24010
|
const searchKeyword = this.search.getSearchKeyword();
|
|
23646
24011
|
if (searchKeyword) {
|
|
@@ -23664,10 +24029,26 @@ var Draw = class {
|
|
|
23664
24029
|
if (prePageCount > curPageCount) {
|
|
23665
24030
|
const deleteCount = prePageCount - curPageCount;
|
|
23666
24031
|
this.ctxList.splice(curPageCount, deleteCount);
|
|
24032
|
+
this.pageRenderVersionList.splice(curPageCount, deleteCount);
|
|
23667
24033
|
this.pageList.splice(curPageCount, deleteCount).forEach((page) => page.remove());
|
|
23668
24034
|
}
|
|
23669
24035
|
if (isLazy && isPagingMode) {
|
|
23670
|
-
this.
|
|
24036
|
+
let visiblePageNoList = this.visiblePageNoList.filter(
|
|
24037
|
+
(pageNo) => pageNo >= 0 && pageNo < curPageCount
|
|
24038
|
+
);
|
|
24039
|
+
let intersectionPageNo = Math.min(
|
|
24040
|
+
this.intersectionPageNo,
|
|
24041
|
+
Math.max(curPageCount - 1, 0)
|
|
24042
|
+
);
|
|
24043
|
+
if (!visiblePageNoList.length || oldPageSize !== curPageCount || intersectionPageNo >= curPageCount) {
|
|
24044
|
+
const visibleInfo = this.scrollObserver.getPageVisibleInfo();
|
|
24045
|
+
intersectionPageNo = visibleInfo.intersectionPageNo;
|
|
24046
|
+
visiblePageNoList = visibleInfo.visiblePageNoList;
|
|
24047
|
+
this.setIntersectionPageNo(intersectionPageNo);
|
|
24048
|
+
this.setVisiblePageNoList(visiblePageNoList);
|
|
24049
|
+
}
|
|
24050
|
+
const renderPageNoList = visiblePageNoList.length ? visiblePageNoList : [intersectionPageNo];
|
|
24051
|
+
this.renderVisiblePages(renderPageNoList);
|
|
23671
24052
|
} else {
|
|
23672
24053
|
this._immediateRender();
|
|
23673
24054
|
}
|
|
@@ -23716,7 +24097,9 @@ var Draw = class {
|
|
|
23716
24097
|
const positionContext = this.position.getPositionContext();
|
|
23717
24098
|
const positionList = this.position.getPositionList();
|
|
23718
24099
|
if (positionContext.isTable) {
|
|
23719
|
-
const tablePositionList = this.resolveTableCellContext(
|
|
24100
|
+
const tablePositionList = this.resolveTableCellContext(
|
|
24101
|
+
this.getOriginalElementList()
|
|
24102
|
+
)?.td.positionList;
|
|
23720
24103
|
if (curIndex === void 0 && tablePositionList) {
|
|
23721
24104
|
curIndex = tablePositionList.length - 1;
|
|
23722
24105
|
}
|
|
@@ -23743,36 +24126,51 @@ var Draw = class {
|
|
|
23743
24126
|
return curIndex;
|
|
23744
24127
|
}
|
|
23745
24128
|
submitHistory(curIndex, isInput = false) {
|
|
23746
|
-
const
|
|
23747
|
-
|
|
23748
|
-
|
|
23749
|
-
this.
|
|
23750
|
-
|
|
23751
|
-
|
|
23752
|
-
this.
|
|
23753
|
-
|
|
23754
|
-
|
|
23755
|
-
const
|
|
23756
|
-
|
|
23757
|
-
|
|
23758
|
-
|
|
23759
|
-
|
|
23760
|
-
|
|
23761
|
-
|
|
23762
|
-
|
|
23763
|
-
|
|
23764
|
-
|
|
23765
|
-
|
|
23766
|
-
|
|
23767
|
-
|
|
23768
|
-
|
|
23769
|
-
|
|
23770
|
-
|
|
24129
|
+
const snapshot = {
|
|
24130
|
+
elementList: getSlimCloneElementList(this.elementList),
|
|
24131
|
+
headerElementList: getSlimCloneElementList(this.header.getElementList()),
|
|
24132
|
+
footerElementList: getSlimCloneElementList(this.footer.getElementList()),
|
|
24133
|
+
range: deepClone(this.range.getRange()),
|
|
24134
|
+
pageNo: this.pageNo,
|
|
24135
|
+
positionContext: deepClone(this.position.getPositionContext()),
|
|
24136
|
+
zone: this.zone.getZone()
|
|
24137
|
+
};
|
|
24138
|
+
const entry = {
|
|
24139
|
+
restore: () => {
|
|
24140
|
+
const {
|
|
24141
|
+
elementList,
|
|
24142
|
+
headerElementList,
|
|
24143
|
+
footerElementList,
|
|
24144
|
+
range,
|
|
24145
|
+
pageNo,
|
|
24146
|
+
positionContext,
|
|
24147
|
+
zone
|
|
24148
|
+
} = snapshot;
|
|
24149
|
+
const restoredHeaderElementList = inflateElementList(
|
|
24150
|
+
deepClone(headerElementList)
|
|
24151
|
+
);
|
|
24152
|
+
const restoredFooterElementList = inflateElementList(
|
|
24153
|
+
deepClone(footerElementList)
|
|
24154
|
+
);
|
|
24155
|
+
const restoredMainElementList = inflateElementList(deepClone(elementList));
|
|
24156
|
+
this.zone.setZone(zone);
|
|
24157
|
+
this.setPageNo(pageNo);
|
|
24158
|
+
this.position.setPositionContext(deepClone(positionContext));
|
|
24159
|
+
this.header.setElementList(restoredHeaderElementList);
|
|
24160
|
+
this.footer.setElementList(restoredFooterElementList);
|
|
24161
|
+
this.elementList = restoredMainElementList;
|
|
24162
|
+
this.range.replaceRange(deepClone(range));
|
|
24163
|
+
this.render({
|
|
24164
|
+
curIndex,
|
|
24165
|
+
isSubmitHistory: false,
|
|
24166
|
+
isSourceHistory: true
|
|
24167
|
+
});
|
|
24168
|
+
}
|
|
23771
24169
|
};
|
|
23772
24170
|
if (isInput && this.historyManager.isInputGroupable()) {
|
|
23773
|
-
this.historyManager.replaceLatest(
|
|
24171
|
+
this.historyManager.replaceLatest(entry);
|
|
23774
24172
|
} else {
|
|
23775
|
-
this.historyManager.execute(
|
|
24173
|
+
this.historyManager.execute(entry);
|
|
23776
24174
|
}
|
|
23777
24175
|
if (isInput) {
|
|
23778
24176
|
this.historyManager.recordInputTime();
|
|
@@ -23867,6 +24265,8 @@ var Command = class {
|
|
|
23867
24265
|
this.executeSearchNavigateNext = adapt.searchNavigateNext.bind(adapt);
|
|
23868
24266
|
this.executeReplace = adapt.replace.bind(adapt);
|
|
23869
24267
|
this.executePrint = adapt.print.bind(adapt);
|
|
24268
|
+
this.executeExportDocx = adapt.exportDocx.bind(adapt);
|
|
24269
|
+
this.executeExportPdf = adapt.exportPdf.bind(adapt);
|
|
23870
24270
|
this.executeReplaceImageElement = adapt.replaceImageElement.bind(adapt);
|
|
23871
24271
|
this.executeSaveAsImageElement = adapt.saveAsImageElement.bind(adapt);
|
|
23872
24272
|
this.executeSetImageCrop = adapt.setImageCrop.bind(adapt);
|
|
@@ -23947,50 +24347,3189 @@ var Command = class {
|
|
|
23947
24347
|
}
|
|
23948
24348
|
};
|
|
23949
24349
|
|
|
23950
|
-
// src/utils/
|
|
23951
|
-
|
|
23952
|
-
|
|
23953
|
-
|
|
23954
|
-
|
|
23955
|
-
|
|
23956
|
-
|
|
23957
|
-
|
|
23958
|
-
|
|
23959
|
-
|
|
23960
|
-
|
|
23961
|
-
|
|
23962
|
-
|
|
23963
|
-
|
|
23964
|
-
|
|
23965
|
-
|
|
23966
|
-
|
|
23967
|
-
|
|
23968
|
-
|
|
23969
|
-
|
|
23970
|
-
|
|
23971
|
-
|
|
23972
|
-
|
|
24350
|
+
// src/utils/docx.ts
|
|
24351
|
+
import {
|
|
24352
|
+
AlignmentType,
|
|
24353
|
+
BorderStyle,
|
|
24354
|
+
ColumnBreak,
|
|
24355
|
+
Document as Document2,
|
|
24356
|
+
ExternalHyperlink,
|
|
24357
|
+
Footer as Footer2,
|
|
24358
|
+
Header as Header2,
|
|
24359
|
+
HeadingLevel,
|
|
24360
|
+
ImageRun,
|
|
24361
|
+
LevelFormat,
|
|
24362
|
+
LineRuleType,
|
|
24363
|
+
Packer,
|
|
24364
|
+
PageBreak,
|
|
24365
|
+
PageNumber as PageNumber2,
|
|
24366
|
+
PageOrientation,
|
|
24367
|
+
Paragraph,
|
|
24368
|
+
ShadingType,
|
|
24369
|
+
Table,
|
|
24370
|
+
TableCell,
|
|
24371
|
+
TableLayoutType,
|
|
24372
|
+
TableRow,
|
|
24373
|
+
TextRun,
|
|
24374
|
+
UnderlineType,
|
|
24375
|
+
VerticalAlign as DocxVerticalAlign,
|
|
24376
|
+
WidthType
|
|
24377
|
+
} from "docx";
|
|
24378
|
+
var DEFAULT_DOCX_FILE_NAME = "document.docx";
|
|
24379
|
+
var DEFAULT_IMAGE_WIDTH = 320;
|
|
24380
|
+
var DEFAULT_IMAGE_HEIGHT = 180;
|
|
24381
|
+
var DEFAULT_LINE_HEIGHT = 1.15;
|
|
24382
|
+
var docxBulletCharMap = {
|
|
24383
|
+
["disc" /* DISC */]: "\u2022",
|
|
24384
|
+
["circle" /* CIRCLE */]: "\u25E6",
|
|
24385
|
+
["square" /* SQUARE */]: "\u25A0",
|
|
24386
|
+
["checkbox" /* CHECKBOX */]: "\u2611"
|
|
24387
|
+
};
|
|
24388
|
+
var titleHeadingMap = {
|
|
24389
|
+
["first" /* FIRST */]: HeadingLevel.HEADING_1,
|
|
24390
|
+
["second" /* SECOND */]: HeadingLevel.HEADING_2,
|
|
24391
|
+
["third" /* THIRD */]: HeadingLevel.HEADING_3,
|
|
24392
|
+
["fourth" /* FOURTH */]: HeadingLevel.HEADING_4,
|
|
24393
|
+
["fifth" /* FIFTH */]: HeadingLevel.HEADING_5,
|
|
24394
|
+
["sixth" /* SIXTH */]: HeadingLevel.HEADING_6
|
|
24395
|
+
};
|
|
24396
|
+
var orderedStyleFormatMap = {
|
|
24397
|
+
["decimal" /* DECIMAL */]: LevelFormat.DECIMAL,
|
|
24398
|
+
["lowerAlpha" /* LOWER_ALPHA */]: LevelFormat.LOWER_LETTER,
|
|
24399
|
+
["upperAlpha" /* UPPER_ALPHA */]: LevelFormat.UPPER_LETTER,
|
|
24400
|
+
["lowerRoman" /* LOWER_ROMAN */]: LevelFormat.LOWER_ROMAN,
|
|
24401
|
+
["upperRoman" /* UPPER_ROMAN */]: LevelFormat.UPPER_ROMAN,
|
|
24402
|
+
["decimalParen" /* DECIMAL_PAREN */]: LevelFormat.DECIMAL,
|
|
24403
|
+
decimalZero: LevelFormat.DECIMAL_ZERO,
|
|
24404
|
+
lowerAlphaParen: LevelFormat.LOWER_LETTER,
|
|
24405
|
+
lowerRomanParen: LevelFormat.LOWER_ROMAN,
|
|
24406
|
+
outline: LevelFormat.DECIMAL
|
|
24407
|
+
};
|
|
24408
|
+
async function exportEditorDataToDocx(payload, options = {}) {
|
|
24409
|
+
const fileName = normalizeDocxFileName(options.fileName);
|
|
24410
|
+
const file = await createDocxDocument(payload);
|
|
24411
|
+
const blob = await Packer.toBlob(file);
|
|
23973
24412
|
return {
|
|
23974
|
-
|
|
23975
|
-
|
|
23976
|
-
height: `${height}px`
|
|
24413
|
+
blob,
|
|
24414
|
+
fileName
|
|
23977
24415
|
};
|
|
23978
24416
|
}
|
|
23979
|
-
function
|
|
23980
|
-
const {
|
|
23981
|
-
const
|
|
23982
|
-
|
|
23983
|
-
|
|
23984
|
-
|
|
23985
|
-
|
|
23986
|
-
|
|
23987
|
-
|
|
23988
|
-
|
|
23989
|
-
|
|
23990
|
-
|
|
23991
|
-
const
|
|
23992
|
-
|
|
23993
|
-
|
|
24417
|
+
async function createDocxDocument(payload) {
|
|
24418
|
+
const { data: data2, options } = payload;
|
|
24419
|
+
const editorOptions = options;
|
|
24420
|
+
const context = createSerializeContext();
|
|
24421
|
+
const headerChildren = editorOptions.header.disabled ? [] : await serializeElementList(data2.header || [], editorOptions, context);
|
|
24422
|
+
const footerChildren = editorOptions.footer.disabled ? [] : await serializeElementList(data2.footer || [], editorOptions, context);
|
|
24423
|
+
const pageNumberParagraph = createPageNumberParagraph(
|
|
24424
|
+
editorOptions.pageNumber
|
|
24425
|
+
);
|
|
24426
|
+
if (pageNumberParagraph) {
|
|
24427
|
+
footerChildren.push(pageNumberParagraph);
|
|
24428
|
+
}
|
|
24429
|
+
const sectionChildren = await serializeElementList(
|
|
24430
|
+
data2.main,
|
|
24431
|
+
editorOptions,
|
|
24432
|
+
context
|
|
24433
|
+
);
|
|
24434
|
+
const { width, height, paperDirection } = editorOptions;
|
|
24435
|
+
const pageWidth = paperDirection === "horizontal" /* HORIZONTAL */ ? height : width;
|
|
24436
|
+
const pageHeight = paperDirection === "horizontal" /* HORIZONTAL */ ? width : height;
|
|
24437
|
+
return new Document2({
|
|
24438
|
+
features: {
|
|
24439
|
+
updateFields: true
|
|
24440
|
+
},
|
|
24441
|
+
numbering: {
|
|
24442
|
+
config: createNumberingConfig()
|
|
24443
|
+
},
|
|
24444
|
+
sections: [
|
|
24445
|
+
{
|
|
24446
|
+
properties: {
|
|
24447
|
+
page: {
|
|
24448
|
+
size: {
|
|
24449
|
+
width: pxToTwips(pageWidth),
|
|
24450
|
+
height: pxToTwips(pageHeight),
|
|
24451
|
+
orientation: paperDirection === "horizontal" /* HORIZONTAL */ ? PageOrientation.LANDSCAPE : PageOrientation.PORTRAIT
|
|
24452
|
+
},
|
|
24453
|
+
margin: {
|
|
24454
|
+
top: pxToTwips(editorOptions.margins[0]),
|
|
24455
|
+
right: pxToTwips(editorOptions.margins[1]),
|
|
24456
|
+
bottom: pxToTwips(editorOptions.margins[2]),
|
|
24457
|
+
left: pxToTwips(editorOptions.margins[3]),
|
|
24458
|
+
header: pxToTwips(editorOptions.header.top),
|
|
24459
|
+
footer: pxToTwips(editorOptions.footer.bottom)
|
|
24460
|
+
},
|
|
24461
|
+
pageNumbers: !editorOptions.pageNumber.disabled && editorOptions.pageNumber.fromPageNo === 0 ? {
|
|
24462
|
+
start: editorOptions.pageNumber.startPageNo
|
|
24463
|
+
} : void 0
|
|
24464
|
+
}
|
|
24465
|
+
},
|
|
24466
|
+
headers: headerChildren.length > 0 ? {
|
|
24467
|
+
default: new Header2({
|
|
24468
|
+
children: headerChildren
|
|
24469
|
+
})
|
|
24470
|
+
} : void 0,
|
|
24471
|
+
footers: footerChildren.length > 0 ? {
|
|
24472
|
+
default: new Footer2({
|
|
24473
|
+
children: footerChildren
|
|
24474
|
+
})
|
|
24475
|
+
} : void 0,
|
|
24476
|
+
children: sectionChildren.length ? sectionChildren : [new Paragraph({})]
|
|
24477
|
+
}
|
|
24478
|
+
]
|
|
24479
|
+
});
|
|
24480
|
+
}
|
|
24481
|
+
async function serializeElementList(elementList, options, context) {
|
|
24482
|
+
const blocks = [];
|
|
24483
|
+
let inlineBuffer = [];
|
|
24484
|
+
const flushInlineBuffer = async () => {
|
|
24485
|
+
if (!inlineBuffer.length) return;
|
|
24486
|
+
blocks.push(
|
|
24487
|
+
...await serializeInlineElements(inlineBuffer, options, context)
|
|
24488
|
+
);
|
|
24489
|
+
inlineBuffer = [];
|
|
24490
|
+
};
|
|
24491
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
24492
|
+
const element = elementList[i];
|
|
24493
|
+
if (element.type === "area" /* AREA */ && element.valueList?.length) {
|
|
24494
|
+
await flushInlineBuffer();
|
|
24495
|
+
blocks.push(
|
|
24496
|
+
...await serializeElementList(element.valueList, options, context)
|
|
24497
|
+
);
|
|
24498
|
+
continue;
|
|
24499
|
+
}
|
|
24500
|
+
if (element.type === "title" /* TITLE */ && element.valueList?.length) {
|
|
24501
|
+
await flushInlineBuffer();
|
|
24502
|
+
blocks.push(
|
|
24503
|
+
...await serializeInlineElements(element.valueList, options, context, {
|
|
24504
|
+
heading: titleHeadingMap[element.level || "first" /* FIRST */]
|
|
24505
|
+
})
|
|
24506
|
+
);
|
|
24507
|
+
continue;
|
|
24508
|
+
}
|
|
24509
|
+
if (element.type === "list" /* LIST */ && element.valueList?.length) {
|
|
24510
|
+
await flushInlineBuffer();
|
|
24511
|
+
blocks.push(...await serializeListElement(element, options, context));
|
|
24512
|
+
continue;
|
|
24513
|
+
}
|
|
24514
|
+
if (element.type === "table" /* TABLE */ && element.trList?.length) {
|
|
24515
|
+
await flushInlineBuffer();
|
|
24516
|
+
blocks.push(await serializeTableElement(element, options, context));
|
|
24517
|
+
continue;
|
|
24518
|
+
}
|
|
24519
|
+
if (element.type === "pageBreak" /* PAGE_BREAK */) {
|
|
24520
|
+
await flushInlineBuffer();
|
|
24521
|
+
blocks.push(
|
|
24522
|
+
new Paragraph({
|
|
24523
|
+
children: [new PageBreak()]
|
|
24524
|
+
})
|
|
24525
|
+
);
|
|
24526
|
+
continue;
|
|
24527
|
+
}
|
|
24528
|
+
if (element.type === "separator" /* SEPARATOR */) {
|
|
24529
|
+
await flushInlineBuffer();
|
|
24530
|
+
blocks.push(
|
|
24531
|
+
new Paragraph({
|
|
24532
|
+
thematicBreak: true
|
|
24533
|
+
})
|
|
24534
|
+
);
|
|
24535
|
+
continue;
|
|
24536
|
+
}
|
|
24537
|
+
if (element.type === "image" /* IMAGE */ && element.imgDisplay && element.imgDisplay !== "inline") {
|
|
24538
|
+
await flushInlineBuffer();
|
|
24539
|
+
blocks.push(...await serializeInlineElements([element], options));
|
|
24540
|
+
continue;
|
|
24541
|
+
}
|
|
24542
|
+
if (element.type === "block" /* BLOCK */) {
|
|
24543
|
+
await flushInlineBuffer();
|
|
24544
|
+
const blockText = getBlockFallbackText(element);
|
|
24545
|
+
if (blockText) {
|
|
24546
|
+
blocks.push(
|
|
24547
|
+
...await serializeInlineElements(
|
|
24548
|
+
[{ value: blockText }],
|
|
24549
|
+
options,
|
|
24550
|
+
context
|
|
24551
|
+
)
|
|
24552
|
+
);
|
|
24553
|
+
}
|
|
24554
|
+
continue;
|
|
24555
|
+
}
|
|
24556
|
+
inlineBuffer.push(element);
|
|
24557
|
+
}
|
|
24558
|
+
await flushInlineBuffer();
|
|
24559
|
+
return blocks;
|
|
24560
|
+
}
|
|
24561
|
+
async function serializeInlineElements(elementList, options, _context, overrides = {}) {
|
|
24562
|
+
const paragraphs = [];
|
|
24563
|
+
let current = null;
|
|
24564
|
+
const getParagraphContext = (element) => ({
|
|
24565
|
+
heading: overrides.heading,
|
|
24566
|
+
numbering: overrides.numbering,
|
|
24567
|
+
alignment: overrides.alignment !== void 0 ? overrides.alignment : mapRowFlexToAlignment(element?.rowFlex),
|
|
24568
|
+
rowMargin: overrides.rowMargin !== void 0 ? overrides.rowMargin : element?.rowMargin
|
|
24569
|
+
});
|
|
24570
|
+
const flushParagraph = (context) => {
|
|
24571
|
+
if (!current) {
|
|
24572
|
+
if (!context) return;
|
|
24573
|
+
paragraphs.push(createParagraph([], context, options.defaultRowMargin));
|
|
24574
|
+
return;
|
|
24575
|
+
}
|
|
24576
|
+
paragraphs.push(
|
|
24577
|
+
createParagraph(
|
|
24578
|
+
current.children,
|
|
24579
|
+
current.context,
|
|
24580
|
+
options.defaultRowMargin
|
|
24581
|
+
)
|
|
24582
|
+
);
|
|
24583
|
+
current = null;
|
|
24584
|
+
};
|
|
24585
|
+
const ensureParagraph = (element) => {
|
|
24586
|
+
if (!current) {
|
|
24587
|
+
current = {
|
|
24588
|
+
children: [],
|
|
24589
|
+
context: getParagraphContext(element)
|
|
24590
|
+
};
|
|
24591
|
+
}
|
|
24592
|
+
return current;
|
|
24593
|
+
};
|
|
24594
|
+
const appendText = (element, text, childFactory, preserveTrailingBreak = false) => {
|
|
24595
|
+
const normalized = normalizeText(text);
|
|
24596
|
+
const parts = normalized.split("\n");
|
|
24597
|
+
let lastSeparatorFlushedContent = false;
|
|
24598
|
+
for (let i = 0; i < parts.length; i++) {
|
|
24599
|
+
const segment = parts[i];
|
|
24600
|
+
if (segment) {
|
|
24601
|
+
ensureParagraph(element).children.push(childFactory(segment));
|
|
24602
|
+
}
|
|
24603
|
+
if (i < parts.length - 1) {
|
|
24604
|
+
if (!current) {
|
|
24605
|
+
paragraphs.push(
|
|
24606
|
+
createParagraph(
|
|
24607
|
+
[],
|
|
24608
|
+
getParagraphContext(element),
|
|
24609
|
+
options.defaultRowMargin
|
|
24610
|
+
)
|
|
24611
|
+
);
|
|
24612
|
+
lastSeparatorFlushedContent = false;
|
|
24613
|
+
} else {
|
|
24614
|
+
flushParagraph();
|
|
24615
|
+
lastSeparatorFlushedContent = true;
|
|
24616
|
+
}
|
|
24617
|
+
}
|
|
24618
|
+
}
|
|
24619
|
+
if (preserveTrailingBreak && normalized.endsWith("\n") && lastSeparatorFlushedContent) {
|
|
24620
|
+
paragraphs.push(
|
|
24621
|
+
createParagraph(
|
|
24622
|
+
[],
|
|
24623
|
+
getParagraphContext(element),
|
|
24624
|
+
options.defaultRowMargin
|
|
24625
|
+
)
|
|
24626
|
+
);
|
|
24627
|
+
}
|
|
24628
|
+
};
|
|
24629
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
24630
|
+
const element = elementList[i];
|
|
24631
|
+
if (element.type === "hyperlink" /* HYPERLINK */ && element.valueList?.length) {
|
|
24632
|
+
const hyperlink = await createHyperlinkChild(element, options);
|
|
24633
|
+
if (hyperlink) {
|
|
24634
|
+
ensureParagraph(element).children.push(hyperlink);
|
|
24635
|
+
}
|
|
24636
|
+
continue;
|
|
24637
|
+
}
|
|
24638
|
+
if (element.type === "image" /* IMAGE */) {
|
|
24639
|
+
const imageChild = await createImageChild(element);
|
|
24640
|
+
if (!imageChild) {
|
|
24641
|
+
appendText(
|
|
24642
|
+
element,
|
|
24643
|
+
"[Image unavailable]",
|
|
24644
|
+
(segment) => createTextRun(
|
|
24645
|
+
segment,
|
|
24646
|
+
element,
|
|
24647
|
+
options.defaultSize,
|
|
24648
|
+
options.defaultFont
|
|
24649
|
+
),
|
|
24650
|
+
i === elementList.length - 1
|
|
24651
|
+
);
|
|
24652
|
+
continue;
|
|
24653
|
+
}
|
|
24654
|
+
ensureParagraph(element).children.push(imageChild);
|
|
24655
|
+
continue;
|
|
24656
|
+
}
|
|
24657
|
+
if (element.type === "columnBreak" /* COLUMN_BREAK */) {
|
|
24658
|
+
ensureParagraph(element).children.push(new ColumnBreak());
|
|
24659
|
+
continue;
|
|
24660
|
+
}
|
|
24661
|
+
if (element.type === "tab" /* TAB */) {
|
|
24662
|
+
appendText(
|
|
24663
|
+
element,
|
|
24664
|
+
" ",
|
|
24665
|
+
(segment) => createTextRun(
|
|
24666
|
+
segment,
|
|
24667
|
+
element,
|
|
24668
|
+
options.defaultSize,
|
|
24669
|
+
options.defaultFont
|
|
24670
|
+
),
|
|
24671
|
+
i === elementList.length - 1
|
|
24672
|
+
);
|
|
24673
|
+
continue;
|
|
24674
|
+
}
|
|
24675
|
+
const textValue = getInlineElementText(element);
|
|
24676
|
+
if (!textValue) {
|
|
24677
|
+
continue;
|
|
24678
|
+
}
|
|
24679
|
+
appendText(
|
|
24680
|
+
element,
|
|
24681
|
+
textValue,
|
|
24682
|
+
(segment) => createTextRun(
|
|
24683
|
+
segment,
|
|
24684
|
+
element,
|
|
24685
|
+
options.defaultSize,
|
|
24686
|
+
options.defaultFont
|
|
24687
|
+
),
|
|
24688
|
+
i === elementList.length - 1
|
|
24689
|
+
);
|
|
24690
|
+
}
|
|
24691
|
+
if (current) {
|
|
24692
|
+
flushParagraph();
|
|
24693
|
+
}
|
|
24694
|
+
return paragraphs.length ? paragraphs : [createParagraph([], overrides, options.defaultRowMargin)];
|
|
24695
|
+
}
|
|
24696
|
+
async function serializeListElement(element, options, context) {
|
|
24697
|
+
const zipList = zipElementList(element.valueList || []);
|
|
24698
|
+
const listItemMap = splitListElement(zipList);
|
|
24699
|
+
const paragraphs = [];
|
|
24700
|
+
const listInstance = createListInstance(context);
|
|
24701
|
+
for (const listItemElements of listItemMap.values()) {
|
|
24702
|
+
const numbering = getListNumbering(
|
|
24703
|
+
getListItemNumberingElement(listItemElements, element),
|
|
24704
|
+
listInstance
|
|
24705
|
+
);
|
|
24706
|
+
paragraphs.push(
|
|
24707
|
+
...await serializeInlineElements(listItemElements, options, context, {
|
|
24708
|
+
numbering
|
|
24709
|
+
})
|
|
24710
|
+
);
|
|
24711
|
+
}
|
|
24712
|
+
return paragraphs;
|
|
24713
|
+
}
|
|
24714
|
+
async function serializeTableElement(element, options, context) {
|
|
24715
|
+
const rows = [];
|
|
24716
|
+
const trList = element.trList || [];
|
|
24717
|
+
const tableContext = createTableSerializeContext(element);
|
|
24718
|
+
for (let i = 0; i < trList.length; i++) {
|
|
24719
|
+
rows.push(
|
|
24720
|
+
await serializeTableRow(trList[i], options, context, tableContext)
|
|
24721
|
+
);
|
|
24722
|
+
}
|
|
24723
|
+
const tableWidth = getTableWidthFromColgroup(element.colgroup);
|
|
24724
|
+
return new Table({
|
|
24725
|
+
rows,
|
|
24726
|
+
width: tableWidth ? {
|
|
24727
|
+
size: pxToTwips(tableWidth),
|
|
24728
|
+
type: WidthType.DXA
|
|
24729
|
+
} : {
|
|
24730
|
+
size: 100,
|
|
24731
|
+
type: WidthType.PERCENTAGE
|
|
24732
|
+
},
|
|
24733
|
+
columnWidths: element.colgroup?.map((col) => pxToTwips(col.width)),
|
|
24734
|
+
layout: TableLayoutType.FIXED,
|
|
24735
|
+
borders: createTableBorders(element)
|
|
24736
|
+
});
|
|
24737
|
+
}
|
|
24738
|
+
async function serializeTableRow(tr, options, context, tableContext) {
|
|
24739
|
+
const children = [];
|
|
24740
|
+
for (let i = 0; i < tr.tdList.length; i++) {
|
|
24741
|
+
children.push(
|
|
24742
|
+
await serializeTableCell(tr.tdList[i], options, context, tableContext)
|
|
24743
|
+
);
|
|
24744
|
+
}
|
|
24745
|
+
return new TableRow({
|
|
24746
|
+
children
|
|
24747
|
+
});
|
|
24748
|
+
}
|
|
24749
|
+
async function serializeTableCell(td, options, context, tableContext) {
|
|
24750
|
+
const children = await serializeElementList(td.value, options, context);
|
|
24751
|
+
const shadingFill = td.backgroundColor ? normalizeHexColor(td.backgroundColor) : void 0;
|
|
24752
|
+
const cellWidth = tableContext.cellLayoutMap.get(td)?.width || td.width;
|
|
24753
|
+
return new TableCell({
|
|
24754
|
+
children: children.length ? children : [new Paragraph({})],
|
|
24755
|
+
columnSpan: td.colspan > 1 ? td.colspan : void 0,
|
|
24756
|
+
rowSpan: td.rowspan > 1 ? td.rowspan : void 0,
|
|
24757
|
+
verticalAlign: mapCellVerticalAlign(td.verticalAlign),
|
|
24758
|
+
width: cellWidth ? {
|
|
24759
|
+
size: pxToTwips(cellWidth),
|
|
24760
|
+
type: WidthType.DXA
|
|
24761
|
+
} : void 0,
|
|
24762
|
+
shading: shadingFill ? {
|
|
24763
|
+
fill: shadingFill,
|
|
24764
|
+
type: ShadingType.CLEAR
|
|
24765
|
+
} : void 0,
|
|
24766
|
+
margins: mapPaddingToTableMargins(td.padding),
|
|
24767
|
+
borders: createTableCellBorders(
|
|
24768
|
+
td,
|
|
24769
|
+
tableContext.borderColor,
|
|
24770
|
+
tableContext.borderWidth
|
|
24771
|
+
)
|
|
24772
|
+
});
|
|
24773
|
+
}
|
|
24774
|
+
function createParagraph(children, context, defaultRowMargin) {
|
|
24775
|
+
return new Paragraph({
|
|
24776
|
+
children,
|
|
24777
|
+
heading: context.heading,
|
|
24778
|
+
numbering: context.numbering,
|
|
24779
|
+
alignment: context.alignment,
|
|
24780
|
+
spacing: {
|
|
24781
|
+
line: Math.round(
|
|
24782
|
+
240 * (context.rowMargin || defaultRowMargin || DEFAULT_LINE_HEIGHT)
|
|
24783
|
+
),
|
|
24784
|
+
lineRule: LineRuleType.AUTO
|
|
24785
|
+
}
|
|
24786
|
+
});
|
|
24787
|
+
}
|
|
24788
|
+
function createTextRun(text, element, defaultSize, defaultFont) {
|
|
24789
|
+
const color = element.color ? normalizeHexColor(element.color, "000000") : void 0;
|
|
24790
|
+
const highlightFill = element.highlight ? normalizeHexColor(element.highlight) : void 0;
|
|
24791
|
+
return new TextRun({
|
|
24792
|
+
text,
|
|
24793
|
+
bold: !!element.bold,
|
|
24794
|
+
italics: !!element.italic,
|
|
24795
|
+
strike: !!element.strikeout,
|
|
24796
|
+
subScript: element.type === "subscript" /* SUBSCRIPT */,
|
|
24797
|
+
superScript: element.type === "superscript" /* SUPERSCRIPT */,
|
|
24798
|
+
color,
|
|
24799
|
+
shading: highlightFill ? {
|
|
24800
|
+
fill: highlightFill,
|
|
24801
|
+
type: ShadingType.CLEAR
|
|
24802
|
+
} : void 0,
|
|
24803
|
+
underline: element.underline ? {
|
|
24804
|
+
type: mapUnderlineType(element.textDecoration?.style)
|
|
24805
|
+
} : void 0,
|
|
24806
|
+
font: element.font || defaultFont,
|
|
24807
|
+
size: Math.round((element.size || defaultSize) * 2)
|
|
24808
|
+
});
|
|
24809
|
+
}
|
|
24810
|
+
async function createHyperlinkChild(element, options) {
|
|
24811
|
+
if (!element.url) {
|
|
24812
|
+
const fallbackText = getTextFromElementList(element.valueList || []);
|
|
24813
|
+
return fallbackText ? createTextRun(
|
|
24814
|
+
fallbackText,
|
|
24815
|
+
element.valueList?.[0] || element,
|
|
24816
|
+
options.defaultSize,
|
|
24817
|
+
options.defaultFont
|
|
24818
|
+
) : null;
|
|
24819
|
+
}
|
|
24820
|
+
const children = await createHyperlinkRuns(
|
|
24821
|
+
element.valueList || [],
|
|
24822
|
+
options.defaultSize,
|
|
24823
|
+
options.defaultFont
|
|
24824
|
+
);
|
|
24825
|
+
if (!children.length) {
|
|
24826
|
+
return null;
|
|
24827
|
+
}
|
|
24828
|
+
return new ExternalHyperlink({
|
|
24829
|
+
link: element.url,
|
|
24830
|
+
children
|
|
24831
|
+
});
|
|
24832
|
+
}
|
|
24833
|
+
async function createHyperlinkRuns(valueList, defaultSize, defaultFont) {
|
|
24834
|
+
const children = [];
|
|
24835
|
+
for (let i = 0; i < valueList.length; i++) {
|
|
24836
|
+
const element = valueList[i];
|
|
24837
|
+
if (element.type === "tab" /* TAB */) {
|
|
24838
|
+
children.push(createTextRun(" ", element, defaultSize, defaultFont));
|
|
24839
|
+
continue;
|
|
24840
|
+
}
|
|
24841
|
+
const text = normalizeText(getInlineElementText(element)).replace(
|
|
24842
|
+
/\n/g,
|
|
24843
|
+
" "
|
|
24844
|
+
);
|
|
24845
|
+
if (text) {
|
|
24846
|
+
children.push(createTextRun(text, element, defaultSize, defaultFont));
|
|
24847
|
+
}
|
|
24848
|
+
}
|
|
24849
|
+
return children;
|
|
24850
|
+
}
|
|
24851
|
+
async function createImageChild(element) {
|
|
24852
|
+
try {
|
|
24853
|
+
const image = await loadImagePayload(element.value);
|
|
24854
|
+
const width = Math.max(1, Math.round(element.width || DEFAULT_IMAGE_WIDTH));
|
|
24855
|
+
const height = Math.max(
|
|
24856
|
+
1,
|
|
24857
|
+
Math.round(element.height || DEFAULT_IMAGE_HEIGHT)
|
|
24858
|
+
);
|
|
24859
|
+
if (image.type === "svg" && image.fallbackPng) {
|
|
24860
|
+
return new ImageRun({
|
|
24861
|
+
type: "svg",
|
|
24862
|
+
data: image.data,
|
|
24863
|
+
fallback: {
|
|
24864
|
+
type: "png",
|
|
24865
|
+
data: image.fallbackPng
|
|
24866
|
+
},
|
|
24867
|
+
transformation: {
|
|
24868
|
+
width,
|
|
24869
|
+
height
|
|
24870
|
+
}
|
|
24871
|
+
});
|
|
24872
|
+
}
|
|
24873
|
+
return new ImageRun({
|
|
24874
|
+
type: image.type,
|
|
24875
|
+
data: image.data,
|
|
24876
|
+
transformation: {
|
|
24877
|
+
width,
|
|
24878
|
+
height
|
|
24879
|
+
}
|
|
24880
|
+
});
|
|
24881
|
+
} catch {
|
|
24882
|
+
return null;
|
|
24883
|
+
}
|
|
24884
|
+
}
|
|
24885
|
+
async function loadImagePayload(src) {
|
|
24886
|
+
const source = src.trim();
|
|
24887
|
+
if (source.startsWith("data:")) {
|
|
24888
|
+
return getImagePayloadFromDataUrl(source);
|
|
24889
|
+
}
|
|
24890
|
+
const response = await fetch(source);
|
|
24891
|
+
if (!response.ok) {
|
|
24892
|
+
throw new Error(`Image request failed: ${response.status}`);
|
|
24893
|
+
}
|
|
24894
|
+
const contentType = response.headers.get("content-type") || "";
|
|
24895
|
+
const data2 = await response.arrayBuffer();
|
|
24896
|
+
return normalizeImagePayload(data2, contentType);
|
|
24897
|
+
}
|
|
24898
|
+
async function getImagePayloadFromDataUrl(src) {
|
|
24899
|
+
const [, meta = "", encoded = ""] = src.match(/^data:([^,]*),(.*)$/) || [];
|
|
24900
|
+
const mime = meta.split(";")[0] || "";
|
|
24901
|
+
const isBase64 = meta.includes(";base64");
|
|
24902
|
+
const text = isBase64 ? atob(encoded) : decodeURIComponent(encoded);
|
|
24903
|
+
const bytes = new Uint8Array(text.length);
|
|
24904
|
+
for (let i = 0; i < text.length; i++) {
|
|
24905
|
+
bytes[i] = text.charCodeAt(i);
|
|
24906
|
+
}
|
|
24907
|
+
return normalizeImagePayload(bytes.buffer, mime);
|
|
24908
|
+
}
|
|
24909
|
+
async function normalizeImagePayload(data2, mime) {
|
|
24910
|
+
const type = getRegularImageType(mime);
|
|
24911
|
+
if (type) {
|
|
24912
|
+
return {
|
|
24913
|
+
type,
|
|
24914
|
+
data: data2
|
|
24915
|
+
};
|
|
24916
|
+
}
|
|
24917
|
+
if (mime.includes("svg")) {
|
|
24918
|
+
return {
|
|
24919
|
+
type: "svg",
|
|
24920
|
+
data: data2,
|
|
24921
|
+
fallbackPng: await rasterizeSvgToPng(data2)
|
|
24922
|
+
};
|
|
24923
|
+
}
|
|
24924
|
+
const fallbackPng = await rasterizeImageToPng(data2, mime);
|
|
24925
|
+
return {
|
|
24926
|
+
type: "png",
|
|
24927
|
+
data: fallbackPng
|
|
24928
|
+
};
|
|
24929
|
+
}
|
|
24930
|
+
async function rasterizeSvgToPng(data2) {
|
|
24931
|
+
return rasterizeImageToPng(data2, "image/svg+xml");
|
|
24932
|
+
}
|
|
24933
|
+
async function rasterizeImageToPng(data2, mime) {
|
|
24934
|
+
const blob = new Blob([data2], {
|
|
24935
|
+
type: mime || "image/png"
|
|
24936
|
+
});
|
|
24937
|
+
const url = URL.createObjectURL(blob);
|
|
24938
|
+
try {
|
|
24939
|
+
const image = await loadHtmlImage(url);
|
|
24940
|
+
const canvas = document.createElement("canvas");
|
|
24941
|
+
canvas.width = image.naturalWidth || DEFAULT_IMAGE_WIDTH;
|
|
24942
|
+
canvas.height = image.naturalHeight || DEFAULT_IMAGE_HEIGHT;
|
|
24943
|
+
const context = canvas.getContext("2d");
|
|
24944
|
+
if (!context) {
|
|
24945
|
+
throw new Error("Canvas context is unavailable");
|
|
24946
|
+
}
|
|
24947
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
24948
|
+
const pngBlob = await new Promise((resolve, reject) => {
|
|
24949
|
+
canvas.toBlob((output) => {
|
|
24950
|
+
if (output) {
|
|
24951
|
+
resolve(output);
|
|
24952
|
+
} else {
|
|
24953
|
+
reject(new Error("Failed to create PNG blob"));
|
|
24954
|
+
}
|
|
24955
|
+
}, "image/png");
|
|
24956
|
+
});
|
|
24957
|
+
return await pngBlob.arrayBuffer();
|
|
24958
|
+
} finally {
|
|
24959
|
+
URL.revokeObjectURL(url);
|
|
24960
|
+
}
|
|
24961
|
+
}
|
|
24962
|
+
function loadHtmlImage(src) {
|
|
24963
|
+
return new Promise((resolve, reject) => {
|
|
24964
|
+
const image = new Image();
|
|
24965
|
+
image.onload = () => resolve(image);
|
|
24966
|
+
image.onerror = () => reject(new Error("Failed to load image"));
|
|
24967
|
+
image.src = src;
|
|
24968
|
+
});
|
|
24969
|
+
}
|
|
24970
|
+
function createPageNumberParagraph(pageNumber) {
|
|
24971
|
+
if (pageNumber.disabled || pageNumber.fromPageNo > 0) {
|
|
24972
|
+
return null;
|
|
24973
|
+
}
|
|
24974
|
+
const children = [];
|
|
24975
|
+
const format = pageNumber.format || FORMAT_PLACEHOLDER.PAGE_NO;
|
|
24976
|
+
const tokens = format.split(/(\{pageNo\}|\{pageCount\})/);
|
|
24977
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
24978
|
+
const token = tokens[i];
|
|
24979
|
+
if (!token) continue;
|
|
24980
|
+
const runChildren = token === FORMAT_PLACEHOLDER.PAGE_NO ? [PageNumber2.CURRENT] : token === FORMAT_PLACEHOLDER.PAGE_COUNT ? [PageNumber2.TOTAL_PAGES] : void 0;
|
|
24981
|
+
children.push(
|
|
24982
|
+
new TextRun({
|
|
24983
|
+
text: runChildren ? void 0 : token,
|
|
24984
|
+
children: runChildren,
|
|
24985
|
+
color: normalizeHexColor(pageNumber.color || "#000000", "000000"),
|
|
24986
|
+
font: pageNumber.font,
|
|
24987
|
+
size: Math.round((pageNumber.size || 12) * 2)
|
|
24988
|
+
})
|
|
24989
|
+
);
|
|
24990
|
+
}
|
|
24991
|
+
return new Paragraph({
|
|
24992
|
+
children,
|
|
24993
|
+
alignment: mapRowFlexToAlignment(pageNumber.rowFlex)
|
|
24994
|
+
});
|
|
24995
|
+
}
|
|
24996
|
+
function createNumberingConfig() {
|
|
24997
|
+
const config = [
|
|
24998
|
+
createOrderedReference("windoc-ol-decimal", Array(9).fill("decimal" /* DECIMAL */)),
|
|
24999
|
+
createOrderedReference(
|
|
25000
|
+
"windoc-ol-lower-alpha",
|
|
25001
|
+
Array(9).fill("lowerAlpha" /* LOWER_ALPHA */)
|
|
25002
|
+
),
|
|
25003
|
+
createOrderedReference(
|
|
25004
|
+
"windoc-ol-upper-alpha",
|
|
25005
|
+
Array(9).fill("upperAlpha" /* UPPER_ALPHA */)
|
|
25006
|
+
),
|
|
25007
|
+
createOrderedReference(
|
|
25008
|
+
"windoc-ol-lower-roman",
|
|
25009
|
+
Array(9).fill("lowerRoman" /* LOWER_ROMAN */)
|
|
25010
|
+
),
|
|
25011
|
+
createOrderedReference(
|
|
25012
|
+
"windoc-ol-upper-roman",
|
|
25013
|
+
Array(9).fill("upperRoman" /* UPPER_ROMAN */)
|
|
25014
|
+
),
|
|
25015
|
+
createOrderedReference(
|
|
25016
|
+
"windoc-ol-decimal-paren",
|
|
25017
|
+
Array(9).fill("decimalParen" /* DECIMAL_PAREN */)
|
|
25018
|
+
),
|
|
25019
|
+
createOrderedReference(
|
|
25020
|
+
`windoc-ol-${"olDefault" /* DEFAULT */}`,
|
|
25021
|
+
createCycleList(olPresetCycles["olDefault" /* DEFAULT */], 9)
|
|
25022
|
+
),
|
|
25023
|
+
createOrderedReference(
|
|
25024
|
+
`windoc-ol-${"olParen" /* PARENTHESIS */}`,
|
|
25025
|
+
createCycleList(olPresetCycles["olParen" /* PARENTHESIS */], 9)
|
|
25026
|
+
),
|
|
25027
|
+
createOrderedReference(
|
|
25028
|
+
`windoc-ol-${"olOutline" /* OUTLINE */}`,
|
|
25029
|
+
createCycleList(olPresetCycles["olOutline" /* OUTLINE */], 9)
|
|
25030
|
+
),
|
|
25031
|
+
createOrderedReference(
|
|
25032
|
+
`windoc-ol-${"olUpperA" /* UPPER_ALPHA */}`,
|
|
25033
|
+
createCycleList(olPresetCycles["olUpperA" /* UPPER_ALPHA */], 9)
|
|
25034
|
+
),
|
|
25035
|
+
createOrderedReference(
|
|
25036
|
+
`windoc-ol-${"olRoman" /* ROMAN */}`,
|
|
25037
|
+
createCycleList(olPresetCycles["olRoman" /* ROMAN */], 9)
|
|
25038
|
+
),
|
|
25039
|
+
createOrderedReference(
|
|
25040
|
+
`windoc-ol-${"olZeroPad" /* ZERO_PAD */}`,
|
|
25041
|
+
createCycleList(olPresetCycles["olZeroPad" /* ZERO_PAD */], 9)
|
|
25042
|
+
),
|
|
25043
|
+
createBulletReference(
|
|
25044
|
+
"windoc-ul-disc",
|
|
25045
|
+
Array(9).fill(docxBulletCharMap["disc" /* DISC */])
|
|
25046
|
+
),
|
|
25047
|
+
createBulletReference(
|
|
25048
|
+
"windoc-ul-circle",
|
|
25049
|
+
Array(9).fill(docxBulletCharMap["circle" /* CIRCLE */])
|
|
25050
|
+
),
|
|
25051
|
+
createBulletReference(
|
|
25052
|
+
"windoc-ul-square",
|
|
25053
|
+
Array(9).fill(docxBulletCharMap["square" /* SQUARE */])
|
|
25054
|
+
),
|
|
25055
|
+
createBulletReference(
|
|
25056
|
+
"windoc-ul-checkbox",
|
|
25057
|
+
Array(9).fill(docxBulletCharMap["checkbox" /* CHECKBOX */])
|
|
25058
|
+
),
|
|
25059
|
+
createBulletReference(
|
|
25060
|
+
`windoc-ul-${"ulDefault" /* DEFAULT */}`,
|
|
25061
|
+
createCycleList(ulPresetCycles["ulDefault" /* DEFAULT */], 9)
|
|
25062
|
+
),
|
|
25063
|
+
createBulletReference(
|
|
25064
|
+
`windoc-ul-${"ulDiamond" /* DIAMOND */}`,
|
|
25065
|
+
createCycleList(ulPresetCycles["ulDiamond" /* DIAMOND */], 9)
|
|
25066
|
+
),
|
|
25067
|
+
createBulletReference(
|
|
25068
|
+
`windoc-ul-${"ulHollowSq" /* HOLLOW_SQ */}`,
|
|
25069
|
+
createCycleList(ulPresetCycles["ulHollowSq" /* HOLLOW_SQ */], 9)
|
|
25070
|
+
),
|
|
25071
|
+
createBulletReference(
|
|
25072
|
+
`windoc-ul-${"ulArrow" /* ARROW */}`,
|
|
25073
|
+
createCycleList(ulPresetCycles["ulArrow" /* ARROW */], 9)
|
|
25074
|
+
),
|
|
25075
|
+
createBulletReference(
|
|
25076
|
+
`windoc-ul-${"ulStar" /* STAR */}`,
|
|
25077
|
+
createCycleList(ulPresetCycles["ulStar" /* STAR */], 9)
|
|
25078
|
+
),
|
|
25079
|
+
createBulletReference(
|
|
25080
|
+
`windoc-ul-${"ulCheckArr" /* CHECK_ARROW */}`,
|
|
25081
|
+
createCycleList(ulPresetCycles["ulCheckArr" /* CHECK_ARROW */], 9)
|
|
25082
|
+
)
|
|
25083
|
+
];
|
|
25084
|
+
return config;
|
|
25085
|
+
}
|
|
25086
|
+
function createOrderedReference(reference, styles) {
|
|
25087
|
+
return {
|
|
25088
|
+
reference,
|
|
25089
|
+
levels: styles.map((style, level) => ({
|
|
25090
|
+
level,
|
|
25091
|
+
format: orderedStyleFormatMap[style] || LevelFormat.DECIMAL,
|
|
25092
|
+
text: getOrderedLevelText(style, level),
|
|
25093
|
+
alignment: AlignmentType.START,
|
|
25094
|
+
style: {
|
|
25095
|
+
paragraph: {
|
|
25096
|
+
indent: {
|
|
25097
|
+
left: 720 * (level + 1),
|
|
25098
|
+
hanging: 360
|
|
25099
|
+
}
|
|
25100
|
+
}
|
|
25101
|
+
}
|
|
25102
|
+
}))
|
|
25103
|
+
};
|
|
25104
|
+
}
|
|
25105
|
+
function createBulletReference(reference, bullets) {
|
|
25106
|
+
return {
|
|
25107
|
+
reference,
|
|
25108
|
+
levels: bullets.map((bullet, level) => ({
|
|
25109
|
+
level,
|
|
25110
|
+
format: LevelFormat.BULLET,
|
|
25111
|
+
text: bullet,
|
|
25112
|
+
alignment: AlignmentType.START,
|
|
25113
|
+
style: {
|
|
25114
|
+
paragraph: {
|
|
25115
|
+
indent: {
|
|
25116
|
+
left: 720 * (level + 1),
|
|
25117
|
+
hanging: 360
|
|
25118
|
+
}
|
|
25119
|
+
}
|
|
25120
|
+
}
|
|
25121
|
+
}))
|
|
25122
|
+
};
|
|
25123
|
+
}
|
|
25124
|
+
function getOrderedLevelText(style, level) {
|
|
25125
|
+
const placeholder = `%${level + 1}`;
|
|
25126
|
+
if (style === "outline") {
|
|
25127
|
+
return Array.from({ length: level + 1 }, (_, index) => `%${index + 1}`).join(
|
|
25128
|
+
"."
|
|
25129
|
+
) + ".";
|
|
25130
|
+
}
|
|
25131
|
+
if (style.endsWith("Paren") || style === "decimalParen" /* DECIMAL_PAREN */) {
|
|
25132
|
+
return `${placeholder})`;
|
|
25133
|
+
}
|
|
25134
|
+
return `${placeholder}.`;
|
|
25135
|
+
}
|
|
25136
|
+
function createCycleList(source = [], size) {
|
|
25137
|
+
const result = [];
|
|
25138
|
+
for (let i = 0; i < size; i++) {
|
|
25139
|
+
result.push(source[i % source.length]);
|
|
25140
|
+
}
|
|
25141
|
+
return result;
|
|
25142
|
+
}
|
|
25143
|
+
function getListNumbering(element, instance) {
|
|
25144
|
+
const level = Math.max(0, Math.min(element.listLevel || 0, 8));
|
|
25145
|
+
if (element.listType === "ul" /* UL */) {
|
|
25146
|
+
const reference2 = element.listPreset ? `windoc-ul-${element.listPreset}` : `windoc-ul-${element.listStyle || "disc" /* DISC */}`;
|
|
25147
|
+
return {
|
|
25148
|
+
reference: reference2,
|
|
25149
|
+
level,
|
|
25150
|
+
instance
|
|
25151
|
+
};
|
|
25152
|
+
}
|
|
25153
|
+
const reference = element.listPreset ? `windoc-ol-${element.listPreset}` : getOrderedReferenceFromStyle(element.listStyle);
|
|
25154
|
+
return {
|
|
25155
|
+
reference,
|
|
25156
|
+
level,
|
|
25157
|
+
instance
|
|
25158
|
+
};
|
|
25159
|
+
}
|
|
25160
|
+
function getOrderedReferenceFromStyle(style) {
|
|
25161
|
+
switch (style) {
|
|
25162
|
+
case "lowerAlpha" /* LOWER_ALPHA */:
|
|
25163
|
+
return "windoc-ol-lower-alpha";
|
|
25164
|
+
case "upperAlpha" /* UPPER_ALPHA */:
|
|
25165
|
+
return "windoc-ol-upper-alpha";
|
|
25166
|
+
case "lowerRoman" /* LOWER_ROMAN */:
|
|
25167
|
+
return "windoc-ol-lower-roman";
|
|
25168
|
+
case "upperRoman" /* UPPER_ROMAN */:
|
|
25169
|
+
return "windoc-ol-upper-roman";
|
|
25170
|
+
case "decimalParen" /* DECIMAL_PAREN */:
|
|
25171
|
+
return "windoc-ol-decimal-paren";
|
|
25172
|
+
default:
|
|
25173
|
+
return "windoc-ol-decimal";
|
|
25174
|
+
}
|
|
25175
|
+
}
|
|
25176
|
+
function createTableBorders(element) {
|
|
25177
|
+
const outerBorder = createBorder(
|
|
25178
|
+
element.borderColor,
|
|
25179
|
+
BorderStyle.SINGLE,
|
|
25180
|
+
element.borderExternalWidth || element.borderWidth
|
|
25181
|
+
);
|
|
25182
|
+
const innerBorder = createBorder(
|
|
25183
|
+
element.borderColor,
|
|
25184
|
+
BorderStyle.SINGLE,
|
|
25185
|
+
element.borderWidth
|
|
25186
|
+
);
|
|
25187
|
+
switch (element.borderType) {
|
|
25188
|
+
case "empty" /* EMPTY */:
|
|
25189
|
+
return {
|
|
25190
|
+
top: noneBorder(),
|
|
25191
|
+
bottom: noneBorder(),
|
|
25192
|
+
left: noneBorder(),
|
|
25193
|
+
right: noneBorder(),
|
|
25194
|
+
insideHorizontal: noneBorder(),
|
|
25195
|
+
insideVertical: noneBorder()
|
|
25196
|
+
};
|
|
25197
|
+
case "external" /* EXTERNAL */:
|
|
25198
|
+
return {
|
|
25199
|
+
top: outerBorder,
|
|
25200
|
+
bottom: outerBorder,
|
|
25201
|
+
left: outerBorder,
|
|
25202
|
+
right: outerBorder,
|
|
25203
|
+
insideHorizontal: noneBorder(),
|
|
25204
|
+
insideVertical: noneBorder()
|
|
25205
|
+
};
|
|
25206
|
+
case "internal" /* INTERNAL */:
|
|
25207
|
+
return {
|
|
25208
|
+
top: noneBorder(),
|
|
25209
|
+
bottom: noneBorder(),
|
|
25210
|
+
left: noneBorder(),
|
|
25211
|
+
right: noneBorder(),
|
|
25212
|
+
insideHorizontal: innerBorder,
|
|
25213
|
+
insideVertical: innerBorder
|
|
25214
|
+
};
|
|
25215
|
+
case "dash" /* DASH */:
|
|
25216
|
+
return {
|
|
25217
|
+
top: createBorder(
|
|
25218
|
+
element.borderColor,
|
|
25219
|
+
BorderStyle.DASHED,
|
|
25220
|
+
element.borderExternalWidth || element.borderWidth
|
|
25221
|
+
),
|
|
25222
|
+
bottom: createBorder(
|
|
25223
|
+
element.borderColor,
|
|
25224
|
+
BorderStyle.DASHED,
|
|
25225
|
+
element.borderExternalWidth || element.borderWidth
|
|
25226
|
+
),
|
|
25227
|
+
left: createBorder(
|
|
25228
|
+
element.borderColor,
|
|
25229
|
+
BorderStyle.DASHED,
|
|
25230
|
+
element.borderExternalWidth || element.borderWidth
|
|
25231
|
+
),
|
|
25232
|
+
right: createBorder(
|
|
25233
|
+
element.borderColor,
|
|
25234
|
+
BorderStyle.DASHED,
|
|
25235
|
+
element.borderExternalWidth || element.borderWidth
|
|
25236
|
+
),
|
|
25237
|
+
insideHorizontal: createBorder(
|
|
25238
|
+
element.borderColor,
|
|
25239
|
+
BorderStyle.DASHED,
|
|
25240
|
+
element.borderWidth
|
|
25241
|
+
),
|
|
25242
|
+
insideVertical: createBorder(
|
|
25243
|
+
element.borderColor,
|
|
25244
|
+
BorderStyle.DASHED,
|
|
25245
|
+
element.borderWidth
|
|
25246
|
+
)
|
|
25247
|
+
};
|
|
25248
|
+
default:
|
|
25249
|
+
return {
|
|
25250
|
+
top: outerBorder,
|
|
25251
|
+
bottom: outerBorder,
|
|
25252
|
+
left: outerBorder,
|
|
25253
|
+
right: outerBorder,
|
|
25254
|
+
insideHorizontal: innerBorder,
|
|
25255
|
+
insideVertical: innerBorder
|
|
25256
|
+
};
|
|
25257
|
+
}
|
|
25258
|
+
}
|
|
25259
|
+
function createTableCellBorders(td, inheritedColor, inheritedWidth) {
|
|
25260
|
+
if (!td.borderTypes?.length && !td.borderColor) {
|
|
25261
|
+
return void 0;
|
|
25262
|
+
}
|
|
25263
|
+
const color = td.borderColor || inheritedColor;
|
|
25264
|
+
const createCellBorder = () => createBorder(color, BorderStyle.SINGLE, inheritedWidth);
|
|
25265
|
+
if (td.borderColor && !td.borderTypes?.length) {
|
|
25266
|
+
return {
|
|
25267
|
+
top: createCellBorder(),
|
|
25268
|
+
right: createCellBorder(),
|
|
25269
|
+
bottom: createCellBorder(),
|
|
25270
|
+
left: createCellBorder()
|
|
25271
|
+
};
|
|
25272
|
+
}
|
|
25273
|
+
const top = td.borderTypes?.includes("top" /* TOP */) ? createCellBorder() : noneBorder();
|
|
25274
|
+
const right2 = td.borderTypes?.includes("right" /* RIGHT */) ? createCellBorder() : noneBorder();
|
|
25275
|
+
const bottom = td.borderTypes?.includes("bottom" /* BOTTOM */) ? createCellBorder() : noneBorder();
|
|
25276
|
+
const left2 = td.borderTypes?.includes("left" /* LEFT */) ? createCellBorder() : noneBorder();
|
|
25277
|
+
return {
|
|
25278
|
+
top,
|
|
25279
|
+
right: right2,
|
|
25280
|
+
bottom,
|
|
25281
|
+
left: left2
|
|
25282
|
+
};
|
|
25283
|
+
}
|
|
25284
|
+
function createBorder(color = "#000000", style = BorderStyle.SINGLE, width = 1) {
|
|
25285
|
+
return {
|
|
25286
|
+
style,
|
|
25287
|
+
color: normalizeHexColor(color, "000000") || "000000",
|
|
25288
|
+
size: pxBorderToDocxSize(width)
|
|
25289
|
+
};
|
|
25290
|
+
}
|
|
25291
|
+
function noneBorder() {
|
|
25292
|
+
return {
|
|
25293
|
+
style: BorderStyle.NONE,
|
|
25294
|
+
size: 0,
|
|
25295
|
+
color: "FFFFFF"
|
|
25296
|
+
};
|
|
25297
|
+
}
|
|
25298
|
+
function mapPaddingToTableMargins(padding) {
|
|
25299
|
+
if (!padding) return void 0;
|
|
25300
|
+
return {
|
|
25301
|
+
top: pxToTwips(padding[0]),
|
|
25302
|
+
right: pxToTwips(padding[1]),
|
|
25303
|
+
bottom: pxToTwips(padding[2]),
|
|
25304
|
+
left: pxToTwips(padding[3]),
|
|
25305
|
+
marginUnitType: WidthType.DXA
|
|
25306
|
+
};
|
|
25307
|
+
}
|
|
25308
|
+
function mapCellVerticalAlign(verticalAlign) {
|
|
25309
|
+
switch (verticalAlign) {
|
|
25310
|
+
case VerticalAlign.CENTER:
|
|
25311
|
+
return DocxVerticalAlign.CENTER;
|
|
25312
|
+
case "bottom" /* BOTTOM */:
|
|
25313
|
+
return DocxVerticalAlign.BOTTOM;
|
|
25314
|
+
default:
|
|
25315
|
+
return DocxVerticalAlign.TOP;
|
|
25316
|
+
}
|
|
25317
|
+
}
|
|
25318
|
+
function mapRowFlexToAlignment(rowFlex) {
|
|
25319
|
+
switch (rowFlex) {
|
|
25320
|
+
case "center" /* CENTER */:
|
|
25321
|
+
return AlignmentType.CENTER;
|
|
25322
|
+
case "right" /* RIGHT */:
|
|
25323
|
+
return AlignmentType.RIGHT;
|
|
25324
|
+
case "alignment" /* ALIGNMENT */:
|
|
25325
|
+
case "justify" /* JUSTIFY */:
|
|
25326
|
+
return AlignmentType.JUSTIFIED;
|
|
25327
|
+
default:
|
|
25328
|
+
return AlignmentType.LEFT;
|
|
25329
|
+
}
|
|
25330
|
+
}
|
|
25331
|
+
function mapUnderlineType(style) {
|
|
25332
|
+
switch (style) {
|
|
25333
|
+
case "double" /* DOUBLE */:
|
|
25334
|
+
return UnderlineType.DOUBLE;
|
|
25335
|
+
case "dashed" /* DASHED */:
|
|
25336
|
+
return UnderlineType.DASH;
|
|
25337
|
+
case "dotted" /* DOTTED */:
|
|
25338
|
+
return UnderlineType.DOTTED;
|
|
25339
|
+
case "wavy" /* WAVY */:
|
|
25340
|
+
return UnderlineType.WAVE;
|
|
25341
|
+
default:
|
|
25342
|
+
return UnderlineType.SINGLE;
|
|
25343
|
+
}
|
|
25344
|
+
}
|
|
25345
|
+
function getInlineElementText(element) {
|
|
25346
|
+
switch (element.type) {
|
|
25347
|
+
case "control" /* CONTROL */:
|
|
25348
|
+
return getControlText(element.control);
|
|
25349
|
+
case "date" /* DATE */:
|
|
25350
|
+
return element.valueList?.length ? getTextFromElementList(element.valueList) : element.value;
|
|
25351
|
+
case "checkbox" /* CHECKBOX */:
|
|
25352
|
+
return element.checkbox?.value ? "\u2611" : "\u2610";
|
|
25353
|
+
case "radio" /* RADIO */:
|
|
25354
|
+
return element.radio?.value ? "\u25C9" : "\u25CB";
|
|
25355
|
+
case "label" /* LABEL */:
|
|
25356
|
+
case "latex" /* LATEX */:
|
|
25357
|
+
case "subscript" /* SUBSCRIPT */:
|
|
25358
|
+
case "superscript" /* SUPERSCRIPT */:
|
|
25359
|
+
return element.value;
|
|
25360
|
+
default:
|
|
25361
|
+
return element.value;
|
|
25362
|
+
}
|
|
25363
|
+
}
|
|
25364
|
+
function getControlText(control) {
|
|
25365
|
+
if (!control) return "";
|
|
25366
|
+
if (control.type === "text" /* TEXT */ || control.type === "date" /* DATE */ || control.type === "number" /* NUMBER */) {
|
|
25367
|
+
const value = control.value?.length ? getTextFromElementList(control.value) : "";
|
|
25368
|
+
const content = value || control.placeholder || "";
|
|
25369
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
25370
|
+
}
|
|
25371
|
+
if (control.type === "select" /* SELECT */) {
|
|
25372
|
+
const labels = getSelectedControlLabels(control.code, control.valueSets);
|
|
25373
|
+
const content = labels.length ? labels.join(control.multiSelectDelimiter || ", ") : control.placeholder || "";
|
|
25374
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
25375
|
+
}
|
|
25376
|
+
if (control.type === "checkbox" /* CHECKBOX */ || control.type === "radio" /* RADIO */) {
|
|
25377
|
+
const isRadio = control.type === "radio" /* RADIO */;
|
|
25378
|
+
return (control.valueSets || []).map((valueSet) => {
|
|
25379
|
+
const checked = control.code?.split(",").includes(valueSet.code) || false;
|
|
25380
|
+
return `${checked ? isRadio ? "\u25C9" : "\u2611" : isRadio ? "\u25CB" : "\u2610"} ${valueSet.value}`;
|
|
25381
|
+
}).join(" ");
|
|
25382
|
+
}
|
|
25383
|
+
return "";
|
|
25384
|
+
}
|
|
25385
|
+
function getSelectedControlLabels(code, valueSets) {
|
|
25386
|
+
if (!code || !valueSets?.length) return [];
|
|
25387
|
+
return code.split(",").map(
|
|
25388
|
+
(selectCode) => valueSets.find((valueSet) => valueSet.code === selectCode)?.value
|
|
25389
|
+
).filter((value) => !!value);
|
|
25390
|
+
}
|
|
25391
|
+
function getBlockFallbackText(element) {
|
|
25392
|
+
if (element.block?.iframeBlock?.src) {
|
|
25393
|
+
return element.block.iframeBlock.src;
|
|
25394
|
+
}
|
|
25395
|
+
if (element.block?.videoBlock?.src) {
|
|
25396
|
+
return element.block.videoBlock.src;
|
|
25397
|
+
}
|
|
25398
|
+
return "";
|
|
25399
|
+
}
|
|
25400
|
+
function normalizeText(text = "") {
|
|
25401
|
+
return text.replace(new RegExp(ZERO, "g"), "").replace(/\r\n/g, "\n");
|
|
25402
|
+
}
|
|
25403
|
+
function createSerializeContext() {
|
|
25404
|
+
return {
|
|
25405
|
+
nextListInstance: 1
|
|
25406
|
+
};
|
|
25407
|
+
}
|
|
25408
|
+
function getListItemNumberingElement(listItemElements, fallback) {
|
|
25409
|
+
return listItemElements.find(
|
|
25410
|
+
(listItem) => listItem.listId || listItem.listLevel !== void 0 || !!listItem.listPreset || !!listItem.listStyle || !!listItem.listType
|
|
25411
|
+
) || fallback;
|
|
25412
|
+
}
|
|
25413
|
+
function createListInstance(context) {
|
|
25414
|
+
return context.nextListInstance++;
|
|
25415
|
+
}
|
|
25416
|
+
function createTableSerializeContext(element) {
|
|
25417
|
+
return {
|
|
25418
|
+
cellLayoutMap: computeTableCellLayout(
|
|
25419
|
+
element.trList || [],
|
|
25420
|
+
element.colgroup || []
|
|
25421
|
+
),
|
|
25422
|
+
borderColor: element.borderColor,
|
|
25423
|
+
borderWidth: element.borderWidth,
|
|
25424
|
+
borderExternalWidth: element.borderExternalWidth
|
|
25425
|
+
};
|
|
25426
|
+
}
|
|
25427
|
+
function computeTableCellLayout(trList, colgroup) {
|
|
25428
|
+
const cellLayoutMap = /* @__PURE__ */ new WeakMap();
|
|
25429
|
+
if (!trList.length || !colgroup.length) {
|
|
25430
|
+
return cellLayoutMap;
|
|
25431
|
+
}
|
|
25432
|
+
const occupiedUntilRow = Array(colgroup.length).fill(0);
|
|
25433
|
+
for (let rowIndex = 0; rowIndex < trList.length; rowIndex++) {
|
|
25434
|
+
const tr = trList[rowIndex];
|
|
25435
|
+
let colIndex = 0;
|
|
25436
|
+
for (let tdIndex = 0; tdIndex < tr.tdList.length; tdIndex++) {
|
|
25437
|
+
while (colIndex < colgroup.length && occupiedUntilRow[colIndex] > rowIndex) {
|
|
25438
|
+
colIndex += 1;
|
|
25439
|
+
}
|
|
25440
|
+
const td = tr.tdList[tdIndex];
|
|
25441
|
+
let width = 0;
|
|
25442
|
+
for (let currentCol = colIndex; currentCol < colIndex + td.colspan && currentCol < colgroup.length; currentCol++) {
|
|
25443
|
+
width += colgroup[currentCol].width;
|
|
25444
|
+
occupiedUntilRow[currentCol] = Math.max(
|
|
25445
|
+
occupiedUntilRow[currentCol],
|
|
25446
|
+
rowIndex + td.rowspan
|
|
25447
|
+
);
|
|
25448
|
+
}
|
|
25449
|
+
cellLayoutMap.set(td, { width });
|
|
25450
|
+
colIndex += td.colspan;
|
|
25451
|
+
}
|
|
25452
|
+
}
|
|
25453
|
+
return cellLayoutMap;
|
|
25454
|
+
}
|
|
25455
|
+
function getTableWidthFromColgroup(colgroup) {
|
|
25456
|
+
if (!colgroup?.length) {
|
|
25457
|
+
return void 0;
|
|
25458
|
+
}
|
|
25459
|
+
return colgroup.reduce((sum, col) => sum + col.width, 0);
|
|
25460
|
+
}
|
|
25461
|
+
function normalizeHexColor(color, fallback) {
|
|
25462
|
+
const normalized = normalizeHexLiteral(color) || normalizeRgbColor(color) || normalizeBrowserColor(color);
|
|
25463
|
+
if (normalized) {
|
|
25464
|
+
return normalized;
|
|
25465
|
+
}
|
|
25466
|
+
return fallback ? normalizeHexLiteral(fallback) || void 0 : void 0;
|
|
25467
|
+
}
|
|
25468
|
+
function normalizeHexLiteral(color) {
|
|
25469
|
+
const value = color.trim().replace(/^#/, "");
|
|
25470
|
+
if (/^[\da-f]{3}$/i.test(value)) {
|
|
25471
|
+
return value.split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
25472
|
+
}
|
|
25473
|
+
if (/^[\da-f]{4}$/i.test(value)) {
|
|
25474
|
+
return value.slice(0, 3).split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
25475
|
+
}
|
|
25476
|
+
if (/^[\da-f]{6}$/i.test(value)) {
|
|
25477
|
+
return value.toUpperCase();
|
|
25478
|
+
}
|
|
25479
|
+
if (/^[\da-f]{8}$/i.test(value)) {
|
|
25480
|
+
return value.slice(0, 6).toUpperCase();
|
|
25481
|
+
}
|
|
25482
|
+
return void 0;
|
|
25483
|
+
}
|
|
25484
|
+
function normalizeRgbColor(color) {
|
|
25485
|
+
const match = color.trim().match(/^rgba?\((.+)\)$/i);
|
|
25486
|
+
if (!match) {
|
|
25487
|
+
return void 0;
|
|
25488
|
+
}
|
|
25489
|
+
const parts = match[1].replace(/\s*\/\s*/g, ",").split(/\s*,\s*|\s+/).filter(Boolean);
|
|
25490
|
+
if (parts.length < 3) {
|
|
25491
|
+
return void 0;
|
|
25492
|
+
}
|
|
25493
|
+
const red = parseRgbChannel(parts[0]);
|
|
25494
|
+
const green = parseRgbChannel(parts[1]);
|
|
25495
|
+
const blue = parseRgbChannel(parts[2]);
|
|
25496
|
+
if (red === null || green === null || blue === null) {
|
|
25497
|
+
return void 0;
|
|
25498
|
+
}
|
|
25499
|
+
const alpha = parts[3] !== void 0 ? parseAlphaChannel(parts[3]) : 1;
|
|
25500
|
+
if (alpha === null || alpha <= 0) {
|
|
25501
|
+
return void 0;
|
|
25502
|
+
}
|
|
25503
|
+
const flattened = alpha >= 1 ? [red, green, blue] : [
|
|
25504
|
+
flattenChannel(red, alpha),
|
|
25505
|
+
flattenChannel(green, alpha),
|
|
25506
|
+
flattenChannel(blue, alpha)
|
|
25507
|
+
];
|
|
25508
|
+
return flattened.map(toHexChannel).join("");
|
|
25509
|
+
}
|
|
25510
|
+
function normalizeBrowserColor(color) {
|
|
25511
|
+
if (typeof document === "undefined") {
|
|
25512
|
+
return void 0;
|
|
25513
|
+
}
|
|
25514
|
+
const canvas = document.createElement("canvas");
|
|
25515
|
+
const context = canvas.getContext("2d");
|
|
25516
|
+
if (!context) {
|
|
25517
|
+
return void 0;
|
|
25518
|
+
}
|
|
25519
|
+
context.fillStyle = "#000000";
|
|
25520
|
+
context.fillStyle = color;
|
|
25521
|
+
const normalized = context.fillStyle;
|
|
25522
|
+
if (typeof normalized !== "string") {
|
|
25523
|
+
return void 0;
|
|
25524
|
+
}
|
|
25525
|
+
return normalizeHexLiteral(normalized) || normalizeRgbColor(normalized);
|
|
25526
|
+
}
|
|
25527
|
+
function parseRgbChannel(value) {
|
|
25528
|
+
if (value.endsWith("%")) {
|
|
25529
|
+
const percent = Number(value.slice(0, -1));
|
|
25530
|
+
if (!Number.isFinite(percent)) {
|
|
25531
|
+
return null;
|
|
25532
|
+
}
|
|
25533
|
+
return clampColorChannel(Math.round(percent / 100 * 255));
|
|
25534
|
+
}
|
|
25535
|
+
const channel = Number(value);
|
|
25536
|
+
if (!Number.isFinite(channel)) {
|
|
25537
|
+
return null;
|
|
25538
|
+
}
|
|
25539
|
+
return clampColorChannel(Math.round(channel));
|
|
25540
|
+
}
|
|
25541
|
+
function parseAlphaChannel(value) {
|
|
25542
|
+
if (value.endsWith("%")) {
|
|
25543
|
+
const percent = Number(value.slice(0, -1));
|
|
25544
|
+
if (!Number.isFinite(percent)) {
|
|
25545
|
+
return null;
|
|
25546
|
+
}
|
|
25547
|
+
return Math.min(Math.max(percent / 100, 0), 1);
|
|
25548
|
+
}
|
|
25549
|
+
const alpha = Number(value);
|
|
25550
|
+
if (!Number.isFinite(alpha)) {
|
|
25551
|
+
return null;
|
|
25552
|
+
}
|
|
25553
|
+
return Math.min(Math.max(alpha, 0), 1);
|
|
25554
|
+
}
|
|
25555
|
+
function clampColorChannel(value) {
|
|
25556
|
+
return Math.min(Math.max(value, 0), 255);
|
|
25557
|
+
}
|
|
25558
|
+
function flattenChannel(value, alpha) {
|
|
25559
|
+
return clampColorChannel(Math.round(255 * (1 - alpha) + value * alpha));
|
|
25560
|
+
}
|
|
25561
|
+
function toHexChannel(value) {
|
|
25562
|
+
return value.toString(16).padStart(2, "0").toUpperCase();
|
|
25563
|
+
}
|
|
25564
|
+
function pxBorderToDocxSize(width) {
|
|
25565
|
+
const safeWidth = Number.isFinite(width) && width > 0 ? width : 1;
|
|
25566
|
+
return Math.max(2, Math.round(safeWidth * 6));
|
|
25567
|
+
}
|
|
25568
|
+
function getRegularImageType(mime) {
|
|
25569
|
+
if (mime.includes("png")) return "png";
|
|
25570
|
+
if (mime.includes("jpeg") || mime.includes("jpg")) return "jpg";
|
|
25571
|
+
if (mime.includes("gif")) return "gif";
|
|
25572
|
+
if (mime.includes("bmp")) return "bmp";
|
|
25573
|
+
return null;
|
|
25574
|
+
}
|
|
25575
|
+
function normalizeDocxFileName(fileName) {
|
|
25576
|
+
const trimmed = fileName?.trim();
|
|
25577
|
+
if (!trimmed) {
|
|
25578
|
+
return DEFAULT_DOCX_FILE_NAME;
|
|
25579
|
+
}
|
|
25580
|
+
return trimmed.toLowerCase().endsWith(".docx") ? trimmed : `${trimmed}.docx`;
|
|
25581
|
+
}
|
|
25582
|
+
function pxToTwips(px) {
|
|
25583
|
+
return Math.round(px * 15);
|
|
25584
|
+
}
|
|
25585
|
+
|
|
25586
|
+
// src/utils/pdf.ts
|
|
25587
|
+
import {
|
|
25588
|
+
PDFDocument,
|
|
25589
|
+
StandardFonts,
|
|
25590
|
+
rgb
|
|
25591
|
+
} from "pdf-lib";
|
|
25592
|
+
var DEFAULT_PDF_FILE_NAME = "document.pdf";
|
|
25593
|
+
var DEFAULT_IMAGE_WIDTH2 = 320;
|
|
25594
|
+
var DEFAULT_IMAGE_HEIGHT2 = 180;
|
|
25595
|
+
var DEFAULT_LINE_HEIGHT2 = 1.15;
|
|
25596
|
+
var PAGE_REGION_GAP = 12;
|
|
25597
|
+
var SEPARATOR_HEIGHT = 12;
|
|
25598
|
+
var LIST_GAP = 8;
|
|
25599
|
+
var FOOTER_MIN_BAR_HEIGHT = 29;
|
|
25600
|
+
var PDF_TEXT_FALLBACKS = {
|
|
25601
|
+
"\u2297": "x",
|
|
25602
|
+
"\u2611": "[x]",
|
|
25603
|
+
"\u2612": "[x]",
|
|
25604
|
+
"\u2610": "[]",
|
|
25605
|
+
"\u2713": "v",
|
|
25606
|
+
"\u2714": "v",
|
|
25607
|
+
"\u2717": "x",
|
|
25608
|
+
"\u2715": "x",
|
|
25609
|
+
"\u25E6": "o",
|
|
25610
|
+
"\u25AA": "*",
|
|
25611
|
+
"\u25A0": "*"
|
|
25612
|
+
};
|
|
25613
|
+
var pdfTextCache = /* @__PURE__ */ new WeakMap();
|
|
25614
|
+
var bulletCharMap = {
|
|
25615
|
+
["disc" /* DISC */]: "\u2022",
|
|
25616
|
+
["circle" /* CIRCLE */]: "\u25E6",
|
|
25617
|
+
["square" /* SQUARE */]: "\u25A0",
|
|
25618
|
+
["checkbox" /* CHECKBOX */]: "\u2611"
|
|
25619
|
+
};
|
|
25620
|
+
async function exportEditorDataToPdf(payload, options = {}) {
|
|
25621
|
+
const editorOptions = payload.options;
|
|
25622
|
+
const pdfDoc = await PDFDocument.create();
|
|
25623
|
+
const context = await createPdfContext(pdfDoc, editorOptions);
|
|
25624
|
+
const headerBlocks = editorOptions.header.disabled ? [] : await parseElementList(payload.data.header || [], context, editorOptions);
|
|
25625
|
+
const footerBlocks = editorOptions.footer.disabled ? [] : await parseElementList(payload.data.footer || [], context, editorOptions);
|
|
25626
|
+
const mainBlocks = await parseElementList(
|
|
25627
|
+
payload.data.main,
|
|
25628
|
+
context,
|
|
25629
|
+
editorOptions
|
|
25630
|
+
);
|
|
25631
|
+
const headerHeight = measureBlocksHeight(
|
|
25632
|
+
headerBlocks,
|
|
25633
|
+
context.contentWidth,
|
|
25634
|
+
context
|
|
25635
|
+
);
|
|
25636
|
+
const footerHeight = measureBlocksHeight(
|
|
25637
|
+
footerBlocks,
|
|
25638
|
+
context.contentWidth,
|
|
25639
|
+
context
|
|
25640
|
+
);
|
|
25641
|
+
const footerBarHeight = getFooterBarHeight(footerHeight, context);
|
|
25642
|
+
const pageNumberHeight = getPageNumberHeight(editorOptions.pageNumber);
|
|
25643
|
+
const contentTop = Math.max(
|
|
25644
|
+
context.margins[0],
|
|
25645
|
+
context.headerTop + headerHeight + (headerBlocks.length ? context.headerGap : 0)
|
|
25646
|
+
);
|
|
25647
|
+
const contentBottom = Math.max(
|
|
25648
|
+
context.margins[2],
|
|
25649
|
+
context.footerBottom + footerBarHeight,
|
|
25650
|
+
getReservedPageNumberBottom(editorOptions.pageNumber, pageNumberHeight)
|
|
25651
|
+
);
|
|
25652
|
+
const pages = renderMainBlocks(
|
|
25653
|
+
mainBlocks,
|
|
25654
|
+
context,
|
|
25655
|
+
contentTop,
|
|
25656
|
+
contentBottom
|
|
25657
|
+
);
|
|
25658
|
+
renderPageDecorations(
|
|
25659
|
+
pages,
|
|
25660
|
+
context,
|
|
25661
|
+
headerBlocks,
|
|
25662
|
+
footerBlocks,
|
|
25663
|
+
headerHeight,
|
|
25664
|
+
footerHeight,
|
|
25665
|
+
footerBarHeight,
|
|
25666
|
+
editorOptions.pageNumber
|
|
25667
|
+
);
|
|
25668
|
+
const bytes = await pdfDoc.save();
|
|
25669
|
+
return {
|
|
25670
|
+
blob: new Blob([bytes], { type: "application/pdf" }),
|
|
25671
|
+
fileName: normalizePdfFileName(options.fileName)
|
|
25672
|
+
};
|
|
25673
|
+
}
|
|
25674
|
+
async function createPdfContext(pdfDoc, options) {
|
|
25675
|
+
const [sans, sansBold, sansItalic, sansBoldItalic] = await Promise.all([
|
|
25676
|
+
pdfDoc.embedFont(StandardFonts.Helvetica),
|
|
25677
|
+
pdfDoc.embedFont(StandardFonts.HelveticaBold),
|
|
25678
|
+
pdfDoc.embedFont(StandardFonts.HelveticaOblique),
|
|
25679
|
+
pdfDoc.embedFont(StandardFonts.HelveticaBoldOblique)
|
|
25680
|
+
]);
|
|
25681
|
+
const [serif, serifBold, serifItalic, serifBoldItalic] = await Promise.all([
|
|
25682
|
+
pdfDoc.embedFont(StandardFonts.TimesRoman),
|
|
25683
|
+
pdfDoc.embedFont(StandardFonts.TimesRomanBold),
|
|
25684
|
+
pdfDoc.embedFont(StandardFonts.TimesRomanItalic),
|
|
25685
|
+
pdfDoc.embedFont(StandardFonts.TimesRomanBoldItalic)
|
|
25686
|
+
]);
|
|
25687
|
+
const [mono, monoBold, monoItalic, monoBoldItalic] = await Promise.all([
|
|
25688
|
+
pdfDoc.embedFont(StandardFonts.Courier),
|
|
25689
|
+
pdfDoc.embedFont(StandardFonts.CourierBold),
|
|
25690
|
+
pdfDoc.embedFont(StandardFonts.CourierOblique),
|
|
25691
|
+
pdfDoc.embedFont(StandardFonts.CourierBoldOblique)
|
|
25692
|
+
]);
|
|
25693
|
+
const pageWidth = options.paperDirection === "horizontal" /* HORIZONTAL */ ? pxToPt(options.height) : pxToPt(options.width);
|
|
25694
|
+
const pageHeight = options.paperDirection === "horizontal" /* HORIZONTAL */ ? pxToPt(options.width) : pxToPt(options.height);
|
|
25695
|
+
const margins = options.margins.map(pxToPt);
|
|
25696
|
+
return {
|
|
25697
|
+
pdfDoc,
|
|
25698
|
+
options,
|
|
25699
|
+
fonts: {
|
|
25700
|
+
sans: {
|
|
25701
|
+
regular: sans,
|
|
25702
|
+
bold: sansBold,
|
|
25703
|
+
italic: sansItalic,
|
|
25704
|
+
boldItalic: sansBoldItalic
|
|
25705
|
+
},
|
|
25706
|
+
serif: {
|
|
25707
|
+
regular: serif,
|
|
25708
|
+
bold: serifBold,
|
|
25709
|
+
italic: serifItalic,
|
|
25710
|
+
boldItalic: serifBoldItalic
|
|
25711
|
+
},
|
|
25712
|
+
mono: {
|
|
25713
|
+
regular: mono,
|
|
25714
|
+
bold: monoBold,
|
|
25715
|
+
italic: monoItalic,
|
|
25716
|
+
boldItalic: monoBoldItalic
|
|
25717
|
+
}
|
|
25718
|
+
},
|
|
25719
|
+
pageWidth,
|
|
25720
|
+
pageHeight,
|
|
25721
|
+
margins,
|
|
25722
|
+
contentWidth: pageWidth - margins[1] - margins[3],
|
|
25723
|
+
headerTop: pxToPt(options.header.top),
|
|
25724
|
+
footerBottom: pxToPt(options.footer.bottom),
|
|
25725
|
+
headerGap: PAGE_REGION_GAP,
|
|
25726
|
+
footerGap: PAGE_REGION_GAP,
|
|
25727
|
+
separatorGap: SEPARATOR_HEIGHT,
|
|
25728
|
+
imageCache: /* @__PURE__ */ new Map()
|
|
25729
|
+
};
|
|
25730
|
+
}
|
|
25731
|
+
async function parseElementList(elementList, context, options) {
|
|
25732
|
+
const blocks = [];
|
|
25733
|
+
let inlineBuffer = [];
|
|
25734
|
+
const flushInlineBuffer = async () => {
|
|
25735
|
+
if (!inlineBuffer.length) return;
|
|
25736
|
+
blocks.push(...await parseInlineElements(inlineBuffer, context, options));
|
|
25737
|
+
inlineBuffer = [];
|
|
25738
|
+
};
|
|
25739
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
25740
|
+
const element = elementList[i];
|
|
25741
|
+
if (element.type === "area" /* AREA */ && element.valueList?.length) {
|
|
25742
|
+
await flushInlineBuffer();
|
|
25743
|
+
blocks.push(
|
|
25744
|
+
...await parseElementList(element.valueList, context, options)
|
|
25745
|
+
);
|
|
25746
|
+
continue;
|
|
25747
|
+
}
|
|
25748
|
+
if (element.type === "title" /* TITLE */ && element.valueList?.length) {
|
|
25749
|
+
await flushInlineBuffer();
|
|
25750
|
+
blocks.push(
|
|
25751
|
+
...await parseInlineElements(element.valueList, context, options, {
|
|
25752
|
+
alignment: element.rowFlex,
|
|
25753
|
+
rowMargin: element.rowMargin,
|
|
25754
|
+
listMarker: void 0,
|
|
25755
|
+
titleLevel: element.level || "first" /* FIRST */
|
|
25756
|
+
})
|
|
25757
|
+
);
|
|
25758
|
+
continue;
|
|
25759
|
+
}
|
|
25760
|
+
if (element.type === "list" /* LIST */ && element.valueList?.length) {
|
|
25761
|
+
await flushInlineBuffer();
|
|
25762
|
+
blocks.push(...await parseListBlock(element, context, options));
|
|
25763
|
+
continue;
|
|
25764
|
+
}
|
|
25765
|
+
if (element.type === "table" /* TABLE */ && element.trList?.length) {
|
|
25766
|
+
await flushInlineBuffer();
|
|
25767
|
+
blocks.push(await parseTableBlock(element, context, options));
|
|
25768
|
+
continue;
|
|
25769
|
+
}
|
|
25770
|
+
if (element.type === "pageBreak" /* PAGE_BREAK */) {
|
|
25771
|
+
await flushInlineBuffer();
|
|
25772
|
+
blocks.push({ type: "pageBreak" });
|
|
25773
|
+
continue;
|
|
25774
|
+
}
|
|
25775
|
+
if (element.type === "separator" /* SEPARATOR */) {
|
|
25776
|
+
await flushInlineBuffer();
|
|
25777
|
+
blocks.push({ type: "separator" });
|
|
25778
|
+
continue;
|
|
25779
|
+
}
|
|
25780
|
+
if (element.type === "image" /* IMAGE */ && element.imgDisplay && element.imgDisplay !== "inline") {
|
|
25781
|
+
await flushInlineBuffer();
|
|
25782
|
+
const imageBlock = await createImageBlock(element, context);
|
|
25783
|
+
if (imageBlock) {
|
|
25784
|
+
blocks.push(imageBlock);
|
|
25785
|
+
}
|
|
25786
|
+
continue;
|
|
25787
|
+
}
|
|
25788
|
+
if (element.type === "block" /* BLOCK */) {
|
|
25789
|
+
await flushInlineBuffer();
|
|
25790
|
+
const blockText = getBlockFallbackText2(element);
|
|
25791
|
+
if (blockText) {
|
|
25792
|
+
blocks.push(
|
|
25793
|
+
...await parseInlineElements(
|
|
25794
|
+
[{ value: blockText }],
|
|
25795
|
+
context,
|
|
25796
|
+
options
|
|
25797
|
+
)
|
|
25798
|
+
);
|
|
25799
|
+
}
|
|
25800
|
+
continue;
|
|
25801
|
+
}
|
|
25802
|
+
inlineBuffer.push(element);
|
|
25803
|
+
}
|
|
25804
|
+
await flushInlineBuffer();
|
|
25805
|
+
return blocks;
|
|
25806
|
+
}
|
|
25807
|
+
async function parseInlineElements(elementList, context, options, overrides = {}) {
|
|
25808
|
+
const paragraphs = [];
|
|
25809
|
+
let current = null;
|
|
25810
|
+
const getParagraphContext = (element) => ({
|
|
25811
|
+
alignment: overrides.alignment !== void 0 ? overrides.alignment : element?.rowFlex,
|
|
25812
|
+
rowMargin: overrides.rowMargin !== void 0 ? overrides.rowMargin : element?.rowMargin,
|
|
25813
|
+
listMarker: overrides.listMarker
|
|
25814
|
+
});
|
|
25815
|
+
const ensureParagraph = (element) => {
|
|
25816
|
+
if (!current) {
|
|
25817
|
+
current = {
|
|
25818
|
+
runs: [],
|
|
25819
|
+
context: getParagraphContext(element)
|
|
25820
|
+
};
|
|
25821
|
+
}
|
|
25822
|
+
return current;
|
|
25823
|
+
};
|
|
25824
|
+
const flushParagraph = (contextValue) => {
|
|
25825
|
+
if (!current) {
|
|
25826
|
+
if (!contextValue) return;
|
|
25827
|
+
paragraphs.push({
|
|
25828
|
+
type: "paragraph",
|
|
25829
|
+
runs: [],
|
|
25830
|
+
context: contextValue
|
|
25831
|
+
});
|
|
25832
|
+
return;
|
|
25833
|
+
}
|
|
25834
|
+
paragraphs.push({
|
|
25835
|
+
type: "paragraph",
|
|
25836
|
+
runs: current.runs,
|
|
25837
|
+
context: current.context
|
|
25838
|
+
});
|
|
25839
|
+
current = null;
|
|
25840
|
+
};
|
|
25841
|
+
const appendText = (element, text, factory, preserveTrailingBreak = false) => {
|
|
25842
|
+
const normalized = normalizeText2(text);
|
|
25843
|
+
const parts = normalized.split("\n");
|
|
25844
|
+
let lastSeparatorFlushedContent = false;
|
|
25845
|
+
for (let i = 0; i < parts.length; i++) {
|
|
25846
|
+
const segment = parts[i];
|
|
25847
|
+
if (segment) {
|
|
25848
|
+
ensureParagraph(element).runs.push(factory(segment));
|
|
25849
|
+
}
|
|
25850
|
+
if (i < parts.length - 1) {
|
|
25851
|
+
if (!current) {
|
|
25852
|
+
paragraphs.push({
|
|
25853
|
+
type: "paragraph",
|
|
25854
|
+
runs: [],
|
|
25855
|
+
context: getParagraphContext(element)
|
|
25856
|
+
});
|
|
25857
|
+
lastSeparatorFlushedContent = false;
|
|
25858
|
+
} else {
|
|
25859
|
+
flushParagraph();
|
|
25860
|
+
lastSeparatorFlushedContent = true;
|
|
25861
|
+
}
|
|
25862
|
+
}
|
|
25863
|
+
}
|
|
25864
|
+
if (preserveTrailingBreak && normalized.endsWith("\n") && lastSeparatorFlushedContent) {
|
|
25865
|
+
paragraphs.push({
|
|
25866
|
+
type: "paragraph",
|
|
25867
|
+
runs: [],
|
|
25868
|
+
context: getParagraphContext(element)
|
|
25869
|
+
});
|
|
25870
|
+
}
|
|
25871
|
+
};
|
|
25872
|
+
for (let i = 0; i < elementList.length; i++) {
|
|
25873
|
+
const element = elementList[i];
|
|
25874
|
+
if (element.type === "hyperlink" /* HYPERLINK */ && element.valueList?.length) {
|
|
25875
|
+
const children = element.valueList || [];
|
|
25876
|
+
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
25877
|
+
const child = children[childIndex];
|
|
25878
|
+
const text = normalizeText2(getInlineElementText2(child));
|
|
25879
|
+
if (!text) continue;
|
|
25880
|
+
appendText(
|
|
25881
|
+
element,
|
|
25882
|
+
text,
|
|
25883
|
+
(segment) => {
|
|
25884
|
+
const run = createTextRun2(
|
|
25885
|
+
child,
|
|
25886
|
+
options,
|
|
25887
|
+
overrides.titleLevel,
|
|
25888
|
+
segment
|
|
25889
|
+
);
|
|
25890
|
+
run.color = run.color || options.defaultHyperlinkColor;
|
|
25891
|
+
run.underline = true;
|
|
25892
|
+
return run;
|
|
25893
|
+
},
|
|
25894
|
+
i === elementList.length - 1 && childIndex === children.length - 1
|
|
25895
|
+
);
|
|
25896
|
+
}
|
|
25897
|
+
continue;
|
|
25898
|
+
}
|
|
25899
|
+
if (element.type === "image" /* IMAGE */) {
|
|
25900
|
+
const imageRun = await createInlineImageRun(element, context);
|
|
25901
|
+
if (imageRun) {
|
|
25902
|
+
ensureParagraph(element).runs.push(imageRun);
|
|
25903
|
+
}
|
|
25904
|
+
continue;
|
|
25905
|
+
}
|
|
25906
|
+
if (element.type === "columnBreak" /* COLUMN_BREAK */) {
|
|
25907
|
+
flushParagraph(getParagraphContext(element));
|
|
25908
|
+
continue;
|
|
25909
|
+
}
|
|
25910
|
+
if (element.type === "pageBreak" /* PAGE_BREAK */) {
|
|
25911
|
+
flushParagraph();
|
|
25912
|
+
paragraphs.push({ type: "pageBreak" });
|
|
25913
|
+
continue;
|
|
25914
|
+
}
|
|
25915
|
+
if (element.type === "tab" /* TAB */) {
|
|
25916
|
+
ensureParagraph(element).runs.push({
|
|
25917
|
+
type: "tab",
|
|
25918
|
+
width: pxToPt(options.defaultTabWidth)
|
|
25919
|
+
});
|
|
25920
|
+
continue;
|
|
25921
|
+
}
|
|
25922
|
+
if (element.type === "label" /* LABEL */) {
|
|
25923
|
+
const badgeRun = createBadgeRun(element, options, overrides.titleLevel);
|
|
25924
|
+
ensureParagraph(element).runs.push(badgeRun);
|
|
25925
|
+
continue;
|
|
25926
|
+
}
|
|
25927
|
+
const textValue = getInlineElementText2(element);
|
|
25928
|
+
if (!textValue) {
|
|
25929
|
+
continue;
|
|
25930
|
+
}
|
|
25931
|
+
appendText(
|
|
25932
|
+
element,
|
|
25933
|
+
textValue,
|
|
25934
|
+
(segment) => createTextRun2(element, options, overrides.titleLevel, segment),
|
|
25935
|
+
i === elementList.length - 1
|
|
25936
|
+
);
|
|
25937
|
+
}
|
|
25938
|
+
if (current) {
|
|
25939
|
+
flushParagraph();
|
|
25940
|
+
}
|
|
25941
|
+
return paragraphs.length ? paragraphs : [
|
|
25942
|
+
{
|
|
25943
|
+
type: "paragraph",
|
|
25944
|
+
runs: [],
|
|
25945
|
+
context: getParagraphContext()
|
|
25946
|
+
}
|
|
25947
|
+
];
|
|
25948
|
+
}
|
|
25949
|
+
async function parseListBlock(element, context, options) {
|
|
25950
|
+
const zipList = zipElementList(element.valueList || []);
|
|
25951
|
+
const listItemMap = splitListElement(zipList);
|
|
25952
|
+
const blocks = [];
|
|
25953
|
+
const orderedCounts = Array(9).fill(0);
|
|
25954
|
+
for (const listItemElements of listItemMap.values()) {
|
|
25955
|
+
const itemElement = getListItemNumberingElement2(listItemElements, element);
|
|
25956
|
+
const marker = getListMarker(itemElement, orderedCounts);
|
|
25957
|
+
blocks.push(
|
|
25958
|
+
...await parseInlineElements(listItemElements, context, options, {
|
|
25959
|
+
alignment: itemElement.rowFlex,
|
|
25960
|
+
rowMargin: itemElement.rowMargin,
|
|
25961
|
+
listMarker: marker
|
|
25962
|
+
})
|
|
25963
|
+
);
|
|
25964
|
+
}
|
|
25965
|
+
return blocks;
|
|
25966
|
+
}
|
|
25967
|
+
async function parseTableBlock(element, context, options) {
|
|
25968
|
+
const placements = computeTableCellPlacement(
|
|
25969
|
+
element.trList || [],
|
|
25970
|
+
element.colgroup || []
|
|
25971
|
+
);
|
|
25972
|
+
const rows = [];
|
|
25973
|
+
for (let rowIndex = 0; rowIndex < (element.trList || []).length; rowIndex++) {
|
|
25974
|
+
const tr = element.trList[rowIndex];
|
|
25975
|
+
const cells = [];
|
|
25976
|
+
for (let cellIndex = 0; cellIndex < tr.tdList.length; cellIndex++) {
|
|
25977
|
+
const td = tr.tdList[cellIndex];
|
|
25978
|
+
const placement = placements.get(td);
|
|
25979
|
+
cells.push({
|
|
25980
|
+
colspan: td.colspan,
|
|
25981
|
+
rowspan: td.rowspan,
|
|
25982
|
+
blocks: await parseElementList(td.value, context, options),
|
|
25983
|
+
colIndex: placement?.colIndex || 0,
|
|
25984
|
+
width: placement?.width || td.width || 0,
|
|
25985
|
+
padding: td.padding || options.table.tdPadding,
|
|
25986
|
+
verticalAlign: td.verticalAlign,
|
|
25987
|
+
backgroundColor: td.backgroundColor,
|
|
25988
|
+
borderColor: td.borderColor,
|
|
25989
|
+
borderTypes: td.borderTypes
|
|
25990
|
+
});
|
|
25991
|
+
}
|
|
25992
|
+
rows.push({
|
|
25993
|
+
height: Math.max(tr.height || 0, options.table.defaultTrMinHeight),
|
|
25994
|
+
cells
|
|
25995
|
+
});
|
|
25996
|
+
}
|
|
25997
|
+
return {
|
|
25998
|
+
type: "table",
|
|
25999
|
+
rows,
|
|
26000
|
+
colWidths: (element.colgroup || []).map((col) => col.width),
|
|
26001
|
+
borderType: element.borderType,
|
|
26002
|
+
borderColor: element.borderColor || options.table.defaultBorderColor,
|
|
26003
|
+
borderWidth: element.borderWidth || 1,
|
|
26004
|
+
borderExternalWidth: element.borderExternalWidth
|
|
26005
|
+
};
|
|
26006
|
+
}
|
|
26007
|
+
async function createImageBlock(element, context) {
|
|
26008
|
+
const image = await loadPdfImage(element.value, context);
|
|
26009
|
+
if (!image) {
|
|
26010
|
+
return null;
|
|
26011
|
+
}
|
|
26012
|
+
return {
|
|
26013
|
+
type: "image",
|
|
26014
|
+
image,
|
|
26015
|
+
width: pxToPt(
|
|
26016
|
+
Math.max(1, Math.round(element.width || DEFAULT_IMAGE_WIDTH2))
|
|
26017
|
+
),
|
|
26018
|
+
height: pxToPt(
|
|
26019
|
+
Math.max(1, Math.round(element.height || DEFAULT_IMAGE_HEIGHT2))
|
|
26020
|
+
),
|
|
26021
|
+
alignment: element.rowFlex
|
|
26022
|
+
};
|
|
26023
|
+
}
|
|
26024
|
+
async function createInlineImageRun(element, context) {
|
|
26025
|
+
const image = await loadPdfImage(element.value, context);
|
|
26026
|
+
if (!image) {
|
|
26027
|
+
return null;
|
|
26028
|
+
}
|
|
26029
|
+
return {
|
|
26030
|
+
type: "image",
|
|
26031
|
+
image,
|
|
26032
|
+
width: pxToPt(
|
|
26033
|
+
Math.max(1, Math.round(element.width || DEFAULT_IMAGE_WIDTH2))
|
|
26034
|
+
),
|
|
26035
|
+
height: pxToPt(
|
|
26036
|
+
Math.max(1, Math.round(element.height || DEFAULT_IMAGE_HEIGHT2))
|
|
26037
|
+
)
|
|
26038
|
+
};
|
|
26039
|
+
}
|
|
26040
|
+
function createTextRun2(element, options, titleLevel, text) {
|
|
26041
|
+
const titleSize = getTitleSize(titleLevel, options);
|
|
26042
|
+
const size = element.size || titleSize || options.defaultSize;
|
|
26043
|
+
const isTitle = !!titleLevel;
|
|
26044
|
+
return {
|
|
26045
|
+
type: "text",
|
|
26046
|
+
text,
|
|
26047
|
+
size,
|
|
26048
|
+
font: element.font || options.defaultFont,
|
|
26049
|
+
bold: isTitle ? true : !!element.bold,
|
|
26050
|
+
italic: !!element.italic,
|
|
26051
|
+
underline: !!element.underline,
|
|
26052
|
+
strikeout: !!element.strikeout,
|
|
26053
|
+
color: element.color || (isTitle ? "#000000" : void 0),
|
|
26054
|
+
highlight: element.highlight,
|
|
26055
|
+
superscript: element.type === "superscript" /* SUPERSCRIPT */,
|
|
26056
|
+
subscript: element.type === "subscript" /* SUBSCRIPT */
|
|
26057
|
+
};
|
|
26058
|
+
}
|
|
26059
|
+
function createBadgeRun(element, options, titleLevel) {
|
|
26060
|
+
const titleSize = getTitleSize(titleLevel, options);
|
|
26061
|
+
return {
|
|
26062
|
+
type: "badge",
|
|
26063
|
+
text: element.value,
|
|
26064
|
+
size: element.size || titleSize || options.defaultSize,
|
|
26065
|
+
font: element.font || options.defaultFont,
|
|
26066
|
+
bold: titleLevel ? true : !!element.bold,
|
|
26067
|
+
italic: !!element.italic,
|
|
26068
|
+
underline: !!element.underline,
|
|
26069
|
+
strikeout: !!element.strikeout,
|
|
26070
|
+
color: element.label?.color || element.color,
|
|
26071
|
+
backgroundColor: element.label?.backgroundColor,
|
|
26072
|
+
borderColor: element.label?.borderColor,
|
|
26073
|
+
padding: element.label?.padding || [2, 4, 2, 4]
|
|
26074
|
+
};
|
|
26075
|
+
}
|
|
26076
|
+
function renderMainBlocks(blocks, context, contentTop, contentBottom) {
|
|
26077
|
+
const pages = [];
|
|
26078
|
+
const contentEnd = context.pageHeight - contentBottom;
|
|
26079
|
+
const createPage = () => {
|
|
26080
|
+
const page = context.pdfDoc.addPage([
|
|
26081
|
+
context.pageWidth,
|
|
26082
|
+
context.pageHeight
|
|
26083
|
+
]);
|
|
26084
|
+
const state = {
|
|
26085
|
+
page,
|
|
26086
|
+
cursorY: contentTop,
|
|
26087
|
+
isEmpty: true
|
|
26088
|
+
};
|
|
26089
|
+
pages.push(state);
|
|
26090
|
+
return state;
|
|
26091
|
+
};
|
|
26092
|
+
let currentPage = createPage();
|
|
26093
|
+
const ensureSpace = (height) => {
|
|
26094
|
+
if (currentPage.cursorY + height <= contentEnd || currentPage.isEmpty) {
|
|
26095
|
+
return;
|
|
26096
|
+
}
|
|
26097
|
+
currentPage = createPage();
|
|
26098
|
+
};
|
|
26099
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
26100
|
+
const block = blocks[i];
|
|
26101
|
+
if (block.type === "pageBreak") {
|
|
26102
|
+
currentPage = createPage();
|
|
26103
|
+
continue;
|
|
26104
|
+
}
|
|
26105
|
+
if (block.type === "paragraph") {
|
|
26106
|
+
currentPage = renderParagraphAcrossPages(
|
|
26107
|
+
block,
|
|
26108
|
+
currentPage,
|
|
26109
|
+
pages,
|
|
26110
|
+
context,
|
|
26111
|
+
contentTop,
|
|
26112
|
+
contentEnd
|
|
26113
|
+
);
|
|
26114
|
+
continue;
|
|
26115
|
+
}
|
|
26116
|
+
if (block.type === "separator") {
|
|
26117
|
+
ensureSpace(context.separatorGap);
|
|
26118
|
+
renderSeparator(
|
|
26119
|
+
currentPage.page,
|
|
26120
|
+
context,
|
|
26121
|
+
currentPage.cursorY,
|
|
26122
|
+
context.margins[3],
|
|
26123
|
+
context.contentWidth
|
|
26124
|
+
);
|
|
26125
|
+
currentPage.cursorY += context.separatorGap;
|
|
26126
|
+
currentPage.isEmpty = false;
|
|
26127
|
+
continue;
|
|
26128
|
+
}
|
|
26129
|
+
if (block.type === "image") {
|
|
26130
|
+
ensureSpace(block.height);
|
|
26131
|
+
renderImageBlock(currentPage.page, block, context, currentPage.cursorY);
|
|
26132
|
+
currentPage.cursorY += block.height;
|
|
26133
|
+
currentPage.isEmpty = false;
|
|
26134
|
+
continue;
|
|
26135
|
+
}
|
|
26136
|
+
const tableLayout = layoutTable(block, context.contentWidth, context);
|
|
26137
|
+
currentPage = renderTableAcrossPages(
|
|
26138
|
+
block,
|
|
26139
|
+
tableLayout,
|
|
26140
|
+
currentPage,
|
|
26141
|
+
pages,
|
|
26142
|
+
context,
|
|
26143
|
+
contentTop,
|
|
26144
|
+
contentEnd
|
|
26145
|
+
);
|
|
26146
|
+
}
|
|
26147
|
+
return pages;
|
|
26148
|
+
}
|
|
26149
|
+
function renderParagraphAcrossPages(block, currentPage, pages, context, contentTop, contentEnd) {
|
|
26150
|
+
const layout = layoutParagraph(block, context.contentWidth, context);
|
|
26151
|
+
for (let lineIndex = 0; lineIndex < layout.lines.length; lineIndex++) {
|
|
26152
|
+
const line = layout.lines[lineIndex];
|
|
26153
|
+
if (currentPage.cursorY + line.height > contentEnd && !currentPage.isEmpty) {
|
|
26154
|
+
const page = context.pdfDoc.addPage([
|
|
26155
|
+
context.pageWidth,
|
|
26156
|
+
context.pageHeight
|
|
26157
|
+
]);
|
|
26158
|
+
currentPage = {
|
|
26159
|
+
page,
|
|
26160
|
+
cursorY: contentTop,
|
|
26161
|
+
isEmpty: true
|
|
26162
|
+
};
|
|
26163
|
+
pages.push(currentPage);
|
|
26164
|
+
}
|
|
26165
|
+
renderParagraphLine(
|
|
26166
|
+
currentPage.page,
|
|
26167
|
+
block,
|
|
26168
|
+
line,
|
|
26169
|
+
lineIndex === 0,
|
|
26170
|
+
layout,
|
|
26171
|
+
context,
|
|
26172
|
+
currentPage.cursorY,
|
|
26173
|
+
context.margins[3],
|
|
26174
|
+
context.contentWidth
|
|
26175
|
+
);
|
|
26176
|
+
currentPage.cursorY += line.height;
|
|
26177
|
+
currentPage.isEmpty = false;
|
|
26178
|
+
}
|
|
26179
|
+
return currentPage;
|
|
26180
|
+
}
|
|
26181
|
+
function renderTableAcrossPages(block, tableLayout, currentPage, pages, context, contentTop, contentEnd) {
|
|
26182
|
+
const scaledColWidths = scaleColumnWidths(
|
|
26183
|
+
block.colWidths,
|
|
26184
|
+
context.contentWidth
|
|
26185
|
+
);
|
|
26186
|
+
let tableTop = currentPage.cursorY;
|
|
26187
|
+
for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex++) {
|
|
26188
|
+
const row = block.rows[rowIndex];
|
|
26189
|
+
const rowHeight = tableLayout.rowHeights[rowIndex];
|
|
26190
|
+
const spanHeight = getSpanningRowHeight(
|
|
26191
|
+
block.rows,
|
|
26192
|
+
tableLayout.rowHeights,
|
|
26193
|
+
rowIndex
|
|
26194
|
+
);
|
|
26195
|
+
if (currentPage.cursorY + spanHeight > contentEnd && !currentPage.isEmpty) {
|
|
26196
|
+
const page = context.pdfDoc.addPage([
|
|
26197
|
+
context.pageWidth,
|
|
26198
|
+
context.pageHeight
|
|
26199
|
+
]);
|
|
26200
|
+
currentPage = {
|
|
26201
|
+
page,
|
|
26202
|
+
cursorY: contentTop,
|
|
26203
|
+
isEmpty: true
|
|
26204
|
+
};
|
|
26205
|
+
pages.push(currentPage);
|
|
26206
|
+
tableTop = currentPage.cursorY;
|
|
26207
|
+
}
|
|
26208
|
+
const rowTop = currentPage.cursorY;
|
|
26209
|
+
for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
|
|
26210
|
+
const cell = row.cells[cellIndex];
|
|
26211
|
+
const cellX = context.margins[3] + getColumnOffset(scaledColWidths, cell.colIndex);
|
|
26212
|
+
const cellWidth = getColumnSpanWidth(
|
|
26213
|
+
scaledColWidths,
|
|
26214
|
+
cell.colIndex,
|
|
26215
|
+
cell.colspan
|
|
26216
|
+
);
|
|
26217
|
+
const cellHeight = getRowSpanHeight(
|
|
26218
|
+
tableLayout.rowHeights,
|
|
26219
|
+
rowIndex,
|
|
26220
|
+
cell.rowspan
|
|
26221
|
+
);
|
|
26222
|
+
renderTableCell(
|
|
26223
|
+
currentPage.page,
|
|
26224
|
+
cell,
|
|
26225
|
+
context,
|
|
26226
|
+
block,
|
|
26227
|
+
cellX,
|
|
26228
|
+
rowTop,
|
|
26229
|
+
cellWidth,
|
|
26230
|
+
cellHeight
|
|
26231
|
+
);
|
|
26232
|
+
}
|
|
26233
|
+
currentPage.cursorY += rowHeight;
|
|
26234
|
+
currentPage.isEmpty = false;
|
|
26235
|
+
}
|
|
26236
|
+
return currentPage;
|
|
26237
|
+
}
|
|
26238
|
+
function renderPageDecorations(pages, context, headerBlocks, footerBlocks, headerHeight, footerHeight, footerBarHeight, pageNumber) {
|
|
26239
|
+
const totalPages = pages.length;
|
|
26240
|
+
for (let index = 0; index < pages.length; index++) {
|
|
26241
|
+
const pageState = pages[index];
|
|
26242
|
+
if (headerBlocks.length) {
|
|
26243
|
+
renderBlocksInRegion(
|
|
26244
|
+
pageState.page,
|
|
26245
|
+
headerBlocks,
|
|
26246
|
+
context,
|
|
26247
|
+
context.margins[3],
|
|
26248
|
+
context.headerTop,
|
|
26249
|
+
context.contentWidth
|
|
26250
|
+
);
|
|
26251
|
+
}
|
|
26252
|
+
if (footerBarHeight > 0) {
|
|
26253
|
+
if (context.options.footer.backgroundColor) {
|
|
26254
|
+
pageState.page.drawRectangle({
|
|
26255
|
+
x: 0,
|
|
26256
|
+
y: context.footerBottom,
|
|
26257
|
+
width: context.pageWidth,
|
|
26258
|
+
height: footerBarHeight,
|
|
26259
|
+
color: toPdfColor(context.options.footer.backgroundColor, "#FFFFFF")
|
|
26260
|
+
});
|
|
26261
|
+
}
|
|
26262
|
+
if (footerBlocks.length) {
|
|
26263
|
+
const footerTop = context.pageHeight - context.footerBottom - footerBarHeight;
|
|
26264
|
+
const footerContentTop = footerTop + Math.max(0, (footerBarHeight - footerHeight) / 2);
|
|
26265
|
+
renderBlocksInRegion(
|
|
26266
|
+
pageState.page,
|
|
26267
|
+
footerBlocks,
|
|
26268
|
+
context,
|
|
26269
|
+
context.margins[3],
|
|
26270
|
+
footerContentTop,
|
|
26271
|
+
context.contentWidth
|
|
26272
|
+
);
|
|
26273
|
+
}
|
|
26274
|
+
}
|
|
26275
|
+
renderPageNumber(pageState.page, context, pageNumber, index, totalPages);
|
|
26276
|
+
}
|
|
26277
|
+
}
|
|
26278
|
+
function renderBlocksInRegion(page, blocks, context, x, top, width) {
|
|
26279
|
+
let cursorY = top;
|
|
26280
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
26281
|
+
const block = blocks[i];
|
|
26282
|
+
if (block.type === "pageBreak") {
|
|
26283
|
+
continue;
|
|
26284
|
+
}
|
|
26285
|
+
if (block.type === "paragraph") {
|
|
26286
|
+
const layout = layoutParagraph(block, width, context);
|
|
26287
|
+
for (let lineIndex = 0; lineIndex < layout.lines.length; lineIndex++) {
|
|
26288
|
+
const line = layout.lines[lineIndex];
|
|
26289
|
+
renderParagraphLine(
|
|
26290
|
+
page,
|
|
26291
|
+
block,
|
|
26292
|
+
line,
|
|
26293
|
+
lineIndex === 0,
|
|
26294
|
+
layout,
|
|
26295
|
+
context,
|
|
26296
|
+
cursorY,
|
|
26297
|
+
x,
|
|
26298
|
+
width
|
|
26299
|
+
);
|
|
26300
|
+
cursorY += line.height;
|
|
26301
|
+
}
|
|
26302
|
+
continue;
|
|
26303
|
+
}
|
|
26304
|
+
if (block.type === "separator") {
|
|
26305
|
+
renderSeparator(page, context, cursorY, x, width);
|
|
26306
|
+
cursorY += context.separatorGap;
|
|
26307
|
+
continue;
|
|
26308
|
+
}
|
|
26309
|
+
if (block.type === "image") {
|
|
26310
|
+
renderImageBlock(page, block, context, cursorY, x, width);
|
|
26311
|
+
cursorY += block.height;
|
|
26312
|
+
continue;
|
|
26313
|
+
}
|
|
26314
|
+
const tableLayout = layoutTable(block, width, context);
|
|
26315
|
+
const scaledColWidths = scaleColumnWidths(block.colWidths, width);
|
|
26316
|
+
for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex++) {
|
|
26317
|
+
const row = block.rows[rowIndex];
|
|
26318
|
+
const rowTop = cursorY;
|
|
26319
|
+
for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
|
|
26320
|
+
const cell = row.cells[cellIndex];
|
|
26321
|
+
const cellX = x + getColumnOffset(scaledColWidths, cell.colIndex);
|
|
26322
|
+
const cellWidth = getColumnSpanWidth(
|
|
26323
|
+
scaledColWidths,
|
|
26324
|
+
cell.colIndex,
|
|
26325
|
+
cell.colspan
|
|
26326
|
+
);
|
|
26327
|
+
const cellHeight = getRowSpanHeight(
|
|
26328
|
+
tableLayout.rowHeights,
|
|
26329
|
+
rowIndex,
|
|
26330
|
+
cell.rowspan
|
|
26331
|
+
);
|
|
26332
|
+
renderTableCell(
|
|
26333
|
+
page,
|
|
26334
|
+
cell,
|
|
26335
|
+
context,
|
|
26336
|
+
block,
|
|
26337
|
+
cellX,
|
|
26338
|
+
rowTop,
|
|
26339
|
+
cellWidth,
|
|
26340
|
+
cellHeight
|
|
26341
|
+
);
|
|
26342
|
+
}
|
|
26343
|
+
cursorY += tableLayout.rowHeights[rowIndex];
|
|
26344
|
+
}
|
|
26345
|
+
}
|
|
26346
|
+
}
|
|
26347
|
+
function renderParagraphLine(page, block, line, isFirstLine, layout, context, top, baseX, regionWidth) {
|
|
26348
|
+
const alignment = normalizeAlignment(block.context.alignment);
|
|
26349
|
+
const lineWidth = line.width;
|
|
26350
|
+
const availableWidth = Math.max(
|
|
26351
|
+
1,
|
|
26352
|
+
regionWidth - layout.listIndent - layout.markerWidth
|
|
26353
|
+
);
|
|
26354
|
+
const justifyExtra = alignment === "justify" /* JUSTIFY */ && !isLastParagraphLine(layout, line) ? getJustifyExtra(line, availableWidth) : 0;
|
|
26355
|
+
let offsetX = 0;
|
|
26356
|
+
if (alignment === "center" /* CENTER */) {
|
|
26357
|
+
offsetX = (availableWidth - lineWidth) / 2;
|
|
26358
|
+
} else if (alignment === "right" /* RIGHT */) {
|
|
26359
|
+
offsetX = availableWidth - lineWidth;
|
|
26360
|
+
}
|
|
26361
|
+
const lineStart = baseX + layout.listIndent + layout.markerWidth + Math.max(0, offsetX);
|
|
26362
|
+
if (isFirstLine && block.context.listMarker) {
|
|
26363
|
+
const markerRun = getMarkerRun(block, context);
|
|
26364
|
+
const markerText = block.context.listMarker.text;
|
|
26365
|
+
drawTextRun(
|
|
26366
|
+
page,
|
|
26367
|
+
markerRun,
|
|
26368
|
+
markerText,
|
|
26369
|
+
baseX + layout.listIndent,
|
|
26370
|
+
top,
|
|
26371
|
+
line.height,
|
|
26372
|
+
context
|
|
26373
|
+
);
|
|
26374
|
+
}
|
|
26375
|
+
let cursorX = lineStart;
|
|
26376
|
+
for (let index = 0; index < line.fragments.length; index++) {
|
|
26377
|
+
const fragment = line.fragments[index];
|
|
26378
|
+
if (fragment.kind === "space" && justifyExtra > 0) {
|
|
26379
|
+
cursorX += justifyExtra;
|
|
26380
|
+
}
|
|
26381
|
+
drawLineFragment(page, fragment, cursorX, top, line.height, context);
|
|
26382
|
+
cursorX += fragment.width;
|
|
26383
|
+
}
|
|
26384
|
+
}
|
|
26385
|
+
function renderSeparator(page, context, top, x, width) {
|
|
26386
|
+
const lineY = toPdfY(context.pageHeight, top + SEPARATOR_HEIGHT / 2);
|
|
26387
|
+
page.drawLine({
|
|
26388
|
+
start: { x, y: lineY },
|
|
26389
|
+
end: { x: x + width, y: lineY },
|
|
26390
|
+
thickness: 1,
|
|
26391
|
+
color: rgb(0.6, 0.6, 0.6)
|
|
26392
|
+
});
|
|
26393
|
+
}
|
|
26394
|
+
function renderImageBlock(page, block, context, top, baseX = context.margins[3], width = context.contentWidth) {
|
|
26395
|
+
const alignment = normalizeAlignment(block.alignment);
|
|
26396
|
+
let x = baseX;
|
|
26397
|
+
if (alignment === "center" /* CENTER */) {
|
|
26398
|
+
x += Math.max(0, (width - block.width) / 2);
|
|
26399
|
+
} else if (alignment === "right" /* RIGHT */) {
|
|
26400
|
+
x += Math.max(0, width - block.width);
|
|
26401
|
+
}
|
|
26402
|
+
page.drawImage(block.image, {
|
|
26403
|
+
x,
|
|
26404
|
+
y: toPdfY(context.pageHeight, top, block.height),
|
|
26405
|
+
width: block.width,
|
|
26406
|
+
height: block.height
|
|
26407
|
+
});
|
|
26408
|
+
}
|
|
26409
|
+
function renderTableCell(page, cell, context, table, x, top, width, height) {
|
|
26410
|
+
if (cell.backgroundColor) {
|
|
26411
|
+
page.drawRectangle({
|
|
26412
|
+
x,
|
|
26413
|
+
y: toPdfY(context.pageHeight, top, height),
|
|
26414
|
+
width,
|
|
26415
|
+
height,
|
|
26416
|
+
color: toPdfColor(cell.backgroundColor)
|
|
26417
|
+
});
|
|
26418
|
+
}
|
|
26419
|
+
drawTableCellBorders(page, cell, context, table, x, top, width, height);
|
|
26420
|
+
const padding = getPadding(cell.padding || defaultTableOption.tdPadding).map(
|
|
26421
|
+
pxToPt
|
|
26422
|
+
);
|
|
26423
|
+
const contentWidth = Math.max(1, width - padding[1] - padding[3]);
|
|
26424
|
+
const contentHeight = measureBlocksHeight(cell.blocks, contentWidth, context);
|
|
26425
|
+
let contentTop = top + padding[0];
|
|
26426
|
+
if (cell.verticalAlign === VerticalAlign.CENTER) {
|
|
26427
|
+
contentTop = top + (height - contentHeight) / 2;
|
|
26428
|
+
} else if (cell.verticalAlign === "bottom" /* BOTTOM */) {
|
|
26429
|
+
contentTop = top + height - contentHeight - padding[2];
|
|
26430
|
+
}
|
|
26431
|
+
renderBlocksInRegion(
|
|
26432
|
+
page,
|
|
26433
|
+
cell.blocks,
|
|
26434
|
+
context,
|
|
26435
|
+
x + padding[3],
|
|
26436
|
+
contentTop,
|
|
26437
|
+
contentWidth
|
|
26438
|
+
);
|
|
26439
|
+
}
|
|
26440
|
+
function renderPageNumber(page, context, pageNumber, pageIndex, totalPages) {
|
|
26441
|
+
if (pageNumber.disabled || pageIndex < pageNumber.fromPageNo || Number.isInteger(pageNumber.maxPageNo) && pageIndex >= pageNumber.maxPageNo) {
|
|
26442
|
+
return;
|
|
26443
|
+
}
|
|
26444
|
+
let text = pageNumber.format || FORMAT_PLACEHOLDER.PAGE_NO;
|
|
26445
|
+
const currentValue = pageIndex + pageNumber.startPageNo - pageNumber.fromPageNo;
|
|
26446
|
+
const totalValue = totalPages - pageNumber.fromPageNo;
|
|
26447
|
+
text = text.replace(
|
|
26448
|
+
new RegExp(FORMAT_PLACEHOLDER.PAGE_NO, "g"),
|
|
26449
|
+
`${currentValue}`
|
|
26450
|
+
);
|
|
26451
|
+
text = text.replace(
|
|
26452
|
+
new RegExp(FORMAT_PLACEHOLDER.PAGE_COUNT, "g"),
|
|
26453
|
+
`${Math.max(0, totalValue)}`
|
|
26454
|
+
);
|
|
26455
|
+
const font = getFont(
|
|
26456
|
+
pageNumber.font || context.options.defaultFont,
|
|
26457
|
+
false,
|
|
26458
|
+
false,
|
|
26459
|
+
context
|
|
26460
|
+
);
|
|
26461
|
+
const size = pageNumber.size || 12;
|
|
26462
|
+
const bottom = pxToPt(pageNumber.bottom || 0);
|
|
26463
|
+
const safeText = sanitizeTextForPdf(text, font);
|
|
26464
|
+
const width = font.widthOfTextAtSize(safeText, size);
|
|
26465
|
+
const descenderHeight = Math.max(
|
|
26466
|
+
0,
|
|
26467
|
+
font.heightAtSize(size) - font.heightAtSize(size, { descender: false })
|
|
26468
|
+
);
|
|
26469
|
+
let x = context.margins[3];
|
|
26470
|
+
const alignment = normalizeAlignment(pageNumber.rowFlex);
|
|
26471
|
+
if (alignment === "center" /* CENTER */) {
|
|
26472
|
+
x = (context.pageWidth - width) / 2;
|
|
26473
|
+
} else if (alignment === "right" /* RIGHT */) {
|
|
26474
|
+
x = context.pageWidth - context.margins[1] - width;
|
|
26475
|
+
}
|
|
26476
|
+
page.drawText(safeText, {
|
|
26477
|
+
x,
|
|
26478
|
+
// Canvas draw uses the alphabetic baseline at `pageHeight - bottom`.
|
|
26479
|
+
// pdf-lib positions text from the text box bottom, so compensate by the
|
|
26480
|
+
// descender height to keep the baseline aligned.
|
|
26481
|
+
y: bottom - descenderHeight,
|
|
26482
|
+
size,
|
|
26483
|
+
font,
|
|
26484
|
+
color: toPdfColor(pageNumber.color, "#000000")
|
|
26485
|
+
});
|
|
26486
|
+
}
|
|
26487
|
+
function layoutParagraph(block, width, context) {
|
|
26488
|
+
const markerWidth = getMarkerWidth(block, context);
|
|
26489
|
+
const listIndent = block.context.listMarker ? pxToPt(block.context.listMarker.level * INDENT_PER_LEVEL) : 0;
|
|
26490
|
+
const availableWidth = Math.max(1, width - listIndent - markerWidth);
|
|
26491
|
+
const tokens = tokenizeParagraphRuns(block.runs, context);
|
|
26492
|
+
const lines = [];
|
|
26493
|
+
let line = {
|
|
26494
|
+
fragments: [],
|
|
26495
|
+
width: 0,
|
|
26496
|
+
height: getEmptyLineHeight(block, context)
|
|
26497
|
+
};
|
|
26498
|
+
const commitLine = () => {
|
|
26499
|
+
trimTrailingSpaces(line);
|
|
26500
|
+
lines.push(line);
|
|
26501
|
+
line = {
|
|
26502
|
+
fragments: [],
|
|
26503
|
+
width: 0,
|
|
26504
|
+
height: getEmptyLineHeight(block, context)
|
|
26505
|
+
};
|
|
26506
|
+
};
|
|
26507
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
26508
|
+
let token = tokens[i];
|
|
26509
|
+
if (token.kind === "space" && !line.fragments.length) {
|
|
26510
|
+
continue;
|
|
26511
|
+
}
|
|
26512
|
+
if (token.width > availableWidth && token.kind === "text" && token.run.type === "text") {
|
|
26513
|
+
const segments = splitTextToken(token, availableWidth, context);
|
|
26514
|
+
for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
|
|
26515
|
+
tokens.splice(i + segmentIndex, 0, segments[segmentIndex]);
|
|
26516
|
+
}
|
|
26517
|
+
continue;
|
|
26518
|
+
}
|
|
26519
|
+
if (line.width + token.width > availableWidth && line.fragments.length) {
|
|
26520
|
+
commitLine();
|
|
26521
|
+
i--;
|
|
26522
|
+
continue;
|
|
26523
|
+
}
|
|
26524
|
+
line.fragments.push(token);
|
|
26525
|
+
line.width += token.width;
|
|
26526
|
+
line.height = Math.max(line.height, token.height);
|
|
26527
|
+
}
|
|
26528
|
+
if (line.fragments.length || !lines.length) {
|
|
26529
|
+
commitLine();
|
|
26530
|
+
}
|
|
26531
|
+
return {
|
|
26532
|
+
lines,
|
|
26533
|
+
height: lines.reduce((sum, current) => sum + current.height, 0),
|
|
26534
|
+
markerWidth,
|
|
26535
|
+
listIndent
|
|
26536
|
+
};
|
|
26537
|
+
}
|
|
26538
|
+
function tokenizeParagraphRuns(runs, context) {
|
|
26539
|
+
const fragments = [];
|
|
26540
|
+
for (let index = 0; index < runs.length; index++) {
|
|
26541
|
+
const run = runs[index];
|
|
26542
|
+
if (run.type === "tab") {
|
|
26543
|
+
fragments.push({
|
|
26544
|
+
kind: "tab",
|
|
26545
|
+
width: run.width,
|
|
26546
|
+
height: 0,
|
|
26547
|
+
run
|
|
26548
|
+
});
|
|
26549
|
+
continue;
|
|
26550
|
+
}
|
|
26551
|
+
if (run.type === "image") {
|
|
26552
|
+
fragments.push({
|
|
26553
|
+
kind: "image",
|
|
26554
|
+
width: run.width,
|
|
26555
|
+
height: run.height,
|
|
26556
|
+
run
|
|
26557
|
+
});
|
|
26558
|
+
continue;
|
|
26559
|
+
}
|
|
26560
|
+
if (run.type === "badge") {
|
|
26561
|
+
const badgeWidth = measureBadgeWidth(run, context);
|
|
26562
|
+
const badgeHeight = measureBadgeHeight(run);
|
|
26563
|
+
fragments.push({
|
|
26564
|
+
kind: "badge",
|
|
26565
|
+
width: badgeWidth,
|
|
26566
|
+
height: badgeHeight,
|
|
26567
|
+
run
|
|
26568
|
+
});
|
|
26569
|
+
continue;
|
|
26570
|
+
}
|
|
26571
|
+
const parts = run.text.split(/(\s+)/);
|
|
26572
|
+
for (let partIndex = 0; partIndex < parts.length; partIndex++) {
|
|
26573
|
+
const part = parts[partIndex];
|
|
26574
|
+
if (!part) continue;
|
|
26575
|
+
const isWhitespace = /^\s+$/.test(part);
|
|
26576
|
+
fragments.push({
|
|
26577
|
+
kind: isWhitespace ? "space" : "text",
|
|
26578
|
+
width: measureTextWidth(part, run, context),
|
|
26579
|
+
height: getRunHeight(run),
|
|
26580
|
+
run: { ...run, text: part }
|
|
26581
|
+
});
|
|
26582
|
+
}
|
|
26583
|
+
}
|
|
26584
|
+
return fragments;
|
|
26585
|
+
}
|
|
26586
|
+
function splitTextToken(token, availableWidth, context) {
|
|
26587
|
+
if (token.run.type !== "text") {
|
|
26588
|
+
return [token];
|
|
26589
|
+
}
|
|
26590
|
+
const chars = splitText(token.run.text);
|
|
26591
|
+
const result = [];
|
|
26592
|
+
let current = "";
|
|
26593
|
+
for (let i = 0; i < chars.length; i++) {
|
|
26594
|
+
const next = current + chars[i];
|
|
26595
|
+
const width = measureTextWidth(next, token.run, context);
|
|
26596
|
+
if (width > availableWidth && current) {
|
|
26597
|
+
result.push({
|
|
26598
|
+
kind: "text",
|
|
26599
|
+
width: measureTextWidth(current, token.run, context),
|
|
26600
|
+
height: getRunHeight(token.run),
|
|
26601
|
+
run: { ...token.run, text: current }
|
|
26602
|
+
});
|
|
26603
|
+
current = chars[i];
|
|
26604
|
+
} else {
|
|
26605
|
+
current = next;
|
|
26606
|
+
}
|
|
26607
|
+
}
|
|
26608
|
+
if (current) {
|
|
26609
|
+
result.push({
|
|
26610
|
+
kind: /^\s+$/.test(current) ? "space" : "text",
|
|
26611
|
+
width: measureTextWidth(current, token.run, context),
|
|
26612
|
+
height: getRunHeight(token.run),
|
|
26613
|
+
run: { ...token.run, text: current }
|
|
26614
|
+
});
|
|
26615
|
+
}
|
|
26616
|
+
return result.length ? result : [token];
|
|
26617
|
+
}
|
|
26618
|
+
function trimTrailingSpaces(line) {
|
|
26619
|
+
while (line.fragments.length && line.fragments[line.fragments.length - 1].kind === "space") {
|
|
26620
|
+
const fragment = line.fragments.pop();
|
|
26621
|
+
line.width -= fragment.width;
|
|
26622
|
+
}
|
|
26623
|
+
}
|
|
26624
|
+
function layoutTable(table, width, context) {
|
|
26625
|
+
const rowHeights = table.rows.map(
|
|
26626
|
+
(row) => Math.max(
|
|
26627
|
+
pxToPt(row.height),
|
|
26628
|
+
pxToPt(context.options.table.defaultTrMinHeight)
|
|
26629
|
+
)
|
|
26630
|
+
);
|
|
26631
|
+
const scaledColWidths = scaleColumnWidths(table.colWidths, width);
|
|
26632
|
+
for (let rowIndex = 0; rowIndex < table.rows.length; rowIndex++) {
|
|
26633
|
+
const row = table.rows[rowIndex];
|
|
26634
|
+
for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
|
|
26635
|
+
const cell = row.cells[cellIndex];
|
|
26636
|
+
const cellWidth = getColumnSpanWidth(
|
|
26637
|
+
scaledColWidths,
|
|
26638
|
+
cell.colIndex,
|
|
26639
|
+
cell.colspan
|
|
26640
|
+
);
|
|
26641
|
+
const padding = getPadding(
|
|
26642
|
+
cell.padding || defaultTableOption.tdPadding
|
|
26643
|
+
).map(pxToPt);
|
|
26644
|
+
const contentWidth = Math.max(1, cellWidth - padding[1] - padding[3]);
|
|
26645
|
+
const contentHeight = measureBlocksHeight(cell.blocks, contentWidth, context) + padding[0] + padding[2];
|
|
26646
|
+
const spanHeight = getRowSpanHeight(rowHeights, rowIndex, cell.rowspan);
|
|
26647
|
+
if (contentHeight > spanHeight) {
|
|
26648
|
+
rowHeights[rowIndex + cell.rowspan - 1] += contentHeight - spanHeight;
|
|
26649
|
+
}
|
|
26650
|
+
}
|
|
26651
|
+
}
|
|
26652
|
+
return {
|
|
26653
|
+
rowHeights,
|
|
26654
|
+
totalHeight: rowHeights.reduce((sum, height) => sum + height, 0)
|
|
26655
|
+
};
|
|
26656
|
+
}
|
|
26657
|
+
function measureBlocksHeight(blocks, width, context) {
|
|
26658
|
+
let height = 0;
|
|
26659
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
26660
|
+
const block = blocks[i];
|
|
26661
|
+
if (block.type === "pageBreak") {
|
|
26662
|
+
continue;
|
|
26663
|
+
}
|
|
26664
|
+
if (block.type === "paragraph") {
|
|
26665
|
+
height += layoutParagraph(block, width, context).height;
|
|
26666
|
+
continue;
|
|
26667
|
+
}
|
|
26668
|
+
if (block.type === "separator") {
|
|
26669
|
+
height += context.separatorGap;
|
|
26670
|
+
continue;
|
|
26671
|
+
}
|
|
26672
|
+
if (block.type === "image") {
|
|
26673
|
+
height += block.height;
|
|
26674
|
+
continue;
|
|
26675
|
+
}
|
|
26676
|
+
height += layoutTable(block, width, context).totalHeight;
|
|
26677
|
+
}
|
|
26678
|
+
return height;
|
|
26679
|
+
}
|
|
26680
|
+
function drawLineFragment(page, fragment, x, top, lineHeight, context) {
|
|
26681
|
+
if (fragment.run.type === "tab") {
|
|
26682
|
+
return;
|
|
26683
|
+
}
|
|
26684
|
+
if (fragment.run.type === "image") {
|
|
26685
|
+
const imageTop = top + (lineHeight - fragment.run.height) / 2;
|
|
26686
|
+
page.drawImage(fragment.run.image, {
|
|
26687
|
+
x,
|
|
26688
|
+
y: toPdfY(context.pageHeight, imageTop, fragment.run.height),
|
|
26689
|
+
width: fragment.run.width,
|
|
26690
|
+
height: fragment.run.height
|
|
26691
|
+
});
|
|
26692
|
+
return;
|
|
26693
|
+
}
|
|
26694
|
+
if (fragment.run.type === "badge") {
|
|
26695
|
+
const badgeHeight = measureBadgeHeight(fragment.run);
|
|
26696
|
+
const badgeTop = top + (lineHeight - badgeHeight) / 2;
|
|
26697
|
+
const padding = getPadding(fragment.run.padding || [2, 4, 2, 4]).map(
|
|
26698
|
+
pxToPt
|
|
26699
|
+
);
|
|
26700
|
+
page.drawRectangle({
|
|
26701
|
+
x,
|
|
26702
|
+
y: toPdfY(context.pageHeight, badgeTop, badgeHeight),
|
|
26703
|
+
width: fragment.width,
|
|
26704
|
+
height: badgeHeight,
|
|
26705
|
+
color: toPdfColor(fragment.run.backgroundColor, "#FFFFFF"),
|
|
26706
|
+
borderColor: fragment.run.borderColor ? toPdfColor(fragment.run.borderColor) : void 0,
|
|
26707
|
+
borderWidth: fragment.run.borderColor ? 0.75 : void 0
|
|
26708
|
+
});
|
|
26709
|
+
drawTextRun(
|
|
26710
|
+
page,
|
|
26711
|
+
fragment.run,
|
|
26712
|
+
fragment.run.text,
|
|
26713
|
+
x + padding[3],
|
|
26714
|
+
badgeTop + padding[0],
|
|
26715
|
+
badgeHeight - padding[0] - padding[2],
|
|
26716
|
+
context
|
|
26717
|
+
);
|
|
26718
|
+
return;
|
|
26719
|
+
}
|
|
26720
|
+
if (fragment.run.type !== "text") {
|
|
26721
|
+
return;
|
|
26722
|
+
}
|
|
26723
|
+
drawTextRun(
|
|
26724
|
+
page,
|
|
26725
|
+
fragment.run,
|
|
26726
|
+
fragment.run.text,
|
|
26727
|
+
x,
|
|
26728
|
+
top,
|
|
26729
|
+
lineHeight,
|
|
26730
|
+
context
|
|
26731
|
+
);
|
|
26732
|
+
}
|
|
26733
|
+
function drawTextRun(page, run, text, x, top, lineHeight, context) {
|
|
26734
|
+
const resolved = resolveTextMetrics(run, context);
|
|
26735
|
+
const safeText = sanitizeTextForPdf(text, resolved.font);
|
|
26736
|
+
let textTop = top + (lineHeight - resolved.size) / 2;
|
|
26737
|
+
if (run.type === "text" && run.superscript) {
|
|
26738
|
+
textTop -= resolved.size * 0.25;
|
|
26739
|
+
}
|
|
26740
|
+
if (run.type === "text" && run.subscript) {
|
|
26741
|
+
textTop += resolved.size * 0.2;
|
|
26742
|
+
}
|
|
26743
|
+
const textY = toPdfY(context.pageHeight, textTop, resolved.size);
|
|
26744
|
+
if ("highlight" in run && run.highlight) {
|
|
26745
|
+
page.drawRectangle({
|
|
26746
|
+
x,
|
|
26747
|
+
y: textY,
|
|
26748
|
+
width: resolved.font.widthOfTextAtSize(safeText, resolved.size),
|
|
26749
|
+
height: resolved.size * 1.05,
|
|
26750
|
+
color: toPdfColor(run.highlight)
|
|
26751
|
+
});
|
|
26752
|
+
}
|
|
26753
|
+
page.drawText(safeText, {
|
|
26754
|
+
x,
|
|
26755
|
+
y: textY,
|
|
26756
|
+
size: resolved.size,
|
|
26757
|
+
font: resolved.font,
|
|
26758
|
+
color: toPdfColor(run.color, "#000000")
|
|
26759
|
+
});
|
|
26760
|
+
const textWidth = resolved.font.widthOfTextAtSize(safeText, resolved.size);
|
|
26761
|
+
if (run.underline) {
|
|
26762
|
+
const underlineY = textY - 1;
|
|
26763
|
+
page.drawLine({
|
|
26764
|
+
start: { x, y: underlineY },
|
|
26765
|
+
end: { x: x + textWidth, y: underlineY },
|
|
26766
|
+
thickness: 0.75,
|
|
26767
|
+
color: toPdfColor(run.color, "#000000")
|
|
26768
|
+
});
|
|
26769
|
+
}
|
|
26770
|
+
if (run.strikeout) {
|
|
26771
|
+
const strikeY = textY + resolved.size * 0.35;
|
|
26772
|
+
page.drawLine({
|
|
26773
|
+
start: { x, y: strikeY },
|
|
26774
|
+
end: { x: x + textWidth, y: strikeY },
|
|
26775
|
+
thickness: 0.75,
|
|
26776
|
+
color: toPdfColor(run.color, "#000000")
|
|
26777
|
+
});
|
|
26778
|
+
}
|
|
26779
|
+
}
|
|
26780
|
+
function drawTableCellBorders(page, cell, context, table, x, top, width, height) {
|
|
26781
|
+
const tableColor = table.borderColor || context.options.table.defaultBorderColor;
|
|
26782
|
+
const innerWidth = table.borderWidth || 1;
|
|
26783
|
+
const outerWidth = table.borderExternalWidth || innerWidth;
|
|
26784
|
+
const color = cell.borderColor || tableColor;
|
|
26785
|
+
const isEmpty = table.borderType === "empty" /* EMPTY */;
|
|
26786
|
+
const isExternal = table.borderType === "external" /* EXTERNAL */;
|
|
26787
|
+
const isInternal = table.borderType === "internal" /* INTERNAL */;
|
|
26788
|
+
const isDash = table.borderType === "dash" /* DASH */;
|
|
26789
|
+
const dashArray = isDash ? [3, 3] : void 0;
|
|
26790
|
+
const lineColor = toPdfColor(color, "#000000");
|
|
26791
|
+
const bottomY = toPdfY(context.pageHeight, top, height);
|
|
26792
|
+
const topY = toPdfY(context.pageHeight, top);
|
|
26793
|
+
const rightX = x + width;
|
|
26794
|
+
const drawEdge = (startX, startY, endX, endY, thickness) => {
|
|
26795
|
+
page.drawLine({
|
|
26796
|
+
start: { x: startX, y: startY },
|
|
26797
|
+
end: { x: endX, y: endY },
|
|
26798
|
+
thickness,
|
|
26799
|
+
color: lineColor,
|
|
26800
|
+
dashArray
|
|
26801
|
+
});
|
|
26802
|
+
};
|
|
26803
|
+
if (cell.borderTypes?.length) {
|
|
26804
|
+
if (cell.borderTypes.includes("top" /* TOP */)) {
|
|
26805
|
+
drawEdge(x, topY, rightX, topY, innerWidth);
|
|
26806
|
+
}
|
|
26807
|
+
if (cell.borderTypes.includes("right" /* RIGHT */)) {
|
|
26808
|
+
drawEdge(rightX, topY, rightX, bottomY, innerWidth);
|
|
26809
|
+
}
|
|
26810
|
+
if (cell.borderTypes.includes("bottom" /* BOTTOM */)) {
|
|
26811
|
+
drawEdge(x, bottomY, rightX, bottomY, innerWidth);
|
|
26812
|
+
}
|
|
26813
|
+
if (cell.borderTypes.includes("left" /* LEFT */)) {
|
|
26814
|
+
drawEdge(x, topY, x, bottomY, innerWidth);
|
|
26815
|
+
}
|
|
26816
|
+
}
|
|
26817
|
+
if (cell.borderColor && !cell.borderTypes?.length) {
|
|
26818
|
+
drawEdge(x, topY, rightX, topY, innerWidth);
|
|
26819
|
+
drawEdge(rightX, topY, rightX, bottomY, innerWidth);
|
|
26820
|
+
drawEdge(x, bottomY, rightX, bottomY, innerWidth);
|
|
26821
|
+
drawEdge(x, topY, x, bottomY, innerWidth);
|
|
26822
|
+
return;
|
|
26823
|
+
}
|
|
26824
|
+
if (isEmpty) {
|
|
26825
|
+
return;
|
|
26826
|
+
}
|
|
26827
|
+
if (!isInternal) {
|
|
26828
|
+
drawEdge(x, topY, rightX, topY, outerWidth);
|
|
26829
|
+
drawEdge(x, topY, x, bottomY, outerWidth);
|
|
26830
|
+
drawEdge(rightX, topY, rightX, bottomY, outerWidth);
|
|
26831
|
+
drawEdge(x, bottomY, rightX, bottomY, outerWidth);
|
|
26832
|
+
if (isExternal) {
|
|
26833
|
+
return;
|
|
26834
|
+
}
|
|
26835
|
+
}
|
|
26836
|
+
drawEdge(rightX, topY, rightX, bottomY, innerWidth);
|
|
26837
|
+
drawEdge(x, bottomY, rightX, bottomY, innerWidth);
|
|
26838
|
+
}
|
|
26839
|
+
function getMarkerWidth(block, context) {
|
|
26840
|
+
if (!block.context.listMarker) {
|
|
26841
|
+
return 0;
|
|
26842
|
+
}
|
|
26843
|
+
const markerRun = getMarkerRun(block, context);
|
|
26844
|
+
return measureTextWidth(block.context.listMarker.text, markerRun, context) + pxToPt(LIST_GAP);
|
|
26845
|
+
}
|
|
26846
|
+
function getMarkerRun(block, context) {
|
|
26847
|
+
const firstTextRun = block.runs.find((run) => run.type === "text" || run.type === "badge") || null;
|
|
26848
|
+
if (!firstTextRun) {
|
|
26849
|
+
return {
|
|
26850
|
+
type: "text",
|
|
26851
|
+
text: "",
|
|
26852
|
+
size: context.options.defaultSize,
|
|
26853
|
+
font: context.options.defaultFont
|
|
26854
|
+
};
|
|
26855
|
+
}
|
|
26856
|
+
if (firstTextRun.type === "badge") {
|
|
26857
|
+
return {
|
|
26858
|
+
type: "text",
|
|
26859
|
+
text: firstTextRun.text,
|
|
26860
|
+
size: firstTextRun.size,
|
|
26861
|
+
font: firstTextRun.font,
|
|
26862
|
+
bold: firstTextRun.bold,
|
|
26863
|
+
italic: firstTextRun.italic,
|
|
26864
|
+
color: firstTextRun.color
|
|
26865
|
+
};
|
|
26866
|
+
}
|
|
26867
|
+
return firstTextRun;
|
|
26868
|
+
}
|
|
26869
|
+
function getEmptyLineHeight(block, context) {
|
|
26870
|
+
const markerRun = getMarkerRun(block, context);
|
|
26871
|
+
return getRunHeight(
|
|
26872
|
+
markerRun,
|
|
26873
|
+
block.context.rowMargin || context.options.defaultRowMargin
|
|
26874
|
+
);
|
|
26875
|
+
}
|
|
26876
|
+
function getRunHeight(run, rowMargin = DEFAULT_LINE_HEIGHT2) {
|
|
26877
|
+
return run.size * rowMargin;
|
|
26878
|
+
}
|
|
26879
|
+
function resolveTextMetrics(run, context) {
|
|
26880
|
+
let size = run.size || context.options.defaultSize;
|
|
26881
|
+
if ("superscript" in run && run.superscript) {
|
|
26882
|
+
size *= 0.65;
|
|
26883
|
+
}
|
|
26884
|
+
if ("subscript" in run && run.subscript) {
|
|
26885
|
+
size *= 0.65;
|
|
26886
|
+
}
|
|
26887
|
+
return {
|
|
26888
|
+
size,
|
|
26889
|
+
font: getFont(
|
|
26890
|
+
run.font || context.options.defaultFont,
|
|
26891
|
+
!!run.bold,
|
|
26892
|
+
!!run.italic,
|
|
26893
|
+
context
|
|
26894
|
+
)
|
|
26895
|
+
};
|
|
26896
|
+
}
|
|
26897
|
+
function measureTextWidth(text, run, context) {
|
|
26898
|
+
const resolved = resolveTextMetrics(run, context);
|
|
26899
|
+
const safeText = sanitizeTextForPdf(text, resolved.font);
|
|
26900
|
+
return resolved.font.widthOfTextAtSize(safeText, resolved.size);
|
|
26901
|
+
}
|
|
26902
|
+
function measureBadgeWidth(run, context) {
|
|
26903
|
+
const padding = getPadding(run.padding || [2, 4, 2, 4]).map(pxToPt);
|
|
26904
|
+
return measureTextWidth(run.text, run, context) + padding[1] + padding[3];
|
|
26905
|
+
}
|
|
26906
|
+
function measureBadgeHeight(run) {
|
|
26907
|
+
const padding = getPadding(run.padding || [2, 4, 2, 4]).map(pxToPt);
|
|
26908
|
+
return run.size + padding[0] + padding[2];
|
|
26909
|
+
}
|
|
26910
|
+
function getJustifyExtra(line, availableWidth) {
|
|
26911
|
+
const spaceCount = line.fragments.filter(
|
|
26912
|
+
(fragment) => fragment.kind === "space"
|
|
26913
|
+
).length;
|
|
26914
|
+
if (!spaceCount || line.width >= availableWidth) {
|
|
26915
|
+
return 0;
|
|
26916
|
+
}
|
|
26917
|
+
return (availableWidth - line.width) / spaceCount;
|
|
26918
|
+
}
|
|
26919
|
+
function isLastParagraphLine(layout, line) {
|
|
26920
|
+
return layout.lines[layout.lines.length - 1] === line;
|
|
26921
|
+
}
|
|
26922
|
+
function getSpanningRowHeight(rows, rowHeights, rowIndex) {
|
|
26923
|
+
const row = rows[rowIndex];
|
|
26924
|
+
let maxHeight = rowHeights[rowIndex];
|
|
26925
|
+
for (let i = 0; i < row.cells.length; i++) {
|
|
26926
|
+
const cell = row.cells[i];
|
|
26927
|
+
maxHeight = Math.max(
|
|
26928
|
+
maxHeight,
|
|
26929
|
+
getRowSpanHeight(rowHeights, rowIndex, cell.rowspan)
|
|
26930
|
+
);
|
|
26931
|
+
}
|
|
26932
|
+
return maxHeight;
|
|
26933
|
+
}
|
|
26934
|
+
function getRowSpanHeight(rowHeights, rowIndex, rowSpan) {
|
|
26935
|
+
let height = 0;
|
|
26936
|
+
for (let i = rowIndex; i < rowIndex + rowSpan; i++) {
|
|
26937
|
+
height += rowHeights[i] || 0;
|
|
26938
|
+
}
|
|
26939
|
+
return height;
|
|
26940
|
+
}
|
|
26941
|
+
function scaleColumnWidths(widths, maxWidth) {
|
|
26942
|
+
const ptWidths = widths.map(pxToPt);
|
|
26943
|
+
const total = ptWidths.reduce((sum, width) => sum + width, 0);
|
|
26944
|
+
if (!total || total <= maxWidth) {
|
|
26945
|
+
return ptWidths;
|
|
26946
|
+
}
|
|
26947
|
+
const ratio = maxWidth / total;
|
|
26948
|
+
return ptWidths.map((width) => width * ratio);
|
|
26949
|
+
}
|
|
26950
|
+
function getColumnOffset(widths, colIndex) {
|
|
26951
|
+
let offset = 0;
|
|
26952
|
+
for (let i = 0; i < colIndex; i++) {
|
|
26953
|
+
offset += widths[i] || 0;
|
|
26954
|
+
}
|
|
26955
|
+
return offset;
|
|
26956
|
+
}
|
|
26957
|
+
function getColumnSpanWidth(widths, colIndex, span) {
|
|
26958
|
+
let width = 0;
|
|
26959
|
+
for (let i = colIndex; i < colIndex + span; i++) {
|
|
26960
|
+
width += widths[i] || 0;
|
|
26961
|
+
}
|
|
26962
|
+
return width;
|
|
26963
|
+
}
|
|
26964
|
+
function computeTableCellPlacement(trList, colgroup) {
|
|
26965
|
+
const placementMap = /* @__PURE__ */ new WeakMap();
|
|
26966
|
+
if (!trList.length || !colgroup.length) {
|
|
26967
|
+
return placementMap;
|
|
26968
|
+
}
|
|
26969
|
+
const occupiedUntilRow = Array(colgroup.length).fill(0);
|
|
26970
|
+
for (let rowIndex = 0; rowIndex < trList.length; rowIndex++) {
|
|
26971
|
+
const tr = trList[rowIndex];
|
|
26972
|
+
let colIndex = 0;
|
|
26973
|
+
for (let tdIndex = 0; tdIndex < tr.tdList.length; tdIndex++) {
|
|
26974
|
+
while (colIndex < colgroup.length && occupiedUntilRow[colIndex] > rowIndex) {
|
|
26975
|
+
colIndex += 1;
|
|
26976
|
+
}
|
|
26977
|
+
const td = tr.tdList[tdIndex];
|
|
26978
|
+
let width = 0;
|
|
26979
|
+
for (let currentCol = colIndex; currentCol < colIndex + td.colspan; currentCol++) {
|
|
26980
|
+
width += colgroup[currentCol]?.width || 0;
|
|
26981
|
+
occupiedUntilRow[currentCol] = Math.max(
|
|
26982
|
+
occupiedUntilRow[currentCol],
|
|
26983
|
+
rowIndex + td.rowspan
|
|
26984
|
+
);
|
|
26985
|
+
}
|
|
26986
|
+
placementMap.set(td, { colIndex, width });
|
|
26987
|
+
colIndex += td.colspan;
|
|
26988
|
+
}
|
|
26989
|
+
}
|
|
26990
|
+
return placementMap;
|
|
26991
|
+
}
|
|
26992
|
+
async function loadPdfImage(src, context) {
|
|
26993
|
+
if (context.imageCache.has(src)) {
|
|
26994
|
+
return context.imageCache.get(src);
|
|
26995
|
+
}
|
|
26996
|
+
try {
|
|
26997
|
+
const payload = await loadPdfImagePayload(src);
|
|
26998
|
+
const image = payload.type === "jpg" ? await context.pdfDoc.embedJpg(payload.data) : await context.pdfDoc.embedPng(payload.data);
|
|
26999
|
+
context.imageCache.set(src, image);
|
|
27000
|
+
return image;
|
|
27001
|
+
} catch {
|
|
27002
|
+
return null;
|
|
27003
|
+
}
|
|
27004
|
+
}
|
|
27005
|
+
async function loadPdfImagePayload(src) {
|
|
27006
|
+
const source = src.trim();
|
|
27007
|
+
if (source.startsWith("data:")) {
|
|
27008
|
+
return getPdfImagePayloadFromDataUrl(source);
|
|
27009
|
+
}
|
|
27010
|
+
const response = await fetch(source);
|
|
27011
|
+
if (!response.ok) {
|
|
27012
|
+
throw new Error(`Image request failed: ${response.status}`);
|
|
27013
|
+
}
|
|
27014
|
+
const contentType = response.headers.get("content-type") || "";
|
|
27015
|
+
const data2 = await response.arrayBuffer();
|
|
27016
|
+
return normalizePdfImagePayload(data2, contentType);
|
|
27017
|
+
}
|
|
27018
|
+
async function getPdfImagePayloadFromDataUrl(src) {
|
|
27019
|
+
const [, meta = "", encoded = ""] = src.match(/^data:([^,]*),(.*)$/) || [];
|
|
27020
|
+
const mime = meta.split(";")[0] || "";
|
|
27021
|
+
const isBase64 = meta.includes(";base64");
|
|
27022
|
+
const text = isBase64 ? atob(encoded) : decodeURIComponent(encoded);
|
|
27023
|
+
const bytes = new Uint8Array(text.length);
|
|
27024
|
+
for (let i = 0; i < text.length; i++) {
|
|
27025
|
+
bytes[i] = text.charCodeAt(i);
|
|
27026
|
+
}
|
|
27027
|
+
return normalizePdfImagePayload(bytes.buffer, mime);
|
|
27028
|
+
}
|
|
27029
|
+
async function normalizePdfImagePayload(data2, mime) {
|
|
27030
|
+
const lower = mime.toLowerCase();
|
|
27031
|
+
if (lower.includes("jpeg") || lower.includes("jpg")) {
|
|
27032
|
+
return {
|
|
27033
|
+
type: "jpg",
|
|
27034
|
+
data: data2
|
|
27035
|
+
};
|
|
27036
|
+
}
|
|
27037
|
+
if (lower.includes("png")) {
|
|
27038
|
+
return {
|
|
27039
|
+
type: "png",
|
|
27040
|
+
data: data2
|
|
27041
|
+
};
|
|
27042
|
+
}
|
|
27043
|
+
return {
|
|
27044
|
+
type: "png",
|
|
27045
|
+
data: await rasterizeImageToPng2(data2, mime)
|
|
27046
|
+
};
|
|
27047
|
+
}
|
|
27048
|
+
async function rasterizeImageToPng2(data2, mime) {
|
|
27049
|
+
const blob = new Blob([data2], {
|
|
27050
|
+
type: mime || "image/png"
|
|
27051
|
+
});
|
|
27052
|
+
const url = URL.createObjectURL(blob);
|
|
27053
|
+
try {
|
|
27054
|
+
const image = await loadHtmlImage2(url);
|
|
27055
|
+
const canvas = document.createElement("canvas");
|
|
27056
|
+
canvas.width = image.naturalWidth || DEFAULT_IMAGE_WIDTH2;
|
|
27057
|
+
canvas.height = image.naturalHeight || DEFAULT_IMAGE_HEIGHT2;
|
|
27058
|
+
const context = canvas.getContext("2d");
|
|
27059
|
+
if (!context) {
|
|
27060
|
+
throw new Error("Canvas context is unavailable");
|
|
27061
|
+
}
|
|
27062
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
27063
|
+
const pngBlob = await new Promise((resolve, reject) => {
|
|
27064
|
+
canvas.toBlob((output) => {
|
|
27065
|
+
if (output) {
|
|
27066
|
+
resolve(output);
|
|
27067
|
+
} else {
|
|
27068
|
+
reject(new Error("Failed to create PNG blob"));
|
|
27069
|
+
}
|
|
27070
|
+
}, "image/png");
|
|
27071
|
+
});
|
|
27072
|
+
return await pngBlob.arrayBuffer();
|
|
27073
|
+
} finally {
|
|
27074
|
+
URL.revokeObjectURL(url);
|
|
27075
|
+
}
|
|
27076
|
+
}
|
|
27077
|
+
function loadHtmlImage2(src) {
|
|
27078
|
+
return new Promise((resolve, reject) => {
|
|
27079
|
+
const image = new Image();
|
|
27080
|
+
image.onload = () => resolve(image);
|
|
27081
|
+
image.onerror = () => reject(new Error("Failed to load image"));
|
|
27082
|
+
image.src = src;
|
|
27083
|
+
});
|
|
27084
|
+
}
|
|
27085
|
+
function getInlineElementText2(element) {
|
|
27086
|
+
switch (element.type) {
|
|
27087
|
+
case "control" /* CONTROL */:
|
|
27088
|
+
return getControlText2(element.control);
|
|
27089
|
+
case "date" /* DATE */:
|
|
27090
|
+
return element.valueList?.length ? getTextFromElementList(element.valueList) : element.value;
|
|
27091
|
+
case "checkbox" /* CHECKBOX */:
|
|
27092
|
+
return element.checkbox?.value ? "\u2611" : "\u2610";
|
|
27093
|
+
case "radio" /* RADIO */:
|
|
27094
|
+
return element.radio?.value ? "\u25C9" : "\u25CB";
|
|
27095
|
+
case "label" /* LABEL */:
|
|
27096
|
+
case "latex" /* LATEX */:
|
|
27097
|
+
case "subscript" /* SUBSCRIPT */:
|
|
27098
|
+
case "superscript" /* SUPERSCRIPT */:
|
|
27099
|
+
return element.value;
|
|
27100
|
+
default:
|
|
27101
|
+
return element.value;
|
|
27102
|
+
}
|
|
27103
|
+
}
|
|
27104
|
+
function getControlText2(control) {
|
|
27105
|
+
if (!control) return "";
|
|
27106
|
+
if (control.type === "text" /* TEXT */ || control.type === "date" /* DATE */ || control.type === "number" /* NUMBER */) {
|
|
27107
|
+
const value = control.value?.length ? getTextFromElementList(control.value) : "";
|
|
27108
|
+
const content = value || control.placeholder || "";
|
|
27109
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
27110
|
+
}
|
|
27111
|
+
if (control.type === "select" /* SELECT */) {
|
|
27112
|
+
const labels = getSelectedControlLabels2(control.code, control.valueSets);
|
|
27113
|
+
const content = labels.length ? labels.join(control.multiSelectDelimiter || ", ") : control.placeholder || "";
|
|
27114
|
+
return `${control.preText || ""}${content}${control.postText || ""}`;
|
|
27115
|
+
}
|
|
27116
|
+
if (control.type === "checkbox" /* CHECKBOX */ || control.type === "radio" /* RADIO */) {
|
|
27117
|
+
const isRadio = control.type === "radio" /* RADIO */;
|
|
27118
|
+
return (control.valueSets || []).map((valueSet) => {
|
|
27119
|
+
const checked = control.code?.split(",").includes(valueSet.code) || false;
|
|
27120
|
+
return `${checked ? isRadio ? "\u25C9" : "\u2611" : isRadio ? "\u25CB" : "\u2610"} ${valueSet.value}`;
|
|
27121
|
+
}).join(" ");
|
|
27122
|
+
}
|
|
27123
|
+
return "";
|
|
27124
|
+
}
|
|
27125
|
+
function getSelectedControlLabels2(code, valueSets) {
|
|
27126
|
+
if (!code || !valueSets?.length) return [];
|
|
27127
|
+
return code.split(",").map(
|
|
27128
|
+
(selectCode) => valueSets.find((valueSet) => valueSet.code === selectCode)?.value
|
|
27129
|
+
).filter((value) => !!value);
|
|
27130
|
+
}
|
|
27131
|
+
function getBlockFallbackText2(element) {
|
|
27132
|
+
if (element.block?.iframeBlock?.src) {
|
|
27133
|
+
return element.block.iframeBlock.src;
|
|
27134
|
+
}
|
|
27135
|
+
if (element.block?.videoBlock?.src) {
|
|
27136
|
+
return element.block.videoBlock.src;
|
|
27137
|
+
}
|
|
27138
|
+
return "";
|
|
27139
|
+
}
|
|
27140
|
+
function getListItemNumberingElement2(listItemElements, fallback) {
|
|
27141
|
+
return listItemElements.find(
|
|
27142
|
+
(listItem) => listItem.listId || listItem.listLevel !== void 0 || !!listItem.listPreset || !!listItem.listStyle || !!listItem.listType
|
|
27143
|
+
) || fallback;
|
|
27144
|
+
}
|
|
27145
|
+
function getListMarker(element, orderedCounts) {
|
|
27146
|
+
const level = Math.max(0, Math.min(element.listLevel || 0, 8));
|
|
27147
|
+
if (element.listType === "ul" /* UL */) {
|
|
27148
|
+
return {
|
|
27149
|
+
text: getUnorderedMarkerText(element, level),
|
|
27150
|
+
level
|
|
27151
|
+
};
|
|
27152
|
+
}
|
|
27153
|
+
while (orderedCounts.length <= level) {
|
|
27154
|
+
orderedCounts.push(0);
|
|
27155
|
+
}
|
|
27156
|
+
orderedCounts[level] += 1;
|
|
27157
|
+
orderedCounts.length = level + 1;
|
|
27158
|
+
const style = element.listPreset ? getOrderedPresetStyle(element.listPreset, level) : getOrderedStyle(element.listStyle);
|
|
27159
|
+
const outlinePrefix = style === "outline" ? orderedCounts.slice(0, level + 1).join(".") : void 0;
|
|
27160
|
+
return {
|
|
27161
|
+
text: formatOlNumber2(orderedCounts[level] - 1, style, outlinePrefix),
|
|
27162
|
+
level
|
|
27163
|
+
};
|
|
27164
|
+
}
|
|
27165
|
+
function getOrderedPresetStyle(preset, level = 0) {
|
|
27166
|
+
const cycle = preset ? olPresetCycles[preset] : void 0;
|
|
27167
|
+
if (!cycle?.length) {
|
|
27168
|
+
return "decimal";
|
|
27169
|
+
}
|
|
27170
|
+
return cycle[level % cycle.length];
|
|
27171
|
+
}
|
|
27172
|
+
function getOrderedStyle(style) {
|
|
27173
|
+
switch (style) {
|
|
27174
|
+
case "lowerAlpha" /* LOWER_ALPHA */:
|
|
27175
|
+
return "lowerAlpha";
|
|
27176
|
+
case "upperAlpha" /* UPPER_ALPHA */:
|
|
27177
|
+
return "upperAlpha";
|
|
27178
|
+
case "lowerRoman" /* LOWER_ROMAN */:
|
|
27179
|
+
return "lowerRoman";
|
|
27180
|
+
case "upperRoman" /* UPPER_ROMAN */:
|
|
27181
|
+
return "upperRoman";
|
|
27182
|
+
case "decimalParen" /* DECIMAL_PAREN */:
|
|
27183
|
+
return "decimalParen";
|
|
27184
|
+
default:
|
|
27185
|
+
return "decimal";
|
|
27186
|
+
}
|
|
27187
|
+
}
|
|
27188
|
+
function getUnorderedMarkerText(element, level) {
|
|
27189
|
+
if (element.listPreset) {
|
|
27190
|
+
const cycle = ulPresetCycles[element.listPreset];
|
|
27191
|
+
if (cycle?.length) {
|
|
27192
|
+
return cycle[level % cycle.length];
|
|
27193
|
+
}
|
|
27194
|
+
}
|
|
27195
|
+
return bulletCharMap[element.listStyle || "disc" /* DISC */] || bulletCharMap["disc" /* DISC */];
|
|
27196
|
+
}
|
|
27197
|
+
function toAlpha2(n, upper) {
|
|
27198
|
+
let result = "";
|
|
27199
|
+
let num = n + 1;
|
|
27200
|
+
while (num > 0) {
|
|
27201
|
+
num--;
|
|
27202
|
+
result = String.fromCharCode((upper ? 65 : 97) + num % 26) + result;
|
|
27203
|
+
num = Math.floor(num / 26);
|
|
27204
|
+
}
|
|
27205
|
+
return result;
|
|
27206
|
+
}
|
|
27207
|
+
function toRoman2(n, upper) {
|
|
27208
|
+
const num = n + 1;
|
|
27209
|
+
const vals = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
|
|
27210
|
+
const syms = [
|
|
27211
|
+
"M",
|
|
27212
|
+
"CM",
|
|
27213
|
+
"D",
|
|
27214
|
+
"CD",
|
|
27215
|
+
"C",
|
|
27216
|
+
"XC",
|
|
27217
|
+
"L",
|
|
27218
|
+
"XL",
|
|
27219
|
+
"X",
|
|
27220
|
+
"IX",
|
|
27221
|
+
"V",
|
|
27222
|
+
"IV",
|
|
27223
|
+
"I"
|
|
27224
|
+
];
|
|
27225
|
+
let result = "";
|
|
27226
|
+
let remaining = num;
|
|
27227
|
+
for (let i = 0; i < vals.length; i++) {
|
|
27228
|
+
while (remaining >= vals[i]) {
|
|
27229
|
+
result += syms[i];
|
|
27230
|
+
remaining -= vals[i];
|
|
27231
|
+
}
|
|
27232
|
+
}
|
|
27233
|
+
return upper ? result : result.toLowerCase();
|
|
27234
|
+
}
|
|
27235
|
+
function formatOlNumber2(index, style, outlinePrefix) {
|
|
27236
|
+
switch (style) {
|
|
27237
|
+
case "decimal":
|
|
27238
|
+
return `${index + 1}.`;
|
|
27239
|
+
case "decimalParen":
|
|
27240
|
+
return `${index + 1})`;
|
|
27241
|
+
case "decimalZero":
|
|
27242
|
+
return `${String(index + 1).padStart(2, "0")}.`;
|
|
27243
|
+
case "lowerAlpha":
|
|
27244
|
+
return `${toAlpha2(index, false)}.`;
|
|
27245
|
+
case "lowerAlphaParen":
|
|
27246
|
+
return `${toAlpha2(index, false)})`;
|
|
27247
|
+
case "upperAlpha":
|
|
27248
|
+
return `${toAlpha2(index, true)}.`;
|
|
27249
|
+
case "lowerRoman":
|
|
27250
|
+
return `${toRoman2(index, false)}.`;
|
|
27251
|
+
case "lowerRomanParen":
|
|
27252
|
+
return `${toRoman2(index, false)})`;
|
|
27253
|
+
case "upperRoman":
|
|
27254
|
+
return `${toRoman2(index, true)}.`;
|
|
27255
|
+
case "outline":
|
|
27256
|
+
return outlinePrefix ? `${outlinePrefix}.` : `${index + 1}.`;
|
|
27257
|
+
default:
|
|
27258
|
+
return `${index + 1}.`;
|
|
27259
|
+
}
|
|
27260
|
+
}
|
|
27261
|
+
function normalizeAlignment(rowFlex) {
|
|
27262
|
+
if (rowFlex === "alignment" /* ALIGNMENT */) {
|
|
27263
|
+
return "justify" /* JUSTIFY */;
|
|
27264
|
+
}
|
|
27265
|
+
return rowFlex || "left" /* LEFT */;
|
|
27266
|
+
}
|
|
27267
|
+
function getFont(family, bold, italic, context) {
|
|
27268
|
+
const fontSet = context.fonts[resolveFontFamily(family)];
|
|
27269
|
+
if (bold && italic) {
|
|
27270
|
+
return fontSet.boldItalic;
|
|
27271
|
+
}
|
|
27272
|
+
if (bold) {
|
|
27273
|
+
return fontSet.bold;
|
|
27274
|
+
}
|
|
27275
|
+
if (italic) {
|
|
27276
|
+
return fontSet.italic;
|
|
27277
|
+
}
|
|
27278
|
+
return fontSet.regular;
|
|
27279
|
+
}
|
|
27280
|
+
function resolveFontFamily(font) {
|
|
27281
|
+
const normalized = (font || "").trim().toLowerCase();
|
|
27282
|
+
if (normalized.includes("sans-serif") || normalized.includes("arial") || normalized.includes("helvetica") || normalized.includes("yahei") || normalized.includes("microsoft") || normalized.includes("inter") || normalized.includes("roboto")) {
|
|
27283
|
+
return "sans";
|
|
27284
|
+
}
|
|
27285
|
+
if (normalized.includes("times") || normalized === "serif" || normalized.endsWith(", serif")) {
|
|
27286
|
+
return "serif";
|
|
27287
|
+
}
|
|
27288
|
+
if (normalized.includes("courier") || normalized.includes("mono") || normalized.includes("code")) {
|
|
27289
|
+
return "mono";
|
|
27290
|
+
}
|
|
27291
|
+
return "sans";
|
|
27292
|
+
}
|
|
27293
|
+
function sanitizeTextForPdf(text, font) {
|
|
27294
|
+
let fontCache = pdfTextCache.get(font);
|
|
27295
|
+
if (!fontCache) {
|
|
27296
|
+
fontCache = /* @__PURE__ */ new Map();
|
|
27297
|
+
pdfTextCache.set(font, fontCache);
|
|
27298
|
+
}
|
|
27299
|
+
if (fontCache.has(text)) {
|
|
27300
|
+
return fontCache.get(text);
|
|
27301
|
+
}
|
|
27302
|
+
let safeText = text;
|
|
27303
|
+
try {
|
|
27304
|
+
font.encodeText(text);
|
|
27305
|
+
} catch {
|
|
27306
|
+
safeText = Array.from(text).map((char) => sanitizePdfChar(char, font)).join("");
|
|
27307
|
+
}
|
|
27308
|
+
fontCache.set(text, safeText);
|
|
27309
|
+
return safeText;
|
|
27310
|
+
}
|
|
27311
|
+
function sanitizePdfChar(char, font) {
|
|
27312
|
+
try {
|
|
27313
|
+
font.encodeText(char);
|
|
27314
|
+
return char;
|
|
27315
|
+
} catch {
|
|
27316
|
+
const directFallback = PDF_TEXT_FALLBACKS[char];
|
|
27317
|
+
if (directFallback) {
|
|
27318
|
+
return directFallback;
|
|
27319
|
+
}
|
|
27320
|
+
if (/^\s$/u.test(char)) {
|
|
27321
|
+
return " ";
|
|
27322
|
+
}
|
|
27323
|
+
const normalized = char.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^\x20-\x7E]/g, "");
|
|
27324
|
+
if (normalized) {
|
|
27325
|
+
try {
|
|
27326
|
+
font.encodeText(normalized);
|
|
27327
|
+
return normalized;
|
|
27328
|
+
} catch {
|
|
27329
|
+
return "?";
|
|
27330
|
+
}
|
|
27331
|
+
}
|
|
27332
|
+
return "?";
|
|
27333
|
+
}
|
|
27334
|
+
}
|
|
27335
|
+
function getPadding(padding) {
|
|
27336
|
+
return [padding[0] ?? 0, padding[1] ?? 0, padding[2] ?? 0, padding[3] ?? 0];
|
|
27337
|
+
}
|
|
27338
|
+
function getTitleSize(titleLevel, options) {
|
|
27339
|
+
if (!titleLevel) {
|
|
27340
|
+
return void 0;
|
|
27341
|
+
}
|
|
27342
|
+
return options.title[titleSizeMapping[titleLevel]];
|
|
27343
|
+
}
|
|
27344
|
+
function getPageNumberHeight(pageNumber) {
|
|
27345
|
+
if (pageNumber.disabled) {
|
|
27346
|
+
return 0;
|
|
27347
|
+
}
|
|
27348
|
+
return pageNumber.size || 12;
|
|
27349
|
+
}
|
|
27350
|
+
function getFooterBarHeight(footerHeight, context) {
|
|
27351
|
+
if (context.options.footer.disabled) {
|
|
27352
|
+
return 0;
|
|
27353
|
+
}
|
|
27354
|
+
return Math.max(footerHeight, pxToPt(FOOTER_MIN_BAR_HEIGHT));
|
|
27355
|
+
}
|
|
27356
|
+
function getReservedPageNumberBottom(pageNumber, pageNumberHeight) {
|
|
27357
|
+
if (pageNumber.disabled) {
|
|
27358
|
+
return 0;
|
|
27359
|
+
}
|
|
27360
|
+
return pxToPt(pageNumber.bottom + 4) + pageNumberHeight;
|
|
27361
|
+
}
|
|
27362
|
+
function normalizeText2(text = "") {
|
|
27363
|
+
return text.replace(new RegExp(ZERO, "g"), "").replace(/\r\n/g, "\n");
|
|
27364
|
+
}
|
|
27365
|
+
function normalizePdfFileName(fileName) {
|
|
27366
|
+
const trimmed = fileName?.trim();
|
|
27367
|
+
if (!trimmed) {
|
|
27368
|
+
return DEFAULT_PDF_FILE_NAME;
|
|
27369
|
+
}
|
|
27370
|
+
return trimmed.toLowerCase().endsWith(".pdf") ? trimmed : `${trimmed}.pdf`;
|
|
27371
|
+
}
|
|
27372
|
+
function pxToPt(px) {
|
|
27373
|
+
return px * (72 / 96);
|
|
27374
|
+
}
|
|
27375
|
+
function toPdfY(pageHeight, top, height = 0) {
|
|
27376
|
+
return pageHeight - top - height;
|
|
27377
|
+
}
|
|
27378
|
+
function toPdfColor(color, fallback = "#000000") {
|
|
27379
|
+
const hex = normalizeHexColor2(color || fallback, "000000") || "000000";
|
|
27380
|
+
const red = parseInt(hex.slice(0, 2), 16) / 255;
|
|
27381
|
+
const green = parseInt(hex.slice(2, 4), 16) / 255;
|
|
27382
|
+
const blue = parseInt(hex.slice(4, 6), 16) / 255;
|
|
27383
|
+
return rgb(red, green, blue);
|
|
27384
|
+
}
|
|
27385
|
+
function normalizeHexColor2(color, fallback) {
|
|
27386
|
+
const normalized = normalizeHexLiteral2(color) || normalizeRgbColor2(color) || normalizeBrowserColor2(color);
|
|
27387
|
+
if (normalized) {
|
|
27388
|
+
return normalized;
|
|
27389
|
+
}
|
|
27390
|
+
return fallback ? normalizeHexLiteral2(fallback) || void 0 : void 0;
|
|
27391
|
+
}
|
|
27392
|
+
function normalizeHexLiteral2(color) {
|
|
27393
|
+
const value = color.trim().replace(/^#/, "");
|
|
27394
|
+
if (/^[\da-f]{3}$/i.test(value)) {
|
|
27395
|
+
return value.split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
27396
|
+
}
|
|
27397
|
+
if (/^[\da-f]{4}$/i.test(value)) {
|
|
27398
|
+
return value.slice(0, 3).split("").map((part) => `${part}${part}`).join("").toUpperCase();
|
|
27399
|
+
}
|
|
27400
|
+
if (/^[\da-f]{6}$/i.test(value)) {
|
|
27401
|
+
return value.toUpperCase();
|
|
27402
|
+
}
|
|
27403
|
+
if (/^[\da-f]{8}$/i.test(value)) {
|
|
27404
|
+
return value.slice(0, 6).toUpperCase();
|
|
27405
|
+
}
|
|
27406
|
+
return void 0;
|
|
27407
|
+
}
|
|
27408
|
+
function normalizeRgbColor2(color) {
|
|
27409
|
+
const match = color.trim().match(/^rgba?\((.+)\)$/i);
|
|
27410
|
+
if (!match) {
|
|
27411
|
+
return void 0;
|
|
27412
|
+
}
|
|
27413
|
+
const parts = match[1].replace(/\s*\/\s*/g, ",").split(/\s*,\s*|\s+/).filter(Boolean);
|
|
27414
|
+
if (parts.length < 3) {
|
|
27415
|
+
return void 0;
|
|
27416
|
+
}
|
|
27417
|
+
const red = parseRgbChannel2(parts[0]);
|
|
27418
|
+
const green = parseRgbChannel2(parts[1]);
|
|
27419
|
+
const blue = parseRgbChannel2(parts[2]);
|
|
27420
|
+
if (red === null || green === null || blue === null) {
|
|
27421
|
+
return void 0;
|
|
27422
|
+
}
|
|
27423
|
+
const alpha = parts[3] !== void 0 ? parseAlphaChannel2(parts[3]) : 1;
|
|
27424
|
+
if (alpha === null || alpha <= 0) {
|
|
27425
|
+
return void 0;
|
|
27426
|
+
}
|
|
27427
|
+
const flattened = alpha >= 1 ? [red, green, blue] : [
|
|
27428
|
+
flattenChannel2(red, alpha),
|
|
27429
|
+
flattenChannel2(green, alpha),
|
|
27430
|
+
flattenChannel2(blue, alpha)
|
|
27431
|
+
];
|
|
27432
|
+
return flattened.map(toHexChannel2).join("");
|
|
27433
|
+
}
|
|
27434
|
+
function normalizeBrowserColor2(color) {
|
|
27435
|
+
if (typeof document === "undefined") {
|
|
27436
|
+
return void 0;
|
|
27437
|
+
}
|
|
27438
|
+
const canvas = document.createElement("canvas");
|
|
27439
|
+
const context = canvas.getContext("2d");
|
|
27440
|
+
if (!context) {
|
|
27441
|
+
return void 0;
|
|
27442
|
+
}
|
|
27443
|
+
context.fillStyle = "#000000";
|
|
27444
|
+
context.fillStyle = color;
|
|
27445
|
+
const normalized = context.fillStyle;
|
|
27446
|
+
if (typeof normalized !== "string") {
|
|
27447
|
+
return void 0;
|
|
27448
|
+
}
|
|
27449
|
+
return normalizeHexLiteral2(normalized) || normalizeRgbColor2(normalized);
|
|
27450
|
+
}
|
|
27451
|
+
function parseRgbChannel2(value) {
|
|
27452
|
+
if (value.endsWith("%")) {
|
|
27453
|
+
const percent = Number(value.slice(0, -1));
|
|
27454
|
+
if (!Number.isFinite(percent)) {
|
|
27455
|
+
return null;
|
|
27456
|
+
}
|
|
27457
|
+
return clampColorChannel2(Math.round(percent / 100 * 255));
|
|
27458
|
+
}
|
|
27459
|
+
const channel = Number(value);
|
|
27460
|
+
if (!Number.isFinite(channel)) {
|
|
27461
|
+
return null;
|
|
27462
|
+
}
|
|
27463
|
+
return clampColorChannel2(Math.round(channel));
|
|
27464
|
+
}
|
|
27465
|
+
function parseAlphaChannel2(value) {
|
|
27466
|
+
if (value.endsWith("%")) {
|
|
27467
|
+
const percent = Number(value.slice(0, -1));
|
|
27468
|
+
if (!Number.isFinite(percent)) {
|
|
27469
|
+
return null;
|
|
27470
|
+
}
|
|
27471
|
+
return Math.min(Math.max(percent / 100, 0), 1);
|
|
27472
|
+
}
|
|
27473
|
+
const alpha = Number(value);
|
|
27474
|
+
if (!Number.isFinite(alpha)) {
|
|
27475
|
+
return null;
|
|
27476
|
+
}
|
|
27477
|
+
return Math.min(Math.max(alpha, 0), 1);
|
|
27478
|
+
}
|
|
27479
|
+
function clampColorChannel2(value) {
|
|
27480
|
+
return Math.min(Math.max(value, 0), 255);
|
|
27481
|
+
}
|
|
27482
|
+
function flattenChannel2(value, alpha) {
|
|
27483
|
+
return clampColorChannel2(Math.round(255 * (1 - alpha) + value * alpha));
|
|
27484
|
+
}
|
|
27485
|
+
function toHexChannel2(value) {
|
|
27486
|
+
return value.toString(16).padStart(2, "0").toUpperCase();
|
|
27487
|
+
}
|
|
27488
|
+
|
|
27489
|
+
// src/utils/print.ts
|
|
27490
|
+
function convertPxToPaperSize(width, height) {
|
|
27491
|
+
if (width === 1125 && height === 1593) {
|
|
27492
|
+
return {
|
|
27493
|
+
size: "a3",
|
|
27494
|
+
width: "297mm",
|
|
27495
|
+
height: "420mm"
|
|
27496
|
+
};
|
|
27497
|
+
}
|
|
27498
|
+
if (width === 794 && height === 1123) {
|
|
27499
|
+
return {
|
|
27500
|
+
size: "a4",
|
|
27501
|
+
width: "210mm",
|
|
27502
|
+
height: "297mm"
|
|
27503
|
+
};
|
|
27504
|
+
}
|
|
27505
|
+
if (width === 565 && height === 796) {
|
|
27506
|
+
return {
|
|
27507
|
+
size: "a5",
|
|
27508
|
+
width: "148mm",
|
|
27509
|
+
height: "210mm"
|
|
27510
|
+
};
|
|
27511
|
+
}
|
|
27512
|
+
return {
|
|
27513
|
+
size: "",
|
|
27514
|
+
width: `${width}px`,
|
|
27515
|
+
height: `${height}px`
|
|
27516
|
+
};
|
|
27517
|
+
}
|
|
27518
|
+
function printImageBase64(base64List, options) {
|
|
27519
|
+
const { width, height, direction = "vertical" /* VERTICAL */ } = options;
|
|
27520
|
+
const iframe = document.createElement("iframe");
|
|
27521
|
+
iframe.style.visibility = "hidden";
|
|
27522
|
+
iframe.style.position = "absolute";
|
|
27523
|
+
iframe.style.left = "0";
|
|
27524
|
+
iframe.style.top = "0";
|
|
27525
|
+
iframe.style.width = "0";
|
|
27526
|
+
iframe.style.height = "0";
|
|
27527
|
+
iframe.style.border = "none";
|
|
27528
|
+
document.body.append(iframe);
|
|
27529
|
+
const contentWindow = iframe.contentWindow;
|
|
27530
|
+
const doc = contentWindow.document;
|
|
27531
|
+
doc.open();
|
|
27532
|
+
const container = document.createElement("div");
|
|
23994
27533
|
const paperSize = convertPxToPaperSize(width, height);
|
|
23995
27534
|
base64List.forEach((base64) => {
|
|
23996
27535
|
const image = document.createElement("img");
|
|
@@ -25159,6 +28698,16 @@ var CommandAdapt = class {
|
|
|
25159
28698
|
this.draw.setPageScale(scale);
|
|
25160
28699
|
}
|
|
25161
28700
|
}
|
|
28701
|
+
async exportDocx(payload = {}) {
|
|
28702
|
+
const result = this.draw.getValue();
|
|
28703
|
+
const { blob, fileName } = await exportEditorDataToDocx(result, payload);
|
|
28704
|
+
downloadBlob(blob, fileName);
|
|
28705
|
+
}
|
|
28706
|
+
async exportPdf(payload = {}) {
|
|
28707
|
+
const result = this.draw.getValue();
|
|
28708
|
+
const { blob, fileName } = await exportEditorDataToPdf(result, payload);
|
|
28709
|
+
downloadBlob(blob, fileName);
|
|
28710
|
+
}
|
|
25162
28711
|
replaceImageElement(payload) {
|
|
25163
28712
|
const { startIndex } = this.range.getRange();
|
|
25164
28713
|
const elementList = this.draw.getElementList();
|