js.documents 11.0.0 → 12.0.0

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.
@@ -210,11 +210,10 @@ function docxRowCells(positions, positionsByRow) {
210
210
  }
211
211
  function appendTable(body, block) {
212
212
  require_edit_table_grid.assertTableObeysGridRule(block, "buildDocxPackage");
213
- const columns = block.columnWidthsPt.length;
214
- if (block.rows.length === 0 || columns === 0) return;
213
+ if (block.rows.length === 0) throw new Error("buildDocxPackage: table has no rows, and a table with no rows cannot be written in every word-processing format (ODF requires at least one table:table-row)");
215
214
  const table = body.appendTable({
216
215
  rows: 0,
217
- columns,
216
+ columns: (0, document_schema_js.tableGridColumnCount)(block),
218
217
  columnWidthsTwips: block.columnWidthsPt.map(require_model_units.ptToTwips)
219
218
  });
220
219
  const positionsByRow = (0, document_schema_js.walkTableGrid)(block);
@@ -11,7 +11,7 @@ import { FLOW_CONTAINER_ORIGIN, drawingOfBlock, embeddedDrawingVectors } from ".
11
11
  import { formulaOfBlock, formulaPlaceholderText } from "../../model/formula.js";
12
12
  import { NUMBERING_CONTENT_TYPE, NUMBERING_PART_PATH, NUMBERING_REL_TYPE, buildNumberingRoot, declaration } from "./numbering.js";
13
13
  import { base64ToBytes } from "ooxml.js";
14
- import { resolveCellFillColor, tableCellColumnSpan, tableCellRowSpan, walkTableGrid } from "document-schema.js";
14
+ import { resolveCellFillColor, tableCellColumnSpan, tableCellRowSpan, tableGridColumnCount, walkTableGrid } from "document-schema.js";
15
15
  //#region src/edit/docx/content.ts
16
16
  var ConstructMarkerState = class {
17
17
  nextBookmarkId = 1;
@@ -209,11 +209,10 @@ function docxRowCells(positions, positionsByRow) {
209
209
  }
210
210
  function appendTable(body, block) {
211
211
  assertTableObeysGridRule(block, "buildDocxPackage");
212
- const columns = block.columnWidthsPt.length;
213
- if (block.rows.length === 0 || columns === 0) return;
212
+ if (block.rows.length === 0) throw new Error("buildDocxPackage: table has no rows, and a table with no rows cannot be written in every word-processing format (ODF requires at least one table:table-row)");
214
213
  const table = body.appendTable({
215
214
  rows: 0,
216
- columns,
215
+ columns: tableGridColumnCount(block),
217
216
  columnWidthsTwips: block.columnWidthsPt.map(ptToTwips)
218
217
  });
219
218
  const positionsByRow = walkTableGrid(block);
@@ -52,11 +52,7 @@ function appendShape(slide, shape) {
52
52
  if (shape.blocks.length === 1 && onlyBlock?.kind === "table") {
53
53
  const { shape: tableFrame, table } = slide.addTable({
54
54
  frame: shape.frame,
55
- table: {
56
- rows: 0,
57
- columns: onlyBlock.columnWidthsPt.length,
58
- columnWidthsPt: onlyBlock.columnWidthsPt
59
- }
55
+ table: require_edit_odt_content.odtTableInit(onlyBlock, "buildOdpPackage")
60
56
  });
61
57
  if (shape.rotationDeg !== void 0) tableFrame.rotationDeg = shape.rotationDeg;
62
58
  require_edit_odt_content.populateOdtTable(table, onlyBlock);
@@ -2,7 +2,7 @@ import { resolveMetadataTimestamps } from "../../model/metadata.js";
2
2
  import { systemClock } from "../../ports/clock.js";
3
3
  import { drawingOfBlock, embeddedDrawingVectors } from "../../model/embedded-drawing.js";
4
4
  import { formulaOfBlock, formulaPlaceholderText } from "../../model/formula.js";
5
- import { populateOdtTable, populateParagraph } from "../odt/content.js";
5
+ import { odtTableInit, populateOdtTable, populateParagraph } from "../odt/content.js";
6
6
  import { createEmptyOdpPackage } from "./scaffold.js";
7
7
  import { OdpEditor } from "./editor.js";
8
8
  import { base64ToBytes } from "odf.js";
@@ -51,11 +51,7 @@ function appendShape(slide, shape) {
51
51
  if (shape.blocks.length === 1 && onlyBlock?.kind === "table") {
52
52
  const { shape: tableFrame, table } = slide.addTable({
53
53
  frame: shape.frame,
54
- table: {
55
- rows: 0,
56
- columns: onlyBlock.columnWidthsPt.length,
57
- columnWidthsPt: onlyBlock.columnWidthsPt
58
- }
54
+ table: odtTableInit(onlyBlock, "buildOdpPackage")
59
55
  });
60
56
  if (shape.rotationDeg !== void 0) tableFrame.rotationDeg = shape.rotationDeg;
61
57
  populateOdtTable(table, onlyBlock);
@@ -1,7 +1,7 @@
1
1
  import { t as ImageInit } from "../../image-D1z0T9Za.cjs";
2
2
  import { t as OdpShape } from "../../shape-Kmmxib5z.cjs";
3
3
  import { s as OdgVector } from "../../vector-DDP7hgvm.cjs";
4
- import { o as TableInit, r as OdtTable } from "../../table-CCjF09Ho.cjs";
4
+ import { o as TableInit, r as OdtTable } from "../../table-BT3wN3Hd.cjs";
5
5
  import { Box, ContentFormula, ContentVector } from "document-schema.js";
6
6
  import { Package, XmlElement, XmlNode } from "odf.js";
7
7
  //#region src/edit/odp/slide.d.ts
@@ -1,7 +1,7 @@
1
1
  import { t as ImageInit } from "../../image-D1z0T9Za.js";
2
2
  import { t as OdpShape } from "../../shape-ZAfNsCC5.js";
3
3
  import { s as OdgVector } from "../../vector-DDP7hgvm.js";
4
- import { o as TableInit, r as OdtTable } from "../../table-BMYJo_-F.js";
4
+ import { o as TableInit, r as OdtTable } from "../../table-DhTy5Re7.js";
5
5
  import { Box, ContentFormula, ContentVector } from "document-schema.js";
6
6
  import { Package, XmlElement, XmlNode } from "odf.js";
7
7
  //#region src/edit/odp/slide.d.ts
@@ -158,14 +158,23 @@ function applyCellDecoration(target, cell) {
158
158
  if (cell.background !== void 0) target.background = (0, document_schema_js.resolveCellFillColor)(cell.background);
159
159
  if (cell.borders !== void 0) target.borders = cell.borders;
160
160
  }
161
- function appendTable(body, block) {
162
- const columns = block.columnWidthsPt.length;
163
- if (block.rows.length === 0 || columns === 0) return;
164
- populateOdtTable(body.appendTable({
161
+ /**
162
+ * The arguments that create the empty `table:table` a ContentTable is written into: no rows, since populateOdtTable appends one per ContentTableRow, and as many columns as the table's grid is wide.
163
+ *
164
+ * The grid width is what the rows and `columnWidthsPt` together state (tableGridColumnCount), so a table whose rows carry cells but which states no column widths still gets one `table:table-column` per grid column; a column with no stated width takes an equal share of the default table width, the same as any column created without one. `columnWidthsPt` is passed through untouched, so a width the table does state is always written.
165
+ *
166
+ * Throws when the table has no rows: ODF requires a `table:table` to hold at least one `table:table-row`, so no faithful spelling exists, and dropping the table would lose it without a trace. `entryPoint` names the caller in the message. A table that breaks the grid rule is refused by populateOdtTable before it writes anything, and a table with no rows has no grid fault to report, so the two checks never compete.
167
+ */
168
+ function odtTableInit(block, entryPoint) {
169
+ if (block.rows.length === 0) throw new Error(`${entryPoint}: table has no rows, and ODF requires a table:table to hold at least one table:table-row`);
170
+ return {
165
171
  rows: 0,
166
- columns,
172
+ columns: (0, document_schema_js.tableGridColumnCount)(block),
167
173
  columnWidthsPt: block.columnWidthsPt
168
- }), block);
174
+ };
175
+ }
176
+ function appendTable(body, block) {
177
+ populateOdtTable(body.appendTable(odtTableInit(block, "buildOdtPackage")), block);
169
178
  }
170
179
  function appendCellBlock(cell, block) {
171
180
  if (block.kind === "paragraph") populateParagraph(cell.appendParagraph(), block, { headings: "element" });
@@ -242,5 +251,6 @@ function appendEmbeddedObject(body, block) {
242
251
  }
243
252
  //#endregion
244
253
  exports.buildOdtPackage = buildOdtPackage;
254
+ exports.odtTableInit = odtTableInit;
245
255
  exports.populateOdtTable = populateOdtTable;
246
256
  exports.populateParagraph = populateParagraph;
@@ -1,6 +1,6 @@
1
1
  import { t as ClockPort } from "../../clock-C7SUuYN0.cjs";
2
2
  import { t as OdtParagraph } from "../../paragraph-CRaLSzWz.cjs";
3
- import { r as OdtTable } from "../../table-CCjF09Ho.cjs";
3
+ import { o as TableInit, r as OdtTable } from "../../table-BT3wN3Hd.cjs";
4
4
  import { ContentDocument, ContentParagraph, ContentTable } from "document-schema.js";
5
5
  import { Package } from "odf.js";
6
6
  //#region src/edit/odt/content.d.ts
@@ -13,5 +13,13 @@ interface PopulateParagraphOptions {
13
13
  }
14
14
  declare function populateParagraph(paragraph: OdtParagraph, block: ContentParagraph, options: PopulateParagraphOptions): void;
15
15
  declare function populateOdtTable(table: OdtTable, block: ContentTable): void;
16
+ /**
17
+ * The arguments that create the empty `table:table` a ContentTable is written into: no rows, since populateOdtTable appends one per ContentTableRow, and as many columns as the table's grid is wide.
18
+ *
19
+ * The grid width is what the rows and `columnWidthsPt` together state (tableGridColumnCount), so a table whose rows carry cells but which states no column widths still gets one `table:table-column` per grid column; a column with no stated width takes an equal share of the default table width, the same as any column created without one. `columnWidthsPt` is passed through untouched, so a width the table does state is always written.
20
+ *
21
+ * Throws when the table has no rows: ODF requires a `table:table` to hold at least one `table:table-row`, so no faithful spelling exists, and dropping the table would lose it without a trace. `entryPoint` names the caller in the message. A table that breaks the grid rule is refused by populateOdtTable before it writes anything, and a table with no rows has no grid fault to report, so the two checks never compete.
22
+ */
23
+ declare function odtTableInit(block: ContentTable, entryPoint: string): TableInit;
16
24
  //#endregion
17
- export { BuildOdtPackageOptions, PopulateParagraphOptions, buildOdtPackage, populateOdtTable, populateParagraph };
25
+ export { BuildOdtPackageOptions, PopulateParagraphOptions, buildOdtPackage, odtTableInit, populateOdtTable, populateParagraph };
@@ -1,6 +1,6 @@
1
1
  import { t as ClockPort } from "../../clock-C7SUuYN0.js";
2
2
  import { t as OdtParagraph } from "../../paragraph-D4f705GG.js";
3
- import { r as OdtTable } from "../../table-BMYJo_-F.js";
3
+ import { o as TableInit, r as OdtTable } from "../../table-DhTy5Re7.js";
4
4
  import { ContentDocument, ContentParagraph, ContentTable } from "document-schema.js";
5
5
  import { Package } from "odf.js";
6
6
  //#region src/edit/odt/content.d.ts
@@ -13,5 +13,13 @@ interface PopulateParagraphOptions {
13
13
  }
14
14
  declare function populateParagraph(paragraph: OdtParagraph, block: ContentParagraph, options: PopulateParagraphOptions): void;
15
15
  declare function populateOdtTable(table: OdtTable, block: ContentTable): void;
16
+ /**
17
+ * The arguments that create the empty `table:table` a ContentTable is written into: no rows, since populateOdtTable appends one per ContentTableRow, and as many columns as the table's grid is wide.
18
+ *
19
+ * The grid width is what the rows and `columnWidthsPt` together state (tableGridColumnCount), so a table whose rows carry cells but which states no column widths still gets one `table:table-column` per grid column; a column with no stated width takes an equal share of the default table width, the same as any column created without one. `columnWidthsPt` is passed through untouched, so a width the table does state is always written.
20
+ *
21
+ * Throws when the table has no rows: ODF requires a `table:table` to hold at least one `table:table-row`, so no faithful spelling exists, and dropping the table would lose it without a trace. `entryPoint` names the caller in the message. A table that breaks the grid rule is refused by populateOdtTable before it writes anything, and a table with no rows has no grid fault to report, so the two checks never compete.
22
+ */
23
+ declare function odtTableInit(block: ContentTable, entryPoint: string): TableInit;
16
24
  //#endregion
17
- export { BuildOdtPackageOptions, PopulateParagraphOptions, buildOdtPackage, populateOdtTable, populateParagraph };
25
+ export { BuildOdtPackageOptions, PopulateParagraphOptions, buildOdtPackage, odtTableInit, populateOdtTable, populateParagraph };
@@ -6,7 +6,7 @@ import { formulaOfBlock, formulaPlaceholderText } from "../../model/formula.js";
6
6
  import { headingStyleName } from "./paragraph.js";
7
7
  import { createEmptyOdtPackage } from "./scaffold.js";
8
8
  import { OdtEditor } from "./editor.js";
9
- import { resolveCellFillColor, tableCellColumnSpan, tableCellRowSpan, walkTableGrid } from "document-schema.js";
9
+ import { resolveCellFillColor, tableCellColumnSpan, tableCellRowSpan, tableGridColumnCount, walkTableGrid } from "document-schema.js";
10
10
  import { base64ToBytes } from "odf.js";
11
11
  //#region src/edit/odt/content.ts
12
12
  function buildOdtPackage(content, options) {
@@ -157,14 +157,23 @@ function applyCellDecoration(target, cell) {
157
157
  if (cell.background !== void 0) target.background = resolveCellFillColor(cell.background);
158
158
  if (cell.borders !== void 0) target.borders = cell.borders;
159
159
  }
160
- function appendTable(body, block) {
161
- const columns = block.columnWidthsPt.length;
162
- if (block.rows.length === 0 || columns === 0) return;
163
- populateOdtTable(body.appendTable({
160
+ /**
161
+ * The arguments that create the empty `table:table` a ContentTable is written into: no rows, since populateOdtTable appends one per ContentTableRow, and as many columns as the table's grid is wide.
162
+ *
163
+ * The grid width is what the rows and `columnWidthsPt` together state (tableGridColumnCount), so a table whose rows carry cells but which states no column widths still gets one `table:table-column` per grid column; a column with no stated width takes an equal share of the default table width, the same as any column created without one. `columnWidthsPt` is passed through untouched, so a width the table does state is always written.
164
+ *
165
+ * Throws when the table has no rows: ODF requires a `table:table` to hold at least one `table:table-row`, so no faithful spelling exists, and dropping the table would lose it without a trace. `entryPoint` names the caller in the message. A table that breaks the grid rule is refused by populateOdtTable before it writes anything, and a table with no rows has no grid fault to report, so the two checks never compete.
166
+ */
167
+ function odtTableInit(block, entryPoint) {
168
+ if (block.rows.length === 0) throw new Error(`${entryPoint}: table has no rows, and ODF requires a table:table to hold at least one table:table-row`);
169
+ return {
164
170
  rows: 0,
165
- columns,
171
+ columns: tableGridColumnCount(block),
166
172
  columnWidthsPt: block.columnWidthsPt
167
- }), block);
173
+ };
174
+ }
175
+ function appendTable(body, block) {
176
+ populateOdtTable(body.appendTable(odtTableInit(block, "buildOdtPackage")), block);
168
177
  }
169
178
  function appendCellBlock(cell, block) {
170
179
  if (block.kind === "paragraph") populateParagraph(cell.appendParagraph(), block, { headings: "element" });
@@ -240,4 +249,4 @@ function appendEmbeddedObject(body, block) {
240
249
  body.appendFormula(formula, block.frame);
241
250
  }
242
251
  //#endregion
243
- export { buildOdtPackage, populateOdtTable, populateParagraph };
252
+ export { buildOdtPackage, odtTableInit, populateOdtTable, populateParagraph };
@@ -1,7 +1,7 @@
1
1
  import { t as ClockPort } from "../../clock-C7SUuYN0.cjs";
2
2
  import { n as ParagraphInit, t as OdtParagraph } from "../../paragraph-CRaLSzWz.cjs";
3
3
  import { t as OdtList } from "../../list-C_UPIZWM.cjs";
4
- import { o as TableInit, r as OdtTable } from "../../table-CCjF09Ho.cjs";
4
+ import { o as TableInit, r as OdtTable } from "../../table-BT3wN3Hd.cjs";
5
5
  import { Box, ContentControlDescriptor, ContentFormula, ContentVector, DivisionDescriptor, LayoutMetadata } from "document-schema.js";
6
6
  import { Package } from "odf.js";
7
7
  //#region src/edit/odt/editor.d.ts
@@ -1,7 +1,7 @@
1
1
  import { t as ClockPort } from "../../clock-C7SUuYN0.js";
2
2
  import { n as ParagraphInit, t as OdtParagraph } from "../../paragraph-D4f705GG.js";
3
3
  import { t as OdtList } from "../../list-C2GWIe6E.js";
4
- import { o as TableInit, r as OdtTable } from "../../table-BMYJo_-F.js";
4
+ import { o as TableInit, r as OdtTable } from "../../table-DhTy5Re7.js";
5
5
  import { Box, ContentControlDescriptor, ContentFormula, ContentVector, DivisionDescriptor, LayoutMetadata } from "document-schema.js";
6
6
  import { Package } from "odf.js";
7
7
  //#region src/edit/odt/editor.d.ts
@@ -5,6 +5,7 @@ const require_edit_table_grid = require("../table-grid.cjs");
5
5
  const require_edit_odt_automatic_styles = require("./automatic-styles.cjs");
6
6
  const require_edit_odt_paragraph = require("./paragraph.cjs");
7
7
  let ooxml_js = require("ooxml.js");
8
+ let document_schema_js = require("document-schema.js");
8
9
  let odf_js = require("odf.js");
9
10
  //#region src/edit/odt/table.ts
10
11
  const DEFAULT_TABLE_WIDTH_PT = 468;
@@ -254,12 +255,106 @@ function gridCellElements(row) {
254
255
  for (const child of row.children) if (child.type === "element" && (child.tag === "table:table-cell" || child.tag === "table:covered-table-cell")) out.push(child);
255
256
  return out;
256
257
  }
258
+ function tableRowElements(table) {
259
+ return table.children.filter((child) => child.type === "element" && child.tag === "table:table-row");
260
+ }
261
+ function placedCells(row, pkg) {
262
+ return gridCellElements(row).flatMap((element, columnIndex) => {
263
+ if (element.tag !== "table:table-cell") return [];
264
+ const cell = new OdtTableCell(element, pkg);
265
+ return [{
266
+ columnIndex,
267
+ cell,
268
+ colSpan: cell.colSpan,
269
+ rowSpan: cell.rowSpan
270
+ }];
271
+ });
272
+ }
273
+ function resolveOdtGrid(table, pkg) {
274
+ const placedRows = [];
275
+ let declaredColumns = 0;
276
+ for (const child of table.children) {
277
+ if (child.type !== "element") continue;
278
+ if (child.tag === "table:table-column") declaredColumns++;
279
+ else if (child.tag === "table:table-row") placedRows.push(placedCells(child, pkg));
280
+ }
281
+ return require_edit_table_grid.resolveLiveTableGrid(placedRows, declaredColumns);
282
+ }
283
+ function regionCovers(region, rowIndex, columnIndex) {
284
+ return region.row <= rowIndex && rowIndex < region.row + region.rowSpan && region.column <= columnIndex && columnIndex < region.column + region.columnSpan;
285
+ }
286
+ function regionsIntersect(a, b) {
287
+ return a.row < b.row + b.rowSpan && b.row < a.row + a.rowSpan && a.column < b.column + b.columnSpan && b.column < a.column + a.columnSpan;
288
+ }
289
+ function regionContains(outer, inner) {
290
+ return outer.row <= inner.row && outer.column <= inner.column && inner.row + inner.rowSpan <= outer.row + outer.rowSpan && inner.column + inner.columnSpan <= outer.column + outer.columnSpan;
291
+ }
292
+ function anchorRegions(grid) {
293
+ return grid.rows.flatMap((positions, row) => positions.flatMap((position, column) => {
294
+ if (!position?.isAnchor) return [];
295
+ const spans = {
296
+ blocks: [],
297
+ colSpan: position.cell.colSpan,
298
+ rowSpan: position.cell.rowSpan
299
+ };
300
+ return [{
301
+ row,
302
+ column,
303
+ rowSpan: (0, document_schema_js.tableCellRowSpan)(spans),
304
+ columnSpan: (0, document_schema_js.tableCellColumnSpan)(spans)
305
+ }];
306
+ }));
307
+ }
308
+ function isUnchangedAnchor(region, target) {
309
+ return target.rowSpan === 1 && region.column === target.column && region.columnSpan === target.columnSpan;
310
+ }
311
+ function describeRegionAnchor(region) {
312
+ return `the merge anchored at row ${region.row}, column ${region.column}`;
313
+ }
314
+ function refuseMerge(rowIndex, reason) {
315
+ return { refusal: {
316
+ rowIndex,
317
+ reason
318
+ } };
319
+ }
320
+ function planMerge(table, pkg, target, rows) {
321
+ const [anchorRow, ...coveredRows] = rows;
322
+ const anchorCells = gridCellElements(anchorRow);
323
+ const coveredCells = coveredRows.map(gridCellElements);
324
+ const anchor = anchorCells[target.column];
325
+ if (anchor === void 0) return refuseMerge(target.row, `column ${target.column} does not exist in this row`);
326
+ const endColumn = target.column + target.columnSpan;
327
+ for (const [offset, cells] of [anchorCells, ...coveredCells].entries()) if (endColumn > cells.length) return refuseMerge(target.row + offset, `colSpan ${target.columnSpan} starting at column ${target.column} exceeds this row's own ${cells.length} grid columns`);
328
+ const regions = anchorRegions(resolveOdtGrid(table, pkg));
329
+ if (anchor.tag === "table:covered-table-cell") {
330
+ const covering = regions.find((region) => regionCovers(region, target.row, target.column));
331
+ return refuseMerge(target.row, covering === void 0 ? `column ${target.column} is a covered position that no merge anchors` : `column ${target.column} is covered by ${describeRegionAnchor(covering)}`);
332
+ }
333
+ const cutting = regions.find((region) => regionsIntersect(region, target) && !regionContains(target, region) && !isUnchangedAnchor(region, target));
334
+ if (cutting !== void 0) {
335
+ const column = Math.max(cutting.column, target.column);
336
+ return refuseMerge(Math.max(cutting.row, target.row), `column ${column} belongs to ${describeRegionAnchor(cutting)}, which reaches outside the region being merged and cannot be merged over`);
337
+ }
338
+ return {
339
+ anchor,
340
+ consumed: [...anchorCells.slice(target.column + 1, endColumn), ...coveredCells.flatMap((cells) => cells.slice(target.column, endColumn))]
341
+ };
342
+ }
343
+ function applyMerge(plan, target, pkg) {
344
+ for (const element of plan.consumed) retagAsCovered(element);
345
+ const anchor = new OdtTableCell(plan.anchor, pkg);
346
+ anchor.colSpan = target.columnSpan;
347
+ if (target.rowSpan > 1) anchor.rowSpan = target.rowSpan;
348
+ return anchor;
349
+ }
257
350
  var OdtTableRow = class {
258
351
  node;
259
352
  pkg;
260
- constructor(node, pkg) {
353
+ table;
354
+ constructor(node, pkg, table) {
261
355
  this.node = node;
262
356
  this.pkg = pkg;
357
+ this.table = table;
263
358
  }
264
359
  cells() {
265
360
  const out = [];
@@ -296,22 +391,22 @@ var OdtTableRow = class {
296
391
  }
297
392
  mergeCellsHorizontally(startColumnIndex, colSpan) {
298
393
  if (!Number.isInteger(colSpan) || colSpan < 1) throw new Error(`mergeCellsHorizontally: colSpan must be a positive integer, got ${colSpan}`);
299
- const gridCells = gridCellElements(this.node);
300
- const anchorElement = gridCells[startColumnIndex];
301
- if (anchorElement === void 0) throw new Error(`mergeCellsHorizontally: column ${startColumnIndex} does not exist in this row`);
302
- if (anchorElement.tag === "table:covered-table-cell") throw new Error(`mergeCellsHorizontally: column ${startColumnIndex} is already covered by another merge -- address that merge's own anchor cell instead`);
303
- if (startColumnIndex + colSpan > gridCells.length) throw new Error(`mergeCellsHorizontally: colSpan ${colSpan} starting at column ${startColumnIndex} exceeds this row's own ${gridCells.length} grid columns`);
304
- for (let i = 1; i < colSpan; i++) {
305
- const consumedElement = gridCells[startColumnIndex + i];
306
- if (consumedElement !== void 0) retagAsCovered(consumedElement);
307
- }
308
- const anchor = new OdtTableCell(anchorElement, this.pkg);
309
- anchor.colSpan = colSpan;
310
- return anchor;
394
+ const target = {
395
+ row: tableRowElements(this.table).indexOf(this.node),
396
+ column: startColumnIndex,
397
+ rowSpan: 1,
398
+ columnSpan: colSpan
399
+ };
400
+ const plan = planMerge(this.table, this.pkg, target, [this.node]);
401
+ if (plan.refusal !== void 0) throw new Error(`mergeCellsHorizontally: ${plan.refusal.reason}`);
402
+ return applyMerge(plan, target, this.pkg);
311
403
  }
312
404
  markCellCovered(columnIndex) {
313
405
  const element = gridCellElements(this.node)[columnIndex];
314
406
  if (element === void 0) throw new Error(`markCellCovered: column ${columnIndex} does not exist in this row`);
407
+ const rowIndex = tableRowElements(this.table).indexOf(this.node);
408
+ const anchored = anchorRegions(resolveOdtGrid(this.table, this.pkg)).find((region) => region.row === rowIndex && region.column === columnIndex && (region.rowSpan > 1 || region.columnSpan > 1));
409
+ if (anchored !== void 0) throw new Error(`markCellCovered: column ${columnIndex} anchors a merge with rowSpan ${anchored.rowSpan} and colSpan ${anchored.columnSpan}, so covering it would leave the rest of that merge without an anchor`);
315
410
  retagAsCovered(element);
316
411
  }
317
412
  };
@@ -339,7 +434,7 @@ var OdtTable = class {
339
434
  }
340
435
  rows() {
341
436
  const out = [];
342
- for (const child of this.live().children) if (child.type === "element" && child.tag === "table:table-row") out.push(new OdtTableRow(child, this.pkg));
437
+ for (const child of this.live().children) if (child.type === "element" && child.tag === "table:table-row") out.push(new OdtTableRow(child, this.pkg, this.node));
343
438
  return out;
344
439
  }
345
440
  gridRows() {
@@ -349,27 +444,7 @@ var OdtTable = class {
349
444
  return this.grid().columnCount;
350
445
  }
351
446
  grid() {
352
- const table = this.live();
353
- const placedRows = [];
354
- let declaredColumns = 0;
355
- for (const child of table.children) {
356
- if (child.type !== "element") continue;
357
- if (child.tag === "table:table-column") declaredColumns++;
358
- else if (child.tag === "table:table-row") placedRows.push(this.placedCells(child));
359
- }
360
- return require_edit_table_grid.resolveLiveTableGrid(placedRows, declaredColumns);
361
- }
362
- placedCells(row) {
363
- return gridCellElements(row).flatMap((element, columnIndex) => {
364
- if (element.tag !== "table:table-cell") return [];
365
- const cell = new OdtTableCell(element, this.pkg);
366
- return [{
367
- columnIndex,
368
- cell,
369
- colSpan: cell.colSpan,
370
- rowSpan: cell.rowSpan
371
- }];
372
- });
447
+ return resolveOdtGrid(this.live(), this.pkg);
373
448
  }
374
449
  cell(rowIndex, columnIndex) {
375
450
  const row = this.rows()[rowIndex];
@@ -382,29 +457,29 @@ var OdtTable = class {
382
457
  const node = this.live();
383
458
  const row = buildRow(this.pkg, columnCount);
384
459
  node.children.push(row);
385
- return new OdtTableRow(row, this.pkg);
460
+ return new OdtTableRow(row, this.pkg, node);
386
461
  }
387
462
  appendEmptyRow() {
388
463
  const node = this.live();
389
464
  const row = require_xml_fragment.el("table:table-row");
390
465
  node.children.push(row);
391
- return new OdtTableRow(row, this.pkg);
466
+ return new OdtTableRow(row, this.pkg, node);
392
467
  }
393
468
  mergeCells(startRow, startColumn, rowSpan, colSpan) {
394
469
  if (!Number.isInteger(rowSpan) || rowSpan < 1 || !Number.isInteger(colSpan) || colSpan < 1) throw new Error(`mergeCells: rowSpan and colSpan must be positive integers, got rowSpan=${rowSpan}, colSpan=${colSpan}`);
395
- const rows = this.rows();
470
+ const rows = tableRowElements(this.live());
396
471
  const anchorRow = rows[startRow];
397
472
  if (anchorRow === void 0) throw new Error(`mergeCells: row ${startRow} does not exist in this table`);
398
- const anchor = anchorRow.mergeCellsHorizontally(startColumn, colSpan);
399
- if (rowSpan > 1) {
400
- anchor.rowSpan = rowSpan;
401
- for (let r = 1; r < rowSpan; r++) {
402
- const coveredRow = rows[startRow + r];
403
- if (coveredRow === void 0) throw new Error(`mergeCells: rowSpan ${rowSpan} starting at row ${startRow} exceeds this table's own ${rows.length} rows`);
404
- for (let c = 0; c < colSpan; c++) coveredRow.markCellCovered(startColumn + c);
405
- }
406
- }
407
- return anchor;
473
+ if (startRow + rowSpan > rows.length) throw new Error(`mergeCells: rowSpan ${rowSpan} starting at row ${startRow} exceeds this table's own ${rows.length} rows`);
474
+ const target = {
475
+ row: startRow,
476
+ column: startColumn,
477
+ rowSpan,
478
+ columnSpan: colSpan
479
+ };
480
+ const plan = planMerge(this.live(), this.pkg, target, [anchorRow, ...rows.slice(startRow + 1, startRow + rowSpan)]);
481
+ if (plan.refusal !== void 0) throw new Error(`mergeCells: row ${plan.refusal.rowIndex}: ${plan.refusal.reason}`);
482
+ return applyMerge(plan, target, this.pkg);
408
483
  }
409
484
  remove() {
410
485
  require_xml_edit.removeChild(this.container, this.live());
@@ -1,2 +1,2 @@
1
- import { a as OdtTableRow, c as buildTable, i as OdtTableCell, l as readCellDecoration, n as OdtCoveredTableCell, o as TableInit, r as OdtTable, s as buildCellStyle, t as CellDecoration } from "../../table-CCjF09Ho.cjs";
1
+ import { a as OdtTableRow, c as buildTable, i as OdtTableCell, l as readCellDecoration, n as OdtCoveredTableCell, o as TableInit, r as OdtTable, s as buildCellStyle, t as CellDecoration } from "../../table-BT3wN3Hd.cjs";
2
2
  export { CellDecoration, OdtCoveredTableCell, OdtTable, OdtTableCell, OdtTableRow, TableInit, buildCellStyle, buildTable, readCellDecoration };
@@ -1,2 +1,2 @@
1
- import { a as OdtTableRow, c as buildTable, i as OdtTableCell, l as readCellDecoration, n as OdtCoveredTableCell, o as TableInit, r as OdtTable, s as buildCellStyle, t as CellDecoration } from "../../table-BMYJo_-F.js";
1
+ import { a as OdtTableRow, c as buildTable, i as OdtTableCell, l as readCellDecoration, n as OdtCoveredTableCell, o as TableInit, r as OdtTable, s as buildCellStyle, t as CellDecoration } from "../../table-DhTy5Re7.js";
2
2
  export { CellDecoration, OdtCoveredTableCell, OdtTable, OdtTableCell, OdtTableRow, TableInit, buildCellStyle, buildTable, readCellDecoration };
@@ -4,6 +4,7 @@ import { resolveLiveTableGrid } from "../table-grid.js";
4
4
  import { ensureAutomaticStyles, nextStyleName } from "./automatic-styles.js";
5
5
  import { OdtParagraph, buildParagraph } from "./paragraph.js";
6
6
  import { attr } from "ooxml.js";
7
+ import { tableCellColumnSpan, tableCellRowSpan } from "document-schema.js";
7
8
  import { findStyleElement, formatOdfColor, formatOdfLength, parseOdfColor, parseOdfLength } from "odf.js";
8
9
  //#region src/edit/odt/table.ts
9
10
  const DEFAULT_TABLE_WIDTH_PT = 468;
@@ -253,12 +254,106 @@ function gridCellElements(row) {
253
254
  for (const child of row.children) if (child.type === "element" && (child.tag === "table:table-cell" || child.tag === "table:covered-table-cell")) out.push(child);
254
255
  return out;
255
256
  }
257
+ function tableRowElements(table) {
258
+ return table.children.filter((child) => child.type === "element" && child.tag === "table:table-row");
259
+ }
260
+ function placedCells(row, pkg) {
261
+ return gridCellElements(row).flatMap((element, columnIndex) => {
262
+ if (element.tag !== "table:table-cell") return [];
263
+ const cell = new OdtTableCell(element, pkg);
264
+ return [{
265
+ columnIndex,
266
+ cell,
267
+ colSpan: cell.colSpan,
268
+ rowSpan: cell.rowSpan
269
+ }];
270
+ });
271
+ }
272
+ function resolveOdtGrid(table, pkg) {
273
+ const placedRows = [];
274
+ let declaredColumns = 0;
275
+ for (const child of table.children) {
276
+ if (child.type !== "element") continue;
277
+ if (child.tag === "table:table-column") declaredColumns++;
278
+ else if (child.tag === "table:table-row") placedRows.push(placedCells(child, pkg));
279
+ }
280
+ return resolveLiveTableGrid(placedRows, declaredColumns);
281
+ }
282
+ function regionCovers(region, rowIndex, columnIndex) {
283
+ return region.row <= rowIndex && rowIndex < region.row + region.rowSpan && region.column <= columnIndex && columnIndex < region.column + region.columnSpan;
284
+ }
285
+ function regionsIntersect(a, b) {
286
+ return a.row < b.row + b.rowSpan && b.row < a.row + a.rowSpan && a.column < b.column + b.columnSpan && b.column < a.column + a.columnSpan;
287
+ }
288
+ function regionContains(outer, inner) {
289
+ return outer.row <= inner.row && outer.column <= inner.column && inner.row + inner.rowSpan <= outer.row + outer.rowSpan && inner.column + inner.columnSpan <= outer.column + outer.columnSpan;
290
+ }
291
+ function anchorRegions(grid) {
292
+ return grid.rows.flatMap((positions, row) => positions.flatMap((position, column) => {
293
+ if (!position?.isAnchor) return [];
294
+ const spans = {
295
+ blocks: [],
296
+ colSpan: position.cell.colSpan,
297
+ rowSpan: position.cell.rowSpan
298
+ };
299
+ return [{
300
+ row,
301
+ column,
302
+ rowSpan: tableCellRowSpan(spans),
303
+ columnSpan: tableCellColumnSpan(spans)
304
+ }];
305
+ }));
306
+ }
307
+ function isUnchangedAnchor(region, target) {
308
+ return target.rowSpan === 1 && region.column === target.column && region.columnSpan === target.columnSpan;
309
+ }
310
+ function describeRegionAnchor(region) {
311
+ return `the merge anchored at row ${region.row}, column ${region.column}`;
312
+ }
313
+ function refuseMerge(rowIndex, reason) {
314
+ return { refusal: {
315
+ rowIndex,
316
+ reason
317
+ } };
318
+ }
319
+ function planMerge(table, pkg, target, rows) {
320
+ const [anchorRow, ...coveredRows] = rows;
321
+ const anchorCells = gridCellElements(anchorRow);
322
+ const coveredCells = coveredRows.map(gridCellElements);
323
+ const anchor = anchorCells[target.column];
324
+ if (anchor === void 0) return refuseMerge(target.row, `column ${target.column} does not exist in this row`);
325
+ const endColumn = target.column + target.columnSpan;
326
+ for (const [offset, cells] of [anchorCells, ...coveredCells].entries()) if (endColumn > cells.length) return refuseMerge(target.row + offset, `colSpan ${target.columnSpan} starting at column ${target.column} exceeds this row's own ${cells.length} grid columns`);
327
+ const regions = anchorRegions(resolveOdtGrid(table, pkg));
328
+ if (anchor.tag === "table:covered-table-cell") {
329
+ const covering = regions.find((region) => regionCovers(region, target.row, target.column));
330
+ return refuseMerge(target.row, covering === void 0 ? `column ${target.column} is a covered position that no merge anchors` : `column ${target.column} is covered by ${describeRegionAnchor(covering)}`);
331
+ }
332
+ const cutting = regions.find((region) => regionsIntersect(region, target) && !regionContains(target, region) && !isUnchangedAnchor(region, target));
333
+ if (cutting !== void 0) {
334
+ const column = Math.max(cutting.column, target.column);
335
+ return refuseMerge(Math.max(cutting.row, target.row), `column ${column} belongs to ${describeRegionAnchor(cutting)}, which reaches outside the region being merged and cannot be merged over`);
336
+ }
337
+ return {
338
+ anchor,
339
+ consumed: [...anchorCells.slice(target.column + 1, endColumn), ...coveredCells.flatMap((cells) => cells.slice(target.column, endColumn))]
340
+ };
341
+ }
342
+ function applyMerge(plan, target, pkg) {
343
+ for (const element of plan.consumed) retagAsCovered(element);
344
+ const anchor = new OdtTableCell(plan.anchor, pkg);
345
+ anchor.colSpan = target.columnSpan;
346
+ if (target.rowSpan > 1) anchor.rowSpan = target.rowSpan;
347
+ return anchor;
348
+ }
256
349
  var OdtTableRow = class {
257
350
  node;
258
351
  pkg;
259
- constructor(node, pkg) {
352
+ table;
353
+ constructor(node, pkg, table) {
260
354
  this.node = node;
261
355
  this.pkg = pkg;
356
+ this.table = table;
262
357
  }
263
358
  cells() {
264
359
  const out = [];
@@ -295,22 +390,22 @@ var OdtTableRow = class {
295
390
  }
296
391
  mergeCellsHorizontally(startColumnIndex, colSpan) {
297
392
  if (!Number.isInteger(colSpan) || colSpan < 1) throw new Error(`mergeCellsHorizontally: colSpan must be a positive integer, got ${colSpan}`);
298
- const gridCells = gridCellElements(this.node);
299
- const anchorElement = gridCells[startColumnIndex];
300
- if (anchorElement === void 0) throw new Error(`mergeCellsHorizontally: column ${startColumnIndex} does not exist in this row`);
301
- if (anchorElement.tag === "table:covered-table-cell") throw new Error(`mergeCellsHorizontally: column ${startColumnIndex} is already covered by another merge -- address that merge's own anchor cell instead`);
302
- if (startColumnIndex + colSpan > gridCells.length) throw new Error(`mergeCellsHorizontally: colSpan ${colSpan} starting at column ${startColumnIndex} exceeds this row's own ${gridCells.length} grid columns`);
303
- for (let i = 1; i < colSpan; i++) {
304
- const consumedElement = gridCells[startColumnIndex + i];
305
- if (consumedElement !== void 0) retagAsCovered(consumedElement);
306
- }
307
- const anchor = new OdtTableCell(anchorElement, this.pkg);
308
- anchor.colSpan = colSpan;
309
- return anchor;
393
+ const target = {
394
+ row: tableRowElements(this.table).indexOf(this.node),
395
+ column: startColumnIndex,
396
+ rowSpan: 1,
397
+ columnSpan: colSpan
398
+ };
399
+ const plan = planMerge(this.table, this.pkg, target, [this.node]);
400
+ if (plan.refusal !== void 0) throw new Error(`mergeCellsHorizontally: ${plan.refusal.reason}`);
401
+ return applyMerge(plan, target, this.pkg);
310
402
  }
311
403
  markCellCovered(columnIndex) {
312
404
  const element = gridCellElements(this.node)[columnIndex];
313
405
  if (element === void 0) throw new Error(`markCellCovered: column ${columnIndex} does not exist in this row`);
406
+ const rowIndex = tableRowElements(this.table).indexOf(this.node);
407
+ const anchored = anchorRegions(resolveOdtGrid(this.table, this.pkg)).find((region) => region.row === rowIndex && region.column === columnIndex && (region.rowSpan > 1 || region.columnSpan > 1));
408
+ if (anchored !== void 0) throw new Error(`markCellCovered: column ${columnIndex} anchors a merge with rowSpan ${anchored.rowSpan} and colSpan ${anchored.columnSpan}, so covering it would leave the rest of that merge without an anchor`);
314
409
  retagAsCovered(element);
315
410
  }
316
411
  };
@@ -338,7 +433,7 @@ var OdtTable = class {
338
433
  }
339
434
  rows() {
340
435
  const out = [];
341
- for (const child of this.live().children) if (child.type === "element" && child.tag === "table:table-row") out.push(new OdtTableRow(child, this.pkg));
436
+ for (const child of this.live().children) if (child.type === "element" && child.tag === "table:table-row") out.push(new OdtTableRow(child, this.pkg, this.node));
342
437
  return out;
343
438
  }
344
439
  gridRows() {
@@ -348,27 +443,7 @@ var OdtTable = class {
348
443
  return this.grid().columnCount;
349
444
  }
350
445
  grid() {
351
- const table = this.live();
352
- const placedRows = [];
353
- let declaredColumns = 0;
354
- for (const child of table.children) {
355
- if (child.type !== "element") continue;
356
- if (child.tag === "table:table-column") declaredColumns++;
357
- else if (child.tag === "table:table-row") placedRows.push(this.placedCells(child));
358
- }
359
- return resolveLiveTableGrid(placedRows, declaredColumns);
360
- }
361
- placedCells(row) {
362
- return gridCellElements(row).flatMap((element, columnIndex) => {
363
- if (element.tag !== "table:table-cell") return [];
364
- const cell = new OdtTableCell(element, this.pkg);
365
- return [{
366
- columnIndex,
367
- cell,
368
- colSpan: cell.colSpan,
369
- rowSpan: cell.rowSpan
370
- }];
371
- });
446
+ return resolveOdtGrid(this.live(), this.pkg);
372
447
  }
373
448
  cell(rowIndex, columnIndex) {
374
449
  const row = this.rows()[rowIndex];
@@ -381,29 +456,29 @@ var OdtTable = class {
381
456
  const node = this.live();
382
457
  const row = buildRow(this.pkg, columnCount);
383
458
  node.children.push(row);
384
- return new OdtTableRow(row, this.pkg);
459
+ return new OdtTableRow(row, this.pkg, node);
385
460
  }
386
461
  appendEmptyRow() {
387
462
  const node = this.live();
388
463
  const row = el("table:table-row");
389
464
  node.children.push(row);
390
- return new OdtTableRow(row, this.pkg);
465
+ return new OdtTableRow(row, this.pkg, node);
391
466
  }
392
467
  mergeCells(startRow, startColumn, rowSpan, colSpan) {
393
468
  if (!Number.isInteger(rowSpan) || rowSpan < 1 || !Number.isInteger(colSpan) || colSpan < 1) throw new Error(`mergeCells: rowSpan and colSpan must be positive integers, got rowSpan=${rowSpan}, colSpan=${colSpan}`);
394
- const rows = this.rows();
469
+ const rows = tableRowElements(this.live());
395
470
  const anchorRow = rows[startRow];
396
471
  if (anchorRow === void 0) throw new Error(`mergeCells: row ${startRow} does not exist in this table`);
397
- const anchor = anchorRow.mergeCellsHorizontally(startColumn, colSpan);
398
- if (rowSpan > 1) {
399
- anchor.rowSpan = rowSpan;
400
- for (let r = 1; r < rowSpan; r++) {
401
- const coveredRow = rows[startRow + r];
402
- if (coveredRow === void 0) throw new Error(`mergeCells: rowSpan ${rowSpan} starting at row ${startRow} exceeds this table's own ${rows.length} rows`);
403
- for (let c = 0; c < colSpan; c++) coveredRow.markCellCovered(startColumn + c);
404
- }
405
- }
406
- return anchor;
472
+ if (startRow + rowSpan > rows.length) throw new Error(`mergeCells: rowSpan ${rowSpan} starting at row ${startRow} exceeds this table's own ${rows.length} rows`);
473
+ const target = {
474
+ row: startRow,
475
+ column: startColumn,
476
+ rowSpan,
477
+ columnSpan: colSpan
478
+ };
479
+ const plan = planMerge(this.live(), this.pkg, target, [anchorRow, ...rows.slice(startRow + 1, startRow + rowSpan)]);
480
+ if (plan.refusal !== void 0) throw new Error(`mergeCells: row ${plan.refusal.rowIndex}: ${plan.refusal.reason}`);
481
+ return applyMerge(plan, target, this.pkg);
407
482
  }
408
483
  remove() {
409
484
  removeChild(this.container, this.live());
@@ -56,12 +56,13 @@ function appendShape(slide, shape, options) {
56
56
  return;
57
57
  }
58
58
  if (shape.blocks.length === 1 && onlyBlock?.kind === "table") {
59
+ if (onlyBlock.rows.length === 0) throw new Error("buildPptxPackage: table has no rows, and a table with no rows cannot be written in every presentation format (ODF requires at least one table:table-row)");
59
60
  populatePptxTable(slide.addTable({
60
61
  frame: shape.frame,
61
62
  rotationDeg: shape.rotationDeg,
62
63
  table: {
63
64
  rows: onlyBlock.rows.length,
64
- columns: onlyBlock.columnWidthsPt.length,
65
+ columns: (0, document_schema_js.tableGridColumnCount)(onlyBlock),
65
66
  columnWidthsPt: onlyBlock.columnWidthsPt
66
67
  }
67
68
  }), onlyBlock, (url) => slide.registerHyperlink(url));
@@ -6,7 +6,7 @@ import { formulaOfBlock, formulaPlaceholderText } from "../../model/formula.js";
6
6
  import { createEmptyPptxPackage } from "./scaffold.js";
7
7
  import { PptxEditor } from "./editor.js";
8
8
  import { base64ToBytes, encodePackage } from "ooxml.js";
9
- import { resolveCellFillColor, tableCellColumnSpan, tableCellRowSpan, walkTableGrid } from "document-schema.js";
9
+ import { resolveCellFillColor, tableCellColumnSpan, tableCellRowSpan, tableGridColumnCount, walkTableGrid } from "document-schema.js";
10
10
  //#region src/edit/pptx/content.ts
11
11
  function buildPptxPackage(content, options) {
12
12
  if (content.kind !== "presentation") throw new Error("buildPptxPackage requires a presentation ContentDocument");
@@ -55,12 +55,13 @@ function appendShape(slide, shape, options) {
55
55
  return;
56
56
  }
57
57
  if (shape.blocks.length === 1 && onlyBlock?.kind === "table") {
58
+ if (onlyBlock.rows.length === 0) throw new Error("buildPptxPackage: table has no rows, and a table with no rows cannot be written in every presentation format (ODF requires at least one table:table-row)");
58
59
  populatePptxTable(slide.addTable({
59
60
  frame: shape.frame,
60
61
  rotationDeg: shape.rotationDeg,
61
62
  table: {
62
63
  rows: onlyBlock.rows.length,
63
- columns: onlyBlock.columnWidthsPt.length,
64
+ columns: tableGridColumnCount(onlyBlock),
64
65
  columnWidthsPt: onlyBlock.columnWidthsPt
65
66
  }
66
67
  }), onlyBlock, (url) => slide.registerHyperlink(url));
package/dist/index.d.cts CHANGED
@@ -47,7 +47,7 @@ import { OdgPage, PageImageInit, TextBoxInit } from "./edit/odg/page.cjs";
47
47
  import { CreateOdgOptions, OdgEditor, createOdg, openOdg } from "./edit/odg/editor.cjs";
48
48
  import { CreateEmptyOdgPackageOptions } from "./edit/odg/scaffold.cjs";
49
49
  import { BuildOdpPackageOptions, buildOdpPackage } from "./edit/odp/content.cjs";
50
- import { a as OdtTableRow, i as OdtTableCell, n as OdtCoveredTableCell, o as TableInit$2, r as OdtTable } from "./table-CCjF09Ho.cjs";
50
+ import { a as OdtTableRow, i as OdtTableCell, n as OdtCoveredTableCell, o as TableInit$2, r as OdtTable } from "./table-BT3wN3Hd.cjs";
51
51
  import { OdpSlide, SlideImageInit, SlideTableInit, TextBoxInit as TextBoxInit$1 } from "./edit/odp/slide.cjs";
52
52
  import { CreateOdpOptions, OdpEditor, createOdp, openOdp } from "./edit/odp/editor.cjs";
53
53
  import { CreateEmptyOdpPackageOptions } from "./edit/odp/scaffold.cjs";
package/dist/index.d.ts CHANGED
@@ -47,7 +47,7 @@ import { OdgPage, PageImageInit, TextBoxInit } from "./edit/odg/page.js";
47
47
  import { CreateOdgOptions, OdgEditor, createOdg, openOdg } from "./edit/odg/editor.js";
48
48
  import { CreateEmptyOdgPackageOptions } from "./edit/odg/scaffold.js";
49
49
  import { BuildOdpPackageOptions, buildOdpPackage } from "./edit/odp/content.js";
50
- import { a as OdtTableRow, i as OdtTableCell, n as OdtCoveredTableCell, o as TableInit$2, r as OdtTable } from "./table-BMYJo_-F.js";
50
+ import { a as OdtTableRow, i as OdtTableCell, n as OdtCoveredTableCell, o as TableInit$2, r as OdtTable } from "./table-DhTy5Re7.js";
51
51
  import { OdpSlide, SlideImageInit, SlideTableInit, TextBoxInit as TextBoxInit$1 } from "./edit/odp/slide.js";
52
52
  import { CreateOdpOptions, OdpEditor, createOdp, openOdp } from "./edit/odp/editor.js";
53
53
  import { CreateEmptyOdpPackageOptions } from "./edit/odp/scaffold.js";
@@ -42,7 +42,8 @@ declare class OdtCoveredTableCell {
42
42
  declare class OdtTableRow {
43
43
  private readonly node;
44
44
  private readonly pkg;
45
- constructor(node: XmlElement, pkg: Package);
45
+ private readonly table;
46
+ constructor(node: XmlElement, pkg: Package, table: XmlElement);
46
47
  cells(): OdtTableCell[];
47
48
  get heightPt(): number | undefined;
48
49
  set heightPt(value: number | undefined);
@@ -62,7 +63,6 @@ declare class OdtTable {
62
63
  gridRows(): TableGridRows<OdtTableCell>;
63
64
  gridColumnCount(): number;
64
65
  private grid;
65
- private placedCells;
66
66
  cell(rowIndex: number, columnIndex: number): OdtTableCell;
67
67
  appendRow(columnCount: number): OdtTableRow;
68
68
  appendEmptyRow(): OdtTableRow;
@@ -42,7 +42,8 @@ declare class OdtCoveredTableCell {
42
42
  declare class OdtTableRow {
43
43
  private readonly node;
44
44
  private readonly pkg;
45
- constructor(node: XmlElement, pkg: Package);
45
+ private readonly table;
46
+ constructor(node: XmlElement, pkg: Package, table: XmlElement);
46
47
  cells(): OdtTableCell[];
47
48
  get heightPt(): number | undefined;
48
49
  set heightPt(value: number | undefined);
@@ -62,7 +63,6 @@ declare class OdtTable {
62
63
  gridRows(): TableGridRows<OdtTableCell>;
63
64
  gridColumnCount(): number;
64
65
  private grid;
65
- private placedCells;
66
66
  cell(rowIndex: number, columnIndex: number): OdtTableCell;
67
67
  appendRow(columnCount: number): OdtTableRow;
68
68
  appendEmptyRow(): OdtTableRow;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js.documents",
3
- "version": "11.0.0",
3
+ "version": "12.0.0",
4
4
  "description": "Bidirectional docx/pptx <-> PDF conversion and a read+write editable OOXML document model, built on ooxml.js and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {