diff --git a/README.md b/README.md
index 44103a3..21ab8bd 100644
--- a/README.md
+++ b/README.md
@@ -254,8 +254,8 @@ export default {
> Create a Diff2HtmlUI instance
```ts
-constructor(diffInput: string | DiffFile[], target: HTMLElement) // diff2html-ui, diff2html-ui-slim
-constructor(diffInput: string | DiffFile[], target: HTMLElement, config: Diff2HtmlUIConfig = {}, hljs?: HighlightJS) // diff2html-ui-base
+constructor(target: HTMLElement, diffInput?: string | DiffFile[]) // diff2html-ui, diff2html-ui-slim
+constructor(target: HTMLElement, diffInput?: string | DiffFile[], config: Diff2HtmlUIConfig = {}, hljs?: HighlightJS) // diff2html-ui-base
```
> Generate and inject in the document the Pretty HTML representation of the diff
@@ -270,6 +270,7 @@ draw(): void
synchronisedScroll(): void
fileListToggle(startVisible: boolean): void
highlightCode(): void
+smartSelection(): void
```
> Check out the [docs/demo.html](./docs/demo.html) for a demo example.
@@ -303,9 +304,9 @@ highlightCode(): void
const targetElement = document.getElementById('destination-elem-id');
const configuration = { drawFileList: true, matching: 'lines' };
-const diff2htmlUi = new Diff2HtmlUI(diffString, targetElement, configuration);
+const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
// or
-const diff2htmlUi = new Diff2HtmlUI(diffJson, targetElement, configuration);
+const diff2htmlUi = new Diff2HtmlUI(targetElement, diffJson, configuration);
```
#### Draw
@@ -338,7 +339,7 @@ index 0000001..0ddf2ba
+console.log("Hello from Diff2Html!")`;
const targetElement = document.getElementById('myDiffElement');
const configuration = { inputFormat: 'json', drawFileList: true, matching: 'lines', highlight: true };
- const diff2htmlUi = new Diff2HtmlUI(diffString, targetElement, configuration);
+ const diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
diff2htmlUi.draw();
diff2htmlUi.highlightCode();
});
@@ -359,7 +360,7 @@ index 0000001..0ddf2ba
```js
document.addEventListener('DOMContentLoaded', () => {
const targetElement = document.getElementById('myDiffElement');
- var diff2htmlUi = new Diff2HtmlUI(lineDiffExample, targetElement, { drawFileList: true, matching: 'lines' });
+ var diff2htmlUi = new Diff2HtmlUI(targetElement, lineDiffExample, { drawFileList: true, matching: 'lines' });
diff2htmlUi.draw();
diff2htmlUi.fileListToggle(false);
});
diff --git a/src/__tests__/diff2html-tests.ts b/src/__tests__/diff2html-tests.ts
index 80784c8..b662c1a 100644
--- a/src/__tests__/diff2html-tests.ts
+++ b/src/__tests__/diff2html-tests.ts
@@ -832,5 +832,109 @@ describe('Diff2Html', () => {
"
`);
});
+
+ it('should generate html correctly without escaping twice', () => {
+ const diff =
+ '--- src/index.html\n' +
+ '+++ src/index.html\n' +
+ '@@ -1,2 +1,2 @@\n' +
+ '-\n' +
+ '-\n' +
+ '+\n' +
+ '+
';
+
+ const result = html(diff);
+ expect(result).toMatchInlineSnapshot(`
+ "
+
+
+
+
+
+
+
+ |
+
+ @@ -1,2 +1,2 @@
+ |
+
+ |
+ 1
+
+ |
+
+
+ -
+ <!-- commented code -->
+
+ |
+
+ |
+ 2
+
+ |
+
+
+ -
+ </div>
+
+ |
+
+ |
+
+ 1
+ |
+
+
+ +
+ <html>
+
+ |
+
+ |
+
+ 2
+ |
+
+
+ +
+ <body>
+
+ |
+
+
+
+
+
+
+
"
+ `);
+ });
});
});
diff --git a/src/render-utils.ts b/src/render-utils.ts
index 6cdf7b8..cf91361 100644
--- a/src/render-utils.ts
+++ b/src/render-utils.ts
@@ -93,11 +93,11 @@ export function escapeForHtml(str: string): string {
/**
* Deconstructs diff @line by separating the content from the prefix type
*/
-export function deconstructLine(line: string, isCombined: boolean): DiffLineParts {
+export function deconstructLine(line: string, isCombined: boolean, escape = true): DiffLineParts {
const indexToSplit = prefixLength(isCombined);
return {
prefix: line.substring(0, indexToSplit),
- content: escapeForHtml(line.substring(indexToSplit)),
+ content: escape ? escapeForHtml(line.substring(indexToSplit)) : line.substring(indexToSplit),
};
}
@@ -216,8 +216,8 @@ export function diffHighlight(
): HighlightedLines {
const { matching, maxLineLengthHighlight, matchWordsThreshold, diffStyle } = { ...defaultRenderConfig, ...config };
- const line1 = deconstructLine(diffLine1, isCombined);
- const line2 = deconstructLine(diffLine2, isCombined);
+ const line1 = deconstructLine(diffLine1, isCombined, false);
+ const line2 = deconstructLine(diffLine2, isCombined, false);
if (line1.content.length > maxLineLengthHighlight || line2.content.length > maxLineLengthHighlight) {
return {
@@ -256,10 +256,11 @@ export function diffHighlight(
const highlightedLine = diff.reduce((highlightedLine, part) => {
const elemType = part.added ? 'ins' : part.removed ? 'del' : null;
const addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : '';
+ const escapedValue = escapeForHtml(part.value);
return elemType !== null
- ? `${highlightedLine}<${elemType}${addClass}>${part.value}${elemType}>`
- : `${highlightedLine}${part.value}`;
+ ? `${highlightedLine}<${elemType}${addClass}>${escapedValue}${elemType}>`
+ : `${highlightedLine}${escapedValue}`;
}, '');
return {
diff --git a/src/ui/js/diff2html-ui-base.ts b/src/ui/js/diff2html-ui-base.ts
index 0c7d116..71805d8 100644
--- a/src/ui/js/diff2html-ui-base.ts
+++ b/src/ui/js/diff2html-ui-base.ts
@@ -29,16 +29,21 @@ export class Diff2HtmlUI {
currentSelectionColumnId = -1;
- constructor(diffInput: string | DiffFile[], target: HTMLElement, config: Diff2HtmlUIConfig = {}, hljs?: HighlightJS) {
+ constructor(
+ target: HTMLElement,
+ diffInput?: string | DiffFile[],
+ config: Diff2HtmlUIConfig = {},
+ hljs?: HighlightJS,
+ ) {
this.config = { ...defaultDiff2HtmlUIConfig, ...config };
- this.diffHtml = html(diffInput, this.config);
+ this.diffHtml = diffInput !== undefined ? html(diffInput, this.config) : target.innerHTML;
this.targetElement = target;
if (hljs !== undefined) this.hljs = hljs;
}
draw(): void {
this.targetElement.innerHTML = this.diffHtml;
- if (this.config.smartSelection) this.initSelection();
+ if (this.config.smartSelection) this.smartSelection();
if (this.config.synchronisedScroll) this.synchronisedScroll();
if (this.config.highlight) this.highlightCode();
if (this.config.fileListToggle) this.fileListToggle(this.config.fileListStartVisible);
@@ -142,29 +147,13 @@ export class Diff2HtmlUI {
}
line.classList.add('hljs');
- line.classList.add('result.language');
+ line.classList.add(result.language);
line.innerHTML = result.value;
});
});
}
- private instanceOfIHighlightResult(object: IHighlightResult | IAutoHighlightResult): object is IHighlightResult {
- return 'top' in object;
- }
-
- private getHashTag(): string | null {
- const docUrl = document.URL;
- const hashTagIndex = docUrl.indexOf('#');
-
- let hashTag = null;
- if (hashTagIndex !== -1) {
- hashTag = docUrl.substr(hashTagIndex + 1);
- }
-
- return hashTag;
- }
-
- private initSelection(): void {
+ smartSelection(): void {
const body = document.getElementsByTagName('body')[0];
const diffTable = body.getElementsByClassName('d2h-diff-table')[0];
@@ -200,6 +189,22 @@ export class Diff2HtmlUI {
});
}
+ private instanceOfIHighlightResult(object: IHighlightResult | IAutoHighlightResult): object is IHighlightResult {
+ return 'top' in object;
+ }
+
+ private getHashTag(): string | null {
+ const docUrl = document.URL;
+ const hashTagIndex = docUrl.indexOf('#');
+
+ let hashTag = null;
+ if (hashTagIndex !== -1) {
+ hashTag = docUrl.substr(hashTagIndex + 1);
+ }
+
+ return hashTag;
+ }
+
private getSelectedText(): string | undefined {
const sel = window.getSelection();
diff --git a/src/ui/js/diff2html-ui-slim.ts b/src/ui/js/diff2html-ui-slim.ts
index 86d40af..2644e7e 100644
--- a/src/ui/js/diff2html-ui-slim.ts
+++ b/src/ui/js/diff2html-ui-slim.ts
@@ -4,8 +4,8 @@ import { DiffFile } from '../../types';
import { Diff2HtmlUI as Diff2HtmlUIBase, Diff2HtmlUIConfig, defaultDiff2HtmlUIConfig } from './diff2html-ui-base';
export class Diff2HtmlUI extends Diff2HtmlUIBase {
- constructor(diffInput: string | DiffFile[], target: HTMLElement, config: Diff2HtmlUIConfig = {}) {
- super(diffInput, target, config, hljs);
+ constructor(target: HTMLElement, diffInput?: string | DiffFile[], config: Diff2HtmlUIConfig = {}) {
+ super(target, diffInput, config, hljs);
}
}
diff --git a/src/ui/js/diff2html-ui.ts b/src/ui/js/diff2html-ui.ts
index eaefad2..fc51604 100644
--- a/src/ui/js/diff2html-ui.ts
+++ b/src/ui/js/diff2html-ui.ts
@@ -4,8 +4,8 @@ import { DiffFile } from '../../types';
import { Diff2HtmlUI as Diff2HtmlUIBase, Diff2HtmlUIConfig, defaultDiff2HtmlUIConfig } from './diff2html-ui-base';
export class Diff2HtmlUI extends Diff2HtmlUIBase {
- constructor(diffInput: string | DiffFile[], target: HTMLElement, config: Diff2HtmlUIConfig = {}) {
- super(diffInput, target, config, hljs);
+ constructor(target: HTMLElement, diffInput?: string | DiffFile[], config: Diff2HtmlUIConfig = {}) {
+ super(target, diffInput, config, hljs);
}
}
diff --git a/website/templates/pages/demo/demo.ts b/website/templates/pages/demo/demo.ts
index d4920cf..82010ca 100644
--- a/website/templates/pages/demo/demo.ts
+++ b/website/templates/pages/demo/demo.ts
@@ -151,7 +151,7 @@ async function getDiff(request: Request): Promise {
}
function draw(diffString: string, config: Diff2HtmlUIConfig, elements: Elements): void {
- const diff2htmlUi = new Diff2HtmlUI(diffString, elements.structure.diffTarget, config);
+ const diff2htmlUi = new Diff2HtmlUI(elements.structure.diffTarget, diffString, config);
diff2htmlUi.draw();
}