Fix some linting errors

This commit is contained in:
Dolan
2018-09-06 08:30:23 +01:00
parent 1a3603dbfb
commit 4994bca34c
10 changed files with 136 additions and 137 deletions

View File

@ -53,17 +53,18 @@ export class Compiler {
}
}
for (const data of file.Media.Array) {
const mediaData = data.stream;
zip.file(`word/media/${data.fileName}`, mediaData);
}
for (let header of file.Headers) {
for (const header of file.Headers) {
for (const data of header.media.Array) {
zip.file(`word/media/${data.fileName}`, data.stream);
}
}
for (let footer of file.Footers) {
for (const footer of file.Footers) {
for (const data of footer.media.Array) {
zip.file(`word/media/${data.fileName}`, data.stream);
}
@ -134,12 +135,12 @@ 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 */
collapseEmptyTags(xmlData : string) : string {
const regEx = /<(([^ <>]+)[^<>]*)><\/\2>/g;
let collapsed = xmlData.replace(regEx, '<$1/>');
return collapsed;
}
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

@ -1,9 +1,8 @@
import { XmlComponent } from "file/xml-components";
import { ITemplateDocument } from "importDocx/importDocx";
import { DocumentAttributes } from "../document/document-attributes";
import { Created, Creator, Description, Keywords, LastModifiedBy, Modified, Revision, Subject, Title } from "./components";
import { TemplateDocument } from 'importDocx/importDocx'
export interface IPropertiesOptions {
title?: string;
subject?: string;
@ -14,7 +13,7 @@ export interface IPropertiesOptions {
revision?: string;
externalStyles?: string;
templateDocument? : TemplateDocument;
templateDocument?: ITemplateDocument;
}
export class CoreProperties extends XmlComponent {

View File

@ -1,7 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../../export/formatter";
import { PageBorderOffsetFrom, PageNumberFormat, FooterReferenceType, HeaderReferenceType } from "./";
import { FooterReferenceType, HeaderReferenceType, PageBorderOffsetFrom, PageNumberFormat } from "./";
import { SectionProperties } from "./section-properties";
describe("SectionProperties", () => {

View File

@ -93,7 +93,7 @@ export class File {
if (!templateHeaders) {
this.createHeader();
} else {
for (let templateHeader of templateHeaders) {
for (const templateHeader of templateHeaders) {
this.addHeaderToDocument(templateHeader.header, templateHeader.type);
}
}
@ -102,7 +102,7 @@ export class File {
if (!templateFooters) {
this.createFooter();
} else {
for (let templateFooter of templateFooters) {
for (const templateFooter of templateFooters) {
this.addFooterToDocument(templateFooter.footer, templateFooter.type);
}
}
@ -127,16 +127,16 @@ export class File {
this.footNotes = new FootNotes();
let headersOptions: IHeaderOptions[] = [];
for (let documentHeader of this.documentHeaders) {
const headersOptions: IHeaderOptions[] = [];
for (const documentHeader of this.documentHeaders) {
headersOptions.push({
headerId: documentHeader.header.Header.ReferenceId,
headerType: documentHeader.type,
});
}
let footersOptions: IFooterOptions[] = [];
for (let documentFooter of this.documentFooters) {
const footersOptions: IFooterOptions[] = [];
for (const documentFooter of this.documentFooters) {
footersOptions.push({
footerId: documentFooter.footer.Footer.ReferenceId,
footerType: documentFooter.type,
@ -148,8 +148,7 @@ export class File {
headers: headersOptions,
footers: footersOptions,
};
}
else {
} else {
sectionPropertiesOptions.headers = headersOptions;
sectionPropertiesOptions.footers = footersOptions;
}
@ -225,7 +224,7 @@ export class File {
return header;
}
private addHeaderToDocument(header: HeaderWrapper, type: HeaderReferenceType = HeaderReferenceType.DEFAULT) {
private addHeaderToDocument(header: HeaderWrapper, type: HeaderReferenceType = HeaderReferenceType.DEFAULT): void {
this.documentHeaders.push({ header, type });
this.docRelationships.createRelationship(
header.Header.ReferenceId,
@ -241,7 +240,7 @@ export class File {
return footer;
}
private addFooterToDocument(footer: FooterWrapper, type: FooterReferenceType = FooterReferenceType.DEFAULT) {
private addFooterToDocument(footer: FooterWrapper, type: FooterReferenceType = FooterReferenceType.DEFAULT): void {
this.documentFooters.push({ footer, type });
this.docRelationships.createRelationship(
footer.Footer.ReferenceId,

View File

@ -1,11 +1,10 @@
import { IMediaData } from "file/media";
import { XmlComponent } from "file/xml-components";
import { Header } from "./header/header";
import { Image, Media } from "./media";
import { ImageParagraph, Paragraph } from "./paragraph";
import { Relationships } from "./relationships";
import { Table } from "./table";
import { IMediaData } from 'file/media';
export class HeaderWrapper {
private readonly header: Header;
@ -51,7 +50,7 @@ export class HeaderWrapper {
}
public createImage(image: Buffer, width?: number, height?: number): void {
let mediaData = this.addImageRelation(image, this.relationships.RelationshipCount, width, height);
const mediaData = this.addImageRelation(image, this.relationships.RelationshipCount, width, height);
this.addImage(new Image(new ImageParagraph(mediaData)));
}

View File

@ -40,7 +40,7 @@ export class Header extends XmlComponent {
cx7: "http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",
cx8: "http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",
w16cid: "http://schemas.microsoft.com/office/word/2016/wordml/cid",
w16se: "http://schemas.microsoft.com/office/word/2015/wordml/symex"
w16se: "http://schemas.microsoft.com/office/word/2015/wordml/symex",
}),
);
}

View File

@ -1,152 +1,154 @@
import * as JSZip from "jszip";
import * as fastXmlParser from "fast-xml-parser";
import { convertToXmlComponent, parseOptions, ImportedXmlComponent } from "file/xml-components";
import { HeaderWrapper } from 'file/header-wrapper';
import { FooterWrapper } from 'file/footer-wrapper';
import { HeaderReferenceType } from 'file/document/body/section-properties/header-reference';
import { FooterReferenceType } from 'file/document/body/section-properties/footer-reference';
// import { RelationshipType } from 'file/relationships/relationship/relationship';
import * as JSZip from "jszip";
import { FooterReferenceType } from "file/document/body/section-properties/footer-reference";
import { HeaderReferenceType } from "file/document/body/section-properties/header-reference";
import { FooterWrapper } from "file/footer-wrapper";
import { HeaderWrapper } from "file/header-wrapper";
import { convertToXmlComponent, ImportedXmlComponent, parseOptions } from "file/xml-components";
const schemeToType = {
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" : 'header',
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" : 'footer',
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" : 'image',
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header": "header",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer": "footer",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image": "image",
};
interface IDocumentRefs {
headers: Array<{ id: number; type: HeaderReferenceType }>;
footers: Array<{ id: number; type: FooterReferenceType }>;
}
interface DocumentRefs {
headers : {id : number, type: HeaderReferenceType}[],
footers : {id : number, type: FooterReferenceType}[]
interface IRelationFileInfo {
id: number;
targetFile: string;
type: "header" | "footer" | "image";
}
type RelationFileInfo = {id : number, targetFile: string, type: 'header' | 'footer' | 'image'};
type DocumentHeaders = Array<{ type: HeaderReferenceType; header: HeaderWrapper }>;
type DocumentFooters = Array<{ type: FooterReferenceType; footer: FooterWrapper }>;
type DocumentHeaders = {type : HeaderReferenceType, header : HeaderWrapper}[];
type DocumentFooters = {type : FooterReferenceType, footer : FooterWrapper}[];
export interface TemplateDocument {
export interface ITemplateDocument {
currentRelationshipId: number;
headers : DocumentHeaders,
footers : DocumentFooters,
headers: DocumentHeaders;
footers: DocumentFooters;
}
export class ImportDocx {
private currentRelationshipId: number = 1;
private currentRelationshipId: number;
constructor() {
this.currentRelationshipId = 1;
}
public async extract(data: Buffer): Promise<ITemplateDocument> {
const zipContent = await JSZip.loadAsync(data);
const documentContent = zipContent.files["word/document.xml"];
const documentRefs: IDocumentRefs = this.extractDocumentRefs(await documentContent.async("text"));
async extract(data : Buffer) : Promise<TemplateDocument> {
let zipContent = await JSZip.loadAsync(data);
const relationshipContent = zipContent.files["word/_rels/document.xml.rels"];
const documentRelations: IRelationFileInfo[] = this.findReferenceFiles(await relationshipContent.async("text"));
let documentContent = zipContent['files']['word/document.xml'];
const documentRefs : DocumentRefs = this.extractDocumentRefs(await documentContent.async('text'))
let relationshipContent = zipContent['files']['word/_rels/document.xml.rels'];
const documentRelations : RelationFileInfo[] = this.findReferenceFiles(await relationshipContent.async('text'));
let headers : DocumentHeaders = [];
for(let headerRef of documentRefs.headers) {
const headerKey = 'w:hdr';
const relationFileInfo = documentRelations.find(rel => rel.id === headerRef.id);
if (relationFileInfo == null) {
throw `can not find target file for id ${headerRef.id}`;
const headers: DocumentHeaders = [];
for (const headerRef of documentRefs.headers) {
const headerKey = "w:hdr";
const relationFileInfo = documentRelations.find((rel) => rel.id === headerRef.id);
if (relationFileInfo === null || !relationFileInfo) {
throw new Error(`Can not find target file for id ${headerRef.id}`);
}
const xmlData = await zipContent['files'][`word/${relationFileInfo.targetFile}`].async('text');
const xmlData = await zipContent.files[`word/${relationFileInfo.targetFile}`].async("text");
const xmlObj = fastXmlParser.parse(xmlData, parseOptions);
let importedComp = convertToXmlComponent(headerKey, xmlObj[headerKey]) as ImportedXmlComponent;
const importedComp = convertToXmlComponent(headerKey, xmlObj[headerKey]) as ImportedXmlComponent;
let header = new HeaderWrapper(this.currentRelationshipId++, importedComp);
const header = new HeaderWrapper(this.currentRelationshipId++, importedComp);
await this.addImagesToWrapper(relationFileInfo, zipContent, header);
headers.push({type : headerRef.type, header})
headers.push({ type: headerRef.type, header });
}
let footers : DocumentFooters = [];
for(let footerRef of documentRefs.footers) {
const footerKey = 'w:ftr'
const relationFileInfo = documentRelations.find(rel => rel.id === footerRef.id);
if (relationFileInfo == null) {
throw `can not find target file for id ${footerRef.id}`;
const footers: DocumentFooters = [];
for (const footerRef of documentRefs.footers) {
const footerKey = "w:ftr";
const relationFileInfo = documentRelations.find((rel) => rel.id === footerRef.id);
if (relationFileInfo === null || !relationFileInfo) {
throw new Error(`Can not find target file for id ${footerRef.id}`);
}
const xmlData = await zipContent['files'][`word/${relationFileInfo.targetFile}`].async('text');
const xmlData = await zipContent.files[`word/${relationFileInfo.targetFile}`].async("text");
const xmlObj = fastXmlParser.parse(xmlData, parseOptions);
let importedComp = convertToXmlComponent(footerKey, xmlObj[footerKey]) as ImportedXmlComponent;
const importedComp = convertToXmlComponent(footerKey, xmlObj[footerKey]) as ImportedXmlComponent;
let footer = new FooterWrapper(this.currentRelationshipId++, importedComp);
const footer = new FooterWrapper(this.currentRelationshipId++, importedComp);
await this.addImagesToWrapper(relationFileInfo, zipContent, footer);
footers.push({type : footerRef.type, footer})
footers.push({ type: footerRef.type, footer });
}
let templateDocument : TemplateDocument = {headers, footers, currentRelationshipId : this.currentRelationshipId}
const templateDocument: ITemplateDocument = { headers, footers, currentRelationshipId: this.currentRelationshipId };
return templateDocument;
}
async addImagesToWrapper(relationFile : RelationFileInfo, zipContent, wrapper : HeaderWrapper | FooterWrapper) {
let wrapperImagesReferences : RelationFileInfo[] = [];
const refFile = zipContent['files'][`word/_rels/${relationFile.targetFile}.rels`];
public async addImagesToWrapper(relationFile: IRelationFileInfo, zipContent: JSZip, wrapper: HeaderWrapper | FooterWrapper): Promise<void> {
let wrapperImagesReferences: IRelationFileInfo[] = [];
const refFile = zipContent.files[`word/_rels/${relationFile.targetFile}.rels`];
if (refFile) {
const xmlRef = await refFile.async('text');
wrapperImagesReferences = this.findReferenceFiles(xmlRef).filter(r => r.type === 'image');
const xmlRef = await refFile.async("text");
wrapperImagesReferences = this.findReferenceFiles(xmlRef).filter((r) => r.type === "image");
}
for (let r of wrapperImagesReferences) {
const buffer = await zipContent['files'][`word/${r.targetFile}`].async('nodebuffer');
for (const r of wrapperImagesReferences) {
const buffer = await zipContent.files[`word/${r.targetFile}`].async("nodebuffer");
wrapper.addImageRelation(buffer, r.id);
}
}
findReferenceFiles(xmlData : string) : RelationFileInfo[] {
public findReferenceFiles(xmlData: string): IRelationFileInfo[] {
const xmlObj = fastXmlParser.parse(xmlData, parseOptions);
const relationXmlArray = Array.isArray(xmlObj['Relationships']['Relationship']) ? xmlObj['Relationships']['Relationship'] : [xmlObj['Relationships']['Relationship']];
const relations : RelationFileInfo[] = relationXmlArray
.map(item => {
const relationXmlArray = Array.isArray(xmlObj.Relationships.Relationship)
? xmlObj.Relationships.Relationship
: [xmlObj.Relationships.Relationship];
const relations: IRelationFileInfo[] = relationXmlArray
.map((item) => {
return {
id : this.parseRefId(item['_attr']['Id']),
type : schemeToType[item['_attr']['Type']],
targetFile : item['_attr']['Target']
}
id: this.parseRefId(item._attr.Id),
type: schemeToType[item._attr.Type],
targetFile: item._attr.Target,
};
})
.filter(item => item.type != null)
.filter((item) => item.type !== null);
return relations;
}
extractDocumentRefs(xmlData : string) : DocumentRefs {
public extractDocumentRefs(xmlData: string): IDocumentRefs {
const xmlObj = fastXmlParser.parse(xmlData, parseOptions);
const sectionProp = xmlObj['w:document']['w:body']['w:sectPr'];
const sectionProp = xmlObj["w:document"]["w:body"]["w:sectPr"];
const headersXmlArray = Array.isArray(sectionProp['w:headerReference']) ? sectionProp['w:headerReference'] : [sectionProp['w:headerReference']];
const headers = headersXmlArray
.map(item => {
const headersXmlArray = Array.isArray(sectionProp["w:headerReference"])
? sectionProp["w:headerReference"]
: [sectionProp["w:headerReference"]];
const headers = headersXmlArray.map((item) => {
return {
type : item['_attr']['w:type'],
id : this.parseRefId(item['_attr']['r:id'])
}
type: item._attr["w:type"],
id: this.parseRefId(item._attr["r:id"]),
};
});
const footersXmlArray = Array.isArray(sectionProp['w:footerReference']) ? sectionProp['w:footerReference'] : [sectionProp['w:footerReference']];
const footers = footersXmlArray
.map(item => {
const footersXmlArray = Array.isArray(sectionProp["w:footerReference"])
? sectionProp["w:footerReference"]
: [sectionProp["w:footerReference"]];
const footers = footersXmlArray.map((item) => {
return {
type : item['_attr']['w:type'],
id : this.parseRefId(item['_attr']['r:id'])
}
type: item._attr["w:type"],
id: this.parseRefId(item._attr["r:id"]),
};
});
return {headers, footers}
return { headers, footers };
}
parseRefId(str : string) : number {
let match = /^rId(\d+)$/.exec(str);
if (match == null) {
throw 'invalid ref id';
public parseRefId(str: string): number {
const match = /^rId(\d+)$/.exec(str);
if (match === null) {
throw new Error("Invalid ref id");
}
return parseInt(match[1]);
return parseInt(match[1], 10);
}
}

View File

@ -1 +1 @@
export * from './importDocx';
export * from "./importDocx";

View File

@ -4,4 +4,3 @@ export { File as Document } from "./file";
export * from "./file";
export * from "./export";
export * from "./importDocx";