Make .addSection fully declarative
This commit is contained in:
@ -3,12 +3,14 @@ import { ICustomPropertyOptions } from "../custom-properties";
|
||||
import { IDocumentBackgroundOptions } from "../document";
|
||||
|
||||
import { DocumentAttributes } from "../document/document-attributes";
|
||||
import { ISectionOptions } from "../file";
|
||||
import { INumberingOptions } from "../numbering";
|
||||
import { Paragraph } from "../paragraph";
|
||||
import { IStylesOptions } from "../styles";
|
||||
import { Created, Creator, Description, Keywords, LastModifiedBy, Modified, Revision, Subject, Title } from "./components";
|
||||
|
||||
export interface IPropertiesOptions {
|
||||
readonly sections: ISectionOptions[];
|
||||
readonly title?: string;
|
||||
readonly subject?: string;
|
||||
readonly creator?: string;
|
||||
@ -34,7 +36,7 @@ export interface IPropertiesOptions {
|
||||
}
|
||||
|
||||
export class CoreProperties extends XmlComponent {
|
||||
constructor(options: IPropertiesOptions) {
|
||||
constructor(options: Omit<IPropertiesOptions, "sections">) {
|
||||
super("cp:coreProperties");
|
||||
this.root.push(
|
||||
new DocumentAttributes({
|
||||
|
@ -14,8 +14,12 @@ describe("Body", () => {
|
||||
describe("#addSection", () => {
|
||||
it("should add section with default parameters", () => {
|
||||
body.addSection({
|
||||
width: 10000,
|
||||
height: 10000,
|
||||
page: {
|
||||
size: {
|
||||
width: 10000,
|
||||
height: 10000,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(body);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IContext, IXmlableObject, XmlComponent } from "file/xml-components";
|
||||
|
||||
import { Paragraph, ParagraphProperties, TableOfContents } from "../..";
|
||||
import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties";
|
||||
import { ISectionPropertiesOptions, SectionProperties } from "./section-properties/section-properties";
|
||||
|
||||
export class Body extends XmlComponent {
|
||||
private readonly sections: SectionProperties[] = [];
|
||||
@ -18,7 +18,7 @@ export class Body extends XmlComponent {
|
||||
* - last section should be direct child of body
|
||||
* @param options new section options
|
||||
*/
|
||||
public addSection(options: SectionPropertiesOptions): void {
|
||||
public addSection(options: ISectionPropertiesOptions): void {
|
||||
const currentSection = this.sections.pop() as SectionProperties;
|
||||
this.root.push(this.createSectionParagraph(currentSection));
|
||||
|
||||
|
@ -8,18 +8,18 @@ export enum LineNumberRestartFormat {
|
||||
}
|
||||
|
||||
export interface ILineNumberAttributes {
|
||||
readonly lineNumberCountBy?: number;
|
||||
readonly lineNumberStart?: number;
|
||||
readonly lineNumberRestart?: LineNumberRestartFormat;
|
||||
readonly lineNumberDistance?: number;
|
||||
readonly countBy?: number;
|
||||
readonly start?: number;
|
||||
readonly restart?: LineNumberRestartFormat;
|
||||
readonly distance?: number;
|
||||
}
|
||||
|
||||
export class LineNumberAttributes extends XmlAttributeComponent<ILineNumberAttributes> {
|
||||
protected readonly xmlKeys = {
|
||||
lineNumberCountBy: "w:countBy",
|
||||
lineNumberStart: "w:start",
|
||||
lineNumberRestart: "w:restart",
|
||||
lineNumberDistance: "w:distance",
|
||||
countBy: "w:countBy",
|
||||
start: "w:start",
|
||||
restart: "w:restart",
|
||||
distance: "w:distance",
|
||||
};
|
||||
}
|
||||
|
||||
@ -28,10 +28,10 @@ export class LineNumberType extends XmlComponent {
|
||||
super("w:lnNumType");
|
||||
this.root.push(
|
||||
new LineNumberAttributes({
|
||||
lineNumberCountBy: countBy,
|
||||
lineNumberStart: start,
|
||||
lineNumberRestart: restart,
|
||||
lineNumberDistance: dist,
|
||||
countBy: countBy,
|
||||
start: start,
|
||||
restart: restart,
|
||||
distance: dist,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -26,16 +26,16 @@ export enum PageNumberSeparator {
|
||||
}
|
||||
|
||||
export interface IPageNumberTypeAttributes {
|
||||
readonly pageNumberStart?: number;
|
||||
readonly pageNumberFormatType?: PageNumberFormat;
|
||||
readonly pageNumberSeparator?: PageNumberSeparator;
|
||||
readonly start?: number;
|
||||
readonly formatType?: PageNumberFormat;
|
||||
readonly separator?: PageNumberSeparator;
|
||||
}
|
||||
|
||||
export class PageNumberTypeAttributes extends XmlAttributeComponent<IPageNumberTypeAttributes> {
|
||||
protected readonly xmlKeys = {
|
||||
pageNumberStart: "w:start",
|
||||
pageNumberFormatType: "w:fmt",
|
||||
pageNumberSeparator: "w:chapSep",
|
||||
start: "w:start",
|
||||
formatType: "w:fmt",
|
||||
separator: "w:chapSep",
|
||||
};
|
||||
}
|
||||
|
||||
@ -44,9 +44,9 @@ export class PageNumberType extends XmlComponent {
|
||||
super("w:pgNumType");
|
||||
this.root.push(
|
||||
new PageNumberTypeAttributes({
|
||||
pageNumberStart: start,
|
||||
pageNumberFormatType: numberFormat,
|
||||
pageNumberSeparator: separator,
|
||||
start: start,
|
||||
formatType: numberFormat,
|
||||
separator: separator,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -19,34 +19,46 @@ describe("SectionProperties", () => {
|
||||
const media = new Media();
|
||||
|
||||
const properties = new SectionProperties({
|
||||
width: 11906,
|
||||
height: 16838,
|
||||
top: convertInchesToTwip(1),
|
||||
right: convertInchesToTwip(1),
|
||||
bottom: convertInchesToTwip(1),
|
||||
left: convertInchesToTwip(1),
|
||||
header: 708,
|
||||
footer: 708,
|
||||
gutter: 0,
|
||||
mirror: false,
|
||||
page: {
|
||||
size: {
|
||||
width: 11906,
|
||||
height: 16838,
|
||||
},
|
||||
margin: {
|
||||
top: convertInchesToTwip(1),
|
||||
right: convertInchesToTwip(1),
|
||||
bottom: convertInchesToTwip(1),
|
||||
left: convertInchesToTwip(1),
|
||||
header: 708,
|
||||
footer: 708,
|
||||
gutter: 0,
|
||||
mirror: false,
|
||||
},
|
||||
pageNumbers: {
|
||||
start: 10,
|
||||
formatType: PageNumberFormat.CARDINAL_TEXT,
|
||||
},
|
||||
},
|
||||
column: {
|
||||
space: 708,
|
||||
count: 1,
|
||||
separate: true,
|
||||
},
|
||||
linePitch: convertInchesToTwip(0.25),
|
||||
headers: {
|
||||
grid: {
|
||||
linePitch: convertInchesToTwip(0.25),
|
||||
},
|
||||
headerWrapperGroup: {
|
||||
default: new HeaderWrapper(media, 100),
|
||||
},
|
||||
footers: {
|
||||
footerWrapperGroup: {
|
||||
even: new FooterWrapper(media, 200),
|
||||
},
|
||||
pageNumberStart: 10,
|
||||
pageNumberFormatType: PageNumberFormat.CARDINAL_TEXT,
|
||||
titlePage: true,
|
||||
verticalAlign: SectionVerticalAlignValue.TOP,
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(properties);
|
||||
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
||||
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
|
||||
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
|
||||
@ -98,7 +110,11 @@ describe("SectionProperties", () => {
|
||||
|
||||
it("should create section properties with changed options", () => {
|
||||
const properties = new SectionProperties({
|
||||
top: 0,
|
||||
page: {
|
||||
margin: {
|
||||
top: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
||||
@ -122,7 +138,11 @@ describe("SectionProperties", () => {
|
||||
|
||||
it("should create section properties with changed options", () => {
|
||||
const properties = new SectionProperties({
|
||||
bottom: 0,
|
||||
page: {
|
||||
margin: {
|
||||
bottom: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
||||
@ -146,8 +166,12 @@ describe("SectionProperties", () => {
|
||||
|
||||
it("should create section properties with changed options", () => {
|
||||
const properties = new SectionProperties({
|
||||
width: 0,
|
||||
height: 0,
|
||||
page: {
|
||||
size: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
||||
@ -171,8 +195,12 @@ describe("SectionProperties", () => {
|
||||
|
||||
it("should create section properties with page borders", () => {
|
||||
const properties = new SectionProperties({
|
||||
pageBorders: {
|
||||
offsetFrom: PageBorderOffsetFrom.PAGE,
|
||||
page: {
|
||||
borders: {
|
||||
pageBorders: {
|
||||
offsetFrom: PageBorderOffsetFrom.PAGE,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
@ -185,7 +213,11 @@ describe("SectionProperties", () => {
|
||||
|
||||
it("should create section properties with page number type, but without start attribute", () => {
|
||||
const properties = new SectionProperties({
|
||||
pageNumberFormatType: PageNumberFormat.UPPER_ROMAN,
|
||||
page: {
|
||||
pageNumbers: {
|
||||
formatType: PageNumberFormat.UPPER_ROMAN,
|
||||
},
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
||||
@ -217,10 +249,12 @@ describe("SectionProperties", () => {
|
||||
|
||||
it("should create section properties line number type", () => {
|
||||
const properties = new SectionProperties({
|
||||
lineNumberCountBy: 2,
|
||||
lineNumberStart: 2,
|
||||
lineNumberRestart: LineNumberRestartFormat.CONTINUOUS,
|
||||
lineNumberDistance: 4,
|
||||
lineNumbers: {
|
||||
countBy: 2,
|
||||
start: 2,
|
||||
restart: LineNumberRestartFormat.CONTINUOUS,
|
||||
distance: 4,
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
||||
|
@ -1,4 +1,6 @@
|
||||
// http://officeopenxml.com/WPsection.php
|
||||
// tslint:disable: no-unnecessary-initializer
|
||||
|
||||
import { convertInchesToTwip } from "convenience-functions";
|
||||
import { FooterWrapper } from "file/footer-wrapper";
|
||||
import { HeaderWrapper } from "file/header-wrapper";
|
||||
@ -21,7 +23,7 @@ import { IPageSizeAttributes, PageOrientation } from "./page-size/page-size-attr
|
||||
import { TitlePage } from "./title-page/title-page";
|
||||
import { Type } from "./type/section-type";
|
||||
import { SectionType } from "./type/section-type-attributes";
|
||||
import { ISectionVerticalAlignAttributes, SectionVerticalAlign } from "./vertical-align";
|
||||
import { SectionVerticalAlign, SectionVerticalAlignValue } from "./vertical-align";
|
||||
|
||||
export interface IHeaderFooterGroup<T> {
|
||||
readonly default?: T;
|
||||
@ -29,89 +31,71 @@ export interface IHeaderFooterGroup<T> {
|
||||
readonly even?: T;
|
||||
}
|
||||
|
||||
interface IHeadersOptions {
|
||||
readonly headers?: IHeaderFooterGroup<HeaderWrapper>;
|
||||
}
|
||||
|
||||
interface IFootersOptions {
|
||||
readonly footers?: IHeaderFooterGroup<FooterWrapper>;
|
||||
}
|
||||
|
||||
interface ITitlePageOptions {
|
||||
readonly titlePage?: boolean;
|
||||
}
|
||||
|
||||
export type SectionPropertiesOptions = IPageSizeAttributes &
|
||||
IPageMarginAttributes &
|
||||
IDocGridAttributesProperties &
|
||||
IHeadersOptions &
|
||||
IFootersOptions &
|
||||
IPageNumberTypeAttributes &
|
||||
ILineNumberAttributes &
|
||||
IPageBordersOptions &
|
||||
ITitlePageOptions &
|
||||
ISectionVerticalAlignAttributes & {
|
||||
readonly column?: {
|
||||
readonly space?: number;
|
||||
readonly count?: number;
|
||||
readonly separate?: boolean;
|
||||
};
|
||||
readonly type?: SectionType;
|
||||
export interface ISectionPropertiesOptions {
|
||||
readonly page?: {
|
||||
readonly size?: IPageSizeAttributes;
|
||||
readonly margin?: IPageMarginAttributes;
|
||||
readonly pageNumbers?: IPageNumberTypeAttributes;
|
||||
readonly borders?: IPageBordersOptions;
|
||||
};
|
||||
// Need to decouple this from the attributes
|
||||
|
||||
readonly grid?: IDocGridAttributesProperties;
|
||||
readonly headerWrapperGroup?: IHeaderFooterGroup<HeaderWrapper>;
|
||||
readonly footerWrapperGroup?: IHeaderFooterGroup<FooterWrapper>;
|
||||
readonly lineNumbers?: ILineNumberAttributes;
|
||||
readonly titlePage?: boolean;
|
||||
readonly verticalAlign?: SectionVerticalAlignValue;
|
||||
readonly column?: {
|
||||
readonly space?: number;
|
||||
readonly count?: number;
|
||||
readonly separate?: boolean;
|
||||
};
|
||||
readonly type?: SectionType;
|
||||
}
|
||||
export class SectionProperties extends XmlComponent {
|
||||
public readonly width: number;
|
||||
public readonly rightMargin: number;
|
||||
public readonly leftMargin: number;
|
||||
|
||||
constructor(
|
||||
{
|
||||
width = 11906,
|
||||
height = 16838,
|
||||
top = convertInchesToTwip(1),
|
||||
right = convertInchesToTwip(1),
|
||||
bottom = convertInchesToTwip(1),
|
||||
left = convertInchesToTwip(1),
|
||||
header = 708,
|
||||
footer = 708,
|
||||
gutter = 0,
|
||||
mirror = false,
|
||||
column = {},
|
||||
linePitch = 360,
|
||||
orientation = PageOrientation.PORTRAIT,
|
||||
headers,
|
||||
footers,
|
||||
pageNumberFormatType,
|
||||
pageNumberStart,
|
||||
pageNumberSeparator,
|
||||
lineNumberCountBy,
|
||||
lineNumberStart,
|
||||
lineNumberRestart,
|
||||
lineNumberDistance,
|
||||
pageBorders,
|
||||
pageBorderTop,
|
||||
pageBorderRight,
|
||||
pageBorderBottom,
|
||||
pageBorderLeft,
|
||||
titlePage = false,
|
||||
verticalAlign,
|
||||
type,
|
||||
}: SectionPropertiesOptions = { column: {} },
|
||||
) {
|
||||
constructor({
|
||||
page: {
|
||||
size: { width = 11906, height = 16838, orientation = PageOrientation.PORTRAIT } = {},
|
||||
margin: {
|
||||
top = convertInchesToTwip(1),
|
||||
right = convertInchesToTwip(1),
|
||||
bottom = convertInchesToTwip(1),
|
||||
left = convertInchesToTwip(1),
|
||||
header = 708,
|
||||
footer = 708,
|
||||
gutter = 0,
|
||||
mirror = false,
|
||||
} = {},
|
||||
pageNumbers: {
|
||||
start: pageNumberStart = undefined,
|
||||
formatType: pageNumberFormatType = undefined,
|
||||
separator: pageNumberSeparator = undefined,
|
||||
} = {},
|
||||
borders: {
|
||||
pageBorders = undefined,
|
||||
pageBorderTop = undefined,
|
||||
pageBorderRight = undefined,
|
||||
pageBorderBottom = undefined,
|
||||
pageBorderLeft = undefined,
|
||||
} = {},
|
||||
} = {},
|
||||
grid: { linePitch = 360 } = {},
|
||||
headerWrapperGroup = {},
|
||||
footerWrapperGroup = {},
|
||||
lineNumbers: { countBy: lineNumberCountBy, start: lineNumberStart, restart: lineNumberRestart, distance: lineNumberDistance } = {},
|
||||
titlePage = false,
|
||||
verticalAlign,
|
||||
column: { space = 708, count = 1, separate = false } = {},
|
||||
type,
|
||||
}: ISectionPropertiesOptions = {}) {
|
||||
super("w:sectPr");
|
||||
|
||||
this.leftMargin = left;
|
||||
this.rightMargin = right;
|
||||
this.width = width;
|
||||
|
||||
this.root.push(new PageSize(width, height, orientation));
|
||||
this.root.push(new PageMargin(top, right, bottom, left, header, footer, gutter, mirror));
|
||||
this.root.push(new Columns(column.space ? column.space : 708, column.count ? column.count : 1, column.separate ?? false));
|
||||
this.root.push(new Columns(space, count, separate));
|
||||
this.root.push(new DocumentGrid(linePitch));
|
||||
|
||||
this.addHeaders(headers);
|
||||
this.addFooters(footers);
|
||||
this.addHeaders(headerWrapperGroup);
|
||||
this.addFooters(footerWrapperGroup);
|
||||
|
||||
this.root.push(new PageNumberType(pageNumberStart, pageNumberFormatType, pageNumberSeparator));
|
||||
|
||||
@ -144,65 +128,61 @@ export class SectionProperties extends XmlComponent {
|
||||
}
|
||||
}
|
||||
|
||||
private addHeaders(headers?: IHeaderFooterGroup<HeaderWrapper>): void {
|
||||
if (headers) {
|
||||
if (headers.default) {
|
||||
this.root.push(
|
||||
new HeaderReference({
|
||||
headerType: HeaderReferenceType.DEFAULT,
|
||||
headerId: headers.default.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
private addHeaders(headers: IHeaderFooterGroup<HeaderWrapper>): void {
|
||||
if (headers.default) {
|
||||
this.root.push(
|
||||
new HeaderReference({
|
||||
headerType: HeaderReferenceType.DEFAULT,
|
||||
headerId: headers.default.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (headers.first) {
|
||||
this.root.push(
|
||||
new HeaderReference({
|
||||
headerType: HeaderReferenceType.FIRST,
|
||||
headerId: headers.first.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (headers.first) {
|
||||
this.root.push(
|
||||
new HeaderReference({
|
||||
headerType: HeaderReferenceType.FIRST,
|
||||
headerId: headers.first.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (headers.even) {
|
||||
this.root.push(
|
||||
new HeaderReference({
|
||||
headerType: HeaderReferenceType.EVEN,
|
||||
headerId: headers.even.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (headers.even) {
|
||||
this.root.push(
|
||||
new HeaderReference({
|
||||
headerType: HeaderReferenceType.EVEN,
|
||||
headerId: headers.even.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private addFooters(footers?: IHeaderFooterGroup<FooterWrapper>): void {
|
||||
if (footers) {
|
||||
if (footers.default) {
|
||||
this.root.push(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.DEFAULT,
|
||||
footerId: footers.default.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
private addFooters(footers: IHeaderFooterGroup<FooterWrapper>): void {
|
||||
if (footers.default) {
|
||||
this.root.push(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.DEFAULT,
|
||||
footerId: footers.default.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (footers.first) {
|
||||
this.root.push(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.FIRST,
|
||||
footerId: footers.first.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (footers.first) {
|
||||
this.root.push(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.FIRST,
|
||||
footerId: footers.first.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (footers.even) {
|
||||
this.root.push(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.EVEN,
|
||||
footerId: footers.even.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (footers.even) {
|
||||
this.root.push(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.EVEN,
|
||||
footerId: footers.even.View.ReferenceId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
import { XmlAttributeComponent } from "file/xml-components";
|
||||
import { SectionVerticalAlignValue } from "./vertical-align";
|
||||
|
||||
export interface ISectionVerticalAlignAttributes {
|
||||
export class SectionVerticalAlignAttributes extends XmlAttributeComponent<{
|
||||
readonly verticalAlign?: SectionVerticalAlignValue;
|
||||
}
|
||||
|
||||
export class SectionVerticalAlignAttributes extends XmlAttributeComponent<ISectionVerticalAlignAttributes> {
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
verticalAlign: "w:val",
|
||||
};
|
||||
|
@ -1,40 +1,26 @@
|
||||
import { expect } from "chai";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import { Formatter } from "export/formatter";
|
||||
|
||||
import { File } from "./file";
|
||||
import { Footer, Header } from "./header";
|
||||
import { Paragraph } from "./paragraph";
|
||||
import { Table, TableCell, TableRow } from "./table";
|
||||
import { TableOfContents } from "./table-of-contents";
|
||||
|
||||
describe("File", () => {
|
||||
describe("#constructor", () => {
|
||||
it("should create with correct headers and footers by default", () => {
|
||||
const doc = new File();
|
||||
|
||||
doc.addSection({
|
||||
children: [],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(doc.Document.View.Body);
|
||||
|
||||
expect(tree["w:body"][0]["w:sectPr"][4]["w:headerReference"]._attr["w:type"]).to.equal("default");
|
||||
expect(tree["w:body"][0]["w:sectPr"][5]["w:footerReference"]._attr["w:type"]).to.equal("default");
|
||||
});
|
||||
|
||||
it("should create with correct headers and footers", () => {
|
||||
const doc = new File();
|
||||
|
||||
doc.addSection({
|
||||
headers: {
|
||||
default: new Header(),
|
||||
},
|
||||
footers: {
|
||||
default: new Footer(),
|
||||
},
|
||||
children: [],
|
||||
const doc = new File({
|
||||
sections: [
|
||||
{
|
||||
headers: {
|
||||
default: new Header(),
|
||||
},
|
||||
footers: {
|
||||
default: new Footer(),
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(doc.Document.View.Body);
|
||||
@ -44,16 +30,18 @@ describe("File", () => {
|
||||
});
|
||||
|
||||
it("should create with first headers and footers", () => {
|
||||
const doc = new File();
|
||||
|
||||
doc.addSection({
|
||||
headers: {
|
||||
first: new Header(),
|
||||
},
|
||||
footers: {
|
||||
first: new Footer(),
|
||||
},
|
||||
children: [],
|
||||
const doc = new File({
|
||||
sections: [
|
||||
{
|
||||
headers: {
|
||||
first: new Header(),
|
||||
},
|
||||
footers: {
|
||||
first: new Footer(),
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(doc.Document.View.Body);
|
||||
@ -62,20 +50,22 @@ describe("File", () => {
|
||||
});
|
||||
|
||||
it("should create with correct headers", () => {
|
||||
const doc = new File();
|
||||
|
||||
doc.addSection({
|
||||
headers: {
|
||||
default: new Header(),
|
||||
first: new Header(),
|
||||
even: new Header(),
|
||||
},
|
||||
footers: {
|
||||
default: new Footer(),
|
||||
first: new Footer(),
|
||||
even: new Footer(),
|
||||
},
|
||||
children: [],
|
||||
const doc = new File({
|
||||
sections: [
|
||||
{
|
||||
headers: {
|
||||
default: new Header(),
|
||||
first: new Header(),
|
||||
even: new Header(),
|
||||
},
|
||||
footers: {
|
||||
default: new Footer(),
|
||||
first: new Footer(),
|
||||
even: new Footer(),
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(doc.Document.View.Body);
|
||||
@ -90,11 +80,13 @@ describe("File", () => {
|
||||
});
|
||||
|
||||
it("should add child", () => {
|
||||
const doc = new File(undefined, undefined, [
|
||||
{
|
||||
children: [new Paragraph("test")],
|
||||
},
|
||||
]);
|
||||
const doc = new File({
|
||||
sections: [
|
||||
{
|
||||
children: [new Paragraph("test")],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(doc.Document.View.Body);
|
||||
|
||||
@ -171,69 +163,13 @@ describe("File", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#addSection", () => {
|
||||
it("should call the underlying document's add a Paragraph", () => {
|
||||
const file = new File();
|
||||
const spy = sinon.spy(file.Document.View, "add");
|
||||
file.addSection({
|
||||
children: [new Paragraph({})],
|
||||
});
|
||||
|
||||
expect(spy.called).to.equal(true);
|
||||
});
|
||||
|
||||
it("should call the underlying document's add when adding a Table", () => {
|
||||
const file = new File();
|
||||
const spy = sinon.spy(file.Document.View, "add");
|
||||
file.addSection({
|
||||
children: [
|
||||
new Table({
|
||||
rows: [
|
||||
new TableRow({
|
||||
children: [
|
||||
new TableCell({
|
||||
children: [new Paragraph("hello")],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
expect(spy.called).to.equal(true);
|
||||
});
|
||||
|
||||
it("should call the underlying document's add when adding an Image (paragraph)", () => {
|
||||
const file = new File();
|
||||
const spy = sinon.spy(file.Document.View, "add");
|
||||
// tslint:disable-next-line:no-any
|
||||
file.addSection({
|
||||
children: [new Paragraph("")],
|
||||
});
|
||||
|
||||
expect(spy.called).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#addSection", () => {
|
||||
it("should call the underlying document's add", () => {
|
||||
const file = new File();
|
||||
const spy = sinon.spy(file.Document.View, "add");
|
||||
file.addSection({
|
||||
children: [new TableOfContents()],
|
||||
});
|
||||
|
||||
expect(spy.called).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#addTrackRevisionsFeature", () => {
|
||||
it("should call the underlying document's add", () => {
|
||||
const file = new File({
|
||||
features: {
|
||||
trackRevisions: true,
|
||||
},
|
||||
sections: [],
|
||||
});
|
||||
|
||||
// tslint:disable-next-line: no-unused-expression no-string-literal
|
||||
@ -249,6 +185,7 @@ describe("File", () => {
|
||||
children: [new Paragraph("hello")],
|
||||
},
|
||||
},
|
||||
sections: [],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(wrapper.FootNotes.View);
|
||||
@ -435,6 +372,7 @@ describe("File", () => {
|
||||
styles: {
|
||||
default: {},
|
||||
},
|
||||
sections: [],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(doc.Styles);
|
||||
@ -454,6 +392,7 @@ describe("File", () => {
|
||||
it("should create with even and odd headers and footers", () => {
|
||||
const doc = new File({
|
||||
evenAndOddHeaderAndFooters: true,
|
||||
sections: [],
|
||||
});
|
||||
|
||||
const tree = new Formatter().format(doc.Settings);
|
||||
|
@ -3,13 +3,7 @@ import { ContentTypes } from "./content-types/content-types";
|
||||
import { CoreProperties, IPropertiesOptions } from "./core-properties";
|
||||
import { CustomProperties } from "./custom-properties";
|
||||
import { DocumentWrapper } from "./document-wrapper";
|
||||
import {
|
||||
FooterReferenceType,
|
||||
HeaderReferenceType,
|
||||
IPageSizeAttributes,
|
||||
SectionPropertiesOptions,
|
||||
} from "./document/body/section-properties";
|
||||
import { IPageMarginAttributes } from "./document/body/section-properties/page-margin/page-margin-attributes";
|
||||
import { FooterReferenceType, HeaderReferenceType, ISectionPropertiesOptions } from "./document/body/section-properties";
|
||||
import { IFileProperties } from "./file-properties";
|
||||
import { FooterWrapper, IDocumentFooter } from "./footer-wrapper";
|
||||
import { FootnotesWrapper } from "./footnotes-wrapper";
|
||||
@ -37,9 +31,7 @@ export interface ISectionOptions {
|
||||
readonly first?: Footer;
|
||||
readonly even?: Footer;
|
||||
};
|
||||
readonly size?: IPageSizeAttributes;
|
||||
readonly margins?: IPageMarginAttributes;
|
||||
readonly properties?: SectionPropertiesOptions;
|
||||
readonly properties?: ISectionPropertiesOptions;
|
||||
readonly children: (Paragraph | Table | TableOfContents)[];
|
||||
}
|
||||
|
||||
@ -61,16 +53,14 @@ export class File {
|
||||
private readonly appProperties: AppProperties;
|
||||
private readonly styles: Styles;
|
||||
|
||||
constructor(
|
||||
options: IPropertiesOptions = {
|
||||
creator: "Un-named",
|
||||
revision: "1",
|
||||
lastModifiedBy: "Un-named",
|
||||
},
|
||||
fileProperties: IFileProperties = {},
|
||||
sections: ISectionOptions[] = [],
|
||||
) {
|
||||
this.coreProperties = new CoreProperties(options);
|
||||
constructor(options: IPropertiesOptions, fileProperties: IFileProperties = {}) {
|
||||
this.coreProperties = new CoreProperties({
|
||||
...options,
|
||||
creator: options.creator ?? "Un-named",
|
||||
revision: options.revision ?? "1",
|
||||
lastModifiedBy: options.lastModifiedBy ?? "Un-named",
|
||||
});
|
||||
|
||||
this.numbering = new Numbering(
|
||||
options.numbering
|
||||
? options.numbering
|
||||
@ -78,6 +68,7 @@ export class File {
|
||||
config: [],
|
||||
},
|
||||
);
|
||||
|
||||
this.fileRelationships = new Relationships();
|
||||
this.customProperties = new CustomProperties(options.customProperties ?? []);
|
||||
this.appProperties = new AppProperties();
|
||||
@ -131,12 +122,8 @@ export class File {
|
||||
}
|
||||
}
|
||||
|
||||
for (const section of sections) {
|
||||
this.documentWrapper.View.Body.addSection(section.properties ? section.properties : {});
|
||||
|
||||
for (const child of section.children) {
|
||||
this.documentWrapper.View.add(child);
|
||||
}
|
||||
for (const section of options.sections) {
|
||||
this.addSection(section);
|
||||
}
|
||||
|
||||
if (options.footnotes) {
|
||||
@ -153,28 +140,25 @@ export class File {
|
||||
}
|
||||
}
|
||||
|
||||
public addSection({
|
||||
headers = { default: new Header() },
|
||||
footers = { default: new Header() },
|
||||
margins = {},
|
||||
size = {},
|
||||
properties,
|
||||
children,
|
||||
}: ISectionOptions): void {
|
||||
public verifyUpdateFields(): void {
|
||||
if (this.documentWrapper.View.getTablesOfContents().length) {
|
||||
this.settings.addUpdateFields();
|
||||
}
|
||||
}
|
||||
|
||||
private addSection({ headers = {}, footers = {}, children, properties }: ISectionOptions): void {
|
||||
this.documentWrapper.View.Body.addSection({
|
||||
...properties,
|
||||
headers: {
|
||||
headerWrapperGroup: {
|
||||
default: headers.default ? this.createHeader(headers.default) : undefined,
|
||||
first: headers.first ? this.createHeader(headers.first) : undefined,
|
||||
even: headers.even ? this.createHeader(headers.even) : undefined,
|
||||
},
|
||||
footers: {
|
||||
footerWrapperGroup: {
|
||||
default: footers.default ? this.createFooter(footers.default) : undefined,
|
||||
first: footers.first ? this.createFooter(footers.first) : undefined,
|
||||
even: footers.even ? this.createFooter(footers.even) : undefined,
|
||||
},
|
||||
...margins,
|
||||
...size,
|
||||
});
|
||||
|
||||
for (const child of children) {
|
||||
@ -182,12 +166,6 @@ export class File {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyUpdateFields(): void {
|
||||
if (this.documentWrapper.View.getTablesOfContents().length) {
|
||||
this.settings.addUpdateFields();
|
||||
}
|
||||
}
|
||||
|
||||
private createHeader(header: Header): HeaderWrapper {
|
||||
const wrapper = new HeaderWrapper(this.media, this.currentRelationshipId++);
|
||||
|
||||
|
Reference in New Issue
Block a user