Merge pull request #307 from brucehappy/features/xml_optimization

Optimize XML output
This commit is contained in:
Dolan
2019-04-11 22:50:10 +01:00
committed by GitHub
62 changed files with 1242 additions and 1608 deletions

View File

@ -31,7 +31,7 @@ describe("Formatter", () => {
const paragraph = new file.Paragraph(); const paragraph = new file.Paragraph();
paragraph.addRun(new file.TextRun("test").bold()); paragraph.addRun(new file.TextRun("test").bold());
const newJson = formatter.format(paragraph); const newJson = formatter.format(paragraph);
assert.isDefined(newJson["w:p"][1]["w:r"][0]["w:rPr"][0]["w:b"][0]._attr["w:val"]); assert.isDefined(newJson["w:p"][0]["w:r"][0]["w:rPr"][0]["w:b"]._attr["w:val"]);
}); });
it("should format attributes (rsidSect)", () => { it("should format attributes (rsidSect)", () => {

View File

@ -191,13 +191,4 @@ export class Compiler {
}, },
}; };
} }
/* By default docx collapse empty tags. <a></a> -> <a/>. this function mimic it
so comparing (diff) original docx file and the library output is easier
Currently not used, so commenting out */
// private collapseEmptyTags(xmlData: string): string {
// const regEx = /<(([^ <>]+)[^<>]*)><\/\2>/g;
// const collapsed = xmlData.replace(regEx, "<$1/>");
// return collapsed;
// }
} }

View File

@ -20,84 +20,70 @@ describe("ContentTypes", () => {
expect(tree["Types"]).to.be.an.instanceof(Array); expect(tree["Types"]).to.be.an.instanceof(Array);
expect(tree["Types"][0]).to.deep.equal({ _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/content-types" } }); expect(tree["Types"][0]).to.deep.equal({ _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/content-types" } });
expect(tree["Types"][1]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/png", Extension: "png" } }] }); expect(tree["Types"][1]).to.deep.equal({ Default: { _attr: { ContentType: "image/png", Extension: "png" } } });
expect(tree["Types"][2]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/jpeg", Extension: "jpeg" } }] }); expect(tree["Types"][2]).to.deep.equal({ Default: { _attr: { ContentType: "image/jpeg", Extension: "jpeg" } } });
expect(tree["Types"][3]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/jpeg", Extension: "jpg" } }] }); expect(tree["Types"][3]).to.deep.equal({ Default: { _attr: { ContentType: "image/jpeg", Extension: "jpg" } } });
expect(tree["Types"][4]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/bmp", Extension: "bmp" } }] }); expect(tree["Types"][4]).to.deep.equal({ Default: { _attr: { ContentType: "image/bmp", Extension: "bmp" } } });
expect(tree["Types"][5]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/gif", Extension: "gif" } }] }); expect(tree["Types"][5]).to.deep.equal({ Default: { _attr: { ContentType: "image/gif", Extension: "gif" } } });
expect(tree["Types"][6]).to.deep.equal({ expect(tree["Types"][6]).to.deep.equal({
Default: [{ _attr: { ContentType: "application/vnd.openxmlformats-package.relationships+xml", Extension: "rels" } }], Default: { _attr: { ContentType: "application/vnd.openxmlformats-package.relationships+xml", Extension: "rels" } },
}); });
expect(tree["Types"][7]).to.deep.equal({ Default: [{ _attr: { ContentType: "application/xml", Extension: "xml" } }] }); expect(tree["Types"][7]).to.deep.equal({ Default: { _attr: { ContentType: "application/xml", Extension: "xml" } } });
expect(tree["Types"][8]).to.deep.equal({ expect(tree["Types"][8]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", PartName: "/word/document.xml",
PartName: "/word/document.xml",
},
}, },
], },
}); });
expect(tree["Types"][9]).to.deep.equal({ expect(tree["Types"][9]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml", PartName: "/word/styles.xml",
PartName: "/word/styles.xml",
},
}, },
], },
}); });
expect(tree["Types"][10]).to.deep.equal({ expect(tree["Types"][10]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-package.core-properties+xml",
ContentType: "application/vnd.openxmlformats-package.core-properties+xml", PartName: "/docProps/core.xml",
PartName: "/docProps/core.xml",
},
}, },
], },
}); });
expect(tree["Types"][11]).to.deep.equal({ expect(tree["Types"][11]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml",
ContentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml", PartName: "/docProps/app.xml",
PartName: "/docProps/app.xml",
},
}, },
], },
}); });
expect(tree["Types"][12]).to.deep.equal({ expect(tree["Types"][12]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml", PartName: "/word/numbering.xml",
PartName: "/word/numbering.xml",
},
}, },
], },
}); });
expect(tree["Types"][13]).to.deep.equal({ expect(tree["Types"][13]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml", PartName: "/word/footnotes.xml",
PartName: "/word/footnotes.xml",
},
}, },
], },
}); });
expect(tree["Types"][14]).to.deep.equal({ expect(tree["Types"][14]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml", PartName: "/word/settings.xml",
PartName: "/word/settings.xml",
},
}, },
], },
}); });
}); });
}); });
@ -109,25 +95,21 @@ describe("ContentTypes", () => {
const tree = new Formatter().format(contentTypes); const tree = new Formatter().format(contentTypes);
expect(tree["Types"][15]).to.deep.equal({ expect(tree["Types"][15]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", PartName: "/word/footer101.xml",
PartName: "/word/footer101.xml",
},
}, },
], },
}); });
expect(tree["Types"][16]).to.deep.equal({ expect(tree["Types"][16]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", PartName: "/word/footer102.xml",
PartName: "/word/footer102.xml",
},
}, },
], },
}); });
}); });
}); });
@ -139,25 +121,21 @@ describe("ContentTypes", () => {
const tree = new Formatter().format(contentTypes); const tree = new Formatter().format(contentTypes);
expect(tree["Types"][15]).to.deep.equal({ expect(tree["Types"][15]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", PartName: "/word/header201.xml",
PartName: "/word/header201.xml",
},
}, },
], },
}); });
expect(tree["Types"][16]).to.deep.equal({ expect(tree["Types"][16]).to.deep.equal({
Override: [ Override: {
{ _attr: {
_attr: { ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", PartName: "/word/header202.xml",
PartName: "/word/header202.xml",
},
}, },
], },
}); });
}); });
}); });

View File

@ -30,14 +30,14 @@ describe("Body", () => {
const formatted = new Formatter().format(body)["w:body"]; const formatted = new Formatter().format(body)["w:body"];
expect(formatted).to.be.an.instanceof(Array); expect(formatted).to.be.an.instanceof(Array);
const defaultSectionPr = formatted[0]["w:p"][1]["w:pPr"][0]["w:sectPr"]; const defaultSectionPr = formatted[0]["w:p"][0]["w:pPr"][0]["w:sectPr"];
// check that this is the default section and added first in paragraph // check that this is the default section and added first in paragraph
expect(defaultSectionPr[0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] }); expect(defaultSectionPr[0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
// check for new section (since it's the last one, it's direct child of body) // check for new section (since it's the last one, it's direct child of body)
const newSection = formatted[1]["w:sectPr"]; const newSection = formatted[1]["w:sectPr"];
expect(newSection[0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 10000, "w:w": 10000, "w:orient": "portrait" } }] }); expect(newSection[0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 10000, "w:w": 10000, "w:orient": "portrait" } } });
}); });
it("should add section with default parameters", () => { it("should add section with default parameters", () => {
@ -52,30 +52,27 @@ describe("Body", () => {
"w:body": [ "w:body": [
{ {
"w:p": [ "w:p": [
{ "w:pPr": [] },
{ {
"w:pPr": [ "w:pPr": [
{ {
"w:sectPr": [ "w:sectPr": [
{ "w:pgSz": [{ _attr: { "w:w": 11906, "w:h": 16838, "w:orient": "portrait" } }] }, { "w:pgSz": { _attr: { "w:w": 11906, "w:h": 16838, "w:orient": "portrait" } } },
{ {
"w:pgMar": [ "w:pgMar": {
{ _attr: {
_attr: { "w:top": 1440,
"w:top": 1440, "w:right": 1440,
"w:right": 1440, "w:bottom": 1440,
"w:bottom": 1440, "w:left": 1440,
"w:left": 1440, "w:header": 708,
"w:header": 708, "w:footer": 708,
"w:footer": 708, "w:gutter": 0,
"w:gutter": 0, "w:mirrorMargins": false,
"w:mirrorMargins": false,
},
}, },
], },
}, },
{ "w:cols": [{ _attr: { "w:space": 708 } }] }, { "w:cols": { _attr: { "w:space": 708 } } },
{ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] }, { "w:docGrid": { _attr: { "w:linePitch": 360 } } },
], ],
}, },
], ],
@ -84,25 +81,23 @@ describe("Body", () => {
}, },
{ {
"w:sectPr": [ "w:sectPr": [
{ "w:pgSz": [{ _attr: { "w:w": 10000, "w:h": 10000, "w:orient": "portrait" } }] }, { "w:pgSz": { _attr: { "w:w": 10000, "w:h": 10000, "w:orient": "portrait" } } },
{ {
"w:pgMar": [ "w:pgMar": {
{ _attr: {
_attr: { "w:top": 1440,
"w:top": 1440, "w:right": 1440,
"w:right": 1440, "w:bottom": 1440,
"w:bottom": 1440, "w:left": 1440,
"w:left": 1440, "w:header": 708,
"w:header": 708, "w:footer": 708,
"w:footer": 708, "w:gutter": 0,
"w:gutter": 0, "w:mirrorMargins": false,
"w:mirrorMargins": false,
},
}, },
], },
}, },
{ "w:cols": [{ _attr: { "w:space": 708 } }] }, { "w:cols": { _attr: { "w:space": 708 } } },
{ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] }, { "w:docGrid": { _attr: { "w:linePitch": 360 } } },
], ],
}, },
], ],

View File

@ -21,8 +21,7 @@ describe("PageBorders", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgBorders"]); expect(Object.keys(tree)).to.deep.equal(["w:pgBorders"]);
expect(tree["w:pgBorders"]).to.be.an.instanceof(Array); expect(tree["w:pgBorders"]).to.deep.equal({ _attr: { "w:display": "firstPage" } });
expect(tree["w:pgBorders"][0]).to.deep.equal({ _attr: { "w:display": "firstPage" } });
}); });
it("should create page borders with full configuration", () => { it("should create page borders with full configuration", () => {
@ -58,32 +57,24 @@ describe("PageBorders", () => {
expect(tree["w:pgBorders"]).to.be.an.instanceof(Array); expect(tree["w:pgBorders"]).to.be.an.instanceof(Array);
expect(tree["w:pgBorders"][0]).to.deep.equal({ _attr: { "w:display": "firstPage", "w:zOrder": "back" } }); expect(tree["w:pgBorders"][0]).to.deep.equal({ _attr: { "w:display": "firstPage", "w:zOrder": "back" } });
expect(tree["w:pgBorders"][1]).to.deep.equal({ expect(tree["w:pgBorders"][1]).to.deep.equal({
"w:top": [ "w:top": {
{ _attr: { "w:color": "001122", "w:size": 10, "w:val": "doubleWave" },
_attr: { "w:color": "001122", "w:size": 10, "w:val": "doubleWave" }, },
},
],
}); });
expect(tree["w:pgBorders"][2]).to.deep.equal({ expect(tree["w:pgBorders"][2]).to.deep.equal({
"w:right": [ "w:right": {
{ _attr: { "w:color": "223344", "w:size": 20, "w:val": "double" },
_attr: { "w:color": "223344", "w:size": 20, "w:val": "double" }, },
},
],
}); });
expect(tree["w:pgBorders"][3]).to.deep.equal({ expect(tree["w:pgBorders"][3]).to.deep.equal({
"w:bottom": [ "w:bottom": {
{ _attr: { "w:color": "556677", "w:size": 30, "w:val": "single" },
_attr: { "w:color": "556677", "w:size": 30, "w:val": "single" }, },
},
],
}); });
expect(tree["w:pgBorders"][4]).to.deep.equal({ expect(tree["w:pgBorders"][4]).to.deep.equal({
"w:left": [ "w:left": {
{ _attr: { "w:color": "889900", "w:size": 40, "w:val": "dotted" },
_attr: { "w:color": "889900", "w:size": 40, "w:val": "dotted" }, },
},
],
}); });
}); });
}); });

View File

@ -1,6 +1,6 @@
// http://officeopenxml.com/WPsectionBorders.php // http://officeopenxml.com/WPsectionBorders.php
import { BorderStyle } from "file/styles"; import { BorderStyle } from "file/styles";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
export enum PageBorderDisplay { export enum PageBorderDisplay {
ALL_PAGES = "allPages", ALL_PAGES = "allPages",
@ -64,7 +64,7 @@ class PageBordersAttributes extends XmlAttributeComponent<IPageBorderAttributes>
}; };
} }
export class PageBorders extends XmlComponent { export class PageBorders extends IgnoreIfEmptyXmlComponent {
constructor(options?: IPageBordersOptions) { constructor(options?: IPageBordersOptions) {
super("w:pgBorders"); super("w:pgBorders");
@ -97,10 +97,4 @@ export class PageBorders extends XmlComponent {
this.root.push(new PageBorder("w:left", options.pageBorderLeft)); this.root.push(new PageBorder("w:left", options.pageBorderLeft));
} }
} }
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
} }

View File

@ -12,8 +12,7 @@ describe("PageSize", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]); expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
expect(tree["w:pgSz"]).to.be.an.instanceof(Array); expect(tree["w:pgSz"]).to.deep.equal({ _attr: { "w:h": 200, "w:w": 100, "w:orient": "portrait" } });
expect(tree["w:pgSz"][0]).to.deep.equal({ _attr: { "w:h": 200, "w:w": 100, "w:orient": "portrait" } });
}); });
it("should create page size with horizontal and invert the lengths", () => { it("should create page size with horizontal and invert the lengths", () => {
@ -21,8 +20,7 @@ describe("PageSize", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]); expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
expect(tree["w:pgSz"]).to.be.an.instanceof(Array); expect(tree["w:pgSz"]).to.deep.equal({ _attr: { "w:h": 100, "w:w": 200, "w:orient": "landscape" } });
expect(tree["w:pgSz"][0]).to.deep.equal({ _attr: { "w:h": 100, "w:w": 200, "w:orient": "landscape" } });
}); });
}); });
}); });

View File

@ -39,29 +39,27 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array); 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" } }] }); expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({ expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [ "w:pgMar": {
{ _attr: {
_attr: { "w:bottom": 1440,
"w:bottom": 1440, "w:footer": 708,
"w:footer": 708, "w:top": 1440,
"w:top": 1440, "w:right": 1440,
"w:right": 1440, "w:left": 1440,
"w:left": 1440, "w:header": 708,
"w:header": 708, "w:gutter": 0,
"w:gutter": 0, "w:mirrorMargins": false,
"w:mirrorMargins": false,
},
}, },
], },
}); });
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": [{ _attr: { "w:space": 708 } }] }); expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": { _attr: { "w:space": 708 } } });
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] }); expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } });
expect(tree["w:sectPr"][4]).to.deep.equal({ "w:headerReference": [{ _attr: { "r:id": "rId100", "w:type": "default" } }] }); expect(tree["w:sectPr"][4]).to.deep.equal({ "w:headerReference": { _attr: { "r:id": "rId100", "w:type": "default" } } });
expect(tree["w:sectPr"][5]).to.deep.equal({ "w:footerReference": [{ _attr: { "r:id": "rId200", "w:type": "even" } }] }); expect(tree["w:sectPr"][5]).to.deep.equal({ "w:footerReference": { _attr: { "r:id": "rId200", "w:type": "even" } } });
expect(tree["w:sectPr"][6]).to.deep.equal({ "w:pgNumType": [{ _attr: { "w:fmt": "cardinalText", "w:start": 10 } }] }); expect(tree["w:sectPr"][6]).to.deep.equal({ "w:pgNumType": { _attr: { "w:fmt": "cardinalText", "w:start": 10 } } });
}); });
it("should create section properties with no options", () => { it("should create section properties with no options", () => {
@ -69,25 +67,23 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array); 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" } }] }); expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({ expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [ "w:pgMar": {
{ _attr: {
_attr: { "w:bottom": 1440,
"w:bottom": 1440, "w:footer": 708,
"w:footer": 708, "w:top": 1440,
"w:top": 1440, "w:right": 1440,
"w:right": 1440, "w:left": 1440,
"w:left": 1440, "w:header": 708,
"w:header": 708, "w:gutter": 0,
"w:gutter": 0, "w:mirrorMargins": false,
"w:mirrorMargins": false,
},
}, },
], },
}); });
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": [{ _attr: { "w:space": 708 } }] }); expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": { _attr: { "w:space": 708 } } });
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] }); expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } });
}); });
it("should create section properties with changed options", () => { it("should create section properties with changed options", () => {
@ -97,22 +93,20 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array); 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" } }] }); expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({ expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [ "w:pgMar": {
{ _attr: {
_attr: { "w:bottom": 1440,
"w:bottom": 1440, "w:footer": 708,
"w:footer": 708, "w:top": 0,
"w:top": 0, "w:right": 1440,
"w:right": 1440, "w:left": 1440,
"w:left": 1440, "w:header": 708,
"w:header": 708, "w:gutter": 0,
"w:gutter": 0, "w:mirrorMargins": false,
"w:mirrorMargins": false,
},
}, },
], },
}); });
}); });
@ -123,22 +117,20 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array); 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" } }] }); expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({ expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [ "w:pgMar": {
{ _attr: {
_attr: { "w:bottom": 0,
"w:bottom": 0, "w:footer": 708,
"w:footer": 708, "w:top": 1440,
"w:top": 1440, "w:right": 1440,
"w:right": 1440, "w:left": 1440,
"w:left": 1440, "w:header": 708,
"w:header": 708, "w:gutter": 0,
"w:gutter": 0, "w:mirrorMargins": false,
"w:mirrorMargins": false,
},
}, },
], },
}); });
}); });
@ -150,22 +142,20 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array); expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 0, "w:w": 0, "w:orient": "portrait" } }] }); expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 0, "w:w": 0, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({ expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [ "w:pgMar": {
{ _attr: {
_attr: { "w:bottom": 1440,
"w:bottom": 1440, "w:footer": 708,
"w:footer": 708, "w:top": 1440,
"w:top": 1440, "w:right": 1440,
"w:right": 1440, "w:left": 1440,
"w:left": 1440, "w:header": 708,
"w:header": 708, "w:gutter": 0,
"w:gutter": 0, "w:mirrorMargins": false,
"w:mirrorMargins": false,
},
}, },
], },
}); });
}); });
@ -179,7 +169,7 @@ describe("SectionProperties", () => {
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
const pgBorders = tree["w:sectPr"].find((item) => item["w:pgBorders"] !== undefined); const pgBorders = tree["w:sectPr"].find((item) => item["w:pgBorders"] !== undefined);
expect(pgBorders).to.deep.equal({ expect(pgBorders).to.deep.equal({
"w:pgBorders": [{ _attr: { "w:offsetFrom": "page" } }], "w:pgBorders": { _attr: { "w:offsetFrom": "page" } },
}); });
}); });
@ -191,7 +181,7 @@ describe("SectionProperties", () => {
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
const pgNumType = tree["w:sectPr"].find((item) => item["w:pgNumType"] !== undefined); const pgNumType = tree["w:sectPr"].find((item) => item["w:pgNumType"] !== undefined);
expect(pgNumType).to.deep.equal({ expect(pgNumType).to.deep.equal({
"w:pgNumType": [{ _attr: { "w:fmt": "upperRoman" } }], "w:pgNumType": { _attr: { "w:fmt": "upperRoman" } },
}); });
}); });

View File

@ -11,8 +11,7 @@ describe("PageSize", () => {
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:titlePg"]); expect(Object.keys(tree)).to.deep.equal(["w:titlePg"]);
expect(tree["w:titlePg"]).to.be.an.instanceof(Array); expect(tree["w:titlePg"]).to.deep.equal({ _attr: { "w:val": "1" } });
expect(tree["w:titlePg"][0]).to.deep.equal({ _attr: { "w:val": "1" } });
}); });
}); });
}); });

View File

@ -52,7 +52,7 @@ describe("Document", () => {
expect(body[0]) expect(body[0])
.to.have.property("w:p") .to.have.property("w:p")
.which.includes({ .which.includes({
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "sample paragraph text"] }], "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "sample paragraph text"] }],
}); });
}); });
}); });
@ -84,9 +84,9 @@ describe("Document", () => {
.to.have.property("w:tbl") .to.have.property("w:tbl")
.which.includes({ .which.includes({
"w:tblGrid": [ "w:tblGrid": [
{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": { _attr: { "w:w": 100 } } },
{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": { _attr: { "w:w": 100 } } },
{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": { _attr: { "w:w": 100 } } },
], ],
}); });
expect(body[0]["w:tbl"].filter((x) => x["w:tr"])).to.have.length(2); expect(body[0]["w:tbl"].filter((x) => x["w:tr"])).to.have.length(2);

View File

@ -25,8 +25,8 @@ describe("File", () => {
const tree = new Formatter().format(doc.Document.Body); const tree = new Formatter().format(doc.Document.Body);
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("default"); expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"][0]._attr["w:type"]).to.equal("default"); expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"]._attr["w:type"]).to.equal("default");
}); });
it("should create with first headers and footers", () => { it("should create with first headers and footers", () => {
@ -45,8 +45,8 @@ describe("File", () => {
const tree = new Formatter().format(doc.Document.Body); const tree = new Formatter().format(doc.Document.Body);
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("first"); expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"][0]._attr["w:type"]).to.equal("first"); expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"]._attr["w:type"]).to.equal("first");
}); });
it("should create with correct headers", () => { it("should create with correct headers", () => {
@ -69,13 +69,13 @@ describe("File", () => {
const tree = new Formatter().format(doc.Document.Body); const tree = new Formatter().format(doc.Document.Body);
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("default"); expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][5]["w:headerReference"][0]._attr["w:type"]).to.equal("first"); expect(tree["w:body"][1]["w:sectPr"][5]["w:headerReference"]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][6]["w:headerReference"][0]._attr["w:type"]).to.equal("even"); expect(tree["w:body"][1]["w:sectPr"][6]["w:headerReference"]._attr["w:type"]).to.equal("even");
expect(tree["w:body"][1]["w:sectPr"][7]["w:footerReference"][0]._attr["w:type"]).to.equal("default"); expect(tree["w:body"][1]["w:sectPr"][7]["w:footerReference"]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][8]["w:footerReference"][0]._attr["w:type"]).to.equal("first"); expect(tree["w:body"][1]["w:sectPr"][8]["w:footerReference"]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][9]["w:footerReference"][0]._attr["w:type"]).to.equal("even"); expect(tree["w:body"][1]["w:sectPr"][9]["w:footerReference"]._attr["w:type"]).to.equal("even");
}); });
}); });

View File

@ -11,8 +11,7 @@ describe("Footnote", () => {
const tree = new Formatter().format(footnote); const tree = new Formatter().format(footnote);
expect(Object.keys(tree)).to.deep.equal(["w:footnote"]); expect(Object.keys(tree)).to.deep.equal(["w:footnote"]);
expect(tree["w:footnote"]).to.be.an.instanceof(Array); expect(tree["w:footnote"]).to.deep.equal({ _attr: { "w:type": "separator", "w:id": 1 } });
expect(tree["w:footnote"][0]).to.deep.equal({ _attr: { "w:type": "separator", "w:id": 1 } });
}); });
it("should create a footnote without a footnote type", () => { it("should create a footnote without a footnote type", () => {
@ -20,8 +19,7 @@ describe("Footnote", () => {
const tree = new Formatter().format(footnote); const tree = new Formatter().format(footnote);
expect(Object.keys(tree)).to.deep.equal(["w:footnote"]); expect(Object.keys(tree)).to.deep.equal(["w:footnote"]);
expect(tree["w:footnote"]).to.be.an.instanceof(Array); expect(tree["w:footnote"]).to.deep.equal({ _attr: { "w:id": 1 } });
expect(tree["w:footnote"][0]).to.deep.equal({ _attr: { "w:id": 1 } });
}); });
}); });
}); });

View File

@ -27,10 +27,10 @@ describe("Media", () => {
const file = new File(); const file = new File();
const image1 = Media.addImage(file, "test"); const image1 = Media.addImage(file, "test");
const tree = new Formatter().format(image1.Paragraph); const tree = new Formatter().format(image1.Paragraph);
const inlineElements = tree["w:p"][1]["w:r"][1]["w:drawing"][0]["wp:inline"]; const inlineElements = tree["w:p"][0]["w:r"][0]["w:drawing"][0]["wp:inline"];
const graphicData = inlineElements.find((x) => x["a:graphic"]); const graphicData = inlineElements.find((x) => x["a:graphic"]);
expect(graphicData["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"][0]).to.deep.equal({ expect(graphicData["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"]).to.deep.equal({
_attr: { _attr: {
"r:embed": `rId{testId.png}`, "r:embed": `rId{testId.png}`,
cstate: "none", cstate: "none",
@ -39,10 +39,10 @@ describe("Media", () => {
const image2 = Media.addImage(file, "test"); const image2 = Media.addImage(file, "test");
const tree2 = new Formatter().format(image2.Paragraph); const tree2 = new Formatter().format(image2.Paragraph);
const inlineElements2 = tree2["w:p"][1]["w:r"][1]["w:drawing"][0]["wp:inline"]; const inlineElements2 = tree2["w:p"][0]["w:r"][0]["w:drawing"][0]["wp:inline"];
const graphicData2 = inlineElements2.find((x) => x["a:graphic"]); const graphicData2 = inlineElements2.find((x) => x["a:graphic"]);
expect(graphicData2["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"][0]).to.deep.equal({ expect(graphicData2["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"]).to.deep.equal({
_attr: { _attr: {
"r:embed": `rId{testId.png}`, "r:embed": `rId{testId.png}`,
cstate: "none", cstate: "none",

View File

@ -7,6 +7,8 @@ import { LevelForOverride } from "./level";
import { Num } from "./num"; import { Num } from "./num";
import { Numbering } from "./numbering"; import { Numbering } from "./numbering";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Numbering", () => { describe("Numbering", () => {
let numbering: Numbering; let numbering: Numbering;
@ -22,7 +24,7 @@ describe("Numbering", () => {
expect(abstractNums).to.have.lengthOf(1); expect(abstractNums).to.have.lengthOf(1);
expect(abstractNums[0]["w:abstractNum"]).to.deep.include.members([ expect(abstractNums[0]["w:abstractNum"]).to.deep.include.members([
{ _attr: { "w:abstractNumId": 0, "w15:restartNumberingAfterBreak": 0 } }, { _attr: { "w:abstractNumId": 0, "w15:restartNumberingAfterBreak": 0 } },
{ "w:multiLevelType": [{ _attr: { "w:val": "hybridMultilevel" } }] }, { "w:multiLevelType": { _attr: { "w:val": "hybridMultilevel" } } },
]); ]);
abstractNums abstractNums
@ -37,9 +39,9 @@ describe("Numbering", () => {
{ "w:numFmt": [{ _attr: { "w:val": "bullet" } }] }, { "w:numFmt": [{ _attr: { "w:val": "bullet" } }] },
]); ]);
// Once chai 4.0.0 lands and #644 is resolved, we can add the following to the test: // Once chai 4.0.0 lands and #644 is resolved, we can add the following to the test:
// {"w:lvlText": [{"_attr": {"w:val": "•"}}]}, // {"w:lvlText": {"_attr": {"w:val": "•"}}},
// {"w:rPr": [{"w:rFonts": [{"_attr": {"w:ascii": "Symbol", "w:cs": "Symbol", "w:eastAsia": "Symbol", "w:hAnsi": "Symbol", "w:hint": "default"}}]}]}, // {"w:rPr": [{"w:rFonts": {"_attr": {"w:ascii": "Symbol", "w:cs": "Symbol", "w:eastAsia": "Symbol", "w:hAnsi": "Symbol", "w:hint": "default"}}}]},
// {"w:pPr": [{"_attr": {}}, // {"w:pPr": [
// {"w:ind": [{"_attr": {"w:left": 720, "w:hanging": 360}}]}]}, // {"w:ind": [{"_attr": {"w:left": 720, "w:hanging": 360}}]}]},
}); });
}); });
@ -65,7 +67,7 @@ describe("Numbering", () => {
expect(n).to.be.instanceof(Num); expect(n).to.be.instanceof(Num);
const tree = new Formatter().format(numbering); const tree = new Formatter().format(numbering);
const serializedN = tree["w:numbering"].find((obj) => obj["w:num"] && obj["w:num"][0]._attr["w:numId"] === n.id); const serializedN = tree["w:numbering"].find((obj) => obj["w:num"] && obj["w:num"][0]._attr["w:numId"] === n.id);
expect(serializedN["w:num"][1]["w:abstractNumId"][0]._attr["w:val"]).to.equal(a2.id); expect(serializedN["w:num"][1]["w:abstractNumId"]._attr["w:val"]).to.equal(a2.id);
}); });
it("assigns a unique ID to each concrete numbering it creates", () => { it("assigns a unique ID to each concrete numbering it creates", () => {
@ -89,10 +91,10 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)", "end"); const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)", "end");
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } }); expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } });
expect(tree["w:lvl"]).to.include({ "w:start": [{ _attr: { "w:val": 1 } }] }); expect(tree["w:lvl"]).to.include({ "w:start": { _attr: { "w:val": 1 } } });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": [{ _attr: { "w:val": "end" } }] }); expect(tree["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "end" } } });
expect(tree["w:lvl"]).to.include({ "w:numFmt": [{ _attr: { "w:val": "lowerLetter" } }] }); expect(tree["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } });
expect(tree["w:lvl"]).to.include({ "w:lvlText": [{ _attr: { "w:val": "%1)" } }] }); expect(tree["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } });
}); });
it("uses 'start' as the default alignment", () => { it("uses 'start' as the default alignment", () => {
@ -100,10 +102,10 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)"); const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)");
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } }); expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } });
expect(tree["w:lvl"]).to.include({ "w:start": [{ _attr: { "w:val": 1 } }] }); expect(tree["w:lvl"]).to.include({ "w:start": { _attr: { "w:val": 1 } } });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": [{ _attr: { "w:val": "start" } }] }); expect(tree["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "start" } } });
expect(tree["w:lvl"]).to.include({ "w:numFmt": [{ _attr: { "w:val": "lowerLetter" } }] }); expect(tree["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } });
expect(tree["w:lvl"]).to.include({ "w:lvlText": [{ _attr: { "w:val": "%1)" } }] }); expect(tree["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } });
}); });
describe("formatting methods: paragraph properties", () => { describe("formatting methods: paragraph properties", () => {
@ -112,7 +114,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").indent({ left: 720 }); const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").indent({ left: 720 });
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:ind": [{ _attr: { "w:left": 720 } }] }], "w:pPr": [{ "w:ind": { _attr: { "w:left": 720 } } }],
}); });
}); });
@ -121,7 +123,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").spacing({ before: 50, after: 150 }); const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").spacing({ before: 50, after: 150 });
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:spacing": [{ _attr: { "w:before": 50, "w:after": 150 } }] }], "w:pPr": [{ "w:spacing": { _attr: { "w:before": 50, "w:after": 150 } } }],
}); });
}); });
@ -130,7 +132,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").center(); const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").center();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "center" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "center" } } }],
}); });
}); });
@ -139,7 +141,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.", "left").left(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.", "left").left();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "left" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "left" } } }],
}); });
}); });
@ -148,7 +150,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").right(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").right();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "right" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "right" } } }],
}); });
}); });
@ -157,7 +159,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").justified(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").justified();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "both" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "both" } } }],
}); });
}); });
@ -170,16 +172,14 @@ describe("AbstractNumbering", () => {
{ {
"w:pBdr": [ "w:pBdr": [
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:color": "auto",
"w:color": "auto", "w:space": "1",
"w:space": "1", "w:val": "single",
"w:val": "single", "w:sz": "6",
"w:sz": "6",
},
}, },
], },
}, },
], ],
}, },
@ -194,7 +194,7 @@ describe("AbstractNumbering", () => {
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [ "w:pPr": [
{ {
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "left", "w:pos": 1200 } }] }], "w:tabs": [{ "w:tab": { _attr: { "w:val": "left", "w:pos": 1200 } } }],
}, },
], ],
}); });
@ -207,7 +207,7 @@ describe("AbstractNumbering", () => {
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [ "w:pPr": [
{ {
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "right", "w:pos": 9026 } }] }], "w:tabs": [{ "w:tab": { _attr: { "w:val": "right", "w:pos": 9026 } } }],
}, },
], ],
}); });
@ -218,7 +218,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepLines(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepLines();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:keepLines": [] }], "w:pPr": [{ "w:keepLines": EMPTY_OBJECT }],
}); });
}); });
@ -227,7 +227,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepNext(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepNext();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:keepNext": [] }], "w:pPr": [{ "w:keepNext": EMPTY_OBJECT }],
}); });
}); });
}); });
@ -238,7 +238,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").size(24); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").size(24);
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }], "w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }],
}); });
}); });
@ -247,7 +247,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").smallCaps(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").smallCaps();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:smallCaps": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:smallCaps": { _attr: { "w:val": true } } }],
}); });
}); });
@ -256,7 +256,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").allCaps(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").allCaps();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:caps": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:caps": { _attr: { "w:val": true } } }],
}); });
}); });
@ -265,7 +265,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").strike(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").strike();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:strike": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:strike": { _attr: { "w:val": true } } }],
}); });
}); });
@ -274,7 +274,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").doubleStrike(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").doubleStrike();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:dstrike": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:dstrike": { _attr: { "w:val": true } } }],
}); });
}); });
@ -283,7 +283,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").subScript(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").subScript();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "subscript" } }] }], "w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "subscript" } } }],
}); });
}); });
@ -292,7 +292,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").superScript(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").superScript();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "superscript" } }] }], "w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "superscript" } } }],
}); });
}); });
@ -302,7 +302,7 @@ describe("AbstractNumbering", () => {
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [ "w:rPr": [
{ "w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }] }, { "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } } },
], ],
}); });
}); });
@ -312,7 +312,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").bold(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").bold();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:b": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:b": { _attr: { "w:val": true } } }],
}); });
}); });
@ -321,7 +321,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").italics(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").italics();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:i": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:i": { _attr: { "w:val": true } } }],
}); });
}); });
@ -331,7 +331,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline(); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline();
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }],
}); });
}); });
@ -340,7 +340,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline("double"); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline("double");
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "double" } } }],
}); });
}); });
@ -349,7 +349,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline("double", "005599"); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").underline("double", "005599");
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "005599" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "005599" } } }],
}); });
}); });
}); });
@ -359,7 +359,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").color("123456"); const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").color("123456");
const tree = new Formatter().format(level); const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ expect(tree["w:lvl"]).to.include({
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "123456" } }] }], "w:rPr": [{ "w:color": { _attr: { "w:val": "123456" } } }],
}); });
}); });
}); });
@ -388,20 +388,12 @@ describe("concrete numbering", () => {
}, },
}, },
{ {
"w:lvl": [ "w:lvl": {
{ _attr: {
_attr: { "w:ilvl": 3,
"w:ilvl": 3, "w15:tentative": 1,
"w15:tentative": 1,
},
}, },
{ },
"w:pPr": [],
},
{
"w:rPr": [],
},
],
}, },
], ],
}); });
@ -418,29 +410,19 @@ describe("concrete numbering", () => {
}, },
}, },
{ {
"w:startOverride": [ "w:startOverride": {
{ _attr: {
_attr: { "w:val": 9,
"w:val": 9,
},
}, },
], },
}, },
{ {
"w:lvl": [ "w:lvl": {
{ _attr: {
_attr: { "w:ilvl": 1,
"w:ilvl": 1, "w15:tentative": 1,
"w15:tentative": 1,
},
}, },
{ },
"w:pPr": [],
},
{
"w:rPr": [],
},
],
}, },
], ],
}); });
@ -454,7 +436,7 @@ describe("concrete numbering", () => {
"w:lvlOverride": [ "w:lvlOverride": [
{ _attr: { "w:ilvl": 1 } }, { _attr: { "w:ilvl": 1 } },
{ {
"w:lvl": [{ _attr: { "w15:tentative": 1, "w:ilvl": 1 } }, { "w:pPr": [] }, { "w:rPr": [] }], "w:lvl": { _attr: { "w15:tentative": 1, "w:ilvl": 1 } },
}, },
], ],
}); });

View File

@ -10,7 +10,7 @@ describe("Spacing", () => {
const spacing = new Spacing({ before: 100, after: 120, line: 150 }); const spacing = new Spacing({ before: 100, after: 120, line: 150 });
const tree = new Formatter().format(spacing); const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:spacing": [{ _attr: { "w:after": 120, "w:before": 100, "w:line": 150 } }], "w:spacing": { _attr: { "w:after": 120, "w:before": 100, "w:line": 150 } },
}); });
}); });
@ -18,7 +18,7 @@ describe("Spacing", () => {
const spacing = new Spacing({ before: 100 }); const spacing = new Spacing({ before: 100 });
const tree = new Formatter().format(spacing); const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:spacing": [{ _attr: { "w:before": 100 } }], "w:spacing": { _attr: { "w:before": 100 } },
}); });
}); });
}); });
@ -30,7 +30,7 @@ describe("ContextualSpacing", () => {
const spacing = new ContextualSpacing(true); const spacing = new ContextualSpacing(true);
const tree = new Formatter().format(spacing); const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:contextualSpacing": [{ _attr: { "w:val": 1 } }], "w:contextualSpacing": { _attr: { "w:val": 1 } },
}); });
}); });
@ -38,7 +38,7 @@ describe("ContextualSpacing", () => {
const spacing = new ContextualSpacing(false); const spacing = new ContextualSpacing(false);
const tree = new Formatter().format(spacing); const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:contextualSpacing": [{ _attr: { "w:val": 0 } }], "w:contextualSpacing": { _attr: { "w:val": 0 } },
}); });
}); });
}); });

View File

@ -5,6 +5,8 @@ import { Formatter } from "export/formatter";
import { ImageParagraph } from "./image"; import { ImageParagraph } from "./image";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Image", () => { describe("Image", () => {
let image: ImageParagraph; let image: ImageParagraph;
@ -45,14 +47,8 @@ describe("Image", () => {
const tree = new Formatter().format(image); const tree = new Formatter().format(image);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{
"w:pPr": [],
},
{ {
"w:r": [ "w:r": [
{
"w:rPr": [],
},
{ {
"w:drawing": [ "w:drawing": [
{ {
@ -66,49 +62,41 @@ describe("Image", () => {
}, },
}, },
{ {
"wp:extent": [ "wp:extent": {
{ _attr: {
_attr: { cx: 20,
cx: 20, cy: 20,
cy: 20,
},
}, },
], },
}, },
{ {
"wp:effectExtent": [ "wp:effectExtent": {
{ _attr: {
_attr: { b: 0,
b: 0, l: 0,
l: 0, r: 0,
r: 0, t: 0,
t: 0,
},
}, },
], },
}, },
{ {
"wp:docPr": [ "wp:docPr": {
{ _attr: {
_attr: { descr: "",
descr: "", id: 0,
id: 0, name: "",
name: "",
},
}, },
], },
}, },
{ {
"wp:cNvGraphicFramePr": [ "wp:cNvGraphicFramePr": [
{ {
"a:graphicFrameLocks": [ "a:graphicFrameLocks": {
{ _attr: {
_attr: { noChangeAspect: 1,
noChangeAspect: 1, "xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
},
}, },
], },
}, },
], ],
}, },
@ -137,27 +125,23 @@ describe("Image", () => {
{ {
"pic:nvPicPr": [ "pic:nvPicPr": [
{ {
"pic:cNvPr": [ "pic:cNvPr": {
{ _attr: {
_attr: { desc: "",
desc: "", id: 0,
id: 0, name: "",
name: "",
},
}, },
], },
}, },
{ {
"pic:cNvPicPr": [ "pic:cNvPicPr": [
{ {
"a:picLocks": [ "a:picLocks": {
{ _attr: {
_attr: { noChangeArrowheads: 1,
noChangeArrowheads: 1, noChangeAspect: 1,
noChangeAspect: 1,
},
}, },
], },
}, },
], ],
}, },
@ -166,22 +150,20 @@ describe("Image", () => {
{ {
"pic:blipFill": [ "pic:blipFill": [
{ {
"a:blip": [ "a:blip": {
{ _attr: {
_attr: { cstate: "none",
cstate: "none", "r:embed": "rId{test.png}",
"r:embed": "rId{test.png}",
},
}, },
], },
}, },
{ {
"a:srcRect": [], "a:srcRect": EMPTY_OBJECT,
}, },
{ {
"a:stretch": [ "a:stretch": [
{ {
"a:fillRect": [], "a:fillRect": EMPTY_OBJECT,
}, },
], ],
}, },
@ -197,24 +179,20 @@ describe("Image", () => {
{ {
"a:xfrm": [ "a:xfrm": [
{ {
"a:ext": [ "a:ext": {
{ _attr: {
_attr: { cx: 10,
cx: 10, cy: 10,
cy: 10,
},
}, },
], },
}, },
{ {
"a:off": [ "a:off": {
{ _attr: {
_attr: { x: 0,
x: 0, y: 0,
y: 0,
},
}, },
], },
}, },
], ],
}, },
@ -226,7 +204,7 @@ describe("Image", () => {
}, },
}, },
{ {
"a:avLst": [], "a:avLst": EMPTY_OBJECT,
}, },
], ],
}, },

View File

@ -31,7 +31,7 @@ describe("Hyperlink", () => {
const tree = new Formatter().format(hyperlink); const tree = new Formatter().format(hyperlink);
const runJson = { const runJson = {
"w:r": [ "w:r": [
{ "w:rPr": [{ "w:rStyle": [{ _attr: { "w:val": "Hyperlink" } }] }] }, { "w:rPr": [{ "w:rStyle": { _attr: { "w:val": "Hyperlink" } } }] },
{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "https://example.com"] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "https://example.com"] },
], ],
}; };

View File

@ -6,6 +6,8 @@ import * as file from "file";
import { Numbering } from "../numbering"; import { Numbering } from "../numbering";
import { LeaderType } from "./formatting"; import { LeaderType } from "./formatting";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Paragraph", () => { describe("Paragraph", () => {
let paragraph: file.Paragraph; let paragraph: file.Paragraph;
@ -40,7 +42,7 @@ describe("Paragraph", () => {
expect(tree) expect(tree)
.to.be.an("array") .to.be.an("array")
.which.includes({ .which.includes({
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "this is a test run"] }], "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "this is a test run"] }],
}); });
}); });
}); });
@ -52,7 +54,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading1" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading1" } } }],
}, },
], ],
}); });
@ -66,7 +68,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading2" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading2" } } }],
}, },
], ],
}); });
@ -80,7 +82,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading3" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading3" } } }],
}, },
], ],
}); });
@ -94,7 +96,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading4" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading4" } } }],
}, },
], ],
}); });
@ -108,7 +110,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading5" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading5" } } }],
}, },
], ],
}); });
@ -122,7 +124,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading6" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading6" } } }],
}, },
], ],
}); });
@ -136,7 +138,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Title" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Title" } } }],
}, },
], ],
}); });
@ -150,7 +152,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "center" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "center" } } }],
}, },
], ],
}); });
@ -164,7 +166,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "left" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "left" } } }],
}, },
], ],
}); });
@ -178,7 +180,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "right" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "right" } } }],
}, },
], ],
}); });
@ -192,7 +194,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "start" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "start" } } }],
}, },
], ],
}); });
@ -206,7 +208,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "end" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "end" } } }],
}, },
], ],
}); });
@ -220,7 +222,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "distribute" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "distribute" } } }],
}, },
], ],
}); });
@ -234,7 +236,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "both" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "both" } } }],
}, },
], ],
}); });
@ -252,14 +254,12 @@ describe("Paragraph", () => {
{ {
"w:tabs": [ "w:tabs": [
{ {
"w:tab": [ "w:tab": {
{ _attr: {
_attr: { "w:pos": 9026,
"w:pos": 9026, "w:val": "right",
"w:val": "right",
},
}, },
], },
}, },
], ],
}, },
@ -281,15 +281,13 @@ describe("Paragraph", () => {
{ {
"w:tabs": [ "w:tabs": [
{ {
"w:tab": [ "w:tab": {
{ _attr: {
_attr: { "w:pos": 100,
"w:pos": 100, "w:val": "left",
"w:val": "left", "w:leader": "hyphen",
"w:leader": "hyphen",
},
}, },
], },
}, },
], ],
}, },
@ -311,15 +309,13 @@ describe("Paragraph", () => {
{ {
"w:tabs": [ "w:tabs": [
{ {
"w:tab": [ "w:tab": {
{ _attr: {
_attr: { "w:pos": 100,
"w:pos": 100, "w:val": "right",
"w:val": "right", "w:leader": "dot",
"w:leader": "dot",
},
}, },
], },
}, },
], ],
}, },
@ -341,15 +337,13 @@ describe("Paragraph", () => {
{ {
"w:tabs": [ "w:tabs": [
{ {
"w:tab": [ "w:tab": {
{ _attr: {
_attr: { "w:pos": 100,
"w:pos": 100, "w:val": "center",
"w:val": "center", "w:leader": "middleDot",
"w:leader": "middleDot",
},
}, },
], },
}, },
], ],
}, },
@ -367,7 +361,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:contextualSpacing": [{ _attr: { "w:val": 1 } }] }], "w:pPr": [{ "w:contextualSpacing": { _attr: { "w:val": 1 } } }],
}, },
], ],
}); });
@ -379,7 +373,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:contextualSpacing": [{ _attr: { "w:val": 0 } }] }], "w:pPr": [{ "w:contextualSpacing": { _attr: { "w:val": 0 } } }],
}, },
], ],
}); });
@ -397,16 +391,14 @@ describe("Paragraph", () => {
{ {
"w:pBdr": [ "w:pBdr": [
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:val": "single",
"w:val": "single", "w:color": "auto",
"w:color": "auto", "w:space": "1",
"w:space": "1", "w:sz": "6",
"w:sz": "6",
},
}, },
], },
}, },
], ],
}, },
@ -430,28 +422,24 @@ describe("Paragraph", () => {
{ {
"w:pBdr": [ "w:pBdr": [
{ {
"w:left": [ "w:left": {
{ _attr: {
_attr: { "w:color": "auto",
"w:color": "auto", "w:space": "1",
"w:space": "1", "w:sz": "6",
"w:sz": "6", "w:val": "single",
"w:val": "single",
},
}, },
], },
}, },
{ {
"w:right": [ "w:right": {
{ _attr: {
_attr: { "w:color": "auto",
"w:color": "auto", "w:space": "1",
"w:space": "1", "w:sz": "6",
"w:sz": "6", "w:val": "single",
"w:val": "single",
},
}, },
], },
}, },
], ],
}, },
@ -469,10 +457,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [], "w:r": [{ "w:br": { _attr: { "w:type": "page" } } }],
},
{
"w:r": [{ "w:rPr": [] }, { "w:br": [{ _attr: { "w:type": "page" } }] }],
}, },
], ],
}); });
@ -488,7 +473,7 @@ describe("Paragraph", () => {
{ {
"w:pPr": [ "w:pPr": [
{ {
"w:pageBreakBefore": [], "w:pageBreakBefore": EMPTY_OBJECT,
}, },
], ],
}, },
@ -510,7 +495,7 @@ describe("Paragraph", () => {
.which.is.an("array") .which.is.an("array")
.which.has.length.at.least(1); .which.has.length.at.least(1);
expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({ expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({
"w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }], "w:pStyle": { _attr: { "w:val": "ListParagraph" } },
}); });
}); });
@ -526,7 +511,7 @@ describe("Paragraph", () => {
.which.is.an("array") .which.is.an("array")
.which.has.length.at.least(1); .which.has.length.at.least(1);
expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({ expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({
"w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }], "w:pStyle": { _attr: { "w:val": "ListParagraph" } },
}); });
}); });
@ -542,7 +527,7 @@ describe("Paragraph", () => {
.which.is.an("array") .which.is.an("array")
.which.has.length.at.least(2); .which.has.length.at.least(2);
expect(tree["w:p"][0]["w:pPr"][1]).to.deep.equal({ expect(tree["w:p"][0]["w:pPr"][1]).to.deep.equal({
"w:numPr": [{ "w:ilvl": [{ _attr: { "w:val": 1 } }] }, { "w:numId": [{ _attr: { "w:val": 1 } }] }], "w:numPr": [{ "w:ilvl": { _attr: { "w:val": 1 } } }, { "w:numId": { _attr: { "w:val": 1 } } }],
}); });
}); });
}); });
@ -565,7 +550,7 @@ describe("Paragraph", () => {
.which.is.an("array") .which.is.an("array")
.which.has.length.at.least(1); .which.has.length.at.least(1);
expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({ expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({
"w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }], "w:pStyle": { _attr: { "w:val": "ListParagraph" } },
}); });
}); });
@ -581,11 +566,11 @@ describe("Paragraph", () => {
"w:p": [ "w:p": [
{ {
"w:pPr": [ "w:pPr": [
{ "w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }] }, { "w:pStyle": { _attr: { "w:val": "ListParagraph" } } },
{ {
"w:numPr": [ "w:numPr": [
{ "w:ilvl": [{ _attr: { "w:val": 0 } }] }, { "w:ilvl": { _attr: { "w:val": 0 } } },
{ "w:numId": [{ _attr: { "w:val": letterNumbering.id } }] }, { "w:numId": { _attr: { "w:val": letterNumbering.id } } },
], ],
}, },
], ],
@ -602,7 +587,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "myFancyStyle" } }] }], "w:pPr": [{ "w:pStyle": { _attr: { "w:val": "myFancyStyle" } } }],
}, },
], ],
}); });
@ -616,7 +601,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:ind": [{ _attr: { "w:left": 720 } }] }], "w:pPr": [{ "w:ind": { _attr: { "w:left": 720 } } }],
}, },
], ],
}); });
@ -630,7 +615,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:spacing": [{ _attr: { "w:before": 90, "w:line": 50 } }] }], "w:pPr": [{ "w:spacing": { _attr: { "w:before": 90, "w:line": 50 } } }],
}, },
], ],
}); });
@ -642,7 +627,7 @@ describe("Paragraph", () => {
paragraph.keepLines(); paragraph.keepLines();
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:pPr": [{ "w:keepLines": [] }] }], "w:p": [{ "w:pPr": [{ "w:keepLines": EMPTY_OBJECT }] }],
}); });
}); });
}); });
@ -652,7 +637,7 @@ describe("Paragraph", () => {
paragraph.keepNext(); paragraph.keepNext();
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:pPr": [{ "w:keepNext": [] }] }], "w:p": [{ "w:pPr": [{ "w:keepNext": EMPTY_OBJECT }] }],
}); });
}); });
}); });
@ -662,7 +647,7 @@ describe("Paragraph", () => {
paragraph.bidirectional(); paragraph.bidirectional();
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:pPr": [{ "w:bidi": [] }] }], "w:p": [{ "w:pPr": [{ "w:bidi": EMPTY_OBJECT }] }],
}); });
}); });
}); });
@ -674,7 +659,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:p": [ "w:p": [
{ {
"w:pPr": [{ "w:outlineLvl": [{ _attr: { "w:val": "0" } }] }], "w:pPr": [{ "w:outlineLvl": { _attr: { "w:val": "0" } } }],
}, },
], ],
}); });

View File

@ -1,8 +1,8 @@
// http://officeopenxml.com/WPparagraphProperties.php // http://officeopenxml.com/WPparagraphProperties.php
import { XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent, XmlComponent } from "file/xml-components";
import { Border } from "./formatting/border"; import { Border } from "./formatting/border";
export class ParagraphProperties extends XmlComponent { export class ParagraphProperties extends IgnoreIfEmptyXmlComponent {
public readonly paragraphBorder: Border; public readonly paragraphBorder: Border;
constructor() { constructor() {

View File

@ -1,6 +1,6 @@
import { XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent, XmlComponent } from "file/xml-components";
export class RunProperties extends XmlComponent { export class RunProperties extends IgnoreIfEmptyXmlComponent {
constructor() { constructor() {
super("w:rPr"); super("w:rPr");
} }

View File

@ -9,7 +9,7 @@ describe("Text", () => {
it("creates an empty text run if no text is given", () => { it("creates an empty text run if no text is given", () => {
const t = new Text(""); const t = new Text("");
const f = new Formatter().format(t); const f = new Formatter().format(t);
expect(f).to.deep.equal({ "w:t": [{ _attr: { "xml:space": "preserve" } }] }); expect(f).to.deep.equal({ "w:t": { _attr: { "xml:space": "preserve" } } });
}); });
it("adds the passed in text to the component", () => { it("adds the passed in text to the component", () => {

View File

@ -9,16 +9,16 @@ describe("RunFonts", () => {
it("uses the font name for both ascii and hAnsi", () => { it("uses the font name for both ascii and hAnsi", () => {
const tree = new Formatter().format(new RunFonts("Times")); const tree = new Formatter().format(new RunFonts("Times"));
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }], "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } },
}); });
}); });
it("uses hint if given", () => { it("uses hint if given", () => {
const tree = new Formatter().format(new RunFonts("Times", "default")); const tree = new Formatter().format(new RunFonts("Times", "default"));
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:rFonts": [ "w:rFonts": {
{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times", "w:hint": "default" } }, _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times", "w:hint": "default" },
], },
}); });
}); });
}); });

View File

@ -41,7 +41,7 @@ describe("Run", () => {
run.underline(); run.underline();
const tree = new Formatter().format(run); const tree = new Formatter().format(run);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }] }], "w:r": [{ "w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }] }],
}); });
}); });
@ -49,7 +49,7 @@ describe("Run", () => {
run.underline("double", "990011"); run.underline("double", "990011");
const tree = new Formatter().format(run); const tree = new Formatter().format(run);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "990011" } }] }] }], "w:r": [{ "w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "990011" } } }] }],
}); });
}); });
}); });
@ -114,7 +114,7 @@ describe("Run", () => {
"w:r": [ "w:r": [
{ {
"w:rPr": [ "w:rPr": [
{ "w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }] }, { "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } } },
], ],
}, },
], ],
@ -127,7 +127,7 @@ describe("Run", () => {
run.color("001122"); run.color("001122");
const tree = new Formatter().format(run); const tree = new Formatter().format(run);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:color": [{ _attr: { "w:val": "001122" } }] }] }], "w:r": [{ "w:rPr": [{ "w:color": { _attr: { "w:val": "001122" } } }] }],
}); });
}); });
}); });
@ -139,7 +139,7 @@ describe("Run", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [ "w:r": [
{ {
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }, { "w:szCs": [{ _attr: { "w:val": 24 } }] }], "w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }, { "w:szCs": { _attr: { "w:val": 24 } } }],
}, },
], ],
}); });
@ -151,7 +151,7 @@ describe("Run", () => {
run.rightToLeft(); run.rightToLeft();
const tree = new Formatter().format(run); const tree = new Formatter().format(run);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:rtl": [{ _attr: { "w:val": true } }] }] }], "w:r": [{ "w:rPr": [{ "w:rtl": { _attr: { "w:val": true } } }] }],
}); });
}); });
}); });
@ -162,11 +162,10 @@ describe("Run", () => {
const tree = new Formatter().format(run); const tree = new Formatter().format(run);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [ "w:r": [
{ "w:rPr": [] }, { "w:fldChar": { _attr: { "w:fldCharType": "begin" } } },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "begin" } }] },
{ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "NUMPAGES"] }, { "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "NUMPAGES"] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "separate" } }] }, { "w:fldChar": { _attr: { "w:fldCharType": "separate" } } },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "end" } }] }, { "w:fldChar": { _attr: { "w:fldCharType": "end" } } },
], ],
}); });
}); });
@ -178,11 +177,10 @@ describe("Run", () => {
const tree = new Formatter().format(run); const tree = new Formatter().format(run);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [ "w:r": [
{ "w:rPr": [] }, { "w:fldChar": { _attr: { "w:fldCharType": "begin" } } },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "begin" } }] },
{ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "PAGE"] }, { "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "PAGE"] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "separate" } }] }, { "w:fldChar": { _attr: { "w:fldCharType": "separate" } } },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "end" } }] }, { "w:fldChar": { _attr: { "w:fldCharType": "end" } } },
], ],
}); });
}); });
@ -193,7 +191,7 @@ describe("Run", () => {
run.style("myRunStyle"); run.style("myRunStyle");
const tree = new Formatter().format(run); const tree = new Formatter().format(run);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:rStyle": [{ _attr: { "w:val": "myRunStyle" } }] }] }], "w:r": [{ "w:rPr": [{ "w:rStyle": { _attr: { "w:val": "myRunStyle" } } }] }],
}); });
}); });
}); });

View File

@ -17,17 +17,12 @@ describe("Sequential Identifier", () => {
const DEFAULT_SEQ = { const DEFAULT_SEQ = {
"w:r": [ "w:r": [
{ {
"w:rPr": [], "w:fldChar": {
}, _attr: {
{ "w:fldCharType": "begin",
"w:fldChar": [ "w:dirty": true,
{
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
}, },
], },
}, },
{ {
"w:instrText": [ "w:instrText": [
@ -40,22 +35,18 @@ const DEFAULT_SEQ = {
], ],
}, },
{ {
"w:fldChar": [ "w:fldChar": {
{ _attr: {
_attr: { "w:fldCharType": "separate",
"w:fldCharType": "separate",
},
}, },
], },
}, },
{ {
"w:fldChar": [ "w:fldChar": {
{ _attr: {
_attr: { "w:fldCharType": "end",
"w:fldCharType": "end",
},
}, },
], },
}, },
], ],
}; };

View File

@ -12,7 +12,7 @@ describe("TextRun", () => {
run = new TextRun("test"); run = new TextRun("test");
const f = new Formatter().format(run); const f = new Formatter().format(run);
expect(f).to.deep.equal({ expect(f).to.deep.equal({
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "test"] }], "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "test"] }],
}); });
}); });
}); });

View File

@ -17,7 +17,7 @@ describe("Underline", () => {
const underline = new u.Underline(); const underline = new u.Underline();
const tree = new Formatter().format(underline); const tree = new Formatter().format(underline);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:u": [{ _attr: { "w:val": "single" } }], "w:u": { _attr: { "w:val": "single" } },
}); });
}); });
@ -25,7 +25,7 @@ describe("Underline", () => {
const underline = new u.Underline("double", "FF00CC"); const underline = new u.Underline("double", "FF00CC");
const tree = new Formatter().format(underline); const tree = new Formatter().format(underline);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:u": [{ _attr: { "w:val": "double", "w:color": "FF00CC" } }], "w:u": { _attr: { "w:val": "double", "w:color": "FF00CC" } },
}); });
}); });
}); });

View File

@ -11,8 +11,7 @@ describe("Relationships", () => {
const properties = new Relationships(); const properties = new Relationships();
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["Relationships"]); expect(Object.keys(tree)).to.deep.equal(["Relationships"]);
expect(tree["Relationships"]).to.be.an.instanceof(Array); expect(tree["Relationships"]).to.deep.equal({
expect(tree["Relationships"][0]).to.deep.equal({
_attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" }, _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" },
}); });
}); });

View File

@ -2,13 +2,15 @@ import { expect } from "chai";
import { Formatter } from "export/formatter"; import { Formatter } from "export/formatter";
import { Compatibility } from "file/settings/compatibility"; import { Compatibility } from "file/settings/compatibility";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Compatibility", () => { describe("Compatibility", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("creates an initially empty property object", () => { it("creates an initially empty property object", () => {
const compatibility = new Compatibility(); const compatibility = new Compatibility();
const tree = new Formatter().format(compatibility); const tree = new Formatter().format(compatibility);
expect(tree).to.deep.equal({ "w:compat": [] }); expect(tree).to.deep.equal({ "w:compat": EMPTY_OBJECT });
}); });
}); });
@ -18,7 +20,7 @@ describe("Compatibility", () => {
compatibility.doNotExpandShiftReturn(); compatibility.doNotExpandShiftReturn();
const tree = new Formatter().format(compatibility); const tree = new Formatter().format(compatibility);
expect(tree).to.deep.equal({ "w:compat": [{ "w:doNotExpandShiftReturn": [] }] }); expect(tree).to.deep.equal({ "w:compat": [{ "w:doNotExpandShiftReturn": EMPTY_OBJECT }] });
}); });
}); });
}); });

View File

@ -13,9 +13,7 @@ describe("Settings", () => {
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:settings"); expect(keys[0]).to.be.equal("w:settings");
expect(tree["w:settings"]).is.an.instanceof(Array); keys = Object.keys(tree["w:settings"]);
expect(tree["w:settings"]).has.length(1);
keys = Object.keys(tree["w:settings"][0]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr"); expect(keys[0]).to.be.equal("_attr");
@ -39,12 +37,12 @@ describe("Settings", () => {
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:updateFields"); expect(keys[0]).to.be.equal("w:updateFields");
const updateFieldsArray = rootArray[1]["w:updateFields"]; const updateFields = rootArray[1]["w:updateFields"];
keys = Object.keys(updateFieldsArray[0]); keys = Object.keys(updateFields);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr"); expect(keys[0]).to.be.equal("_attr");
const updateFieldsAttr = updateFieldsArray[0]._attr; const updateFieldsAttr = updateFields._attr;
expect(updateFieldsAttr["w:val"]).to.be.equal(true); expect(updateFieldsAttr["w:val"]).to.be.equal(true);
}; };
it("should add a UpdateFields with value true", () => { it("should add a UpdateFields with value true", () => {

View File

@ -5,22 +5,18 @@ import { Formatter } from "export/formatter";
import { UpdateFields } from "./update-fields"; import { UpdateFields } from "./update-fields";
const UF_TRUE = { const UF_TRUE = {
"w:updateFields": [ "w:updateFields": {
{ _attr: {
_attr: { "w:val": true,
"w:val": true,
},
}, },
], },
}; };
const UF_FALSE = { const UF_FALSE = {
"w:updateFields": [ "w:updateFields": {
{ _attr: {
_attr: { "w:val": false,
"w:val": false,
},
}, },
], },
}; };
describe("Update Fields", () => { describe("Update Fields", () => {
describe("#constructor", () => { describe("#constructor", () => {

View File

@ -71,24 +71,34 @@ describe("External styles factory", () => {
deleted: false, deleted: false,
root: [ root: [
{ {
_attr: {
"w:ascii": "Arial",
"w:cstheme": "minorHAnsi",
"w:eastAsiaTheme": "minorHAnsi",
"w:hAnsi": "Arial",
},
deleted: false, deleted: false,
root: [], root: [
{
deleted: false,
root: {
"w:ascii": "Arial",
"w:cstheme": "minorHAnsi",
"w:eastAsiaTheme": "minorHAnsi",
"w:hAnsi": "Arial",
},
rootKey: "_attr",
},
],
rootKey: "w:rFonts", rootKey: "w:rFonts",
}, },
{ {
_attr: {
"w:bidi": "ar-SA",
"w:eastAsia": "en-US",
"w:val": "en-US",
},
deleted: false, deleted: false,
root: [], root: [
{
deleted: false,
root: {
"w:bidi": "ar-SA",
"w:eastAsia": "en-US",
"w:val": "en-US",
},
rootKey: "_attr",
},
],
rootKey: "w:lang", rootKey: "w:lang",
}, },
], ],
@ -104,13 +114,18 @@ describe("External styles factory", () => {
deleted: false, deleted: false,
root: [ root: [
{ {
_attr: {
"w:after": "160",
"w:line": "259",
"w:lineRule": "auto",
},
deleted: false, deleted: false,
root: [], root: [
{
deleted: false,
root: {
"w:after": "160",
"w:line": "259",
"w:lineRule": "auto",
},
rootKey: "_attr",
},
],
rootKey: "w:spacing", rootKey: "w:spacing",
}, },
], ],
@ -123,12 +138,17 @@ describe("External styles factory", () => {
rootKey: "w:docDefaults", rootKey: "w:docDefaults",
}); });
expect(importedStyle.root[2]).to.deep.equal({ expect(importedStyle.root[2]).to.deep.equal({
_attr: {
"w:defLockedState": "1",
"w:defUIPriority": "99",
},
deleted: false, deleted: false,
root: [], root: [
{
deleted: false,
root: {
"w:defLockedState": "1",
"w:defUIPriority": "99",
},
rootKey: "_attr",
},
],
rootKey: "w:latentStyles", rootKey: "w:latentStyles",
}); });
}); });
@ -139,19 +159,28 @@ describe("External styles factory", () => {
expect(importedStyle.root.length).to.equal(5); expect(importedStyle.root.length).to.equal(5);
expect(importedStyle.root[3]).to.deep.equal({ expect(importedStyle.root[3]).to.deep.equal({
_attr: {
"w:default": "1",
"w:styleId": "Normal",
"w:type": "paragraph",
},
deleted: false, deleted: false,
root: [ root: [
{ {
_attr: {
"w:val": "Normal",
},
deleted: false, deleted: false,
root: [], root: {
"w:default": "1",
"w:styleId": "Normal",
"w:type": "paragraph",
},
rootKey: "_attr",
},
{
deleted: false,
root: [
{
deleted: false,
root: {
"w:val": "Normal",
},
rootKey: "_attr",
},
],
rootKey: "w:name", rootKey: "w:name",
}, },
{ {
@ -164,26 +193,40 @@ describe("External styles factory", () => {
}); });
expect(importedStyle.root[4]).to.deep.equal({ expect(importedStyle.root[4]).to.deep.equal({
_attr: {
"w:styleId": "Heading1",
"w:type": "paragraph",
},
deleted: false, deleted: false,
root: [ root: [
{ {
_attr: {
"w:val": "heading 1",
},
deleted: false, deleted: false,
root: [], root: {
"w:styleId": "Heading1",
"w:type": "paragraph",
},
rootKey: "_attr",
},
{
deleted: false,
root: [
{
deleted: false,
root: {
"w:val": "heading 1",
},
rootKey: "_attr",
},
],
rootKey: "w:name", rootKey: "w:name",
}, },
{ {
_attr: {
"w:val": "Normal",
},
deleted: false, deleted: false,
root: [], root: [
{
deleted: false,
root: {
"w:val": "Normal",
},
rootKey: "_attr",
},
],
rootKey: "w:basedOn", rootKey: "w:basedOn",
}, },
{ {
@ -203,14 +246,19 @@ describe("External styles factory", () => {
deleted: false, deleted: false,
root: [ root: [
{ {
_attr: {
"w:color": "auto",
"w:space": "1",
"w:sz": "4",
"w:val": "single",
},
deleted: false, deleted: false,
root: [], root: [
{
deleted: false,
root: {
"w:color": "auto",
"w:space": "1",
"w:sz": "4",
"w:val": "single",
},
rootKey: "_attr",
},
],
rootKey: "w:bottom", rootKey: "w:bottom",
}, },
], ],

View File

@ -4,6 +4,8 @@ import { Formatter } from "export/formatter";
import { CharacterStyle } from "./character-style"; import { CharacterStyle } from "./character-style";
import { EMPTY_OBJECT } from "file/xml-components";
describe("CharacterStyle", () => { describe("CharacterStyle", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("should set the style type to character and use the given style id", () => { it("should set the style type to character and use the given style id", () => {
@ -12,18 +14,15 @@ describe("CharacterStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ "w:rPr": [] },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -35,19 +34,16 @@ describe("CharacterStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Style Name" } }] }, { "w:name": { _attr: { "w:val": "Style Name" } } },
{ "w:rPr": [] },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -61,20 +57,17 @@ describe("CharacterStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ "w:rPr": [] },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
{ "w:basedOn": [{ _attr: { "w:val": "otherId" } }] }, { "w:basedOn": { _attr: { "w:val": "otherId" } } },
], ],
}); });
}); });
@ -88,19 +81,17 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }, { "w:szCs": [{ _attr: { "w:val": 24 } }] }], "w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }, { "w:szCs": { _attr: { "w:val": 24 } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -114,19 +105,17 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -139,19 +128,17 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "double" } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -164,19 +151,17 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "005599" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "005599" } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -192,27 +177,23 @@ describe("CharacterStyle", () => {
{ {
"w:rPr": [ "w:rPr": [
{ {
"w:vertAlign": [ "w:vertAlign": {
{ _attr: {
_attr: { "w:val": "superscript",
"w:val": "superscript",
},
}, },
],
},
],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
}, },
}, },
], ],
}, },
{ {
"w:unhideWhenUsed": [], "w:uiPriority": {
_attr: {
"w:val": "99",
},
},
},
{
"w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -225,19 +206,17 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "123456" } }] }], "w:rPr": [{ "w:color": { _attr: { "w:val": "123456" } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -250,19 +229,17 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [{ "w:b": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:b": { _attr: { "w:val": true } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -275,19 +252,17 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [{ "w:i": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:i": { _attr: { "w:val": true } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -300,21 +275,16 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [], "w:uiPriority": {
}, _attr: {
{ "w:val": "99",
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
{ "w:link": [{ _attr: { "w:val": "MyLink" } }] }, { "w:link": { _attr: { "w:val": "MyLink" } } },
], ],
}); });
}); });
@ -326,19 +296,14 @@ describe("CharacterStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ {
"w:rPr": [], "w:uiPriority": {
}, _attr: {
{ "w:val": "99",
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
}, },
], },
}, },
{ "w:unhideWhenUsed": [] }, { "w:unhideWhenUsed": EMPTY_OBJECT },
{ "w:semiHidden": [] }, { "w:semiHidden": EMPTY_OBJECT },
], ],
}); });
}); });

View File

@ -2,52 +2,54 @@ import { expect } from "chai";
import { Formatter } from "export/formatter"; import { Formatter } from "export/formatter";
import * as components from "./components"; import * as components from "./components";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Style components", () => { describe("Style components", () => {
it("Name#constructor", () => { it("Name#constructor", () => {
const style = new components.Name("Style Name"); const style = new components.Name("Style Name");
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:name": [{ _attr: { "w:val": "Style Name" } }] }); expect(tree).to.deep.equal({ "w:name": { _attr: { "w:val": "Style Name" } } });
}); });
it("BasedOn#constructor", () => { it("BasedOn#constructor", () => {
const style = new components.BasedOn("otherId"); const style = new components.BasedOn("otherId");
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:basedOn": [{ _attr: { "w:val": "otherId" } }] }); expect(tree).to.deep.equal({ "w:basedOn": { _attr: { "w:val": "otherId" } } });
}); });
it("Next#constructor", () => { it("Next#constructor", () => {
const style = new components.Next("otherId"); const style = new components.Next("otherId");
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:next": [{ _attr: { "w:val": "otherId" } }] }); expect(tree).to.deep.equal({ "w:next": { _attr: { "w:val": "otherId" } } });
}); });
it("Link#constructor", () => { it("Link#constructor", () => {
const style = new components.Link("otherId"); const style = new components.Link("otherId");
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:link": [{ _attr: { "w:val": "otherId" } }] }); expect(tree).to.deep.equal({ "w:link": { _attr: { "w:val": "otherId" } } });
}); });
it("UiPriority#constructor", () => { it("UiPriority#constructor", () => {
const style = new components.UiPriority("123"); const style = new components.UiPriority("123");
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:uiPriority": [{ _attr: { "w:val": "123" } }] }); expect(tree).to.deep.equal({ "w:uiPriority": { _attr: { "w:val": "123" } } });
}); });
it("UnhideWhenUsed#constructor", () => { it("UnhideWhenUsed#constructor", () => {
const style = new components.UnhideWhenUsed(); const style = new components.UnhideWhenUsed();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:unhideWhenUsed": [] }); expect(tree).to.deep.equal({ "w:unhideWhenUsed": EMPTY_OBJECT });
}); });
it("QuickFormat#constructor", () => { it("QuickFormat#constructor", () => {
const style = new components.QuickFormat(); const style = new components.QuickFormat();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:qFormat": [] }); expect(tree).to.deep.equal({ "w:qFormat": EMPTY_OBJECT });
}); });
it("SemiHidden#constructor", () => { it("SemiHidden#constructor", () => {
const style = new components.SemiHidden(); const style = new components.SemiHidden();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:semiHidden": [] }); expect(tree).to.deep.equal({ "w:semiHidden": EMPTY_OBJECT });
}); });
}); });

View File

@ -2,6 +2,8 @@ import { expect } from "chai";
import { Formatter } from "export/formatter"; import { Formatter } from "export/formatter";
import * as defaultStyels from "./default-styles"; import * as defaultStyels from "./default-styles";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Default Styles", () => { describe("Default Styles", () => {
it("HeadingStyle#constructor", () => { it("HeadingStyle#constructor", () => {
const style = new defaultStyels.HeadingStyle("Heading1", "Heading 1"); const style = new defaultStyels.HeadingStyle("Heading1", "Heading 1");
@ -9,12 +11,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading1" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Heading1" } },
{ "w:name": [{ _attr: { "w:val": "Heading 1" } }] }, { "w:name": { _attr: { "w:val": "Heading 1" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -25,12 +25,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Title" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Title" } },
{ "w:name": [{ _attr: { "w:val": "Title" } }] }, { "w:name": { _attr: { "w:val": "Title" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -41,12 +39,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading1" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Heading1" } },
{ "w:name": [{ _attr: { "w:val": "Heading 1" } }] }, { "w:name": { _attr: { "w:val": "Heading 1" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -57,12 +53,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading2" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Heading2" } },
{ "w:name": [{ _attr: { "w:val": "Heading 2" } }] }, { "w:name": { _attr: { "w:val": "Heading 2" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -73,12 +67,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading3" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Heading3" } },
{ "w:name": [{ _attr: { "w:val": "Heading 3" } }] }, { "w:name": { _attr: { "w:val": "Heading 3" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -89,12 +81,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading4" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Heading4" } },
{ "w:name": [{ _attr: { "w:val": "Heading 4" } }] }, { "w:name": { _attr: { "w:val": "Heading 4" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -105,12 +95,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading5" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Heading5" } },
{ "w:name": [{ _attr: { "w:val": "Heading 5" } }] }, { "w:name": { _attr: { "w:val": "Heading 5" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -121,12 +109,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading6" } }, { _attr: { "w:type": "paragraph", "w:styleId": "Heading6" } },
{ "w:name": [{ _attr: { "w:val": "Heading 6" } }] }, { "w:name": { _attr: { "w:val": "Heading 6" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -137,11 +123,9 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "ListParagraph" } }, { _attr: { "w:type": "paragraph", "w:styleId": "ListParagraph" } },
{ "w:name": [{ _attr: { "w:val": "List Paragraph" } }] }, { "w:name": { _attr: { "w:val": "List Paragraph" } } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:rPr": [] }, { "w:qFormat": EMPTY_OBJECT },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
], ],
}); });
}); });
@ -152,60 +136,52 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "FootnoteText" } }, { _attr: { "w:type": "paragraph", "w:styleId": "FootnoteText" } },
{ "w:name": [{ _attr: { "w:val": "footnote text" } }] }, { "w:name": { _attr: { "w:val": "footnote text" } } },
{ {
"w:pPr": [ "w:pPr": [
{ {
"w:spacing": [ "w:spacing": {
{ _attr: {
_attr: { "w:after": 0,
"w:after": 0, "w:line": 240,
"w:line": 240, "w:lineRule": "auto",
"w:lineRule": "auto",
},
}, },
], },
}, },
], ],
}, },
{ {
"w:rPr": [ "w:rPr": [
{ {
"w:sz": [ "w:sz": {
{ _attr: {
_attr: { "w:val": 20,
"w:val": 20,
},
}, },
], },
}, },
{ {
"w:szCs": [ "w:szCs": {
{ _attr: {
_attr: { "w:val": 20,
"w:val": 20,
},
}, },
],
},
],
},
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:link": [{ _attr: { "w:val": "FootnoteTextChar" } }] },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
}, },
}, },
], ],
}, },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:link": { _attr: { "w:val": "FootnoteTextChar" } } },
{ {
"w:semiHidden": [], "w:uiPriority": {
_attr: {
"w:val": "99",
},
},
}, },
{ {
"w:unhideWhenUsed": [], "w:semiHidden": EMPTY_OBJECT,
},
{
"w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}); });
@ -217,36 +193,32 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "FootnoteReference" } }, { _attr: { "w:type": "character", "w:styleId": "FootnoteReference" } },
{ "w:name": [{ _attr: { "w:val": "footnote reference" } }] }, { "w:name": { _attr: { "w:val": "footnote reference" } } },
{ {
"w:rPr": [ "w:rPr": [
{ {
"w:vertAlign": [ "w:vertAlign": {
{ _attr: {
_attr: { "w:val": "superscript",
"w:val": "superscript",
},
}, },
],
},
],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
}, },
}, },
], ],
}, },
{ {
"w:unhideWhenUsed": [], "w:uiPriority": {
_attr: {
"w:val": "99",
},
},
}, },
{ "w:basedOn": [{ _attr: { "w:val": "DefaultParagraphFont" } }] }, {
"w:unhideWhenUsed": EMPTY_OBJECT,
},
{ "w:basedOn": { _attr: { "w:val": "DefaultParagraphFont" } } },
{ {
"w:semiHidden": [], "w:semiHidden": EMPTY_OBJECT,
}, },
], ],
}); });
@ -258,45 +230,39 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "FootnoteTextChar" } }, { _attr: { "w:type": "character", "w:styleId": "FootnoteTextChar" } },
{ "w:name": [{ _attr: { "w:val": "Footnote Text Char" } }] }, { "w:name": { _attr: { "w:val": "Footnote Text Char" } } },
{ {
"w:rPr": [ "w:rPr": [
{ {
"w:sz": [ "w:sz": {
{ _attr: {
_attr: { "w:val": 20,
"w:val": 20,
},
}, },
], },
}, },
{ {
"w:szCs": [ "w:szCs": {
{ _attr: {
_attr: { "w:val": 20,
"w:val": 20,
},
}, },
],
},
],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
}, },
}, },
], ],
}, },
{ {
"w:unhideWhenUsed": [], "w:uiPriority": {
_attr: {
"w:val": "99",
},
},
}, },
{ "w:basedOn": [{ _attr: { "w:val": "DefaultParagraphFont" } }] },
{ "w:link": [{ _attr: { "w:val": "FootnoteText" } }] },
{ {
"w:semiHidden": [], "w:unhideWhenUsed": EMPTY_OBJECT,
},
{ "w:basedOn": { _attr: { "w:val": "DefaultParagraphFont" } } },
{ "w:link": { _attr: { "w:val": "FootnoteText" } } },
{
"w:semiHidden": EMPTY_OBJECT,
}, },
], ],
}); });
@ -308,23 +274,21 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "Hyperlink" } }, { _attr: { "w:type": "character", "w:styleId": "Hyperlink" } },
{ "w:name": [{ _attr: { "w:val": "Hyperlink" } }] }, { "w:name": { _attr: { "w:val": "Hyperlink" } } },
{ {
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "0563C1" } }] }, { "w:u": [{ _attr: { "w:val": "single" } }] }], "w:rPr": [{ "w:color": { _attr: { "w:val": "0563C1" } } }, { "w:u": { _attr: { "w:val": "single" } } }],
}, },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
{ "w:basedOn": [{ _attr: { "w:val": "DefaultParagraphFont" } }] }, { "w:basedOn": { _attr: { "w:val": "DefaultParagraphFont" } } },
], ],
}); });
}); });

View File

@ -4,13 +4,15 @@ import { Formatter } from "export/formatter";
import { ParagraphStyle } from "./paragraph-style"; import { ParagraphStyle } from "./paragraph-style";
import { EMPTY_OBJECT } from "file/xml-components";
describe("ParagraphStyle", () => { describe("ParagraphStyle", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("should set the style type to paragraph and use the given style id", () => { it("should set the style type to paragraph and use the given style id", () => {
const style = new ParagraphStyle("myStyleId"); const style = new ParagraphStyle("myStyleId");
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:pPr": [] }, { "w:rPr": [] }], "w:style": { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
}); });
}); });
@ -20,9 +22,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Style Name" } }] }, { "w:name": { _attr: { "w:val": "Style Name" } } },
{ "w:pPr": [] },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -35,9 +35,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] }, { "w:basedOn": { _attr: { "w:val": "otherId" } } },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "otherId" } }] },
], ],
}); });
}); });
@ -46,12 +44,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").quickFormat(); const style = new ParagraphStyle("myStyleId").quickFormat();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:qFormat": EMPTY_OBJECT }],
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:qFormat": [] },
],
}); });
}); });
@ -61,9 +54,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] }, { "w:next": { _attr: { "w:val": "otherId" } } },
{ "w:rPr": [] },
{ "w:next": [{ _attr: { "w:val": "otherId" } }] },
], ],
}); });
}); });
@ -77,9 +68,8 @@ describe("ParagraphStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ {
"w:pPr": [{ "w:ind": [{ _attr: { "w:left": 720 } }] }], "w:pPr": [{ "w:ind": { _attr: { "w:left": 720 } } }],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -91,9 +81,8 @@ describe("ParagraphStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ {
"w:pPr": [{ "w:spacing": [{ _attr: { "w:before": 50, "w:after": 150 } }] }], "w:pPr": [{ "w:spacing": { _attr: { "w:before": 50, "w:after": 150 } } }],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -105,9 +94,8 @@ describe("ParagraphStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "center" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "center" } } }],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -118,9 +106,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:spacing": [{ _attr: { "w:val": 24 } }] }], "w:rPr": [{ "w:spacing": { _attr: { "w:val": 24 } } }],
}, },
], ],
}); });
@ -133,9 +120,8 @@ describe("ParagraphStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "left" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "left" } } }],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -147,9 +133,8 @@ describe("ParagraphStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "right" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "right" } } }],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -161,9 +146,8 @@ describe("ParagraphStyle", () => {
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ {
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "both" } }] }], "w:pPr": [{ "w:jc": { _attr: { "w:val": "both" } } }],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -179,22 +163,19 @@ describe("ParagraphStyle", () => {
{ {
"w:pBdr": [ "w:pBdr": [
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:color": "auto",
"w:color": "auto", "w:space": "1",
"w:space": "1", "w:val": "single",
"w:val": "single", "w:sz": "6",
"w:sz": "6",
},
}, },
], },
}, },
], ],
}, },
], ],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -208,11 +189,10 @@ describe("ParagraphStyle", () => {
{ {
"w:pPr": [ "w:pPr": [
{ {
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "left", "w:pos": 1200 } }] }], "w:tabs": [{ "w:tab": { _attr: { "w:val": "left", "w:pos": 1200 } } }],
}, },
], ],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -226,11 +206,10 @@ describe("ParagraphStyle", () => {
{ {
"w:pPr": [ "w:pPr": [
{ {
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "right", "w:pos": 9026 } }] }], "w:tabs": [{ "w:tab": { _attr: { "w:val": "right", "w:pos": 9026 } } }],
}, },
], ],
}, },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -239,11 +218,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").keepLines(); const style = new ParagraphStyle("myStyleId").keepLines();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:pPr": [{ "w:keepLines": EMPTY_OBJECT }] }],
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [{ "w:keepLines": [] }] },
{ "w:rPr": [] },
],
}); });
}); });
@ -251,11 +226,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").keepNext(); const style = new ParagraphStyle("myStyleId").keepNext();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:pPr": [{ "w:keepNext": EMPTY_OBJECT }] }],
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [{ "w:keepNext": [] }] },
{ "w:rPr": [] },
],
}); });
}); });
@ -265,8 +236,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [{ "w:outlineLvl": [{ _attr: { "w:val": "1" } }] }] }, { "w:pPr": [{ "w:outlineLvl": { _attr: { "w:val": "1" } } }] },
{ "w:rPr": [] },
], ],
}); });
}); });
@ -279,9 +249,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }, { "w:szCs": [{ _attr: { "w:val": 24 } }] }], "w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }, { "w:szCs": { _attr: { "w:val": 24 } } }],
}, },
], ],
}); });
@ -293,9 +262,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:smallCaps": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:smallCaps": { _attr: { "w:val": true } } }],
}, },
], ],
}); });
@ -307,9 +275,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:caps": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:caps": { _attr: { "w:val": true } } }],
}, },
], ],
}); });
@ -321,9 +288,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:strike": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:strike": { _attr: { "w:val": true } } }],
}, },
], ],
}); });
@ -335,9 +301,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:dstrike": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:dstrike": { _attr: { "w:val": true } } }],
}, },
], ],
}); });
@ -349,9 +314,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "subscript" } }] }], "w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "subscript" } } }],
}, },
], ],
}); });
@ -363,9 +327,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "superscript" } }] }], "w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "superscript" } } }],
}, },
], ],
}); });
@ -377,10 +340,9 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [ "w:rPr": [
{ "w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }] }, { "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } } },
], ],
}, },
], ],
@ -393,9 +355,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:b": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:b": { _attr: { "w:val": true } } }],
}, },
], ],
}); });
@ -407,9 +368,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:i": [{ _attr: { "w:val": true } }] }], "w:rPr": [{ "w:i": { _attr: { "w:val": true } } }],
}, },
], ],
}); });
@ -422,9 +382,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }],
}, },
], ],
}); });
@ -436,9 +395,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "double" } } }],
}, },
], ],
}); });
@ -450,9 +408,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "005599" } }] }], "w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "005599" } } }],
}, },
], ],
}); });
@ -465,9 +422,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ {
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "123456" } }] }], "w:rPr": [{ "w:color": { _attr: { "w:val": "123456" } } }],
}, },
], ],
}); });
@ -477,12 +433,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").link("MyLink"); const style = new ParagraphStyle("myStyleId").link("MyLink");
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:link": { _attr: { "w:val": "MyLink" } } }],
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:link": [{ _attr: { "w:val": "MyLink" } }] },
],
}); });
}); });
@ -490,12 +441,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").semiHidden(); const style = new ParagraphStyle("myStyleId").semiHidden();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:semiHidden": EMPTY_OBJECT }],
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:semiHidden": [] },
],
}); });
}); });
@ -505,16 +451,12 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
], ],
}); });
@ -524,12 +466,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").unhideWhenUsed(); const style = new ParagraphStyle("myStyleId").unhideWhenUsed();
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:unhideWhenUsed": EMPTY_OBJECT }],
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:unhideWhenUsed": [] },
],
}); });
}); });
}); });

View File

@ -12,7 +12,7 @@ describe("Style", () => {
}); });
const tree = new Formatter().format(style); const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId", "w:default": true } }], "w:style": { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId", "w:default": true } },
}); });
}); });
@ -28,7 +28,7 @@ describe("Style", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Style Name" } }] }, { "w:name": { _attr: { "w:val": "Style Name" } } },
], ],
}); });
}); });

View File

@ -6,6 +6,8 @@ import { CharacterStyle, ParagraphStyle } from "./style";
import { Styles } from "./styles"; import { Styles } from "./styles";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Styles", () => { describe("Styles", () => {
let styles: Styles; let styles: Styles;
@ -27,7 +29,7 @@ describe("Styles", () => {
const tree = new Formatter().format(styles)["w:styles"].filter((x) => !x._attr); const tree = new Formatter().format(styles)["w:styles"].filter((x) => !x._attr);
expect(tree).to.deep.equal([ expect(tree).to.deep.equal([
{ {
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "pStyleId" } }, { "w:pPr": [] }, { "w:rPr": [] }], "w:style": { _attr: { "w:type": "paragraph", "w:styleId": "pStyleId" } },
}, },
]); ]);
}); });
@ -40,9 +42,7 @@ describe("Styles", () => {
{ {
"w:style": [ "w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "pStyleId" } }, { _attr: { "w:type": "paragraph", "w:styleId": "pStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Paragraph Style" } }] }, { "w:name": { _attr: { "w:val": "Paragraph Style" } } },
{ "w:pPr": [] },
{ "w:rPr": [] },
], ],
}, },
]); ]);
@ -58,18 +58,15 @@ describe("Styles", () => {
{ {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "pStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "pStyleId" } },
{ "w:rPr": [] },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}, },
@ -84,19 +81,16 @@ describe("Styles", () => {
{ {
"w:style": [ "w:style": [
{ _attr: { "w:type": "character", "w:styleId": "pStyleId" } }, { _attr: { "w:type": "character", "w:styleId": "pStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Character Style" } }] }, { "w:name": { _attr: { "w:val": "Character Style" } } },
{ "w:rPr": [] },
{ {
"w:uiPriority": [ "w:uiPriority": {
{ _attr: {
_attr: { "w:val": "99",
"w:val": "99",
},
}, },
], },
}, },
{ {
"w:unhideWhenUsed": [], "w:unhideWhenUsed": EMPTY_OBJECT,
}, },
], ],
}, },

View File

@ -49,13 +49,11 @@ const DEFAULT_TOC = {
{ {
"w:sdtPr": [ "w:sdtPr": [
{ {
"w:alias": [ "w:alias": {
{ _attr: {
_attr: { "w:val": "Table of Contents",
"w:val": "Table of Contents",
},
}, },
], },
}, },
], ],
}, },
@ -63,23 +61,15 @@ const DEFAULT_TOC = {
"w:sdtContent": [ "w:sdtContent": [
{ {
"w:p": [ "w:p": [
{
"w:pPr": [],
},
{ {
"w:r": [ "w:r": [
{ {
"w:rPr": [], "w:fldChar": {
}, _attr: {
{ "w:fldCharType": "begin",
"w:fldChar": [ "w:dirty": true,
{
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
}, },
], },
}, },
{ {
"w:instrText": [ "w:instrText": [
@ -92,13 +82,11 @@ const DEFAULT_TOC = {
], ],
}, },
{ {
"w:fldChar": [ "w:fldChar": {
{ _attr: {
_attr: { "w:fldCharType": "separate",
"w:fldCharType": "separate",
},
}, },
], },
}, },
], ],
}, },
@ -106,22 +94,14 @@ const DEFAULT_TOC = {
}, },
{ {
"w:p": [ "w:p": [
{
"w:pPr": [],
},
{ {
"w:r": [ "w:r": [
{ {
"w:rPr": [], "w:fldChar": {
}, _attr: {
{ "w:fldCharType": "end",
"w:fldChar": [
{
_attr: {
"w:fldCharType": "end",
},
}, },
], },
}, },
], ],
}, },
@ -137,13 +117,11 @@ const COMPLETE_TOC = {
{ {
"w:sdtPr": [ "w:sdtPr": [
{ {
"w:alias": [ "w:alias": {
{ _attr: {
_attr: { "w:val": "Summary",
"w:val": "Summary",
},
}, },
], },
}, },
], ],
}, },
@ -151,23 +129,15 @@ const COMPLETE_TOC = {
"w:sdtContent": [ "w:sdtContent": [
{ {
"w:p": [ "w:p": [
{
"w:pPr": [],
},
{ {
"w:r": [ "w:r": [
{ {
"w:rPr": [], "w:fldChar": {
}, _attr: {
{ "w:fldCharType": "begin",
"w:fldChar": [ "w:dirty": true,
{
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
}, },
], },
}, },
{ {
"w:instrText": [ "w:instrText": [
@ -180,13 +150,11 @@ const COMPLETE_TOC = {
], ],
}, },
{ {
"w:fldChar": [ "w:fldChar": {
{ _attr: {
_attr: { "w:fldCharType": "separate",
"w:fldCharType": "separate",
},
}, },
], },
}, },
], ],
}, },
@ -194,22 +162,14 @@ const COMPLETE_TOC = {
}, },
{ {
"w:p": [ "w:p": [
{
"w:pPr": [],
},
{ {
"w:r": [ "w:r": [
{ {
"w:rPr": [], "w:fldChar": {
}, _attr: {
{ "w:fldCharType": "end",
"w:fldChar": [
{
_attr: {
"w:fldCharType": "end",
},
}, },
], },
}, },
], ],
}, },

View File

@ -4,20 +4,22 @@ import { Formatter } from "export/formatter";
import { GridCol, TableGrid } from "./grid"; import { GridCol, TableGrid } from "./grid";
import { EMPTY_OBJECT } from "file/xml-components";
describe("GridCol", () => { describe("GridCol", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("sets the width attribute to the value given", () => { it("sets the width attribute to the value given", () => {
const grid = new GridCol(1234); const grid = new GridCol(1234);
const tree = new Formatter().format(grid); const tree = new Formatter().format(grid);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:gridCol": [{ _attr: { "w:w": 1234 } }], "w:gridCol": { _attr: { "w:w": 1234 } },
}); });
}); });
it("does not set a width attribute if not given", () => { it("does not set a width attribute if not given", () => {
const grid = new GridCol(); const grid = new GridCol();
const tree = new Formatter().format(grid); const tree = new Formatter().format(grid);
expect(tree).to.deep.equal({ "w:gridCol": [] }); expect(tree).to.deep.equal({ "w:gridCol": EMPTY_OBJECT });
}); });
}); });
}); });
@ -29,9 +31,9 @@ describe("TableGrid", () => {
const tree = new Formatter().format(grid); const tree = new Formatter().format(grid);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tblGrid": [ "w:tblGrid": [
{ "w:gridCol": [{ _attr: { "w:w": 1234 } }] }, { "w:gridCol": { _attr: { "w:w": 1234 } } },
{ "w:gridCol": [{ _attr: { "w:w": 321 } }] }, { "w:gridCol": { _attr: { "w:w": 321 } } },
{ "w:gridCol": [{ _attr: { "w:w": 123 } }] }, { "w:gridCol": { _attr: { "w:w": 123 } } },
], ],
}); });
}); });

View File

@ -7,30 +7,26 @@ import { ShadingType, TableShading } from "./shading";
describe("TableShading", () => { describe("TableShading", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("should create", () => { it("should create", () => {
const cellMargain = new TableShading({}); const shading = new TableShading({});
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(shading);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:shd": [ "w:shd": {
{ _attr: {},
_attr: {}, },
},
],
}); });
}); });
it("should create with params", () => { it("should create with params", () => {
const cellMargain = new TableShading({ val: ShadingType.PERCENT_40, color: "FF0000", fill: "555555" }); const shading = new TableShading({ val: ShadingType.PERCENT_40, color: "FF0000", fill: "555555" });
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(shading);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:shd": [ "w:shd": {
{ _attr: {
_attr: { "w:color": "FF0000",
"w:color": "FF0000", "w:fill": "555555",
"w:fill": "555555", "w:val": "pct40",
"w:val": "pct40",
},
}, },
], },
}); });
}); });
}); });

View File

@ -10,14 +10,12 @@ describe("TopCellMargain", () => {
const cellMargain = new TopCellMargain(1); const cellMargain = new TopCellMargain(1);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:top": [ "w:top": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 1,
"w:w": 1,
},
}, },
], },
}); });
}); });
}); });
@ -29,14 +27,12 @@ describe("BottomCellMargain", () => {
const cellMargain = new BottomCellMargain(1); const cellMargain = new BottomCellMargain(1);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 1,
"w:w": 1,
},
}, },
], },
}); });
}); });
}); });
@ -48,14 +44,12 @@ describe("LeftCellMargain", () => {
const cellMargain = new LeftCellMargain(1); const cellMargain = new LeftCellMargain(1);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:start": [ "w:start": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 1,
"w:w": 1,
},
}, },
], },
}); });
}); });
}); });
@ -67,14 +61,12 @@ describe("RightCellMargain", () => {
const cellMargain = new RightCellMargain(1); const cellMargain = new RightCellMargain(1);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:end": [ "w:end": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 1,
"w:w": 1,
},
}, },
], },
}); });
}); });
}); });

View File

@ -12,44 +12,36 @@ describe("TableCellMargain", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcMar": [ "w:tcMar": [
{ {
"w:top": [ "w:top": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
{ {
"w:end": [ "w:end": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
{ {
"w:start": [ "w:start": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
], ],
}); });
@ -66,44 +58,36 @@ describe("TableCellMargain", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcMar": [ "w:tcMar": [
{ {
"w:top": [ "w:top": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 5,
"w:w": 5,
},
}, },
], },
}, },
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 5,
"w:w": 5,
},
}, },
], },
}, },
{ {
"w:end": [ "w:end": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 5,
"w:w": 5,
},
}, },
], },
}, },
{ {
"w:start": [ "w:start": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 5,
"w:w": 5,
},
}, },
], },
}, },
], ],
}); });

View File

@ -1,5 +1,5 @@
import { BorderStyle } from "file/styles"; import { BorderStyle } from "file/styles";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
interface ICellBorder { interface ICellBorder {
readonly style: BorderStyle; readonly style: BorderStyle;
@ -24,17 +24,11 @@ class BaseTableCellBorder extends XmlComponent {
} }
} }
export class TableCellBorders extends XmlComponent { export class TableCellBorders extends IgnoreIfEmptyXmlComponent {
constructor() { constructor() {
super("w:tcBorders"); super("w:tcBorders");
} }
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
public addTopBorder(style: BorderStyle, size: number, color: string): TableCellBorders { public addTopBorder(style: BorderStyle, size: number, color: string): TableCellBorders {
const top = new BaseTableCellBorder("w:top"); const top = new BaseTableCellBorder("w:top");
top.setProperties(style, size, color); top.setProperties(style, size, color);

View File

@ -9,77 +9,80 @@ import { TableCellProperties } from "./table-cell-properties";
describe("TableCellProperties", () => { describe("TableCellProperties", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("creates an initially empty property object", () => { it("creates an initially empty property object", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
const tree = new Formatter().format(cellMargain); // The TableCellProperties is ignorable if there are no attributes,
expect(tree).to.deep.equal({ "w:tcPr": [] }); // which results in prepForXml returning undefined, which causes
// the formatter to throw an error if that is the only object it
// has been asked to format.
expect(() => new Formatter().format(properties)).to.throw("XMLComponent did not format correctly");
}); });
}); });
describe("#addGridSpan", () => { describe("#addGridSpan", () => {
it("adds grid span", () => { it("adds grid span", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
cellMargain.addGridSpan(1); properties.addGridSpan(1);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:gridSpan": [{ _attr: { "w:val": 1 } }] }] }); expect(tree).to.deep.equal({ "w:tcPr": [{ "w:gridSpan": { _attr: { "w:val": 1 } } }] });
}); });
}); });
describe("#addVerticalMerge", () => { describe("#addVerticalMerge", () => {
it("adds vertical merge", () => { it("adds vertical merge", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
cellMargain.addVerticalMerge(VMergeType.CONTINUE); properties.addVerticalMerge(VMergeType.CONTINUE);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vMerge": [{ _attr: { "w:val": "continue" } }] }] }); expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "continue" } } }] });
}); });
}); });
describe("#setVerticalAlign", () => { describe("#setVerticalAlign", () => {
it("sets vertical align", () => { it("sets vertical align", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
cellMargain.setVerticalAlign(VerticalAlign.BOTTOM); properties.setVerticalAlign(VerticalAlign.BOTTOM);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vAlign": [{ _attr: { "w:val": "bottom" } }] }] }); expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vAlign": { _attr: { "w:val": "bottom" } } }] });
}); });
}); });
describe("#setWidth", () => { describe("#setWidth", () => {
it("should set width", () => { it("should set width", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
cellMargain.setWidth(1, WidthType.DXA); properties.setWidth(1, WidthType.DXA);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": [{ _attr: { "w:type": "dxa", "w:w": 1 } }] }] }); expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": { _attr: { "w:type": "dxa", "w:w": 1 } } }] });
}); });
it("should set width using default of AUTO", () => { it("should set width using default of AUTO", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
cellMargain.setWidth(1); properties.setWidth(1);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": [{ _attr: { "w:type": "auto", "w:w": 1 } }] }] }); expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": { _attr: { "w:type": "auto", "w:w": 1 } } }] });
}); });
}); });
describe("#setShading", () => { describe("#setShading", () => {
it("sets shading", () => { it("sets shading", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
cellMargain.setShading({ properties.setShading({
fill: "test", fill: "test",
color: "000", color: "000",
}); });
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:shd": [{ _attr: { "w:fill": "test", "w:color": "000" } }] }] }); expect(tree).to.deep.equal({ "w:tcPr": [{ "w:shd": { _attr: { "w:fill": "test", "w:color": "000" } } }] });
}); });
}); });
describe("#Borders", () => { describe("#Borders", () => {
it("should return the TableCellBorders if Border has borders", () => { it("should return the TableCellBorders if Border has borders", () => {
const cellMargain = new TableCellProperties(); const properties = new TableCellProperties();
cellMargain.Borders.addTopBorder(BorderStyle.DASH_DOT_STROKED, 3, "red"); properties.Borders.addTopBorder(BorderStyle.DASH_DOT_STROKED, 3, "red");
const borders = cellMargain.Borders; const borders = properties.Borders;
const tree = new Formatter().format(borders); const tree = new Formatter().format(borders);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [{ "w:top": [{ _attr: { "w:val": "dashDotStroked", "w:sz": 3, "w:color": "red" } }] }], "w:tcBorders": [{ "w:top": { _attr: { "w:val": "dashDotStroked", "w:sz": 3, "w:color": "red" } } }],
}); });
}); });
}); });

View File

@ -1,10 +1,10 @@
import { XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent } from "file/xml-components";
import { ITableShadingAttributesProperties, TableShading } from "../shading"; import { ITableShadingAttributesProperties, TableShading } from "../shading";
import { ITableCellMargainOptions, TableCellMargain } from "./cell-margain/table-cell-margains"; import { ITableCellMargainOptions, TableCellMargain } from "./cell-margain/table-cell-margains";
import { GridSpan, TableCellBorders, TableCellWidth, VAlign, VerticalAlign, VMerge, VMergeType, WidthType } from "./table-cell-components"; import { GridSpan, TableCellBorders, TableCellWidth, VAlign, VerticalAlign, VMerge, VMergeType, WidthType } from "./table-cell-components";
export class TableCellProperties extends XmlComponent { export class TableCellProperties extends IgnoreIfEmptyXmlComponent {
private readonly cellBorder: TableCellBorders; private readonly cellBorder: TableCellBorders;
constructor() { constructor() {

View File

@ -22,15 +22,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [ "w:tcBorders": [
{ {
"w:top": [ "w:top": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 1,
"w:sz": 1, "w:val": "dotted",
"w:val": "dotted",
},
}, },
], },
}, },
], ],
}); });
@ -44,15 +42,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [ "w:tcBorders": [
{ {
"w:start": [ "w:start": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 2,
"w:sz": 2, "w:val": "single",
"w:val": "single",
},
}, },
], },
}, },
], ],
}); });
@ -66,15 +62,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [ "w:tcBorders": [
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 1,
"w:sz": 1, "w:val": "double",
"w:val": "double",
},
}, },
], },
}, },
], ],
}); });
@ -88,15 +82,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [ "w:tcBorders": [
{ {
"w:end": [ "w:end": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 3,
"w:sz": 3, "w:val": "thick",
"w:val": "thick",
},
}, },
], },
}, },
], ],
}); });
@ -110,15 +102,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [ "w:tcBorders": [
{ {
"w:left": [ "w:left": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 3,
"w:sz": 3, "w:val": "thick",
"w:val": "thick",
},
}, },
], },
}, },
], ],
}); });
@ -132,15 +122,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [ "w:tcBorders": [
{ {
"w:right": [ "w:right": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 3,
"w:sz": 3, "w:val": "thick",
"w:val": "thick",
},
}, },
], },
}, },
], ],
}); });
@ -159,70 +147,58 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcBorders": [ "w:tcBorders": [
{ {
"w:top": [ "w:top": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 1,
"w:sz": 1, "w:val": "dotted",
"w:val": "dotted",
},
}, },
], },
}, },
{ {
"w:end": [ "w:end": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 3,
"w:sz": 3, "w:val": "thick",
"w:val": "thick",
},
}, },
], },
}, },
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 1,
"w:sz": 1, "w:val": "double",
"w:val": "double",
},
}, },
], },
}, },
{ {
"w:start": [ "w:start": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 2,
"w:sz": 2, "w:val": "single",
"w:val": "single",
},
}, },
], },
}, },
{ {
"w:left": [ "w:left": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 2,
"w:sz": 2, "w:val": "single",
"w:val": "single",
},
}, },
], },
}, },
{ {
"w:right": [ "w:right": {
{ _attr: {
_attr: { "w:color": "FF00FF",
"w:color": "FF00FF", "w:sz": 2,
"w:sz": 2, "w:val": "single",
"w:val": "single",
},
}, },
], },
}, },
], ],
}); });
@ -236,14 +212,12 @@ describe("TableCellWidth", () => {
const tcWidth = new TableCellWidth(100, WidthType.DXA); const tcWidth = new TableCellWidth(100, WidthType.DXA);
const tree = new Formatter().format(tcWidth); const tree = new Formatter().format(tcWidth);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tcW": [ "w:tcW": {
{ _attr: {
_attr: { "w:type": "dxa",
"w:type": "dxa", "w:w": 100,
"w:w": 100,
},
}, },
], },
}); });
}); });
}); });

View File

@ -30,16 +30,10 @@ export class TableCell extends XmlComponent {
public prepForXml(): IXmlableObject | undefined { public prepForXml(): IXmlableObject | undefined {
// Cells must end with a paragraph // Cells must end with a paragraph
const retval = super.prepForXml(); if (!(this.root[this.root.length - 1] instanceof Paragraph)) {
if (!retval) { this.createParagraph();
return undefined;
} }
return super.prepForXml();
const content = retval["w:tc"];
if (!content[content.length - 1]["w:p"]) {
content.push(new Paragraph().prepForXml());
}
return retval;
} }
public createParagraph(text?: string): Paragraph { public createParagraph(text?: string): Paragraph {

View File

@ -5,6 +5,8 @@ import { Formatter } from "export/formatter";
import { TableCell } from "./table-cell"; import { TableCell } from "./table-cell";
import { TableColumn } from "./table-column"; import { TableColumn } from "./table-column";
import { EMPTY_OBJECT } from "file/xml-components";
describe("TableColumn", () => { describe("TableColumn", () => {
let cells: TableCell[]; let cells: TableCell[];
beforeEach(() => { beforeEach(() => {
@ -37,15 +39,15 @@ describe("TableColumn", () => {
const tree = new Formatter().format(cells[0]); const tree = new Formatter().format(cells[0]);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tc": [{ "w:tcPr": [{ "w:vMerge": [{ _attr: { "w:val": "restart" } }] }] }, { "w:p": [{ "w:pPr": [] }] }], "w:tc": [{ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "restart" } } }] }, { "w:p": EMPTY_OBJECT }],
}); });
const tree2 = new Formatter().format(cells[1]); const tree2 = new Formatter().format(cells[1]);
expect(tree2).to.deep.equal({ "w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }] }); expect(tree2).to.deep.equal({ "w:tc": [{ "w:p": EMPTY_OBJECT }] });
const tree3 = new Formatter().format(cells[2]); const tree3 = new Formatter().format(cells[2]);
expect(tree3).to.deep.equal({ expect(tree3).to.deep.equal({
"w:tc": [{ "w:tcPr": [{ "w:vMerge": [{ _attr: { "w:val": "continue" } }] }] }, { "w:p": [{ "w:pPr": [] }] }], "w:tc": [{ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "continue" } } }] }, { "w:p": EMPTY_OBJECT }],
}); });
}); });
}); });

View File

@ -18,7 +18,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin(); const cellMargain = new TableCellMargin();
cellMargain.addTopMargin(1234, WidthType.DXA); cellMargain.addTopMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:top": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }); expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:top": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
}); });
}); });
@ -27,7 +27,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin(); const cellMargain = new TableCellMargin();
cellMargain.addLeftMargin(1234, WidthType.DXA); cellMargain.addLeftMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:left": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }); expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:left": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
}); });
}); });
@ -36,7 +36,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin(); const cellMargain = new TableCellMargin();
cellMargain.addBottomMargin(1234, WidthType.DXA); cellMargain.addBottomMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:bottom": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }); expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:bottom": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
}); });
}); });
@ -45,7 +45,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin(); const cellMargain = new TableCellMargin();
cellMargain.addRightMargin(1234, WidthType.DXA); cellMargain.addRightMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain); const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:right": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }); expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:right": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
}); });
}); });
}); });

View File

@ -1,4 +1,4 @@
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { WidthType } from "../table-cell"; import { WidthType } from "../table-cell";
@ -17,17 +17,11 @@ class BaseTableCellMargin extends XmlComponent {
} }
} }
export class TableCellMargin extends XmlComponent { export class TableCellMargin extends IgnoreIfEmptyXmlComponent {
constructor() { constructor() {
super("w:tblCellMar"); super("w:tblCellMar");
} }
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
public addTopMargin(value: number, type: WidthType = WidthType.DXA): void { public addTopMargin(value: number, type: WidthType = WidthType.DXA): void {
const top = new BaseTableCellMargin("w:top"); const top = new BaseTableCellMargin("w:top");

View File

@ -26,20 +26,18 @@ describe("Table Float Properties", () => {
}); });
const DEFAULT_TFP = { const DEFAULT_TFP = {
"w:tblpPr": [ "w:tblpPr": {
{ _attr: {
_attr: { "w:horzAnchor": "margin",
"w:horzAnchor": "margin", "w:vertAnchor": "page",
"w:vertAnchor": "page", "w:tblpX": 10,
"w:tblpX": 10, "w:tblpXSpec": "center",
"w:tblpXSpec": "center", "w:tblpY": 20,
"w:tblpY": 20, "w:tblpYSpec": "bottom",
"w:tblpYSpec": "bottom", "w:bottomFromText": 30,
"w:bottomFromText": 30, "w:topFromText": 40,
"w:topFromText": 40, "w:leftFromText": 50,
"w:leftFromText": 50, "w:rightFromText": 60,
"w:rightFromText": 60,
},
}, },
], },
}; };

View File

@ -9,8 +9,11 @@ describe("TableProperties", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("creates an initially empty property object", () => { it("creates an initially empty property object", () => {
const tp = new TableProperties(); const tp = new TableProperties();
const tree = new Formatter().format(tp); // The TableProperties is ignorable if there are no attributes,
expect(tree).to.deep.equal({ "w:tblPr": [] }); // which results in prepForXml returning undefined, which causes
// the formatter to throw an error if that is the only object it
// has been asked to format.
expect(() => new Formatter().format(tp)).to.throw("XMLComponent did not format correctly");
}); });
}); });
@ -19,7 +22,7 @@ describe("TableProperties", () => {
const tp = new TableProperties().setWidth(1234, WidthType.DXA); const tp = new TableProperties().setWidth(1234, WidthType.DXA);
const tree = new Formatter().format(tp); const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblW": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }], "w:tblPr": [{ "w:tblW": { _attr: { "w:type": "dxa", "w:w": 1234 } } }],
}); });
}); });
@ -27,7 +30,7 @@ describe("TableProperties", () => {
const tp = new TableProperties().setWidth(1234); const tp = new TableProperties().setWidth(1234);
const tree = new Formatter().format(tp); const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblW": [{ _attr: { "w:type": "auto", "w:w": 1234 } }] }], "w:tblPr": [{ "w:tblW": { _attr: { "w:type": "auto", "w:w": 1234 } } }],
}); });
}); });
}); });
@ -37,7 +40,7 @@ describe("TableProperties", () => {
const tp = new TableProperties().setFixedWidthLayout(); const tp = new TableProperties().setFixedWidthLayout();
const tree = new Formatter().format(tp); const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblLayout": [{ _attr: { "w:type": "fixed" } }] }], "w:tblPr": [{ "w:tblLayout": { _attr: { "w:type": "fixed" } } }],
}); });
}); });
}); });
@ -48,7 +51,7 @@ describe("TableProperties", () => {
tp.CellMargin.addTopMargin(1234, WidthType.DXA); tp.CellMargin.addTopMargin(1234, WidthType.DXA);
const tree = new Formatter().format(tp); const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblCellMar": [{ "w:top": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }], "w:tblPr": [{ "w:tblCellMar": [{ "w:top": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] }],
}); });
}); });
@ -57,7 +60,7 @@ describe("TableProperties", () => {
tp.CellMargin.addLeftMargin(1234, WidthType.DXA); tp.CellMargin.addLeftMargin(1234, WidthType.DXA);
const tree = new Formatter().format(tp); const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblCellMar": [{ "w:left": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }], "w:tblPr": [{ "w:tblCellMar": [{ "w:left": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] }],
}); });
}); });
}); });

View File

@ -1,4 +1,4 @@
import { XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent } from "file/xml-components";
import { ITableShadingAttributesProperties, TableShading } from "../shading"; import { ITableShadingAttributesProperties, TableShading } from "../shading";
import { WidthType } from "../table-cell"; import { WidthType } from "../table-cell";
@ -8,7 +8,7 @@ import { ITableFloatOptions, TableFloatProperties } from "./table-float-properti
import { TableLayout, TableLayoutType } from "./table-layout"; import { TableLayout, TableLayoutType } from "./table-layout";
import { PreferredTableWidth } from "./table-width"; import { PreferredTableWidth } from "./table-width";
export class TableProperties extends XmlComponent { export class TableProperties extends IgnoreIfEmptyXmlComponent {
private readonly cellMargin: TableCellMargin; private readonly cellMargin: TableCellMargin;
constructor() { constructor() {

View File

@ -6,8 +6,11 @@ describe("TableRowProperties", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("creates an initially empty property object", () => { it("creates an initially empty property object", () => {
const rowProperties = new TableRowProperties(); const rowProperties = new TableRowProperties();
const tree = new Formatter().format(rowProperties); // The TableRowProperties is ignorable if there are no attributes,
expect(tree).to.deep.equal({ "w:trPr": [] }); // which results in prepForXml returning undefined, which causes
// the formatter to throw an error if that is the only object it
// has been asked to format.
expect(() => new Formatter().format(rowProperties)).to.throw("XMLComponent did not format correctly");
}); });
}); });
@ -16,7 +19,7 @@ describe("TableRowProperties", () => {
const rowProperties = new TableRowProperties(); const rowProperties = new TableRowProperties();
rowProperties.setCantSplit(); rowProperties.setCantSplit();
const tree = new Formatter().format(rowProperties); const tree = new Formatter().format(rowProperties);
expect(tree).to.deep.equal({ "w:trPr": [{ "w:cantSplit": [{ _attr: { "w:val": true } }] }] }); expect(tree).to.deep.equal({ "w:trPr": [{ "w:cantSplit": { _attr: { "w:val": true } } }] });
}); });
}); });
@ -25,7 +28,7 @@ describe("TableRowProperties", () => {
const rowProperties = new TableRowProperties(); const rowProperties = new TableRowProperties();
rowProperties.setTableHeader(); rowProperties.setTableHeader();
const tree = new Formatter().format(rowProperties); const tree = new Formatter().format(rowProperties);
expect(tree).to.deep.equal({ "w:trPr": [{ "w:tblHeader": [{ _attr: { "w:val": true } }] }] }); expect(tree).to.deep.equal({ "w:trPr": [{ "w:tblHeader": { _attr: { "w:val": true } } }] });
}); });
}); });
}); });

View File

@ -1,6 +1,6 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
export class TableRowProperties extends XmlComponent { export class TableRowProperties extends IgnoreIfEmptyXmlComponent {
constructor() { constructor() {
super("w:trPr"); super("w:trPr");
} }

View File

@ -5,17 +5,15 @@ import { Formatter } from "export/formatter";
import { TableCell } from "../table-cell"; import { TableCell } from "../table-cell";
import { TableRow } from "./table-row"; import { TableRow } from "./table-row";
import { EMPTY_OBJECT } from "file/xml-components";
describe("TableRow", () => { describe("TableRow", () => {
describe("#constructor", () => { describe("#constructor", () => {
it("should create with no cells", () => { it("should create with no cells", () => {
const tableRow = new TableRow([]); const tableRow = new TableRow([]);
const tree = new Formatter().format(tableRow); const tree = new Formatter().format(tableRow);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tr": [ "w:tr": EMPTY_OBJECT,
{
"w:trPr": [],
},
],
}); });
}); });
@ -24,20 +22,10 @@ describe("TableRow", () => {
const tree = new Formatter().format(tableRow); const tree = new Formatter().format(tableRow);
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tr": [ "w:tr": [
{
"w:trPr": [],
},
{ {
"w:tc": [ "w:tc": [
{ {
"w:tcPr": [], "w:p": EMPTY_OBJECT,
},
{
"w:p": [
{
"w:pPr": [],
},
],
}, },
], ],
}, },

View File

@ -8,71 +8,63 @@ import { Table } from "./table";
// import { WidthType } from "./table-cell"; // import { WidthType } from "./table-cell";
import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType } from "./table-properties"; import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType } from "./table-properties";
import { EMPTY_OBJECT } from "file/xml-components";
const DEFAULT_TABLE_PROPERTIES = { const DEFAULT_TABLE_PROPERTIES = {
"w:tblCellMar": [ "w:tblCellMar": [
{ {
"w:bottom": [ "w:bottom": {
{ _attr: {
_attr: { "w:type": "auto",
"w:type": "auto", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
{ {
"w:top": [ "w:top": {
{ _attr: {
_attr: { "w:type": "auto",
"w:type": "auto", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
{ {
"w:left": [ "w:left": {
{ _attr: {
_attr: { "w:type": "auto",
"w:type": "auto", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
{ {
"w:right": [ "w:right": {
{ _attr: {
_attr: { "w:type": "auto",
"w:type": "auto", "w:w": 0,
"w:w": 0,
},
}, },
], },
}, },
], ],
}; };
const BORDERS = { const BORDERS = {
"w:tblBorders": [ "w:tblBorders": [
{ "w:top": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, { "w:top": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:left": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, { "w:left": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:bottom": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, { "w:bottom": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:right": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, { "w:right": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:insideH": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, { "w:insideH": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:insideV": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, { "w:insideV": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
], ],
}; };
const WIDTHS = { const WIDTHS = {
"w:tblW": [ "w:tblW": {
{ _attr: {
_attr: { "w:type": "auto",
"w:type": "auto", "w:w": 100,
"w:w": 100,
},
}, },
], },
}; };
// const f = { // const f = {
@ -81,45 +73,43 @@ const WIDTHS = {
// "w:tblPr": [ // "w:tblPr": [
// { // {
// "w:tblCellMar": [ // "w:tblCellMar": [
// { "w:bottom": [{ _attr: { "w:type": "auto", "w:w": 0 } }] }, // { "w:bottom": { _attr: { "w:type": "auto", "w:w": 0 } } },
// { "w:top": [{ _attr: { "w:type": "auto", "w:w": 0 } }] }, // { "w:top": { _attr: { "w:type": "auto", "w:w": 0 } } },
// { "w:left": [{ _attr: { "w:type": "auto", "w:w": 0 } }] }, // { "w:left": { _attr: { "w:type": "auto", "w:w": 0 } } },
// { "w:right": [{ _attr: { "w:type": "auto", "w:w": 0 } }] }, // { "w:right": { _attr: { "w:type": "auto", "w:w": 0 } } },
// ], // ],
// }, // },
// { // {
// "w:tblBorders": [ // "w:tblBorders": [
// { "w:top": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, // { "w:top": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:left": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, // { "w:left": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:bottom": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, // { "w:bottom": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:right": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, // { "w:right": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:insideH": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, // { "w:insideH": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:insideV": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] }, // { "w:insideV": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// ], // ],
// }, // },
// { "w:tblW": [{ _attr: { "w:type": "auto", "w:w": 100 } }] }, // { "w:tblW": { _attr: { "w:type": "auto", "w:w": 100 } } },
// { // {
// "w:tblpPr": [ // "w:tblpPr": {
// { // _attr: {
// _attr: { // "w:horzAnchor": "margin",
// "w:horzAnchor": "margin", // "w:vertAnchor": "page",
// "w:vertAnchor": "page", // "w:tblpX": 10,
// "w:tblpX": 10, // "w:tblpXSpec": "center",
// "w:tblpXSpec": "center", // "w:tblpY": 20,
// "w:tblpY": 20, // "w:tblpYSpec": "bottom",
// "w:tblpYSpec": "bottom", // "w:bottomFromText": 30,
// "w:bottomFromText": 30, // "w:topFromText": 40,
// "w:topFromText": 40, // "w:leftFromText": 50,
// "w:leftFromText": 50, // "w:rightFromText": 60,
// "w:rightFromText": 60,
// },
// }, // },
// ], // },
// }, // },
// ], // ],
// }, // },
// { "w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }] }, // { "w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }] },
// { "w:tr": [{ "w:trPr": [] }, { "w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }] }] }, // { "w:tr": [{ "w:tc": [{ "w:p": EMPTY_OBJECT }] }] },
// ], // ],
// }; // };
@ -131,16 +121,16 @@ describe("Table", () => {
columns: 2, columns: 2,
}); });
const tree = new Formatter().format(table); const tree = new Formatter().format(table);
const cell = { "w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }] }; const cell = { "w:tc": [{ "w:p": EMPTY_OBJECT }] };
expect(tree).to.deep.equal({ expect(tree).to.deep.equal({
"w:tbl": [ "w:tbl": [
{ "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] }, { "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] },
{ {
"w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": [{ _attr: { "w:w": 100 } }] }], "w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }, { "w:gridCol": { _attr: { "w:w": 100 } } }],
}, },
{ "w:tr": [{ "w:trPr": [] }, cell, cell] }, { "w:tr": [cell, cell] },
{ "w:tr": [{ "w:trPr": [] }, cell, cell] }, { "w:tr": [cell, cell] },
{ "w:tr": [{ "w:trPr": [] }, cell, cell] }, { "w:tr": [cell, cell] },
], ],
}); });
}); });
@ -172,9 +162,8 @@ describe("Table", () => {
const tree = new Formatter().format(table); const tree = new Formatter().format(table);
const cell = (c) => ({ const cell = (c) => ({
"w:tc": [ "w:tc": [
{ "w:tcPr": [] },
{ {
"w:p": [{ "w:pPr": [] }, { "w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }], "w:p": [{ "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }],
}, },
], ],
}); });
@ -182,10 +171,10 @@ describe("Table", () => {
"w:tbl": [ "w:tbl": [
{ "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] }, { "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] },
{ {
"w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": [{ _attr: { "w:w": 100 } }] }], "w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }, { "w:gridCol": { _attr: { "w:w": 100 } } }],
}, },
{ "w:tr": [{ "w:trPr": [] }, cell("A1"), cell("B1")] }, { "w:tr": [cell("A1"), cell("B1")] },
{ "w:tr": [{ "w:trPr": [] }, cell("A2"), cell("B2")] }, { "w:tr": [cell("A2"), cell("B2")] },
], ],
}); });
}); });
@ -222,9 +211,8 @@ describe("Table", () => {
const tree = new Formatter().format(table); const tree = new Formatter().format(table);
const cell = (c) => ({ const cell = (c) => ({
"w:tc": [ "w:tc": [
{ "w:tcPr": [] },
{ {
"w:p": [{ "w:pPr": [] }, { "w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }], "w:p": [{ "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }],
}, },
], ],
}); });
@ -232,10 +220,10 @@ describe("Table", () => {
"w:tbl": [ "w:tbl": [
{ "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] }, { "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] },
{ {
"w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": [{ _attr: { "w:w": 100 } }] }], "w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }, { "w:gridCol": { _attr: { "w:w": 100 } } }],
}, },
{ "w:tr": [{ "w:trPr": [] }, cell("A1"), cell("B1")] }, { "w:tr": [cell("A1"), cell("B1")] },
{ "w:tr": [{ "w:trPr": [] }, cell("A2"), cell("B2")] }, { "w:tr": [cell("A2"), cell("B2")] },
], ],
}); });
}); });
@ -250,7 +238,7 @@ describe("Table", () => {
// .which.is.an("array") // .which.is.an("array")
// .with.has.length.at.least(1); // .with.has.length.at.least(1);
// expect(tree["w:tbl"][0]).to.deep.equal({ // expect(tree["w:tbl"][0]).to.deep.equal({
// "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": [{ _attr: { "w:type": "pct", "w:w": "1000%" } }] }], // "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": { _attr: { "w:type": "pct", "w:w": "1000%" } } }],
// }); // });
// }); // });
@ -259,7 +247,7 @@ describe("Table", () => {
// const tree = new Formatter().format(table); // const tree = new Formatter().format(table);
// expect(tree["w:tbl"][0]).to.deep.equal({ // expect(tree["w:tbl"][0]).to.deep.equal({
// "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": [{ _attr: { "w:type": "auto", "w:w": 1000 } }] }], // "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": { _attr: { "w:type": "auto", "w:w": 1000 } } }],
// }); // });
// }); // });
// }); // });
@ -276,7 +264,7 @@ describe("Table", () => {
.which.is.an("array") .which.is.an("array")
.with.has.length.at.least(1); .with.has.length.at.least(1);
expect(tree["w:tbl"][0]).to.deep.equal({ expect(tree["w:tbl"][0]).to.deep.equal({
"w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS, { "w:tblLayout": [{ _attr: { "w:type": "fixed" } }] }], "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS, { "w:tblLayout": { _attr: { "w:type": "fixed" } } }],
}); });
}); });
}); });
@ -298,7 +286,7 @@ describe("Table", () => {
.to.be.an("array") .to.be.an("array")
.which.has.length.at.least(1); .which.has.length.at.least(1);
expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({ expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({
"w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }], "w:tc": [{ "w:p": EMPTY_OBJECT }],
}); });
}); });
@ -325,7 +313,7 @@ describe("Table", () => {
const cell = row["w:tr"].find((x) => x["w:tc"]); const cell = row["w:tr"].find((x) => x["w:tc"]);
expect(cell).not.to.be.undefined; expect(cell).not.to.be.undefined;
expect(cell["w:tc"][cell["w:tc"].length - 1]).to.deep.equal({ expect(cell["w:tc"][cell["w:tc"].length - 1]).to.deep.equal({
"w:p": [{ "w:pPr": [] }], "w:p": EMPTY_OBJECT,
}); });
}); });
@ -346,12 +334,8 @@ describe("Table", () => {
.which.has.length.at.least(1); .which.has.length.at.least(1);
expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({ expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({
"w:tc": [ "w:tc": [
{ "w:tcPr": [] },
{ {
"w:p": [ "w:p": [{ "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "Hello"] }] }],
{ "w:pPr": [] },
{ "w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "Hello"] }] },
],
}, },
], ],
}); });
@ -377,12 +361,10 @@ describe("Table", () => {
.which.has.length.at.least(1); .which.has.length.at.least(1);
expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({ expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({
"w:tc": [ "w:tc": [
{ "w:tcPr": [] },
{ {
"w:p": [ "w:p": [
{ "w:pPr": [] },
{ {
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "Test paragraph"] }], "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "Test paragraph"] }],
}, },
], ],
}, },
@ -421,22 +403,20 @@ describe("Table", () => {
BORDERS, BORDERS,
WIDTHS, WIDTHS,
{ {
"w:tblpPr": [ "w:tblpPr": {
{ _attr: {
_attr: { "w:horzAnchor": "margin",
"w:horzAnchor": "margin", "w:vertAnchor": "page",
"w:vertAnchor": "page", "w:tblpX": 10,
"w:tblpX": 10, "w:tblpXSpec": "center",
"w:tblpXSpec": "center", "w:tblpY": 20,
"w:tblpY": 20, "w:tblpYSpec": "bottom",
"w:tblpYSpec": "bottom", "w:bottomFromText": 30,
"w:bottomFromText": 30, "w:topFromText": 40,
"w:topFromText": 40, "w:leftFromText": 50,
"w:leftFromText": 50, "w:rightFromText": 60,
"w:rightFromText": 60,
},
}, },
], },
}, },
], ],
}); });

View File

@ -6,7 +6,7 @@ export type AttributeMap<T> = { [P in keyof T]: string };
export abstract class XmlAttributeComponent<T> extends BaseXmlComponent { export abstract class XmlAttributeComponent<T> extends BaseXmlComponent {
// tslint:disable-next-line:readonly-keyword // tslint:disable-next-line:readonly-keyword
protected root: T; protected root: T;
protected readonly xmlKeys: AttributeMap<T>; protected readonly xmlKeys?: AttributeMap<T>;
constructor(properties: T) { constructor(properties: T) {
super("_attr"); super("_attr");
@ -18,7 +18,7 @@ export abstract class XmlAttributeComponent<T> extends BaseXmlComponent {
Object.keys(this.root).forEach((key) => { Object.keys(this.root).forEach((key) => {
const value = this.root[key]; const value = this.root[key];
if (value !== undefined) { if (value !== undefined) {
const newKey = this.xmlKeys[key]; const newKey = (this.xmlKeys && this.xmlKeys[key]) || key;
attrs[newKey] = value; attrs[newKey] = value;
} }
}); });

View File

@ -1,7 +1,7 @@
import { expect } from "chai"; import { expect } from "chai";
import { Element, xml2js } from "xml-js"; import { Element, xml2js } from "xml-js";
import { ImportedXmlComponent } from "./"; import { EMPTY_OBJECT, ImportedXmlComponent } from "./";
import { convertToXmlComponent } from "./imported-xml-component"; import { convertToXmlComponent } from "./imported-xml-component";
const xmlString = ` const xmlString = `
@ -25,11 +25,25 @@ const convertedXmlElement = {
deleted: false, deleted: false,
rootKey: "w:p", rootKey: "w:p",
root: [ root: [
{ deleted: false, rootKey: "_attr", root: { "w:one": "value 1", "w:two": "value 2" } },
{ deleted: false, rootKey: "w:rPr", root: [{ deleted: false, rootKey: "w:noProof", root: ["some value"] }] }, { deleted: false, rootKey: "w:rPr", root: [{ deleted: false, rootKey: "w:noProof", root: ["some value"] }] },
{ deleted: false, rootKey: "w:r", root: [{ deleted: false, rootKey: "w:t", root: ["Text 1"] }], _attr: { active: "true" } }, {
{ deleted: false, rootKey: "w:r", root: [{ deleted: false, rootKey: "w:t", root: ["Text 2"] }], _attr: { active: "true" } }, deleted: false,
rootKey: "w:r",
root: [
{ deleted: false, rootKey: "_attr", root: { active: "true" } },
{ deleted: false, rootKey: "w:t", root: ["Text 1"] },
],
},
{
deleted: false,
rootKey: "w:r",
root: [
{ deleted: false, rootKey: "_attr", root: { active: "true" } },
{ deleted: false, rootKey: "w:t", root: ["Text 2"] },
],
},
], ],
_attr: { "w:one": "value 1", "w:two": "value 2" },
}, },
], ],
rootKey: undefined, rootKey: undefined,
@ -59,7 +73,7 @@ describe("ImportedXmlComponent", () => {
}, },
}, },
{ {
"w:child": [], "w:child": EMPTY_OBJECT,
}, },
], ],
}); });

View File

@ -1,6 +1,6 @@
// 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, XmlComponent } from "."; import { IXmlableObject, XmlAttributeComponent, XmlComponent } from ".";
/** /**
* Converts the given xml element (in json format) into XmlComponent. * Converts the given xml element (in json format) into XmlComponent.
@ -27,6 +27,10 @@ export function convertToXmlComponent(element: XmlElement): ImportedXmlComponent
} }
} }
class ImportedXmlComponentAttributes extends XmlAttributeComponent<any> {
// noop
}
/** /**
* Represents imported xml component from xml file. * Represents imported xml component from xml file.
*/ */
@ -46,58 +50,14 @@ export class ImportedXmlComponent extends XmlComponent {
* @param importedContent xml content of the imported component * @param importedContent xml content of the imported component
*/ */
// tslint:disable-next-line:variable-name
private readonly _attr: any;
// tslint:disable-next-line:variable-name // tslint:disable-next-line:variable-name
constructor(rootKey: string, _attr?: any) { constructor(rootKey: string, _attr?: any) {
super(rootKey); super(rootKey);
if (_attr) { if (_attr) {
this._attr = _attr; this.root.push(new ImportedXmlComponentAttributes(_attr));
} }
} }
/**
* Transforms the object so it can be converted to xml. Example:
* <w:someKey someAttr="1" otherAttr="11">
* <w:child childAttr="2">
* </w:child>
* </w:someKey>
* {
* 'w:someKey': [
* {
* _attr: {
* someAttr: "1",
* otherAttr: "11"
* }
* },
* {
* 'w:child': [
* {
* _attr: {
* childAttr: "2"
* }
* }
* ]
* }
* ]
* }
*/
public prepForXml(): IXmlableObject | undefined {
const result = super.prepForXml();
if (!result) {
return undefined;
}
if (!!this._attr) {
if (!Array.isArray(result[this.rootKey])) {
result[this.rootKey] = [result[this.rootKey]];
}
result[this.rootKey].unshift({ _attr: this._attr });
}
return result;
}
public push(xmlComponent: XmlComponent | string): void { public push(xmlComponent: XmlComponent | string): void {
this.root.push(xmlComponent); this.root.push(xmlComponent);
} }

View File

@ -1,7 +1,7 @@
import { assert } from "chai"; import { expect } from "chai";
import { Utility } from "tests/utility"; import { Utility } from "tests/utility";
import { XmlComponent } from "./"; import { EMPTY_OBJECT, XmlComponent } from "./";
class TestComponent extends XmlComponent {} class TestComponent extends XmlComponent {}
@ -15,7 +15,7 @@ describe("XmlComponent", () => {
describe("#constructor()", () => { describe("#constructor()", () => {
it("should create an Xml Component which has the correct rootKey", () => { it("should create an Xml Component which has the correct rootKey", () => {
const newJson = Utility.jsonify(xmlComponent); const newJson = Utility.jsonify(xmlComponent);
assert.equal(newJson.rootKey, "w:test"); expect(newJson.rootKey).to.equal("w:test");
}); });
}); });
@ -31,7 +31,7 @@ describe("XmlComponent", () => {
return; return;
} }
assert.equal(xml["w:test"].length, 0); expect(xml["w:test"]).to.deep.equal(EMPTY_OBJECT);
}); });
}); });
}); });

View File

@ -2,6 +2,8 @@ import { BaseXmlComponent } from "./base";
import { IXmlableObject } from "./xmlable-object"; import { IXmlableObject } from "./xmlable-object";
export { BaseXmlComponent }; export { BaseXmlComponent };
export const EMPTY_OBJECT = Object.seal({});
export abstract class XmlComponent extends BaseXmlComponent { export abstract class XmlComponent extends BaseXmlComponent {
// tslint:disable-next-line:readonly-keyword // tslint:disable-next-line:readonly-keyword
protected root: Array<BaseXmlComponent | string>; protected root: Array<BaseXmlComponent | string>;
@ -17,7 +19,7 @@ export abstract class XmlComponent extends BaseXmlComponent {
if (c instanceof BaseXmlComponent) { if (c instanceof BaseXmlComponent) {
return !c.IsDeleted; return !c.IsDeleted;
} }
return true; return c !== undefined;
}) })
.map((comp) => { .map((comp) => {
if (comp instanceof BaseXmlComponent) { if (comp instanceof BaseXmlComponent) {
@ -26,8 +28,15 @@ export abstract class XmlComponent extends BaseXmlComponent {
return comp; return comp;
}) })
.filter((comp) => comp !== undefined); // Exclude undefined .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;
return { return {
[this.rootKey]: children, [this.rootKey]: children.length ? (children.length === 1 && onlyAttrs(children[0]) ? children[0] : children) : EMPTY_OBJECT,
}; };
} }
@ -41,3 +50,14 @@ export abstract class XmlComponent extends BaseXmlComponent {
this.deleted = true; this.deleted = true;
} }
} }
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;
}
}
}