diff --git a/ts/docx/run/text.ts b/ts/docx/run/text.ts index 68019098d4..745c605094 100644 --- a/ts/docx/run/text.ts +++ b/ts/docx/run/text.ts @@ -1,9 +1,11 @@ -import { XmlUnitComponent } from "../xml-components"; +import { XmlComponent } from "../xml-components"; -export class Text extends XmlUnitComponent { +export class Text extends XmlComponent { constructor(text: string) { super("w:t"); - this.root = text; + if (text) { + this.root.push(text); + } } } diff --git a/ts/docx/xml-components/default-attributes.ts b/ts/docx/xml-components/default-attributes.ts index 02b873f8f1..b95611d4c8 100644 --- a/ts/docx/xml-components/default-attributes.ts +++ b/ts/docx/xml-components/default-attributes.ts @@ -2,10 +2,10 @@ import * as _ from "lodash"; import { BaseXmlComponent } from "./base"; export abstract class XmlAttributeComponent extends BaseXmlComponent { - protected root: Object; - private xmlKeys: Object; + protected root: object; + private xmlKeys: object; - constructor(xmlKeys: Object, properties: Object) { + constructor(xmlKeys: object, properties: object) { super("_attr"); this.xmlKeys = xmlKeys; diff --git a/ts/docx/xml-components/index.ts b/ts/docx/xml-components/index.ts index 626239fb2a..bcbaef4eec 100644 --- a/ts/docx/xml-components/index.ts +++ b/ts/docx/xml-components/index.ts @@ -2,7 +2,7 @@ import * as _ from "lodash"; import { BaseXmlComponent } from "./base"; export abstract class XmlComponent extends BaseXmlComponent { - protected root: BaseXmlComponent[]; + protected root: Array; constructor(rootKey: string) { super(rootKey); @@ -26,4 +26,3 @@ export abstract class XmlComponent extends BaseXmlComponent { export * from "./attributes" export * from "./default-attributes"; -export * from "./unit"; diff --git a/ts/docx/xml-components/unit.ts b/ts/docx/xml-components/unit.ts deleted file mode 100644 index 604655d230..0000000000 --- a/ts/docx/xml-components/unit.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {BaseXmlComponent} from "./base"; - -export abstract class XmlUnitComponent extends BaseXmlComponent { - protected root: string; - - constructor(rootKey: string) { - super(rootKey); - } - - public replaceKey(): void { - if (this.root !== undefined) { - this[this.rootKey] = this.root; - delete this.root; - } - } -} diff --git a/ts/numbering/abstract-numbering.ts b/ts/numbering/abstract-numbering.ts index 1a5b4bfffb..d987702a8a 100644 --- a/ts/numbering/abstract-numbering.ts +++ b/ts/numbering/abstract-numbering.ts @@ -43,7 +43,9 @@ export class AbstractNumbering extends XmlComponent { public clearVariables(): void { _.forEach(this.root, (element) => { - element.clearVariables(); + if (element instanceof XmlComponent) { + element.clearVariables(); + } }); delete this.id; } diff --git a/ts/numbering/index.ts b/ts/numbering/index.ts index 69dc9a3fd9..fd789faf5f 100644 --- a/ts/numbering/index.ts +++ b/ts/numbering/index.ts @@ -90,7 +90,9 @@ export class Numbering extends XmlComponent { public clearVariables(): void { super.clearVariables(); _.forEach(this.root, (element) => { - element.clearVariables(); + if (element instanceof XmlComponent) { + element.clearVariables(); + } }); delete this.nextId; } diff --git a/ts/properties/components.ts b/ts/properties/components.ts index 5f25767a96..d5e1b7fc01 100644 --- a/ts/properties/components.ts +++ b/ts/properties/components.ts @@ -1,66 +1,64 @@ import { DocumentAttributes } from "../docx/document/document-attributes"; -import { XmlUnitComponent } from "../docx/xml-components"; import { XmlComponent } from "../docx/xml-components"; -export class Title extends XmlUnitComponent { +export class Title extends XmlComponent { constructor(value: string) { super("dc:title"); - this.root = value; + this.root.push(value); } } -export class Subject extends XmlUnitComponent { +export class Subject extends XmlComponent { constructor(value: string) { super("dc:subject"); - this.root = value; + this.root.push(value); } } -export class Creator extends XmlUnitComponent { +export class Creator extends XmlComponent { constructor(value: string) { super("dc:creator"); - this.root = value; + this.root.push(value); } } -export class Keywords extends XmlUnitComponent { +export class Keywords extends XmlComponent { constructor(value: string) { super("cp:keywords"); - this.root = value; + this.root.push(value); } } -export class Description extends XmlUnitComponent { +export class Description extends XmlComponent { constructor(value: string) { super("dc:description"); - this.root = value; + this.root.push(value); } } -export class LastModifiedBy extends XmlUnitComponent { +export class LastModifiedBy extends XmlComponent { constructor(value: string) { super("cp:lastModifiedBy"); - this.root = value; + this.root.push(value); } } -export class Revision extends XmlUnitComponent { +export class Revision extends XmlComponent { constructor(value: string) { super("cp:revision"); - const revision = value; - this.root = value; + this.root.push(value); } } abstract class DateComponent extends XmlComponent { - protected getCurrentDate(): any { + protected getCurrentDate(): string { const date = new Date(); const year = date.getFullYear(); const month = ("0" + (date.getMonth() + 1)).slice(-2); diff --git a/ts/properties/index.ts b/ts/properties/index.ts index cbda98a13d..22067d1caa 100644 --- a/ts/properties/index.ts +++ b/ts/properties/index.ts @@ -23,13 +23,27 @@ export class Properties extends XmlComponent { dcmitype: "http://purl.org/dc/dcmitype/", xsi: "http://www.w3.org/2001/XMLSchema-instance", })); - this.root.push(new Title(options.title)); - this.root.push(new Subject(options.subject)); - this.root.push(new Creator(options.creator)); - this.root.push(new Keywords(options.keywords)); - this.root.push(new Description(options.description)); - this.root.push(new LastModifiedBy(options.lastModifiedBy)); - this.root.push(new Revision(options.revision)); + if (options.title) { + this.root.push(new Title(options.title)); + } + if (options.subject) { + this.root.push(new Subject(options.subject)); + } + if (options.creator) { + this.root.push(new Creator(options.creator)); + } + if (options.keywords) { + this.root.push(new Keywords(options.keywords)); + } + if (options.description) { + this.root.push(new Description(options.description)); + } + if (options.lastModifiedBy) { + this.root.push(new LastModifiedBy(options.lastModifiedBy)); + } + if (options.revision) { + this.root.push(new Revision(options.revision)); + } this.root.push(new Created()); this.root.push(new Modified()); } diff --git a/ts/styles/index.ts b/ts/styles/index.ts index 519ad925e2..f69ebdafd8 100644 --- a/ts/styles/index.ts +++ b/ts/styles/index.ts @@ -32,7 +32,9 @@ export class Styles extends XmlComponent { public clearVariables(): void { this.root.forEach((element) => { - element.clearVariables(); + if (element instanceof XmlComponent) { + element.clearVariables(); + } }); } diff --git a/ts/tests/docx/xml-components/xmlUnitTests.ts b/ts/tests/docx/xml-components/xmlUnitTests.ts deleted file mode 100644 index 313d8916d2..0000000000 --- a/ts/tests/docx/xml-components/xmlUnitTests.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { XmlUnitComponent } from "../../../docx/xml-components"; -import { assert } from "chai"; - -function jsonify(obj: Object) { - let stringifiedJson = JSON.stringify(obj); - return JSON.parse(stringifiedJson); -} - -class TestComponent extends XmlUnitComponent { - -} - -describe("XmlUnitComponent", () => { - let xmlComponent: TestComponent; - - beforeEach(() => { - xmlComponent = new TestComponent("w:test"); - }); - - describe("#constructor()", () => { - - it("should create an Xml Component which has the correct rootKey", () => { - let newJson = jsonify(xmlComponent); - assert.equal(newJson.rootKey, "w:test"); - }); - }); - - describe("#replaceKey", () => { - - it("should not replace the key to the specified root key as root is null", () => { - xmlComponent.replaceKey(); - let newJson = jsonify(xmlComponent); - assert.isUndefined(newJson["w:test"]); - }); - }); -}); \ No newline at end of file diff --git a/ts/tests/propertiesTest.ts b/ts/tests/propertiesTest.ts index 0c56ccd13c..c11505381d 100644 --- a/ts/tests/propertiesTest.ts +++ b/ts/tests/propertiesTest.ts @@ -1,25 +1,74 @@ -import { Properties } from "../properties"; -import { assert } from "chai"; +import { expect } from "chai"; -function jsonify(obj: Object) { - let stringifiedJson = JSON.stringify(obj); - return JSON.parse(stringifiedJson); -} +import { Formatter } from "../export/formatter"; +import { Properties } from "../properties"; describe("Properties", () => { - let properties: Properties; - - beforeEach(() => { - - }); describe("#constructor()", () => { - it("should create properties with a title", () => { - properties = new Properties({ - title: "test document" + it("sets the appropriate attributes on the top-level", () => { + const properties = new Properties({}); + const tree = new Formatter().format(properties); + expect(Object.keys(tree)).to.deep.equal(["cp:coreProperties"]); + expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array); + expect(tree["cp:coreProperties"][0]).to.deep.equal({ + _attr: { + "xmlns:cp": "http://schemas.openxmlformats.org/package/2006/metadata/core-properties", + "xmlns:dc": "http://purl.org/dc/elements/1.1/", + "xmlns:dcmitype": "http://purl.org/dc/dcmitype/", + "xmlns:dcterms": "http://purl.org/dc/terms/", + "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", + }, }); - let newJson = jsonify(properties); - assert(newJson.root[1].root === "test document"); + }); + + it("should create properties with a title", () => { + const properties = new Properties({title: "test document"}); + const tree = new Formatter().format(properties); + expect(Object.keys(tree)).to.deep.equal(["cp:coreProperties"]); + expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array); + expect(Object.keys(tree["cp:coreProperties"][0])).to.deep.equal(["_attr"]); + expect(tree["cp:coreProperties"][1]).to.deep.equal( + {"dc:title": ["test document"]}, + ); + }); + + it("should create properties with all the attributes given", () => { + const properties = new Properties({ + title: "test document", + subject: "test subject", + creator: "me", + keywords: "test docx", + description: "testing document", + lastModifiedBy: "the author", + revision: "123", + }); + const tree = new Formatter().format(properties); + expect(Object.keys(tree)).to.deep.equal(["cp:coreProperties"]); + expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array); + const key = (obj) => Object.keys(obj)[0]; + const props = tree["cp:coreProperties"].map(key).sort(); + expect(props).to.deep.equal([ + "_attr", + "cp:keywords", + "cp:lastModifiedBy", + "cp:revision", + "dc:creator", + "dc:description", + "dc:subject", + "dc:title", + "dcterms:created", + "dcterms:modified", + ]); + expect(tree["cp:coreProperties"].slice(1, -2).sort((a, b) => key(a) < key(b) ? -1 : 1)).to.deep.equal([ + {"cp:keywords": ["test docx"]}, + {"cp:lastModifiedBy": ["the author"]}, + {"cp:revision": ["123"]}, + {"dc:creator": ["me"]}, + {"dc:description": ["testing document"]}, + {"dc:subject": ["test subject"]}, + {"dc:title": ["test document"]}, + ]); }); }); -}); \ No newline at end of file +});