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/src/lib/index.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
.d2h-wrapper {
|
|
2
|
-
.hljs {
|
|
3
|
-
display: inline-block;
|
|
4
|
-
padding: 0;
|
|
5
|
-
background: transparent;
|
|
6
|
-
vertical-align: middle;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.hljs-comment,
|
|
10
|
-
.hljs-quote {
|
|
11
|
-
color: #800;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.hljs-keyword,
|
|
15
|
-
.hljs-selector-tag,
|
|
16
|
-
.hljs-section,
|
|
17
|
-
.hljs-title,
|
|
18
|
-
.hljs-name {
|
|
19
|
-
color: #008;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.hljs-variable,
|
|
23
|
-
.hljs-template-variable {
|
|
24
|
-
color: #660;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.hljs-string,
|
|
28
|
-
.hljs-selector-attr,
|
|
29
|
-
.hljs-selector-pseudo,
|
|
30
|
-
.hljs-regexp {
|
|
31
|
-
color: #080;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.hljs-literal,
|
|
35
|
-
.hljs-symbol,
|
|
36
|
-
.hljs-bullet,
|
|
37
|
-
.hljs-meta,
|
|
38
|
-
.hljs-number,
|
|
39
|
-
.hljs-link {
|
|
40
|
-
color: #066;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.hljs-title,
|
|
44
|
-
.hljs-doctag,
|
|
45
|
-
.hljs-type,
|
|
46
|
-
.hljs-attr,
|
|
47
|
-
.hljs-built_in,
|
|
48
|
-
.hljs-builtin-name,
|
|
49
|
-
.hljs-params {
|
|
50
|
-
color: #606;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.hljs-attribute,
|
|
54
|
-
.hljs-subst {
|
|
55
|
-
color: #000;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.hljs-formula {
|
|
59
|
-
background-color: #eee;
|
|
60
|
-
font-style: italic;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.hljs-selector-id,
|
|
64
|
-
.hljs-selector-class {
|
|
65
|
-
color: #9B703F
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.hljs-addition {
|
|
69
|
-
background-color: #baeeba;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.hljs-deletion {
|
|
73
|
-
background-color: #ffc8bd;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.hljs-doctag,
|
|
77
|
-
.hljs-strong {
|
|
78
|
-
font-weight: bold;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.hljs-emphasis {
|
|
82
|
-
font-style: italic;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
.d2h-wrapper {
|
|
2
|
-
position: relative;
|
|
3
|
-
line-height: normal;
|
|
4
|
-
.d2h-file-header {
|
|
5
|
-
display: none;
|
|
6
|
-
}
|
|
7
|
-
.d2h-files-diff {
|
|
8
|
-
display: flex;
|
|
9
|
-
}
|
|
10
|
-
.d2h-file-side-diff {
|
|
11
|
-
margin-bottom: -5px;
|
|
12
|
-
}
|
|
13
|
-
.d2h-code-side-emptyplaceholder {
|
|
14
|
-
max-height: 19px;
|
|
15
|
-
}
|
|
16
|
-
.d2h-code-side-line,
|
|
17
|
-
.d2h-code-line {
|
|
18
|
-
width: auto;
|
|
19
|
-
}
|
|
20
|
-
.d2h-code-side-line .d2h-info {
|
|
21
|
-
height: 18px;
|
|
22
|
-
}
|
|
23
|
-
.d2h-cntx,
|
|
24
|
-
.d2h-del,
|
|
25
|
-
.d2h-ins {
|
|
26
|
-
height: 18px;
|
|
27
|
-
}
|
|
28
|
-
.d2h-code-linenumber,
|
|
29
|
-
.d2h-code-side-linenumber {
|
|
30
|
-
line-height: 20px;
|
|
31
|
-
height: 20px;
|
|
32
|
-
}
|
|
33
|
-
tr {
|
|
34
|
-
height: 20px;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { createPatch } from 'diff'
|
|
2
|
-
import * as d2h from 'diff2html'
|
|
3
|
-
import hljs from 'highlight.js'
|
|
4
|
-
import { SetupContext } from 'vue-demi'
|
|
5
|
-
|
|
6
|
-
type Props = Readonly<{
|
|
7
|
-
highlight: boolean
|
|
8
|
-
oldString: string
|
|
9
|
-
newString: string
|
|
10
|
-
context: number
|
|
11
|
-
outputFormat: 'side-by-side' | 'line-by-line'
|
|
12
|
-
drawFileList: boolean
|
|
13
|
-
renderNothingWhenEmpty: boolean
|
|
14
|
-
fileName: string
|
|
15
|
-
isShowNoChange: boolean
|
|
16
|
-
diffStyle: 'word' | 'char'
|
|
17
|
-
trim: boolean
|
|
18
|
-
language: string
|
|
19
|
-
noDiffLineFeed: boolean
|
|
20
|
-
} & {}>
|
|
21
|
-
|
|
22
|
-
export function useDebounceFn (fn, delay) {
|
|
23
|
-
let timer
|
|
24
|
-
return function () {
|
|
25
|
-
const context = this
|
|
26
|
-
const args = arguments
|
|
27
|
-
clearTimeout(timer)
|
|
28
|
-
timer = setTimeout(function () {
|
|
29
|
-
fn.apply(context, args)
|
|
30
|
-
}, delay)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const createHtml = (props: Props) => {
|
|
35
|
-
let oldString = props.trim ? props.oldString.trim() : props.oldString
|
|
36
|
-
let newString = props.trim ? props.newString.trim() : props.newString
|
|
37
|
-
oldString = props.noDiffLineFeed ? oldString.replace(/(\r\n)/g, '\n') : oldString
|
|
38
|
-
newString = props.noDiffLineFeed ? newString.replace(/(\r\n)/g, '\n') : newString
|
|
39
|
-
let context = props.context
|
|
40
|
-
if (props.isShowNoChange && oldString === newString) {
|
|
41
|
-
oldString = 'File Without Change\tOldString: ======================== \n' + oldString
|
|
42
|
-
newString = 'File Without Change\tNewString: ======================== \n' + newString
|
|
43
|
-
context = 99999
|
|
44
|
-
}
|
|
45
|
-
const dd = createPatch(props.fileName, oldString, newString, '', '', { context: context })
|
|
46
|
-
return d2h.html(dd, {
|
|
47
|
-
outputFormat: props.outputFormat,
|
|
48
|
-
drawFileList: props.drawFileList,
|
|
49
|
-
matching: 'lines',
|
|
50
|
-
diffStyle: props.diffStyle,
|
|
51
|
-
renderNothingWhenEmpty: props.renderNothingWhenEmpty
|
|
52
|
-
})
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function listElements (element: Element): Promise<Element[]> {
|
|
56
|
-
return new Promise(resolve => {
|
|
57
|
-
setTimeout(() => {
|
|
58
|
-
const elements = element.querySelectorAll('.d2h-wrapper .d2h-code-line-ctn')
|
|
59
|
-
resolve(Array.from(elements))
|
|
60
|
-
}, 0)
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function highlightElement (el: HTMLElement, language: string): Promise<boolean> {
|
|
65
|
-
return new Promise(resolve => {
|
|
66
|
-
setTimeout(() => {
|
|
67
|
-
if (language) {
|
|
68
|
-
const text = el.innerText
|
|
69
|
-
el.innerHTML = hljs.highlight(text, { language: language }).value
|
|
70
|
-
} else {
|
|
71
|
-
hljs.highlightElement(<HTMLElement>el)
|
|
72
|
-
}
|
|
73
|
-
resolve(true)
|
|
74
|
-
}, 0)
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export async function highlightElements (element: Element, props, ctx: SetupContext<any>) {
|
|
79
|
-
ctx.emit('before-render')
|
|
80
|
-
const elements = await listElements(element)
|
|
81
|
-
const promises = Array.from(elements).map(el => highlightElement(el as HTMLElement, props.language))
|
|
82
|
-
await Promise.all(promises)
|
|
83
|
-
ctx.emit('after-render')
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function syncScroll (selector) {
|
|
87
|
-
let active: HTMLElement = document.createElement('div')
|
|
88
|
-
document.querySelectorAll(selector).forEach(function (element) {
|
|
89
|
-
element.addEventListener('mouseenter', function (e) {
|
|
90
|
-
active = e.target
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
element.addEventListener('scroll', function (e) {
|
|
94
|
-
if (e.target !== active) return
|
|
95
|
-
|
|
96
|
-
document.querySelectorAll(selector).forEach(function (target) {
|
|
97
|
-
if (active === target) return
|
|
98
|
-
|
|
99
|
-
target.scrollTop = active.scrollTop
|
|
100
|
-
target.scrollLeft = active.scrollLeft
|
|
101
|
-
})
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { defineComponent, isVue3, PropType, h, ref, watch, onUpdated, onMounted } from 'vue-demi'
|
|
2
|
-
import { createHtml, highlightElements, syncScroll, useDebounceFn } from './util'
|
|
3
|
-
import './styles'
|
|
4
|
-
|
|
5
|
-
export default defineComponent({
|
|
6
|
-
name: 'CodeDiff',
|
|
7
|
-
props: {
|
|
8
|
-
highlight: {
|
|
9
|
-
type: Boolean,
|
|
10
|
-
default: true
|
|
11
|
-
},
|
|
12
|
-
oldString: {
|
|
13
|
-
type: String,
|
|
14
|
-
default: ''
|
|
15
|
-
},
|
|
16
|
-
newString: {
|
|
17
|
-
type: String,
|
|
18
|
-
default: ''
|
|
19
|
-
},
|
|
20
|
-
context: {
|
|
21
|
-
type: Number,
|
|
22
|
-
default: 10
|
|
23
|
-
},
|
|
24
|
-
outputFormat: {
|
|
25
|
-
type: String as PropType<'line-by-line' | 'side-by-side'>,
|
|
26
|
-
default: 'line-by-line'
|
|
27
|
-
},
|
|
28
|
-
drawFileList: {
|
|
29
|
-
type: Boolean,
|
|
30
|
-
default: false
|
|
31
|
-
},
|
|
32
|
-
renderNothingWhenEmpty: {
|
|
33
|
-
type: Boolean,
|
|
34
|
-
default: false
|
|
35
|
-
},
|
|
36
|
-
diffStyle: {
|
|
37
|
-
type: String as PropType<'word' | 'char'>,
|
|
38
|
-
default: 'word'
|
|
39
|
-
},
|
|
40
|
-
fileName: {
|
|
41
|
-
type: String,
|
|
42
|
-
default: ''
|
|
43
|
-
},
|
|
44
|
-
isShowNoChange: {
|
|
45
|
-
type: Boolean,
|
|
46
|
-
default: false
|
|
47
|
-
},
|
|
48
|
-
trim: {
|
|
49
|
-
type: Boolean,
|
|
50
|
-
default: false
|
|
51
|
-
},
|
|
52
|
-
language: {
|
|
53
|
-
type: String,
|
|
54
|
-
default: ''
|
|
55
|
-
},
|
|
56
|
-
noDiffLineFeed: {
|
|
57
|
-
type: Boolean,
|
|
58
|
-
default: false
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
emits: ['before-render', 'after-render'],
|
|
62
|
-
setup (props, ctx) {
|
|
63
|
-
const html = ref(createHtml(props))
|
|
64
|
-
const cb = useDebounceFn(async () => {
|
|
65
|
-
html.value = createHtml(props)
|
|
66
|
-
if (props.highlight) {
|
|
67
|
-
const el = document.createElement('div')
|
|
68
|
-
el.innerHTML = html.value
|
|
69
|
-
await highlightElements(el, props, ctx)
|
|
70
|
-
html.value = el.innerHTML
|
|
71
|
-
}
|
|
72
|
-
}, 200)
|
|
73
|
-
watch(props, cb, { deep: true, immediate: true })
|
|
74
|
-
|
|
75
|
-
onMounted(() => {
|
|
76
|
-
if (props.outputFormat === 'side-by-side') {
|
|
77
|
-
syncScroll('.d2h-file-side-diff')
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
onUpdated(() => {
|
|
82
|
-
if (props.outputFormat === 'side-by-side') {
|
|
83
|
-
syncScroll('.d2h-file-side-diff')
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
html
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
render () {
|
|
92
|
-
if (isVue3) {
|
|
93
|
-
return h('div', {
|
|
94
|
-
innerHTML: this.html
|
|
95
|
-
})
|
|
96
|
-
} else {
|
|
97
|
-
return h('div', {
|
|
98
|
-
domProps: {
|
|
99
|
-
innerHTML: this.html
|
|
100
|
-
}
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
})
|