v-code-diff 1.13.0 → 1.13.2
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/README.md +20 -5
- package/dist/v2/{index.cjs.js → index.cjs} +17 -17
- package/dist/v2/index.es.js +1119 -1097
- package/dist/v2/index.umd.js +17 -17
- package/dist/v2.7/{index.cjs.js → index.cjs} +14 -14
- package/dist/v2.7/index.es.js +625 -613
- package/dist/v2.7/index.umd.js +13 -13
- package/dist/v3/{index.cjs.js → index.cjs} +14 -14
- package/dist/v3/index.es.js +860 -840
- package/dist/v3/index.umd.js +15 -15
- package/package.json +21 -13
- package/scripts/perf-test.ts +40 -0
- package/scripts/postinstall.cjs +15 -18
- package/scripts/utils.cjs +4 -19
- package/src/CodeDiff.vue +7 -5
- package/src/split/SplitLine.vue +9 -5
- package/src/unified/UnifiedLine.vue +1 -1
- package/src/utils.ts +17 -0
- package/types/index.d.ts +3 -0
package/package.json
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "v-code-diff",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.13.
|
|
5
|
-
"
|
|
4
|
+
"version": "1.13.2",
|
|
5
|
+
"packageManager": "pnpm@11.2.2",
|
|
6
|
+
"description": "A code diff viewer for Vue 2.6, Vue 2.7, and Vue 3",
|
|
6
7
|
"license": "MIT",
|
|
7
8
|
"exports": {
|
|
8
9
|
".": {
|
|
9
10
|
"types": "./types/index.d.ts",
|
|
10
11
|
"import": "./dist/index.es.js",
|
|
11
|
-
"require": "./dist/index.cjs
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
},
|
|
14
|
+
"./vue2": {
|
|
15
|
+
"types": "./types/index.d.ts",
|
|
16
|
+
"import": "./dist/v2/index.es.js",
|
|
17
|
+
"require": "./dist/v2/index.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./vue2.7": {
|
|
20
|
+
"types": "./types/index.d.ts",
|
|
21
|
+
"import": "./dist/v2.7/index.es.js",
|
|
22
|
+
"require": "./dist/v2.7/index.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./vue3": {
|
|
25
|
+
"types": "./types/index.d.ts",
|
|
26
|
+
"import": "./dist/v3/index.es.js",
|
|
27
|
+
"require": "./dist/v3/index.cjs"
|
|
12
28
|
}
|
|
13
29
|
},
|
|
14
30
|
"main": "dist/index.cjs",
|
|
@@ -50,7 +66,7 @@
|
|
|
50
66
|
}
|
|
51
67
|
},
|
|
52
68
|
"dependencies": {
|
|
53
|
-
"diff": "^5.2.
|
|
69
|
+
"diff": "^5.2.2",
|
|
54
70
|
"diff-match-patch": "^1.0.5",
|
|
55
71
|
"highlight.js": "^11.10.0",
|
|
56
72
|
"vue-demi": "^0.14.6"
|
|
@@ -67,6 +83,7 @@
|
|
|
67
83
|
"npm-run-all": "^4.1.5",
|
|
68
84
|
"rimraf": "^3.0.2",
|
|
69
85
|
"sass": "^1.69.5",
|
|
86
|
+
"tsx": "^4.19.4",
|
|
70
87
|
"typescript": "~4.7.4",
|
|
71
88
|
"vite": "^5.4.2",
|
|
72
89
|
"vite-plugin-css-injected-by-js": "^2.4.0",
|
|
@@ -75,14 +92,5 @@
|
|
|
75
92
|
"vue-tsc": "^0.40.13",
|
|
76
93
|
"vue2": "npm:vue@2",
|
|
77
94
|
"vue3": "npm:vue@3"
|
|
78
|
-
},
|
|
79
|
-
"pnpm": {
|
|
80
|
-
"packageExtensions": {
|
|
81
|
-
"vue-template-compiler": {
|
|
82
|
-
"peerDependencies": {
|
|
83
|
-
"vue": "~2.6.14"
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
95
|
}
|
|
88
96
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { createSplitDiff } from '../src/utils'
|
|
5
|
+
|
|
6
|
+
// 获取当前文件的 URL 和目录路径
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
8
|
+
const __dirname = path.dirname(__filename)
|
|
9
|
+
|
|
10
|
+
// 构建文件的绝对路径
|
|
11
|
+
const oldTextPath = path.join(__dirname, '../demo/text/old-long-text.txt')
|
|
12
|
+
const newTextPath = path.join(__dirname, '../demo/text/new-long-text.txt')
|
|
13
|
+
|
|
14
|
+
// 同步读取文件内容
|
|
15
|
+
const oldLongText = fs.readFileSync(oldTextPath, 'utf-8')
|
|
16
|
+
const newLongText = fs.readFileSync(newTextPath, 'utf-8')
|
|
17
|
+
|
|
18
|
+
console.log('开始执行性能测试...') // 更新日志消息以匹配函数名
|
|
19
|
+
|
|
20
|
+
const label = 'createSplitDiff execution time' // 更新标签以匹配函数名
|
|
21
|
+
|
|
22
|
+
// 开始计时
|
|
23
|
+
console.time(label)
|
|
24
|
+
|
|
25
|
+
// 执行函数
|
|
26
|
+
try {
|
|
27
|
+
const _result = createSplitDiff(oldLongText, newLongText) // 将 result 重命名为 _result 以消除未使用变量的警告
|
|
28
|
+
console.log(_result.changes.length)
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('执行 createSplitDiff 时出错:', error) // 更新错误消息
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 结束计时并打印时间
|
|
35
|
+
console.timeEnd(label)
|
|
36
|
+
|
|
37
|
+
console.log('性能测试完成.')
|
|
38
|
+
|
|
39
|
+
// 你可能还需要一个空的 export {} 来让 TypeScript 将其视为一个模块(如果需要)
|
|
40
|
+
// export {};
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const { switchVersion
|
|
1
|
+
const fs = require('node:fs')
|
|
2
|
+
const { switchVersion } = require('./utils.cjs')
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (fs.existsSync('.local'))
|
|
4
|
+
if (fs.existsSync('.local')) {
|
|
7
5
|
console.log('Currently, it is the local development environment, not doing anything.')
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
const { version } = require('vue')
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
else
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
else if (Vue.version.startsWith('3.'))
|
|
19
|
-
switchVersion('3')
|
|
20
|
-
|
|
21
|
-
else console.warn(`[v-code-diff] Vue version v${Vue.version} is not suppported.`)
|
|
10
|
+
if (version.startsWith('2.7.'))
|
|
11
|
+
switchVersion('2.7')
|
|
12
|
+
else if (version.startsWith('2.'))
|
|
13
|
+
switchVersion('2')
|
|
14
|
+
else if (version.startsWith('3.'))
|
|
15
|
+
switchVersion('3')
|
|
16
|
+
else
|
|
17
|
+
throw new Error(`[v-code-diff] Vue version v${version} is not supported.`)
|
|
18
|
+
}
|
package/scripts/utils.cjs
CHANGED
|
@@ -1,36 +1,21 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
1
|
+
const fs = require('node:fs')
|
|
2
|
+
const path = require('node:path')
|
|
3
3
|
|
|
4
4
|
const dir = path.resolve(__dirname, '..', 'dist')
|
|
5
5
|
|
|
6
|
-
function loadModule(name) {
|
|
7
|
-
try {
|
|
8
|
-
return require(name)
|
|
9
|
-
}
|
|
10
|
-
catch (e) {
|
|
11
|
-
return undefined
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
6
|
function copy(name, version, vue) {
|
|
16
7
|
vue = vue || 'vue'
|
|
17
8
|
const src = path.join(dir, `v${version}`, name)
|
|
18
9
|
const dest = path.join(dir, name)
|
|
19
10
|
let content = fs.readFileSync(src, 'utf-8')
|
|
20
11
|
content = content.replace(/'vue'/g, `'${vue}'`)
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
fs.unlinkSync(dest)
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
}
|
|
12
|
+
fs.rmSync(dest, { force: true })
|
|
27
13
|
fs.writeFileSync(dest, content, 'utf-8')
|
|
28
14
|
}
|
|
29
15
|
|
|
30
16
|
function switchVersion(version, vue) {
|
|
31
17
|
copy('index.es.js', version, vue)
|
|
32
|
-
copy('index.cjs
|
|
18
|
+
copy('index.cjs', version, vue)
|
|
33
19
|
}
|
|
34
20
|
|
|
35
|
-
module.exports.loadModule = loadModule
|
|
36
21
|
module.exports.switchVersion = switchVersion
|
package/src/CodeDiff.vue
CHANGED
|
@@ -81,9 +81,10 @@ const diffChange = ref(raw.value)
|
|
|
81
81
|
const isNotChanged = computed(() => diffChange.value.stat.additionsNum === 0 && diffChange.value.stat.deletionsNum === 0)
|
|
82
82
|
|
|
83
83
|
const currentDiffIndex = ref(-1)
|
|
84
|
+
const root = ref<HTMLElement>()
|
|
84
85
|
|
|
85
86
|
function goToNextDiff() {
|
|
86
|
-
const diffs =
|
|
87
|
+
const diffs = root.value!.querySelectorAll('[data-diff-change]')
|
|
87
88
|
if (currentDiffIndex.value < diffs.length - 1) {
|
|
88
89
|
currentDiffIndex.value++
|
|
89
90
|
updateCurrentDiffHighlight(diffs)
|
|
@@ -91,7 +92,7 @@ function goToNextDiff() {
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
function goToPrevDiff() {
|
|
94
|
-
const diffs =
|
|
95
|
+
const diffs = root.value!.querySelectorAll('[data-diff-change]')
|
|
95
96
|
if (currentDiffIndex.value > 0) {
|
|
96
97
|
currentDiffIndex.value--
|
|
97
98
|
updateCurrentDiffHighlight(diffs)
|
|
@@ -99,17 +100,18 @@ function goToPrevDiff() {
|
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
function updateCurrentDiffHighlight(diffs: NodeListOf<Element>) {
|
|
102
|
-
|
|
103
|
+
root.value!.querySelectorAll('.current-diff').forEach(diff => diff.classList.remove('current-diff'))
|
|
103
104
|
|
|
104
105
|
const currentDiff = diffs[currentDiffIndex.value]
|
|
105
106
|
|
|
106
107
|
if (currentDiff) {
|
|
107
|
-
currentDiff.classList.add('current-diff')
|
|
108
|
+
currentDiff.querySelectorAll('.blob-code').forEach(diff => diff.classList.add('current-diff'))
|
|
108
109
|
currentDiff.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
watch(() => props, () => {
|
|
114
|
+
currentDiffIndex.value = -1
|
|
113
115
|
diffChange.value = raw.value
|
|
114
116
|
emits('diff', {
|
|
115
117
|
stat: {
|
|
@@ -122,7 +124,7 @@ watch(() => props, () => {
|
|
|
122
124
|
</script>
|
|
123
125
|
|
|
124
126
|
<template>
|
|
125
|
-
<div class="code-diff-view" :theme="theme" :style="{ maxHeight }">
|
|
127
|
+
<div ref="root" class="code-diff-view" :theme="theme" :style="{ maxHeight }">
|
|
126
128
|
<div v-if="!hideHeader" class="file-header">
|
|
127
129
|
<!-- line by line -->
|
|
128
130
|
<div v-if="isUnifiedViewer" class="file-info">
|
package/src/split/SplitLine.vue
CHANGED
|
@@ -16,9 +16,10 @@ function getCodeMarker(type: DiffType) {
|
|
|
16
16
|
return ''
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function onSplitLineMousedown(side: 'left' | 'right') {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
19
|
+
function onSplitLineMousedown(event: MouseEvent, side: 'left' | 'right') {
|
|
20
|
+
const table = (event.currentTarget as HTMLElement).closest('.file-diff-split')!
|
|
21
|
+
const leftElements = table.querySelectorAll('.split-side-left')
|
|
22
|
+
const rightElements = table.querySelectorAll('.split-side-right')
|
|
22
23
|
|
|
23
24
|
for (const el of rightElements)
|
|
24
25
|
el.classList.toggle('no-select', side === 'left')
|
|
@@ -37,7 +38,10 @@ function onSplitLineMousedown(side: 'left' | 'right') {
|
|
|
37
38
|
⋯
|
|
38
39
|
</td>
|
|
39
40
|
</tr>
|
|
40
|
-
<tr
|
|
41
|
+
<tr
|
|
42
|
+
v-else-if="!splitLine.hide"
|
|
43
|
+
:data-diff-change="splitLine.left.type === DiffType.DELETE || splitLine.right.type === DiffType.ADD ? '' : undefined"
|
|
44
|
+
>
|
|
41
45
|
<template v-for="(line, index) in [splitLine.left, splitLine.right]">
|
|
42
46
|
<!-- eslint-disable -->
|
|
43
47
|
<template v-if="line.type === DiffType.EMPTY">
|
|
@@ -66,7 +70,7 @@ function onSplitLineMousedown(side: 'left' | 'right') {
|
|
|
66
70
|
'split-side-left': index === 0,
|
|
67
71
|
'split-side-right': index === 1,
|
|
68
72
|
}"
|
|
69
|
-
@mousedown="onSplitLineMousedown(index === 0 ? 'left' : 'right')"
|
|
73
|
+
@mousedown="onSplitLineMousedown($event, index === 0 ? 'left' : 'right')"
|
|
70
74
|
>
|
|
71
75
|
<span
|
|
72
76
|
class="blob-code-inner blob-code-marker" :data-code-marker="getCodeMarker(line.type)"
|
package/src/utils.ts
CHANGED
|
@@ -11,6 +11,17 @@ const MODIFIED_CLOSE_TAG = '</code-diff-modified>'
|
|
|
11
11
|
const startEntity = MODIFIED_START_TAG.replace('<', '<').replace('>', '>')
|
|
12
12
|
const closeEntity = MODIFIED_CLOSE_TAG.replace('<', '<').replace('>', '>')
|
|
13
13
|
|
|
14
|
+
function escapeHtml(code: string): string {
|
|
15
|
+
const entities: Record<string, string> = {
|
|
16
|
+
'&': '&',
|
|
17
|
+
'<': '<',
|
|
18
|
+
'>': '>',
|
|
19
|
+
'"': '"',
|
|
20
|
+
'\'': ''',
|
|
21
|
+
}
|
|
22
|
+
return code.replace(/[&<>"']/g, char => entities[char])
|
|
23
|
+
}
|
|
24
|
+
|
|
14
25
|
function lineType(diff: Diff.Change): DiffType {
|
|
15
26
|
if (diff === undefined)
|
|
16
27
|
return DiffType.EQUAL
|
|
@@ -59,6 +70,12 @@ function diffLines(prev: string, current: string) {
|
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
function getHighlightCode(language: string, code: string) {
|
|
73
|
+
if (typeof document === 'undefined') {
|
|
74
|
+
return escapeHtml(code)
|
|
75
|
+
.replace(new RegExp(startEntity, 'g'), '<span class="x">')
|
|
76
|
+
.replace(new RegExp(closeEntity, 'g'), '</span>')
|
|
77
|
+
}
|
|
78
|
+
|
|
62
79
|
const hasModifiedTags = code.match(new RegExp(`(${MODIFIED_START_TAG}|${MODIFIED_CLOSE_TAG})`, 'g'))
|
|
63
80
|
|
|
64
81
|
if (!hasModifiedTags)
|
package/types/index.d.ts
CHANGED
|
@@ -8,8 +8,11 @@ declare const _default: {
|
|
|
8
8
|
|
|
9
9
|
// eslint-disable-next-line
|
|
10
10
|
declare const CodeDiff: DefineComponent<{}, {}, any>
|
|
11
|
+
// eslint-disable-next-line
|
|
12
|
+
declare const CodeReader: DefineComponent<{}, {}, any>
|
|
11
13
|
export {
|
|
12
14
|
CodeDiff,
|
|
15
|
+
CodeReader,
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
export default _default
|