Files
docx-js/src/file/xml-components/xml-component.ts

64 lines
2.3 KiB
TypeScript
Raw Normal View History

2019-12-18 21:11:15 +00:00
import { File } from "../file";
2017-09-19 15:46:20 +01:00
import { BaseXmlComponent } from "./base";
import { IXmlableObject } from "./xmlable-object";
export const EMPTY_OBJECT = Object.seal({});
2017-09-19 15:46:20 +01:00
export abstract class XmlComponent extends BaseXmlComponent {
2019-12-18 21:11:15 +00:00
// tslint:disable-next-line:readonly-keyword no-any
2020-08-01 17:58:16 +01:00
protected root: (BaseXmlComponent | string | any)[];
2017-09-19 15:46:20 +01:00
constructor(rootKey: string) {
2017-09-19 15:46:20 +01:00
super(rootKey);
this.root = new Array<BaseXmlComponent | string>();
2017-09-19 15:46:20 +01:00
}
2019-12-18 21:11:15 +00:00
public prepForXml(file?: File): IXmlableObject | undefined {
2018-01-23 01:33:12 +00:00
const children = this.root
2018-05-06 03:19:36 +01:00
.filter((c) => {
if (c instanceof BaseXmlComponent) {
2018-08-07 01:25:28 +01:00
return !c.IsDeleted;
}
return c !== undefined;
})
2018-01-23 01:33:12 +00:00
.map((comp) => {
if (comp instanceof BaseXmlComponent) {
2019-12-18 21:11:15 +00:00
return comp.prepForXml(file);
2018-01-23 01:33:12 +00:00
}
return comp;
})
.filter((comp) => comp !== undefined); // Exclude undefined
// If we only have a single IXmlableObject in our children array and it
// represents our attributes, use the object itself as our children to
// avoid an unneeded XML close element. (Note: We have to use this
// function to get typescript to allow our check.)
// Additionally, if the array is empty, use an empty object as our
// children in order to get an empty XML element generated.
const onlyAttrs = (c) => typeof c === "object" && c._attr;
2017-09-19 15:46:20 +01:00
return {
[this.rootKey]: children.length ? (children.length === 1 && onlyAttrs(children[0]) ? children[0] : children) : EMPTY_OBJECT,
2017-09-19 15:46:20 +01:00
};
}
2018-04-23 11:49:57 +02:00
2018-05-06 03:19:36 +01:00
public addChildElement(child: XmlComponent | string): XmlComponent {
2018-04-23 11:49:57 +02:00
this.root.push(child);
2018-05-06 03:19:36 +01:00
return this;
2018-04-23 11:49:57 +02:00
}
2018-05-06 03:19:36 +01:00
public delete(): void {
this.deleted = true;
}
2017-09-19 15:46:20 +01:00
}
export abstract class IgnoreIfEmptyXmlComponent extends XmlComponent {
public prepForXml(): IXmlableObject | undefined {
const result = super.prepForXml();
// 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).
if (result && (typeof result[this.rootKey] !== "object" || Object.keys(result[this.rootKey]).length)) {
return result;
}
}
}