Use context in prep xml

This commit is contained in:
Dolan
2021-03-11 01:06:55 +00:00
parent cf6c4998d0
commit 566ac03f9a
16 changed files with 216 additions and 87 deletions

View File

@ -4,20 +4,24 @@ import * as fs from "fs";
import { Document, ExternalHyperlink, Footer, FootnoteReferenceRun, Media, Packer, Paragraph, TextRun } from "../build"; import { Document, ExternalHyperlink, Footer, FootnoteReferenceRun, Media, Packer, Paragraph, TextRun } from "../build";
const doc = new Document({ const doc = new Document({
footnotes: [ footnotes: {
new Paragraph({ 1: {
children: [ children: [
new TextRun("Click here for the "), new Paragraph({
new ExternalHyperlink({ children: [
child: new TextRun({ new TextRun("Click here for the "),
text: "Footnotes external hyperlink", new ExternalHyperlink({
style: "Hyperlink", child: new TextRun({
}), text: "Footnotes external hyperlink",
link: "http://www.example.com", style: "Hyperlink",
}),
link: "http://www.example.com",
}),
],
}), }),
], ],
}), },
], },
}); });
const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg")); const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
@ -69,7 +73,7 @@ doc.addSection({
}), }),
link: "http://www.example.com", link: "http://www.example.com",
}), }),
new FootnoteReferenceRun(1) new FootnoteReferenceRun(1),
], ],
}), }),
new Paragraph({ new Paragraph({

View File

@ -27,25 +27,29 @@ import {
*/ */
const doc = new Document({ const doc = new Document({
footnotes: [ footnotes: {
new Paragraph({ 1: {
children: [ children: [
new TextRun("This is a footnote"), new Paragraph({
new DeletedTextRun({ children: [
text: " with some extra text which was deleted", new TextRun("This is a footnote"),
id: 0, new DeletedTextRun({
author: "Firstname Lastname", text: " with some extra text which was deleted",
date: "2020-10-06T09:05:00Z", id: 0,
}), author: "Firstname Lastname",
new InsertedTextRun({ date: "2020-10-06T09:05:00Z",
text: " and new content", }),
id: 1, new InsertedTextRun({
author: "Firstname Lastname", text: " and new content",
date: "2020-10-06T09:05:00Z", id: 1,
author: "Firstname Lastname",
date: "2020-10-06T09:05:00Z",
}),
],
}), }),
], ],
}), },
], },
features: { features: {
trackRevisions: true, trackRevisions: true,
}, },

View File

@ -1,9 +1,9 @@
import { IViewWrapper } from "file/document-wrapper"; import { BaseXmlComponent, IContext, IXmlableObject } from "file/xml-components";
import { BaseXmlComponent, IXmlableObject } from "file/xml-components";
export class Formatter { export class Formatter {
public format(input: BaseXmlComponent, file?: IViewWrapper): IXmlableObject { // tslint:disable-next-line: no-object-literal-type-assertion
const output = input.prepForXml(file); public format(input: BaseXmlComponent, context: IContext = {} as IContext): IXmlableObject {
const output = input.prepForXml(context);
if (output) { if (output) {
return output; return output;

View File

@ -73,7 +73,13 @@ export class Compiler {
file.verifyUpdateFields(); file.verifyUpdateFields();
const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1; const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
const documentXmlData = xml(this.formatter.format(file.Document.View, file.Document), prettify); const documentXmlData = xml(
this.formatter.format(file.Document.View, {
viewWrapper: file.Document,
file,
}),
prettify,
);
const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media); const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media);
return { return {
@ -87,7 +93,13 @@ export class Compiler {
); );
}); });
return xml(this.formatter.format(file.Document.Relationships, file.Document), prettify); return xml(
this.formatter.format(file.Document.Relationships, {
viewWrapper: file.Document,
file,
}),
prettify,
);
})(), })(),
path: "word/_rels/document.xml.rels", path: "word/_rels/document.xml.rels",
}, },
@ -101,28 +113,58 @@ export class Compiler {
path: "word/document.xml", path: "word/document.xml",
}, },
Styles: { Styles: {
data: xml(this.formatter.format(file.Styles, file.Document), prettify), data: xml(
this.formatter.format(file.Styles, {
viewWrapper: file.Document,
file,
}),
prettify,
),
path: "word/styles.xml", path: "word/styles.xml",
}, },
Properties: { Properties: {
data: xml(this.formatter.format(file.CoreProperties, file.Document), { data: xml(
declaration: { this.formatter.format(file.CoreProperties, {
standalone: "yes", viewWrapper: file.Document,
encoding: "UTF-8", file,
}),
{
declaration: {
standalone: "yes",
encoding: "UTF-8",
},
}, },
}), ),
path: "docProps/core.xml", path: "docProps/core.xml",
}, },
Numbering: { Numbering: {
data: xml(this.formatter.format(file.Numbering, file.Document), prettify), data: xml(
this.formatter.format(file.Numbering, {
viewWrapper: file.Document,
file,
}),
prettify,
),
path: "word/numbering.xml", path: "word/numbering.xml",
}, },
FileRelationships: { FileRelationships: {
data: xml(this.formatter.format(file.FileRelationships, file.Document), prettify), data: xml(
this.formatter.format(file.FileRelationships, {
viewWrapper: file.Document,
file,
}),
prettify,
),
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.View, headerWrapper), prettify); const xmlData = xml(
this.formatter.format(headerWrapper.View, {
viewWrapper: headerWrapper,
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) => {
@ -134,12 +176,24 @@ export class Compiler {
}); });
return { return {
data: xml(this.formatter.format(headerWrapper.Relationships, headerWrapper), prettify), data: xml(
this.formatter.format(headerWrapper.Relationships, {
viewWrapper: headerWrapper,
file,
}),
prettify,
),
path: `word/_rels/header${index + 1}.xml.rels`, path: `word/_rels/header${index + 1}.xml.rels`,
}; };
}), }),
FooterRelationships: file.Footers.map((footerWrapper, index) => { FooterRelationships: file.Footers.map((footerWrapper, index) => {
const xmlData = xml(this.formatter.format(footerWrapper.View, footerWrapper), prettify); const xmlData = xml(
this.formatter.format(footerWrapper.View, {
viewWrapper: footerWrapper,
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) => {
@ -151,12 +205,24 @@ export class Compiler {
}); });
return { return {
data: xml(this.formatter.format(footerWrapper.Relationships, footerWrapper), prettify), data: xml(
this.formatter.format(footerWrapper.Relationships, {
viewWrapper: footerWrapper,
file,
}),
prettify,
),
path: `word/_rels/footer${index + 1}.xml.rels`, path: `word/_rels/footer${index + 1}.xml.rels`,
}; };
}), }),
Headers: file.Headers.map((headerWrapper, index) => { Headers: file.Headers.map((headerWrapper, index) => {
const tempXmlData = xml(this.formatter.format(headerWrapper.View, headerWrapper), prettify); const tempXmlData = xml(
this.formatter.format(headerWrapper.View, {
viewWrapper: headerWrapper,
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);
@ -167,7 +233,13 @@ export class Compiler {
}; };
}), }),
Footers: file.Footers.map((footerWrapper, index) => { Footers: file.Footers.map((footerWrapper, index) => {
const tempXmlData = xml(this.formatter.format(footerWrapper.View, footerWrapper), prettify); const tempXmlData = xml(
this.formatter.format(footerWrapper.View, {
viewWrapper: footerWrapper,
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);
@ -178,27 +250,63 @@ export class Compiler {
}; };
}), }),
ContentTypes: { ContentTypes: {
data: xml(this.formatter.format(file.ContentTypes, file.Document), prettify), data: xml(
this.formatter.format(file.ContentTypes, {
viewWrapper: file.Document,
file,
}),
prettify,
),
path: "[Content_Types].xml", path: "[Content_Types].xml",
}, },
CustomProperties: { CustomProperties: {
data: xml(this.formatter.format(file.CustomProperties, file.Document), prettify), data: xml(
this.formatter.format(file.CustomProperties, {
viewWrapper: file.Document,
file,
}),
prettify,
),
path: "docProps/custom.xml", path: "docProps/custom.xml",
}, },
AppProperties: { AppProperties: {
data: xml(this.formatter.format(file.AppProperties, file.Document), prettify), data: xml(
this.formatter.format(file.AppProperties, {
viewWrapper: file.Document,
file,
}),
prettify,
),
path: "docProps/app.xml", path: "docProps/app.xml",
}, },
FootNotes: { FootNotes: {
data: xml(this.formatter.format(file.FootNotes.View, file.FootNotes), prettify), data: xml(
this.formatter.format(file.FootNotes.View, {
viewWrapper: file.FootNotes,
file: file,
}),
prettify,
),
path: "word/footnotes.xml", path: "word/footnotes.xml",
}, },
FootNotesRelationships: { FootNotesRelationships: {
data: xml(this.formatter.format(file.FootNotes.Relationships, file.FootNotes), prettify), data: xml(
this.formatter.format(file.FootNotes.Relationships, {
viewWrapper: file.FootNotes,
file: file,
}),
prettify,
),
path: "word/_rels/footnotes.xml.rels", path: "word/_rels/footnotes.xml.rels",
}, },
Settings: { Settings: {
data: xml(this.formatter.format(file.Settings, file.Document), prettify), data: xml(
this.formatter.format(file.Settings, {
viewWrapper: file.Document,
file,
}),
prettify,
),
path: "word/settings.xml", path: "word/settings.xml",
}, },
}; };

View File

@ -1,4 +1,4 @@
import { IXmlableObject, XmlComponent } from "file/xml-components"; import { IContext, IXmlableObject, XmlComponent } from "file/xml-components";
import { CustomPropertiesAttributes } from "./custom-properties-attributes"; import { CustomPropertiesAttributes } from "./custom-properties-attributes";
import { CustomProperty, ICustomPropertyOptions } from "./custom-property"; import { CustomProperty, ICustomPropertyOptions } from "./custom-property";
@ -26,9 +26,9 @@ export class CustomProperties extends XmlComponent {
} }
} }
public prepForXml(): IXmlableObject | undefined { public prepForXml(context: IContext): IXmlableObject | undefined {
this.properties.forEach((x) => this.root.push(x)); this.properties.forEach((x) => this.root.push(x));
return super.prepForXml(); return super.prepForXml(context);
} }
public addCustomProperty(property: ICustomPropertyOptions): void { public addCustomProperty(property: ICustomPropertyOptions): void {

View File

@ -1,5 +1,4 @@
import { IViewWrapper } from "file/document-wrapper"; import { IContext, IXmlableObject, XmlComponent } from "file/xml-components";
import { IXmlableObject, XmlComponent } from "file/xml-components";
import { Paragraph, ParagraphProperties, TableOfContents } from "../.."; import { Paragraph, ParagraphProperties, TableOfContents } from "../..";
import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties"; import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties";
@ -26,13 +25,13 @@ export class Body extends XmlComponent {
this.sections.push(new SectionProperties(options)); this.sections.push(new SectionProperties(options));
} }
public prepForXml(file?: IViewWrapper): IXmlableObject | undefined { public prepForXml(context: IContext): IXmlableObject | undefined {
if (this.sections.length === 1) { if (this.sections.length === 1) {
this.root.splice(0, 1); this.root.splice(0, 1);
this.root.push(this.sections.pop() as SectionProperties); this.root.push(this.sections.pop() as SectionProperties);
} }
return super.prepForXml(file); return super.prepForXml(context);
} }
public push(component: XmlComponent): void { public push(component: XmlComponent): void {

View File

@ -1,7 +1,7 @@
// http://officeopenxml.com/WPnumbering.php // http://officeopenxml.com/WPnumbering.php
import { convertInchesToTwip } from "convenience-functions"; import { convertInchesToTwip } from "convenience-functions";
import { AlignmentType } from "file/paragraph"; import { AlignmentType } from "file/paragraph";
import { IXmlableObject, XmlComponent } from "file/xml-components"; import { IContext, IXmlableObject, XmlComponent } from "file/xml-components";
import { DocumentAttributes } from "../document/document-attributes"; import { DocumentAttributes } from "../document/document-attributes";
import { AbstractNumbering } from "./abstract-numbering"; import { AbstractNumbering } from "./abstract-numbering";
@ -158,10 +158,10 @@ export class Numbering extends XmlComponent {
} }
} }
public prepForXml(): IXmlableObject | undefined { public prepForXml(context: IContext): IXmlableObject | undefined {
this.abstractNumbering.forEach((x) => this.root.push(x)); this.abstractNumbering.forEach((x) => this.root.push(x));
this.concreteNumbering.forEach((x) => this.root.push(x)); this.concreteNumbering.forEach((x) => this.root.push(x));
return super.prepForXml(); return super.prepForXml(context);
} }
private createConcreteNumbering(abstractNumbering: AbstractNumbering, reference?: string): ConcreteNumbering { private createConcreteNumbering(abstractNumbering: AbstractNumbering, reference?: string): ConcreteNumbering {

View File

@ -6,6 +6,7 @@ import { Formatter } from "export/formatter";
import { EMPTY_OBJECT } from "file/xml-components"; import { EMPTY_OBJECT } from "file/xml-components";
import { IViewWrapper } from "../document-wrapper"; import { IViewWrapper } from "../document-wrapper";
import { File } from "../file";
import { ShadingType } from "../table/shading"; import { ShadingType } from "../table/shading";
import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition, TabStopType } from "./formatting"; import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition, TabStopType } from "./formatting";
import { Bookmark, ExternalHyperlink } from "./links"; import { Bookmark, ExternalHyperlink } from "./links";
@ -830,12 +831,17 @@ describe("Paragraph", () => {
}), }),
], ],
}); });
const fileMock = ({ const viewWrapperMock = ({
Relationships: { Relationships: {
createRelationship: () => ({}), createRelationship: () => ({}),
}, },
} as unknown) as IViewWrapper; } as unknown) as IViewWrapper;
paragraph.prepForXml(fileMock);
const file = ({} as unknown) as File;
paragraph.prepForXml({
viewWrapper: viewWrapperMock,
file: file,
});
const tree = new Formatter().format(paragraph); const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [

View File

@ -2,9 +2,8 @@
import * as shortid from "shortid"; import * as shortid from "shortid";
import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"; import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run";
import { IXmlableObject, XmlComponent } from "file/xml-components"; import { IContext, IXmlableObject, XmlComponent } from "file/xml-components";
import { IViewWrapper } from "../document-wrapper";
import { TargetModeType } from "../relationships/relationship/relationship"; import { TargetModeType } from "../relationships/relationship/relationship";
import { DeletedTextRun, InsertedTextRun } from "../track-revision"; import { DeletedTextRun, InsertedTextRun } from "../track-revision";
import { PageBreak } from "./formatting/page-break"; import { PageBreak } from "./formatting/page-break";
@ -76,12 +75,12 @@ export class Paragraph extends XmlComponent {
} }
} }
public prepForXml(file: IViewWrapper): IXmlableObject | undefined { public prepForXml(context: IContext): IXmlableObject | undefined {
for (const element of this.root) { for (const element of this.root) {
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.Relationships.createRelationship( context.viewWrapper.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,
@ -91,7 +90,7 @@ export class Paragraph extends XmlComponent {
} }
} }
return super.prepForXml(); return super.prepForXml(context);
} }
public addRunToFront(run: Run): Paragraph { public addRunToFront(run: Run): Paragraph {

View File

@ -1,8 +1,7 @@
// http://officeopenxml.com/WPtableGrid.php // http://officeopenxml.com/WPtableGrid.php
import { IViewWrapper } from "file/document-wrapper";
import { Paragraph } from "file/paragraph"; import { Paragraph } from "file/paragraph";
import { BorderStyle } from "file/styles"; import { BorderStyle } from "file/styles";
import { IXmlableObject, XmlComponent } from "file/xml-components"; import { IContext, IXmlableObject, XmlComponent } from "file/xml-components";
import { ITableShadingAttributesProperties } from "../shading"; import { ITableShadingAttributesProperties } from "../shading";
import { Table } from "../table"; import { Table } from "../table";
@ -105,11 +104,11 @@ export class TableCell extends XmlComponent {
} }
} }
public prepForXml(file?: IViewWrapper): IXmlableObject | undefined { public prepForXml(context: IContext): IXmlableObject | undefined {
// Cells must end with a paragraph // Cells must end with a paragraph
if (!(this.root[this.root.length - 1] instanceof Paragraph)) { if (!(this.root[this.root.length - 1] instanceof Paragraph)) {
this.root.push(new Paragraph({})); this.root.push(new Paragraph({}));
} }
return super.prepForXml(file); return super.prepForXml(context);
} }
} }

View File

@ -1,6 +1,12 @@
import { IViewWrapper } from "../document-wrapper"; import { IViewWrapper } from "../document-wrapper";
import { File } from "../file";
import { IXmlableObject } from "./xmlable-object"; import { IXmlableObject } from "./xmlable-object";
export interface IContext {
readonly file: File;
readonly viewWrapper: IViewWrapper;
}
export abstract class BaseXmlComponent { export abstract class BaseXmlComponent {
protected readonly rootKey: string; protected readonly rootKey: string;
// tslint:disable-next-line:readonly-keyword // tslint:disable-next-line:readonly-keyword
@ -10,7 +16,7 @@ export abstract class BaseXmlComponent {
this.rootKey = rootKey; this.rootKey = rootKey;
} }
public abstract prepForXml(file?: IViewWrapper): IXmlableObject | undefined; public abstract prepForXml(context: IContext): IXmlableObject | undefined;
public get IsDeleted(): boolean { public get IsDeleted(): boolean {
return this.deleted; return this.deleted;

View File

@ -1,4 +1,4 @@
import { BaseXmlComponent } from "./base"; import { BaseXmlComponent, IContext } from "./base";
import { IXmlableObject } from "./xmlable-object"; import { IXmlableObject } from "./xmlable-object";
export type AttributeMap<T> = { [P in keyof T]: string }; export type AttributeMap<T> = { [P in keyof T]: string };
@ -13,7 +13,7 @@ export abstract class XmlAttributeComponent<T> extends BaseXmlComponent {
this.root = properties; this.root = properties;
} }
public prepForXml(): IXmlableObject { public prepForXml(_: IContext): IXmlableObject {
const attrs = {}; const attrs = {};
Object.keys(this.root).forEach((key) => { Object.keys(this.root).forEach((key) => {
const value = this.root[key]; const value = this.root[key];

View File

@ -2,6 +2,7 @@ import { expect } from "chai";
import { Element, xml2js } from "xml-js"; import { Element, xml2js } from "xml-js";
import { EMPTY_OBJECT, ImportedXmlComponent } from "./"; import { EMPTY_OBJECT, ImportedXmlComponent } from "./";
import { IContext } from "./base";
import { convertToXmlComponent } from "./imported-xml-component"; import { convertToXmlComponent } from "./imported-xml-component";
const xmlString = ` const xmlString = `
@ -63,7 +64,8 @@ describe("ImportedXmlComponent", () => {
describe("#prepForXml()", () => { describe("#prepForXml()", () => {
it("should transform for xml", () => { it("should transform for xml", () => {
const converted = importedXmlComponent.prepForXml(); // tslint:disable-next-line: no-object-literal-type-assertion
const converted = importedXmlComponent.prepForXml({} as IContext);
expect(converted).to.deep.equal({ expect(converted).to.deep.equal({
"w:test": [ "w:test": [
{ {

View File

@ -1,6 +1,7 @@
// tslint:disable:no-any // tslint:disable:no-any
import { Element as XmlElement, xml2js } from "xml-js"; import { Element as XmlElement, xml2js } from "xml-js";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "."; import { IXmlableObject, XmlAttributeComponent, XmlComponent } from ".";
import { IContext } from "./base";
/** /**
* Converts the given xml element (in json format) into XmlComponent. * Converts the given xml element (in json format) into XmlComponent.
@ -72,7 +73,7 @@ export class ImportedRootElementAttributes extends XmlComponent {
super(""); super("");
} }
public prepForXml(): IXmlableObject { public prepForXml(_: IContext): IXmlableObject {
return { return {
_attr: this._attr, _attr: this._attr,
}; };

View File

@ -2,6 +2,7 @@ import { expect } from "chai";
import { Formatter } from "export/formatter"; import { Formatter } from "export/formatter";
import { EMPTY_OBJECT, XmlComponent } from "./"; import { EMPTY_OBJECT, XmlComponent } from "./";
import { IContext } from "./base";
class TestComponent extends XmlComponent {} class TestComponent extends XmlComponent {}
@ -27,7 +28,8 @@ describe("XmlComponent", () => {
child.delete(); child.delete();
xmlComponent.addChildElement(child); xmlComponent.addChildElement(child);
const xml = xmlComponent.prepForXml(); // tslint:disable-next-line: no-object-literal-type-assertion
const xml = xmlComponent.prepForXml({} as IContext);
if (!xml) { if (!xml) {
return; return;

View File

@ -1,5 +1,4 @@
import { IViewWrapper } from "../document-wrapper"; import { BaseXmlComponent, IContext } from "./base";
import { BaseXmlComponent } from "./base";
import { IXmlableObject } from "./xmlable-object"; import { IXmlableObject } from "./xmlable-object";
export const EMPTY_OBJECT = Object.seal({}); export const EMPTY_OBJECT = Object.seal({});
@ -13,7 +12,7 @@ export abstract class XmlComponent extends BaseXmlComponent {
this.root = new Array<BaseXmlComponent | string>(); this.root = new Array<BaseXmlComponent | string>();
} }
public prepForXml(file?: IViewWrapper): IXmlableObject | undefined { public prepForXml(context: IContext): IXmlableObject | undefined {
const children = this.root const children = this.root
.filter((c) => { .filter((c) => {
if (c instanceof BaseXmlComponent) { if (c instanceof BaseXmlComponent) {
@ -23,7 +22,7 @@ export abstract class XmlComponent extends BaseXmlComponent {
}) })
.map((comp) => { .map((comp) => {
if (comp instanceof BaseXmlComponent) { if (comp instanceof BaseXmlComponent) {
return comp.prepForXml(file); return comp.prepForXml(context);
} }
return comp; return comp;
}) })
@ -52,8 +51,8 @@ export abstract class XmlComponent extends BaseXmlComponent {
} }
export abstract class IgnoreIfEmptyXmlComponent extends XmlComponent { export abstract class IgnoreIfEmptyXmlComponent extends XmlComponent {
public prepForXml(): IXmlableObject | undefined { public prepForXml(context: IContext): IXmlableObject | undefined {
const result = super.prepForXml(); const result = super.prepForXml(context);
// Ignore the object if its falsey or is an empty object (would produce // Ignore the object if its falsey or is an empty object (would produce
// an empty XML element if allowed to be included in the output). // an empty XML element if allowed to be included in the output).
if (result && (typeof result[this.rootKey] !== "object" || Object.keys(result[this.rootKey]).length)) { if (result && (typeof result[this.rootKey] !== "object" || Object.keys(result[this.rootKey]).length)) {