clean: Improve diff2html-ui APIs for standalone usage
This commit is contained in:
parent
aa6dd18c37
commit
8b5111f8de
7 changed files with 149 additions and 38 deletions
13
README.md
13
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);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -832,5 +832,109 @@ describe('Diff2Html', () => {
|
|||
</div>"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate html correctly without escaping twice', () => {
|
||||
const diff =
|
||||
'--- src/index.html\n' +
|
||||
'+++ src/index.html\n' +
|
||||
'@@ -1,2 +1,2 @@\n' +
|
||||
'-<!-- commented code -->\n' +
|
||||
'-</div>\n' +
|
||||
'+<html>\n' +
|
||||
'+<body>';
|
||||
|
||||
const result = html(diff);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"<div class=\\"d2h-file-list-wrapper\\">
|
||||
<div class=\\"d2h-file-list-header\\">
|
||||
<span class=\\"d2h-file-list-title\\">Files changed (1)</span>
|
||||
<a class=\\"d2h-file-switch d2h-hide\\">hide</a>
|
||||
<a class=\\"d2h-file-switch d2h-show\\">show</a>
|
||||
</div>
|
||||
<ol class=\\"d2h-file-list\\">
|
||||
<li class=\\"d2h-file-list-line\\">
|
||||
<span class=\\"d2h-file-name-wrapper\\">
|
||||
<svg aria-hidden=\\"true\\" class=\\"d2h-icon d2h-changed\\" height=\\"16\\" title=\\"modified\\" version=\\"1.1\\"
|
||||
viewBox=\\"0 0 14 16\\" width=\\"14\\">
|
||||
<path d=\\"M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z\\"></path>
|
||||
</svg> <a href=\\"#d2h-597266\\" class=\\"d2h-file-name\\">src/index.html</a>
|
||||
<span class=\\"d2h-file-stats\\">
|
||||
<span class=\\"d2h-lines-added\\">+2</span>
|
||||
<span class=\\"d2h-lines-deleted\\">-2</span>
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
</ol>
|
||||
</div><div class=\\"d2h-wrapper\\">
|
||||
<div id=\\"d2h-597266\\" class=\\"d2h-file-wrapper\\" data-lang=\\"html\\">
|
||||
<div class=\\"d2h-file-header\\">
|
||||
<span class=\\"d2h-file-name-wrapper\\">
|
||||
<svg aria-hidden=\\"true\\" class=\\"d2h-icon\\" height=\\"16\\" version=\\"1.1\\" viewBox=\\"0 0 12 16\\" width=\\"12\\">
|
||||
<path d=\\"M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z\\"></path>
|
||||
</svg> <span class=\\"d2h-file-name\\">src/index.html</span>
|
||||
<span class=\\"d2h-tag d2h-changed d2h-changed-tag\\">CHANGED</span></span>
|
||||
</div>
|
||||
<div class=\\"d2h-file-diff\\">
|
||||
<div class=\\"d2h-code-wrapper\\">
|
||||
<table class=\\"d2h-diff-table\\">
|
||||
<tbody class=\\"d2h-diff-tbody\\">
|
||||
<tr>
|
||||
<td class=\\"d2h-code-linenumber d2h-info\\"></td>
|
||||
<td class=\\"d2h-info\\">
|
||||
<div class=\\"d2h-code-line d2h-info\\">@@ -1,2 +1,2 @@</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class=\\"d2h-code-linenumber d2h-del d2h-change\\">
|
||||
<div class=\\"line-num1\\">1</div>
|
||||
<div class=\\"line-num2\\"></div>
|
||||
</td>
|
||||
<td class=\\"d2h-del d2h-change\\">
|
||||
<div class=\\"d2h-code-line d2h-del d2h-change\\">
|
||||
<span class=\\"d2h-code-line-prefix\\">-</span>
|
||||
<span class=\\"d2h-code-line-ctn\\"><del><!-- commented code --></del></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class=\\"d2h-code-linenumber d2h-del d2h-change\\">
|
||||
<div class=\\"line-num1\\">2</div>
|
||||
<div class=\\"line-num2\\"></div>
|
||||
</td>
|
||||
<td class=\\"d2h-del d2h-change\\">
|
||||
<div class=\\"d2h-code-line d2h-del d2h-change\\">
|
||||
<span class=\\"d2h-code-line-prefix\\">-</span>
|
||||
<span class=\\"d2h-code-line-ctn\\"><del></div</del>></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class=\\"d2h-code-linenumber d2h-ins d2h-change\\">
|
||||
<div class=\\"line-num1\\"></div>
|
||||
<div class=\\"line-num2\\">1</div>
|
||||
</td>
|
||||
<td class=\\"d2h-ins d2h-change\\">
|
||||
<div class=\\"d2h-code-line d2h-ins d2h-change\\">
|
||||
<span class=\\"d2h-code-line-prefix\\">+</span>
|
||||
<span class=\\"d2h-code-line-ctn\\"><ins><html></ins></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class=\\"d2h-code-linenumber d2h-ins d2h-change\\">
|
||||
<div class=\\"line-num1\\"></div>
|
||||
<div class=\\"line-num2\\">2</div>
|
||||
</td>
|
||||
<td class=\\"d2h-ins d2h-change\\">
|
||||
<div class=\\"d2h-code-line d2h-ins d2h-change\\">
|
||||
<span class=\\"d2h-code-line-prefix\\">+</span>
|
||||
<span class=\\"d2h-code-line-ctn\\"><ins><body</ins>></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>"
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ async function getDiff(request: Request): Promise<string> {
|
|||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue