Merge pull request #297 from rtfpessoa/release-major-version
release: New major refactor of diff2html to Typescript
This commit is contained in:
commit
8731f97266
10 changed files with 1112 additions and 955 deletions
|
|
@ -10,16 +10,15 @@ jobs:
|
||||||
- run:
|
- run:
|
||||||
name: Get next version
|
name: Get next version
|
||||||
command: |
|
command: |
|
||||||
# Hack: Set a unique fake name for the release branch to avoid releasing master as the new 3.x major release for now
|
export NEXT_VERSION="$(/bin/git-version --folder=$PWD --release-branch=master)"
|
||||||
export NEXT_VERSION="$(/bin/git-version --folder=$PWD --release-branch=FAKE-RELEASE-BRANCH-NAME)"
|
|
||||||
echo "Next version is ${NEXT_VERSION}"
|
echo "Next version is ${NEXT_VERSION}"
|
||||||
echo "${NEXT_VERSION}" > .version
|
echo "${NEXT_VERSION}" > .version
|
||||||
- run:
|
- run:
|
||||||
name: Get next npm tag name
|
name: Get next npm tag name
|
||||||
command: |
|
command: |
|
||||||
if [ "${GITHUB_REF#refs/heads/}" = "master" ]; then
|
if [ "${CIRCLE_BRANCH}" = "master" ]; then
|
||||||
export PUBLISH_TAG="latest"
|
export PUBLISH_TAG="latest"
|
||||||
elif [ "${GITHUB_REF#refs/heads/}" = "next" ]; then
|
elif [ "${CIRCLE_BRANCH}" = "next" ]; then
|
||||||
export PUBLISH_TAG="next"
|
export PUBLISH_TAG="next"
|
||||||
else
|
else
|
||||||
export PUBLISH_TAG="pr"
|
export PUBLISH_TAG="pr"
|
||||||
|
|
@ -132,6 +131,7 @@ jobs:
|
||||||
command: |
|
command: |
|
||||||
# Update version in packages to publish
|
# Update version in packages to publish
|
||||||
yarn version --non-interactive --new-version $(cat .version)
|
yarn version --non-interactive --new-version $(cat .version)
|
||||||
|
git push --tags "https://rtfpessoa:$GPR_AUTH_TOKEN@github.com/rtfpessoa/diff2html"
|
||||||
- run:
|
- run:
|
||||||
name: Setup npm credentials
|
name: Setup npm credentials
|
||||||
command: |
|
command: |
|
||||||
|
|
@ -208,3 +208,7 @@ workflows:
|
||||||
- publish_website:
|
- publish_website:
|
||||||
requires:
|
requires:
|
||||||
- publish_approval
|
- publish_approval
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
|
||||||
22
README.md
22
README.md
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
[]() []()
|
[]() []()
|
||||||
[](https://www.npmjs.com/package/diff2html)
|
[](https://www.npmjs.com/package/diff2html)
|
||||||
[](#contributors-)
|
[](#contributors)
|
||||||
[](https://gitter.im/rtfpessoa/diff2html?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[](https://gitter.im/rtfpessoa/diff2html?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
|
|
||||||
diff2html generates pretty HTML diffs from git diff or unified diff output.
|
diff2html generates pretty HTML diffs from git diff or unified diff output.
|
||||||
|
|
@ -25,13 +25,14 @@ diff2html generates pretty HTML diffs from git diff or unified diff output.
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Online Example](#online-example)
|
- [Online Example](#online-example)
|
||||||
- [Distributions](#distributions)
|
- [Distributions](#distributions)
|
||||||
|
- [Usage](#usage)
|
||||||
- [Diff2Html Usage](#diff2html-usage)
|
- [Diff2Html Usage](#diff2html-usage)
|
||||||
- [Diff2Html API](#diff2html-api)
|
- [Diff2Html API](#diff2html-api)
|
||||||
- [Diff2Html Configuration](#diff2html-configuration)
|
- [Diff2Html Configuration](#diff2html-configuration)
|
||||||
- [Diff2Html Browser](#diff2html-browser)
|
- [Diff2Html Browser](#diff2html-browser)
|
||||||
- [Diff2Html NPM / Node.js Library](#diff2html-npm--nodejs-library)
|
- [Diff2Html NPM / Node.js Library](#diff2html-npm--nodejs-library)
|
||||||
- [Diff2Html Examples](#diff2html-examples)
|
- [Diff2Html Examples](#diff2html-examples)
|
||||||
- [Diff2HtmlUI](#diff2htmlui)
|
- [Diff2HtmlUI Usage](#diff2htmlui-usage)
|
||||||
- [Diff2HtmlUI API](#diff2htmlui-api)
|
- [Diff2HtmlUI API](#diff2htmlui-api)
|
||||||
- [Diff2HtmlUI Configuration](#diff2htmlui-configuration)
|
- [Diff2HtmlUI Configuration](#diff2htmlui-configuration)
|
||||||
- [Diff2HtmlUI Browser](#diff2htmlui-browser)
|
- [Diff2HtmlUI Browser](#diff2htmlui-browser)
|
||||||
|
|
@ -101,6 +102,17 @@ diff2html generates pretty HTML diffs from git diff or unified diff output.
|
||||||
including a `highlight.js` implementation. You can use it without syntax highlight or by passing your own
|
including a `highlight.js` implementation. You can use it without syntax highlight or by passing your own
|
||||||
implementation with the languages you prefer
|
implementation with the languages you prefer
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Diff2Html can be used in various ways as listed in the [distributions](#distributions) section. The two main ways are:
|
||||||
|
|
||||||
|
- [Diff2Html](#diff2html-usage): using the parser and html generator directly from the library gives you complete
|
||||||
|
control about what you can do with the json or html generated.
|
||||||
|
- [Diff2HtmlUI](#diff2htmlui-usage): using this wrapper makes it easy to inject the html in the DOM and adds some nice
|
||||||
|
features to the diff, like syntax highlight.
|
||||||
|
|
||||||
|
Bellow you can find more details and exemples about each option.
|
||||||
|
|
||||||
## Diff2Html Usage
|
## Diff2Html Usage
|
||||||
|
|
||||||
To load correctly in the Browser you always need to include the stylesheet in the final HTML.
|
To load correctly in the Browser you always need to include the stylesheet in the final HTML.
|
||||||
|
|
@ -135,11 +147,11 @@ function html(diffInput: string | DiffFile[], configuration: Diff2HtmlConfig = {
|
||||||
The HTML output accepts a Javascript object with configuration. Possible options:
|
The HTML output accepts a Javascript object with configuration. Possible options:
|
||||||
|
|
||||||
- `outputFormat`: the format of the output data: `'line-by-line'` or `'side-by-side'`, default is `'line-by-line'`
|
- `outputFormat`: the format of the output data: `'line-by-line'` or `'side-by-side'`, default is `'line-by-line'`
|
||||||
- `drawFileList`: show a file list before the diff: `true` or `false`, default is `false`
|
- `drawFileList`: show a file list before the diff: `true` or `false`, default is `true`
|
||||||
- `diffStyle`: show differences level in each line: `word` or `char`, default is `word`
|
- `diffStyle`: show differences level in each line: `word` or `char`, default is `word`
|
||||||
- `matching`: matching level: `'lines'` for matching lines, `'words'` for matching lines and words or `'none'`, default
|
- `matching`: matching level: `'lines'` for matching lines, `'words'` for matching lines and words or `'none'`, default
|
||||||
is `none`
|
is `none`
|
||||||
- `matchWordsThreshold`: similarity threshold for word matching, default is 0.25
|
- `matchWordsThreshold`: similarity threshold for word matching, default is `0.25`
|
||||||
- `matchingMaxComparisons`: perform at most this much comparisons for line matching a block of changes, default is
|
- `matchingMaxComparisons`: perform at most this much comparisons for line matching a block of changes, default is
|
||||||
`2500`
|
`2500`
|
||||||
- `maxLineSizeInBlockForComparison`: maximum number os characters of the bigger line in a block to apply comparison,
|
- `maxLineSizeInBlockForComparison`: maximum number os characters of the bigger line in a block to apply comparison,
|
||||||
|
|
@ -266,7 +278,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Diff2HtmlUI
|
## Diff2HtmlUI Usage
|
||||||
|
|
||||||
> Simple wrapper to ease simple tasks in the browser such as: code highlight and js effects
|
> Simple wrapper to ease simple tasks in the browser such as: code highlight and js effects
|
||||||
|
|
||||||
|
|
|
||||||
48
package.json
48
package.json
|
|
@ -26,7 +26,7 @@
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://www.github.com/rtfpessoa/diff2html.git"
|
"url": "git://github.com/rtfpessoa/diff2html.git"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://www.github.com/rtfpessoa/diff2html/issues"
|
"url": "https://www.github.com/rtfpessoa/diff2html/issues"
|
||||||
|
|
@ -48,8 +48,9 @@
|
||||||
"build:css": "rm -rf ./bundles/css; postcss --config ./postcss.config.js --no-map -o ./bundles/css/diff2html.min.css ./src/ui/css/diff2html.css",
|
"build:css": "rm -rf ./bundles/css; postcss --config ./postcss.config.js --no-map -o ./bundles/css/diff2html.min.css ./src/ui/css/diff2html.css",
|
||||||
"build:templates": "ts-node ./scripts/hulk.ts --wrapper ts --variable 'defaultTemplates' ./src/templates/*.mustache > ./src/diff2html-templates.ts",
|
"build:templates": "ts-node ./scripts/hulk.ts --wrapper ts --variable 'defaultTemplates' ./src/templates/*.mustache > ./src/diff2html-templates.ts",
|
||||||
"build:website": "rm -rf docs; webpack ---display-reasons --display-modules --mode production --config webpack.website.ts",
|
"build:website": "rm -rf docs; webpack ---display-reasons --display-modules --mode production --config webpack.website.ts",
|
||||||
"build:toc-base": "markdown-toc --maxdepth 3 --bullets='-' -i",
|
"gen": "yarn run gen:toc",
|
||||||
"build:toc": "yarn run build:toc-base README.md",
|
"gen:toc-base": "markdown-toc --maxdepth 3 --bullets='-' -i",
|
||||||
|
"gen:toc": "yarn run gen:toc-base README.md",
|
||||||
"test": "is-ci 'test:coverage' 'test:watch'",
|
"test": "is-ci 'test:coverage' 'test:watch'",
|
||||||
"test:coverage": "jest --coverage",
|
"test:coverage": "jest --coverage",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
|
|
@ -74,16 +75,13 @@
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"**/*.+(js|jsx|ts|tsx|json)": [
|
"**/*.+(js|jsx|ts|tsx|json)": [
|
||||||
"prettier --write",
|
"prettier --write",
|
||||||
"eslint --fix",
|
"eslint --fix"
|
||||||
"git add"
|
|
||||||
],
|
],
|
||||||
"**/*.+(css|html|md|mdx)": [
|
"**/*.+(css|html|md|mdx)": [
|
||||||
"prettier --write",
|
"prettier --write"
|
||||||
"git add"
|
|
||||||
],
|
],
|
||||||
"README.md": [
|
"README.md": [
|
||||||
"yarn run build:toc-base",
|
"yarn run gen:toc-base"
|
||||||
"git add"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -91,7 +89,7 @@
|
||||||
"hogan.js": "3.0.2"
|
"hogan.js": "3.0.2"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"highlight.js": "9.17.1"
|
"highlight.js": "9.18.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/clipboard": "2.0.1",
|
"@types/clipboard": "2.0.1",
|
||||||
|
|
@ -99,15 +97,15 @@
|
||||||
"@types/diff": "4.0.2",
|
"@types/diff": "4.0.2",
|
||||||
"@types/highlight.js": "9.12.3",
|
"@types/highlight.js": "9.12.3",
|
||||||
"@types/hogan.js": "3.0.0",
|
"@types/hogan.js": "3.0.0",
|
||||||
"@types/html-webpack-plugin": "3.2.1",
|
"@types/html-webpack-plugin": "3.2.2",
|
||||||
"@types/jest": "24.9.0",
|
"@types/jest": "25.1.1",
|
||||||
"@types/mini-css-extract-plugin": "0.9.0",
|
"@types/mini-css-extract-plugin": "0.9.0",
|
||||||
"@types/mkdirp": "0.5.2",
|
"@types/mkdirp": "0.5.2",
|
||||||
"@types/node": "13.1.8",
|
"@types/node": "13.7.0",
|
||||||
"@types/nopt": "3.0.29",
|
"@types/nopt": "3.0.29",
|
||||||
"@types/webpack": "4.41.2",
|
"@types/webpack": "4.41.5",
|
||||||
"@typescript-eslint/eslint-plugin": "2.16.0",
|
"@typescript-eslint/eslint-plugin": "2.19.0",
|
||||||
"@typescript-eslint/parser": "2.16.0",
|
"@typescript-eslint/parser": "2.19.0",
|
||||||
"autoprefixer": "9.7.4",
|
"autoprefixer": "9.7.4",
|
||||||
"bulma": "^0.8.0",
|
"bulma": "^0.8.0",
|
||||||
"clipboard": "2.0.4",
|
"clipboard": "2.0.4",
|
||||||
|
|
@ -116,8 +114,8 @@
|
||||||
"css-loader": "3.4.2",
|
"css-loader": "3.4.2",
|
||||||
"cssnano": "4.1.10",
|
"cssnano": "4.1.10",
|
||||||
"eslint": "6.8.0",
|
"eslint": "6.8.0",
|
||||||
"eslint-config-prettier": "6.9.0",
|
"eslint-config-prettier": "6.10.0",
|
||||||
"eslint-plugin-import": "2.20.0",
|
"eslint-plugin-import": "2.20.1",
|
||||||
"eslint-plugin-jest": "23.6.0",
|
"eslint-plugin-jest": "23.6.0",
|
||||||
"eslint-plugin-json": "2.0.1",
|
"eslint-plugin-json": "2.0.1",
|
||||||
"eslint-plugin-node": "11.0.0",
|
"eslint-plugin-node": "11.0.0",
|
||||||
|
|
@ -125,17 +123,17 @@
|
||||||
"eslint-plugin-promise": "4.2.1",
|
"eslint-plugin-promise": "4.2.1",
|
||||||
"eslint-plugin-sonarjs": "0.5.0",
|
"eslint-plugin-sonarjs": "0.5.0",
|
||||||
"file-loader": "5.0.2",
|
"file-loader": "5.0.2",
|
||||||
"handlebars": "4.7.2",
|
"handlebars": "4.7.3",
|
||||||
"handlebars-loader": "1.7.1",
|
"handlebars-loader": "1.7.1",
|
||||||
"html-webpack-plugin": "3.2.0",
|
"html-webpack-plugin": "3.2.0",
|
||||||
"husky": "4.0.10",
|
"husky": "4.2.1",
|
||||||
"image-webpack-loader": "6.0.0",
|
"image-webpack-loader": "6.0.0",
|
||||||
"is-ci-cli": "2.0.0",
|
"is-ci-cli": "2.0.0",
|
||||||
"jest": "24.9.0",
|
"jest": "25.1.0",
|
||||||
"lint-staged": "9.5.0",
|
"lint-staged": "10.0.7",
|
||||||
"markdown-toc": "^1.2.0",
|
"markdown-toc": "^1.2.0",
|
||||||
"mini-css-extract-plugin": "0.9.0",
|
"mini-css-extract-plugin": "0.9.0",
|
||||||
"mkdirp": "0.5.1",
|
"mkdirp": "1.0.3",
|
||||||
"nopt": "4.0.1",
|
"nopt": "4.0.1",
|
||||||
"postcss": "7.0.26",
|
"postcss": "7.0.26",
|
||||||
"postcss-cli": "7.1.0",
|
"postcss-cli": "7.1.0",
|
||||||
|
|
@ -143,14 +141,14 @@
|
||||||
"postcss-loader": "3.0.0",
|
"postcss-loader": "3.0.0",
|
||||||
"postcss-preset-env": "6.7.0",
|
"postcss-preset-env": "6.7.0",
|
||||||
"prettier": "1.19.1",
|
"prettier": "1.19.1",
|
||||||
"ts-jest": "24.3.0",
|
"ts-jest": "25.2.0",
|
||||||
"ts-loader": "6.2.1",
|
"ts-loader": "6.2.1",
|
||||||
"ts-node": "8.6.2",
|
"ts-node": "8.6.2",
|
||||||
"typescript": "3.7.5",
|
"typescript": "3.7.5",
|
||||||
"url-loader": "3.0.0",
|
"url-loader": "3.0.0",
|
||||||
"webpack": "4.41.5",
|
"webpack": "4.41.5",
|
||||||
"webpack-cli": "3.3.10",
|
"webpack-cli": "3.3.10",
|
||||||
"webpack-dev-server": "3.10.1",
|
"webpack-dev-server": "3.10.3",
|
||||||
"whatwg-fetch": "3.0.0"
|
"whatwg-fetch": "3.0.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,22 @@ import { unifyPath, hashCode } from './utils';
|
||||||
import * as rematch from './rematch';
|
import * as rematch from './rematch';
|
||||||
import { LineMatchingType, DiffStyleType, LineType, DiffLineParts, DiffFile, DiffFileName } from './types';
|
import { LineMatchingType, DiffStyleType, LineType, DiffLineParts, DiffFile, DiffFileName } from './types';
|
||||||
|
|
||||||
export enum CSSLineClass {
|
export type CSSLineClass =
|
||||||
INSERTS = 'd2h-ins',
|
| 'd2h-ins'
|
||||||
DELETES = 'd2h-del',
|
| 'd2h-del'
|
||||||
CONTEXT = 'd2h-cntx',
|
| 'd2h-cntx'
|
||||||
INFO = 'd2h-info',
|
| 'd2h-info'
|
||||||
INSERT_CHANGES = 'd2h-ins d2h-change',
|
| 'd2h-ins d2h-change'
|
||||||
DELETE_CHANGES = 'd2h-del d2h-change',
|
| 'd2h-del d2h-change';
|
||||||
}
|
|
||||||
|
export const CSSLineClass: { [_: string]: CSSLineClass } = {
|
||||||
|
INSERTS: 'd2h-ins',
|
||||||
|
DELETES: 'd2h-del',
|
||||||
|
CONTEXT: 'd2h-cntx',
|
||||||
|
INFO: 'd2h-info',
|
||||||
|
INSERT_CHANGES: 'd2h-ins d2h-change',
|
||||||
|
DELETE_CHANGES: 'd2h-del d2h-change',
|
||||||
|
};
|
||||||
|
|
||||||
export type HighlightedLines = {
|
export type HighlightedLines = {
|
||||||
oldLine: {
|
oldLine: {
|
||||||
|
|
|
||||||
32
src/types.ts
32
src/types.ts
|
|
@ -69,18 +69,24 @@ export interface DiffFile extends DiffFileName {
|
||||||
mode?: string;
|
mode?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OutputFormatType {
|
export type OutputFormatType = 'line-by-line' | 'side-by-side';
|
||||||
LINE_BY_LINE = 'line-by-line',
|
|
||||||
SIDE_BY_SIDE = 'side-by-side',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum LineMatchingType {
|
export const OutputFormatType: { [_: string]: OutputFormatType } = {
|
||||||
LINES = 'lines',
|
LINE_BY_LINE: 'line-by-line',
|
||||||
WORDS = 'words',
|
SIDE_BY_SIDE: 'side-by-side',
|
||||||
NONE = 'none',
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export enum DiffStyleType {
|
export type LineMatchingType = 'lines' | 'words' | 'none';
|
||||||
WORD = 'word',
|
|
||||||
CHAR = 'char',
|
export const LineMatchingType: { [_: string]: LineMatchingType } = {
|
||||||
}
|
LINES: 'lines',
|
||||||
|
WORDS: 'words',
|
||||||
|
NONE: 'none',
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DiffStyleType = 'word' | 'char';
|
||||||
|
|
||||||
|
export const DiffStyleType: { [_: string]: DiffStyleType } = {
|
||||||
|
WORD: 'word',
|
||||||
|
CHAR: 'char',
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,13 @@ export class Diff2HtmlUI {
|
||||||
|
|
||||||
synchronisedScroll(): void {
|
synchronisedScroll(): void {
|
||||||
this.targetElement.querySelectorAll('.d2h-file-wrapper').forEach(wrapper => {
|
this.targetElement.querySelectorAll('.d2h-file-wrapper').forEach(wrapper => {
|
||||||
const [left, right] = [].slice.call(wrapper.querySelectorAll('.d2h-file-side-diff')) as HTMLElement[];
|
const [left, right] = Array<Element>().slice.call(wrapper.querySelectorAll('.d2h-file-side-diff'));
|
||||||
|
|
||||||
if (left === undefined || right === undefined) return;
|
if (left === undefined || right === undefined) return;
|
||||||
|
|
||||||
const onScroll = (event: Event): void => {
|
const onScroll = (event: Event): void => {
|
||||||
if (event === null || event.target === null) return;
|
if (event === null || event.target === null) return;
|
||||||
|
|
||||||
if (event.target === left) {
|
if (event.target === left) {
|
||||||
right.scrollTop = left.scrollTop;
|
right.scrollTop = left.scrollTop;
|
||||||
right.scrollLeft = left.scrollLeft;
|
right.scrollLeft = left.scrollLeft;
|
||||||
|
|
@ -70,29 +73,28 @@ export class Diff2HtmlUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
fileListToggle(startVisible: boolean): void {
|
fileListToggle(startVisible: boolean): void {
|
||||||
const hashTag = this.getHashTag();
|
const showBtn: HTMLElement | null = this.targetElement.querySelector('d2h-show');
|
||||||
|
const hideBtn: HTMLElement | null = this.targetElement.querySelector('.d2h-hide');
|
||||||
const showBtn = this.targetElement.querySelector('.d2h-show') as HTMLElement;
|
const fileList: HTMLElement | null = this.targetElement.querySelector('.d2h-file-list');
|
||||||
const hideBtn = this.targetElement.querySelector('.d2h-hide') as HTMLElement;
|
|
||||||
const fileList = this.targetElement.querySelector('.d2h-file-list') as HTMLElement;
|
|
||||||
|
|
||||||
if (showBtn === null || hideBtn === null || fileList === null) return;
|
if (showBtn === null || hideBtn === null || fileList === null) return;
|
||||||
|
|
||||||
function show(): void {
|
const show: () => void = () => {
|
||||||
showBtn.style.display = 'none';
|
showBtn.style.display = 'none';
|
||||||
hideBtn.style.display = 'inline';
|
hideBtn.style.display = 'inline';
|
||||||
fileList.style.display = 'block';
|
fileList.style.display = 'block';
|
||||||
}
|
};
|
||||||
|
|
||||||
function hide(): void {
|
const hide: () => void = () => {
|
||||||
showBtn.style.display = 'inline';
|
showBtn.style.display = 'inline';
|
||||||
hideBtn.style.display = 'none';
|
hideBtn.style.display = 'none';
|
||||||
fileList.style.display = 'none';
|
fileList.style.display = 'none';
|
||||||
}
|
};
|
||||||
|
|
||||||
showBtn.addEventListener('click', () => show());
|
showBtn.addEventListener('click', () => show());
|
||||||
hideBtn.addEventListener('click', () => hide());
|
hideBtn.addEventListener('click', () => hide());
|
||||||
|
|
||||||
|
const hashTag = this.getHashTag();
|
||||||
if (hashTag === 'files-summary-show') show();
|
if (hashTag === 'files-summary-show') show();
|
||||||
else if (hashTag === 'files-summary-hide') hide();
|
else if (hashTag === 'files-summary-hide') hide();
|
||||||
else if (startVisible) show();
|
else if (startVisible) show();
|
||||||
|
|
@ -117,11 +119,11 @@ export class Diff2HtmlUI {
|
||||||
if (this.hljs === null) return;
|
if (this.hljs === null) return;
|
||||||
|
|
||||||
const text = line.textContent;
|
const text = line.textContent;
|
||||||
const lineParent = line.parentNode as HTMLElement;
|
const lineParent = line.parentNode;
|
||||||
|
|
||||||
if (lineParent === null || text === null) return;
|
if (text === null || lineParent === null || !this.isElement(lineParent)) return;
|
||||||
|
|
||||||
const lineState = lineParent.className.indexOf('d2h-del') !== -1 ? oldLinesState : newLinesState;
|
const lineState = lineParent.classList.contains('d2h-del') ? oldLinesState : newLinesState;
|
||||||
|
|
||||||
const language = file.getAttribute('data-lang');
|
const language = file.getAttribute('data-lang');
|
||||||
const result =
|
const result =
|
||||||
|
|
@ -130,9 +132,9 @@ export class Diff2HtmlUI {
|
||||||
: this.hljs.highlightAuto(text);
|
: this.hljs.highlightAuto(text);
|
||||||
|
|
||||||
if (this.instanceOfIHighlightResult(result)) {
|
if (this.instanceOfIHighlightResult(result)) {
|
||||||
if (lineParent.className.indexOf('d2h-del') !== -1) {
|
if (lineParent.classList.contains('d2h-del')) {
|
||||||
oldLinesState = result.top;
|
oldLinesState = result.top;
|
||||||
} else if (lineParent.className.indexOf('d2h-ins') !== -1) {
|
} else if (lineParent.classList.contains('d2h-ins')) {
|
||||||
newLinesState = result.top;
|
newLinesState = result.top;
|
||||||
} else {
|
} else {
|
||||||
oldLinesState = result.top;
|
oldLinesState = result.top;
|
||||||
|
|
@ -159,18 +161,15 @@ export class Diff2HtmlUI {
|
||||||
const diffTable = body.getElementsByClassName('d2h-diff-table')[0];
|
const diffTable = body.getElementsByClassName('d2h-diff-table')[0];
|
||||||
|
|
||||||
diffTable.addEventListener('mousedown', event => {
|
diffTable.addEventListener('mousedown', event => {
|
||||||
if (event === null || event.target === null) return;
|
if (event === null || !this.isElement(event.target)) return;
|
||||||
|
|
||||||
const mouseEvent = event as MouseEvent;
|
|
||||||
const target = mouseEvent.target as HTMLElement;
|
|
||||||
const table = target.closest('.d2h-diff-table');
|
|
||||||
|
|
||||||
|
const table = event.target.closest('.d2h-diff-table');
|
||||||
if (table !== null) {
|
if (table !== null) {
|
||||||
if (target.closest('.d2h-code-line,.d2h-code-side-line') !== null) {
|
if (event.target.closest('.d2h-code-line,.d2h-code-side-line') !== null) {
|
||||||
table.classList.remove('selecting-left');
|
table.classList.remove('selecting-left');
|
||||||
table.classList.add('selecting-right');
|
table.classList.add('selecting-right');
|
||||||
this.currentSelectionColumnId = 1;
|
this.currentSelectionColumnId = 1;
|
||||||
} else if (target.closest('.d2h-code-linenumber,.d2h-code-side-linenumber') !== null) {
|
} else if (event.target.closest('.d2h-code-linenumber,.d2h-code-side-linenumber') !== null) {
|
||||||
table.classList.remove('selecting-right');
|
table.classList.remove('selecting-right');
|
||||||
table.classList.add('selecting-left');
|
table.classList.add('selecting-left');
|
||||||
this.currentSelectionColumnId = 0;
|
this.currentSelectionColumnId = 0;
|
||||||
|
|
@ -179,8 +178,9 @@ export class Diff2HtmlUI {
|
||||||
});
|
});
|
||||||
|
|
||||||
diffTable.addEventListener('copy', event => {
|
diffTable.addEventListener('copy', event => {
|
||||||
const clipboardEvent = event as ClipboardEvent;
|
if (!this.isClipboardEvent(event)) return;
|
||||||
const clipboardData = clipboardEvent.clipboardData;
|
|
||||||
|
const clipboardData = event.clipboardData;
|
||||||
const text = this.getSelectedText();
|
const text = this.getSelectedText();
|
||||||
|
|
||||||
if (clipboardData === null || text === undefined) return;
|
if (clipboardData === null || text === undefined) return;
|
||||||
|
|
@ -231,4 +231,12 @@ export class Diff2HtmlUI {
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isElement(arg?: unknown): arg is Element {
|
||||||
|
return arg !== null && (arg as Element)?.classList !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isClipboardEvent(arg?: unknown): arg is ClipboardEvent {
|
||||||
|
return arg !== null && (arg as ClipboardEvent)?.clipboardData !== undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,10 @@ export function mergeStreams(original: NodeEvent[], highlighted: NodeEvent[], va
|
||||||
let result = '';
|
let result = '';
|
||||||
const nodeStack = [];
|
const nodeStack = [];
|
||||||
|
|
||||||
|
function isElement(arg?: unknown): arg is Element {
|
||||||
|
return arg !== null && (arg as Element)?.attributes !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function selectStream(): NodeEvent[] {
|
function selectStream(): NodeEvent[] {
|
||||||
if (!original.length || !highlighted.length) {
|
if (!original.length || !highlighted.length) {
|
||||||
return original.length ? original : highlighted;
|
return original.length ? original : highlighted;
|
||||||
|
|
@ -88,9 +92,12 @@ export function mergeStreams(original: NodeEvent[], highlighted: NodeEvent[], va
|
||||||
}
|
}
|
||||||
|
|
||||||
function open(node: Node): void {
|
function open(node: Node): void {
|
||||||
const htmlNode = node as HTMLElement;
|
if (!isElement(node)) {
|
||||||
result += `<${tag(node)} ${[].map
|
throw new Error('Node is not an Element');
|
||||||
.call(htmlNode.attributes, (attr: Attr) => `${attr.nodeName}="${escape(attr.value)}"`)
|
}
|
||||||
|
|
||||||
|
result += `<${tag(node)} ${Array<Attr>()
|
||||||
|
.map.call(node.attributes, attr => `${attr.nodeName}="${escape(attr.value)}"`)
|
||||||
.join(' ')}>`;
|
.join(' ')}>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,30 @@ type Elements = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isHTMLInputElement(arg?: unknown): arg is HTMLInputElement {
|
||||||
|
return arg !== null && (arg as HTMLInputElement)?.value !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHTMLInputElementById(id: string): HTMLInputElement {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
|
||||||
|
if (!isHTMLInputElement(element)) {
|
||||||
|
throw new Error(`Could not find html input element with id '${id}'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHTMLElementById(id: string): HTMLElement {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
|
||||||
|
if (element === null) {
|
||||||
|
throw new Error(`Could not find html element with id '${id}'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
// Improves browser compatibility
|
// Improves browser compatibility
|
||||||
require('whatwg-fetch');
|
require('whatwg-fetch');
|
||||||
|
|
@ -226,20 +250,20 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
const elements: Elements = {
|
const elements: Elements = {
|
||||||
structure: {
|
structure: {
|
||||||
diffTarget: document.getElementById('url-diff-container') as HTMLElement,
|
diffTarget: getHTMLElementById('url-diff-container'),
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
input: document.getElementById('url') as HTMLInputElement,
|
input: getHTMLInputElementById('url'),
|
||||||
button: document.getElementById('url-btn') as HTMLElement,
|
button: getHTMLElementById('url-btn'),
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
outputFormat: document.getElementById('diff-url-options-output-format') as HTMLInputElement,
|
outputFormat: getHTMLInputElementById('diff-url-options-output-format'),
|
||||||
matching: document.getElementById('diff-url-options-matching') as HTMLInputElement,
|
matching: getHTMLInputElementById('diff-url-options-matching'),
|
||||||
wordsThreshold: document.getElementById('diff-url-options-match-words-threshold') as HTMLInputElement,
|
wordsThreshold: getHTMLInputElementById('diff-url-options-match-words-threshold'),
|
||||||
matchingMaxComparisons: document.getElementById('diff-url-options-matching-max-comparisons') as HTMLInputElement,
|
matchingMaxComparisons: getHTMLInputElementById('diff-url-options-matching-max-comparisons'),
|
||||||
},
|
},
|
||||||
checkboxes: {
|
checkboxes: {
|
||||||
drawFileList: document.getElementById('diff-url-options-show-files') as HTMLInputElement,
|
drawFileList: getHTMLInputElementById('diff-url-options-show-files'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
<a class="navbar-item" href="index.html#install">Getting Started</a>
|
<a class="navbar-item" href="index.html#install">Getting Started</a>
|
||||||
<a class="navbar-item" href="index.html#cli">CLI</a>
|
<a class="navbar-item" href="index.html#cli">CLI</a>
|
||||||
<a class="navbar-item" href="demo.html">Demo</a>
|
<a class="navbar-item" href="demo.html">Demo</a>
|
||||||
<a class="navbar-item" href="https://github.com/rtfpessoa/diff2html#how-to-use" target="_blank"
|
<a class="navbar-item" href="https://github.com/rtfpessoa/diff2html#usage" target="_blank"
|
||||||
rel="noopener" rel="noreferrer">Docs</a>
|
rel="noopener" rel="noreferrer">Docs</a>
|
||||||
<a class="navbar-item" href="https://github.com/rtfpessoa/diff2html/issues/new" target="_blank"
|
<a class="navbar-item" href="https://github.com/rtfpessoa/diff2html/issues/new" target="_blank"
|
||||||
rel="noopener" rel="noreferrer">Support</a>
|
rel="noopener" rel="noreferrer">Support</a>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue