From 09db2c528a15a5442967e7633cfd2fd7b425f7c5 Mon Sep 17 00:00:00 2001 From: Thomas Jansen Date: Thu, 24 Sep 2020 10:24:00 +0200 Subject: [PATCH] added InsertedTextRun and DeletedTextRun for Revision Tracking --- src/file/index.ts | 1 + src/file/paragraph/paragraph.ts | 3 + src/file/track-revision/index.ts | 1 + .../track-revision/track-revision.spec.ts | 81 +++++++++++++++++++ src/file/track-revision/track-revision.ts | 72 +++++++++++++++++ 5 files changed, 158 insertions(+) create mode 100644 src/file/track-revision/index.ts create mode 100644 src/file/track-revision/track-revision.spec.ts create mode 100644 src/file/track-revision/track-revision.ts diff --git a/src/file/index.ts b/src/file/index.ts index c4ce99e345..62e7e647ac 100644 --- a/src/file/index.ts +++ b/src/file/index.ts @@ -13,3 +13,4 @@ export * from "./header-wrapper"; export * from "./footer-wrapper"; export * from "./header"; export * from "./footnotes"; +export * from "./track-revision" diff --git a/src/file/paragraph/paragraph.ts b/src/file/paragraph/paragraph.ts index e1db0ec910..856c34aacf 100644 --- a/src/file/paragraph/paragraph.ts +++ b/src/file/paragraph/paragraph.ts @@ -3,6 +3,7 @@ import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run" import { IXmlableObject, XmlComponent } from "file/xml-components"; import { File } from "../file"; +import { InsertedTextRun, DeletedTextRun } from "../track-revision"; import { PageBreak } from "./formatting/page-break"; import { Bookmark, HyperlinkRef } from "./links"; import { IParagraphPropertiesOptions, ParagraphProperties } from "./properties"; @@ -19,6 +20,8 @@ export interface IParagraphOptions extends IParagraphPropertiesOptions { | SequentialIdentifier | FootnoteReferenceRun | HyperlinkRef + | InsertedTextRun + | DeletedTextRun )[]; } diff --git a/src/file/track-revision/index.ts b/src/file/track-revision/index.ts new file mode 100644 index 0000000000..20bb87a229 --- /dev/null +++ b/src/file/track-revision/index.ts @@ -0,0 +1 @@ +export * from "./track-revision"; diff --git a/src/file/track-revision/track-revision.spec.ts b/src/file/track-revision/track-revision.spec.ts new file mode 100644 index 0000000000..faa4d5a565 --- /dev/null +++ b/src/file/track-revision/track-revision.spec.ts @@ -0,0 +1,81 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { InsertedTextRun, DeletedTextRun } from "./track-revision"; +import { TextRun } from "../paragraph"; + +describe("InsertedTestRun", () => { + describe("#constructor", () => { + it("should create a inserted text run", () => { + const textRun = new TextRun({ + text: "some text" + }); + const insertedTextRun = new InsertedTextRun({ child: textRun, id: 0, date: "123", author: "Author" }) + const tree = new Formatter().format(insertedTextRun); + expect(tree).to.deep.equal({ + "w:ins": [ + { + "_attr": + { + "w:author": "Author", + "w:date": "123", + "w:id": 0 + } + }, + { + "w:r": [ + { + "w:t": [ + { + "_attr": + { + "xml:space": "preserve" + } + }, + "some text" + ] + } + ], + } + ] + }); + }); + }); +}); +describe("DeletedTestRun", () => { + describe("#constructor", () => { + it("should create a deleted text run", () => { + + const insertedParagraph = new DeletedTextRun({ text: 'some text', id: 0, date: "123", author: "Author" }) + const tree = new Formatter().format(insertedParagraph); + expect(tree).to.deep.equal({ + "w:del": [ + { + "_attr": + { + "w:author": "Author", + "w:date": "123", + "w:id": 0 + } + }, + { + "w:r": [ + { + "w:delText": [ + { + "_attr": + { + "xml:space": "preserve" + } + }, + "some text" + ] + } + ], + } + ] + }); + }); + }); +}); diff --git a/src/file/track-revision/track-revision.ts b/src/file/track-revision/track-revision.ts new file mode 100644 index 0000000000..1af9e7dba3 --- /dev/null +++ b/src/file/track-revision/track-revision.ts @@ -0,0 +1,72 @@ +import { SpaceType } from "file/space-type"; +import { XmlComponent, XmlAttributeComponent } from "file/xml-components"; +import { TextRun } from "../index"; + +export interface ITrackRevisionAttributesProperties { + readonly id: number; + readonly author: string; + readonly date: string; +} + +export class TrackRevisionAttributes extends XmlAttributeComponent { + protected readonly xmlKeys = { + id: "w:id", + author: "w:author", + date: "w:date", + }; +} + +export interface IInsertedTextRunOptions extends ITrackRevisionAttributesProperties { + readonly child: TextRun +} + +export interface IDeletedTextRunOptions extends ITrackRevisionAttributesProperties { + readonly text: string +} + +export class InsertedTextRun extends XmlComponent { + constructor(options: IInsertedTextRunOptions) { + super("w:ins"); + this.root.push( + new TrackRevisionAttributes({ + id: options.id, + author: options.author, + date: options.date, + }) + ); + this.addChildElement(options.child); + } +} + +export class DeletedTextRunWrapper extends XmlComponent { + constructor(text: string) { + super("w:r"); + this.root.push(new DeletedText(text)); + } +} + +class TextAttributes extends XmlAttributeComponent<{ readonly space: SpaceType }> { + protected readonly xmlKeys = { space: "xml:space" }; +} + +export class DeletedText extends XmlComponent { + constructor(text: string) { + super("w:delText"); + this.root.push(new TextAttributes({ space: SpaceType.PRESERVE })); + this.root.push(text); + } +} + +export class DeletedTextRun extends XmlComponent { + constructor(options: IDeletedTextRunOptions) { + super("w:del"); + this.root.push( + new TrackRevisionAttributes({ + id: options.id, + author: options.author, + date: options.date, + }) + ); + this.addChildElement(new DeletedTextRunWrapper(options.text)); + } +}