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.
- package/dist/edit/docx/content.cjs +2 -3
- package/dist/edit/docx/content.js +3 -4
- package/dist/edit/odp/content.cjs +1 -5
- package/dist/edit/odp/content.js +2 -6
- package/dist/edit/odp/slide.d.cts +1 -1
- package/dist/edit/odp/slide.d.ts +1 -1
- package/dist/edit/odt/content.cjs +16 -6
- package/dist/edit/odt/content.d.cts +10 -2
- package/dist/edit/odt/content.d.ts +10 -2
- package/dist/edit/odt/content.js +17 -8
- package/dist/edit/odt/editor.d.cts +1 -1
- package/dist/edit/odt/editor.d.ts +1 -1
- package/dist/edit/odt/table.cjs +123 -48
- package/dist/edit/odt/table.d.cts +1 -1
- package/dist/edit/odt/table.d.ts +1 -1
- package/dist/edit/odt/table.js +123 -48
- package/dist/edit/pptx/content.cjs +2 -1
- package/dist/edit/pptx/content.js +3 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/{table-CCjF09Ho.d.cts → table-BT3wN3Hd.d.cts} +2 -2
- package/dist/{table-BMYJo_-F.d.ts → table-DhTy5Re7.d.ts} +2 -2
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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);
|
package/dist/edit/odp/content.js
CHANGED
|
@@ -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-
|
|
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
|
package/dist/edit/odp/slide.d.ts
CHANGED
|
@@ -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-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
}
|
|
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-
|
|
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-
|
|
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 };
|
package/dist/edit/odt/content.js
CHANGED
|
@@ -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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
}
|
|
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-
|
|
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-
|
|
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
|
package/dist/edit/odt/table.cjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
return
|
|
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-
|
|
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 };
|
package/dist/edit/odt/table.d.ts
CHANGED
|
@@ -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-
|
|
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 };
|
package/dist/edit/odt/table.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
return
|
|
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
|
|
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
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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