From f7d18bfead70a622d377d627fb7524cad14dafec Mon Sep 17 00:00:00 2001 From: Dolan Date: Tue, 23 Oct 2018 23:44:50 +0100 Subject: [PATCH] Tidied up table components --- docs/contribution-guidelines.md | 44 ++++-- src/file/table/index.ts | 2 +- src/file/table/properties.ts | 103 ------------ src/file/table/table-cell/index.ts | 2 + .../table-cell-components.ts} | 2 +- .../table/table-cell/table-cell-properties.ts | 57 +++++++ .../table/{ => table-cell}/table-cell.spec.ts | 6 +- src/file/table/table-cell/table-cell.ts | 45 ++++++ src/file/table/table-properties/index.ts | 2 + .../table/table-properties/table-borders.ts | 36 +++++ .../table-cell-margin.ts | 3 +- .../table-float-properties.spec.ts | 2 +- .../table-float-properties.ts | 0 .../table/table-properties/table-layout.ts | 17 ++ .../table-properties.spec.ts} | 6 +- .../table-properties/table-properties.ts | 43 +++++ .../table/table-properties/table-width.ts | 19 +++ src/file/table/table-row/index.ts | 2 + .../table/table-row/table-row-properties.ts | 7 + src/file/table/table-row/table-row.ts | 40 +++++ src/file/table/table.spec.ts | 2 +- src/file/table/table.ts | 149 +----------------- 22 files changed, 324 insertions(+), 265 deletions(-) delete mode 100644 src/file/table/properties.ts create mode 100644 src/file/table/table-cell/index.ts rename src/file/table/{table-cell.ts => table-cell/table-cell-components.ts} (99%) create mode 100644 src/file/table/table-cell/table-cell-properties.ts rename src/file/table/{ => table-cell}/table-cell.spec.ts (98%) create mode 100644 src/file/table/table-cell/table-cell.ts create mode 100644 src/file/table/table-properties/index.ts create mode 100644 src/file/table/table-properties/table-borders.ts rename src/file/table/{ => table-properties}/table-cell-margin.ts (97%) rename src/file/table/{ => table-properties}/table-float-properties.spec.ts (96%) rename src/file/table/{ => table-properties}/table-float-properties.ts (100%) create mode 100644 src/file/table/table-properties/table-layout.ts rename src/file/table/{properties.spec.ts => table-properties/table-properties.spec.ts} (91%) create mode 100644 src/file/table/table-properties/table-properties.ts create mode 100644 src/file/table/table-properties/table-width.ts create mode 100644 src/file/table/table-row/index.ts create mode 100644 src/file/table/table-row/table-row-properties.ts create mode 100644 src/file/table/table-row/table-row.ts diff --git a/docs/contribution-guidelines.md b/docs/contribution-guidelines.md index a212a081c2..9bc1d4c90d 100644 --- a/docs/contribution-guidelines.md +++ b/docs/contribution-guidelines.md @@ -1,5 +1,15 @@ # Contribution Guidelines +* Include documentation reference(s) at the top of each file: + + ```js + // http://officeopenxml.com/WPdocument.php + ``` + +* Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin. + +* Follow the `TSLint` rules + ## Always think about the user The number one pillar for contribution is to **ALWAYS** think about how the user will use the library. @@ -25,17 +35,33 @@ demo updated // Getting better, but capitalize the first letter Unesesary coment removed // Make sure to use correct spelling ``` -## Writing Code +## No leaky components in API interface -* Include documentation reference(s) at the top of each file: +This mainly applies to the API the end user will consume. - ```js - // http://officeopenxml.com/WPdocument.php - ``` +Try to make method parameters accept primatives, or `json` objects, so that child components are created **inside** the component, rather than being **injected** in. -* Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin. +This is so that: -* Follow the `TSLint` rules +1. Imports are much cleaner, no need for: + ```js + import { ChildComponent } from "./my-feature/sub-component/deeper/.../my-deep.component"; + ``` + +2. This is what I consider "leakage". The code is aware of the underlying implementation of the component. +3. It means the end user does not need to import and create the child component to be injected. + +**Do not** +`TableFloatProperties` is a class. The outside world would have to construct the object, and inject it in +```js + public float(tableFloatProperties: TableFloatProperties): Table +``` + +**Do** +`ITableFloatOptions` is an interface for a JSON of primatives. +```js + public float(tableFloatOptions: ITableFloatOptions): Table +``` ## Add vs Create @@ -64,7 +90,7 @@ Getters and Setters are done with a capital letter like so: ```js public get Level() { - + ... } ``` @@ -130,7 +156,7 @@ enum WeaponType = { ## Spell correctly, full and in American English -I am not sure where these habit in software development comes from, but I do not believe it is beneficial: +I am not sure where these habits in software development come from, but I do not believe it is beneficial: **Do not:** ```js diff --git a/src/file/table/index.ts b/src/file/table/index.ts index 5048912098..a7adf3017e 100644 --- a/src/file/table/index.ts +++ b/src/file/table/index.ts @@ -1,3 +1,3 @@ export * from "./table"; export * from "./table-cell"; -export * from "./table-float-properties"; +export * from "./table-properties"; diff --git a/src/file/table/properties.ts b/src/file/table/properties.ts deleted file mode 100644 index 248895ca42..0000000000 --- a/src/file/table/properties.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; -import { WidthType } from "./table-cell"; -import { TableCellMargin } from "./table-cell-margin"; -import { TableFloatProperties } from "./table-float-properties"; - -export class TableProperties extends XmlComponent { - private readonly cellMargin: TableCellMargin; - - constructor() { - super("w:tblPr"); - - this.cellMargin = new TableCellMargin(); - this.root.push(this.cellMargin); - } - - public setWidth(type: WidthType, w: number | string): TableProperties { - this.root.push(new PreferredTableWidth(type, w)); - return this; - } - - public setFixedWidthLayout(): TableProperties { - this.root.push(new TableLayout("fixed")); - return this; - } - - public setBorder(): TableProperties { - this.root.push(new TableBorders()); - return this; - } - - public get CellMargin(): TableCellMargin { - return this.cellMargin; - } - - public setTableFloatProperties(tableFloatProperties: TableFloatProperties): TableProperties { - this.root.push(tableFloatProperties); - return this; - } -} - -interface ITableWidth { - type: WidthType; - w: number | string; -} - -class TableWidthAttributes extends XmlAttributeComponent { - protected xmlKeys = { type: "w:type", w: "w:w" }; -} - -class PreferredTableWidth extends XmlComponent { - constructor(type: WidthType, w: number | string) { - super("w:tblW"); - this.root.push(new TableWidthAttributes({ type, w })); - } -} - -type TableLayoutOptions = "autofit" | "fixed"; - -class TableLayoutAttributes extends XmlAttributeComponent<{ type: TableLayoutOptions }> { - protected xmlKeys = { type: "w:type" }; -} - -class TableLayout extends XmlComponent { - constructor(type: TableLayoutOptions) { - super("w:tblLayout"); - this.root.push(new TableLayoutAttributes({ type })); - } -} - -class TableBorders extends XmlComponent { - constructor() { - super("w:tblBorders"); - this.root.push(new TableBordersElement("w:top", "single", 4, 0, "auto")); - this.root.push(new TableBordersElement("w:left", "single", 4, 0, "auto")); - this.root.push(new TableBordersElement("w:bottom", "single", 4, 0, "auto")); - this.root.push(new TableBordersElement("w:right", "single", 4, 0, "auto")); - this.root.push(new TableBordersElement("w:insideH", "single", 4, 0, "auto")); - this.root.push(new TableBordersElement("w:insideV", "single", 4, 0, "auto")); - } -} - -class TableBordersElement extends XmlComponent { - constructor(elementName: string, value: string, size: number, space: number, color: string) { - super(elementName); - this.root.push( - new TableBordersAttributes({ - value, - size, - space, - color, - }), - ); - } -} - -class TableBordersAttributes extends XmlAttributeComponent<{ value: string; size: number; space: number; color: string }> { - protected xmlKeys = { - value: "w:val", - size: "w:sz", - space: "w:space", - color: "w:color", - }; -} diff --git a/src/file/table/table-cell/index.ts b/src/file/table/table-cell/index.ts new file mode 100644 index 0000000000..5a095cd19d --- /dev/null +++ b/src/file/table/table-cell/index.ts @@ -0,0 +1,2 @@ +export * from "./table-cell"; +export * from "./table-cell-components"; diff --git a/src/file/table/table-cell.ts b/src/file/table/table-cell/table-cell-components.ts similarity index 99% rename from src/file/table/table-cell.ts rename to src/file/table/table-cell/table-cell-components.ts index 046cc8d8aa..a81a66b3ae 100644 --- a/src/file/table/table-cell.ts +++ b/src/file/table/table-cell/table-cell-components.ts @@ -1,5 +1,5 @@ +import { BorderStyle } from "file/styles"; import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components"; -import { BorderStyle } from "../styles"; interface ICellBorder { style: BorderStyle; diff --git a/src/file/table/table-cell/table-cell-properties.ts b/src/file/table/table-cell/table-cell-properties.ts new file mode 100644 index 0000000000..639541d4cd --- /dev/null +++ b/src/file/table/table-cell/table-cell-properties.ts @@ -0,0 +1,57 @@ +import { XmlComponent } from "file/xml-components"; + +import { + GridSpan, + TableCellBorders, + TableCellShading, + TableCellWidth, + VAlign, + VerticalAlign, + VMerge, + VMergeType, + WidthType, +} from "./table-cell-components"; + +export class TableCellProperties extends XmlComponent { + private readonly cellBorder: TableCellBorders; + + constructor() { + super("w:tcPr"); + this.cellBorder = new TableCellBorders(); + this.root.push(this.cellBorder); + } + + public get Borders(): TableCellBorders { + return this.cellBorder; + } + + public addGridSpan(cellSpan: number): TableCellProperties { + this.root.push(new GridSpan(cellSpan)); + + return this; + } + + public addVerticalMerge(type: VMergeType): TableCellProperties { + this.root.push(new VMerge(type)); + + return this; + } + + public setVerticalAlign(type: VerticalAlign): TableCellProperties { + this.root.push(new VAlign(type)); + + return this; + } + + public setWidth(width: string | number, type: WidthType): TableCellProperties { + this.root.push(new TableCellWidth(width, type)); + + return this; + } + + public setShading(attrs: object): TableCellProperties { + this.root.push(new TableCellShading(attrs)); + + return this; + } +} diff --git a/src/file/table/table-cell.spec.ts b/src/file/table/table-cell/table-cell.spec.ts similarity index 98% rename from src/file/table/table-cell.spec.ts rename to src/file/table/table-cell/table-cell.spec.ts index 4e761d2e07..a69c64d642 100644 --- a/src/file/table/table-cell.spec.ts +++ b/src/file/table/table-cell/table-cell.spec.ts @@ -1,8 +1,8 @@ import { expect } from "chai"; -import { Formatter } from "../../export/formatter"; -import { BorderStyle } from "../styles"; -import { TableCellBorders, TableCellWidth, WidthType } from "./table-cell"; +import { Formatter } from "../../../export/formatter"; +import { BorderStyle } from "../../styles"; +import { TableCellBorders, TableCellWidth, WidthType } from "./table-cell-components"; describe("TableCellBorders", () => { describe("#prepForXml", () => { diff --git a/src/file/table/table-cell/table-cell.ts b/src/file/table/table-cell/table-cell.ts new file mode 100644 index 0000000000..60673ec87a --- /dev/null +++ b/src/file/table/table-cell/table-cell.ts @@ -0,0 +1,45 @@ +// http://officeopenxml.com/WPtableGrid.php +import { Paragraph } from "file/paragraph"; +import { IXmlableObject, XmlComponent } from "file/xml-components"; + +import { Table } from "../table"; +import { TableCellProperties } from "./table-cell-properties"; + +export class TableCell extends XmlComponent { + private readonly properties: TableCellProperties; + + constructor() { + super("w:tc"); + this.properties = new TableCellProperties(); + this.root.push(this.properties); + } + + public addContent(content: Paragraph | Table): TableCell { + this.root.push(content); + return this; + } + + public prepForXml(): IXmlableObject | undefined { + // Cells must end with a paragraph + const retval = super.prepForXml(); + if (!retval) { + return undefined; + } + + const content = retval["w:tc"]; + if (!content[content.length - 1]["w:p"]) { + content.push(new Paragraph().prepForXml()); + } + return retval; + } + + public createParagraph(text?: string): Paragraph { + const para = new Paragraph(text); + this.addContent(para); + return para; + } + + public get CellProperties(): TableCellProperties { + return this.properties; + } +} diff --git a/src/file/table/table-properties/index.ts b/src/file/table/table-properties/index.ts new file mode 100644 index 0000000000..913c3a7839 --- /dev/null +++ b/src/file/table/table-properties/index.ts @@ -0,0 +1,2 @@ +export * from "./table-properties"; +export * from "./table-float-properties"; diff --git a/src/file/table/table-properties/table-borders.ts b/src/file/table/table-properties/table-borders.ts new file mode 100644 index 0000000000..c27155ecd0 --- /dev/null +++ b/src/file/table/table-properties/table-borders.ts @@ -0,0 +1,36 @@ +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +export class TableBorders extends XmlComponent { + constructor() { + super("w:tblBorders"); + this.root.push(new TableBordersElement("w:top", "single", 4, 0, "auto")); + this.root.push(new TableBordersElement("w:left", "single", 4, 0, "auto")); + this.root.push(new TableBordersElement("w:bottom", "single", 4, 0, "auto")); + this.root.push(new TableBordersElement("w:right", "single", 4, 0, "auto")); + this.root.push(new TableBordersElement("w:insideH", "single", 4, 0, "auto")); + this.root.push(new TableBordersElement("w:insideV", "single", 4, 0, "auto")); + } +} + +class TableBordersElement extends XmlComponent { + constructor(elementName: string, value: string, size: number, space: number, color: string) { + super(elementName); + this.root.push( + new TableBordersAttributes({ + value, + size, + space, + color, + }), + ); + } +} + +class TableBordersAttributes extends XmlAttributeComponent<{ value: string; size: number; space: number; color: string }> { + protected xmlKeys = { + value: "w:val", + size: "w:sz", + space: "w:space", + color: "w:color", + }; +} diff --git a/src/file/table/table-cell-margin.ts b/src/file/table/table-properties/table-cell-margin.ts similarity index 97% rename from src/file/table/table-cell-margin.ts rename to src/file/table/table-properties/table-cell-margin.ts index 2b8fd32049..2cd14682fc 100644 --- a/src/file/table/table-cell-margin.ts +++ b/src/file/table/table-properties/table-cell-margin.ts @@ -1,5 +1,6 @@ import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components"; -import { WidthType } from "./table-cell"; + +import { WidthType } from "../table-cell"; class TableCellMarginAttributes extends XmlAttributeComponent<{ type: WidthType; value: number }> { protected xmlKeys = { value: "w:w", type: "w:sz" }; diff --git a/src/file/table/table-float-properties.spec.ts b/src/file/table/table-properties/table-float-properties.spec.ts similarity index 96% rename from src/file/table/table-float-properties.spec.ts rename to src/file/table/table-properties/table-float-properties.spec.ts index 57daea1f1a..e0abea8efe 100644 --- a/src/file/table/table-float-properties.spec.ts +++ b/src/file/table/table-properties/table-float-properties.spec.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; -import { Formatter } from "../../export/formatter"; +import { Formatter } from "../../../export/formatter"; import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType, TableFloatProperties } from "./table-float-properties"; describe("Table Float Properties", () => { diff --git a/src/file/table/table-float-properties.ts b/src/file/table/table-properties/table-float-properties.ts similarity index 100% rename from src/file/table/table-float-properties.ts rename to src/file/table/table-properties/table-float-properties.ts diff --git a/src/file/table/table-properties/table-layout.ts b/src/file/table/table-properties/table-layout.ts new file mode 100644 index 0000000000..85334181e0 --- /dev/null +++ b/src/file/table/table-properties/table-layout.ts @@ -0,0 +1,17 @@ +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +export enum TableLayoutType { + AUTOFIT = "autofit", + FIXED = "fixed", +} + +class TableLayoutAttributes extends XmlAttributeComponent<{ type: TableLayoutType }> { + protected xmlKeys = { type: "w:type" }; +} + +export class TableLayout extends XmlComponent { + constructor(type: TableLayoutType) { + super("w:tblLayout"); + this.root.push(new TableLayoutAttributes({ type })); + } +} diff --git a/src/file/table/properties.spec.ts b/src/file/table/table-properties/table-properties.spec.ts similarity index 91% rename from src/file/table/properties.spec.ts rename to src/file/table/table-properties/table-properties.spec.ts index a26e3fd352..6146a52b03 100644 --- a/src/file/table/properties.spec.ts +++ b/src/file/table/table-properties/table-properties.spec.ts @@ -1,8 +1,8 @@ import { expect } from "chai"; -import { Formatter } from "../../export/formatter"; -import { TableProperties } from "./properties"; -import { WidthType } from "./table-cell"; +import { Formatter } from "../../../export/formatter"; +import { WidthType } from "../table-cell"; +import { TableProperties } from "./table-properties"; describe("TableProperties", () => { describe("#constructor", () => { diff --git a/src/file/table/table-properties/table-properties.ts b/src/file/table/table-properties/table-properties.ts new file mode 100644 index 0000000000..f8198eea59 --- /dev/null +++ b/src/file/table/table-properties/table-properties.ts @@ -0,0 +1,43 @@ +import { XmlComponent } from "file/xml-components"; + +import { WidthType } from "../table-cell"; +import { TableBorders } from "./table-borders"; +import { TableCellMargin } from "./table-cell-margin"; +import { ITableFloatOptions, TableFloatProperties } from "./table-float-properties"; +import { TableLayout, TableLayoutType } from "./table-layout"; +import { PreferredTableWidth } from "./table-width"; + +export class TableProperties extends XmlComponent { + private readonly cellMargin: TableCellMargin; + + constructor() { + super("w:tblPr"); + + this.cellMargin = new TableCellMargin(); + this.root.push(this.cellMargin); + } + + public setWidth(type: WidthType, w: number | string): TableProperties { + this.root.push(new PreferredTableWidth(type, w)); + return this; + } + + public setFixedWidthLayout(): TableProperties { + this.root.push(new TableLayout(TableLayoutType.FIXED)); + return this; + } + + public setBorder(): TableProperties { + this.root.push(new TableBorders()); + return this; + } + + public get CellMargin(): TableCellMargin { + return this.cellMargin; + } + + public setTableFloatProperties(tableFloatOptions: ITableFloatOptions): TableProperties { + this.root.push(new TableFloatProperties(tableFloatOptions)); + return this; + } +} diff --git a/src/file/table/table-properties/table-width.ts b/src/file/table/table-properties/table-width.ts new file mode 100644 index 0000000000..27caa5c819 --- /dev/null +++ b/src/file/table/table-properties/table-width.ts @@ -0,0 +1,19 @@ +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +import { WidthType } from "../table-cell"; + +interface ITableWidth { + type: WidthType; + w: number | string; +} + +class TableWidthAttributes extends XmlAttributeComponent { + protected xmlKeys = { type: "w:type", w: "w:w" }; +} + +export class PreferredTableWidth extends XmlComponent { + constructor(type: WidthType, w: number | string) { + super("w:tblW"); + this.root.push(new TableWidthAttributes({ type, w })); + } +} diff --git a/src/file/table/table-row/index.ts b/src/file/table/table-row/index.ts new file mode 100644 index 0000000000..c8a880cf50 --- /dev/null +++ b/src/file/table/table-row/index.ts @@ -0,0 +1,2 @@ +export * from "./table-row"; +export * from "./table-row-properties"; diff --git a/src/file/table/table-row/table-row-properties.ts b/src/file/table/table-row/table-row-properties.ts new file mode 100644 index 0000000000..7d96ea9810 --- /dev/null +++ b/src/file/table/table-row/table-row-properties.ts @@ -0,0 +1,7 @@ +import { XmlComponent } from "file/xml-components"; + +export class TableRowProperties extends XmlComponent { + constructor() { + super("w:trPr"); + } +} diff --git a/src/file/table/table-row/table-row.ts b/src/file/table/table-row/table-row.ts new file mode 100644 index 0000000000..d1ced91c4a --- /dev/null +++ b/src/file/table/table-row/table-row.ts @@ -0,0 +1,40 @@ +import { XmlComponent } from "file/xml-components"; + +import { TableCell } from "../table-cell"; +import { TableRowProperties } from "./table-row-properties"; + +export class TableRow extends XmlComponent { + private readonly properties: TableRowProperties; + + constructor(private readonly cells: TableCell[]) { + super("w:tr"); + this.properties = new TableRowProperties(); + this.root.push(this.properties); + cells.forEach((c) => this.root.push(c)); + } + + public getCell(ix: number): TableCell { + const cell = this.cells[ix]; + + if (!cell) { + throw Error("Index out of bounds when trying to get cell on row"); + } + + return cell; + } + + public addGridSpan(index: number, cellSpan: number): TableCell { + const remainCell = this.cells[index]; + remainCell.CellProperties.addGridSpan(cellSpan); + this.cells.splice(index + 1, cellSpan - 1); + this.root.splice(index + 2, cellSpan - 1); + + return remainCell; + } + + public mergeCells(startIndex: number, endIndex: number): TableCell { + const cellSpan = endIndex - startIndex + 1; + + return this.addGridSpan(startIndex, cellSpan); + } +} diff --git a/src/file/table/table.spec.ts b/src/file/table/table.spec.ts index c67e11b9e1..65c259ef12 100644 --- a/src/file/table/table.spec.ts +++ b/src/file/table/table.spec.ts @@ -5,7 +5,7 @@ import { Formatter } from "../../export/formatter"; import { Paragraph } from "../paragraph"; import { Table } from "./"; import { WidthType } from "./table-cell"; -import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType } from "./table-float-properties"; +import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType } from "./table-properties"; const DEFAULT_TABLE_PROPERTIES = { "w:tblBorders": [ diff --git a/src/file/table/table.ts b/src/file/table/table.ts index b9d18567d0..8311b5ecfd 100644 --- a/src/file/table/table.ts +++ b/src/file/table/table.ts @@ -1,20 +1,10 @@ // http://officeopenxml.com/WPtableGrid.php -import { - GridSpan, - TableCellBorders, - TableCellShading, - TableCellWidth, - VAlign, - VerticalAlign, - VMerge, - VMergeType, - WidthType, -} from "file/table/table-cell"; -import { IXmlableObject, XmlComponent } from "file/xml-components"; -import { Paragraph } from "../paragraph"; +import { XmlComponent } from "file/xml-components"; + import { TableGrid } from "./grid"; -import { TableProperties } from "./properties"; -import { ITableFloatOptions, TableFloatProperties } from "./table-float-properties"; +import { TableCell, WidthType } from "./table-cell"; +import { ITableFloatOptions, TableProperties } from "./table-properties"; +import { TableRow } from "./table-row"; export class Table extends XmlComponent { private readonly properties: TableProperties; @@ -85,8 +75,8 @@ export class Table extends XmlComponent { return this; } - public float(tableFloatProperties: ITableFloatOptions): Table { - this.properties.setTableFloatProperties(new TableFloatProperties(tableFloatProperties)); + public float(tableFloatOptions: ITableFloatOptions): Table { + this.properties.setTableFloatProperties(tableFloatOptions); return this; } @@ -94,128 +84,3 @@ export class Table extends XmlComponent { return this.properties; } } - -export class TableRow extends XmlComponent { - private readonly properties: TableRowProperties; - - constructor(private readonly cells: TableCell[]) { - super("w:tr"); - this.properties = new TableRowProperties(); - this.root.push(this.properties); - cells.forEach((c) => this.root.push(c)); - } - - public getCell(ix: number): TableCell { - const cell = this.cells[ix]; - - if (!cell) { - throw Error("Index out of bounds when trying to get cell on row"); - } - - return cell; - } - - public addGridSpan(index: number, cellSpan: number): TableCell { - const remainCell = this.cells[index]; - remainCell.CellProperties.addGridSpan(cellSpan); - this.cells.splice(index + 1, cellSpan - 1); - this.root.splice(index + 2, cellSpan - 1); - - return remainCell; - } - - public mergeCells(startIndex: number, endIndex: number): TableCell { - const cellSpan = endIndex - startIndex + 1; - - return this.addGridSpan(startIndex, cellSpan); - } -} - -export class TableRowProperties extends XmlComponent { - constructor() { - super("w:trPr"); - } -} - -export class TableCell extends XmlComponent { - private readonly properties: TableCellProperties; - - constructor() { - super("w:tc"); - this.properties = new TableCellProperties(); - this.root.push(this.properties); - } - - public addContent(content: Paragraph | Table): TableCell { - this.root.push(content); - return this; - } - - public prepForXml(): IXmlableObject | undefined { - // Cells must end with a paragraph - const retval = super.prepForXml(); - if (!retval) { - return undefined; - } - - const content = retval["w:tc"]; - if (!content[content.length - 1]["w:p"]) { - content.push(new Paragraph().prepForXml()); - } - return retval; - } - - public createParagraph(text?: string): Paragraph { - const para = new Paragraph(text); - this.addContent(para); - return para; - } - - public get CellProperties(): TableCellProperties { - return this.properties; - } -} - -export class TableCellProperties extends XmlComponent { - private readonly cellBorder: TableCellBorders; - - constructor() { - super("w:tcPr"); - this.cellBorder = new TableCellBorders(); - this.root.push(this.cellBorder); - } - - public get Borders(): TableCellBorders { - return this.cellBorder; - } - - public addGridSpan(cellSpan: number): TableCellProperties { - this.root.push(new GridSpan(cellSpan)); - - return this; - } - - public addVerticalMerge(type: VMergeType): TableCellProperties { - this.root.push(new VMerge(type)); - - return this; - } - - public setVerticalAlign(type: VerticalAlign): TableCellProperties { - this.root.push(new VAlign(type)); - - return this; - } - - public setWidth(width: string | number, type: WidthType): TableCellProperties { - this.root.push(new TableCellWidth(width, type)); - - return this; - } - - public setShading(attrs: object): TableCellProperties { - this.root.push(new TableCellShading(attrs)); - - return this; - } -}