Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Commit 3cf101e

Browse files
committed
chore: development
1 parent a7e1d02 commit 3cf101e

File tree

4 files changed

+81
-14
lines changed

4 files changed

+81
-14
lines changed

dev/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export default defineComponent({
5050
const modes = ref(['split', 'unified'])
5151
const mode = ref('split')
5252
const languages = ref(['javascript', 'html', 'css'])
53-
const language = ref('html')
53+
const language = ref('javascript')
5454
const themes = ref(['dark', 'light'])
5555
const theme = ref('dark')
5656

src/Code.vue

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,23 @@
77

88
<script lang="ts">
99
import hljs from 'highlight.js'
10-
import { defineComponent, ref, onMounted } from 'vue'
10+
import { defineComponent, ref, onMounted, watch } from 'vue'
1111
import { MODIFIED_START_TAG, MODIFIED_CLOSE_TAG } from './utils'
1212
import 'highlight.js/styles/monokai.css'
1313
14+
hljs.configure({
15+
noHighlightRe: new RegExp(`(${MODIFIED_START_TAG}|${MODIFIED_CLOSE_TAG})`, 'g')
16+
})
17+
18+
function escapeHTML (value: string) {
19+
return value
20+
// .replace(/&/g, '&amp;')
21+
// .replace(/</g, '&lt;')
22+
// .replace(/>/g, '&gt;')
23+
// .replace(/"/g, '&quot;')
24+
// .replace(/'/g, '&#x27;')
25+
}
26+
1427
export default defineComponent({
1528
props: {
1629
language: {
@@ -25,14 +38,68 @@ export default defineComponent({
2538
setup (props) {
2639
const code = ref('')
2740
28-
const pureValue = props.value.replace(new RegExp(`(${MODIFIED_START_TAG}|${MODIFIED_CLOSE_TAG})`, 'g'), '')
29-
code.value = hljs.highlight(props.language, pureValue).value
30-
3141
onMounted(() => {
32-
const el = document.createElement('div')
33-
el.innerHTML = code.value
42+
watch(() => props.value, () => {
43+
const hasModifyTags = props.value.match(new RegExp(`(${MODIFIED_START_TAG}|${MODIFIED_CLOSE_TAG})`, 'g'))
44+
45+
if (!hasModifyTags) {
46+
const { value: highlightCode } = hljs.highlight(props.language, props.value)
47+
code.value = highlightCode
48+
return
49+
}
50+
51+
let highlightCode = ''
52+
const pureValue = props.value.replace(new RegExp(`(${MODIFIED_START_TAG}|${MODIFIED_CLOSE_TAG})`, 'g'), '') // without modify tag
53+
54+
const pureHighlightCode = hljs.highlight(props.language, pureValue).value
55+
let plainCode = escapeHTML(props.value)
56+
highlightCode = plainCode
57+
58+
const pureEl = document.createElement('pre')
59+
pureEl.innerHTML = pureHighlightCode
60+
const plainEl = document.createElement('div')
61+
plainEl.innerHTML = plainCode
62+
63+
function diff (node: HTMLElement) {
64+
node.childNodes.forEach(child => {
65+
if (child.nodeType === 1) {
66+
diff(child as HTMLElement)
67+
}
68+
if (child.nodeType === 3) {
69+
if (!child.textContent) return
70+
71+
let text = escapeHTML(child.textContent)
72+
73+
let code = ''
74+
75+
while (text.length) {
76+
if (plainCode.startsWith(MODIFIED_START_TAG)) {
77+
plainCode = plainCode.slice(MODIFIED_START_TAG.length)
78+
code = code + MODIFIED_START_TAG
79+
continue
80+
}
81+
if (plainCode.startsWith(MODIFIED_CLOSE_TAG)) {
82+
plainCode = plainCode.slice(MODIFIED_CLOSE_TAG.length)
83+
code = code + MODIFIED_CLOSE_TAG
84+
continue
85+
}
86+
87+
code = code + text[0]
88+
plainCode = plainCode.slice(1)
89+
text = text.slice(1)
90+
}
91+
92+
child.textContent = code
93+
}
94+
})
95+
}
96+
diff(pureEl)
97+
98+
const startEntity = MODIFIED_START_TAG.replace('<', '&lt;').replace('>', '&gt;')
99+
const closeEntity = MODIFIED_CLOSE_TAG.replace('<', '&lt;').replace('>', '&gt;')
34100
35-
console.log(el.childNodes)
101+
code.value = pureEl.innerHTML.replace(new RegExp(startEntity, 'g'), '<span class="modified">').replace(new RegExp(closeEntity, 'g'), '</span>')
102+
}, { immediate: true })
36103
})
37104
38105
return {

src/Line.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ td {
109109
td.vue-diff-cell-removed {
110110
background-color: rgba(255, 0, 0, .1);
111111
112-
:deep(.hljs-modified) {
113-
background-color: rgba(255, 0, 0, .3);
112+
:deep(.modified) {
113+
background-color: rgba(255, 0, 0, .2);
114114
}
115115
}
116116
@@ -123,8 +123,8 @@ td.vue-diff-cell-removed.code {
123123
td.vue-diff-cell-added {
124124
background-color: rgba(0, 255, 128, .1);
125125
126-
:deep(.hljs-modified) {
127-
background-color: rgba(0, 255, 128, .3);
126+
:deep(.modified) {
127+
background-color: rgba(0, 255, 128, .2);
128128
}
129129
}
130130

src/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ interface Line {
1414
type Lines = Array<Line>
1515
type Diffs = Array<Change>
1616

17-
const MODIFIED_START_TAG = '<span class="modified">'
18-
const MODIFIED_CLOSE_TAG = '</span>'
17+
const MODIFIED_START_TAG = '<vue-diff-modified>'
18+
const MODIFIED_CLOSE_TAG = '</vue-diff-modified>'
1919

2020
const getDiffType = (diff: Change) => {
2121
if (!diff.count) return 'disabled'

0 commit comments

Comments
 (0)