Skip to content

Commit

Permalink
Merge pull request #514 from JHWelch/add-dark-mode
Browse files Browse the repository at this point in the history
Add Dark & Auto color schemes
  • Loading branch information
rtfpessoa authored Sep 29, 2023
2 parents 8102d3c + 7410d25 commit b04a400
Show file tree
Hide file tree
Showing 18 changed files with 1,289 additions and 107 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ diff2htmlUi.draw();

```html
<!-- Stylesheet -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/github.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />

<!-- Javascripts -->
Expand All @@ -227,6 +227,21 @@ document.addEventListener('DOMContentLoaded', () => {
});
```

When using the `auto` color scheme, you will need to specify both the light and dark themes for highlight.js to use.

```html
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css"
media="screen and (prefers-color-scheme: light)"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css"
media="screen and (prefers-color-scheme: dark)"
/>
```

#### Collapsable File Summary List

> Add the dependencies.
Expand Down Expand Up @@ -386,6 +401,8 @@ The HTML output accepts a Javascript object with configuration. Possible options
> [src/templates](https://github.com/rtfpessoa/diff2html/tree/master/src/templates)
- `highlightLanguages`: Map of extension to language name, used for highlighting. This overrides the default language
detection based on file extensions.
- `colorScheme`: color scheme to use for the diff, default is `light`. Possible values are `light`, `dark`, and `auto`
which will use the browser's preferred color scheme.

### Diff2Html Browser

Expand Down
312 changes: 298 additions & 14 deletions src/__tests__/diff2html-tests.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { render } from '../file-list-renderer';
import { FileListRenderer } from '../file-list-renderer';
import HoganJsUtils from '../hoganjs-utils';
import { ColorSchemeType } from '../types';

describe('FileListPrinter', () => {
describe('generateFileList', () => {
describe('FileListRenderer', () => {
describe('render', () => {
it('should expose old and new files to templates', () => {
const hoganUtils = new HoganJsUtils({
rawTemplates: {
'file-summary-wrapper': '{{{files}}}',
'file-summary-line': '{{oldName}}, {{newName}}, {{fileName}}',
},
});
const fileListRenderer = new FileListRenderer(hoganUtils);
const files = [
{
isCombined: false,
Expand Down Expand Up @@ -55,7 +57,7 @@ describe('FileListPrinter', () => {
},
];

const fileHtml = render(files, hoganUtils);
const fileHtml = fileListRenderer.render(files);

expect(fileHtml).toMatchInlineSnapshot(`
"my/file/name.js, my/file/name.js, my/file/name.js
Expand All @@ -67,6 +69,8 @@ describe('FileListPrinter', () => {

it('should work for all kinds of files', () => {
const hoganUtils = new HoganJsUtils({});
const fileListRenderer = new FileListRenderer(hoganUtils);

const files = [
{
isCombined: false,
Expand Down Expand Up @@ -111,9 +115,9 @@ describe('FileListPrinter', () => {
isDeleted: true,
},
];
const fileHtml = render(files, hoganUtils);
const fileHtml = fileListRenderer.render(files);
expect(fileHtml).toMatchInlineSnapshot(`
"<div class="d2h-file-list-wrapper">
"<div class="d2h-file-list-wrapper d2h-light-color-scheme">
<div class="d2h-file-list-header">
<span class="d2h-file-list-title">Files changed (4)</span>
<a class="d2h-file-switch d2h-hide">hide</a>
Expand Down Expand Up @@ -172,5 +176,97 @@ describe('FileListPrinter', () => {
</div>"
`);
});

describe('with dark colorScheme', () => {
it('should include dark colorScheme', () => {
const hoganUtils = new HoganJsUtils({});
const fileListRenderer = new FileListRenderer(hoganUtils, {
colorScheme: ColorSchemeType.DARK,
});

const files = [
{
isCombined: false,
isGitDiff: false,
blocks: [],
addedLines: 12,
deletedLines: 41,
language: 'js',
oldName: 'my/file/name.js',
newName: 'my/file/name.js',
},
];
const fileHtml = fileListRenderer.render(files);
expect(fileHtml).toMatchInlineSnapshot(`
"<div class="d2h-file-list-wrapper d2h-dark-color-scheme">
<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-781444" class="d2h-file-name">my/file/name.js</a>
<span class="d2h-file-stats">
<span class="d2h-lines-added">+12</span>
<span class="d2h-lines-deleted">-41</span>
</span>
</span>
</li>
</ol>
</div>"
`);
});
});

describe('with auto colorScheme', () => {
it('should include auto colorScheme', () => {
const hoganUtils = new HoganJsUtils({});
const fileListRenderer = new FileListRenderer(hoganUtils, {
colorScheme: ColorSchemeType.AUTO,
});

const files = [
{
isCombined: false,
isGitDiff: false,
blocks: [],
addedLines: 12,
deletedLines: 41,
language: 'js',
oldName: 'my/file/name.js',
newName: 'my/file/name.js',
},
];
const fileHtml = fileListRenderer.render(files);
expect(fileHtml).toMatchInlineSnapshot(`
"<div class="d2h-file-list-wrapper d2h-auto-color-scheme">
<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-781444" class="d2h-file-name">my/file/name.js</a>
<span class="d2h-file-stats">
<span class="d2h-lines-added">+12</span>
<span class="d2h-lines-deleted">-41</span>
</span>
</span>
</li>
</ol>
</div>"
`);
});
});
});
});
6 changes: 3 additions & 3 deletions src/__tests__/line-by-line-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ describe('LineByLineRenderer', () => {
});
const html = lineByLineRenderer.render(exampleJson);
expect(html).toMatchInlineSnapshot(`
"<div class="d2h-wrapper">
"<div class="d2h-wrapper d2h-light-color-scheme">
<div id="d2h-675094" class="d2h-file-wrapper" data-lang="txt">
<div class="d2h-file-header">
<span class="d2h-file-name-wrapper">
Expand Down Expand Up @@ -523,7 +523,7 @@ describe('LineByLineRenderer', () => {
});
const html = lineByLineRenderer.render(exampleJson);
expect(html).toMatchInlineSnapshot(`
"<div class="d2h-wrapper">
"<div class="d2h-wrapper d2h-light-color-scheme">
<div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">
<div class="d2h-file-header">
<span class="d2h-file-name-wrapper">
Expand Down Expand Up @@ -583,7 +583,7 @@ describe('LineByLineRenderer', () => {
const lineByLineRenderer = new LineByLineRenderer(hoganUtils);
const html = lineByLineRenderer.render(exampleJson);
expect(html).toMatchInlineSnapshot(`
"<div class="d2h-wrapper">
"<div class="d2h-wrapper d2h-light-color-scheme">
<div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">
<div class="d2h-file-header">
<span class="d2h-file-name-wrapper">
Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/side-by-side-printer-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ describe('SideBySideRenderer', () => {
const sideBySideRenderer = new SideBySideRenderer(hoganUtils, { matching: LineMatchingType.LINES });
const html = sideBySideRenderer.render(exampleJson);
expect(html).toMatchInlineSnapshot(`
"<div class="d2h-wrapper">
"<div class="d2h-wrapper d2h-light-color-scheme">
<div id="d2h-675094" class="d2h-file-wrapper" data-lang="txt">
<div class="d2h-file-header">
<span class="d2h-file-name-wrapper">
Expand Down Expand Up @@ -363,7 +363,7 @@ describe('SideBySideRenderer', () => {
const sideBySideRenderer = new SideBySideRenderer(hoganUtils, {});
const html = sideBySideRenderer.render(exampleJson);
expect(html).toMatchInlineSnapshot(`
"<div class="d2h-wrapper">
"<div class="d2h-wrapper d2h-light-color-scheme">
<div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">
<div class="d2h-file-header">
<span class="d2h-file-name-wrapper">
Expand Down Expand Up @@ -434,7 +434,7 @@ describe('SideBySideRenderer', () => {
const sideBySideRenderer = new SideBySideRenderer(hoganUtils);
const html = sideBySideRenderer.render(exampleJson);
expect(html).toMatchInlineSnapshot(`
"<div class="d2h-wrapper">
"<div class="d2h-wrapper d2h-light-color-scheme">
<div id="d2h-675094" class="d2h-file-wrapper" data-lang="js">
<div class="d2h-file-header">
<span class="d2h-file-name-wrapper">
Expand Down
7 changes: 5 additions & 2 deletions src/diff2html.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as DiffParser from './diff-parser';
import * as fileListPrinter from './file-list-renderer';
import { FileListRenderer } from './file-list-renderer';
import LineByLineRenderer, { LineByLineRendererConfig, defaultLineByLineRendererConfig } from './line-by-line-renderer';
import SideBySideRenderer, { SideBySideRendererConfig, defaultSideBySideRendererConfig } from './side-by-side-renderer';
import { DiffFile, OutputFormatType } from './types';
Expand Down Expand Up @@ -32,7 +32,10 @@ export function html(diffInput: string | DiffFile[], configuration: Diff2HtmlCon

const hoganUtils = new HoganJsUtils(config);

const fileList = config.drawFileList ? fileListPrinter.render(diffJson, hoganUtils) : '';
const { colorScheme } = config;
const fileListRendererConfig = { colorScheme };

const fileList = config.drawFileList ? new FileListRenderer(hoganUtils, fileListRendererConfig).render(diffJson) : '';

const diffOutput =
config.outputFormat === 'side-by-side'
Expand Down
69 changes: 44 additions & 25 deletions src/file-list-renderer.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,52 @@
import * as renderUtils from './render-utils';
import HoganJsUtils from './hoganjs-utils';
import { DiffFile } from './types';
import { ColorSchemeType, DiffFile } from './types';

const baseTemplatesPath = 'file-summary';
const iconsBaseTemplatesPath = 'icon';

export function render(diffFiles: DiffFile[], hoganUtils: HoganJsUtils): string {
const files = diffFiles
.map(file =>
hoganUtils.render(
baseTemplatesPath,
'line',
{
fileHtmlId: renderUtils.getHtmlId(file),
oldName: file.oldName,
newName: file.newName,
fileName: renderUtils.filenameDiff(file),
deletedLines: '-' + file.deletedLines,
addedLines: '+' + file.addedLines,
},
{
fileIcon: hoganUtils.template(iconsBaseTemplatesPath, renderUtils.getFileIcon(file)),
},
),
)
.join('\n');
export interface FileListRendererConfig {
colorScheme?: ColorSchemeType;
}

export const defaultFileListRendererConfig = {
colorScheme: renderUtils.defaultRenderConfig.colorScheme,
};

export class FileListRenderer {
private readonly hoganUtils: HoganJsUtils;
private readonly config: typeof defaultFileListRendererConfig;

constructor(hoganUtils: HoganJsUtils, config: FileListRendererConfig = {}) {
this.hoganUtils = hoganUtils;
this.config = { ...defaultFileListRendererConfig, ...config };
}

render(diffFiles: DiffFile[]): string {
const files = diffFiles
.map(file =>
this.hoganUtils.render(
baseTemplatesPath,
'line',
{
fileHtmlId: renderUtils.getHtmlId(file),
oldName: file.oldName,
newName: file.newName,
fileName: renderUtils.filenameDiff(file),
deletedLines: '-' + file.deletedLines,
addedLines: '+' + file.addedLines,
},
{
fileIcon: this.hoganUtils.template(iconsBaseTemplatesPath, renderUtils.getFileIcon(file)),
},
),
)
.join('\n');

return hoganUtils.render(baseTemplatesPath, 'wrapper', {
filesNumber: diffFiles.length,
files: files,
});
return this.hoganUtils.render(baseTemplatesPath, 'wrapper', {
colorScheme: renderUtils.colorSchemeToCss(this.config.colorScheme),
filesNumber: diffFiles.length,
files: files,
});
}
}
5 changes: 4 additions & 1 deletion src/line-by-line-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export default class LineByLineRenderer {
})
.join('\n');

return this.hoganUtils.render(genericTemplatesPath, 'wrapper', { content: diffsHtml });
return this.hoganUtils.render(genericTemplatesPath, 'wrapper', {
colorScheme: renderUtils.colorSchemeToCss(this.config.colorScheme),
content: diffsHtml,
});
}

makeFileDiffHtml(file: DiffFile, diffs: string): string {
Expand Down
Loading

0 comments on commit b04a400

Please sign in to comment.