diff --git a/README.md b/README.md index 9760114..63c24da 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ diff2htmlUi.draw(); ```html - + @@ -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 + + +``` + #### Collapsable File Summary List > Add the dependencies. @@ -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 diff --git a/src/__tests__/diff2html-tests.ts b/src/__tests__/diff2html-tests.ts index dbf78ab..d9e4e8c 100644 --- a/src/__tests__/diff2html-tests.ts +++ b/src/__tests__/diff2html-tests.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import { parse, html } from '../diff2html'; -import { DiffFile, LineType, OutputFormatType } from '../types'; +import { ColorSchemeType, DiffFile, LineType, OutputFormatType } from '../types'; const diffExample1 = 'diff --git a/sample b/sample\n' + @@ -205,7 +205,7 @@ describe('Diff2Html', () => { it('should generate pretty line by line html from diff', () => { const result = html(diffExample1, { drawFileList: false }); expect(result).toMatchInlineSnapshot(` - "
+ "
@@ -262,7 +262,7 @@ describe('Diff2Html', () => { it('should generate pretty line by line html from json', () => { const result = html(jsonExample1, { drawFileList: false }); expect(result).toMatchInlineSnapshot(` - "
+ "
@@ -319,7 +319,7 @@ describe('Diff2Html', () => { it('should generate pretty diff with files summary', () => { const result = html(diffExample1, { drawFileList: true }); expect(result).toMatchInlineSnapshot(` - "
+ "
Files changed (1) hide @@ -339,7 +339,7 @@ describe('Diff2Html', () => { -
+
@@ -396,7 +396,7 @@ describe('Diff2Html', () => { it('should generate pretty side by side html from diff', () => { const result = html(diffExample1, { outputFormat: OutputFormatType.SIDE_BY_SIDE, drawFileList: false }); expect(result).toMatchInlineSnapshot(` - "
+ "
@@ -467,7 +467,7 @@ describe('Diff2Html', () => { it('should generate pretty side by side html from json', () => { const result = html(jsonExample1, { outputFormat: OutputFormatType.SIDE_BY_SIDE, drawFileList: false }); expect(result).toMatchInlineSnapshot(` - "
+ "
@@ -538,7 +538,7 @@ describe('Diff2Html', () => { it('should generate pretty side by side html from diff 2', () => { const result = html(diffExample1, { outputFormat: OutputFormatType.SIDE_BY_SIDE, drawFileList: true }); expect(result).toMatchInlineSnapshot(` - "
+ "
Files changed (1) hide @@ -558,7 +558,7 @@ describe('Diff2Html', () => { -
+
@@ -652,7 +652,7 @@ describe('Diff2Html', () => { ' \n'; const result = html(diffExample2, { drawFileList: false }); expect(result).toMatchInlineSnapshot(` - "
+ "
@@ -878,7 +878,7 @@ describe('Diff2Html', () => { const result = html(diff); expect(result).toMatchInlineSnapshot(` - "
+ "
Files changed (1) hide @@ -898,7 +898,7 @@ describe('Diff2Html', () => { -
+
@@ -980,7 +980,7 @@ describe('Diff2Html', () => { const result = html(diff); /* eslint-disable no-irregular-whitespace */ expect(result).toMatchInlineSnapshot(` - "
+ "
Files changed (1) hide @@ -1000,7 +1000,7 @@ describe('Diff2Html', () => { -
+
@@ -1258,5 +1258,289 @@ describe('Diff2Html', () => { `); /* eslint-enable no-irregular-whitespace */ }); + + describe('with auto colorScheme', () => { + it('should return a html diff with auto color scheme', () => { + const result = html(diffExample1, { + drawFileList: false, + colorScheme: ColorSchemeType.AUTO, + }); + expect(result).toMatchInlineSnapshot(` + "
+
+
+ + sample + CHANGED + +
+
+
+ + + + + + + + + + + + + +
+
@@ -1 +1 @@
+
+
1
+
+
+
+ - + test +
+
+
+
1
+
+
+ + + test1 +
+
+
+
+
+
" + `); + }); + + it('should include auto colorScheme on file list', () => { + const result = html(diffExample1, { + drawFileList: true, + colorScheme: ColorSchemeType.AUTO, + }); + expect(result).toMatchInlineSnapshot(` + "
+
+ Files changed (1) + hide + show +
+
    +
  1. + + sample + + +1 + -1 + + +
  2. +
+
+
+
+ + sample + CHANGED + +
+
+
+ + + + + + + + + + + + + +
+
@@ -1 +1 @@
+
+
1
+
+
+
+ - + test +
+
+
+
1
+
+
+ + + test1 +
+
+
+
+
+
" + `); + }); + }); + + describe('with dark colorScheme', () => { + it('should return a html diff with dark mode', () => { + const result = html(diffExample1, { + drawFileList: false, + colorScheme: ColorSchemeType.DARK, + }); + expect(result).toMatchInlineSnapshot(` + "
+
+
+ + sample + CHANGED + +
+
+
+ + + + + + + + + + + + + +
+
@@ -1 +1 @@
+
+
1
+
+
+
+ - + test +
+
+
+
1
+
+
+ + + test1 +
+
+
+
+
+
" + `); + }); + + it('should include dark colorScheme on file list', () => { + const result = html(diffExample1, { + drawFileList: true, + colorScheme: ColorSchemeType.DARK, + }); + expect(result).toMatchInlineSnapshot(` + "
+
+ Files changed (1) + hide + show +
+
    +
  1. + + sample + + +1 + -1 + + +
  2. +
+
+
+
+ + sample + CHANGED + +
+
+
+ + + + + + + + + + + + + +
+
@@ -1 +1 @@
+
+
1
+
+
+
+ - + test +
+
+
+
1
+
+
+ + + test1 +
+
+
+
+
+
" + `); + }); + }); }); }); diff --git a/src/__tests__/file-list-printer-tests.ts b/src/__tests__/file-list-renderer-tests.ts similarity index 59% rename from src/__tests__/file-list-printer-tests.ts rename to src/__tests__/file-list-renderer-tests.ts index 486d8da..52c703b 100644 --- a/src/__tests__/file-list-printer-tests.ts +++ b/src/__tests__/file-list-renderer-tests.ts @@ -1,8 +1,9 @@ -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: { @@ -10,6 +11,7 @@ describe('FileListPrinter', () => { 'file-summary-line': '{{oldName}}, {{newName}}, {{fileName}}', }, }); + const fileListRenderer = new FileListRenderer(hoganUtils); const files = [ { isCombined: false, @@ -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 @@ -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, @@ -111,9 +115,9 @@ describe('FileListPrinter', () => { isDeleted: true, }, ]; - const fileHtml = render(files, hoganUtils); + const fileHtml = fileListRenderer.render(files); expect(fileHtml).toMatchInlineSnapshot(` - "
+ "
Files changed (4) hide @@ -172,5 +176,97 @@ describe('FileListPrinter', () => {
" `); }); + + 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(` + "
+
+ Files changed (1) + hide + show +
+
    +
  1. + + my/file/name.js + + +12 + -41 + + +
  2. +
+
" + `); + }); + }); + + 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(` + "
+
+ Files changed (1) + hide + show +
+
    +
  1. + + my/file/name.js + + +12 + -41 + + +
  2. +
+
" + `); + }); + }); }); }); diff --git a/src/__tests__/line-by-line-tests.ts b/src/__tests__/line-by-line-tests.ts index 4e1ae32..e8f5bff 100644 --- a/src/__tests__/line-by-line-tests.ts +++ b/src/__tests__/line-by-line-tests.ts @@ -449,7 +449,7 @@ describe('LineByLineRenderer', () => { }); const html = lineByLineRenderer.render(exampleJson); expect(html).toMatchInlineSnapshot(` - "
+ "
@@ -523,7 +523,7 @@ describe('LineByLineRenderer', () => { }); const html = lineByLineRenderer.render(exampleJson); expect(html).toMatchInlineSnapshot(` - "
+ "
@@ -583,7 +583,7 @@ describe('LineByLineRenderer', () => { const lineByLineRenderer = new LineByLineRenderer(hoganUtils); const html = lineByLineRenderer.render(exampleJson); expect(html).toMatchInlineSnapshot(` - "
+ "
diff --git a/src/__tests__/side-by-side-printer-tests.ts b/src/__tests__/side-by-side-printer-tests.ts index 681022e..ab886ab 100644 --- a/src/__tests__/side-by-side-printer-tests.ts +++ b/src/__tests__/side-by-side-printer-tests.ts @@ -278,7 +278,7 @@ describe('SideBySideRenderer', () => { const sideBySideRenderer = new SideBySideRenderer(hoganUtils, { matching: LineMatchingType.LINES }); const html = sideBySideRenderer.render(exampleJson); expect(html).toMatchInlineSnapshot(` - "
+ "
@@ -363,7 +363,7 @@ describe('SideBySideRenderer', () => { const sideBySideRenderer = new SideBySideRenderer(hoganUtils, {}); const html = sideBySideRenderer.render(exampleJson); expect(html).toMatchInlineSnapshot(` - "
+ "
@@ -434,7 +434,7 @@ describe('SideBySideRenderer', () => { const sideBySideRenderer = new SideBySideRenderer(hoganUtils); const html = sideBySideRenderer.render(exampleJson); expect(html).toMatchInlineSnapshot(` - "
+ "
diff --git a/src/diff2html.ts b/src/diff2html.ts index 5daed0e..06f00f7 100644 --- a/src/diff2html.ts +++ b/src/diff2html.ts @@ -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'; @@ -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' diff --git a/src/file-list-renderer.ts b/src/file-list-renderer.ts index 90836c4..bbb1698 100644 --- a/src/file-list-renderer.ts +++ b/src/file-list-renderer.ts @@ -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'); - - return hoganUtils.render(baseTemplatesPath, 'wrapper', { - filesNumber: diffFiles.length, - files: files, - }); +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 this.hoganUtils.render(baseTemplatesPath, 'wrapper', { + colorScheme: renderUtils.colorSchemeToCss(this.config.colorScheme), + filesNumber: diffFiles.length, + files: files, + }); + } } diff --git a/src/line-by-line-renderer.ts b/src/line-by-line-renderer.ts index c3a3805..430d026 100644 --- a/src/line-by-line-renderer.ts +++ b/src/line-by-line-renderer.ts @@ -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 { diff --git a/src/render-utils.ts b/src/render-utils.ts index 830628e..f557796 100644 --- a/src/render-utils.ts +++ b/src/render-utils.ts @@ -2,7 +2,15 @@ import * as jsDiff from 'diff'; import { unifyPath, hashCode } from './utils'; import * as rematch from './rematch'; -import { LineMatchingType, DiffStyleType, LineType, DiffLineParts, DiffFile, DiffFileName } from './types'; +import { + ColorSchemeType, + DiffFile, + DiffFileName, + DiffLineParts, + DiffStyleType, + LineMatchingType, + LineType, +} from './types'; export type CSSLineClass = | 'd2h-ins' @@ -37,6 +45,7 @@ export interface RenderConfig { matchWordsThreshold?: number; maxLineLengthHighlight?: number; diffStyle?: DiffStyleType; + colorScheme?: ColorSchemeType; } export const defaultRenderConfig = { @@ -44,6 +53,7 @@ export const defaultRenderConfig = { matchWordsThreshold: 0.25, maxLineLengthHighlight: 10000, diffStyle: DiffStyleType.WORD, + colorScheme: ColorSchemeType.LIGHT, }; const separator = '/'; @@ -76,6 +86,18 @@ export function toCSSClass(lineType: LineType): CSSLineClass { } } +export function colorSchemeToCss(colorScheme: ColorSchemeType): string { + switch (colorScheme) { + case ColorSchemeType.DARK: + return 'd2h-dark-color-scheme'; + case ColorSchemeType.AUTO: + return 'd2h-auto-color-scheme'; + case ColorSchemeType.LIGHT: + default: + return 'd2h-light-color-scheme'; + } +} + /** * Prefix length of the hunk lines in the diff */ diff --git a/src/side-by-side-renderer.ts b/src/side-by-side-renderer.ts index 9a0fb6b..e63893a 100644 --- a/src/side-by-side-renderer.ts +++ b/src/side-by-side-renderer.ts @@ -52,7 +52,10 @@ export default class SideBySideRenderer { }) .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: FileHtml): string { diff --git a/src/templates/file-summary-wrapper.mustache b/src/templates/file-summary-wrapper.mustache index 126854c..e0cb897 100644 --- a/src/templates/file-summary-wrapper.mustache +++ b/src/templates/file-summary-wrapper.mustache @@ -1,4 +1,4 @@ -
+
Files changed ({{filesNumber}}) hide diff --git a/src/templates/generic-wrapper.mustache b/src/templates/generic-wrapper.mustache index be5096a..e186314 100644 --- a/src/templates/generic-wrapper.mustache +++ b/src/templates/generic-wrapper.mustache @@ -1,3 +1,3 @@ -
+
{{{content}}}
diff --git a/src/types.ts b/src/types.ts index ea28b49..d226286 100644 --- a/src/types.ts +++ b/src/types.ts @@ -91,3 +91,9 @@ export const DiffStyleType: { [_: string]: DiffStyleType } = { WORD: 'word', CHAR: 'char', }; + +export enum ColorSchemeType { + AUTO = 'auto', + DARK = 'dark', + LIGHT = 'light', +} diff --git a/src/ui/css/diff2html.css b/src/ui/css/diff2html.css index b0e502a..5c515ac 100644 --- a/src/ui/css/diff2html.css +++ b/src/ui/css/diff2html.css @@ -5,6 +5,81 @@ * */ +:root { + --d2h-bg-color: #fff; + --d2h-border-color: #ddd; + + --d2h-dim-color: rgba(0, 0, 0, 0.3); + + --d2h-line-border-color: #eeeeee; + + --d2h-file-header-bg-color: #f7f7f7; + --d2h-file-header-border-color: #d8d8d8; + + --d2h-empty-placeholder-bg-color: #f1f1f1; + --d2h-empty-placeholder-border-color: #e1e1e1; + + --d2h-selected-color: #c8e1ff; + + --d2h-ins-bg-color: #dfd; + --d2h-ins-border-color: #b4e2b4; + --d2h-ins-highlight-bg-color: #97f295; + --d2h-ins-label-color: #399839; + + --d2h-del-bg-color: #fee8e9; + --d2h-del-border-color: #e9aeae; + --d2h-del-highlight-bg-color: #ffb6ba; + --d2h-del-label-color: #c33; + + --d2h-change-del-color: #fdf2d0; + --d2h-change-ins-color: #ded; + + --d2h-info-bg-color: #f8fafd; + --d2h-info-border-color: #d5e4f2; + + --d2h-change-label-color: #d0b44c; + --d2h-moved-label-color: #3572b0; + + /** + * Dark Color Scheme + */ + + --d2h-dark-color: rgb(230, 237, 243); + --d2h-dark-bg-color: rgb(13, 17, 23); + --d2h-dark-border-color: rgb(48, 54, 61); + + --d2h-dark-dim-color: rgb(110, 118, 129); + + --d2h-dark-line-border-color: rgb(33, 38, 45); + + --d2h-dark-file-header-bg-color: rgb(22, 27, 34); + --d2h-dark-file-header-border-color: rgb(48, 54, 61); + + --d2h-dark-empty-placeholder-bg-color: #rgba(110, 118, 129, 0.1); + --d2h-dark-empty-placeholder-border-color: rgb(48, 54, 61); + + --d2h-dark-selected-color: rgba(56, 139, 253, 0.1); + + --d2h-dark-ins-bg-color: rgba(46, 160, 67, 0.15); + --d2h-dark-ins-border-color: rgba(46, 160, 67, 0.4); + --d2h-dark-ins-highlight-bg-color: rgba(46, 160, 67, 0.4); + --d2h-dark-ins-label-color: rgb(63, 185, 80); + + --d2h-dark-del-bg-color: rgba(248, 81, 73, 0.1); + --d2h-dark-del-border-color: rgba(248, 81, 73, 0.4); + --d2h-dark-del-highlight-bg-color: rgba(248, 81, 73, 0.4); + --d2h-dark-del-label-color: rgb(248, 81, 73); + + --d2h-dark-change-del-color: rgba(210, 153, 34, 0.2); + --d2h-dark-change-ins-color: rgba(46, 160, 67, 0.25); + + --d2h-dark-info-bg-color: rgba(56, 139, 253, 0.1); + --d2h-dark-info-border-color: rgba(56, 139, 253, 0.4); + + --d2h-dark-change-label-color: rgb(210, 153, 34); + --d2h-dark-moved-label-color: #3572b0; +} + .d2h-wrapper { text-align: left; } @@ -13,10 +88,11 @@ display: flex; height: 35px; padding: 5px 10px; - border-bottom: 1px solid #d8d8d8; - background-color: #f7f7f7; + border-bottom: 1px solid var(--d2h-file-header-border-color); + background-color: var(--d2h-file-header-bg-color); font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif; } + .d2h-file-header.d2h-sticky-header { position: sticky; top: 0; @@ -33,18 +109,18 @@ .d2h-lines-added { text-align: right; - border: 1px solid #b4e2b4; + border: 1px solid var(--d2h-ins-border-color); border-radius: 5px 0 0 5px; - color: #399839; + color: var(--d2h-ins-label-color); padding: 2px; vertical-align: middle; } .d2h-lines-deleted { text-align: left; - border: 1px solid #e9aeae; + border: 1px solid var(--d2h-del-border-color); border-radius: 0 5px 5px 0; - color: #c33; + color: var(--d2h-del-label-color); padding: 2px; vertical-align: middle; margin-left: 1px; @@ -68,7 +144,7 @@ } .d2h-file-wrapper { - border: 1px solid #ddd; + border: 1px solid var(--d2h-border-color); border-radius: 3px; margin-bottom: 1em; } @@ -80,12 +156,12 @@ font-size: 12px; align-items: center; border-radius: 3px; - border: 1px solid #ddd; + border: 1px solid var(--d2h-border-color); padding: 4px 8px; } .d2h-file-collapse.d2h-selected { - background-color: #c8e1ff; + background-color: var(--d2h-selected-color); } .d2h-file-collapse-input { @@ -154,7 +230,7 @@ display: inline-block; margin-top: -1px; text-decoration: none; - background-color: #ffb6ba; + background-color: var(--d2h-del-highlight-bg-color); border-radius: 0.2em; } @@ -163,7 +239,7 @@ display: inline-block; margin-top: -1px; text-decoration: none; - background-color: #97f295; + background-color: var(--d2h-ins-highlight-bg-color); border-radius: 0.2em; text-align: left; } @@ -200,10 +276,10 @@ /* Keep the numbers fixed on line contents scroll */ position: absolute; display: inline-block; - background-color: #fff; - color: rgba(0, 0, 0, 0.3); + background-color: var(--d2h-bg-color); + color: var(--d2h-dim-color); text-align: right; - border: solid #eeeeee; + border: solid var(--d2h-line-border-color); border-width: 0 1px 0 1px; cursor: pointer; } @@ -218,10 +294,10 @@ display: inline-block; box-sizing: border-box; width: 4em; - background-color: #fff; - color: rgba(0, 0, 0, 0.3); + background-color: var(--d2h-bg-color); + color: var(--d2h-dim-color); text-align: right; - border: solid #eeeeee; + border: solid var(--d2h-line-border-color); border-width: 0 1px 0 1px; cursor: pointer; overflow: hidden; @@ -235,8 +311,8 @@ .d2h-code-side-emptyplaceholder, .d2h-emptyplaceholder { - background-color: #f1f1f1; - border-color: #e1e1e1; + background-color: var(--d2h-empty-placeholder-bg-color); + border-color: var(--d2h-empty-placeholder-border-color); } .d2h-code-linenumber, @@ -256,27 +332,27 @@ */ .d2h-del { - background-color: #fee8e9; - border-color: #e9aeae; + background-color: var(--d2h-del-bg-color); + border-color: var(--d2h-del-border-color); } .d2h-ins { - background-color: #dfd; - border-color: #b4e2b4; + background-color: var(--d2h-ins-bg-color); + border-color: var(--d2h-ins-border-color); } .d2h-info { - background-color: #f8fafd; - color: rgba(0, 0, 0, 0.3); - border-color: #d5e4f2; + background-color: var(--d2h-info-bg-color); + color: var(--d2h-dim-color); + border-color: var(--d2h-info-border-color); } .d2h-file-diff .d2h-del.d2h-change { - background-color: #fdf2d0; + background-color: var(--d2h-change-del-color); } .d2h-file-diff .d2h-ins.d2h-change { - background-color: #ded; + background-color: var(--d2h-change-ins-color); } /* @@ -289,11 +365,11 @@ .d2h-file-list-wrapper a { text-decoration: none; - color: #3572b0; + color: var(--d2h-moved-label-color); } .d2h-file-list-wrapper a:visited { - color: #3572b0; + color: var(--d2h-moved-label-color); } .d2h-file-list-header { @@ -319,7 +395,7 @@ } .d2h-file-list > li { - border-bottom: #ddd solid 1px; + border-bottom: var(--d2h-border-color) solid 1px; padding: 5px 10px; margin: 0; } @@ -341,19 +417,19 @@ } .d2h-deleted { - color: #c33; + color: var(--d2h-del-label-color); } .d2h-added { - color: #399839; + color: var(--d2h-ins-label-color); } .d2h-changed { - color: #d0b44c; + color: var(--d2h-change-label-color); } .d2h-moved { - color: #3572b0; + color: var(--d2h-moved-label-color); } .d2h-tag { @@ -363,21 +439,302 @@ font-size: 10px; margin-left: 5px; padding: 0 2px; - background-color: #fff; + background-color: var(--d2h-bg-color); } .d2h-deleted-tag { - border: #c33 1px solid; + border: var(--d2h-del-label-color) 1px solid; } .d2h-added-tag { - border: #399839 1px solid; + border: var(--d2h-ins-label-color) 1px solid; } .d2h-changed-tag { - border: #d0b44c 1px solid; + border: var(--d2h-change-label-color) 1px solid; } .d2h-moved-tag { - border: #3572b0 1px solid; + border: var(--d2h-moved-label-color) 1px solid; +} + +/** + * Dark Mode Colors + */ + +.d2h-dark-color-scheme { + color: var(--d2h-dark-color); + background-color: var(--d2h-dark-bg-color); +} + +.d2h-dark-color-scheme .d2h-file-header { + background-color: var(--d2h-dark-file-header-bg-color); + border-bottom: var(--d2h-dark-file-header-border-color); +} + +.d2h-dark-color-scheme .d2h-lines-added { + border: 1px solid var(--d2h-dark-ins-border-color); + color: var(--d2h-dark-ins-label-color); +} + +.d2h-dark-color-scheme .d2h-lines-deleted { + border: 1px solid var(--d2h-dark-del-border-color); + color: var(--d2h-dark-del-label-color); +} + +.d2h-dark-color-scheme .d2h-code-line del, +.d2h-dark-color-scheme .d2h-code-side-line del { + background-color: var(--d2h-dark-del-highlight-bg-color); +} + +.d2h-dark-color-scheme .d2h-code-line ins, +.d2h-dark-color-scheme .d2h-code-side-line ins { + background-color: var(--d2h-dark-ins-highlight-bg-color); +} + +.d2h-dark-color-scheme .d2h-diff-tbody { + border-color: var(--d2h-dark-border-color); +} + +.d2h-dark-color-scheme .d2h-code-side-linenumber { + background-color: var(--d2h-dark-bg-color); + color: var(--d2h-dark-dim-color); + border-color: var(--d2h-dark-line-border-color); +} + +.d2h-dark-color-scheme .d2h-files-diff .d2h-code-side-emptyplaceholder, +.d2h-dark-color-scheme .d2h-files-diff .d2h-emptyplaceholder { + background-color: var(--d2h-dark-empty-placeholder-bg-color); + border-color: var(--d2h-dark-empty-placeholder-border-color); +} + +.d2h-dark-color-scheme .d2h-code-linenumber { + background-color: var(--d2h-dark-bg-color); + color: var(--d2h-dark-dim-color); + border-color: var(--d2h-dark-line-border-color); +} + +.d2h-dark-color-scheme .d2h-del { + background-color: var(--d2h-dark-del-bg-color); + border-color: var(--d2h-dark-del-border-color); +} + +.d2h-dark-color-scheme .d2h-ins { + background-color: var(--d2h-dark-ins-bg-color); + border-color: var(--d2h-dark-ins-border-color); +} + +.d2h-dark-color-scheme .d2h-info { + background-color: var(--d2h-dark-info-bg-color); + color: var(--d2h-dark-dim-color); + border-color: var(--d2h-dark-info-border-color); +} + +.d2h-dark-color-scheme .d2h-file-diff .d2h-del.d2h-change { + background-color: var(--d2h-dark-change-del-color); +} + +.d2h-dark-color-scheme .d2h-file-diff .d2h-ins.d2h-change { + background-color: var(--d2h-dark-change-ins-color); +} + +.d2h-dark-color-scheme .d2h-file-wrapper { + border: 1px solid var(--d2h-dark-border-color); +} + +.d2h-dark-color-scheme .d2h-file-collapse { + border: 1px solid var(--d2h-dark-bg-color); +} + +.d2h-dark-color-scheme .d2h-file-collapse.d2h-selected { + background-color: var(--d2h-dark-selected-color); +} + +.d2h-dark-color-scheme .d2h-file-list-wrapper a { + color: var(--d2h-dark-moved-label-color); +} + +.d2h-dark-color-scheme .d2h-file-list-wrapper a:visited { + color: var(--d2h-dark-moved-label-color); +} + +.d2h-dark-color-scheme .d2h-file-list > li { + border-bottom: var(--d2h-dark-bg-color) solid 1px; +} + +.d2h-dark-color-scheme .d2h-deleted { + color: var(--d2h-dark-del-label-color); +} + +.d2h-dark-color-scheme .d2h-added { + color: var(--d2h-dark-ins-label-color); +} + +.d2h-dark-color-scheme .d2h-changed { + color: var(--d2h-dark-change-label-color); +} + +.d2h-dark-color-scheme .d2h-moved { + color: var(--d2h-dark-moved-label-color); +} + +.d2h-dark-color-scheme .d2h-tag { + background-color: var(--d2h-dark-bg-color); +} + +.d2h-dark-color-scheme .d2h-deleted-tag { + border: var(--d2h-dark-del-label-color) 1px solid; +} + +.d2h-dark-color-scheme .d2h-added-tag { + border: var(--d2h-dark-ins-label-color) 1px solid; +} + +.d2h-dark-color-scheme .d2h-changed-tag { + border: var(--d2h-dark-change-label-color) 1px solid; +} + +.d2h-dark-color-scheme .d2h-moved-tag { + border: var(--d2h-dark-moved-label-color) 1px solid; +} + +/** + * Auto Mode Colors + */ +@media (prefers-color-scheme: dark) { + .d2h-auto-color-scheme { + background-color: var(--d2h-dark-bg-color); + color: var(--d2h-dark-color); + } + + .d2h-auto-color-scheme .d2h-file-header { + background-color: var(--d2h-dark-file-header-bg-color); + border-bottom: var(--d2h-dark-file-header-border-color); + } + + .d2h-auto-color-scheme .d2h-lines-added { + border: 1px solid var(--d2h-dark-ins-border-color); + color: var(--d2h-dark-ins-label-color); + } + + .d2h-auto-color-scheme .d2h-lines-deleted { + border: 1px solid var(--d2h-dark-del-border-color); + color: var(--d2h-dark-del-label-color); + } + + .d2h-auto-color-scheme .d2h-code-line del, + .d2h-auto-color-scheme .d2h-code-side-line del { + background-color: var(--d2h-dark-del-highlight-bg-color); + } + + .d2h-auto-color-scheme .d2h-code-line ins, + .d2h-auto-color-scheme .d2h-code-side-line ins { + background-color: var(--d2h-dark-ins-highlight-bg-color); + } + + .d2h-auto-color-scheme .d2h-diff-tbody { + border-color: var(--d2h-dark-border-color); + } + + .d2h-auto-color-scheme .d2h-code-side-linenumber { + background-color: var(--d2h-dark-bg-color); + color: var(--d2h-dark-dim-color); + border-color: var(--d2h-dark-line-border-color); + } + + .d2h-auto-color-scheme .d2h-files-diff .d2h-code-side-emptyplaceholder, + .d2h-auto-color-scheme .d2h-files-diff .d2h-emptyplaceholder { + background-color: var(--d2h-dark-empty-placeholder-bg-color); + border-color: var(--d2h-dark-empty-placeholder-border-color); + } + + .d2h-auto-color-scheme .d2h-code-linenumber { + background-color: var(--d2h-dark-bg-color); + color: var(--d2h-dark-dim-color); + border-color: var(--d2h-dark-line-border-color); + } + + .d2h-auto-color-scheme .d2h-del { + background-color: var(--d2h-dark-del-bg-color); + border-color: var(--d2h-dark-del-border-color); + } + + .d2h-auto-color-scheme .d2h-ins { + background-color: var(--d2h-dark-ins-bg-color); + border-color: var(--d2h-dark-ins-border-color); + } + + .d2h-auto-color-scheme .d2h-info { + background-color: var(--d2h-dark-info-bg-color); + color: var(--d2h-dark-dim-color); + border-color: var(--d2h-dark-info-border-color); + } + + .d2h-auto-color-scheme .d2h-file-diff .d2h-del.d2h-change { + background-color: var(--d2h-dark-change-del-color); + } + + .d2h-auto-color-scheme .d2h-file-diff .d2h-ins.d2h-change { + background-color: var(--d2h-dark-change-ins-color); + } + + .d2h-auto-color-scheme .d2h-file-wrapper { + border: 1px solid var(--d2h-dark-border-color); + } + + .d2h-auto-color-scheme .d2h-file-collapse { + border: 1px solid var(--d2h-dark-bg-color); + } + + .d2h-auto-color-scheme .d2h-file-collapse.d2h-selected { + background-color: var(--d2h-dark-selected-color); + } + + .d2h-auto-color-scheme .d2h-file-list-wrapper a { + color: var(--d2h-dark-moved-label-color); + } + + .d2h-auto-color-scheme .d2h-file-list-wrapper a:visited { + color: var(--d2h-dark-moved-label-color); + } + + .d2h-auto-color-scheme .d2h-file-list > li { + border-bottom: var(--d2h-dark-bg-color) solid 1px; + } + + .d2h-dark-color-scheme .d2h-deleted { + color: var(--d2h-dark-del-label-color); + } + + .d2h-auto-color-scheme .d2h-added { + color: var(--d2h-dark-ins-label-color); + } + + .d2h-auto-color-scheme .d2h-changed { + color: var(--d2h-dark-change-label-color); + } + + .d2h-auto-color-scheme .d2h-moved { + color: var(--d2h-dark-moved-label-color); + } + + .d2h-auto-color-scheme .d2h-tag { + background-color: var(--d2h-dark-bg-color); + } + + .d2h-auto-color-scheme .d2h-deleted-tag { + border: var(--d2h-dark-del-label-color) 1px solid; + } + + .d2h-auto-color-scheme .d2h-added-tag { + border: var(--d2h-dark-ins-label-color) 1px solid; + } + + .d2h-auto-color-scheme .d2h-changed-tag { + border: var(--d2h-dark-change-label-color) 1px solid; + } + + .d2h-auto-color-scheme .d2h-moved-tag { + border: var(--d2h-dark-moved-label-color) 1px solid; + } } diff --git a/website/templates/pages/demo/content.handlebars b/website/templates/pages/demo/content.handlebars index 813b9b1..0db7b0a 100644 --- a/website/templates/pages/demo/content.handlebars +++ b/website/templates/pages/demo/content.handlebars @@ -2,7 +2,7 @@
-
+
-
+
+ +
+
-
+
-
+
-
+
- \ No newline at end of file + diff --git a/website/templates/pages/demo/demo.css b/website/templates/pages/demo/demo.css index f8e6cbb..e2ced3f 100644 --- a/website/templates/pages/demo/demo.css +++ b/website/templates/pages/demo/demo.css @@ -5,3 +5,21 @@ .diff-url-btn.is-small { font-size: 0.85rem; } + +.d2h-dark-color-scheme .title { + color: #fff; +} + +.d2h-dark-color-scheme .footer { + background-color: #2d2d2d; +} + +@media (prefers-color-scheme: dark) { + .d2h-auto-color-scheme .title { + color: #fff; + } + + .d2h-auto-color-scheme .footer { + background-color: #2d2d2d; + } +} diff --git a/website/templates/pages/demo/demo.ts b/website/templates/pages/demo/demo.ts index 53c7019..9475280 100644 --- a/website/templates/pages/demo/demo.ts +++ b/website/templates/pages/demo/demo.ts @@ -2,9 +2,11 @@ import { Diff2HtmlUI, defaultDiff2HtmlUIConfig, Diff2HtmlUIConfig } from '../../ import '../../../main.ts'; import '../../../main.css'; -import 'highlight.js/styles/github.css'; +import './github-highlights.css'; import '../../../../src/ui/css/diff2html.css'; import './demo.css'; +import { colorSchemeToCss } from '../../../../src/render-utils'; +import { ColorSchemeType } from '../../../../src/types'; /* * Example URLs: @@ -155,9 +157,16 @@ async function getDiff(request: Request): Promise { function draw(diffString: string, config: Diff2HtmlUIConfig, elements: Elements): void { const diff2htmlUi = new Diff2HtmlUI(elements.structure.diffTarget, diffString, config); + + setBodyColorScheme(diff2htmlUi.config.colorScheme); + diff2htmlUi.draw(); } +function setBodyColorScheme(colorScheme: ColorSchemeType): void { + document.body.className = colorSchemeToCss(colorScheme); +} + async function prepareInitialState(elements: Elements): Promise<[Diff2HtmlUIConfig, string]> { const urlParams = getParamsFromSearch(window.location.search); const currentUrl = (urlParams && urlParams[searchParam]) || 'https://github.com/rtfpessoa/diff2html/pull/106'; @@ -200,6 +209,7 @@ type Elements = { }; options: { outputFormat: HTMLInputElement; + colorScheme: HTMLInputElement; matching: HTMLInputElement; wordsThreshold: HTMLInputElement; matchingMaxComparisons: HTMLInputElement; @@ -259,6 +269,7 @@ document.addEventListener('DOMContentLoaded', async () => { }, options: { outputFormat: getHTMLInputElementById('diff-url-options-output-format'), + colorScheme: getHTMLInputElementById('diff-url-options-color-scheme'), matching: getHTMLInputElementById('diff-url-options-matching'), wordsThreshold: getHTMLInputElementById('diff-url-options-match-words-threshold'), matchingMaxComparisons: getHTMLInputElementById('diff-url-options-matching-max-comparisons'), @@ -272,6 +283,7 @@ document.addEventListener('DOMContentLoaded', async () => { // Update HTML inputs from any changes in URL config.outputFormat && (elements.options.outputFormat.value = config.outputFormat); + config.colorScheme && (elements.options.colorScheme.value = config.colorScheme); config.drawFileList && (elements.checkboxes.drawFileList.checked = config.drawFileList); config.matching && (elements.options.matching.value = config.matching); config.matchWordsThreshold && (elements.options.wordsThreshold.value = config.matchWordsThreshold.toString()); diff --git a/website/templates/pages/demo/github-highlights.css b/website/templates/pages/demo/github-highlights.css new file mode 100644 index 0000000..6492281 --- /dev/null +++ b/website/templates/pages/demo/github-highlights.css @@ -0,0 +1,332 @@ +/*! + Theme Adapted from highlight.js github theme + Theme: Modified GitHub Dark + Description: Dark theme as seen on github.com, modified for diff2html demo + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-dark + Current colors taken from GitHub's CSS +*/ + +pre code.hljs { + display: block; + overflow-x: auto; + padding: 1em; +} +code.hljs { + padding: 3px 5px; +} + +.hljs { + color: #24292e; +} +.hljs-doctag, +.hljs-keyword, +.hljs-meta .hljs-keyword, +.hljs-template-tag, +.hljs-template-variable, +.hljs-type, +.hljs-variable.language_ { + color: #d73a49; +} +.hljs-title, +.hljs-title.class_, +.hljs-title.class_.inherited__, +.hljs-title.function_ { + color: #6f42c1; +} +.hljs-attr, +.hljs-attribute, +.hljs-literal, +.hljs-meta, +.hljs-number, +.hljs-operator, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-selector-id, +.hljs-variable { + color: #005cc5; +} +.hljs-meta .hljs-string, +.hljs-regexp, +.hljs-string { + color: #032f62; +} +.hljs-built_in, +.hljs-symbol { + color: #e36209; +} +.hljs-code, +.hljs-comment, +.hljs-formula { + color: #6a737d; +} +.hljs-name, +.hljs-quote, +.hljs-selector-pseudo, +.hljs-selector-tag { + color: #22863a; +} +.hljs-subst { + color: #24292e; +} +.hljs-section { + color: #005cc5; + font-weight: 700; +} +.hljs-bullet { + color: #735c0f; +} +.hljs-emphasis { + color: #24292e; + font-style: italic; +} +.hljs-strong { + color: #24292e; + font-weight: 700; +} +.hljs-addition { + color: #22863a; + background-color: #f0fff4; +} +.hljs-deletion { + color: #b31d28; + background-color: #ffeef0; +} + +.d2h-dark-color-scheme .hljs { + color: #c9d1d9; +} +.d2h-dark-color-scheme .hljs-doctag, +.d2h-dark-color-scheme .hljs-keyword, +.d2h-dark-color-scheme .hljs-meta .hljs-keyword, +.d2h-dark-color-scheme .hljs-template-tag, +.d2h-dark-color-scheme .hljs-template-variable, +.d2h-dark-color-scheme .hljs-type, +.d2h-dark-color-scheme .hljs-variable.language_ { + color: #ff7b72; +} +.d2h-dark-color-scheme .hljs-title, +.d2h-dark-color-scheme .hljs-title.class_, +.d2h-dark-color-scheme .hljs-title.class_.inherited__, +.d2h-dark-color-scheme .hljs-title.function_ { + color: #d2a8ff; +} +.d2h-dark-color-scheme .hljs-attr, +.d2h-dark-color-scheme .hljs-attribute, +.d2h-dark-color-scheme .hljs-literal, +.d2h-dark-color-scheme .hljs-meta, +.d2h-dark-color-scheme .hljs-number, +.d2h-dark-color-scheme .hljs-operator, +.d2h-dark-color-scheme .hljs-selector-attr, +.d2h-dark-color-scheme .hljs-selector-class, +.d2h-dark-color-scheme .hljs-selector-id, +.d2h-dark-color-scheme .hljs-variable { + color: #79c0ff; +} +.d2h-dark-color-scheme .hljs-meta .hljs-string, +.d2h-dark-color-scheme .hljs-regexp, +.d2h-dark-color-scheme .hljs-string { + color: #a5d6ff; +} +.d2h-dark-color-scheme .hljs-built_in, +.d2h-dark-color-scheme .hljs-symbol { + color: #ffa657; +} +.d2h-dark-color-scheme .hljs-code, +.d2h-dark-color-scheme .hljs-comment, +.d2h-dark-color-scheme .hljs-formula { + color: #8b949e; +} +.d2h-dark-color-scheme .hljs-name, +.d2h-dark-color-scheme .hljs-quote, +.d2h-dark-color-scheme .hljs-selector-pseudo, +.d2h-dark-color-scheme .hljs-selector-tag { + color: #7ee787; +} +.d2h-dark-color-scheme .hljs-subst { + color: #c9d1d9; +} +.d2h-dark-color-scheme .hljs-section { + color: #1f6feb; + font-weight: 700; +} +.d2h-dark-color-scheme .hljs-bullet { + color: #f2cc60; +} +.d2h-dark-color-scheme .hljs-emphasis { + color: #c9d1d9; + font-style: italic; +} +.d2h-dark-color-scheme .hljs-strong { + color: #c9d1d9; + font-weight: 700; +} +.d2h-dark-color-scheme .hljs-addition { + color: #aff5b4; + background-color: #033a16; +} +.d2h-dark-color-scheme .hljs-deletion { + color: #ffdcd7; + background-color: #67060c; +} + +@media (prefers-color-scheme: dark) { + .d2h-auto-color-scheme .hljs { + color: #c9d1d9; + } + .d2h-auto-color-scheme .hljs-doctag, + .d2h-auto-color-scheme .hljs-keyword, + .d2h-auto-color-scheme .hljs-meta .hljs-keyword, + .d2h-auto-color-scheme .hljs-template-tag, + .d2h-auto-color-scheme .hljs-template-variable, + .d2h-auto-color-scheme .hljs-type, + .d2h-auto-color-scheme .hljs-variable.language_ { + color: #ff7b72; + } + .d2h-auto-color-scheme .hljs-title, + .d2h-auto-color-scheme .hljs-title.class_, + .d2h-auto-color-scheme .hljs-title.class_.inherited__, + .d2h-auto-color-scheme .hljs-title.function_ { + color: #d2a8ff; + } + .d2h-auto-color-scheme .hljs-attr, + .d2h-auto-color-scheme .hljs-attribute, + .d2h-auto-color-scheme .hljs-literal, + .d2h-auto-color-scheme .hljs-meta, + .d2h-auto-color-scheme .hljs-number, + .d2h-auto-color-scheme .hljs-operator, + .d2h-auto-color-scheme .hljs-selector-attr, + .d2h-auto-color-scheme .hljs-selector-class, + .d2h-auto-color-scheme .hljs-selector-id, + .d2h-auto-color-scheme .hljs-variable { + color: #79c0ff; + } + .d2h-auto-color-scheme .hljs-meta .hljs-string, + .d2h-auto-color-scheme .hljs-regexp, + .d2h-auto-color-scheme .hljs-string { + color: #a5d6ff; + } + .d2h-auto-color-scheme .hljs-built_in, + .d2h-auto-color-scheme .hljs-symbol { + color: #ffa657; + } + .d2h-auto-color-scheme .hljs-code, + .d2h-auto-color-scheme .hljs-comment, + .d2h-auto-color-scheme .hljs-formula { + color: #8b949e; + } + .d2h-auto-color-scheme .hljs-name, + .d2h-auto-color-scheme .hljs-quote, + .d2h-auto-color-scheme .hljs-selector-pseudo, + .d2h-auto-color-scheme .hljs-selector-tag { + color: #7ee787; + } + .d2h-auto-color-scheme .hljs-subst { + color: #c9d1d9; + } + .d2h-auto-color-scheme .hljs-section { + color: #1f6feb; + font-weight: 700; + } + .d2h-auto-color-scheme .hljs-bullet { + color: #f2cc60; + } + .d2h-auto-color-scheme .hljs-emphasis { + color: #c9d1d9; + font-style: italic; + } + .d2h-auto-color-scheme .hljs-strong { + color: #c9d1d9; + font-weight: 700; + } + .d2h-auto-color-scheme .hljs-addition { + color: #aff5b4; + background-color: #033a16; + } + .d2h-auto-color-scheme .hljs-deletion { + color: #ffdcd7; + background-color: #67060c; + } +} + +@media (prefers-color-scheme: light) { + .d2h-auto-color-scheme .hljs { + color: #24292e; + } + .d2h-auto-color-scheme .hljs-doctag, + .d2h-auto-color-scheme .hljs-keyword, + .d2h-auto-color-scheme .hljs-meta .hljs-keyword, + .d2h-auto-color-scheme .hljs-template-tag, + .d2h-auto-color-scheme .hljs-template-variable, + .d2h-auto-color-scheme .hljs-type, + .d2h-auto-color-scheme .hljs-variable.language_ { + color: #d73a49; + } + .d2h-auto-color-scheme .hljs-title, + .d2h-auto-color-scheme .hljs-title.class_, + .d2h-auto-color-scheme .hljs-title.class_.inherited__, + .d2h-auto-color-scheme .hljs-title.function_ { + color: #6f42c1; + } + .d2h-auto-color-scheme .hljs-attr, + .d2h-auto-color-scheme .hljs-attribute, + .d2h-auto-color-scheme .hljs-literal, + .d2h-auto-color-scheme .hljs-meta, + .d2h-auto-color-scheme .hljs-number, + .d2h-auto-color-scheme .hljs-operator, + .d2h-auto-color-scheme .hljs-selector-attr, + .d2h-auto-color-scheme .hljs-selector-class, + .d2h-auto-color-scheme .hljs-selector-id, + .d2h-auto-color-scheme .hljs-variable { + color: #005cc5; + } + .d2h-auto-color-scheme .hljs-meta .hljs-string, + .d2h-auto-color-scheme .hljs-regexp, + .d2h-auto-color-scheme .hljs-string { + color: #032f62; + } + .d2h-auto-color-scheme .hljs-built_in, + .d2h-auto-color-scheme .hljs-symbol { + color: #e36209; + } + .d2h-auto-color-scheme .hljs-code, + .d2h-auto-color-scheme .hljs-comment, + .d2h-auto-color-scheme .hljs-formula { + color: #6a737d; + } + .d2h-auto-color-scheme .hljs-name, + .d2h-auto-color-scheme .hljs-quote, + .d2h-auto-color-scheme .hljs-selector-pseudo, + .d2h-auto-color-scheme .hljs-selector-tag { + color: #22863a; + } + .d2h-auto-color-scheme .hljs-subst { + color: #24292e; + } + .d2h-auto-color-scheme .hljs-section { + color: #005cc5; + font-weight: 700; + } + .d2h-auto-color-scheme .hljs-bullet { + color: #735c0f; + } + .d2h-auto-color-scheme .hljs-emphasis { + color: #24292e; + font-style: italic; + } + .d2h-auto-color-scheme .hljs-strong { + color: #24292e; + font-weight: 700; + } + .d2h-auto-color-scheme .hljs-addition { + color: #22863a; + background-color: #f0fff4; + } + .d2h-auto-color-scheme .hljs-deletion { + color: #b31d28; + background-color: #ffeef0; + } +}