@harbour-enterprises/superdoc 0.24.0-next.4 → 0.24.0-next.6

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.
Files changed (33) hide show
  1. package/dist/chunks/{PdfViewer-D7C8g2G4.es.js → PdfViewer-BiHh3x6b.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-kOVuv-4I.cjs → PdfViewer-qk_hITc5.cjs} +1 -1
  3. package/dist/chunks/{index-BFKwBQjS.cjs → index-Di6nG2sc.cjs} +66 -10
  4. package/dist/chunks/{index-CnEAVnHQ.es.js → index-aMnFs35I.es.js} +66 -10
  5. package/dist/chunks/{super-editor.es-BmGTQ05x.cjs → super-editor.es-BKZvTraR.cjs} +579 -137
  6. package/dist/chunks/{super-editor.es-CBPoWvjs.es.js → super-editor.es-Dz7y81Yr.es.js} +579 -137
  7. package/dist/core/SuperDoc.d.ts.map +1 -1
  8. package/dist/core/helpers/export.d.ts +1 -1
  9. package/dist/core/helpers/export.d.ts.map +1 -1
  10. package/dist/core/types/index.d.ts.map +1 -1
  11. package/dist/style.css +10 -0
  12. package/dist/super-editor/ai-writer.es.js +2 -2
  13. package/dist/super-editor/chunks/{converter-DpPj67OW.js → converter-CI3WqmGV.js} +514 -197
  14. package/dist/super-editor/chunks/{docx-zipper-6Kc95yG-.js → docx-zipper-D4fk50d9.js} +1 -1
  15. package/dist/super-editor/chunks/{editor-Dx6AhT5N.js → editor-DC6pZVp1.js} +170 -43
  16. package/dist/super-editor/chunks/{toolbar-CXSg2lJ9.js → toolbar-DMobfM6u.js} +2 -2
  17. package/dist/super-editor/converter.es.js +1 -1
  18. package/dist/super-editor/docx-zipper.es.js +2 -2
  19. package/dist/super-editor/editor.es.js +3 -3
  20. package/dist/super-editor/file-zipper.es.js +1 -1
  21. package/dist/super-editor/style.css +10 -0
  22. package/dist/super-editor/super-editor/src/core/super-converter/helpers.d.ts +1 -0
  23. package/dist/super-editor/super-editor/src/core/super-converter/v3/handlers/w/tr/tr-helpers.d.ts +16 -0
  24. package/dist/super-editor/super-editor/src/extensions/table/TableView.d.ts +1 -1
  25. package/dist/super-editor/super-editor.es.js +7 -7
  26. package/dist/super-editor/toolbar.es.js +2 -2
  27. package/dist/super-editor.cjs +1 -1
  28. package/dist/super-editor.es.js +1 -1
  29. package/dist/superdoc.cjs +2 -2
  30. package/dist/superdoc.es.js +2 -2
  31. package/dist/superdoc.umd.js +643 -145
  32. package/dist/superdoc.umd.js.map +1 -1
  33. package/package.json +1 -1
@@ -15093,6 +15093,7 @@ async function readFromClipboard(state2) {
15093
15093
  }
15094
15094
  return content;
15095
15095
  }
15096
+ const PIXELS_PER_INCH = 96;
15096
15097
  function inchesToTwips(inches) {
15097
15098
  if (inches == null) return;
15098
15099
  if (typeof inches === "string") inches = parseFloat(inches);
@@ -15115,12 +15116,12 @@ function pixelsToTwips(pixels) {
15115
15116
  }
15116
15117
  function inchesToPixels(inches) {
15117
15118
  if (inches == null) return;
15118
- const pixels = inches * 96;
15119
+ const pixels = inches * PIXELS_PER_INCH;
15119
15120
  return Math.round(pixels * 1e3) / 1e3;
15120
15121
  }
15121
15122
  function pixelsToInches(pixels) {
15122
15123
  if (pixels == null) return;
15123
- const inches = Number(pixels) / 96;
15124
+ const inches = Number(pixels) / PIXELS_PER_INCH;
15124
15125
  return inches;
15125
15126
  }
15126
15127
  function twipsToLines(twips) {
@@ -15138,7 +15139,7 @@ function halfPointToPoints(halfPoints) {
15138
15139
  function emuToPixels(emu) {
15139
15140
  if (emu == null) return;
15140
15141
  if (typeof emu === "string") emu = parseFloat(emu);
15141
- const pixels = emu * 96 / 914400;
15142
+ const pixels = emu * PIXELS_PER_INCH / 914400;
15142
15143
  return Math.round(pixels);
15143
15144
  }
15144
15145
  function pixelsToEmu(px) {
@@ -15174,12 +15175,12 @@ function degreesToRot(degrees) {
15174
15175
  }
15175
15176
  function pixelsToPolygonUnits(pixels) {
15176
15177
  if (pixels == null) return;
15177
- const pu = pixels * 96;
15178
+ const pu = pixels * PIXELS_PER_INCH;
15178
15179
  return Math.round(pu);
15179
15180
  }
15180
15181
  function polygonUnitsToPixels(pu) {
15181
15182
  if (pu == null) return;
15182
- const pixels = Number(pu) / 96;
15183
+ const pixels = Number(pu) / PIXELS_PER_INCH;
15183
15184
  return Math.round(pixels * 1e3) / 1e3;
15184
15185
  }
15185
15186
  function polygonToObj(polygonNode) {
@@ -27055,6 +27056,68 @@ const translator$_ = NodeTranslator.from(
27055
27056
  repeatHeader: false
27056
27057
  })
27057
27058
  );
27059
+ const createPlaceholderCell = (gridWidth, reason) => {
27060
+ const safeWidth = Number.isFinite(gridWidth) ? gridWidth : 0;
27061
+ const noBorder = { val: "none", size: 0 };
27062
+ return {
27063
+ type: "tableCell",
27064
+ attrs: {
27065
+ colspan: 1,
27066
+ rowspan: 1,
27067
+ colwidth: [safeWidth],
27068
+ __placeholder: reason,
27069
+ borders: {
27070
+ top: { ...noBorder },
27071
+ right: { ...noBorder },
27072
+ bottom: { ...noBorder },
27073
+ left: { ...noBorder }
27074
+ }
27075
+ },
27076
+ content: [{ type: "paragraph", content: [] }]
27077
+ };
27078
+ };
27079
+ const advancePastRowSpans = (pendingRowSpans, startIndex, totalColumns) => {
27080
+ let index2 = startIndex;
27081
+ while (index2 < totalColumns && pendingRowSpans[index2] > 0) {
27082
+ pendingRowSpans[index2] -= 1;
27083
+ index2 += 1;
27084
+ }
27085
+ return index2;
27086
+ };
27087
+ const fillPlaceholderColumns = ({
27088
+ content,
27089
+ pendingRowSpans,
27090
+ currentIndex,
27091
+ targetIndex,
27092
+ totalColumns,
27093
+ gridColumnWidths,
27094
+ reason
27095
+ }) => {
27096
+ let index2 = currentIndex;
27097
+ while (index2 < targetIndex && index2 < totalColumns) {
27098
+ if (pendingRowSpans[index2] > 0) {
27099
+ pendingRowSpans[index2] -= 1;
27100
+ index2 += 1;
27101
+ continue;
27102
+ }
27103
+ const width = Array.isArray(gridColumnWidths) ? gridColumnWidths[index2] ?? 0 : 0;
27104
+ content.push(createPlaceholderCell(width, reason));
27105
+ index2 += 1;
27106
+ }
27107
+ return index2;
27108
+ };
27109
+ const isPlaceholderCell = (cell) => {
27110
+ if (!cell) return false;
27111
+ if (cell.attrs?.__placeholder) return true;
27112
+ const widths = cell.attrs?.colwidth;
27113
+ if (Array.isArray(widths) && widths.length > 0) {
27114
+ const hasMeaningfulWidth = widths.some(
27115
+ (value) => typeof value === "number" && Number.isFinite(value) && Math.abs(value) > 1
27116
+ );
27117
+ if (!hasMeaningfulWidth) return true;
27118
+ }
27119
+ return false;
27120
+ };
27058
27121
  const XML_NODE_NAME$h = "w:tr";
27059
27122
  const SD_NODE_NAME$d = "tableRow";
27060
27123
  const validXmlAttributes$b = ["w:rsidDel", "w:rsidR", "w:rsidRPr", "w:rsidTr", "w14:paraId", "w14:textId"].map(
@@ -27070,29 +27133,64 @@ const encode$n = (params2, encodedAttrs) => {
27070
27133
  nodes: [tPr]
27071
27134
  });
27072
27135
  }
27136
+ const gridBeforeRaw = tableRowProperties?.["gridBefore"];
27137
+ const safeGridBefore = typeof gridBeforeRaw === "number" && Number.isFinite(gridBeforeRaw) && gridBeforeRaw > 0 ? gridBeforeRaw : 0;
27073
27138
  encodedAttrs["tableRowProperties"] = Object.freeze(tableRowProperties);
27074
27139
  encodedAttrs["rowHeight"] = twipsToPixels(tableRowProperties["rowHeight"]?.value);
27075
27140
  encodedAttrs["cantSplit"] = tableRowProperties["cantSplit"];
27076
- const { columnWidths: gridColumnWidths } = params2.extraParams;
27141
+ const { columnWidths: gridColumnWidths, activeRowSpans = [] } = params2.extraParams;
27142
+ const totalColumns = Array.isArray(gridColumnWidths) ? gridColumnWidths.length : 0;
27143
+ const pendingRowSpans = Array.isArray(activeRowSpans) ? activeRowSpans.slice() : [];
27144
+ while (pendingRowSpans.length < totalColumns) pendingRowSpans.push(0);
27077
27145
  const cellNodes = row.elements.filter((el) => el.name === "w:tc");
27146
+ const content = [];
27078
27147
  let currentColumnIndex = 0;
27079
- const content = cellNodes?.map((n) => {
27080
- let columnWidth = gridColumnWidths?.[currentColumnIndex] || null;
27148
+ const fillUntil = (target, reason) => {
27149
+ currentColumnIndex = fillPlaceholderColumns({
27150
+ content,
27151
+ pendingRowSpans,
27152
+ currentIndex: currentColumnIndex,
27153
+ targetIndex: target,
27154
+ totalColumns,
27155
+ gridColumnWidths,
27156
+ reason
27157
+ });
27158
+ };
27159
+ const skipOccupiedColumns = () => {
27160
+ currentColumnIndex = advancePastRowSpans(pendingRowSpans, currentColumnIndex, totalColumns);
27161
+ };
27162
+ fillUntil(safeGridBefore, "gridBefore");
27163
+ skipOccupiedColumns();
27164
+ cellNodes?.forEach((node) => {
27165
+ skipOccupiedColumns();
27166
+ const startColumn = currentColumnIndex;
27167
+ const columnWidth = gridColumnWidths?.[startColumn] || null;
27081
27168
  const result = translator$c.encode({
27082
27169
  ...params2,
27083
27170
  extraParams: {
27084
27171
  ...params2.extraParams,
27085
- node: n,
27086
- columnIndex: currentColumnIndex,
27172
+ node,
27173
+ columnIndex: startColumn,
27087
27174
  columnWidth
27088
27175
  }
27089
27176
  });
27090
- const tcPr = n.elements?.find((el) => el.name === "w:tcPr");
27091
- const colspanTag = tcPr?.elements?.find((el) => el.name === "w:gridSpan");
27092
- const colspan = parseInt(colspanTag?.attributes["w:val"] || 1, 10);
27093
- currentColumnIndex += colspan;
27094
- return result;
27095
- }) || [];
27177
+ if (result) {
27178
+ content.push(result);
27179
+ const colspan = Math.max(1, result.attrs?.colspan || 1);
27180
+ const rowspan = Math.max(1, result.attrs?.rowspan || 1);
27181
+ if (rowspan > 1) {
27182
+ for (let offset2 = 0; offset2 < colspan; offset2 += 1) {
27183
+ const target = startColumn + offset2;
27184
+ if (target < pendingRowSpans.length) {
27185
+ pendingRowSpans[target] = Math.max(pendingRowSpans[target], rowspan - 1);
27186
+ }
27187
+ }
27188
+ }
27189
+ currentColumnIndex = startColumn + colspan;
27190
+ }
27191
+ });
27192
+ skipOccupiedColumns();
27193
+ fillUntil(totalColumns, "gridAfter");
27096
27194
  const newNode = {
27097
27195
  type: "tableRow",
27098
27196
  content,
@@ -27102,9 +27200,37 @@ const encode$n = (params2, encodedAttrs) => {
27102
27200
  };
27103
27201
  const decode$p = (params2, decodedAttrs) => {
27104
27202
  const { node } = params2;
27105
- const elements = translateChildNodes(params2);
27203
+ const cells = node.content || [];
27204
+ let leadingPlaceholders = 0;
27205
+ while (leadingPlaceholders < cells.length && isPlaceholderCell(cells[leadingPlaceholders])) {
27206
+ leadingPlaceholders += 1;
27207
+ }
27208
+ let trailingPlaceholders = 0;
27209
+ while (trailingPlaceholders < cells.length - leadingPlaceholders && isPlaceholderCell(cells[cells.length - 1 - trailingPlaceholders])) {
27210
+ trailingPlaceholders += 1;
27211
+ }
27212
+ const trimmedSlice = cells.slice(leadingPlaceholders, cells.length - trailingPlaceholders);
27213
+ const sanitizedCells = trimmedSlice.map((cell) => {
27214
+ if (cell?.attrs && "__placeholder" in cell.attrs) {
27215
+ const { __placeholder, ...rest } = cell.attrs;
27216
+ return { ...cell, attrs: rest };
27217
+ }
27218
+ return cell;
27219
+ });
27220
+ const trimmedContent = sanitizedCells.filter((_2, index2) => !isPlaceholderCell(trimmedSlice[index2]));
27221
+ const translateParams = {
27222
+ ...params2,
27223
+ node: { ...node, content: trimmedContent }
27224
+ };
27225
+ const elements = translateChildNodes(translateParams);
27106
27226
  if (node.attrs?.tableRowProperties) {
27107
27227
  const tableRowProperties = { ...node.attrs.tableRowProperties };
27228
+ if (leadingPlaceholders > 0) {
27229
+ tableRowProperties.gridBefore = leadingPlaceholders;
27230
+ }
27231
+ if (trailingPlaceholders > 0) {
27232
+ tableRowProperties.gridAfter = trailingPlaceholders;
27233
+ }
27108
27234
  if (node.attrs.rowHeight != null) {
27109
27235
  const rowHeightPixels = twipsToPixels(node.attrs.tableRowProperties["rowHeight"]?.value);
27110
27236
  if (rowHeightPixels !== node.attrs.rowHeight) {
@@ -27334,17 +27460,21 @@ const decode$o = (params2) => {
27334
27460
  const fallbackColumnWidthTwips = resolveFallbackColumnWidthTwips(params2, totalColumns, cellMinWidth);
27335
27461
  const elements = [];
27336
27462
  let columnIndex = 0;
27337
- const pushColumn = (widthTwips) => {
27463
+ const pushColumn = (widthTwips, { enforceMinimum = false } = {}) => {
27338
27464
  let numericWidth = typeof widthTwips === "string" ? parseInt(widthTwips, 10) : widthTwips;
27465
+ let shouldEnforceMinimum = enforceMinimum;
27339
27466
  if (numericWidth == null || Number.isNaN(numericWidth) || numericWidth <= 0) {
27340
27467
  numericWidth = fallbackColumnWidthTwips;
27468
+ shouldEnforceMinimum = true;
27341
27469
  }
27342
- numericWidth = Math.max(numericWidth, cellMinWidth);
27470
+ const roundedWidth = Math.round(numericWidth);
27471
+ const minimumWidth = shouldEnforceMinimum ? cellMinWidth : 1;
27472
+ const safeWidth = Math.max(roundedWidth, minimumWidth);
27343
27473
  const decoded = translator$u.decode({
27344
27474
  node: { type: (
27345
27475
  /** @type {string} */
27346
27476
  translator$u.sdNodeOrKeyName
27347
- ), attrs: { col: numericWidth } }
27477
+ ), attrs: { col: safeWidth } }
27348
27478
  });
27349
27479
  if (decoded) elements.push(decoded);
27350
27480
  };
@@ -27352,13 +27482,17 @@ const decode$o = (params2) => {
27352
27482
  const { colspan = 1, colwidth } = cell?.attrs || {};
27353
27483
  const spanCount = Math.max(1, colspan);
27354
27484
  for (let span = 0; span < spanCount; span++) {
27355
- const cellWidthPixels = Array.isArray(colwidth) ? colwidth[span] : void 0;
27485
+ const rawWidth = Array.isArray(colwidth) ? colwidth[span] : void 0;
27486
+ const cellWidthPixels = typeof rawWidth === "number" && Number.isFinite(rawWidth) ? rawWidth : Number(rawWidth);
27487
+ const hasCellWidth = Number.isFinite(cellWidthPixels) && cellWidthPixels > 0;
27356
27488
  const colGridAttrs = grid?.[columnIndex] || {};
27357
27489
  const gridWidthTwips = normalizeTwipWidth(colGridAttrs.col);
27358
27490
  const gridWidthPixels = gridWidthTwips != null ? twipsToPixels(gridWidthTwips) : null;
27359
27491
  let cellWidthTwips;
27360
- if (cellWidthPixels != null) {
27361
- if (gridWidthTwips != null && gridWidthPixels === cellWidthPixels) {
27492
+ let enforceMinimum = false;
27493
+ if (hasCellWidth) {
27494
+ const tolerance = 0.5;
27495
+ if (gridWidthTwips != null && gridWidthPixels != null && Math.abs(gridWidthPixels - cellWidthPixels) <= tolerance) {
27362
27496
  cellWidthTwips = gridWidthTwips;
27363
27497
  } else {
27364
27498
  cellWidthTwips = pixelsToTwips(cellWidthPixels);
@@ -27367,8 +27501,9 @@ const decode$o = (params2) => {
27367
27501
  cellWidthTwips = gridWidthTwips;
27368
27502
  } else {
27369
27503
  cellWidthTwips = fallbackColumnWidthTwips;
27504
+ enforceMinimum = true;
27370
27505
  }
27371
- pushColumn(cellWidthTwips);
27506
+ pushColumn(cellWidthTwips, { enforceMinimum });
27372
27507
  columnIndex++;
27373
27508
  }
27374
27509
  });
@@ -27531,7 +27666,9 @@ const encode$l = (params2, encodedAttrs) => {
27531
27666
  }
27532
27667
  }
27533
27668
  const content = [];
27534
- rows.forEach((row) => {
27669
+ const totalColumns = columnWidths.length;
27670
+ const activeRowSpans = totalColumns > 0 ? new Array(totalColumns).fill(0) : [];
27671
+ rows.forEach((row, rowIndex) => {
27535
27672
  const result = translator$Z.encode({
27536
27673
  ...params2,
27537
27674
  nodes: [row],
@@ -27540,10 +27677,45 @@ const encode$l = (params2, encodedAttrs) => {
27540
27677
  table: node,
27541
27678
  rowBorders: borderRowData,
27542
27679
  styleTag: tblStyleTag,
27543
- columnWidths
27680
+ columnWidths,
27681
+ activeRowSpans: activeRowSpans.slice(),
27682
+ rowIndex
27544
27683
  }
27545
27684
  });
27546
- if (result) content.push(result);
27685
+ if (result) {
27686
+ content.push(result);
27687
+ if (totalColumns > 0) {
27688
+ const activeRowSpansForCurrentRow = activeRowSpans.slice();
27689
+ for (let col = 0; col < totalColumns; col++) {
27690
+ if (activeRowSpans[col] > 0) {
27691
+ activeRowSpans[col] -= 1;
27692
+ }
27693
+ }
27694
+ let columnIndex = 0;
27695
+ const advanceColumnIndex = () => {
27696
+ while (columnIndex < totalColumns && activeRowSpansForCurrentRow[columnIndex] > 0) {
27697
+ columnIndex += 1;
27698
+ }
27699
+ };
27700
+ advanceColumnIndex();
27701
+ result.content?.forEach((cell) => {
27702
+ advanceColumnIndex();
27703
+ const colspan = Math.max(1, cell.attrs?.colspan || 1);
27704
+ const rowspan = Math.max(1, cell.attrs?.rowspan || 1);
27705
+ if (rowspan > 1) {
27706
+ for (let offset2 = 0; offset2 < colspan && columnIndex + offset2 < totalColumns; offset2++) {
27707
+ const targetIndex = columnIndex + offset2;
27708
+ const remainingRows = rowspan - 1;
27709
+ if (remainingRows > 0 && remainingRows > activeRowSpans[targetIndex]) {
27710
+ activeRowSpans[targetIndex] = remainingRows;
27711
+ }
27712
+ }
27713
+ }
27714
+ columnIndex += colspan;
27715
+ advanceColumnIndex();
27716
+ });
27717
+ }
27718
+ }
27547
27719
  });
27548
27720
  return {
27549
27721
  type: "table",
@@ -27948,14 +28120,104 @@ function handleTableCellNode({
27948
28120
  }
27949
28121
  return {
27950
28122
  type: "tableCell",
27951
- content: nodeListHandler.handler({
27952
- ...params2,
27953
- nodes: node.elements,
27954
- path: [...params2.path || [], node]
27955
- }),
28123
+ content: normalizeTableCellContent(
28124
+ nodeListHandler.handler({
28125
+ ...params2,
28126
+ nodes: node.elements,
28127
+ path: [...params2.path || [], node]
28128
+ }),
28129
+ params2.editor
28130
+ ),
27956
28131
  attrs: attributes
27957
28132
  };
27958
28133
  }
28134
+ function normalizeTableCellContent(content, editor) {
28135
+ if (!Array.isArray(content) || content.length === 0) return content;
28136
+ const normalized = [];
28137
+ const pendingForNextBlock = [];
28138
+ const schema = editor?.schema;
28139
+ const cloneBlock = (node) => {
28140
+ if (!node) return node;
28141
+ const cloned = { ...node };
28142
+ if (Array.isArray(node.content)) {
28143
+ cloned.content = [...node.content];
28144
+ }
28145
+ return cloned;
28146
+ };
28147
+ const ensureArray = (node) => {
28148
+ if (!Array.isArray(node.content)) {
28149
+ node.content = [];
28150
+ }
28151
+ return node.content;
28152
+ };
28153
+ const isInlineNode = (node) => {
28154
+ if (!node || typeof node.type !== "string") return false;
28155
+ if (node.type === "text") return true;
28156
+ if (node.type === "bookmarkStart" || node.type === "bookmarkEnd") return true;
28157
+ const nodeType = schema?.nodes?.[node.type];
28158
+ if (nodeType) {
28159
+ if (typeof nodeType.isInline === "boolean") return nodeType.isInline;
28160
+ if (nodeType.spec?.group && typeof nodeType.spec.group === "string") {
28161
+ return nodeType.spec.group.split(" ").includes("inline");
28162
+ }
28163
+ }
28164
+ return false;
28165
+ };
28166
+ for (const node of content) {
28167
+ if (!node || typeof node.type !== "string") {
28168
+ normalized.push(node);
28169
+ continue;
28170
+ }
28171
+ if (!isInlineNode(node)) {
28172
+ const blockNode = cloneBlock(node);
28173
+ if (pendingForNextBlock.length) {
28174
+ const blockContent = ensureArray(blockNode);
28175
+ const leadingInline = pendingForNextBlock.splice(0);
28176
+ blockNode.content = [...leadingInline, ...blockContent];
28177
+ } else if (Array.isArray(blockNode.content)) {
28178
+ blockNode.content = [...blockNode.content];
28179
+ }
28180
+ normalized.push(blockNode);
28181
+ continue;
28182
+ }
28183
+ const targetIsNextBlock = node.type === "bookmarkStart" || normalized.length === 0;
28184
+ if (targetIsNextBlock) {
28185
+ pendingForNextBlock.push(node);
28186
+ } else {
28187
+ const lastIndex = normalized.length - 1;
28188
+ const lastNode = normalized[lastIndex];
28189
+ if (!lastNode || typeof lastNode.type !== "string" || isInlineNode(lastNode)) {
28190
+ pendingForNextBlock.push(node);
28191
+ continue;
28192
+ }
28193
+ const blockContent = ensureArray(lastNode);
28194
+ if (pendingForNextBlock.length) {
28195
+ blockContent.push(...pendingForNextBlock.splice(0));
28196
+ }
28197
+ blockContent.push(node);
28198
+ }
28199
+ }
28200
+ if (pendingForNextBlock.length) {
28201
+ if (normalized.length) {
28202
+ const lastIndex = normalized.length - 1;
28203
+ const lastNode = normalized[lastIndex];
28204
+ if (lastNode && typeof lastNode.type === "string" && !isInlineNode(lastNode)) {
28205
+ const blockContent = ensureArray(lastNode);
28206
+ blockContent.push(...pendingForNextBlock);
28207
+ pendingForNextBlock.length = 0;
28208
+ }
28209
+ }
28210
+ if (pendingForNextBlock.length) {
28211
+ normalized.push({
28212
+ type: "paragraph",
28213
+ attrs: {},
28214
+ content: [...pendingForNextBlock]
28215
+ });
28216
+ pendingForNextBlock.length = 0;
28217
+ }
28218
+ }
28219
+ return normalized;
28220
+ }
27959
28221
  const processInlineCellBorders = (borders, rowBorders) => {
27960
28222
  if (!borders) return null;
27961
28223
  return ["bottom", "top", "left", "right"].reduce((acc, direction) => {
@@ -28509,6 +28771,7 @@ function sdtNodeTypeStrategy(node) {
28509
28771
  }
28510
28772
  return { type: "unknown", handler: null };
28511
28773
  }
28774
+ const DRAWING_XML_TAG = "w:drawing";
28512
28775
  function handleImageNode(node, params2, isAnchor) {
28513
28776
  const { docx, filename } = params2;
28514
28777
  const { attributes } = node;
@@ -28520,32 +28783,10 @@ function handleImageNode(node, params2, isAnchor) {
28520
28783
  };
28521
28784
  const extent = node.elements.find((el) => el.name === "wp:extent");
28522
28785
  const size2 = {
28523
- width: emuToPixels(extent.attributes?.cx),
28524
- height: emuToPixels(extent.attributes?.cy)
28786
+ width: emuToPixels(extent?.attributes?.cx),
28787
+ height: emuToPixels(extent?.attributes?.cy)
28525
28788
  };
28526
- const graphic = node.elements.find((el) => el.name === "a:graphic");
28527
- const graphicData = graphic.elements.find((el) => el.name === "a:graphicData");
28528
- const { uri: uri2 } = graphicData?.attributes || {};
28529
- const shapeURI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
28530
- if (!!uri2 && uri2 === shapeURI) {
28531
- return handleShapeDrawing(params2, node, graphicData);
28532
- }
28533
- const picture = graphicData.elements.find((el) => el.name === "pic:pic");
28534
- if (!picture || !picture.elements) return null;
28535
- const blipFill = picture.elements.find((el) => el.name === "pic:blipFill");
28536
- const blip = blipFill.elements.find((el) => el.name === "a:blip");
28537
- const spPr = picture.elements.find((el) => el.name === "pic:spPr");
28538
28789
  let transformData = {};
28539
- if (spPr) {
28540
- const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
28541
- if (xfrm?.attributes) {
28542
- transformData = {
28543
- rotation: rotToDegrees(xfrm.attributes["rot"]),
28544
- verticalFlip: xfrm.attributes["flipV"] === "1",
28545
- horizontalFlip: xfrm.attributes["flipH"] === "1"
28546
- };
28547
- }
28548
- }
28549
28790
  const effectExtent = node.elements.find((el) => el.name === "wp:effectExtent");
28550
28791
  if (effectExtent) {
28551
28792
  const sanitizeEmuValue = (value) => {
@@ -28554,22 +28795,26 @@ function handleImageNode(node, params2, isAnchor) {
28554
28795
  return Number.isFinite(numeric) ? numeric : 0;
28555
28796
  };
28556
28797
  transformData.sizeExtension = {
28557
- left: emuToPixels(sanitizeEmuValue(effectExtent.attributes["l"])),
28558
- top: emuToPixels(sanitizeEmuValue(effectExtent.attributes["t"])),
28559
- right: emuToPixels(sanitizeEmuValue(effectExtent.attributes["r"])),
28560
- bottom: emuToPixels(sanitizeEmuValue(effectExtent.attributes["b"]))
28798
+ left: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["l"])),
28799
+ top: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["t"])),
28800
+ right: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["r"])),
28801
+ bottom: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["b"]))
28561
28802
  };
28562
28803
  }
28563
28804
  const positionHTag = node.elements.find((el) => el.name === "wp:positionH");
28564
28805
  const positionH = positionHTag?.elements.find((el) => el.name === "wp:posOffset");
28565
28806
  const positionHValue = emuToPixels(positionH?.elements[0]?.text);
28566
- const hRelativeFrom = positionHTag?.attributes.relativeFrom;
28567
- const alignH = positionHTag?.elements.find((el) => el.name === "wp:align")?.elements[0]?.text;
28807
+ const hRelativeFrom = positionHTag?.attributes?.relativeFrom;
28808
+ const alignH = positionHTag?.elements.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
28568
28809
  const positionVTag = node.elements.find((el) => el.name === "wp:positionV");
28569
28810
  const positionV = positionVTag?.elements?.find((el) => el.name === "wp:posOffset");
28570
28811
  const positionVValue = emuToPixels(positionV?.elements[0]?.text);
28571
- const vRelativeFrom = positionVTag?.attributes.relativeFrom;
28572
- const alignV = positionVTag?.elements?.find((el) => el.name === "wp:align")?.elements[0]?.text;
28812
+ const vRelativeFrom = positionVTag?.attributes?.relativeFrom;
28813
+ const alignV = positionVTag?.elements?.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
28814
+ const marginOffset = {
28815
+ horizontal: positionHValue,
28816
+ top: positionVValue
28817
+ };
28573
28818
  const simplePos = node.elements.find((el) => el.name === "wp:simplePos");
28574
28819
  const wrapNode = isAnchor ? node.elements.find(
28575
28820
  (el) => ["wp:wrapNone", "wp:wrapSquare", "wp:wrapThrough", "wp:wrapTight", "wp:wrapTopAndBottom"].includes(el.name)
@@ -28577,38 +28822,40 @@ function handleImageNode(node, params2, isAnchor) {
28577
28822
  const wrap2 = isAnchor ? { type: wrapNode?.name.slice(7) || "None", attrs: {} } : { type: "Inline" };
28578
28823
  switch (wrap2.type) {
28579
28824
  case "Square":
28580
- wrap2.attrs.wrapText = wrapNode.attributes.wrapText;
28581
- if ("distB" in (wrapNode.attributes || {})) {
28825
+ if (wrapNode?.attributes?.wrapText) {
28826
+ wrap2.attrs.wrapText = wrapNode.attributes.wrapText;
28827
+ }
28828
+ if ("distB" in (wrapNode?.attributes || {})) {
28582
28829
  wrap2.attrs.distBottom = emuToPixels(wrapNode.attributes.distB);
28583
28830
  }
28584
- if ("distL" in (wrapNode.attributes || {})) {
28831
+ if ("distL" in (wrapNode?.attributes || {})) {
28585
28832
  wrap2.attrs.distLeft = emuToPixels(wrapNode.attributes.distL);
28586
28833
  }
28587
- if ("distR" in (wrapNode.attributes || {})) {
28834
+ if ("distR" in (wrapNode?.attributes || {})) {
28588
28835
  wrap2.attrs.distRight = emuToPixels(wrapNode.attributes.distR);
28589
28836
  }
28590
- if ("distT" in (wrapNode.attributes || {})) {
28837
+ if ("distT" in (wrapNode?.attributes || {})) {
28591
28838
  wrap2.attrs.distTop = emuToPixels(wrapNode.attributes.distT);
28592
28839
  }
28593
28840
  break;
28594
28841
  case "Tight":
28595
28842
  case "Through": {
28596
- if ("distL" in (wrapNode.attributes || {})) {
28843
+ if ("distL" in (wrapNode?.attributes || {})) {
28597
28844
  wrap2.attrs.distLeft = emuToPixels(wrapNode.attributes.distL);
28598
28845
  }
28599
- if ("distR" in (wrapNode.attributes || {})) {
28846
+ if ("distR" in (wrapNode?.attributes || {})) {
28600
28847
  wrap2.attrs.distRight = emuToPixels(wrapNode.attributes.distR);
28601
28848
  }
28602
- if ("distT" in (wrapNode.attributes || {})) {
28849
+ if ("distT" in (wrapNode?.attributes || {})) {
28603
28850
  wrap2.attrs.distTop = emuToPixels(wrapNode.attributes.distT);
28604
28851
  }
28605
- if ("distB" in (wrapNode.attributes || {})) {
28852
+ if ("distB" in (wrapNode?.attributes || {})) {
28606
28853
  wrap2.attrs.distBottom = emuToPixels(wrapNode.attributes.distB);
28607
28854
  }
28608
- if ("wrapText" in (wrapNode.attributes || {})) {
28855
+ if ("wrapText" in (wrapNode?.attributes || {})) {
28609
28856
  wrap2.attrs.wrapText = wrapNode.attributes.wrapText;
28610
28857
  }
28611
- const polygon = wrapNode.elements?.find((el) => el.name === "wp:wrapPolygon");
28858
+ const polygon = wrapNode?.elements?.find((el) => el.name === "wp:wrapPolygon");
28612
28859
  if (polygon) {
28613
28860
  wrap2.attrs.polygon = polygonToObj(polygon);
28614
28861
  if (polygon.attributes?.edited !== void 0) {
@@ -28618,10 +28865,10 @@ function handleImageNode(node, params2, isAnchor) {
28618
28865
  break;
28619
28866
  }
28620
28867
  case "TopAndBottom":
28621
- if ("distB" in (wrapNode.attributes || {})) {
28868
+ if ("distB" in (wrapNode?.attributes || {})) {
28622
28869
  wrap2.attrs.distBottom = emuToPixels(wrapNode.attributes.distB);
28623
28870
  }
28624
- if ("distT" in (wrapNode.attributes || {})) {
28871
+ if ("distT" in (wrapNode?.attributes || {})) {
28625
28872
  wrap2.attrs.distTop = emuToPixels(wrapNode.attributes.distT);
28626
28873
  }
28627
28874
  break;
@@ -28639,17 +28886,42 @@ function handleImageNode(node, params2, isAnchor) {
28639
28886
  alignV
28640
28887
  };
28641
28888
  }
28642
- const marginOffset = {
28643
- horizontal: positionHValue,
28644
- top: positionVValue
28645
- };
28889
+ const graphic = node.elements.find((el) => el.name === "a:graphic");
28890
+ const graphicData = graphic?.elements.find((el) => el.name === "a:graphicData");
28891
+ const { uri: uri2 } = graphicData?.attributes || {};
28892
+ const shapeURI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
28893
+ if (!!uri2 && uri2 === shapeURI) {
28894
+ const shapeMarginOffset = {
28895
+ left: positionHValue,
28896
+ horizontal: positionHValue,
28897
+ top: positionVValue
28898
+ };
28899
+ return handleShapeDrawing(params2, node, graphicData, size2, padding, shapeMarginOffset);
28900
+ }
28901
+ const picture = graphicData?.elements.find((el) => el.name === "pic:pic");
28902
+ if (!picture || !picture.elements) return null;
28903
+ const blipFill = picture.elements.find((el) => el.name === "pic:blipFill");
28904
+ const blip = blipFill?.elements.find((el) => el.name === "a:blip");
28905
+ if (!blip) return null;
28906
+ const spPr = picture.elements.find((el) => el.name === "pic:spPr");
28907
+ if (spPr) {
28908
+ const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
28909
+ if (xfrm?.attributes) {
28910
+ transformData = {
28911
+ ...transformData,
28912
+ rotation: rotToDegrees(xfrm.attributes["rot"]),
28913
+ verticalFlip: xfrm.attributes["flipV"] === "1",
28914
+ horizontalFlip: xfrm.attributes["flipH"] === "1"
28915
+ };
28916
+ }
28917
+ }
28646
28918
  const { attributes: blipAttributes = {} } = blip;
28647
28919
  const rEmbed = blipAttributes["r:embed"];
28648
28920
  if (!rEmbed) return null;
28649
28921
  const currentFile = filename || "document.xml";
28650
28922
  let rels = docx[`word/_rels/${currentFile}.rels`];
28651
28923
  if (!rels) rels = docx[`word/_rels/document.xml.rels`];
28652
- const relationships = rels.elements.find((el) => el.name === "Relationships");
28924
+ const relationships = rels?.elements.find((el) => el.name === "Relationships");
28653
28925
  const { elements } = relationships || [];
28654
28926
  const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
28655
28927
  if (!rel) return null;
@@ -28662,10 +28934,10 @@ function handleImageNode(node, params2, isAnchor) {
28662
28934
  type: "image",
28663
28935
  attrs: {
28664
28936
  src: path,
28665
- alt: ["emf", "wmf"].includes(extension) ? "Unable to render EMF/WMF image" : docPr?.attributes.name || "Image",
28937
+ alt: ["emf", "wmf"].includes(extension) ? "Unable to render EMF/WMF image" : docPr?.attributes?.name || "Image",
28666
28938
  extension,
28667
- id: docPr?.attributes.id || "",
28668
- title: docPr?.attributes.descr || "Image",
28939
+ id: docPr?.attributes?.id || "",
28940
+ title: docPr?.attributes?.descr || "Image",
28669
28941
  inline: true,
28670
28942
  padding,
28671
28943
  marginOffset,
@@ -28680,6 +28952,10 @@ function handleImageNode(node, params2, isAnchor) {
28680
28952
  }
28681
28953
  },
28682
28954
  wrap: wrap2,
28955
+ ...wrap2.type === "Square" && wrap2.attrs.wrapText ? {
28956
+ wrapText: wrap2.attrs.wrapText
28957
+ } : {},
28958
+ wrapTopAndBottom: wrap2.type === "TopAndBottom",
28683
28959
  originalPadding: {
28684
28960
  distT: attributes["distT"],
28685
28961
  distB: attributes["distB"],
@@ -28691,7 +28967,7 @@ function handleImageNode(node, params2, isAnchor) {
28691
28967
  }
28692
28968
  };
28693
28969
  }
28694
- const handleShapeDrawing = (params2, node, graphicData) => {
28970
+ const handleShapeDrawing = (params2, node, graphicData, size2, padding, marginOffset) => {
28695
28971
  const wsp = graphicData.elements.find((el) => el.name === "wps:wsp");
28696
28972
  const textBox = wsp.elements.find((el) => el.name === "wps:txbx");
28697
28973
  const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
@@ -28702,21 +28978,14 @@ const handleShapeDrawing = (params2, node, graphicData) => {
28702
28978
  return getRectangleShape(params2, spPr);
28703
28979
  }
28704
28980
  if (!textBoxContent) {
28705
- return null;
28981
+ return buildShapePlaceholder(node, size2, padding, marginOffset, "drawing");
28706
28982
  }
28707
- const { nodeListHandler } = params2;
28708
- const translatedElement = nodeListHandler.handler({
28709
- ...params2,
28710
- node: textBoxContent.elements[0],
28711
- nodes: textBoxContent.elements,
28712
- path: [...params2.path || [], textBoxContent]
28713
- });
28714
- return translatedElement[0];
28983
+ return buildShapePlaceholder(node, size2, padding, marginOffset, "textbox");
28715
28984
  };
28716
28985
  const getRectangleShape = (params2, node) => {
28717
28986
  const schemaAttrs = {};
28718
28987
  const [drawingNode] = params2.nodes;
28719
- if (drawingNode?.name === "w:drawing") {
28988
+ if (drawingNode?.name === DRAWING_XML_TAG) {
28720
28989
  schemaAttrs.drawingContent = drawingNode;
28721
28990
  }
28722
28991
  const xfrm = node.elements.find((el) => el.name === "a:xfrm");
@@ -28740,6 +29009,52 @@ const getRectangleShape = (params2, node) => {
28740
29009
  attrs: schemaAttrs
28741
29010
  };
28742
29011
  };
29012
+ const buildShapePlaceholder = (node, size2, padding, marginOffset, shapeType) => {
29013
+ const attrs = {
29014
+ drawingContent: {
29015
+ name: DRAWING_XML_TAG,
29016
+ elements: [carbonCopy(node)]
29017
+ },
29018
+ attributes: {
29019
+ "data-shape-type": shapeType
29020
+ }
29021
+ };
29022
+ if (size2 && (Number.isFinite(size2.width) || Number.isFinite(size2.height))) {
29023
+ attrs.size = {
29024
+ ...Number.isFinite(size2.width) ? { width: size2.width } : {},
29025
+ ...Number.isFinite(size2.height) ? { height: size2.height } : {}
29026
+ };
29027
+ }
29028
+ if (padding) {
29029
+ const paddingData = {};
29030
+ if (Number.isFinite(padding.top)) paddingData["data-padding-top"] = padding.top;
29031
+ if (Number.isFinite(padding.right)) paddingData["data-padding-right"] = padding.right;
29032
+ if (Number.isFinite(padding.bottom)) paddingData["data-padding-bottom"] = padding.bottom;
29033
+ if (Number.isFinite(padding.left)) paddingData["data-padding-left"] = padding.left;
29034
+ if (Object.keys(paddingData).length) {
29035
+ attrs.attributes = {
29036
+ ...attrs.attributes,
29037
+ ...paddingData
29038
+ };
29039
+ }
29040
+ }
29041
+ if (marginOffset) {
29042
+ const offsetData = {};
29043
+ const horizontal = Number.isFinite(marginOffset.horizontal) ? marginOffset.horizontal : Number.isFinite(marginOffset.left) ? marginOffset.left : void 0;
29044
+ if (Number.isFinite(horizontal)) offsetData["data-offset-x"] = horizontal;
29045
+ if (Number.isFinite(marginOffset.top)) offsetData["data-offset-y"] = marginOffset.top;
29046
+ if (Object.keys(offsetData).length) {
29047
+ attrs.attributes = {
29048
+ ...attrs.attributes,
29049
+ ...offsetData
29050
+ };
29051
+ }
29052
+ }
29053
+ return {
29054
+ type: "contentBlock",
29055
+ attrs
29056
+ };
29057
+ };
28743
29058
  function handleAnchorNode(params2) {
28744
29059
  const { node } = params2.extraParams;
28745
29060
  if (node.name !== "wp:anchor") {
@@ -58948,8 +59263,11 @@ const HardBreak = Node$1.create({
58948
59263
  }
58949
59264
  });
58950
59265
  const getColStyleDeclaration = (minWidth, width) => {
58951
- if (width) {
58952
- return ["width", `${Math.max(width, minWidth)}px`];
59266
+ if (width != null) {
59267
+ const numericWidth = Number(width);
59268
+ if (Number.isFinite(numericWidth) && numericWidth >= 0) {
59269
+ return ["width", `${numericWidth}px`];
59270
+ }
58953
59271
  }
58954
59272
  return ["min-width", `${minWidth}px`];
58955
59273
  };
@@ -58971,7 +59289,7 @@ const createTableView = ({ editor }) => {
58971
59289
  this.table = this.dom.appendChild(document.createElement("table"));
58972
59290
  this.colgroup = this.table.appendChild(document.createElement("colgroup"));
58973
59291
  updateTable(this.editor, this.node, this.table);
58974
- updateColumns(node, this.colgroup, this.table, cellMinWidth2);
59292
+ updateColumns(node, this.colgroup, this.table, cellMinWidth2, void 0, void 0, this.editor);
58975
59293
  this.contentDOM = this.table.appendChild(document.createElement("tbody"));
58976
59294
  setTimeout(() => {
58977
59295
  updateTableWrapper(this.dom, this.table);
@@ -58983,7 +59301,7 @@ const createTableView = ({ editor }) => {
58983
59301
  }
58984
59302
  this.node = node;
58985
59303
  updateTable(this.editor, node, this.table);
58986
- updateColumns(node, this.colgroup, this.table, this.cellMinWidth);
59304
+ updateColumns(node, this.colgroup, this.table, this.cellMinWidth, void 0, void 0, this.editor);
58987
59305
  updateTableWrapper(this.dom, this.table);
58988
59306
  return true;
58989
59307
  }
@@ -58996,46 +59314,105 @@ const createTableView = ({ editor }) => {
58996
59314
  }
58997
59315
  };
58998
59316
  };
58999
- function updateColumns(node, colgroup, table, cellMinWidth2, overrideCol, overrideValue) {
59000
- let totalWidth = 0;
59001
- let fixedWidth = true;
59002
- let nextDOM = colgroup.firstChild;
59317
+ function updateColumns(node, colgroup, table, cellMinWidth2, overrideCol, overrideValue, editor) {
59318
+ const gridColumns = Array.isArray(node.attrs?.grid) && node.attrs.grid.length ? node.attrs.grid.map((col) => twipsToPixels(col.col)) : null;
59319
+ const totalColumns = gridColumns?.length ?? null;
59320
+ const pageBody = table.closest(".page__body");
59321
+ const wrapper = table.parentElement;
59322
+ let availableWidth = pageBody?.getBoundingClientRect?.().width;
59323
+ if (!availableWidth && wrapper) {
59324
+ availableWidth = wrapper.getBoundingClientRect().width;
59325
+ }
59326
+ if (typeof availableWidth === "number" && !Number.isNaN(availableWidth)) {
59327
+ availableWidth = Math.max(availableWidth - 2, 0);
59328
+ } else {
59329
+ availableWidth = null;
59330
+ }
59331
+ const pageStyles = editor?.converter?.pageStyles;
59332
+ if (pageStyles?.pageSize?.width) {
59333
+ const toNumber = (v2) => typeof v2 === "number" ? v2 : parseFloat(v2) || 0;
59334
+ const pageWidth = toNumber(pageStyles.pageSize.width);
59335
+ const marginLeft = toNumber(pageStyles.pageMargins?.left);
59336
+ const marginRight = toNumber(pageStyles.pageMargins?.right);
59337
+ const pageAvailableWidthPx = Math.max((pageWidth - marginLeft - marginRight) * PIXELS_PER_INCH, 0);
59338
+ if (pageAvailableWidthPx > 0) {
59339
+ availableWidth = availableWidth ? Math.min(availableWidth, pageAvailableWidthPx) : pageAvailableWidthPx;
59340
+ }
59341
+ }
59342
+ const resolveColumnWidth = (colIndex2, colwidthValue) => {
59343
+ if (overrideCol === colIndex2) return overrideValue;
59344
+ if (colwidthValue != null) return colwidthValue;
59345
+ if (gridColumns && gridColumns[colIndex2] != null) return gridColumns[colIndex2];
59346
+ return null;
59347
+ };
59348
+ const widths = [];
59003
59349
  const row = node.firstChild;
59350
+ let colIndex = 0;
59004
59351
  if (row !== null) {
59005
- for (let i = 0, col = 0; i < row.childCount; i++) {
59006
- const { colspan, colwidth } = row.child(i).attrs;
59007
- for (let j2 = 0; j2 < colspan; j2++, col++) {
59008
- const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j2];
59009
- const cssWidth = hasWidth ? `${hasWidth}px` : "";
59010
- totalWidth += hasWidth || cellMinWidth2;
59011
- if (!hasWidth) fixedWidth = false;
59012
- if (!nextDOM) {
59013
- const col2 = document.createElement("col");
59014
- const [propKey, propVal] = getColStyleDeclaration(cellMinWidth2, hasWidth);
59015
- col2.style.setProperty(propKey, propVal);
59016
- colgroup.appendChild(col2);
59017
- } else {
59018
- if (nextDOM.style.width !== cssWidth) {
59019
- const [propKey, propVal] = getColStyleDeclaration(cellMinWidth2, hasWidth);
59020
- nextDOM.style.setProperty(propKey, propVal);
59021
- }
59022
- nextDOM = nextDOM.nextSibling;
59023
- }
59352
+ for (let i = 0; i < row.childCount; i++) {
59353
+ const child = row.child(i);
59354
+ const { colspan, colwidth } = child.attrs;
59355
+ for (let span = 0; span < colspan; span += 1, colIndex += 1) {
59356
+ widths.push(resolveColumnWidth(colIndex, colwidth && colwidth[span]));
59024
59357
  }
59025
59358
  }
59026
59359
  }
59027
- while (nextDOM) {
59028
- const after = nextDOM.nextSibling;
59029
- nextDOM.parentNode?.removeChild(nextDOM);
59030
- nextDOM = after;
59360
+ if (totalColumns != null && colIndex < totalColumns) {
59361
+ for (let col = colIndex; col < totalColumns; col += 1) {
59362
+ widths.push(resolveColumnWidth(col));
59363
+ }
59031
59364
  }
59032
- if (fixedWidth) {
59033
- table.style.width = `${totalWidth}px`;
59365
+ const normalizedWidths = widths.map((widthPx) => {
59366
+ const numericWidth = Number(widthPx);
59367
+ if (!Number.isFinite(numericWidth)) return null;
59368
+ if (numericWidth < 0) return null;
59369
+ if (numericWidth === 0) return 0;
59370
+ if (numericWidth < 1) return 0;
59371
+ return numericWidth;
59372
+ });
59373
+ const rawTotalWidth = normalizedWidths.reduce((sum, width) => sum + (width != null ? width : cellMinWidth2), 0);
59374
+ let scale = 1;
59375
+ if (availableWidth && rawTotalWidth > 0 && rawTotalWidth > availableWidth) {
59376
+ scale = availableWidth / rawTotalWidth;
59377
+ }
59378
+ let totalWidth = 0;
59379
+ let hasUndefinedWidth = false;
59380
+ let dom = colgroup.firstChild;
59381
+ normalizedWidths.forEach((width) => {
59382
+ let scaledWidth = width;
59383
+ if (scaledWidth != null) {
59384
+ scaledWidth = scaledWidth * scale;
59385
+ }
59386
+ const [propKey, propVal] = getColStyleDeclaration(cellMinWidth2, scaledWidth);
59387
+ if (scaledWidth == null) {
59388
+ totalWidth += cellMinWidth2;
59389
+ hasUndefinedWidth = true;
59390
+ } else {
59391
+ totalWidth += scaledWidth;
59392
+ }
59393
+ if (!dom) {
59394
+ const colElement = document.createElement("col");
59395
+ colElement.style.setProperty(propKey, propVal);
59396
+ colgroup.appendChild(colElement);
59397
+ } else {
59398
+ dom.style.setProperty(propKey, propVal);
59399
+ dom = dom.nextSibling;
59400
+ }
59401
+ });
59402
+ while (dom) {
59403
+ const next = dom.nextSibling;
59404
+ dom.parentNode?.removeChild(dom);
59405
+ dom = next;
59406
+ }
59407
+ if (scale < 1 || !hasUndefinedWidth) {
59408
+ const clampedWidth = Math.min(totalWidth, availableWidth || totalWidth);
59409
+ table.style.width = `${clampedWidth}px`;
59034
59410
  table.style.minWidth = "";
59035
59411
  } else {
59036
59412
  table.style.width = "";
59037
59413
  table.style.minWidth = `${totalWidth}px`;
59038
59414
  }
59415
+ table.style.maxWidth = "100%";
59039
59416
  }
59040
59417
  function updateTable(editor, node, table) {
59041
59418
  const allExtensionsAttrs = editor.extensionService.attributes;
@@ -59113,22 +59490,61 @@ const createTable = (schema, rowsCount, colsCount, withHeaderRow, cellContent =
59113
59490
  const tableBorders = createTableBorders();
59114
59491
  return types2.table.createChecked({ borders: tableBorders }, rows);
59115
59492
  };
59493
+ const MIN_MEANINGFUL_WIDTH_PX = 1;
59116
59494
  const createColGroup = (node, cellMinWidth2, overrideCol, overrideValue) => {
59117
59495
  let totalWidth = 0;
59118
59496
  let fixedWidth = true;
59119
59497
  const cols = [];
59120
59498
  const colsValues = [];
59121
59499
  const row = node.firstChild;
59500
+ const gridColumns = Array.isArray(node.attrs?.grid) && node.attrs.grid.length ? node.attrs.grid.map((col) => twipsToPixels(col.col)) : null;
59122
59501
  if (!row) return {};
59123
- for (let i = 0, col = 0; i < row.childCount; i++) {
59124
- const { colspan, colwidth } = row.child(i).attrs;
59125
- for (let j2 = 0; j2 < colspan; j2++, col++) {
59126
- const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j2];
59127
- totalWidth += hasWidth || cellMinWidth2;
59128
- if (!hasWidth) fixedWidth = false;
59129
- const [prop, value] = getColStyleDeclaration(cellMinWidth2, hasWidth);
59502
+ const totalColumns = gridColumns?.length;
59503
+ const resolveColumnWidth = (colIndex2, colwidthValue) => {
59504
+ if (overrideCol === colIndex2) return overrideValue;
59505
+ if (colwidthValue != null) return colwidthValue;
59506
+ if (gridColumns && gridColumns[colIndex2] != null) return gridColumns[colIndex2];
59507
+ return null;
59508
+ };
59509
+ let colIndex = 0;
59510
+ for (let i = 0; i < row.childCount; i++) {
59511
+ const child = row.child(i);
59512
+ const { colspan, colwidth } = child.attrs;
59513
+ for (let j2 = 0; j2 < colspan; j2++, colIndex++) {
59514
+ const candidateWidth = resolveColumnWidth(colIndex, colwidth && colwidth[j2]);
59515
+ const numericWidth = Number(candidateWidth);
59516
+ let effectiveWidth = Number.isFinite(numericWidth) && numericWidth > 0 ? numericWidth : null;
59517
+ if (effectiveWidth != null && effectiveWidth < MIN_MEANINGFUL_WIDTH_PX) {
59518
+ effectiveWidth = 0;
59519
+ }
59520
+ if (effectiveWidth == null) {
59521
+ totalWidth += cellMinWidth2;
59522
+ fixedWidth = false;
59523
+ } else {
59524
+ totalWidth += effectiveWidth;
59525
+ }
59526
+ const [prop, value] = getColStyleDeclaration(cellMinWidth2, effectiveWidth);
59130
59527
  cols.push(["col", { style: `${prop}: ${value}` }]);
59131
- colsValues.push(parseInt(value, 10));
59528
+ colsValues.push(parseFloat(value));
59529
+ }
59530
+ }
59531
+ if (totalColumns != null) {
59532
+ for (let col = colIndex; col < totalColumns; col++) {
59533
+ const candidateWidth = resolveColumnWidth(col);
59534
+ const numericWidth = Number(candidateWidth);
59535
+ let effectiveWidth = Number.isFinite(numericWidth) && numericWidth > 0 ? numericWidth : null;
59536
+ if (effectiveWidth != null && effectiveWidth < MIN_MEANINGFUL_WIDTH_PX) {
59537
+ effectiveWidth = 0;
59538
+ }
59539
+ if (effectiveWidth == null) {
59540
+ totalWidth += cellMinWidth2;
59541
+ fixedWidth = false;
59542
+ } else {
59543
+ totalWidth += effectiveWidth;
59544
+ }
59545
+ const [prop, value] = getColStyleDeclaration(cellMinWidth2, effectiveWidth);
59546
+ cols.push(["col", { style: `${prop}: ${value}` }]);
59547
+ colsValues.push(parseFloat(value));
59132
59548
  }
59133
59549
  }
59134
59550
  const tableWidth = fixedWidth ? `${totalWidth}px` : "";
@@ -62031,6 +62447,19 @@ const TableHeader = Node$1.create({
62031
62447
  "data-colwidth": attrs.colwidth.join(",")
62032
62448
  };
62033
62449
  }
62450
+ },
62451
+ __placeholder: {
62452
+ default: null,
62453
+ parseDOM: (element) => {
62454
+ const value = element.getAttribute("data-placeholder");
62455
+ return value || null;
62456
+ },
62457
+ renderDOM({ __placeholder }) {
62458
+ if (!__placeholder) return {};
62459
+ return {
62460
+ "data-placeholder": __placeholder
62461
+ };
62462
+ }
62034
62463
  }
62035
62464
  };
62036
62465
  },
@@ -62191,6 +62620,19 @@ const TableCell = Node$1.create({
62191
62620
  default: "px",
62192
62621
  rendered: false
62193
62622
  },
62623
+ __placeholder: {
62624
+ default: null,
62625
+ parseDOM: (element) => {
62626
+ const value = element.getAttribute("data-placeholder");
62627
+ return value || null;
62628
+ },
62629
+ renderDOM({ __placeholder }) {
62630
+ if (!__placeholder) return {};
62631
+ return {
62632
+ "data-placeholder": __placeholder
62633
+ };
62634
+ }
62635
+ },
62194
62636
  /**
62195
62637
  * @category Attribute
62196
62638
  * @param {TableCellProperties} tableCellProperties - Properties for the table cell.