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

Commit 21fb4f8

Browse files
authored
fix: HTML 渲染异常 (#152)
* fix: 修复 `API` 版本 HTML 会被渲染的问题[#146] * chore: version 2.8.1
1 parent 2c509c3 commit 21fb4f8

File tree

8 files changed

+73
-17
lines changed

8 files changed

+73
-17
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## v2.8.1
2+
3+
`2023-02-27`
4+
5+
### BugFix
6+
- 修复 `API` 版本不是 `Markdown` 时,普通 `HTML` 代码会被渲染的问题 [#146]
7+
18
## v2.8.0
29

310
`2023-02-27`

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "chatgpt-web",
3-
"version": "2.8.0",
3+
"version": "2.8.1",
44
"private": false,
55
"description": "ChatGPT Web",
66
"author": "ChenZhaoYu <[email protected]>",

src/directives/highlight.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { App, Directive } from 'vue'
2+
import hljs from 'highlight.js'
3+
import { includeCode } from '@/utils/format'
4+
5+
hljs.configure({ ignoreUnescapedHTML: true })
6+
7+
function highlightCode(el: HTMLElement) {
8+
if (includeCode(el.textContent))
9+
hljs.highlightBlock(el)
10+
}
11+
12+
export default function setupHighlightDirective(app: App) {
13+
const highLightDirective: Directive<HTMLElement> = {
14+
mounted(el: HTMLElement) {
15+
highlightCode(el)
16+
},
17+
updated(el: HTMLElement) {
18+
highlightCode(el)
19+
},
20+
}
21+
22+
app.directive('highlight', highLightDirective)
23+
}

src/directives/index.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1-
export function setupDirectives() {}
1+
import type { App } from 'vue'
2+
import setupHighlightDirective from './highlight'
3+
4+
export function setupDirectives(app: App) {
5+
setupHighlightDirective(app)
6+
}

src/main.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createApp } from 'vue'
22
import App from './App.vue'
3+
import { setupDirectives } from './directives'
34
import { setupAssets } from '@/plugins'
45
import { setupStore } from '@/store'
56
import { setupRouter } from '@/router'
@@ -10,6 +11,8 @@ async function bootstrap() {
1011

1112
setupStore(app)
1213

14+
setupDirectives(app)
15+
1316
await setupRouter(app)
1417

1518
app.mount('#app')

src/utils/format/index.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// 转义 HTML 字符
2+
export function encodeHTML(source: string) {
3+
return source
4+
.replace(/&/g, '&amp;')
5+
.replace(/</g, '&lt;')
6+
.replace(/>/g, '&gt;')
7+
.replace(/"/g, '&quot;')
8+
.replace(/'/g, '&#39;')
9+
}
10+
11+
// 判断是否为代码块
12+
export function includeCode(text: string | null | undefined) {
13+
const regexp = /^(?:\s{4}|\t).+/gm
14+
return !!(text?.includes(' = ') || text?.match(regexp))
15+
}

src/utils/functions/includeCode.ts

-6
This file was deleted.

src/views/chat/components/Message/Text.vue

+18-9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { computed } from 'vue'
33
import { marked } from 'marked'
44
import hljs from 'highlight.js'
55
import { useBasicLayout } from '@/hooks/useBasicLayout'
6+
import { encodeHTML } from '@/utils/format'
67
78
interface Props {
89
inversion?: boolean
@@ -15,12 +16,19 @@ const props = defineProps<Props>()
1516
1617
const { isMobile } = useBasicLayout()
1718
18-
marked.setOptions({
19-
renderer: new marked.Renderer(),
20-
highlight(code) {
21-
return hljs.highlightAuto(code).value
22-
},
23-
})
19+
const renderer = new marked.Renderer()
20+
21+
renderer.html = (html) => {
22+
return `<p>${encodeHTML(html)}</p>`
23+
}
24+
25+
renderer.code = (code, language) => {
26+
const validLang = !!(language && hljs.getLanguage(language))
27+
const highlighted = validLang ? hljs.highlight(language, code).value : code
28+
return `<pre><code class="hljs ${language}">${highlighted}</code></pre>`
29+
}
30+
31+
marked.setOptions({ renderer })
2432
2533
const wrapClass = computed(() => {
2634
return [
@@ -35,9 +43,10 @@ const wrapClass = computed(() => {
3543
})
3644
3745
const text = computed(() => {
38-
if (props.text && !props.inversion)
39-
return marked(props.text)
40-
return props.text
46+
const value = props.text ?? ''
47+
if (!props.inversion)
48+
return marked(value)
49+
return value
4150
})
4251
</script>
4352

0 commit comments

Comments
 (0)