Work on moving Document into its own wrapper

This commit is contained in:
Dolan
2021-02-28 16:04:21 +00:00
parent e750735fa4
commit 655b40d418
15 changed files with 157 additions and 65 deletions

View File

@ -1,13 +1,31 @@
// Example on how to add hyperlinks to websites // Example on how to add hyperlinks to websites
// Import from 'docx' rather than '../build' if you install from npm // Import from 'docx' rather than '../build' if you install from npm
import * as fs from "fs"; import * as fs from "fs";
import { ExternalHyperlink, Document, Packer, Paragraph, Media, TextRun } from "../build"; import { ExternalHyperlink, Document, Packer, Paragraph, Media, TextRun, Footer } from "../build";
const doc = new Document({}); const doc = new Document({});
const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg")); const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
doc.addSection({ doc.addSection({
footers: {
default: new Footer({
children: [
new Paragraph({
children: [
new TextRun("Click here for the "),
new ExternalHyperlink({
child: new TextRun({
text: "Footer external hyperlink",
style: "Hyperlink",
}),
link: "http://www.example.com",
}),
],
}),
],
}),
},
children: [ children: [
new Paragraph({ new Paragraph({
children: [ children: [

View File

@ -69,23 +69,23 @@ export class Compiler {
private xmlifyFile(file: File, prettify?: boolean): IXmlifyedFileMapping { private xmlifyFile(file: File, prettify?: boolean): IXmlifyedFileMapping {
file.verifyUpdateFields(); file.verifyUpdateFields();
const documentRelationshipCount = file.DocumentRelationships.RelationshipCount + 1; const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
const documentXmlData = xml(this.formatter.format(file.Document, file), prettify); const documentXmlData = xml(this.formatter.format(file.Document.View, file), prettify);
const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media); const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media);
return { return {
Relationships: { Relationships: {
data: (() => { data: (() => {
documentMediaDatas.forEach((mediaData, i) => { documentMediaDatas.forEach((mediaData, i) => {
file.DocumentRelationships.createRelationship( file.Document.Relationships.createRelationship(
documentRelationshipCount + i, documentRelationshipCount + i,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
`media/${mediaData.fileName}`, `media/${mediaData.fileName}`,
); );
}); });
return xml(this.formatter.format(file.DocumentRelationships, file), prettify); return xml(this.formatter.format(file.Document.Relationships, file), prettify);
})(), })(),
path: "word/_rels/document.xml.rels", path: "word/_rels/document.xml.rels",
}, },
@ -120,7 +120,7 @@ export class Compiler {
path: "_rels/.rels", path: "_rels/.rels",
}, },
HeaderRelationships: file.Headers.map((headerWrapper, index) => { HeaderRelationships: file.Headers.map((headerWrapper, index) => {
const xmlData = xml(this.formatter.format(headerWrapper.Header, file), prettify); const xmlData = xml(this.formatter.format(headerWrapper.View, file), prettify);
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media); const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
mediaDatas.forEach((mediaData, i) => { mediaDatas.forEach((mediaData, i) => {
@ -137,7 +137,7 @@ export class Compiler {
}; };
}), }),
FooterRelationships: file.Footers.map((footerWrapper, index) => { FooterRelationships: file.Footers.map((footerWrapper, index) => {
const xmlData = xml(this.formatter.format(footerWrapper.Footer, file), prettify); const xmlData = xml(this.formatter.format(footerWrapper.View, file), prettify);
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media); const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
mediaDatas.forEach((mediaData, i) => { mediaDatas.forEach((mediaData, i) => {
@ -154,7 +154,7 @@ export class Compiler {
}; };
}), }),
Headers: file.Headers.map((headerWrapper, index) => { Headers: file.Headers.map((headerWrapper, index) => {
const tempXmlData = xml(this.formatter.format(headerWrapper.Header, file), prettify); const tempXmlData = xml(this.formatter.format(headerWrapper.View, file), prettify);
const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media); const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media);
// TODO: 0 needs to be changed when headers get relationships of their own // TODO: 0 needs to be changed when headers get relationships of their own
const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0); const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0);
@ -165,7 +165,7 @@ export class Compiler {
}; };
}), }),
Footers: file.Footers.map((footerWrapper, index) => { Footers: file.Footers.map((footerWrapper, index) => {
const tempXmlData = xml(this.formatter.format(footerWrapper.Footer, file), prettify); const tempXmlData = xml(this.formatter.format(footerWrapper.View, file), prettify);
const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media); const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media);
// TODO: 0 needs to be changed when headers get relationships of their own // TODO: 0 needs to be changed when headers get relationships of their own
const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0); const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0);

View File

@ -0,0 +1,50 @@
import { expect } from "chai";
import * as sinon from "sinon";
import { FooterWrapper } from "./footer-wrapper";
import { Media } from "./media";
import { Paragraph } from "./paragraph";
import { Table, TableCell, TableRow } from "./table";
describe("FooterWrapper", () => {
describe("#add", () => {
it("should call the underlying footer's addParagraph", () => {
const file = new FooterWrapper(new Media(), 1);
const spy = sinon.spy(file.View, "add");
file.add(new Paragraph({}));
expect(spy.called).to.equal(true);
});
it("should call the underlying footer's addParagraph", () => {
const file = new FooterWrapper(new Media(), 1);
const spy = sinon.spy(file.View, "add");
file.add(
new Table({
rows: [
new TableRow({
children: [
new TableCell({
children: [new Paragraph("hello")],
}),
],
}),
],
}),
);
expect(spy.called).to.equal(true);
});
});
describe("#addChildElement", () => {
it("should call the underlying footer's addChildElement", () => {
const file = new FooterWrapper(new Media(), 1);
const spy = sinon.spy(file.View, "addChildElement");
// tslint:disable-next-line:no-any
file.addChildElement({} as any);
expect(spy.called).to.equal(true);
});
});
});

View File

@ -0,0 +1,27 @@
import { Document, IDocumentOptions } from "./document";
import { Footer } from "./footer";
import { Header } from "./header/header";
import { Relationships } from "./relationships";
export interface IViewWrapper {
readonly View: Document | Footer | Header;
readonly Relationships: Relationships;
}
export class DocumentWrapper implements IViewWrapper {
private readonly document: Document;
private readonly relationships: Relationships;
constructor(options: IDocumentOptions) {
this.document = new Document(options);
this.relationships = new Relationships();
}
public get View(): Document {
return this.document;
}
public get Relationships(): Relationships {
return this.relationships;
}
}

View File

@ -145,7 +145,7 @@ export class SectionProperties extends XmlComponent {
this.root.push( this.root.push(
new HeaderReference({ new HeaderReference({
headerType: HeaderReferenceType.DEFAULT, headerType: HeaderReferenceType.DEFAULT,
headerId: headers.default.Header.ReferenceId, headerId: headers.default.View.ReferenceId,
}), }),
); );
} }
@ -154,7 +154,7 @@ export class SectionProperties extends XmlComponent {
this.root.push( this.root.push(
new HeaderReference({ new HeaderReference({
headerType: HeaderReferenceType.FIRST, headerType: HeaderReferenceType.FIRST,
headerId: headers.first.Header.ReferenceId, headerId: headers.first.View.ReferenceId,
}), }),
); );
} }
@ -163,7 +163,7 @@ export class SectionProperties extends XmlComponent {
this.root.push( this.root.push(
new HeaderReference({ new HeaderReference({
headerType: HeaderReferenceType.EVEN, headerType: HeaderReferenceType.EVEN,
headerId: headers.even.Header.ReferenceId, headerId: headers.even.View.ReferenceId,
}), }),
); );
} }
@ -176,7 +176,7 @@ export class SectionProperties extends XmlComponent {
this.root.push( this.root.push(
new FooterReference({ new FooterReference({
footerType: FooterReferenceType.DEFAULT, footerType: FooterReferenceType.DEFAULT,
footerId: footers.default.Footer.ReferenceId, footerId: footers.default.View.ReferenceId,
}), }),
); );
} }
@ -185,7 +185,7 @@ export class SectionProperties extends XmlComponent {
this.root.push( this.root.push(
new FooterReference({ new FooterReference({
footerType: FooterReferenceType.FIRST, footerType: FooterReferenceType.FIRST,
footerId: footers.first.Footer.ReferenceId, footerId: footers.first.View.ReferenceId,
}), }),
); );
} }
@ -194,7 +194,7 @@ export class SectionProperties extends XmlComponent {
this.root.push( this.root.push(
new FooterReference({ new FooterReference({
footerType: FooterReferenceType.EVEN, footerType: FooterReferenceType.EVEN,
footerId: footers.even.Footer.ReferenceId, footerId: footers.even.View.ReferenceId,
}), }),
); );
} }

View File

@ -7,7 +7,7 @@ import { Body } from "./body";
import { DocumentAttributes } from "./document-attributes"; import { DocumentAttributes } from "./document-attributes";
import { DocumentBackground, IDocumentBackgroundOptions } from "./document-background"; import { DocumentBackground, IDocumentBackgroundOptions } from "./document-background";
interface IDocumentOptions { export interface IDocumentOptions {
readonly background: IDocumentBackgroundOptions; readonly background: IDocumentBackgroundOptions;
} }

View File

@ -18,7 +18,7 @@ describe("File", () => {
children: [], children: [],
}); });
const tree = new Formatter().format(doc.Document.Body); 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"][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"); expect(tree["w:body"][0]["w:sectPr"][5]["w:footerReference"]._attr["w:type"]).to.equal("default");
@ -37,7 +37,7 @@ describe("File", () => {
children: [], children: [],
}); });
const tree = new Formatter().format(doc.Document.Body); 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"][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"); expect(tree["w:body"][0]["w:sectPr"][5]["w:footerReference"]._attr["w:type"]).to.equal("default");
@ -56,7 +56,7 @@ describe("File", () => {
children: [], children: [],
}); });
const tree = new Formatter().format(doc.Document.Body); const tree = new Formatter().format(doc.Document.View.Body);
expect(tree["w:body"][0]["w:sectPr"][5]["w:headerReference"]._attr["w:type"]).to.equal("first"); expect(tree["w:body"][0]["w:sectPr"][5]["w:headerReference"]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][0]["w:sectPr"][7]["w:footerReference"]._attr["w:type"]).to.equal("first"); expect(tree["w:body"][0]["w:sectPr"][7]["w:footerReference"]._attr["w:type"]).to.equal("first");
@ -79,7 +79,7 @@ describe("File", () => {
children: [], children: [],
}); });
const tree = new Formatter().format(doc.Document.Body); 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"][4]["w:headerReference"]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][0]["w:sectPr"][5]["w:headerReference"]._attr["w:type"]).to.equal("first"); expect(tree["w:body"][0]["w:sectPr"][5]["w:headerReference"]._attr["w:type"]).to.equal("first");
@ -97,7 +97,7 @@ describe("File", () => {
}, },
]); ]);
const tree = new Formatter().format(doc.Document.Body); const tree = new Formatter().format(doc.Document.View.Body);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:body": [ "w:body": [
@ -169,7 +169,7 @@ describe("File", () => {
describe("#addSection", () => { describe("#addSection", () => {
it("should call the underlying document's add a Paragraph", () => { it("should call the underlying document's add a Paragraph", () => {
const file = new File(); const file = new File();
const spy = sinon.spy(file.Document, "add"); const spy = sinon.spy(file.Document.View, "add");
file.addSection({ file.addSection({
children: [new Paragraph({})], children: [new Paragraph({})],
}); });
@ -179,7 +179,7 @@ describe("File", () => {
it("should call the underlying document's add when adding a Table", () => { it("should call the underlying document's add when adding a Table", () => {
const file = new File(); const file = new File();
const spy = sinon.spy(file.Document, "add"); const spy = sinon.spy(file.Document.View, "add");
file.addSection({ file.addSection({
children: [ children: [
new Table({ new Table({
@ -201,7 +201,7 @@ describe("File", () => {
it("should call the underlying document's add when adding an Image (paragraph)", () => { it("should call the underlying document's add when adding an Image (paragraph)", () => {
const file = new File(); const file = new File();
const spy = sinon.spy(file.Document, "add"); const spy = sinon.spy(file.Document.View, "add");
// tslint:disable-next-line:no-any // tslint:disable-next-line:no-any
file.addSection({ file.addSection({
children: [new Paragraph("")], children: [new Paragraph("")],
@ -214,7 +214,7 @@ describe("File", () => {
describe("#addSection", () => { describe("#addSection", () => {
it("should call the underlying document's add", () => { it("should call the underlying document's add", () => {
const file = new File(); const file = new File();
const spy = sinon.spy(file.Document, "add"); const spy = sinon.spy(file.Document.View, "add");
file.addSection({ file.addSection({
children: [new TableOfContents()], children: [new TableOfContents()],
}); });

View File

@ -1,7 +1,7 @@
import { AppProperties } from "./app-properties/app-properties"; import { AppProperties } from "./app-properties/app-properties";
import { ContentTypes } from "./content-types/content-types"; import { ContentTypes } from "./content-types/content-types";
import { CoreProperties, IPropertiesOptions } from "./core-properties"; import { CoreProperties, IPropertiesOptions } from "./core-properties";
import { Document } from "./document"; import { DocumentWrapper } from "./document-wrapper";
import { import {
FooterReferenceType, FooterReferenceType,
HeaderReferenceType, HeaderReferenceType,
@ -46,10 +46,9 @@ export class File {
// tslint:disable-next-line:readonly-keyword // tslint:disable-next-line:readonly-keyword
private currentRelationshipId: number = 1; private currentRelationshipId: number = 1;
private readonly document: Document; private readonly documentWrapper: DocumentWrapper;
private readonly headers: IDocumentHeader[] = []; private readonly headers: IDocumentHeader[] = [];
private readonly footers: IDocumentFooter[] = []; private readonly footers: IDocumentFooter[] = [];
private readonly docRelationships: Relationships;
private readonly coreProperties: CoreProperties; private readonly coreProperties: CoreProperties;
private readonly numbering: Numbering; private readonly numbering: Numbering;
private readonly media: Media; private readonly media: Media;
@ -77,12 +76,12 @@ export class File {
config: [], config: [],
}, },
); );
this.docRelationships = new Relationships(); // this.documentWrapper.Relationships = new Relationships();
this.fileRelationships = new Relationships(); this.fileRelationships = new Relationships();
this.appProperties = new AppProperties(); this.appProperties = new AppProperties();
this.footNotes = new FootNotes(); this.footNotes = new FootNotes();
this.contentTypes = new ContentTypes(); this.contentTypes = new ContentTypes();
this.document = new Document({ background: options.background || {} }); this.documentWrapper = new DocumentWrapper({ background: options.background || {} });
this.settings = new Settings({ this.settings = new Settings({
compatabilityModeVersion: options.compatabilityModeVersion, compatabilityModeVersion: options.compatabilityModeVersion,
}); });
@ -130,10 +129,10 @@ export class File {
} }
for (const section of sections) { for (const section of sections) {
this.document.Body.addSection(section.properties ? section.properties : {}); this.documentWrapper.View.Body.addSection(section.properties ? section.properties : {});
for (const child of section.children) { for (const child of section.children) {
this.document.add(child); this.documentWrapper.View.add(child);
} }
} }
@ -158,7 +157,7 @@ export class File {
properties, properties,
children, children,
}: ISectionOptions): void { }: ISectionOptions): void {
this.document.Body.addSection({ this.documentWrapper.View.Body.addSection({
...properties, ...properties,
headers: { headers: {
default: headers.default ? this.createHeader(headers.default) : this.createHeader(new Header()), default: headers.default ? this.createHeader(headers.default) : this.createHeader(new Header()),
@ -175,12 +174,12 @@ export class File {
}); });
for (const child of children) { for (const child of children) {
this.document.add(child); this.documentWrapper.View.add(child);
} }
} }
public verifyUpdateFields(): void { public verifyUpdateFields(): void {
if (this.document.getTablesOfContents().length) { if (this.documentWrapper.View.getTablesOfContents().length) {
this.settings.addUpdateFields(); this.settings.addUpdateFields();
} }
} }
@ -209,8 +208,8 @@ export class File {
private addHeaderToDocument(header: HeaderWrapper, type: HeaderReferenceType = HeaderReferenceType.DEFAULT): void { private addHeaderToDocument(header: HeaderWrapper, type: HeaderReferenceType = HeaderReferenceType.DEFAULT): void {
this.headers.push({ header, type }); this.headers.push({ header, type });
this.docRelationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
header.Header.ReferenceId, header.View.ReferenceId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
`header${this.headers.length}.xml`, `header${this.headers.length}.xml`,
); );
@ -219,8 +218,8 @@ export class File {
private addFooterToDocument(footer: FooterWrapper, type: FooterReferenceType = FooterReferenceType.DEFAULT): void { private addFooterToDocument(footer: FooterWrapper, type: FooterReferenceType = FooterReferenceType.DEFAULT): void {
this.footers.push({ footer, type }); this.footers.push({ footer, type });
this.docRelationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
footer.Footer.ReferenceId, footer.View.ReferenceId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
`footer${this.footers.length}.xml`, `footer${this.footers.length}.xml`,
); );
@ -244,30 +243,30 @@ export class File {
"docProps/app.xml", "docProps/app.xml",
); );
this.docRelationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
"styles.xml", "styles.xml",
); );
this.docRelationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
"numbering.xml", "numbering.xml",
); );
this.docRelationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
"footnotes.xml", "footnotes.xml",
); );
this.docRelationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
"settings.xml", "settings.xml",
); );
} }
public get Document(): Document { public get Document(): DocumentWrapper {
return this.document; return this.documentWrapper;
} }
public get Styles(): Styles { public get Styles(): Styles {
@ -286,10 +285,6 @@ export class File {
return this.media; return this.media;
} }
public get DocumentRelationships(): Relationships {
return this.docRelationships;
}
public get FileRelationships(): Relationships { public get FileRelationships(): Relationships {
return this.fileRelationships; return this.fileRelationships;
} }

View File

@ -10,7 +10,7 @@ describe("FooterWrapper", () => {
describe("#add", () => { describe("#add", () => {
it("should call the underlying footer's addParagraph", () => { it("should call the underlying footer's addParagraph", () => {
const file = new FooterWrapper(new Media(), 1); const file = new FooterWrapper(new Media(), 1);
const spy = sinon.spy(file.Footer, "add"); const spy = sinon.spy(file.View, "add");
file.add(new Paragraph({})); file.add(new Paragraph({}));
expect(spy.called).to.equal(true); expect(spy.called).to.equal(true);
@ -18,7 +18,7 @@ describe("FooterWrapper", () => {
it("should call the underlying footer's addParagraph", () => { it("should call the underlying footer's addParagraph", () => {
const file = new FooterWrapper(new Media(), 1); const file = new FooterWrapper(new Media(), 1);
const spy = sinon.spy(file.Footer, "add"); const spy = sinon.spy(file.View, "add");
file.add( file.add(
new Table({ new Table({
rows: [ rows: [
@ -40,7 +40,7 @@ describe("FooterWrapper", () => {
describe("#addChildElement", () => { describe("#addChildElement", () => {
it("should call the underlying footer's addChildElement", () => { it("should call the underlying footer's addChildElement", () => {
const file = new FooterWrapper(new Media(), 1); const file = new FooterWrapper(new Media(), 1);
const spy = sinon.spy(file.Footer, "addChildElement"); const spy = sinon.spy(file.View, "addChildElement");
// tslint:disable-next-line:no-any // tslint:disable-next-line:no-any
file.addChildElement({} as any); file.addChildElement({} as any);

View File

@ -1,6 +1,7 @@
import { XmlComponent } from "file/xml-components"; import { XmlComponent } from "file/xml-components";
import { FooterReferenceType } from "./document"; import { FooterReferenceType } from "./document";
import { IViewWrapper } from "./document-wrapper";
import { Footer } from "./footer/footer"; import { Footer } from "./footer/footer";
import { Media } from "./media"; import { Media } from "./media";
import { Paragraph } from "./paragraph"; import { Paragraph } from "./paragraph";
@ -12,7 +13,7 @@ export interface IDocumentFooter {
readonly type: FooterReferenceType; readonly type: FooterReferenceType;
} }
export class FooterWrapper { export class FooterWrapper implements IViewWrapper {
private readonly footer: Footer; private readonly footer: Footer;
private readonly relationships: Relationships; private readonly relationships: Relationships;
@ -29,7 +30,7 @@ export class FooterWrapper {
this.footer.addChildElement(childElement); this.footer.addChildElement(childElement);
} }
public get Footer(): Footer { public get View(): Footer {
return this.footer; return this.footer;
} }

View File

@ -10,7 +10,7 @@ describe("HeaderWrapper", () => {
describe("#add", () => { describe("#add", () => {
it("should call the underlying header's addChildElement for Paragraph", () => { it("should call the underlying header's addChildElement for Paragraph", () => {
const wrapper = new HeaderWrapper(new Media(), 1); const wrapper = new HeaderWrapper(new Media(), 1);
const spy = sinon.spy(wrapper.Header, "add"); const spy = sinon.spy(wrapper.View, "add");
wrapper.add(new Paragraph({})); wrapper.add(new Paragraph({}));
expect(spy.called).to.equal(true); expect(spy.called).to.equal(true);
@ -18,7 +18,7 @@ describe("HeaderWrapper", () => {
it("should call the underlying header's addChildElement for Table", () => { it("should call the underlying header's addChildElement for Table", () => {
const wrapper = new HeaderWrapper(new Media(), 1); const wrapper = new HeaderWrapper(new Media(), 1);
const spy = sinon.spy(wrapper.Header, "add"); const spy = sinon.spy(wrapper.View, "add");
wrapper.add( wrapper.add(
new Table({ new Table({
rows: [ rows: [
@ -40,7 +40,7 @@ describe("HeaderWrapper", () => {
describe("#addChildElement", () => { describe("#addChildElement", () => {
it("should call the underlying header's addChildElement", () => { it("should call the underlying header's addChildElement", () => {
const file = new HeaderWrapper(new Media(), 1); const file = new HeaderWrapper(new Media(), 1);
const spy = sinon.spy(file.Header, "addChildElement"); const spy = sinon.spy(file.View, "addChildElement");
// tslint:disable-next-line:no-any // tslint:disable-next-line:no-any
file.addChildElement({} as any); file.addChildElement({} as any);

View File

@ -1,6 +1,7 @@
import { XmlComponent } from "file/xml-components"; import { XmlComponent } from "file/xml-components";
import { HeaderReferenceType } from "./document"; import { HeaderReferenceType } from "./document";
import { IViewWrapper } from "./document-wrapper";
import { Header } from "./header/header"; import { Header } from "./header/header";
import { Media } from "./media"; import { Media } from "./media";
import { Paragraph } from "./paragraph"; import { Paragraph } from "./paragraph";
@ -12,7 +13,7 @@ export interface IDocumentHeader {
readonly type: HeaderReferenceType; readonly type: HeaderReferenceType;
} }
export class HeaderWrapper { export class HeaderWrapper implements IViewWrapper {
private readonly header: Header; private readonly header: Header;
private readonly relationships: Relationships; private readonly relationships: Relationships;
@ -31,7 +32,7 @@ export class HeaderWrapper {
this.header.addChildElement(childElement); this.header.addChildElement(childElement);
} }
public get Header(): Header { public get View(): Header {
return this.header; return this.header;
} }

View File

@ -1,14 +1,12 @@
import { IDrawingOptions } from "../drawing"; import { IDrawingOptions } from "../drawing";
import { File } from "../file"; import { File } from "../file";
import { FooterWrapper } from "../footer-wrapper";
import { HeaderWrapper } from "../header-wrapper";
import { PictureRun } from "../paragraph"; import { PictureRun } from "../paragraph";
import { IMediaData } from "./data"; import { IMediaData } from "./data";
// import { Image } from "./image"; // import { Image } from "./image";
export class Media { export class Media {
public static addImage( public static addImage(
file: File | HeaderWrapper | FooterWrapper, file: File,
buffer: Buffer | string | Uint8Array | ArrayBuffer, buffer: Buffer | string | Uint8Array | ArrayBuffer,
width?: number, width?: number,
height?: number, height?: number,

View File

@ -804,8 +804,10 @@ describe("Paragraph", () => {
], ],
}); });
const fileMock = ({ const fileMock = ({
DocumentRelationships: { Document: {
createRelationship: () => ({}), Relationships: {
createRelationship: () => ({}),
},
}, },
} as unknown) as File; } as unknown) as File;
paragraph.prepForXml(fileMock); paragraph.prepForXml(fileMock);

View File

@ -79,7 +79,7 @@ export class Paragraph extends XmlComponent {
if (element instanceof ExternalHyperlink) { if (element instanceof ExternalHyperlink) {
const index = this.root.indexOf(element); const index = this.root.indexOf(element);
const concreteHyperlink = new ConcreteHyperlink(element.options.child, shortid.generate().toLowerCase()); const concreteHyperlink = new ConcreteHyperlink(element.options.child, shortid.generate().toLowerCase());
file.DocumentRelationships.createRelationship( file.Document.Relationships.createRelationship(
concreteHyperlink.linkId, concreteHyperlink.linkId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
element.options.link, element.options.link,