@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
@@ -15076,6 +15076,7 @@ async function readFromClipboard(state2) {
15076
15076
  }
15077
15077
  return content;
15078
15078
  }
15079
+ const PIXELS_PER_INCH = 96;
15079
15080
  function inchesToTwips(inches) {
15080
15081
  if (inches == null) return;
15081
15082
  if (typeof inches === "string") inches = parseFloat(inches);
@@ -15098,12 +15099,12 @@ function pixelsToTwips(pixels) {
15098
15099
  }
15099
15100
  function inchesToPixels(inches) {
15100
15101
  if (inches == null) return;
15101
- const pixels = inches * 96;
15102
+ const pixels = inches * PIXELS_PER_INCH;
15102
15103
  return Math.round(pixels * 1e3) / 1e3;
15103
15104
  }
15104
15105
  function pixelsToInches(pixels) {
15105
15106
  if (pixels == null) return;
15106
- const inches = Number(pixels) / 96;
15107
+ const inches = Number(pixels) / PIXELS_PER_INCH;
15107
15108
  return inches;
15108
15109
  }
15109
15110
  function twipsToLines(twips) {
@@ -15121,7 +15122,7 @@ function halfPointToPoints(halfPoints) {
15121
15122
  function emuToPixels(emu) {
15122
15123
  if (emu == null) return;
15123
15124
  if (typeof emu === "string") emu = parseFloat(emu);
15124
- const pixels = emu * 96 / 914400;
15125
+ const pixels = emu * PIXELS_PER_INCH / 914400;
15125
15126
  return Math.round(pixels);
15126
15127
  }
15127
15128
  function pixelsToEmu(px) {
@@ -15157,12 +15158,12 @@ function degreesToRot(degrees) {
15157
15158
  }
15158
15159
  function pixelsToPolygonUnits(pixels) {
15159
15160
  if (pixels == null) return;
15160
- const pu = pixels * 96;
15161
+ const pu = pixels * PIXELS_PER_INCH;
15161
15162
  return Math.round(pu);
15162
15163
  }
15163
15164
  function polygonUnitsToPixels(pu) {
15164
15165
  if (pu == null) return;
15165
- const pixels = Number(pu) / 96;
15166
+ const pixels = Number(pu) / PIXELS_PER_INCH;
15166
15167
  return Math.round(pixels * 1e3) / 1e3;
15167
15168
  }
15168
15169
  function polygonToObj(polygonNode) {
@@ -27038,6 +27039,68 @@ const translator$_ = NodeTranslator.from(
27038
27039
  repeatHeader: false
27039
27040
  })
27040
27041
  );
27042
+ const createPlaceholderCell = (gridWidth, reason) => {
27043
+ const safeWidth = Number.isFinite(gridWidth) ? gridWidth : 0;
27044
+ const noBorder = { val: "none", size: 0 };
27045
+ return {
27046
+ type: "tableCell",
27047
+ attrs: {
27048
+ colspan: 1,
27049
+ rowspan: 1,
27050
+ colwidth: [safeWidth],
27051
+ __placeholder: reason,
27052
+ borders: {
27053
+ top: { ...noBorder },
27054
+ right: { ...noBorder },
27055
+ bottom: { ...noBorder },
27056
+ left: { ...noBorder }
27057
+ }
27058
+ },
27059
+ content: [{ type: "paragraph", content: [] }]
27060
+ };
27061
+ };
27062
+ const advancePastRowSpans = (pendingRowSpans, startIndex, totalColumns) => {
27063
+ let index2 = startIndex;
27064
+ while (index2 < totalColumns && pendingRowSpans[index2] > 0) {
27065
+ pendingRowSpans[index2] -= 1;
27066
+ index2 += 1;
27067
+ }
27068
+ return index2;
27069
+ };
27070
+ const fillPlaceholderColumns = ({
27071
+ content,
27072
+ pendingRowSpans,
27073
+ currentIndex,
27074
+ targetIndex,
27075
+ totalColumns,
27076
+ gridColumnWidths,
27077
+ reason
27078
+ }) => {
27079
+ let index2 = currentIndex;
27080
+ while (index2 < targetIndex && index2 < totalColumns) {
27081
+ if (pendingRowSpans[index2] > 0) {
27082
+ pendingRowSpans[index2] -= 1;
27083
+ index2 += 1;
27084
+ continue;
27085
+ }
27086
+ const width = Array.isArray(gridColumnWidths) ? gridColumnWidths[index2] ?? 0 : 0;
27087
+ content.push(createPlaceholderCell(width, reason));
27088
+ index2 += 1;
27089
+ }
27090
+ return index2;
27091
+ };
27092
+ const isPlaceholderCell = (cell) => {
27093
+ if (!cell) return false;
27094
+ if (cell.attrs?.__placeholder) return true;
27095
+ const widths = cell.attrs?.colwidth;
27096
+ if (Array.isArray(widths) && widths.length > 0) {
27097
+ const hasMeaningfulWidth = widths.some(
27098
+ (value) => typeof value === "number" && Number.isFinite(value) && Math.abs(value) > 1
27099
+ );
27100
+ if (!hasMeaningfulWidth) return true;
27101
+ }
27102
+ return false;
27103
+ };
27041
27104
  const XML_NODE_NAME$h = "w:tr";
27042
27105
  const SD_NODE_NAME$d = "tableRow";
27043
27106
  const validXmlAttributes$b = ["w:rsidDel", "w:rsidR", "w:rsidRPr", "w:rsidTr", "w14:paraId", "w14:textId"].map(
@@ -27053,29 +27116,64 @@ const encode$n = (params2, encodedAttrs) => {
27053
27116
  nodes: [tPr]
27054
27117
  });
27055
27118
  }
27119
+ const gridBeforeRaw = tableRowProperties?.["gridBefore"];
27120
+ const safeGridBefore = typeof gridBeforeRaw === "number" && Number.isFinite(gridBeforeRaw) && gridBeforeRaw > 0 ? gridBeforeRaw : 0;
27056
27121
  encodedAttrs["tableRowProperties"] = Object.freeze(tableRowProperties);
27057
27122
  encodedAttrs["rowHeight"] = twipsToPixels(tableRowProperties["rowHeight"]?.value);
27058
27123
  encodedAttrs["cantSplit"] = tableRowProperties["cantSplit"];
27059
- const { columnWidths: gridColumnWidths } = params2.extraParams;
27124
+ const { columnWidths: gridColumnWidths, activeRowSpans = [] } = params2.extraParams;
27125
+ const totalColumns = Array.isArray(gridColumnWidths) ? gridColumnWidths.length : 0;
27126
+ const pendingRowSpans = Array.isArray(activeRowSpans) ? activeRowSpans.slice() : [];
27127
+ while (pendingRowSpans.length < totalColumns) pendingRowSpans.push(0);
27060
27128
  const cellNodes = row.elements.filter((el) => el.name === "w:tc");
27129
+ const content = [];
27061
27130
  let currentColumnIndex = 0;
27062
- const content = cellNodes?.map((n) => {
27063
- let columnWidth = gridColumnWidths?.[currentColumnIndex] || null;
27131
+ const fillUntil = (target, reason) => {
27132
+ currentColumnIndex = fillPlaceholderColumns({
27133
+ content,
27134
+ pendingRowSpans,
27135
+ currentIndex: currentColumnIndex,
27136
+ targetIndex: target,
27137
+ totalColumns,
27138
+ gridColumnWidths,
27139
+ reason
27140
+ });
27141
+ };
27142
+ const skipOccupiedColumns = () => {
27143
+ currentColumnIndex = advancePastRowSpans(pendingRowSpans, currentColumnIndex, totalColumns);
27144
+ };
27145
+ fillUntil(safeGridBefore, "gridBefore");
27146
+ skipOccupiedColumns();
27147
+ cellNodes?.forEach((node) => {
27148
+ skipOccupiedColumns();
27149
+ const startColumn = currentColumnIndex;
27150
+ const columnWidth = gridColumnWidths?.[startColumn] || null;
27064
27151
  const result = translator$c.encode({
27065
27152
  ...params2,
27066
27153
  extraParams: {
27067
27154
  ...params2.extraParams,
27068
- node: n,
27069
- columnIndex: currentColumnIndex,
27155
+ node,
27156
+ columnIndex: startColumn,
27070
27157
  columnWidth
27071
27158
  }
27072
27159
  });
27073
- const tcPr = n.elements?.find((el) => el.name === "w:tcPr");
27074
- const colspanTag = tcPr?.elements?.find((el) => el.name === "w:gridSpan");
27075
- const colspan = parseInt(colspanTag?.attributes["w:val"] || 1, 10);
27076
- currentColumnIndex += colspan;
27077
- return result;
27078
- }) || [];
27160
+ if (result) {
27161
+ content.push(result);
27162
+ const colspan = Math.max(1, result.attrs?.colspan || 1);
27163
+ const rowspan = Math.max(1, result.attrs?.rowspan || 1);
27164
+ if (rowspan > 1) {
27165
+ for (let offset2 = 0; offset2 < colspan; offset2 += 1) {
27166
+ const target = startColumn + offset2;
27167
+ if (target < pendingRowSpans.length) {
27168
+ pendingRowSpans[target] = Math.max(pendingRowSpans[target], rowspan - 1);
27169
+ }
27170
+ }
27171
+ }
27172
+ currentColumnIndex = startColumn + colspan;
27173
+ }
27174
+ });
27175
+ skipOccupiedColumns();
27176
+ fillUntil(totalColumns, "gridAfter");
27079
27177
  const newNode = {
27080
27178
  type: "tableRow",
27081
27179
  content,
@@ -27085,9 +27183,37 @@ const encode$n = (params2, encodedAttrs) => {
27085
27183
  };
27086
27184
  const decode$p = (params2, decodedAttrs) => {
27087
27185
  const { node } = params2;
27088
- const elements = translateChildNodes(params2);
27186
+ const cells = node.content || [];
27187
+ let leadingPlaceholders = 0;
27188
+ while (leadingPlaceholders < cells.length && isPlaceholderCell(cells[leadingPlaceholders])) {
27189
+ leadingPlaceholders += 1;
27190
+ }
27191
+ let trailingPlaceholders = 0;
27192
+ while (trailingPlaceholders < cells.length - leadingPlaceholders && isPlaceholderCell(cells[cells.length - 1 - trailingPlaceholders])) {
27193
+ trailingPlaceholders += 1;
27194
+ }
27195
+ const trimmedSlice = cells.slice(leadingPlaceholders, cells.length - trailingPlaceholders);
27196
+ const sanitizedCells = trimmedSlice.map((cell) => {
27197
+ if (cell?.attrs && "__placeholder" in cell.attrs) {
27198
+ const { __placeholder, ...rest } = cell.attrs;
27199
+ return { ...cell, attrs: rest };
27200
+ }
27201
+ return cell;
27202
+ });
27203
+ const trimmedContent = sanitizedCells.filter((_2, index2) => !isPlaceholderCell(trimmedSlice[index2]));
27204
+ const translateParams = {
27205
+ ...params2,
27206
+ node: { ...node, content: trimmedContent }
27207
+ };
27208
+ const elements = translateChildNodes(translateParams);
27089
27209
  if (node.attrs?.tableRowProperties) {
27090
27210
  const tableRowProperties = { ...node.attrs.tableRowProperties };
27211
+ if (leadingPlaceholders > 0) {
27212
+ tableRowProperties.gridBefore = leadingPlaceholders;
27213
+ }
27214
+ if (trailingPlaceholders > 0) {
27215
+ tableRowProperties.gridAfter = trailingPlaceholders;
27216
+ }
27091
27217
  if (node.attrs.rowHeight != null) {
27092
27218
  const rowHeightPixels = twipsToPixels(node.attrs.tableRowProperties["rowHeight"]?.value);
27093
27219
  if (rowHeightPixels !== node.attrs.rowHeight) {
@@ -27317,17 +27443,21 @@ const decode$o = (params2) => {
27317
27443
  const fallbackColumnWidthTwips = resolveFallbackColumnWidthTwips(params2, totalColumns, cellMinWidth);
27318
27444
  const elements = [];
27319
27445
  let columnIndex = 0;
27320
- const pushColumn = (widthTwips) => {
27446
+ const pushColumn = (widthTwips, { enforceMinimum = false } = {}) => {
27321
27447
  let numericWidth = typeof widthTwips === "string" ? parseInt(widthTwips, 10) : widthTwips;
27448
+ let shouldEnforceMinimum = enforceMinimum;
27322
27449
  if (numericWidth == null || Number.isNaN(numericWidth) || numericWidth <= 0) {
27323
27450
  numericWidth = fallbackColumnWidthTwips;
27451
+ shouldEnforceMinimum = true;
27324
27452
  }
27325
- numericWidth = Math.max(numericWidth, cellMinWidth);
27453
+ const roundedWidth = Math.round(numericWidth);
27454
+ const minimumWidth = shouldEnforceMinimum ? cellMinWidth : 1;
27455
+ const safeWidth = Math.max(roundedWidth, minimumWidth);
27326
27456
  const decoded = translator$u.decode({
27327
27457
  node: { type: (
27328
27458
  /** @type {string} */
27329
27459
  translator$u.sdNodeOrKeyName
27330
- ), attrs: { col: numericWidth } }
27460
+ ), attrs: { col: safeWidth } }
27331
27461
  });
27332
27462
  if (decoded) elements.push(decoded);
27333
27463
  };
@@ -27335,13 +27465,17 @@ const decode$o = (params2) => {
27335
27465
  const { colspan = 1, colwidth } = cell?.attrs || {};
27336
27466
  const spanCount = Math.max(1, colspan);
27337
27467
  for (let span = 0; span < spanCount; span++) {
27338
- const cellWidthPixels = Array.isArray(colwidth) ? colwidth[span] : void 0;
27468
+ const rawWidth = Array.isArray(colwidth) ? colwidth[span] : void 0;
27469
+ const cellWidthPixels = typeof rawWidth === "number" && Number.isFinite(rawWidth) ? rawWidth : Number(rawWidth);
27470
+ const hasCellWidth = Number.isFinite(cellWidthPixels) && cellWidthPixels > 0;
27339
27471
  const colGridAttrs = grid?.[columnIndex] || {};
27340
27472
  const gridWidthTwips = normalizeTwipWidth(colGridAttrs.col);
27341
27473
  const gridWidthPixels = gridWidthTwips != null ? twipsToPixels(gridWidthTwips) : null;
27342
27474
  let cellWidthTwips;
27343
- if (cellWidthPixels != null) {
27344
- if (gridWidthTwips != null && gridWidthPixels === cellWidthPixels) {
27475
+ let enforceMinimum = false;
27476
+ if (hasCellWidth) {
27477
+ const tolerance = 0.5;
27478
+ if (gridWidthTwips != null && gridWidthPixels != null && Math.abs(gridWidthPixels - cellWidthPixels) <= tolerance) {
27345
27479
  cellWidthTwips = gridWidthTwips;
27346
27480
  } else {
27347
27481
  cellWidthTwips = pixelsToTwips(cellWidthPixels);
@@ -27350,8 +27484,9 @@ const decode$o = (params2) => {
27350
27484
  cellWidthTwips = gridWidthTwips;
27351
27485
  } else {
27352
27486
  cellWidthTwips = fallbackColumnWidthTwips;
27487
+ enforceMinimum = true;
27353
27488
  }
27354
- pushColumn(cellWidthTwips);
27489
+ pushColumn(cellWidthTwips, { enforceMinimum });
27355
27490
  columnIndex++;
27356
27491
  }
27357
27492
  });
@@ -27514,7 +27649,9 @@ const encode$l = (params2, encodedAttrs) => {
27514
27649
  }
27515
27650
  }
27516
27651
  const content = [];
27517
- rows.forEach((row) => {
27652
+ const totalColumns = columnWidths.length;
27653
+ const activeRowSpans = totalColumns > 0 ? new Array(totalColumns).fill(0) : [];
27654
+ rows.forEach((row, rowIndex) => {
27518
27655
  const result = translator$Z.encode({
27519
27656
  ...params2,
27520
27657
  nodes: [row],
@@ -27523,10 +27660,45 @@ const encode$l = (params2, encodedAttrs) => {
27523
27660
  table: node,
27524
27661
  rowBorders: borderRowData,
27525
27662
  styleTag: tblStyleTag,
27526
- columnWidths
27663
+ columnWidths,
27664
+ activeRowSpans: activeRowSpans.slice(),
27665
+ rowIndex
27527
27666
  }
27528
27667
  });
27529
- if (result) content.push(result);
27668
+ if (result) {
27669
+ content.push(result);
27670
+ if (totalColumns > 0) {
27671
+ const activeRowSpansForCurrentRow = activeRowSpans.slice();
27672
+ for (let col = 0; col < totalColumns; col++) {
27673
+ if (activeRowSpans[col] > 0) {
27674
+ activeRowSpans[col] -= 1;
27675
+ }
27676
+ }
27677
+ let columnIndex = 0;
27678
+ const advanceColumnIndex = () => {
27679
+ while (columnIndex < totalColumns && activeRowSpansForCurrentRow[columnIndex] > 0) {
27680
+ columnIndex += 1;
27681
+ }
27682
+ };
27683
+ advanceColumnIndex();
27684
+ result.content?.forEach((cell) => {
27685
+ advanceColumnIndex();
27686
+ const colspan = Math.max(1, cell.attrs?.colspan || 1);
27687
+ const rowspan = Math.max(1, cell.attrs?.rowspan || 1);
27688
+ if (rowspan > 1) {
27689
+ for (let offset2 = 0; offset2 < colspan && columnIndex + offset2 < totalColumns; offset2++) {
27690
+ const targetIndex = columnIndex + offset2;
27691
+ const remainingRows = rowspan - 1;
27692
+ if (remainingRows > 0 && remainingRows > activeRowSpans[targetIndex]) {
27693
+ activeRowSpans[targetIndex] = remainingRows;
27694
+ }
27695
+ }
27696
+ }
27697
+ columnIndex += colspan;
27698
+ advanceColumnIndex();
27699
+ });
27700
+ }
27701
+ }
27530
27702
  });
27531
27703
  return {
27532
27704
  type: "table",
@@ -27931,14 +28103,104 @@ function handleTableCellNode({
27931
28103
  }
27932
28104
  return {
27933
28105
  type: "tableCell",
27934
- content: nodeListHandler.handler({
27935
- ...params2,
27936
- nodes: node.elements,
27937
- path: [...params2.path || [], node]
27938
- }),
28106
+ content: normalizeTableCellContent(
28107
+ nodeListHandler.handler({
28108
+ ...params2,
28109
+ nodes: node.elements,
28110
+ path: [...params2.path || [], node]
28111
+ }),
28112
+ params2.editor
28113
+ ),
27939
28114
  attrs: attributes
27940
28115
  };
27941
28116
  }
28117
+ function normalizeTableCellContent(content, editor) {
28118
+ if (!Array.isArray(content) || content.length === 0) return content;
28119
+ const normalized = [];
28120
+ const pendingForNextBlock = [];
28121
+ const schema = editor?.schema;
28122
+ const cloneBlock = (node) => {
28123
+ if (!node) return node;
28124
+ const cloned = { ...node };
28125
+ if (Array.isArray(node.content)) {
28126
+ cloned.content = [...node.content];
28127
+ }
28128
+ return cloned;
28129
+ };
28130
+ const ensureArray = (node) => {
28131
+ if (!Array.isArray(node.content)) {
28132
+ node.content = [];
28133
+ }
28134
+ return node.content;
28135
+ };
28136
+ const isInlineNode = (node) => {
28137
+ if (!node || typeof node.type !== "string") return false;
28138
+ if (node.type === "text") return true;
28139
+ if (node.type === "bookmarkStart" || node.type === "bookmarkEnd") return true;
28140
+ const nodeType = schema?.nodes?.[node.type];
28141
+ if (nodeType) {
28142
+ if (typeof nodeType.isInline === "boolean") return nodeType.isInline;
28143
+ if (nodeType.spec?.group && typeof nodeType.spec.group === "string") {
28144
+ return nodeType.spec.group.split(" ").includes("inline");
28145
+ }
28146
+ }
28147
+ return false;
28148
+ };
28149
+ for (const node of content) {
28150
+ if (!node || typeof node.type !== "string") {
28151
+ normalized.push(node);
28152
+ continue;
28153
+ }
28154
+ if (!isInlineNode(node)) {
28155
+ const blockNode = cloneBlock(node);
28156
+ if (pendingForNextBlock.length) {
28157
+ const blockContent = ensureArray(blockNode);
28158
+ const leadingInline = pendingForNextBlock.splice(0);
28159
+ blockNode.content = [...leadingInline, ...blockContent];
28160
+ } else if (Array.isArray(blockNode.content)) {
28161
+ blockNode.content = [...blockNode.content];
28162
+ }
28163
+ normalized.push(blockNode);
28164
+ continue;
28165
+ }
28166
+ const targetIsNextBlock = node.type === "bookmarkStart" || normalized.length === 0;
28167
+ if (targetIsNextBlock) {
28168
+ pendingForNextBlock.push(node);
28169
+ } else {
28170
+ const lastIndex = normalized.length - 1;
28171
+ const lastNode = normalized[lastIndex];
28172
+ if (!lastNode || typeof lastNode.type !== "string" || isInlineNode(lastNode)) {
28173
+ pendingForNextBlock.push(node);
28174
+ continue;
28175
+ }
28176
+ const blockContent = ensureArray(lastNode);
28177
+ if (pendingForNextBlock.length) {
28178
+ blockContent.push(...pendingForNextBlock.splice(0));
28179
+ }
28180
+ blockContent.push(node);
28181
+ }
28182
+ }
28183
+ if (pendingForNextBlock.length) {
28184
+ if (normalized.length) {
28185
+ const lastIndex = normalized.length - 1;
28186
+ const lastNode = normalized[lastIndex];
28187
+ if (lastNode && typeof lastNode.type === "string" && !isInlineNode(lastNode)) {
28188
+ const blockContent = ensureArray(lastNode);
28189
+ blockContent.push(...pendingForNextBlock);
28190
+ pendingForNextBlock.length = 0;
28191
+ }
28192
+ }
28193
+ if (pendingForNextBlock.length) {
28194
+ normalized.push({
28195
+ type: "paragraph",
28196
+ attrs: {},
28197
+ content: [...pendingForNextBlock]
28198
+ });
28199
+ pendingForNextBlock.length = 0;
28200
+ }
28201
+ }
28202
+ return normalized;
28203
+ }
27942
28204
  const processInlineCellBorders = (borders, rowBorders) => {
27943
28205
  if (!borders) return null;
27944
28206
  return ["bottom", "top", "left", "right"].reduce((acc, direction) => {
@@ -28492,6 +28754,7 @@ function sdtNodeTypeStrategy(node) {
28492
28754
  }
28493
28755
  return { type: "unknown", handler: null };
28494
28756
  }
28757
+ const DRAWING_XML_TAG = "w:drawing";
28495
28758
  function handleImageNode(node, params2, isAnchor) {
28496
28759
  const { docx, filename } = params2;
28497
28760
  const { attributes } = node;
@@ -28503,32 +28766,10 @@ function handleImageNode(node, params2, isAnchor) {
28503
28766
  };
28504
28767
  const extent = node.elements.find((el) => el.name === "wp:extent");
28505
28768
  const size2 = {
28506
- width: emuToPixels(extent.attributes?.cx),
28507
- height: emuToPixels(extent.attributes?.cy)
28769
+ width: emuToPixels(extent?.attributes?.cx),
28770
+ height: emuToPixels(extent?.attributes?.cy)
28508
28771
  };
28509
- const graphic = node.elements.find((el) => el.name === "a:graphic");
28510
- const graphicData = graphic.elements.find((el) => el.name === "a:graphicData");
28511
- const { uri: uri2 } = graphicData?.attributes || {};
28512
- const shapeURI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
28513
- if (!!uri2 && uri2 === shapeURI) {
28514
- return handleShapeDrawing(params2, node, graphicData);
28515
- }
28516
- const picture = graphicData.elements.find((el) => el.name === "pic:pic");
28517
- if (!picture || !picture.elements) return null;
28518
- const blipFill = picture.elements.find((el) => el.name === "pic:blipFill");
28519
- const blip = blipFill.elements.find((el) => el.name === "a:blip");
28520
- const spPr = picture.elements.find((el) => el.name === "pic:spPr");
28521
28772
  let transformData = {};
28522
- if (spPr) {
28523
- const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
28524
- if (xfrm?.attributes) {
28525
- transformData = {
28526
- rotation: rotToDegrees(xfrm.attributes["rot"]),
28527
- verticalFlip: xfrm.attributes["flipV"] === "1",
28528
- horizontalFlip: xfrm.attributes["flipH"] === "1"
28529
- };
28530
- }
28531
- }
28532
28773
  const effectExtent = node.elements.find((el) => el.name === "wp:effectExtent");
28533
28774
  if (effectExtent) {
28534
28775
  const sanitizeEmuValue = (value) => {
@@ -28537,22 +28778,26 @@ function handleImageNode(node, params2, isAnchor) {
28537
28778
  return Number.isFinite(numeric) ? numeric : 0;
28538
28779
  };
28539
28780
  transformData.sizeExtension = {
28540
- left: emuToPixels(sanitizeEmuValue(effectExtent.attributes["l"])),
28541
- top: emuToPixels(sanitizeEmuValue(effectExtent.attributes["t"])),
28542
- right: emuToPixels(sanitizeEmuValue(effectExtent.attributes["r"])),
28543
- bottom: emuToPixels(sanitizeEmuValue(effectExtent.attributes["b"]))
28781
+ left: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["l"])),
28782
+ top: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["t"])),
28783
+ right: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["r"])),
28784
+ bottom: emuToPixels(sanitizeEmuValue(effectExtent.attributes?.["b"]))
28544
28785
  };
28545
28786
  }
28546
28787
  const positionHTag = node.elements.find((el) => el.name === "wp:positionH");
28547
28788
  const positionH = positionHTag?.elements.find((el) => el.name === "wp:posOffset");
28548
28789
  const positionHValue = emuToPixels(positionH?.elements[0]?.text);
28549
- const hRelativeFrom = positionHTag?.attributes.relativeFrom;
28550
- const alignH = positionHTag?.elements.find((el) => el.name === "wp:align")?.elements[0]?.text;
28790
+ const hRelativeFrom = positionHTag?.attributes?.relativeFrom;
28791
+ const alignH = positionHTag?.elements.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
28551
28792
  const positionVTag = node.elements.find((el) => el.name === "wp:positionV");
28552
28793
  const positionV = positionVTag?.elements?.find((el) => el.name === "wp:posOffset");
28553
28794
  const positionVValue = emuToPixels(positionV?.elements[0]?.text);
28554
- const vRelativeFrom = positionVTag?.attributes.relativeFrom;
28555
- const alignV = positionVTag?.elements?.find((el) => el.name === "wp:align")?.elements[0]?.text;
28795
+ const vRelativeFrom = positionVTag?.attributes?.relativeFrom;
28796
+ const alignV = positionVTag?.elements?.find((el) => el.name === "wp:align")?.elements?.[0]?.text;
28797
+ const marginOffset = {
28798
+ horizontal: positionHValue,
28799
+ top: positionVValue
28800
+ };
28556
28801
  const simplePos = node.elements.find((el) => el.name === "wp:simplePos");
28557
28802
  const wrapNode = isAnchor ? node.elements.find(
28558
28803
  (el) => ["wp:wrapNone", "wp:wrapSquare", "wp:wrapThrough", "wp:wrapTight", "wp:wrapTopAndBottom"].includes(el.name)
@@ -28560,38 +28805,40 @@ function handleImageNode(node, params2, isAnchor) {
28560
28805
  const wrap2 = isAnchor ? { type: wrapNode?.name.slice(7) || "None", attrs: {} } : { type: "Inline" };
28561
28806
  switch (wrap2.type) {
28562
28807
  case "Square":
28563
- wrap2.attrs.wrapText = wrapNode.attributes.wrapText;
28564
- if ("distB" in (wrapNode.attributes || {})) {
28808
+ if (wrapNode?.attributes?.wrapText) {
28809
+ wrap2.attrs.wrapText = wrapNode.attributes.wrapText;
28810
+ }
28811
+ if ("distB" in (wrapNode?.attributes || {})) {
28565
28812
  wrap2.attrs.distBottom = emuToPixels(wrapNode.attributes.distB);
28566
28813
  }
28567
- if ("distL" in (wrapNode.attributes || {})) {
28814
+ if ("distL" in (wrapNode?.attributes || {})) {
28568
28815
  wrap2.attrs.distLeft = emuToPixels(wrapNode.attributes.distL);
28569
28816
  }
28570
- if ("distR" in (wrapNode.attributes || {})) {
28817
+ if ("distR" in (wrapNode?.attributes || {})) {
28571
28818
  wrap2.attrs.distRight = emuToPixels(wrapNode.attributes.distR);
28572
28819
  }
28573
- if ("distT" in (wrapNode.attributes || {})) {
28820
+ if ("distT" in (wrapNode?.attributes || {})) {
28574
28821
  wrap2.attrs.distTop = emuToPixels(wrapNode.attributes.distT);
28575
28822
  }
28576
28823
  break;
28577
28824
  case "Tight":
28578
28825
  case "Through": {
28579
- if ("distL" in (wrapNode.attributes || {})) {
28826
+ if ("distL" in (wrapNode?.attributes || {})) {
28580
28827
  wrap2.attrs.distLeft = emuToPixels(wrapNode.attributes.distL);
28581
28828
  }
28582
- if ("distR" in (wrapNode.attributes || {})) {
28829
+ if ("distR" in (wrapNode?.attributes || {})) {
28583
28830
  wrap2.attrs.distRight = emuToPixels(wrapNode.attributes.distR);
28584
28831
  }
28585
- if ("distT" in (wrapNode.attributes || {})) {
28832
+ if ("distT" in (wrapNode?.attributes || {})) {
28586
28833
  wrap2.attrs.distTop = emuToPixels(wrapNode.attributes.distT);
28587
28834
  }
28588
- if ("distB" in (wrapNode.attributes || {})) {
28835
+ if ("distB" in (wrapNode?.attributes || {})) {
28589
28836
  wrap2.attrs.distBottom = emuToPixels(wrapNode.attributes.distB);
28590
28837
  }
28591
- if ("wrapText" in (wrapNode.attributes || {})) {
28838
+ if ("wrapText" in (wrapNode?.attributes || {})) {
28592
28839
  wrap2.attrs.wrapText = wrapNode.attributes.wrapText;
28593
28840
  }
28594
- const polygon = wrapNode.elements?.find((el) => el.name === "wp:wrapPolygon");
28841
+ const polygon = wrapNode?.elements?.find((el) => el.name === "wp:wrapPolygon");
28595
28842
  if (polygon) {
28596
28843
  wrap2.attrs.polygon = polygonToObj(polygon);
28597
28844
  if (polygon.attributes?.edited !== void 0) {
@@ -28601,10 +28848,10 @@ function handleImageNode(node, params2, isAnchor) {
28601
28848
  break;
28602
28849
  }
28603
28850
  case "TopAndBottom":
28604
- if ("distB" in (wrapNode.attributes || {})) {
28851
+ if ("distB" in (wrapNode?.attributes || {})) {
28605
28852
  wrap2.attrs.distBottom = emuToPixels(wrapNode.attributes.distB);
28606
28853
  }
28607
- if ("distT" in (wrapNode.attributes || {})) {
28854
+ if ("distT" in (wrapNode?.attributes || {})) {
28608
28855
  wrap2.attrs.distTop = emuToPixels(wrapNode.attributes.distT);
28609
28856
  }
28610
28857
  break;
@@ -28622,17 +28869,42 @@ function handleImageNode(node, params2, isAnchor) {
28622
28869
  alignV
28623
28870
  };
28624
28871
  }
28625
- const marginOffset = {
28626
- horizontal: positionHValue,
28627
- top: positionVValue
28628
- };
28872
+ const graphic = node.elements.find((el) => el.name === "a:graphic");
28873
+ const graphicData = graphic?.elements.find((el) => el.name === "a:graphicData");
28874
+ const { uri: uri2 } = graphicData?.attributes || {};
28875
+ const shapeURI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
28876
+ if (!!uri2 && uri2 === shapeURI) {
28877
+ const shapeMarginOffset = {
28878
+ left: positionHValue,
28879
+ horizontal: positionHValue,
28880
+ top: positionVValue
28881
+ };
28882
+ return handleShapeDrawing(params2, node, graphicData, size2, padding, shapeMarginOffset);
28883
+ }
28884
+ const picture = graphicData?.elements.find((el) => el.name === "pic:pic");
28885
+ if (!picture || !picture.elements) return null;
28886
+ const blipFill = picture.elements.find((el) => el.name === "pic:blipFill");
28887
+ const blip = blipFill?.elements.find((el) => el.name === "a:blip");
28888
+ if (!blip) return null;
28889
+ const spPr = picture.elements.find((el) => el.name === "pic:spPr");
28890
+ if (spPr) {
28891
+ const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
28892
+ if (xfrm?.attributes) {
28893
+ transformData = {
28894
+ ...transformData,
28895
+ rotation: rotToDegrees(xfrm.attributes["rot"]),
28896
+ verticalFlip: xfrm.attributes["flipV"] === "1",
28897
+ horizontalFlip: xfrm.attributes["flipH"] === "1"
28898
+ };
28899
+ }
28900
+ }
28629
28901
  const { attributes: blipAttributes = {} } = blip;
28630
28902
  const rEmbed = blipAttributes["r:embed"];
28631
28903
  if (!rEmbed) return null;
28632
28904
  const currentFile = filename || "document.xml";
28633
28905
  let rels = docx[`word/_rels/${currentFile}.rels`];
28634
28906
  if (!rels) rels = docx[`word/_rels/document.xml.rels`];
28635
- const relationships = rels.elements.find((el) => el.name === "Relationships");
28907
+ const relationships = rels?.elements.find((el) => el.name === "Relationships");
28636
28908
  const { elements } = relationships || [];
28637
28909
  const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
28638
28910
  if (!rel) return null;
@@ -28645,10 +28917,10 @@ function handleImageNode(node, params2, isAnchor) {
28645
28917
  type: "image",
28646
28918
  attrs: {
28647
28919
  src: path,
28648
- alt: ["emf", "wmf"].includes(extension) ? "Unable to render EMF/WMF image" : docPr?.attributes.name || "Image",
28920
+ alt: ["emf", "wmf"].includes(extension) ? "Unable to render EMF/WMF image" : docPr?.attributes?.name || "Image",
28649
28921
  extension,
28650
- id: docPr?.attributes.id || "",
28651
- title: docPr?.attributes.descr || "Image",
28922
+ id: docPr?.attributes?.id || "",
28923
+ title: docPr?.attributes?.descr || "Image",
28652
28924
  inline: true,
28653
28925
  padding,
28654
28926
  marginOffset,
@@ -28663,6 +28935,10 @@ function handleImageNode(node, params2, isAnchor) {
28663
28935
  }
28664
28936
  },
28665
28937
  wrap: wrap2,
28938
+ ...wrap2.type === "Square" && wrap2.attrs.wrapText ? {
28939
+ wrapText: wrap2.attrs.wrapText
28940
+ } : {},
28941
+ wrapTopAndBottom: wrap2.type === "TopAndBottom",
28666
28942
  originalPadding: {
28667
28943
  distT: attributes["distT"],
28668
28944
  distB: attributes["distB"],
@@ -28674,7 +28950,7 @@ function handleImageNode(node, params2, isAnchor) {
28674
28950
  }
28675
28951
  };
28676
28952
  }
28677
- const handleShapeDrawing = (params2, node, graphicData) => {
28953
+ const handleShapeDrawing = (params2, node, graphicData, size2, padding, marginOffset) => {
28678
28954
  const wsp = graphicData.elements.find((el) => el.name === "wps:wsp");
28679
28955
  const textBox = wsp.elements.find((el) => el.name === "wps:txbx");
28680
28956
  const textBoxContent = textBox?.elements?.find((el) => el.name === "w:txbxContent");
@@ -28685,21 +28961,14 @@ const handleShapeDrawing = (params2, node, graphicData) => {
28685
28961
  return getRectangleShape(params2, spPr);
28686
28962
  }
28687
28963
  if (!textBoxContent) {
28688
- return null;
28964
+ return buildShapePlaceholder(node, size2, padding, marginOffset, "drawing");
28689
28965
  }
28690
- const { nodeListHandler } = params2;
28691
- const translatedElement = nodeListHandler.handler({
28692
- ...params2,
28693
- node: textBoxContent.elements[0],
28694
- nodes: textBoxContent.elements,
28695
- path: [...params2.path || [], textBoxContent]
28696
- });
28697
- return translatedElement[0];
28966
+ return buildShapePlaceholder(node, size2, padding, marginOffset, "textbox");
28698
28967
  };
28699
28968
  const getRectangleShape = (params2, node) => {
28700
28969
  const schemaAttrs = {};
28701
28970
  const [drawingNode] = params2.nodes;
28702
- if (drawingNode?.name === "w:drawing") {
28971
+ if (drawingNode?.name === DRAWING_XML_TAG) {
28703
28972
  schemaAttrs.drawingContent = drawingNode;
28704
28973
  }
28705
28974
  const xfrm = node.elements.find((el) => el.name === "a:xfrm");
@@ -28723,6 +28992,52 @@ const getRectangleShape = (params2, node) => {
28723
28992
  attrs: schemaAttrs
28724
28993
  };
28725
28994
  };
28995
+ const buildShapePlaceholder = (node, size2, padding, marginOffset, shapeType) => {
28996
+ const attrs = {
28997
+ drawingContent: {
28998
+ name: DRAWING_XML_TAG,
28999
+ elements: [carbonCopy(node)]
29000
+ },
29001
+ attributes: {
29002
+ "data-shape-type": shapeType
29003
+ }
29004
+ };
29005
+ if (size2 && (Number.isFinite(size2.width) || Number.isFinite(size2.height))) {
29006
+ attrs.size = {
29007
+ ...Number.isFinite(size2.width) ? { width: size2.width } : {},
29008
+ ...Number.isFinite(size2.height) ? { height: size2.height } : {}
29009
+ };
29010
+ }
29011
+ if (padding) {
29012
+ const paddingData = {};
29013
+ if (Number.isFinite(padding.top)) paddingData["data-padding-top"] = padding.top;
29014
+ if (Number.isFinite(padding.right)) paddingData["data-padding-right"] = padding.right;
29015
+ if (Number.isFinite(padding.bottom)) paddingData["data-padding-bottom"] = padding.bottom;
29016
+ if (Number.isFinite(padding.left)) paddingData["data-padding-left"] = padding.left;
29017
+ if (Object.keys(paddingData).length) {
29018
+ attrs.attributes = {
29019
+ ...attrs.attributes,
29020
+ ...paddingData
29021
+ };
29022
+ }
29023
+ }
29024
+ if (marginOffset) {
29025
+ const offsetData = {};
29026
+ const horizontal = Number.isFinite(marginOffset.horizontal) ? marginOffset.horizontal : Number.isFinite(marginOffset.left) ? marginOffset.left : void 0;
29027
+ if (Number.isFinite(horizontal)) offsetData["data-offset-x"] = horizontal;
29028
+ if (Number.isFinite(marginOffset.top)) offsetData["data-offset-y"] = marginOffset.top;
29029
+ if (Object.keys(offsetData).length) {
29030
+ attrs.attributes = {
29031
+ ...attrs.attributes,
29032
+ ...offsetData
29033
+ };
29034
+ }
29035
+ }
29036
+ return {
29037
+ type: "contentBlock",
29038
+ attrs
29039
+ };
29040
+ };
28726
29041
  function handleAnchorNode(params2) {
28727
29042
  const { node } = params2.extraParams;
28728
29043
  if (node.name !== "wp:anchor") {
@@ -58931,8 +59246,11 @@ const HardBreak = Node$1.create({
58931
59246
  }
58932
59247
  });
58933
59248
  const getColStyleDeclaration = (minWidth, width) => {
58934
- if (width) {
58935
- return ["width", `${Math.max(width, minWidth)}px`];
59249
+ if (width != null) {
59250
+ const numericWidth = Number(width);
59251
+ if (Number.isFinite(numericWidth) && numericWidth >= 0) {
59252
+ return ["width", `${numericWidth}px`];
59253
+ }
58936
59254
  }
58937
59255
  return ["min-width", `${minWidth}px`];
58938
59256
  };
@@ -58954,7 +59272,7 @@ const createTableView = ({ editor }) => {
58954
59272
  this.table = this.dom.appendChild(document.createElement("table"));
58955
59273
  this.colgroup = this.table.appendChild(document.createElement("colgroup"));
58956
59274
  updateTable(this.editor, this.node, this.table);
58957
- updateColumns(node, this.colgroup, this.table, cellMinWidth2);
59275
+ updateColumns(node, this.colgroup, this.table, cellMinWidth2, void 0, void 0, this.editor);
58958
59276
  this.contentDOM = this.table.appendChild(document.createElement("tbody"));
58959
59277
  setTimeout(() => {
58960
59278
  updateTableWrapper(this.dom, this.table);
@@ -58966,7 +59284,7 @@ const createTableView = ({ editor }) => {
58966
59284
  }
58967
59285
  this.node = node;
58968
59286
  updateTable(this.editor, node, this.table);
58969
- updateColumns(node, this.colgroup, this.table, this.cellMinWidth);
59287
+ updateColumns(node, this.colgroup, this.table, this.cellMinWidth, void 0, void 0, this.editor);
58970
59288
  updateTableWrapper(this.dom, this.table);
58971
59289
  return true;
58972
59290
  }
@@ -58979,46 +59297,105 @@ const createTableView = ({ editor }) => {
58979
59297
  }
58980
59298
  };
58981
59299
  };
58982
- function updateColumns(node, colgroup, table, cellMinWidth2, overrideCol, overrideValue) {
58983
- let totalWidth = 0;
58984
- let fixedWidth = true;
58985
- let nextDOM = colgroup.firstChild;
59300
+ function updateColumns(node, colgroup, table, cellMinWidth2, overrideCol, overrideValue, editor) {
59301
+ const gridColumns = Array.isArray(node.attrs?.grid) && node.attrs.grid.length ? node.attrs.grid.map((col) => twipsToPixels(col.col)) : null;
59302
+ const totalColumns = gridColumns?.length ?? null;
59303
+ const pageBody = table.closest(".page__body");
59304
+ const wrapper = table.parentElement;
59305
+ let availableWidth = pageBody?.getBoundingClientRect?.().width;
59306
+ if (!availableWidth && wrapper) {
59307
+ availableWidth = wrapper.getBoundingClientRect().width;
59308
+ }
59309
+ if (typeof availableWidth === "number" && !Number.isNaN(availableWidth)) {
59310
+ availableWidth = Math.max(availableWidth - 2, 0);
59311
+ } else {
59312
+ availableWidth = null;
59313
+ }
59314
+ const pageStyles = editor?.converter?.pageStyles;
59315
+ if (pageStyles?.pageSize?.width) {
59316
+ const toNumber = (v2) => typeof v2 === "number" ? v2 : parseFloat(v2) || 0;
59317
+ const pageWidth = toNumber(pageStyles.pageSize.width);
59318
+ const marginLeft = toNumber(pageStyles.pageMargins?.left);
59319
+ const marginRight = toNumber(pageStyles.pageMargins?.right);
59320
+ const pageAvailableWidthPx = Math.max((pageWidth - marginLeft - marginRight) * PIXELS_PER_INCH, 0);
59321
+ if (pageAvailableWidthPx > 0) {
59322
+ availableWidth = availableWidth ? Math.min(availableWidth, pageAvailableWidthPx) : pageAvailableWidthPx;
59323
+ }
59324
+ }
59325
+ const resolveColumnWidth = (colIndex2, colwidthValue) => {
59326
+ if (overrideCol === colIndex2) return overrideValue;
59327
+ if (colwidthValue != null) return colwidthValue;
59328
+ if (gridColumns && gridColumns[colIndex2] != null) return gridColumns[colIndex2];
59329
+ return null;
59330
+ };
59331
+ const widths = [];
58986
59332
  const row = node.firstChild;
59333
+ let colIndex = 0;
58987
59334
  if (row !== null) {
58988
- for (let i = 0, col = 0; i < row.childCount; i++) {
58989
- const { colspan, colwidth } = row.child(i).attrs;
58990
- for (let j2 = 0; j2 < colspan; j2++, col++) {
58991
- const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j2];
58992
- const cssWidth = hasWidth ? `${hasWidth}px` : "";
58993
- totalWidth += hasWidth || cellMinWidth2;
58994
- if (!hasWidth) fixedWidth = false;
58995
- if (!nextDOM) {
58996
- const col2 = document.createElement("col");
58997
- const [propKey, propVal] = getColStyleDeclaration(cellMinWidth2, hasWidth);
58998
- col2.style.setProperty(propKey, propVal);
58999
- colgroup.appendChild(col2);
59000
- } else {
59001
- if (nextDOM.style.width !== cssWidth) {
59002
- const [propKey, propVal] = getColStyleDeclaration(cellMinWidth2, hasWidth);
59003
- nextDOM.style.setProperty(propKey, propVal);
59004
- }
59005
- nextDOM = nextDOM.nextSibling;
59006
- }
59335
+ for (let i = 0; i < row.childCount; i++) {
59336
+ const child = row.child(i);
59337
+ const { colspan, colwidth } = child.attrs;
59338
+ for (let span = 0; span < colspan; span += 1, colIndex += 1) {
59339
+ widths.push(resolveColumnWidth(colIndex, colwidth && colwidth[span]));
59007
59340
  }
59008
59341
  }
59009
59342
  }
59010
- while (nextDOM) {
59011
- const after = nextDOM.nextSibling;
59012
- nextDOM.parentNode?.removeChild(nextDOM);
59013
- nextDOM = after;
59343
+ if (totalColumns != null && colIndex < totalColumns) {
59344
+ for (let col = colIndex; col < totalColumns; col += 1) {
59345
+ widths.push(resolveColumnWidth(col));
59346
+ }
59014
59347
  }
59015
- if (fixedWidth) {
59016
- table.style.width = `${totalWidth}px`;
59348
+ const normalizedWidths = widths.map((widthPx) => {
59349
+ const numericWidth = Number(widthPx);
59350
+ if (!Number.isFinite(numericWidth)) return null;
59351
+ if (numericWidth < 0) return null;
59352
+ if (numericWidth === 0) return 0;
59353
+ if (numericWidth < 1) return 0;
59354
+ return numericWidth;
59355
+ });
59356
+ const rawTotalWidth = normalizedWidths.reduce((sum, width) => sum + (width != null ? width : cellMinWidth2), 0);
59357
+ let scale = 1;
59358
+ if (availableWidth && rawTotalWidth > 0 && rawTotalWidth > availableWidth) {
59359
+ scale = availableWidth / rawTotalWidth;
59360
+ }
59361
+ let totalWidth = 0;
59362
+ let hasUndefinedWidth = false;
59363
+ let dom = colgroup.firstChild;
59364
+ normalizedWidths.forEach((width) => {
59365
+ let scaledWidth = width;
59366
+ if (scaledWidth != null) {
59367
+ scaledWidth = scaledWidth * scale;
59368
+ }
59369
+ const [propKey, propVal] = getColStyleDeclaration(cellMinWidth2, scaledWidth);
59370
+ if (scaledWidth == null) {
59371
+ totalWidth += cellMinWidth2;
59372
+ hasUndefinedWidth = true;
59373
+ } else {
59374
+ totalWidth += scaledWidth;
59375
+ }
59376
+ if (!dom) {
59377
+ const colElement = document.createElement("col");
59378
+ colElement.style.setProperty(propKey, propVal);
59379
+ colgroup.appendChild(colElement);
59380
+ } else {
59381
+ dom.style.setProperty(propKey, propVal);
59382
+ dom = dom.nextSibling;
59383
+ }
59384
+ });
59385
+ while (dom) {
59386
+ const next = dom.nextSibling;
59387
+ dom.parentNode?.removeChild(dom);
59388
+ dom = next;
59389
+ }
59390
+ if (scale < 1 || !hasUndefinedWidth) {
59391
+ const clampedWidth = Math.min(totalWidth, availableWidth || totalWidth);
59392
+ table.style.width = `${clampedWidth}px`;
59017
59393
  table.style.minWidth = "";
59018
59394
  } else {
59019
59395
  table.style.width = "";
59020
59396
  table.style.minWidth = `${totalWidth}px`;
59021
59397
  }
59398
+ table.style.maxWidth = "100%";
59022
59399
  }
59023
59400
  function updateTable(editor, node, table) {
59024
59401
  const allExtensionsAttrs = editor.extensionService.attributes;
@@ -59096,22 +59473,61 @@ const createTable = (schema, rowsCount, colsCount, withHeaderRow, cellContent =
59096
59473
  const tableBorders = createTableBorders();
59097
59474
  return types2.table.createChecked({ borders: tableBorders }, rows);
59098
59475
  };
59476
+ const MIN_MEANINGFUL_WIDTH_PX = 1;
59099
59477
  const createColGroup = (node, cellMinWidth2, overrideCol, overrideValue) => {
59100
59478
  let totalWidth = 0;
59101
59479
  let fixedWidth = true;
59102
59480
  const cols = [];
59103
59481
  const colsValues = [];
59104
59482
  const row = node.firstChild;
59483
+ const gridColumns = Array.isArray(node.attrs?.grid) && node.attrs.grid.length ? node.attrs.grid.map((col) => twipsToPixels(col.col)) : null;
59105
59484
  if (!row) return {};
59106
- for (let i = 0, col = 0; i < row.childCount; i++) {
59107
- const { colspan, colwidth } = row.child(i).attrs;
59108
- for (let j2 = 0; j2 < colspan; j2++, col++) {
59109
- const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j2];
59110
- totalWidth += hasWidth || cellMinWidth2;
59111
- if (!hasWidth) fixedWidth = false;
59112
- const [prop, value] = getColStyleDeclaration(cellMinWidth2, hasWidth);
59485
+ const totalColumns = gridColumns?.length;
59486
+ const resolveColumnWidth = (colIndex2, colwidthValue) => {
59487
+ if (overrideCol === colIndex2) return overrideValue;
59488
+ if (colwidthValue != null) return colwidthValue;
59489
+ if (gridColumns && gridColumns[colIndex2] != null) return gridColumns[colIndex2];
59490
+ return null;
59491
+ };
59492
+ let colIndex = 0;
59493
+ for (let i = 0; i < row.childCount; i++) {
59494
+ const child = row.child(i);
59495
+ const { colspan, colwidth } = child.attrs;
59496
+ for (let j2 = 0; j2 < colspan; j2++, colIndex++) {
59497
+ const candidateWidth = resolveColumnWidth(colIndex, colwidth && colwidth[j2]);
59498
+ const numericWidth = Number(candidateWidth);
59499
+ let effectiveWidth = Number.isFinite(numericWidth) && numericWidth > 0 ? numericWidth : null;
59500
+ if (effectiveWidth != null && effectiveWidth < MIN_MEANINGFUL_WIDTH_PX) {
59501
+ effectiveWidth = 0;
59502
+ }
59503
+ if (effectiveWidth == null) {
59504
+ totalWidth += cellMinWidth2;
59505
+ fixedWidth = false;
59506
+ } else {
59507
+ totalWidth += effectiveWidth;
59508
+ }
59509
+ const [prop, value] = getColStyleDeclaration(cellMinWidth2, effectiveWidth);
59113
59510
  cols.push(["col", { style: `${prop}: ${value}` }]);
59114
- colsValues.push(parseInt(value, 10));
59511
+ colsValues.push(parseFloat(value));
59512
+ }
59513
+ }
59514
+ if (totalColumns != null) {
59515
+ for (let col = colIndex; col < totalColumns; col++) {
59516
+ const candidateWidth = resolveColumnWidth(col);
59517
+ const numericWidth = Number(candidateWidth);
59518
+ let effectiveWidth = Number.isFinite(numericWidth) && numericWidth > 0 ? numericWidth : null;
59519
+ if (effectiveWidth != null && effectiveWidth < MIN_MEANINGFUL_WIDTH_PX) {
59520
+ effectiveWidth = 0;
59521
+ }
59522
+ if (effectiveWidth == null) {
59523
+ totalWidth += cellMinWidth2;
59524
+ fixedWidth = false;
59525
+ } else {
59526
+ totalWidth += effectiveWidth;
59527
+ }
59528
+ const [prop, value] = getColStyleDeclaration(cellMinWidth2, effectiveWidth);
59529
+ cols.push(["col", { style: `${prop}: ${value}` }]);
59530
+ colsValues.push(parseFloat(value));
59115
59531
  }
59116
59532
  }
59117
59533
  const tableWidth = fixedWidth ? `${totalWidth}px` : "";
@@ -62014,6 +62430,19 @@ const TableHeader = Node$1.create({
62014
62430
  "data-colwidth": attrs.colwidth.join(",")
62015
62431
  };
62016
62432
  }
62433
+ },
62434
+ __placeholder: {
62435
+ default: null,
62436
+ parseDOM: (element) => {
62437
+ const value = element.getAttribute("data-placeholder");
62438
+ return value || null;
62439
+ },
62440
+ renderDOM({ __placeholder }) {
62441
+ if (!__placeholder) return {};
62442
+ return {
62443
+ "data-placeholder": __placeholder
62444
+ };
62445
+ }
62017
62446
  }
62018
62447
  };
62019
62448
  },
@@ -62174,6 +62603,19 @@ const TableCell = Node$1.create({
62174
62603
  default: "px",
62175
62604
  rendered: false
62176
62605
  },
62606
+ __placeholder: {
62607
+ default: null,
62608
+ parseDOM: (element) => {
62609
+ const value = element.getAttribute("data-placeholder");
62610
+ return value || null;
62611
+ },
62612
+ renderDOM({ __placeholder }) {
62613
+ if (!__placeholder) return {};
62614
+ return {
62615
+ "data-placeholder": __placeholder
62616
+ };
62617
+ }
62618
+ },
62177
62619
  /**
62178
62620
  * @category Attribute
62179
62621
  * @param {TableCellProperties} tableCellProperties - Properties for the table cell.