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/package.json CHANGED
@@ -1,14 +1,30 @@
1
1
  {
2
2
  "name": "v-code-diff",
3
3
  "type": "module",
4
- "version": "1.13.0",
5
- "description": "template component for vue-demi, can dev and build",
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.js"
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.0",
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 {};
@@ -1,21 +1,18 @@
1
- const fs = require('fs')
2
- const { switchVersion, loadModule } = require('./utils.cjs')
1
+ const fs = require('node:fs')
2
+ const { switchVersion } = require('./utils.cjs')
3
3
 
4
- const Vue = loadModule('vue')
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
- else if (!Vue || typeof Vue.version !== 'string')
10
- console.warn('[v-code-diff] Vue is not found. Please run "npm install vue" to install.')
11
-
12
- else if (Vue.version.startsWith('2.7.'))
13
- switchVersion('2.7')
14
-
15
- else if (Vue.version.startsWith('2.'))
16
- switchVersion('2')
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
- // unlink for pnpm, #92
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.js', version, vue)
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 = document.querySelectorAll('.blob-code-addition')
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 = document.querySelectorAll('.blob-code-addition')
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
- diffs.forEach((diff: { classList: { remove: (arg0: string) => any } }) => diff.classList.remove('current-diff'))
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">
@@ -16,9 +16,10 @@ function getCodeMarker(type: DiffType) {
16
16
  return ''
17
17
  }
18
18
 
19
- function onSplitLineMousedown(side: 'left' | 'right') {
20
- const leftElements = document.querySelectorAll('.file-diff-split .split-side-left')!
21
- const rightElements = document.querySelectorAll('.file-diff-split .split-side-right')!
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 v-else-if="!splitLine.hide">
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)"
@@ -25,7 +25,7 @@ function getCodeMarker(type: DiffType) {
25
25
 
26
26
  </td>
27
27
  </tr>
28
- <tr v-else-if="!line.hide">
28
+ <tr v-else-if="!line.hide" :data-diff-change="line.type !== DiffType.EQUAL ? '' : undefined">
29
29
  <td
30
30
  class="blob-num"
31
31
  :class="{
package/src/utils.ts CHANGED
@@ -11,6 +11,17 @@ const MODIFIED_CLOSE_TAG = '</code-diff-modified>'
11
11
  const startEntity = MODIFIED_START_TAG.replace('<', '&lt;').replace('>', '&gt;')
12
12
  const closeEntity = MODIFIED_CLOSE_TAG.replace('<', '&lt;').replace('>', '&gt;')
13
13
 
14
+ function escapeHtml(code: string): string {
15
+ const entities: Record<string, string> = {
16
+ '&': '&amp;',
17
+ '<': '&lt;',
18
+ '>': '&gt;',
19
+ '"': '&quot;',
20
+ '\'': '&#39;',
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