v-code-diff 0.3.12 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +135 -90
- package/dist/v2/index.cjs.js +9 -0
- package/dist/v2/index.es.js +4526 -0
- package/dist/v2.7/index.cjs.js +9 -0
- package/dist/v2.7/index.es.js +4337 -0
- package/dist/v3/index.cjs.js +9 -0
- package/dist/v3/index.es.js +4315 -0
- package/package.json +44 -87
- package/scripts/postinstall.js +18 -0
- package/scripts/utils.js +36 -0
- package/src/CodeDiff.vue +57 -0
- package/src/highlight.ts +23 -0
- package/src/index.ts +15 -0
- package/src/split/SplitLine.vue +66 -0
- package/src/split/SplitViewer.vue +26 -0
- package/src/style.scss +114 -0
- package/src/types.ts +29 -0
- package/src/unified/UnifiedLine.vue +62 -0
- package/src/unified/UnifiedViewer.vue +20 -0
- package/src/utils.ts +418 -0
- package/src/var.scss +439 -0
- package/types/index.d.ts +14 -0
- package/dist/index.d.ts +0 -6
- package/dist/v-code-diff/index.d.ts +0 -2
- package/dist/v-code-diff/styles/index.d.ts +0 -3
- package/dist/v-code-diff/util.d.ts +0 -21
- package/dist/v-code-diff/v-code-diff.d.ts +0 -129
- package/dist/v-code-diff.cjs.js +0 -1
- package/dist/v-code-diff.esm.js +0 -1
- package/dist/v-code-diff.umd.js +0 -1
- package/src/lib/index.ts +0 -13
- package/src/lib/v-code-diff/index.ts +0 -3
- package/src/lib/v-code-diff/styles/highlight.scss +0 -84
- package/src/lib/v-code-diff/styles/index.ts +0 -3
- package/src/lib/v-code-diff/styles/style.scss +0 -36
- package/src/lib/v-code-diff/util.ts +0 -104
- package/src/lib/v-code-diff/v-code-diff.ts +0 -104
package/package.json
CHANGED
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "v-code-diff",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"gh-pages": "vite build --base=/v-code-diff/ && gh-pages -d ./pages"
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "template component for vue-demi, can dev and build",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.es.js",
|
|
7
|
+
"types": "./types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.es.js",
|
|
11
|
+
"require": "./dist/index.cjs.js"
|
|
12
|
+
}
|
|
14
13
|
},
|
|
15
|
-
"main": "dist/v-code-diff.cjs.js",
|
|
16
|
-
"module": "dist/v-code-diff.esm.js",
|
|
17
|
-
"unpkg": "dist/v-code-diff.umd.js",
|
|
18
14
|
"files": [
|
|
15
|
+
"scripts",
|
|
19
16
|
"dist",
|
|
20
|
-
"src
|
|
21
|
-
|
|
22
|
-
"types": "dist/index.d.ts",
|
|
23
|
-
"keywords": [
|
|
24
|
-
"vue",
|
|
25
|
-
"vue3",
|
|
26
|
-
"code",
|
|
27
|
-
"diff"
|
|
17
|
+
"src",
|
|
18
|
+
"types"
|
|
28
19
|
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "npm run clean && run-s build:*",
|
|
22
|
+
"build:2": "vue-demi-switch 2 vue2 && pnpm --filter vue2-playground build",
|
|
23
|
+
"build:2.7": "vue-demi-switch 2.7 vue2 && pnpm --filter vue2.7-playground build",
|
|
24
|
+
"build:3": "vue-demi-switch 3 vue3 && pnpm --filter vue3-playground build",
|
|
25
|
+
"clean": "rimraf ./dist",
|
|
26
|
+
"dev:2": "vue-demi-switch 2 vue2 && pnpm --filter vue2-playground dev",
|
|
27
|
+
"dev:2.7": "vue-demi-switch 2.7 vue2 && pnpm --filter vue2.7-playground dev",
|
|
28
|
+
"dev:3": "vue-demi-switch 3 vue3 && pnpm --filter vue3-playground dev",
|
|
29
|
+
"lint:fix": "eslint . --ext .vue,.js,.jsx,.ts,.tsx --fix --ignore-path .gitignore",
|
|
30
|
+
"postinstall": "node scripts/postinstall.js",
|
|
31
|
+
"prepublishOnly": "npm run build",
|
|
32
|
+
"release": "bumpp --commit --no-push --tag && npm publish"
|
|
33
|
+
},
|
|
29
34
|
"author": "Shimada666<649940882@qq.com>",
|
|
30
35
|
"license": "MIT",
|
|
31
|
-
"bugs": {
|
|
32
|
-
"url": "https://github.com/Shimada666/v-code-diff/issues"
|
|
33
|
-
},
|
|
34
36
|
"repository": {
|
|
35
|
-
"type": "git"
|
|
36
|
-
"url": "git+https://github.com/Shimada666/v-code-diff.git"
|
|
37
|
+
"type": "git"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
39
|
-
"@vue/composition-api": "^1.
|
|
40
|
-
"vue": "^2.
|
|
40
|
+
"@vue/composition-api": "^1.4.9",
|
|
41
|
+
"vue": "^2.6.0 || >=3.0.0"
|
|
41
42
|
},
|
|
42
43
|
"peerDependenciesMeta": {
|
|
43
44
|
"@vue/composition-api": {
|
|
@@ -46,67 +47,23 @@
|
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
49
|
"diff": "^5.0.0",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"vue-demi": "^0.13.6"
|
|
50
|
+
"highlight.js": "^11.6.0",
|
|
51
|
+
"vue-demi": "latest"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@
|
|
55
|
-
"@commitlint/cli": "^8.2.0",
|
|
56
|
-
"@commitlint/config-conventional": "^8.2.0",
|
|
57
|
-
"@rollup/plugin-node-resolve": "^11.1.1",
|
|
54
|
+
"@antfu/eslint-config": "^0.34.0",
|
|
58
55
|
"@types/diff": "^5.0.0",
|
|
59
|
-
"@types/node": "^
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"body-parser": "^1.19.0",
|
|
70
|
-
"commitizen": "^4.2.3",
|
|
71
|
-
"conventional-changelog-cli": "^2.1.1",
|
|
72
|
-
"cross-env": "^7.0.3",
|
|
73
|
-
"dotenv": "^8.2.0",
|
|
74
|
-
"eslint": "^7.22.0",
|
|
75
|
-
"eslint-plugin-import": "^2.22.1",
|
|
76
|
-
"eslint-plugin-vue": "^7.17.0",
|
|
77
|
-
"gh-pages": "^3.2.1",
|
|
78
|
-
"lint-staged": "^10.5.4",
|
|
79
|
-
"rollup": "^2.38.5",
|
|
80
|
-
"rollup-plugin-styles": "^3.14.1",
|
|
81
|
-
"rollup-plugin-terser": "^7.0.2",
|
|
82
|
-
"rollup-plugin-typescript2": "^0.29.0",
|
|
83
|
-
"rollup-plugin-vue": "^6.0.0",
|
|
84
|
-
"sass": "^1.35.1",
|
|
85
|
-
"stylelint": "^13.12.0",
|
|
86
|
-
"stylelint-config-prettier": "^8.0.2",
|
|
87
|
-
"stylelint-config-standard": "^21.0.0",
|
|
88
|
-
"stylelint-order": "^4.1.0",
|
|
89
|
-
"typescript": "^4.4.2",
|
|
90
|
-
"vite": "^2.5.6",
|
|
91
|
-
"vue": "^3.2.11",
|
|
92
|
-
"vue-eslint-parser": "^7.11.0",
|
|
93
|
-
"vue-tsc": "^0.3.0",
|
|
56
|
+
"@types/node": "^18.11.18",
|
|
57
|
+
"bumpp": "^8.2.1",
|
|
58
|
+
"eslint": "^8.31.0",
|
|
59
|
+
"npm-run-all": "^4.1.5",
|
|
60
|
+
"rimraf": "^3.0.2",
|
|
61
|
+
"sass": "^1.57.1",
|
|
62
|
+
"typescript": "~4.7.4",
|
|
63
|
+
"vite": "^4.0.4",
|
|
64
|
+
"vite-plugin-css-injected-by-js": "^2.4.0",
|
|
65
|
+
"vue-tsc": "^0.40.13",
|
|
94
66
|
"vue2": "npm:vue@2",
|
|
95
|
-
"
|
|
96
|
-
},
|
|
97
|
-
"gitHooks": {
|
|
98
|
-
"pre-commit": "lint-staged",
|
|
99
|
-
"commit-msg": "commitlint -e"
|
|
100
|
-
},
|
|
101
|
-
"config": {
|
|
102
|
-
"commitizen": {
|
|
103
|
-
"path": "cz-conventional-changelog"
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
"lint-staged": {
|
|
107
|
-
"*.{js,vue,ts}": [
|
|
108
|
-
"eslint --ext .ts,.vue,.tsx src",
|
|
109
|
-
"git add"
|
|
110
|
-
]
|
|
67
|
+
"vue3": "npm:vue@3"
|
|
111
68
|
}
|
|
112
69
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { switchVersion, loadModule } = require('./utils')
|
|
2
|
+
|
|
3
|
+
const Vue = loadModule('vue')
|
|
4
|
+
|
|
5
|
+
if (!Vue || typeof Vue.version !== 'string')
|
|
6
|
+
console.warn('[vue-demi-sfc-component-template] Vue is not found. Please run "npm install vue" to install.')
|
|
7
|
+
|
|
8
|
+
else if (Vue.version.startsWith('2.7.'))
|
|
9
|
+
switchVersion('2.7')
|
|
10
|
+
|
|
11
|
+
else if (Vue.version.startsWith('2.'))
|
|
12
|
+
switchVersion('2')
|
|
13
|
+
|
|
14
|
+
else if (Vue.version.startsWith('3.'))
|
|
15
|
+
switchVersion('3')
|
|
16
|
+
|
|
17
|
+
else
|
|
18
|
+
console.warn(`[vue-demi-sfc-component-template] Vue version v${Vue.version} is not suppported.`)
|
package/scripts/utils.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
const dir = path.resolve(__dirname, '..', 'dist')
|
|
5
|
+
|
|
6
|
+
function loadModule(name) {
|
|
7
|
+
try {
|
|
8
|
+
return require(name)
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
return undefined
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function copy(name, version, vue) {
|
|
16
|
+
vue = vue || 'vue'
|
|
17
|
+
const src = path.join(dir, `v${version}`, name)
|
|
18
|
+
const dest = path.join(dir, name)
|
|
19
|
+
let content = fs.readFileSync(src, 'utf-8')
|
|
20
|
+
content = content.replace(/'vue'/g, `'${vue}'`)
|
|
21
|
+
// unlink for pnpm, #92
|
|
22
|
+
try {
|
|
23
|
+
fs.unlinkSync(dest)
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
}
|
|
27
|
+
fs.writeFileSync(dest, content, 'utf-8')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function switchVersion(version, vue) {
|
|
31
|
+
copy('index.es.js', version, vue)
|
|
32
|
+
copy('index.cjs.js', version, vue)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports.loadModule = loadModule
|
|
36
|
+
module.exports.switchVersion = switchVersion
|
package/src/CodeDiff.vue
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue-demi'
|
|
3
|
+
import { createSplitDiff, createUnifiedDiff } from './utils'
|
|
4
|
+
import UnifiedViewer from './unified/UnifiedViewer.vue'
|
|
5
|
+
import SplitViewer from './split/SplitViewer.vue'
|
|
6
|
+
|
|
7
|
+
import './style.scss'
|
|
8
|
+
import 'highlight.js/scss/vs.scss'
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
newString: string
|
|
12
|
+
oldString: string
|
|
13
|
+
language?: string
|
|
14
|
+
context?: number
|
|
15
|
+
diffStyle?: 'word' | 'char'
|
|
16
|
+
outputFormat?: 'line-by-line' | 'side-by-side'
|
|
17
|
+
trim?: boolean
|
|
18
|
+
noDiffLineFeed?: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
22
|
+
language: 'plaintext',
|
|
23
|
+
context: 10,
|
|
24
|
+
diffStyle: 'word',
|
|
25
|
+
outputFormat: 'line-by-line',
|
|
26
|
+
trim: false,
|
|
27
|
+
noDiffLineFeed: false,
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const isUnifiedViewer = computed(() => props.outputFormat === 'line-by-line')
|
|
31
|
+
|
|
32
|
+
const oldString = computed(() => {
|
|
33
|
+
const value = props.trim ? props.oldString.trim() : props.oldString
|
|
34
|
+
return props.noDiffLineFeed ? value.replace(/(\r\n)/g, '\n') : value
|
|
35
|
+
})
|
|
36
|
+
const newString = computed(() => {
|
|
37
|
+
const value = props.trim ? props.newString.trim() : props.newString
|
|
38
|
+
return props.noDiffLineFeed ? value.replace(/(\r\n)/g, '\n') : value
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const diffChange = computed(() =>
|
|
42
|
+
isUnifiedViewer.value
|
|
43
|
+
? createUnifiedDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context)
|
|
44
|
+
: createSplitDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context),
|
|
45
|
+
)
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<div class="code-diff-view">
|
|
50
|
+
<UnifiedViewer v-if="isUnifiedViewer" :diff-change="diffChange" />
|
|
51
|
+
<SplitViewer v-else :diff-change="diffChange" />
|
|
52
|
+
</div>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<style lang="scss">
|
|
56
|
+
|
|
57
|
+
</style>
|
package/src/highlight.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import hljs from 'highlight.js/lib/core'
|
|
2
|
+
|
|
3
|
+
import xml from 'highlight.js/lib/languages/xml'
|
|
4
|
+
import javascript from 'highlight.js/lib/languages/javascript'
|
|
5
|
+
import json from 'highlight.js/lib/languages/json'
|
|
6
|
+
import yaml from 'highlight.js/lib/languages/yaml'
|
|
7
|
+
import plaintext from 'highlight.js/lib/languages/plaintext'
|
|
8
|
+
import python from 'highlight.js/lib/languages/python'
|
|
9
|
+
import java from 'highlight.js/lib/languages/java'
|
|
10
|
+
import bash from 'highlight.js/lib/languages/bash'
|
|
11
|
+
import sql from 'highlight.js/lib/languages/sql'
|
|
12
|
+
|
|
13
|
+
hljs.registerLanguage('xml', xml)
|
|
14
|
+
hljs.registerLanguage('javascript', javascript)
|
|
15
|
+
hljs.registerLanguage('json', json)
|
|
16
|
+
hljs.registerLanguage('yaml', yaml)
|
|
17
|
+
hljs.registerLanguage('plaintext', plaintext)
|
|
18
|
+
hljs.registerLanguage('python', python)
|
|
19
|
+
hljs.registerLanguage('java', java)
|
|
20
|
+
hljs.registerLanguage('bash', bash)
|
|
21
|
+
hljs.registerLanguage('sql', sql)
|
|
22
|
+
|
|
23
|
+
export default hljs
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { DiffType } from '../types'
|
|
3
|
+
import type { SplitDiffLine } from '../types'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
splitLine: SplitDiffLine
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const getCodeMarker = (type: DiffType) => {
|
|
10
|
+
if (type === DiffType.DELETE)
|
|
11
|
+
return '-'
|
|
12
|
+
if (type === DiffType.ADD)
|
|
13
|
+
return '+'
|
|
14
|
+
return ''
|
|
15
|
+
}
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<tr v-if="splitLine.fold">
|
|
20
|
+
<td class="blob-num blob-num-empty empty-cell" colspan="1">
|
|
21
|
+
>
|
|
22
|
+
</td>
|
|
23
|
+
<td class="blob-code blob-code-empty empty-cell" colspan="3" align="left">
|
|
24
|
+
⋯
|
|
25
|
+
</td>
|
|
26
|
+
</tr>
|
|
27
|
+
<tr v-else>
|
|
28
|
+
<template v-for="line in [splitLine.left, splitLine.right]">
|
|
29
|
+
<!-- eslint-disable -->
|
|
30
|
+
<template v-if="line.type === DiffType.EMPTY">
|
|
31
|
+
<td class="blob-num blob-num-empty empty-cell" />
|
|
32
|
+
<td class="blob-code blob-code-empty empty-cell" />
|
|
33
|
+
</template>
|
|
34
|
+
<template v-else>
|
|
35
|
+
<td
|
|
36
|
+
class="blob-num"
|
|
37
|
+
:class="{
|
|
38
|
+
'blob-num-deletion': line.type === DiffType.DELETE,
|
|
39
|
+
'blob-num-addition': line.type === DiffType.ADD,
|
|
40
|
+
'blob-num-context': line.type === DiffType.EQUAL,
|
|
41
|
+
}"
|
|
42
|
+
>
|
|
43
|
+
{{ line.num }}
|
|
44
|
+
</td>
|
|
45
|
+
<td
|
|
46
|
+
class="blob-code"
|
|
47
|
+
:class="{
|
|
48
|
+
'blob-code-deletion': line.type === DiffType.DELETE,
|
|
49
|
+
'blob-code-addition': line.type === DiffType.ADD,
|
|
50
|
+
'blob-code-context': line.type === DiffType.EQUAL,
|
|
51
|
+
}"
|
|
52
|
+
>
|
|
53
|
+
<span
|
|
54
|
+
class="blob-code-inner blob-code-marker"
|
|
55
|
+
:data-code-marker="getCodeMarker(line.type)"
|
|
56
|
+
v-html="line.code"
|
|
57
|
+
/>
|
|
58
|
+
</td>
|
|
59
|
+
</template>
|
|
60
|
+
<!-- eslint-enable -->
|
|
61
|
+
</template>
|
|
62
|
+
</tr>
|
|
63
|
+
</template>
|
|
64
|
+
|
|
65
|
+
<style lang="scss">
|
|
66
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { SplitViewerChange } from '../types'
|
|
3
|
+
import SplitLine from './SplitLine.vue'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
diffChange: SplitViewerChange
|
|
7
|
+
}>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div class="file">
|
|
12
|
+
<table class="file-diff-split diff-table">
|
|
13
|
+
<colgroup>
|
|
14
|
+
<col width="44">
|
|
15
|
+
<col>
|
|
16
|
+
<col width="44">
|
|
17
|
+
<col>
|
|
18
|
+
</colgroup>
|
|
19
|
+
<tbody>
|
|
20
|
+
<SplitLine v-for="(item, index) in diffChange" :key="index" :split-line="item" />
|
|
21
|
+
</tbody>
|
|
22
|
+
</table>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<style scoped></style>
|
package/src/style.scss
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
@import "./var";
|
|
2
|
+
|
|
3
|
+
.code-diff-view {
|
|
4
|
+
* {
|
|
5
|
+
position: static;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.file {
|
|
9
|
+
position: relative;
|
|
10
|
+
margin-top: 16px;
|
|
11
|
+
margin-bottom: 16px;
|
|
12
|
+
border: 1px solid var(--color-border-default, #ddd);
|
|
13
|
+
border-radius: 2px;
|
|
14
|
+
|
|
15
|
+
table {
|
|
16
|
+
border-spacing: 0;
|
|
17
|
+
}
|
|
18
|
+
.diff-table {
|
|
19
|
+
width: 100%;
|
|
20
|
+
|
|
21
|
+
.blob-num {
|
|
22
|
+
position: relative;
|
|
23
|
+
width: 1%;
|
|
24
|
+
min-width: 50px;
|
|
25
|
+
padding-right: 10px;
|
|
26
|
+
padding-left: 10px;
|
|
27
|
+
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
|
|
28
|
+
font-size: 12px;
|
|
29
|
+
line-height: 20px;
|
|
30
|
+
color: var(--color-fg-subtle);
|
|
31
|
+
text-align: right;
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
vertical-align: top;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
-webkit-user-select: none;
|
|
36
|
+
user-select: none;
|
|
37
|
+
}
|
|
38
|
+
.blob-num-deletion {
|
|
39
|
+
color: var(--color-diff-blob-deletion-num-text);
|
|
40
|
+
background-color: var(--color-diff-blob-deletion-num-bg);
|
|
41
|
+
border-color: var(--color-danger-emphasis);
|
|
42
|
+
}
|
|
43
|
+
.blob-num-addition {
|
|
44
|
+
color: var(--color-diff-blob-addition-num-text);
|
|
45
|
+
background-color: var(--color-diff-blob-addition-num-bg);
|
|
46
|
+
border-color: var(--color-success-emphasis);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.blob-code {
|
|
50
|
+
position: relative;
|
|
51
|
+
padding-right: 10px;
|
|
52
|
+
padding-left: 10px;
|
|
53
|
+
line-height: 20px;
|
|
54
|
+
vertical-align: top;
|
|
55
|
+
.blob-code-inner {
|
|
56
|
+
display: table-cell;
|
|
57
|
+
overflow: visible;
|
|
58
|
+
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
|
|
59
|
+
font-size: 12px;
|
|
60
|
+
color: var(--color-fg-default);
|
|
61
|
+
word-wrap: anywhere;
|
|
62
|
+
white-space: pre-wrap;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
.blob-code-deletion {
|
|
66
|
+
background-color: var(--color-diff-blob-deletion-line-bg);
|
|
67
|
+
outline: 1px dashed transparent;
|
|
68
|
+
|
|
69
|
+
.x {
|
|
70
|
+
color: var(--color-diff-blob-deletion-fg);
|
|
71
|
+
background-color: var(--color-diff-blob-deletion-word-bg);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
.blob-code-addition {
|
|
75
|
+
background-color: var(--color-diff-blob-addition-line-bg);
|
|
76
|
+
outline: 1px dotted transparent;
|
|
77
|
+
|
|
78
|
+
.x {
|
|
79
|
+
color: var(--color-diff-blob-addition-fg);
|
|
80
|
+
background-color: var(--color-diff-blob-addition-word-bg);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.blob-code-context,
|
|
85
|
+
.blob-code-addition,
|
|
86
|
+
.blob-code-deletion {
|
|
87
|
+
padding-left: 22px !important;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.blob-code-marker::before {
|
|
91
|
+
position: absolute;
|
|
92
|
+
top: 1px;
|
|
93
|
+
left: 8px;
|
|
94
|
+
padding-right: 8px;
|
|
95
|
+
content: attr(data-code-marker);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.file-diff-split {
|
|
100
|
+
table-layout: fixed;
|
|
101
|
+
|
|
102
|
+
.blob-code + .blob-num {
|
|
103
|
+
border-left: 1px solid var(--color-border-muted);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.empty-cell {
|
|
108
|
+
cursor: default;
|
|
109
|
+
background-color: var(--color-neutral-subtle);
|
|
110
|
+
border-right-color: var(--color-border-muted);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const enum DiffType {
|
|
2
|
+
EQUAL = 'equal',
|
|
3
|
+
DELETE = 'removed',
|
|
4
|
+
ADD = 'added',
|
|
5
|
+
EMPTY = 'empty',
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface DiffLine {
|
|
9
|
+
type: DiffType
|
|
10
|
+
code?: string
|
|
11
|
+
num?: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface SplitDiffLine {
|
|
15
|
+
fold?: boolean
|
|
16
|
+
left: DiffLine
|
|
17
|
+
right: DiffLine
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface UnifiedLine {
|
|
21
|
+
fold?: boolean
|
|
22
|
+
type: DiffType
|
|
23
|
+
code: string
|
|
24
|
+
delNum?: number
|
|
25
|
+
addNum?: number
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type SplitViewerChange = SplitDiffLine[]
|
|
29
|
+
export type UnifiedViewerChange = UnifiedLine[]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { UnifiedLine } from '../types'
|
|
3
|
+
import { DiffType } from '../types'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
line: UnifiedLine
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const getCodeMarker = (type: DiffType) => {
|
|
10
|
+
if (type === DiffType.DELETE)
|
|
11
|
+
return '-'
|
|
12
|
+
if (type === DiffType.ADD)
|
|
13
|
+
return '+'
|
|
14
|
+
return ''
|
|
15
|
+
}
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<tr v-if="line.fold">
|
|
20
|
+
<td class="blob-num blob-num-empty empty-cell">
|
|
21
|
+
>
|
|
22
|
+
</td>
|
|
23
|
+
<td class="blob-num blob-num-empty empty-cell">
|
|
24
|
+
>
|
|
25
|
+
</td>
|
|
26
|
+
<td class="blob-code blob-code-empty empty-cell" align="left">
|
|
27
|
+
⋯
|
|
28
|
+
</td>
|
|
29
|
+
</tr>
|
|
30
|
+
<tr v-else>
|
|
31
|
+
<td
|
|
32
|
+
class="blob-num"
|
|
33
|
+
:class="{
|
|
34
|
+
'blob-num-deletion': line.type === DiffType.DELETE,
|
|
35
|
+
'blob-num-addition': line.type === DiffType.ADD,
|
|
36
|
+
'blob-num-context': line.type === DiffType.EQUAL,
|
|
37
|
+
}"
|
|
38
|
+
>
|
|
39
|
+
{{ line.delNum }}
|
|
40
|
+
</td>
|
|
41
|
+
<td
|
|
42
|
+
class="blob-num"
|
|
43
|
+
:class="{
|
|
44
|
+
'blob-num-deletion': line.type === DiffType.DELETE,
|
|
45
|
+
'blob-num-addition': line.type === DiffType.ADD,
|
|
46
|
+
'blob-num-context': line.type === DiffType.EQUAL,
|
|
47
|
+
}"
|
|
48
|
+
>
|
|
49
|
+
{{ line.addNum }}
|
|
50
|
+
</td>
|
|
51
|
+
<td
|
|
52
|
+
class="blob-code"
|
|
53
|
+
:class="{
|
|
54
|
+
'blob-code-deletion': line.type === DiffType.DELETE,
|
|
55
|
+
'blob-code-addition': line.type === DiffType.ADD,
|
|
56
|
+
'blob-code-context': line.type === DiffType.EQUAL,
|
|
57
|
+
}"
|
|
58
|
+
>
|
|
59
|
+
<span class="blob-code-inner blob-code-marker" :data-code-marker="getCodeMarker(line.type)" v-html="line.code" />
|
|
60
|
+
</td>
|
|
61
|
+
</tr>
|
|
62
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { UnifiedViewerChange } from '../types'
|
|
3
|
+
import UnifiedLine from './UnifiedLine.vue'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
diffChange: UnifiedViewerChange
|
|
7
|
+
}>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div class="file">
|
|
12
|
+
<table class="diff-table">
|
|
13
|
+
<tbody>
|
|
14
|
+
<UnifiedLine v-for="(item, index) in diffChange" :key="index" :line="item" />
|
|
15
|
+
</tbody>
|
|
16
|
+
</table>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<style scoped></style>
|