@harbour-enterprises/superdoc 1.5.0-next.5 → 1.5.0-next.7
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/chunks/{PdfViewer-s90Ubj4h.es.js → PdfViewer-ClST5VR6.es.js} +2 -2
- package/dist/chunks/{PdfViewer-BsNt5K_V.cjs → PdfViewer-Cli6IR-X.cjs} +2 -2
- package/dist/chunks/{SuperConverter--XoKPr84.cjs → SuperConverter-CIjArITT.cjs} +608 -36
- package/dist/chunks/{SuperConverter-BYBgTS6T.es.js → SuperConverter-S5AfMnkn.es.js} +608 -36
- package/dist/chunks/{index-u4_Ee95y.es.js → index-7ebfCUN0.es.js} +11 -4
- package/dist/chunks/{index-H9yQJDe_.cjs → index-CbbEjpJ0.cjs} +4 -4
- package/dist/chunks/{index-hAbdauPd.cjs → index-LpMObyDy.cjs} +11 -4
- package/dist/chunks/{index-ARobn9PY.es.js → index-bw_yQ0EP.es.js} +4 -4
- package/dist/super-editor/converter.cjs +1 -1
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor.cjs +2 -2
- package/dist/super-editor.es.js +3 -3
- package/dist/superdoc.cjs +3 -3
- package/dist/superdoc.es.js +3 -3
- package/dist/superdoc.umd.js +617 -38
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +3 -3
|
@@ -3642,6 +3642,11 @@ const DEFAULT_DOCX_DEFS = {
|
|
|
3642
3642
|
"xmlns:v": "urn:schemas-microsoft-com:vml",
|
|
3643
3643
|
"xmlns:wp14": "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
|
|
3644
3644
|
"xmlns:wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
|
3645
|
+
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
3646
|
+
"xmlns:pic": "http://schemas.openxmlformats.org/drawingml/2006/picture",
|
|
3647
|
+
"xmlns:c": "http://schemas.openxmlformats.org/drawingml/2006/chart",
|
|
3648
|
+
"xmlns:dgm": "http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
|
3649
|
+
"xmlns:lc": "http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas",
|
|
3645
3650
|
"xmlns:w10": "urn:schemas-microsoft-com:office:word",
|
|
3646
3651
|
"xmlns:w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
|
3647
3652
|
"xmlns:w14": "http://schemas.microsoft.com/office/word/2010/wordml",
|
|
@@ -10086,6 +10091,11 @@ const SD_NODE_NAME$g = "tableRow";
|
|
|
10086
10091
|
const validXmlAttributes$9 = ["w:rsidDel", "w:rsidR", "w:rsidRPr", "w:rsidTr", "w14:paraId", "w14:textId"].map(
|
|
10087
10092
|
(xmlName) => createAttributeHandler(xmlName)
|
|
10088
10093
|
);
|
|
10094
|
+
const getColspan$1 = (cell) => {
|
|
10095
|
+
const rawColspan = cell?.attrs?.colspan;
|
|
10096
|
+
const numericColspan = typeof rawColspan === "string" ? parseInt(rawColspan, 10) : rawColspan;
|
|
10097
|
+
return Number.isFinite(numericColspan) && numericColspan > 0 ? numericColspan : 1;
|
|
10098
|
+
};
|
|
10089
10099
|
const encode$v = (params, encodedAttrs) => {
|
|
10090
10100
|
const { row } = params.extraParams;
|
|
10091
10101
|
let tableRowProperties = {};
|
|
@@ -10218,7 +10228,27 @@ const decode$x = (params, decodedAttrs) => {
|
|
|
10218
10228
|
}
|
|
10219
10229
|
return cell;
|
|
10220
10230
|
});
|
|
10221
|
-
|
|
10231
|
+
let trimmedContent = sanitizedCells.filter((_2, index2) => !isPlaceholderCell(trimmedSlice[index2]));
|
|
10232
|
+
const preferTableGrid = params.extraParams?.preferTableGrid === true;
|
|
10233
|
+
const totalColumns = params.extraParams?.totalColumns;
|
|
10234
|
+
if (preferTableGrid && typeof totalColumns === "number" && Number.isFinite(totalColumns) && totalColumns > 0) {
|
|
10235
|
+
const rawGridBefore = node.attrs?.tableRowProperties?.gridBefore;
|
|
10236
|
+
const numericGridBefore = typeof rawGridBefore === "string" ? parseInt(rawGridBefore, 10) : rawGridBefore;
|
|
10237
|
+
const safeGridBefore = Number.isFinite(numericGridBefore) && numericGridBefore > 0 ? numericGridBefore : 0;
|
|
10238
|
+
const effectiveGridBefore = leadingPlaceholders > 0 ? leadingPlaceholders : safeGridBefore;
|
|
10239
|
+
const availableColumns = Math.max(totalColumns - effectiveGridBefore, 0);
|
|
10240
|
+
let usedColumns = 0;
|
|
10241
|
+
const constrainedCells = [];
|
|
10242
|
+
for (const cell of trimmedContent) {
|
|
10243
|
+
const colspan = getColspan$1(cell);
|
|
10244
|
+
if (usedColumns + colspan > availableColumns) {
|
|
10245
|
+
break;
|
|
10246
|
+
}
|
|
10247
|
+
constrainedCells.push(cell);
|
|
10248
|
+
usedColumns += colspan;
|
|
10249
|
+
}
|
|
10250
|
+
trimmedContent = constrainedCells;
|
|
10251
|
+
}
|
|
10222
10252
|
const translateParams = {
|
|
10223
10253
|
...params,
|
|
10224
10254
|
node: { ...node, content: trimmedContent }
|
|
@@ -19240,9 +19270,9 @@ function handleImageNode(node, params, isAnchor) {
|
|
|
19240
19270
|
if (!blip) {
|
|
19241
19271
|
return null;
|
|
19242
19272
|
}
|
|
19243
|
-
const stretch = blipFill?.elements
|
|
19244
|
-
const fillRect = stretch?.elements
|
|
19245
|
-
const srcRect = blipFill?.elements
|
|
19273
|
+
const stretch = blipFill?.elements?.find((el) => el.name === "a:stretch");
|
|
19274
|
+
const fillRect = stretch?.elements?.find((el) => el.name === "a:fillRect");
|
|
19275
|
+
const srcRect = blipFill?.elements?.find((el) => el.name === "a:srcRect");
|
|
19246
19276
|
const srcRectAttrs = srcRect?.attributes || {};
|
|
19247
19277
|
const srcRectHasNegativeValues = ["l", "t", "r", "b"].some((attr) => {
|
|
19248
19278
|
const val = srcRectAttrs[attr];
|
|
@@ -25963,6 +25993,53 @@ const config$d = {
|
|
|
25963
25993
|
attributes: validXmlAttributes$5
|
|
25964
25994
|
};
|
|
25965
25995
|
const translator$s = NodeTranslator.from(config$d);
|
|
25996
|
+
const getColspan = (cell) => {
|
|
25997
|
+
const rawColspan = cell?.attrs?.colspan;
|
|
25998
|
+
const numericColspan = typeof rawColspan === "string" ? parseInt(rawColspan, 10) : rawColspan;
|
|
25999
|
+
return Number.isFinite(numericColspan) && numericColspan > 0 ? numericColspan : 1;
|
|
26000
|
+
};
|
|
26001
|
+
const resolveGridBefore = (row) => {
|
|
26002
|
+
const rawGridBefore = row?.attrs?.tableRowProperties?.gridBefore ?? row?.attrs?.gridBefore;
|
|
26003
|
+
const numericGridBefore = typeof rawGridBefore === "string" ? parseInt(rawGridBefore, 10) : rawGridBefore;
|
|
26004
|
+
if (!Number.isFinite(numericGridBefore) || numericGridBefore <= 0) return 0;
|
|
26005
|
+
const cells = Array.isArray(row.content) ? row.content : [];
|
|
26006
|
+
let leadingGridBefore = 0;
|
|
26007
|
+
while (leadingGridBefore < cells.length && cells[leadingGridBefore]?.attrs?.__placeholder === "gridBefore") {
|
|
26008
|
+
leadingGridBefore += 1;
|
|
26009
|
+
}
|
|
26010
|
+
return leadingGridBefore > 0 ? 0 : numericGridBefore;
|
|
26011
|
+
};
|
|
26012
|
+
const advanceColumnsForCell = (columnIndex, cell) => columnIndex + getColspan(cell);
|
|
26013
|
+
const getCellStartColumn = (row, targetCell) => {
|
|
26014
|
+
const cells = Array.isArray(row.content) ? row.content : [];
|
|
26015
|
+
let columnIndex = resolveGridBefore(row);
|
|
26016
|
+
for (const cell of cells) {
|
|
26017
|
+
if (cell === targetCell) return columnIndex;
|
|
26018
|
+
columnIndex = advanceColumnsForCell(columnIndex, cell);
|
|
26019
|
+
}
|
|
26020
|
+
return columnIndex;
|
|
26021
|
+
};
|
|
26022
|
+
const findCellCoveringColumn = (row, targetColumn) => {
|
|
26023
|
+
const cells = Array.isArray(row.content) ? row.content : [];
|
|
26024
|
+
let columnIndex = resolveGridBefore(row);
|
|
26025
|
+
for (const cell of cells) {
|
|
26026
|
+
const colspan = getColspan(cell);
|
|
26027
|
+
if (targetColumn >= columnIndex && targetColumn < columnIndex + colspan) {
|
|
26028
|
+
return cell;
|
|
26029
|
+
}
|
|
26030
|
+
columnIndex = advanceColumnsForCell(columnIndex, cell);
|
|
26031
|
+
}
|
|
26032
|
+
return null;
|
|
26033
|
+
};
|
|
26034
|
+
const findInsertionIndexForColumn = (row, targetColumn) => {
|
|
26035
|
+
const cells = Array.isArray(row.content) ? row.content : [];
|
|
26036
|
+
let columnIndex = resolveGridBefore(row);
|
|
26037
|
+
for (let index2 = 0; index2 < cells.length; index2++) {
|
|
26038
|
+
if (columnIndex >= targetColumn) return index2;
|
|
26039
|
+
columnIndex = advanceColumnsForCell(columnIndex, cells[index2]);
|
|
26040
|
+
}
|
|
26041
|
+
return cells.length;
|
|
26042
|
+
};
|
|
25966
26043
|
function preProcessVerticalMergeCells(table, { editorSchema }) {
|
|
25967
26044
|
if (!table || !Array.isArray(table.content)) {
|
|
25968
26045
|
return table;
|
|
@@ -25978,15 +26055,17 @@ function preProcessVerticalMergeCells(table, { editorSchema }) {
|
|
|
25978
26055
|
const cell = row.content[cellIndex];
|
|
25979
26056
|
if (!cell) continue;
|
|
25980
26057
|
const attrs = cell.attrs || {};
|
|
25981
|
-
|
|
25982
|
-
|
|
26058
|
+
const rawRowspan = typeof attrs.rowspan === "string" ? parseInt(attrs.rowspan, 10) : attrs.rowspan;
|
|
26059
|
+
if (!Number.isFinite(rawRowspan) || rawRowspan <= 1) continue;
|
|
26060
|
+
const maxRowspan = Math.min(rawRowspan, rows.length - rowIndex);
|
|
26061
|
+
const startColumn = getCellStartColumn(row, cell);
|
|
25983
26062
|
for (let offset = 1; offset < maxRowspan; offset++) {
|
|
25984
26063
|
const rowToChange = rows[rowIndex + offset];
|
|
25985
26064
|
if (!rowToChange) continue;
|
|
25986
26065
|
if (!Array.isArray(rowToChange.content)) {
|
|
25987
26066
|
rowToChange.content = [];
|
|
25988
26067
|
}
|
|
25989
|
-
const existingCell = rowToChange
|
|
26068
|
+
const existingCell = findCellCoveringColumn(rowToChange, startColumn);
|
|
25990
26069
|
if (existingCell?.attrs?.continueMerge) continue;
|
|
25991
26070
|
const mergedCell = {
|
|
25992
26071
|
type: cell.type,
|
|
@@ -25997,7 +26076,8 @@ function preProcessVerticalMergeCells(table, { editorSchema }) {
|
|
|
25997
26076
|
continueMerge: true
|
|
25998
26077
|
}
|
|
25999
26078
|
};
|
|
26000
|
-
rowToChange
|
|
26079
|
+
const insertionIndex = findInsertionIndexForColumn(rowToChange, startColumn);
|
|
26080
|
+
rowToChange.content.splice(insertionIndex, 0, mergedCell);
|
|
26001
26081
|
}
|
|
26002
26082
|
}
|
|
26003
26083
|
}
|
|
@@ -26149,15 +26229,24 @@ const encode$q = (params) => {
|
|
|
26149
26229
|
const decode$s = (params) => {
|
|
26150
26230
|
const { grid: rawGrid } = params.node.attrs || {};
|
|
26151
26231
|
const grid = Array.isArray(rawGrid) ? rawGrid : [];
|
|
26152
|
-
const { firstRow = {} } = params.extraParams || {};
|
|
26232
|
+
const { firstRow = {}, preferTableGrid = false, totalColumns: requestedColumns } = params.extraParams || {};
|
|
26153
26233
|
const cellNodes = firstRow.content?.filter((n) => n.type === "tableCell") ?? [];
|
|
26154
|
-
|
|
26234
|
+
let colWidthsFromCellNodes = cellNodes.flatMap((cell) => {
|
|
26155
26235
|
const spanCount = Math.max(1, cell?.attrs?.colspan ?? 1);
|
|
26156
26236
|
const colwidth = cell.attrs?.colwidth;
|
|
26157
26237
|
return Array.from({ length: spanCount }).map((_2, span) => Array.isArray(colwidth) ? colwidth[span] : void 0);
|
|
26158
26238
|
});
|
|
26159
26239
|
const columnCountFromCells = colWidthsFromCellNodes.length;
|
|
26160
|
-
const
|
|
26240
|
+
const gridColumnCount = grid.length;
|
|
26241
|
+
let totalColumns = Math.max(columnCountFromCells, gridColumnCount);
|
|
26242
|
+
if (typeof requestedColumns === "number" && Number.isFinite(requestedColumns) && requestedColumns > 0) {
|
|
26243
|
+
totalColumns = requestedColumns;
|
|
26244
|
+
} else if (preferTableGrid && gridColumnCount > 0) {
|
|
26245
|
+
totalColumns = gridColumnCount;
|
|
26246
|
+
}
|
|
26247
|
+
if (colWidthsFromCellNodes.length > totalColumns) {
|
|
26248
|
+
colWidthsFromCellNodes = colWidthsFromCellNodes.slice(0, totalColumns);
|
|
26249
|
+
}
|
|
26161
26250
|
const fallbackColumnWidthTwips = resolveFallbackColumnWidthTwips(params, totalColumns, cellMinWidth);
|
|
26162
26251
|
const elements = [];
|
|
26163
26252
|
const pushColumn = (widthTwips, { enforceMinimum = false } = {}) => {
|
|
@@ -26417,22 +26506,31 @@ const encode$p = (params, encodedAttrs) => {
|
|
|
26417
26506
|
const decode$r = (params, decodedAttrs) => {
|
|
26418
26507
|
params.node = preProcessVerticalMergeCells(params.node, params);
|
|
26419
26508
|
const { node } = params;
|
|
26420
|
-
const
|
|
26509
|
+
const rawGrid = node.attrs?.grid;
|
|
26510
|
+
const grid = Array.isArray(rawGrid) ? rawGrid : [];
|
|
26511
|
+
const preferTableGrid = node.attrs?.userEdited !== true && grid.length > 0;
|
|
26512
|
+
const totalColumns = preferTableGrid ? grid.length : void 0;
|
|
26513
|
+
const extraParams = {
|
|
26514
|
+
...params.extraParams || {},
|
|
26515
|
+
preferTableGrid,
|
|
26516
|
+
totalColumns
|
|
26517
|
+
};
|
|
26518
|
+
const elements = translateChildNodes({ ...params, extraParams });
|
|
26421
26519
|
const firstRow = node.content?.find((n) => n.type === "tableRow");
|
|
26422
|
-
const properties = node.attrs.grid;
|
|
26423
26520
|
const element = translator$c.decode({
|
|
26424
26521
|
...params,
|
|
26425
|
-
node: { ...node, attrs: { ...node.attrs, grid
|
|
26522
|
+
node: { ...node, attrs: { ...node.attrs, grid } },
|
|
26426
26523
|
extraParams: {
|
|
26524
|
+
...extraParams,
|
|
26427
26525
|
firstRow
|
|
26428
26526
|
}
|
|
26429
26527
|
});
|
|
26430
26528
|
if (element) elements.unshift(element);
|
|
26431
26529
|
if (node.attrs?.tableProperties) {
|
|
26432
|
-
const
|
|
26530
|
+
const properties = { ...node.attrs.tableProperties };
|
|
26433
26531
|
const element2 = translator$e.decode({
|
|
26434
26532
|
...params,
|
|
26435
|
-
node: { ...node, attrs: { ...node.attrs, tableProperties:
|
|
26533
|
+
node: { ...node, attrs: { ...node.attrs, tableProperties: properties } }
|
|
26436
26534
|
});
|
|
26437
26535
|
if (element2) elements.unshift(element2);
|
|
26438
26536
|
}
|
|
@@ -30033,7 +30131,7 @@ function buildStyles(styleObject) {
|
|
|
30033
30131
|
}
|
|
30034
30132
|
return style;
|
|
30035
30133
|
}
|
|
30036
|
-
function
|
|
30134
|
+
function handleShapeImageWatermarkImport({ params, pict }) {
|
|
30037
30135
|
const shape = pict.elements?.find((el) => el.name === "v:shape");
|
|
30038
30136
|
if (!shape) return null;
|
|
30039
30137
|
const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
|
|
@@ -30059,7 +30157,7 @@ function handleShapeImageImport({ params, pict }) {
|
|
|
30059
30157
|
const targetPath = rel.attributes["Target"];
|
|
30060
30158
|
const normalizedPath = normalizeTargetPath(targetPath);
|
|
30061
30159
|
const style = shapeAttrs.style || "";
|
|
30062
|
-
const styleObj = parseVmlStyle(style);
|
|
30160
|
+
const styleObj = parseVmlStyle$1(style);
|
|
30063
30161
|
const width = styleObj.width || "100px";
|
|
30064
30162
|
const height = styleObj.height || "100px";
|
|
30065
30163
|
const position = {
|
|
@@ -30105,12 +30203,12 @@ function handleShapeImageImport({ params, pict }) {
|
|
|
30105
30203
|
},
|
|
30106
30204
|
// Size
|
|
30107
30205
|
size: {
|
|
30108
|
-
width: convertToPixels(width),
|
|
30109
|
-
height: convertToPixels(height)
|
|
30206
|
+
width: convertToPixels$1(width),
|
|
30207
|
+
height: convertToPixels$1(height)
|
|
30110
30208
|
},
|
|
30111
30209
|
marginOffset: {
|
|
30112
|
-
horizontal: convertToPixels(position.marginLeft),
|
|
30113
|
-
top: convertToPixels(position.marginTop)
|
|
30210
|
+
horizontal: convertToPixels$1(position.marginLeft),
|
|
30211
|
+
top: convertToPixels$1(position.marginTop)
|
|
30114
30212
|
},
|
|
30115
30213
|
// Image adjustments
|
|
30116
30214
|
...gain && { gain },
|
|
@@ -30126,7 +30224,7 @@ function normalizeTargetPath(targetPath = "") {
|
|
|
30126
30224
|
if (trimmed.startsWith("media/")) return `word/${trimmed}`;
|
|
30127
30225
|
return `word/${trimmed}`;
|
|
30128
30226
|
}
|
|
30129
|
-
function parseVmlStyle(style) {
|
|
30227
|
+
function parseVmlStyle$1(style) {
|
|
30130
30228
|
const result = {};
|
|
30131
30229
|
if (!style) return result;
|
|
30132
30230
|
const declarations = style.split(";").filter((s) => s.trim());
|
|
@@ -30138,6 +30236,267 @@ function parseVmlStyle(style) {
|
|
|
30138
30236
|
}
|
|
30139
30237
|
return result;
|
|
30140
30238
|
}
|
|
30239
|
+
function convertToPixels$1(value) {
|
|
30240
|
+
if (typeof value === "number") return value;
|
|
30241
|
+
if (!value || typeof value !== "string") return 0;
|
|
30242
|
+
const match = value.match(/^([\d.]+)([a-z%]+)?$/i);
|
|
30243
|
+
if (!match) return 0;
|
|
30244
|
+
const num = parseFloat(match[1]);
|
|
30245
|
+
const unit = match[2] || "px";
|
|
30246
|
+
switch (unit.toLowerCase()) {
|
|
30247
|
+
case "px":
|
|
30248
|
+
return num;
|
|
30249
|
+
case "pt":
|
|
30250
|
+
return num * (96 / 72);
|
|
30251
|
+
// 1pt = 1/72 inch, 96 DPI
|
|
30252
|
+
case "in":
|
|
30253
|
+
return num * 96;
|
|
30254
|
+
case "cm":
|
|
30255
|
+
return num * (96 / 2.54);
|
|
30256
|
+
case "mm":
|
|
30257
|
+
return num * (96 / 25.4);
|
|
30258
|
+
case "pc":
|
|
30259
|
+
return num * 16;
|
|
30260
|
+
// 1pc = 12pt
|
|
30261
|
+
default:
|
|
30262
|
+
return num;
|
|
30263
|
+
}
|
|
30264
|
+
}
|
|
30265
|
+
function handleShapeTextWatermarkImport({ pict }) {
|
|
30266
|
+
const shape = pict.elements?.find((el) => el.name === "v:shape");
|
|
30267
|
+
if (!shape) return null;
|
|
30268
|
+
const textpath = shape.elements?.find((el) => el.name === "v:textpath");
|
|
30269
|
+
if (!textpath) return null;
|
|
30270
|
+
const shapeAttrs = shape.attributes || {};
|
|
30271
|
+
const textpathAttrs = textpath.attributes || {};
|
|
30272
|
+
const watermarkText = textpathAttrs["string"] || "";
|
|
30273
|
+
if (!watermarkText) {
|
|
30274
|
+
console.warn("v:textpath missing string attribute");
|
|
30275
|
+
return null;
|
|
30276
|
+
}
|
|
30277
|
+
const style = shapeAttrs.style || "";
|
|
30278
|
+
const styleObj = parseVmlStyle(style);
|
|
30279
|
+
const width = styleObj.width || "481.8pt";
|
|
30280
|
+
const height = styleObj.height || "82.8pt";
|
|
30281
|
+
const position = {
|
|
30282
|
+
type: styleObj.position || "absolute",
|
|
30283
|
+
marginLeft: styleObj["margin-left"] || "0",
|
|
30284
|
+
marginTop: styleObj["margin-top"] || "0"
|
|
30285
|
+
};
|
|
30286
|
+
const rotation = parseFloat(styleObj.rotation) || 0;
|
|
30287
|
+
const hPosition = styleObj["mso-position-horizontal"] || "center";
|
|
30288
|
+
const vPosition = styleObj["mso-position-vertical"] || "center";
|
|
30289
|
+
const hRelativeTo = styleObj["mso-position-horizontal-relative"] || "margin";
|
|
30290
|
+
const vRelativeTo = styleObj["mso-position-vertical-relative"] || "margin";
|
|
30291
|
+
const textAnchor = styleObj["v-text-anchor"] || "middle";
|
|
30292
|
+
const fill = shape.elements?.find((el) => el.name === "v:fill");
|
|
30293
|
+
const fillAttrs = fill?.attributes || {};
|
|
30294
|
+
const rawFillColor = shapeAttrs.fillcolor || fillAttrs.color || "silver";
|
|
30295
|
+
const rawFillColor2 = fillAttrs.color2 || "#3f3f3f";
|
|
30296
|
+
const fillColor = sanitizeColor(rawFillColor, "silver");
|
|
30297
|
+
const fillColor2 = sanitizeColor(rawFillColor2, "#3f3f3f");
|
|
30298
|
+
const opacity = fillAttrs.opacity || "0.5";
|
|
30299
|
+
const fillType = fillAttrs.type || "solid";
|
|
30300
|
+
const stroke = shape.elements?.find((el) => el.name === "v:stroke");
|
|
30301
|
+
const strokeAttrs = stroke?.attributes || {};
|
|
30302
|
+
const stroked = shapeAttrs.stroked || "f";
|
|
30303
|
+
const strokeColor = strokeAttrs.color || "#3465a4";
|
|
30304
|
+
const strokeJoinstyle = strokeAttrs.joinstyle || "round";
|
|
30305
|
+
const strokeEndcap = strokeAttrs.endcap || "flat";
|
|
30306
|
+
const textpathStyle = textpathAttrs.style || "";
|
|
30307
|
+
const textStyleObj = parseVmlStyle(textpathStyle);
|
|
30308
|
+
const rawFontFamily = textStyleObj["font-family"]?.replace(/['"]/g, "");
|
|
30309
|
+
const fontFamily = sanitizeFontFamily(rawFontFamily);
|
|
30310
|
+
const fontSize = textStyleObj["font-size"] || "1pt";
|
|
30311
|
+
const fitshape = textpathAttrs.fitshape || "t";
|
|
30312
|
+
const trim = textpathAttrs.trim || "t";
|
|
30313
|
+
const textpathOn = textpathAttrs.on || "t";
|
|
30314
|
+
const path = shape.elements?.find((el) => el.name === "v:path");
|
|
30315
|
+
const pathAttrs = path?.attributes || {};
|
|
30316
|
+
const textpathok = pathAttrs.textpathok || "t";
|
|
30317
|
+
const wrap2 = shape.elements?.find((el) => el.name === "w10:wrap");
|
|
30318
|
+
const wrapAttrs = wrap2?.attributes || {};
|
|
30319
|
+
const wrapType = wrapAttrs.type || "none";
|
|
30320
|
+
const widthPx = convertToPixels(width);
|
|
30321
|
+
const heightPx = convertToPixels(height);
|
|
30322
|
+
const sanitizedOpacity = sanitizeNumeric(parseFloat(opacity), 0.5, 0, 1);
|
|
30323
|
+
const sanitizedRotation = sanitizeNumeric(rotation, 0, -360, 360);
|
|
30324
|
+
const svgResult = generateTextWatermarkSVG({
|
|
30325
|
+
text: watermarkText,
|
|
30326
|
+
width: widthPx,
|
|
30327
|
+
height: heightPx,
|
|
30328
|
+
rotation: sanitizedRotation,
|
|
30329
|
+
fill: {
|
|
30330
|
+
color: fillColor,
|
|
30331
|
+
opacity: sanitizedOpacity
|
|
30332
|
+
},
|
|
30333
|
+
textStyle: {
|
|
30334
|
+
fontFamily,
|
|
30335
|
+
fontSize
|
|
30336
|
+
}
|
|
30337
|
+
});
|
|
30338
|
+
const svgDataUri = svgResult.dataUri;
|
|
30339
|
+
const imageWatermarkNode = {
|
|
30340
|
+
type: "image",
|
|
30341
|
+
attrs: {
|
|
30342
|
+
src: svgDataUri,
|
|
30343
|
+
alt: watermarkText,
|
|
30344
|
+
title: watermarkText,
|
|
30345
|
+
extension: "svg",
|
|
30346
|
+
// Mark this as a text watermark for export
|
|
30347
|
+
vmlWatermark: true,
|
|
30348
|
+
vmlTextWatermark: true,
|
|
30349
|
+
// Store VML-specific attributes for round-trip
|
|
30350
|
+
vmlStyle: style,
|
|
30351
|
+
vmlAttributes: shapeAttrs,
|
|
30352
|
+
vmlTextpathAttributes: textpathAttrs,
|
|
30353
|
+
vmlPathAttributes: pathAttrs,
|
|
30354
|
+
vmlFillAttributes: fillAttrs,
|
|
30355
|
+
vmlStrokeAttributes: strokeAttrs,
|
|
30356
|
+
vmlWrapAttributes: wrapAttrs,
|
|
30357
|
+
// Positioning (same as image watermarks)
|
|
30358
|
+
isAnchor: true,
|
|
30359
|
+
inline: false,
|
|
30360
|
+
wrap: {
|
|
30361
|
+
type: wrapType === "none" ? "None" : wrapType,
|
|
30362
|
+
attrs: {
|
|
30363
|
+
behindDoc: true
|
|
30364
|
+
}
|
|
30365
|
+
},
|
|
30366
|
+
anchorData: {
|
|
30367
|
+
hRelativeFrom: hRelativeTo,
|
|
30368
|
+
vRelativeFrom: vRelativeTo,
|
|
30369
|
+
alignH: hPosition,
|
|
30370
|
+
alignV: vPosition
|
|
30371
|
+
},
|
|
30372
|
+
// Size - use rotated bounding box dimensions to prevent clipping
|
|
30373
|
+
size: {
|
|
30374
|
+
width: svgResult.svgWidth,
|
|
30375
|
+
height: svgResult.svgHeight
|
|
30376
|
+
},
|
|
30377
|
+
marginOffset: {
|
|
30378
|
+
horizontal: convertToPixels(position.marginLeft),
|
|
30379
|
+
// For center-aligned watermarks relative to margin, Word's margin-top value
|
|
30380
|
+
// is not suitable for browser rendering. Set to 0 to let center alignment work.
|
|
30381
|
+
top: vPosition === "center" && vRelativeTo === "margin" ? 0 : convertToPixels(position.marginTop)
|
|
30382
|
+
},
|
|
30383
|
+
// Store text watermark specific data for export
|
|
30384
|
+
textWatermarkData: {
|
|
30385
|
+
text: watermarkText,
|
|
30386
|
+
rotation: sanitizedRotation,
|
|
30387
|
+
textStyle: {
|
|
30388
|
+
fontFamily,
|
|
30389
|
+
fontSize,
|
|
30390
|
+
textAnchor
|
|
30391
|
+
},
|
|
30392
|
+
fill: {
|
|
30393
|
+
color: fillColor,
|
|
30394
|
+
color2: fillColor2,
|
|
30395
|
+
opacity: sanitizedOpacity,
|
|
30396
|
+
type: fillType
|
|
30397
|
+
},
|
|
30398
|
+
stroke: {
|
|
30399
|
+
enabled: stroked !== "f",
|
|
30400
|
+
color: strokeColor,
|
|
30401
|
+
joinstyle: strokeJoinstyle,
|
|
30402
|
+
endcap: strokeEndcap
|
|
30403
|
+
},
|
|
30404
|
+
textpath: {
|
|
30405
|
+
on: textpathOn === "t",
|
|
30406
|
+
fitshape: fitshape === "t",
|
|
30407
|
+
trim: trim === "t",
|
|
30408
|
+
textpathok: textpathok === "t"
|
|
30409
|
+
}
|
|
30410
|
+
}
|
|
30411
|
+
}
|
|
30412
|
+
};
|
|
30413
|
+
return imageWatermarkNode;
|
|
30414
|
+
}
|
|
30415
|
+
function sanitizeFontFamily(fontFamily) {
|
|
30416
|
+
if (!fontFamily || typeof fontFamily !== "string") {
|
|
30417
|
+
return "Arial";
|
|
30418
|
+
}
|
|
30419
|
+
const sanitized = fontFamily.replace(/[^a-zA-Z0-9\s,\-]/g, "").trim();
|
|
30420
|
+
return sanitized || "Arial";
|
|
30421
|
+
}
|
|
30422
|
+
function sanitizeColor(color, defaultColor = "silver") {
|
|
30423
|
+
if (!color || typeof color !== "string") {
|
|
30424
|
+
return defaultColor;
|
|
30425
|
+
}
|
|
30426
|
+
const sanitized = color.replace(/[^a-zA-Z0-9#%(),.]/g, "").trim();
|
|
30427
|
+
return sanitized || defaultColor;
|
|
30428
|
+
}
|
|
30429
|
+
function sanitizeNumeric(value, defaultValue, min = -Infinity, max = Infinity) {
|
|
30430
|
+
const num = typeof value === "number" ? value : parseFloat(value);
|
|
30431
|
+
if (isNaN(num) || !isFinite(num)) {
|
|
30432
|
+
return defaultValue;
|
|
30433
|
+
}
|
|
30434
|
+
return Math.max(min, Math.min(max, num));
|
|
30435
|
+
}
|
|
30436
|
+
function generateTextWatermarkSVG({ text, width, height, rotation, fill, textStyle }) {
|
|
30437
|
+
let fontSize = height * 0.9;
|
|
30438
|
+
if (textStyle?.fontSize && textStyle.fontSize.trim() !== "1pt") {
|
|
30439
|
+
const match = textStyle.fontSize.match(/^([\d.]+)(pt|px)?$/);
|
|
30440
|
+
if (match) {
|
|
30441
|
+
const value = parseFloat(match[1]);
|
|
30442
|
+
const unit = match[2] || "pt";
|
|
30443
|
+
fontSize = (unit === "pt" ? value * (96 / 72) : value) * 50;
|
|
30444
|
+
}
|
|
30445
|
+
}
|
|
30446
|
+
fontSize = Math.max(fontSize, 48);
|
|
30447
|
+
const color = sanitizeColor(fill?.color, "silver");
|
|
30448
|
+
const opacity = sanitizeNumeric(fill?.opacity, 0.5, 0, 1);
|
|
30449
|
+
const fontFamily = sanitizeFontFamily(textStyle?.fontFamily);
|
|
30450
|
+
const sanitizedRotation = sanitizeNumeric(rotation, 0, -360, 360);
|
|
30451
|
+
const sanitizedWidth = sanitizeNumeric(width, 100, 1, 1e4);
|
|
30452
|
+
const sanitizedHeight = sanitizeNumeric(height, 100, 1, 1e4);
|
|
30453
|
+
const sanitizedFontSize = sanitizeNumeric(fontSize, 48, 1, 1e3);
|
|
30454
|
+
const radians = sanitizedRotation * Math.PI / 180;
|
|
30455
|
+
const cos = Math.abs(Math.cos(radians));
|
|
30456
|
+
const sin = Math.abs(Math.sin(radians));
|
|
30457
|
+
const rotatedWidth = sanitizedWidth * cos + sanitizedHeight * sin;
|
|
30458
|
+
const rotatedHeight = sanitizedWidth * sin + sanitizedHeight * cos;
|
|
30459
|
+
const svgWidth = Math.max(sanitizedWidth, rotatedWidth);
|
|
30460
|
+
const svgHeight = Math.max(sanitizedHeight, rotatedHeight);
|
|
30461
|
+
const centerX = svgWidth / 2;
|
|
30462
|
+
const centerY = svgHeight / 2;
|
|
30463
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${svgWidth}" height="${svgHeight}" viewBox="0 0 ${svgWidth} ${svgHeight}">
|
|
30464
|
+
<text
|
|
30465
|
+
x="${centerX}"
|
|
30466
|
+
y="${centerY}"
|
|
30467
|
+
text-anchor="middle"
|
|
30468
|
+
dominant-baseline="middle"
|
|
30469
|
+
font-family="${fontFamily}"
|
|
30470
|
+
font-size="${sanitizedFontSize}px"
|
|
30471
|
+
font-weight="bold"
|
|
30472
|
+
fill="${color}"
|
|
30473
|
+
opacity="${opacity}"
|
|
30474
|
+
transform="rotate(${sanitizedRotation} ${centerX} ${centerY})">${escapeXml(text)}</text>
|
|
30475
|
+
</svg>`;
|
|
30476
|
+
return {
|
|
30477
|
+
dataUri: `data:image/svg+xml,${encodeURIComponent(svg)}`,
|
|
30478
|
+
svgWidth,
|
|
30479
|
+
svgHeight
|
|
30480
|
+
};
|
|
30481
|
+
}
|
|
30482
|
+
function escapeXml(text) {
|
|
30483
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
30484
|
+
}
|
|
30485
|
+
function parseVmlStyle(style) {
|
|
30486
|
+
const result = {};
|
|
30487
|
+
if (!style) return result;
|
|
30488
|
+
const declarations = style.split(";").filter((s) => s.trim());
|
|
30489
|
+
for (const decl of declarations) {
|
|
30490
|
+
const colonIndex = decl.indexOf(":");
|
|
30491
|
+
if (colonIndex === -1) continue;
|
|
30492
|
+
const prop = decl.substring(0, colonIndex).trim();
|
|
30493
|
+
const value = decl.substring(colonIndex + 1).trim();
|
|
30494
|
+
if (prop && value) {
|
|
30495
|
+
result[prop] = value;
|
|
30496
|
+
}
|
|
30497
|
+
}
|
|
30498
|
+
return result;
|
|
30499
|
+
}
|
|
30141
30500
|
function convertToPixels(value) {
|
|
30142
30501
|
if (typeof value === "number") return value;
|
|
30143
30502
|
if (!value || typeof value !== "string") return 0;
|
|
@@ -30182,9 +30541,13 @@ function pictNodeTypeStrategy(node) {
|
|
|
30182
30541
|
if (textbox) {
|
|
30183
30542
|
return { type: "shapeContainer", handler: handleShapeTextboxImport };
|
|
30184
30543
|
}
|
|
30544
|
+
const textpath = shape.elements?.find((el) => el.name === "v:textpath");
|
|
30545
|
+
if (textpath) {
|
|
30546
|
+
return { type: "image", handler: handleShapeTextWatermarkImport };
|
|
30547
|
+
}
|
|
30185
30548
|
const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
|
|
30186
30549
|
if (imagedata) {
|
|
30187
|
-
return { type: "image", handler:
|
|
30550
|
+
return { type: "image", handler: handleShapeImageWatermarkImport };
|
|
30188
30551
|
}
|
|
30189
30552
|
}
|
|
30190
30553
|
return { type: "unknown", handler: null };
|
|
@@ -30284,7 +30647,7 @@ function translateVRectContentBlock(params) {
|
|
|
30284
30647
|
};
|
|
30285
30648
|
return wrapTextInRun(pict);
|
|
30286
30649
|
}
|
|
30287
|
-
function
|
|
30650
|
+
function translateImageWatermark(params) {
|
|
30288
30651
|
const { node } = params;
|
|
30289
30652
|
const { attrs } = node;
|
|
30290
30653
|
if (attrs.vmlAttributes && attrs.vmlImagedata) {
|
|
@@ -30314,7 +30677,7 @@ function translateVmlWatermark(params) {
|
|
|
30314
30677
|
};
|
|
30315
30678
|
return par2;
|
|
30316
30679
|
}
|
|
30317
|
-
const style = buildVmlStyle(attrs);
|
|
30680
|
+
const style = buildVmlStyle$1(attrs);
|
|
30318
30681
|
const shape = {
|
|
30319
30682
|
name: "v:shape",
|
|
30320
30683
|
attributes: {
|
|
@@ -30349,23 +30712,23 @@ function translateVmlWatermark(params) {
|
|
|
30349
30712
|
};
|
|
30350
30713
|
return par;
|
|
30351
30714
|
}
|
|
30352
|
-
function buildVmlStyle(attrs) {
|
|
30715
|
+
function buildVmlStyle$1(attrs) {
|
|
30353
30716
|
const styles = [];
|
|
30354
30717
|
styles.push("position:absolute");
|
|
30355
30718
|
if (attrs.size) {
|
|
30356
30719
|
if (attrs.size.width) {
|
|
30357
|
-
styles.push(`width:${convertToPt(attrs.size.width)}pt`);
|
|
30720
|
+
styles.push(`width:${convertToPt$1(attrs.size.width)}pt`);
|
|
30358
30721
|
}
|
|
30359
30722
|
if (attrs.size.height) {
|
|
30360
|
-
styles.push(`height:${convertToPt(attrs.size.height)}pt`);
|
|
30723
|
+
styles.push(`height:${convertToPt$1(attrs.size.height)}pt`);
|
|
30361
30724
|
}
|
|
30362
30725
|
}
|
|
30363
30726
|
if (attrs.marginOffset) {
|
|
30364
30727
|
if (attrs.marginOffset.horizontal !== void 0) {
|
|
30365
|
-
styles.push(`margin-left:${convertToPt(attrs.marginOffset.horizontal)}pt`);
|
|
30728
|
+
styles.push(`margin-left:${convertToPt$1(attrs.marginOffset.horizontal)}pt`);
|
|
30366
30729
|
}
|
|
30367
30730
|
if (attrs.marginOffset.top !== void 0) {
|
|
30368
|
-
styles.push(`margin-top:${convertToPt(attrs.marginOffset.top)}pt`);
|
|
30731
|
+
styles.push(`margin-top:${convertToPt$1(attrs.marginOffset.top)}pt`);
|
|
30369
30732
|
}
|
|
30370
30733
|
}
|
|
30371
30734
|
if (attrs.wrap?.attrs?.behindDoc) {
|
|
@@ -30389,9 +30752,215 @@ function buildVmlStyle(attrs) {
|
|
|
30389
30752
|
styles.push("mso-height-percent:0");
|
|
30390
30753
|
return styles.join(";");
|
|
30391
30754
|
}
|
|
30392
|
-
function convertToPt(pixels) {
|
|
30755
|
+
function convertToPt$1(pixels) {
|
|
30393
30756
|
return pixels * 72 / 96;
|
|
30394
30757
|
}
|
|
30758
|
+
function translateTextWatermark(params) {
|
|
30759
|
+
const { node } = params;
|
|
30760
|
+
const { attrs } = node;
|
|
30761
|
+
const text = attrs.textWatermarkData?.text || attrs.vmlTextpathAttributes?.string || "";
|
|
30762
|
+
if (attrs.vmlAttributes && attrs.vmlTextpathAttributes) {
|
|
30763
|
+
const shapeElements2 = [];
|
|
30764
|
+
if (attrs.vmlPathAttributes) {
|
|
30765
|
+
shapeElements2.push({
|
|
30766
|
+
name: "v:path",
|
|
30767
|
+
attributes: attrs.vmlPathAttributes
|
|
30768
|
+
});
|
|
30769
|
+
}
|
|
30770
|
+
shapeElements2.push({
|
|
30771
|
+
name: "v:textpath",
|
|
30772
|
+
attributes: {
|
|
30773
|
+
...attrs.vmlTextpathAttributes,
|
|
30774
|
+
string: text
|
|
30775
|
+
}
|
|
30776
|
+
});
|
|
30777
|
+
if (attrs.vmlFillAttributes && Object.keys(attrs.vmlFillAttributes).length > 0) {
|
|
30778
|
+
shapeElements2.push({
|
|
30779
|
+
name: "v:fill",
|
|
30780
|
+
attributes: attrs.vmlFillAttributes
|
|
30781
|
+
});
|
|
30782
|
+
}
|
|
30783
|
+
if (attrs.vmlStrokeAttributes && Object.keys(attrs.vmlStrokeAttributes).length > 0) {
|
|
30784
|
+
shapeElements2.push({
|
|
30785
|
+
name: "v:stroke",
|
|
30786
|
+
attributes: attrs.vmlStrokeAttributes
|
|
30787
|
+
});
|
|
30788
|
+
}
|
|
30789
|
+
if (attrs.vmlWrapAttributes) {
|
|
30790
|
+
shapeElements2.push({
|
|
30791
|
+
name: "w10:wrap",
|
|
30792
|
+
attributes: attrs.vmlWrapAttributes
|
|
30793
|
+
});
|
|
30794
|
+
}
|
|
30795
|
+
const shape2 = {
|
|
30796
|
+
name: "v:shape",
|
|
30797
|
+
attributes: attrs.vmlAttributes,
|
|
30798
|
+
elements: shapeElements2
|
|
30799
|
+
};
|
|
30800
|
+
const pict2 = {
|
|
30801
|
+
name: "w:pict",
|
|
30802
|
+
elements: [shape2]
|
|
30803
|
+
};
|
|
30804
|
+
const par2 = {
|
|
30805
|
+
name: "w:p",
|
|
30806
|
+
elements: [wrapTextInRun(pict2)]
|
|
30807
|
+
};
|
|
30808
|
+
return par2;
|
|
30809
|
+
}
|
|
30810
|
+
const wmData = attrs.textWatermarkData || {};
|
|
30811
|
+
const style = buildVmlStyle(attrs, wmData);
|
|
30812
|
+
const textpathStyle = buildTextpathStyle(wmData);
|
|
30813
|
+
const shapeElements = [];
|
|
30814
|
+
shapeElements.push({
|
|
30815
|
+
name: "v:path",
|
|
30816
|
+
attributes: {
|
|
30817
|
+
textpathok: "t"
|
|
30818
|
+
}
|
|
30819
|
+
});
|
|
30820
|
+
shapeElements.push({
|
|
30821
|
+
name: "v:textpath",
|
|
30822
|
+
attributes: {
|
|
30823
|
+
on: "t",
|
|
30824
|
+
fitshape: "t",
|
|
30825
|
+
string: text,
|
|
30826
|
+
style: textpathStyle,
|
|
30827
|
+
...wmData.textpath?.trim !== void 0 && { trim: wmData.textpath.trim ? "t" : "f" }
|
|
30828
|
+
}
|
|
30829
|
+
});
|
|
30830
|
+
const fillAttrs = {};
|
|
30831
|
+
const fill = wmData.fill || attrs.fill;
|
|
30832
|
+
if (fill) {
|
|
30833
|
+
if (fill.type) fillAttrs.type = fill.type;
|
|
30834
|
+
if (fill.color2) fillAttrs.color2 = fill.color2;
|
|
30835
|
+
if (fill.opacity !== void 0) fillAttrs.opacity = fill.opacity.toString();
|
|
30836
|
+
if (fill.detectmouseclick !== void 0) {
|
|
30837
|
+
fillAttrs["o:detectmouseclick"] = fill.detectmouseclick ? "t" : "f";
|
|
30838
|
+
}
|
|
30839
|
+
}
|
|
30840
|
+
if (Object.keys(fillAttrs).length > 0) {
|
|
30841
|
+
shapeElements.push({
|
|
30842
|
+
name: "v:fill",
|
|
30843
|
+
attributes: fillAttrs
|
|
30844
|
+
});
|
|
30845
|
+
}
|
|
30846
|
+
const stroke = wmData.stroke || attrs.stroke;
|
|
30847
|
+
if (stroke && stroke.enabled !== false) {
|
|
30848
|
+
const strokeAttrs = {};
|
|
30849
|
+
if (stroke.color) strokeAttrs.color = stroke.color;
|
|
30850
|
+
if (stroke.joinstyle) strokeAttrs.joinstyle = stroke.joinstyle;
|
|
30851
|
+
if (stroke.endcap) strokeAttrs.endcap = stroke.endcap;
|
|
30852
|
+
if (Object.keys(strokeAttrs).length > 0) {
|
|
30853
|
+
shapeElements.push({
|
|
30854
|
+
name: "v:stroke",
|
|
30855
|
+
attributes: strokeAttrs
|
|
30856
|
+
});
|
|
30857
|
+
}
|
|
30858
|
+
}
|
|
30859
|
+
shapeElements.push({
|
|
30860
|
+
name: "w10:wrap",
|
|
30861
|
+
attributes: {
|
|
30862
|
+
type: attrs.wrap?.type?.toLowerCase() || "none"
|
|
30863
|
+
}
|
|
30864
|
+
});
|
|
30865
|
+
const shape = {
|
|
30866
|
+
name: "v:shape",
|
|
30867
|
+
attributes: {
|
|
30868
|
+
id: `PowerPlusWaterMarkObject${generateRandomSigned32BitIntStrId().replace("-", "")}`,
|
|
30869
|
+
"o:spid": `shape_${Math.floor(Math.random() * 1e4)}`,
|
|
30870
|
+
type: "#_x0000_t136",
|
|
30871
|
+
style,
|
|
30872
|
+
fillcolor: fill?.color || "silver",
|
|
30873
|
+
stroked: stroke?.enabled !== false ? "t" : "f",
|
|
30874
|
+
"o:allowincell": "f",
|
|
30875
|
+
...attrs.vmlAttributes?.adj && { adj: attrs.vmlAttributes.adj }
|
|
30876
|
+
},
|
|
30877
|
+
elements: shapeElements
|
|
30878
|
+
};
|
|
30879
|
+
const pict = {
|
|
30880
|
+
name: "w:pict",
|
|
30881
|
+
elements: [shape]
|
|
30882
|
+
};
|
|
30883
|
+
const par = {
|
|
30884
|
+
name: "w:p",
|
|
30885
|
+
elements: [wrapTextInRun(pict)]
|
|
30886
|
+
};
|
|
30887
|
+
return par;
|
|
30888
|
+
}
|
|
30889
|
+
function buildVmlStyle(attrs, wmData) {
|
|
30890
|
+
const styles = [];
|
|
30891
|
+
styles.push("position:absolute");
|
|
30892
|
+
if (attrs.marginOffset) {
|
|
30893
|
+
if (attrs.marginOffset.horizontal !== void 0) {
|
|
30894
|
+
styles.push(`margin-left:${convertToPt(attrs.marginOffset.horizontal)}pt`);
|
|
30895
|
+
}
|
|
30896
|
+
if (attrs.marginOffset.top !== void 0) {
|
|
30897
|
+
styles.push(`margin-top:${convertToPt(attrs.marginOffset.top)}pt`);
|
|
30898
|
+
}
|
|
30899
|
+
} else {
|
|
30900
|
+
styles.push("margin-left:0.05pt");
|
|
30901
|
+
styles.push("margin-top:315.7pt");
|
|
30902
|
+
}
|
|
30903
|
+
if (attrs.size) {
|
|
30904
|
+
if (attrs.size.width) {
|
|
30905
|
+
styles.push(`width:${convertToPt(attrs.size.width)}pt`);
|
|
30906
|
+
}
|
|
30907
|
+
if (attrs.size.height) {
|
|
30908
|
+
styles.push(`height:${convertToPt(attrs.size.height)}pt`);
|
|
30909
|
+
}
|
|
30910
|
+
}
|
|
30911
|
+
const wrapType = attrs.wrap?.type;
|
|
30912
|
+
let msoWrapStyle = "none";
|
|
30913
|
+
if (wrapType) {
|
|
30914
|
+
const wrapTypeLower = wrapType.toLowerCase();
|
|
30915
|
+
if (wrapTypeLower === "topandbottom") {
|
|
30916
|
+
msoWrapStyle = "top-and-bottom";
|
|
30917
|
+
} else if (["square", "tight", "through"].includes(wrapTypeLower)) {
|
|
30918
|
+
msoWrapStyle = wrapTypeLower;
|
|
30919
|
+
}
|
|
30920
|
+
}
|
|
30921
|
+
styles.push(`mso-wrap-style:${msoWrapStyle}`);
|
|
30922
|
+
const textAnchor = wmData.textStyle?.textAnchor || attrs.textStyle?.textAnchor;
|
|
30923
|
+
if (textAnchor) {
|
|
30924
|
+
styles.push(`v-text-anchor:${textAnchor}`);
|
|
30925
|
+
}
|
|
30926
|
+
const rotation = wmData.rotation || attrs.rotation;
|
|
30927
|
+
if (rotation !== void 0 && rotation !== 0) {
|
|
30928
|
+
styles.push(`rotation:${rotation}`);
|
|
30929
|
+
}
|
|
30930
|
+
if (attrs.anchorData) {
|
|
30931
|
+
if (attrs.anchorData.alignH) {
|
|
30932
|
+
styles.push(`mso-position-horizontal:${attrs.anchorData.alignH}`);
|
|
30933
|
+
}
|
|
30934
|
+
if (attrs.anchorData.alignV) {
|
|
30935
|
+
styles.push(`mso-position-vertical:${attrs.anchorData.alignV}`);
|
|
30936
|
+
}
|
|
30937
|
+
if (attrs.anchorData.hRelativeFrom) {
|
|
30938
|
+
styles.push(`mso-position-horizontal-relative:${attrs.anchorData.hRelativeFrom}`);
|
|
30939
|
+
}
|
|
30940
|
+
if (attrs.anchorData.vRelativeFrom) {
|
|
30941
|
+
styles.push(`mso-position-vertical-relative:${attrs.anchorData.vRelativeFrom}`);
|
|
30942
|
+
}
|
|
30943
|
+
}
|
|
30944
|
+
return styles.join(";");
|
|
30945
|
+
}
|
|
30946
|
+
function buildTextpathStyle(wmData) {
|
|
30947
|
+
const styles = [];
|
|
30948
|
+
if (wmData.textStyle) {
|
|
30949
|
+
if (wmData.textStyle.fontFamily) {
|
|
30950
|
+
styles.push(`font-family:"${wmData.textStyle.fontFamily}"`);
|
|
30951
|
+
}
|
|
30952
|
+
if (wmData.textStyle.fontSize) {
|
|
30953
|
+
styles.push(`font-size:${wmData.textStyle.fontSize}`);
|
|
30954
|
+
}
|
|
30955
|
+
}
|
|
30956
|
+
return styles.join(";");
|
|
30957
|
+
}
|
|
30958
|
+
function convertToPt(pixels) {
|
|
30959
|
+
if (typeof pixels === "number") {
|
|
30960
|
+
return pixels * 72 / 96;
|
|
30961
|
+
}
|
|
30962
|
+
return parseFloat(pixels) || 0;
|
|
30963
|
+
}
|
|
30395
30964
|
const XML_NODE_NAME = "w:pict";
|
|
30396
30965
|
const SD_NODE_NAME = ["shapeContainer", "contentBlock", "image"];
|
|
30397
30966
|
const validXmlAttributes = [];
|
|
@@ -30419,7 +30988,10 @@ function decode(params) {
|
|
|
30419
30988
|
contentBlock: () => translateContentBlock(params),
|
|
30420
30989
|
image: () => {
|
|
30421
30990
|
if (node.attrs?.vmlWatermark) {
|
|
30422
|
-
|
|
30991
|
+
if (node.attrs?.vmlTextWatermark) {
|
|
30992
|
+
return translateTextWatermark(params);
|
|
30993
|
+
}
|
|
30994
|
+
return translateImageWatermark(params);
|
|
30423
30995
|
}
|
|
30424
30996
|
return null;
|
|
30425
30997
|
},
|
|
@@ -31564,7 +32136,7 @@ class SuperConverter {
|
|
|
31564
32136
|
static getStoredSuperdocVersion(docx) {
|
|
31565
32137
|
return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
|
|
31566
32138
|
}
|
|
31567
|
-
static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.5.0-next.
|
|
32139
|
+
static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.5.0-next.7") {
|
|
31568
32140
|
return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version, false);
|
|
31569
32141
|
}
|
|
31570
32142
|
/**
|
|
@@ -32239,8 +32811,8 @@ export {
|
|
|
32239
32811
|
SelectionRange as Z,
|
|
32240
32812
|
Transform as _,
|
|
32241
32813
|
createDocFromHTML as a,
|
|
32242
|
-
translator$
|
|
32243
|
-
translator$
|
|
32814
|
+
translator$1O as a0,
|
|
32815
|
+
translator$14 as a1,
|
|
32244
32816
|
resolveDocxFontFamily as a2,
|
|
32245
32817
|
combineIndentProperties as a3,
|
|
32246
32818
|
_getReferencedTableStyles as a4,
|