diff --git a/demo/60-track-revisions.ts b/demo/60-track-revisions.ts index ced597806c..232b74f691 100644 --- a/demo/60-track-revisions.ts +++ b/demo/60-track-revisions.ts @@ -113,6 +113,16 @@ const doc = new Document({ bold: true, children: ["\tuse Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)], }), + new TextRun({ + bold: true, + text: "And some style changes", + revision: { + id: 4, + author: "Firstname Lastname", + date: "2020-10-06T09:05:00Z", + bold: false, + } + }), ], }), ], diff --git a/docs/usage/change-tracking.md b/docs/usage/change-tracking.md index 96d10799ca..977c69894d 100644 --- a/docs/usage/change-tracking.md +++ b/docs/usage/change-tracking.md @@ -53,9 +53,21 @@ In addition to marking text as inserted or deleted, change tracking can also be ```ts import { Document } from "docx"; -const doc = new Document({ - features: { - trackRevisions: true, - }, -}); +const doc = new Document({}); +doc.Settings.addTrackRevisions() ``` + +If you want to express a style changes, you can add a `revision` to a `TextRun` which need to include all previous style attributes. + +```ts +new TextRun({ + bold: true, + text: "This text is now bold and was previously not", + revision: { + id: 1, + author: "Firstname Lastname", + date: "2020-10-06T09:05:00Z", + bold: false, + } +}).break() +```` diff --git a/src/file/paragraph/run/properties.ts b/src/file/paragraph/run/properties.ts index 3c47099b85..7b5d2418cd 100644 --- a/src/file/paragraph/run/properties.ts +++ b/src/file/paragraph/run/properties.ts @@ -1,3 +1,5 @@ +import { ChangeAttributes, IChangedAttributesProperties } from "../../track-revision/track-revision"; + import { IShadingAttributesProperties, Shading } from "file/shading"; import { HpsMeasureElement, IgnoreIfEmptyXmlComponent, OnOffElement, StringValueElement, XmlComponent } from "file/xml-components"; import { EmphasisMark, EmphasisMarkType } from "./emphasis-mark"; @@ -40,12 +42,15 @@ export interface IRunStylePropertiesOptions { readonly shading?: IShadingAttributesProperties; readonly emboss?: boolean; readonly imprint?: boolean; + readonly revision?: IRunPropertiesChangeOptions; } export interface IRunPropertiesOptions extends IRunStylePropertiesOptions { readonly style?: string; } +export interface IRunPropertiesChangeOptions extends IRunPropertiesOptions, IChangedAttributesProperties {} + // // // @@ -200,9 +205,27 @@ export class RunProperties extends IgnoreIfEmptyXmlComponent { if (options.shading) { this.push(new Shading(options.shading)); } + + if (options.revision) { + this.push(new RunPropertiesChange(options.revision)); + } } public push(item: XmlComponent): void { this.root.push(item); } } + +export class RunPropertiesChange extends XmlComponent { + constructor(options: IRunPropertiesChangeOptions) { + super("w:rPrChange"); + this.root.push( + new ChangeAttributes({ + id: options.id, + author: options.author, + date: options.date, + }), + ); + this.addChildElement(new RunProperties(options as IRunPropertiesOptions)); + } +} diff --git a/src/file/paragraph/run/run.spec.ts b/src/file/paragraph/run/run.spec.ts index aaa2a640de..3e67e88793 100644 --- a/src/file/paragraph/run/run.spec.ts +++ b/src/file/paragraph/run/run.spec.ts @@ -428,4 +428,64 @@ describe("Run", () => { }); }); }); + + describe("#revisions", () => { + it("should add style revisions", () => { + const run = new Run({ + bold: true, + italics: true, + revision: { + id: 0, + author: "Firstname Lastname", + date: "123", + bold: false, + italics: true, + }, + }); + const tree = new Formatter().format(run); + expect(tree).to.deep.equal({ + "w:r": [ + { + "w:rPr": [ + { "w:b": {} }, + { + "w:bCs": {}, + }, + { "w:i": {} }, + { + "w:iCs": {}, + }, + { + "w:rPrChange": [ + { + _attr: { + "w:author": "Firstname Lastname", + "w:date": "123", + "w:id": 0, + }, + }, + { + "w:rPr": [ + { "w:b": { _attr: { "w:val": false } } }, + { + "w:bCs": { + _attr: { + "w:val": false, + }, + }, + }, + { "w:i": {} }, + { + "w:iCs": {}, + }, + ], + }, + ], + }, + ], + }, + ], + }); + }); + }); });