Skip to content

Commit

Permalink
fix: HTML 渲染异常 (Chanzhaoyu#152)
Browse files Browse the repository at this point in the history
* fix: 修复 `API` 版本 HTML 会被渲染的问题[Chanzhaoyu#146]

* chore: version 2.8.1
  • Loading branch information
Chanzhaoyu committed Feb 27, 2023
1 parent 2c509c3 commit 21fb4f8
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 17 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## v2.8.1

`2023-02-27`

### BugFix
- 修复 `API` 版本不是 `Markdown` 时,普通 `HTML` 代码会被渲染的问题 [#146]

## v2.8.0

`2023-02-27`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chatgpt-web",
"version": "2.8.0",
"version": "2.8.1",
"private": false,
"description": "ChatGPT Web",
"author": "ChenZhaoYu <[email protected]>",
Expand Down
23 changes: 23 additions & 0 deletions src/directives/highlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { App, Directive } from 'vue'
import hljs from 'highlight.js'
import { includeCode } from '@/utils/format'

hljs.configure({ ignoreUnescapedHTML: true })

function highlightCode(el: HTMLElement) {
if (includeCode(el.textContent))
hljs.highlightBlock(el)
}

export default function setupHighlightDirective(app: App) {
const highLightDirective: Directive<HTMLElement> = {
mounted(el: HTMLElement) {
highlightCode(el)
},
updated(el: HTMLElement) {
highlightCode(el)
},
}

app.directive('highlight', highLightDirective)
}
7 changes: 6 additions & 1 deletion src/directives/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export function setupDirectives() {}
import type { App } from 'vue'
import setupHighlightDirective from './highlight'

export function setupDirectives(app: App) {
setupHighlightDirective(app)
}
3 changes: 3 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createApp } from 'vue'
import App from './App.vue'
import { setupDirectives } from './directives'
import { setupAssets } from '@/plugins'
import { setupStore } from '@/store'
import { setupRouter } from '@/router'
Expand All @@ -10,6 +11,8 @@ async function bootstrap() {

setupStore(app)

setupDirectives(app)

await setupRouter(app)

app.mount('#app')
Expand Down
15 changes: 15 additions & 0 deletions src/utils/format/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 转义 HTML 字符
export function encodeHTML(source: string) {
return source
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
}

// 判断是否为代码块
export function includeCode(text: string | null | undefined) {
const regexp = /^(?:\s{4}|\t).+/gm
return !!(text?.includes(' = ') || text?.match(regexp))
}
6 changes: 0 additions & 6 deletions src/utils/functions/includeCode.ts

This file was deleted.

27 changes: 18 additions & 9 deletions src/views/chat/components/Message/Text.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { computed } from 'vue'
import { marked } from 'marked'
import hljs from 'highlight.js'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { encodeHTML } from '@/utils/format'
interface Props {
inversion?: boolean
Expand All @@ -15,12 +16,19 @@ const props = defineProps<Props>()
const { isMobile } = useBasicLayout()
marked.setOptions({
renderer: new marked.Renderer(),
highlight(code) {
return hljs.highlightAuto(code).value
},
})
const renderer = new marked.Renderer()
renderer.html = (html) => {
return `<p>${encodeHTML(html)}</p>`
}
renderer.code = (code, language) => {
const validLang = !!(language && hljs.getLanguage(language))
const highlighted = validLang ? hljs.highlight(language, code).value : code
return `<pre><code class="hljs ${language}">${highlighted}</code></pre>`
}
marked.setOptions({ renderer })
const wrapClass = computed(() => {
return [
Expand All @@ -35,9 +43,10 @@ const wrapClass = computed(() => {
})
const text = computed(() => {
if (props.text && !props.inversion)
return marked(props.text)
return props.text
const value = props.text ?? ''
if (!props.inversion)
return marked(value)
return value
})
</script>

Expand Down

0 comments on commit 21fb4f8

Please sign in to comment.