md添加hightlight支持。

This commit is contained in:
539943419 committed 2025-01-20 23:42:33 +08:00
1 parent 63206e71b8
commit 72ba1691fb
6 files changed
+385 -18

No files matched your search

+95 -6
View File
@@ -12,6 +12,7 @@
</div> </div>
<miao-collapse :show="show" style="overflow: hidden;"> <miao-collapse :show="show" style="overflow: hidden;">
<div ref="cmRootRef"></div> <div ref="cmRootRef"></div>
<el-skeleton v-if="isLoading === true" :rows="rows" style="display: flex;flex-direction: column;" />
</miao-collapse> </miao-collapse>
</div> </div>
</template> </template>
@@ -23,29 +24,116 @@ import { EditorState } from "@codemirror/state"
// import {javascript} from "@codemirror/lang-javascript" // import {javascript} from "@codemirror/lang-javascript"
const props = defineProps<{ const props = defineProps<{
data: string data: string,
type?: string,
}>() }>()
const show = ref(true) const show = ref(true)
const cmRootRef = ref<HTMLElement>() const cmRootRef = ref<HTMLElement>()
onMounted(() => { const isLoading = ref(true)
if (!cmRootRef.value) {
return const rows = computed(() => {
if (!props.data) {
return 5
} }
new EditorView({ const lines = props.data.split('\n')
console.log({
L: lines.length,
})
return lines.length - 2 > 0 ? lines.length - 2 : 1
})
const useLangExtensions = async () => {
const ext = props.type
switch (ext) {
case 'js':
case 'jsx':
case 'ts':
case 'tsx':
const { javascript } = await import('@codemirror/lang-javascript')
return [
javascript({
jsx: ext.substring(2, 3) === 'x',
typescript: ext.substring(0, 2) === 'js'
})
]
break
case 'css':
case 'scss':
const { sass } = await import('@codemirror/lang-sass')
return [sass()]
break
case 'html':
const { html } = await import('@codemirror/lang-html')
return [html()]
break
case 'py':
const { python } = await import('@codemirror/lang-python')
return [python()]
break
case 'go':
const { go } = await import('@codemirror/lang-go')
return [go()]
break
case 'json':
const { json } = await import('@codemirror/lang-json')
return [json()]
break
case 'md':
const { markdown } = await import('@codemirror/lang-markdown')
return [markdown()]
break
case 'yaml':
const { yaml } = await import('@codemirror/lang-yaml')
return [yaml()]
break
case 'vue':
const { vue } = await import('@codemirror/lang-vue')
return [vue()]
break
case 'xml':
const { xml } = await import('@codemirror/lang-xml')
return [xml()]
break
default:
return []
}
}
let cm: EditorView
onMounted(async () => {
const langExtensions = await useLangExtensions()
cm = new EditorView({
parent: cmRootRef.value, parent: cmRootRef.value,
doc: props.data, doc: props.data,
extensions: [ extensions: [
basicSetup, basicSetup,
EditorState.readOnly.of(true), EditorState.readOnly.of(true),
...langExtensions
], ],
}) })
isLoading.value = false
})
onUpdated(() => {
cm.dispatch({
changes: {
from: 0,
to: cm.state.doc.length,
insert: props.data,
},
})
})
onBeforeUnmount(() => {
cm.destroy()
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.cm-rander-wrapper { .cm-rander-wrapper {
.cm-header { .cm-header {
display: flex; display: flex;
@@ -57,6 +145,7 @@ onMounted(() => {
color: #fff; color: #fff;
border-radius: 10px 10px 0 0; border-radius: 10px 10px 0 0;
user-select: none; user-select: none;
.cm-header-controls { .cm-header-controls {
.cm-switch-show-hide { .cm-switch-show-hide {
cursor: pointer; cursor: pointer;
+12 -3
View File
@@ -33,15 +33,24 @@ const VNodeArr = computed(() => {
}, },
rander({ rander({
item, item,
tagName, // tagName,
tagAttrs, tagAttrs,
middlewareMap // middlewareMap
}) { }) {
// console.log({
// tagName,
// tagAttrs,
// })
const codeType = tagAttrs?.class?.slice(1, -1)?.split('-')?.[1] ?? ''
// console.log({
// codeType,
// })
return h( return h(
codeMirror, codeMirror,
{ {
// @ts-ignore // @ts-ignore
data: (item.children[0].children as string).replaceAll('&lt;', '<').replaceAll('&gt;', '>'), data: item.children[0].children.trim(),
type: codeType,
}, },
) )
}, },
+2 -2
View File
@@ -67,14 +67,14 @@ const handleShow = () => {
cwStyle.value = { cwStyle.value = {
maxHeight: 0, maxHeight: 0,
opacity: 0, opacity: 0,
transition: "all 0.2s ease-in-out, opacity 0.3s ease-in", transition: "all .2s ease-in-out, opacity .15s ease-in .07s",
pointerEvents: 'none', pointerEvents: 'none',
} }
timer.push(setTimeout(() => { timer.push(setTimeout(() => {
cwStyle.value = { cwStyle.value = {
maxHeight: `${originHeight}px`, maxHeight: `${originHeight}px`,
opacity: 1, opacity: 1,
transition: "all 0.2s ease-in-out, opacity 0.3s ease-in" transition: "all .2s ease-in-out, opacity .15s ease-in .07s"
} }
timer.push(setTimeout(() => { timer.push(setTimeout(() => {
cwStyle.value = { cwStyle.value = {
+9
View File
@@ -29,6 +29,15 @@
"vue-router": "^4.3.0" "vue-router": "^4.3.0"
}, },
"devDependencies": { "devDependencies": {
"@codemirror/lang-go": "^6.0.1",
"@codemirror/lang-html": "^6.4.9",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-markdown": "^6.3.2",
"@codemirror/lang-python": "^6.1.7",
"@codemirror/lang-sass": "^6.0.2",
"@codemirror/lang-vue": "^0.1.3",
"@codemirror/lang-xml": "^6.1.0",
"@codemirror/lang-yaml": "^6.1.2",
"@element-plus/nuxt": "^1.1.1", "@element-plus/nuxt": "^1.1.1",
"@types/bcryptjs": "^2.4.6", "@types/bcryptjs": "^2.4.6",
"@types/better-sqlite3": "^7.6.12", "@types/better-sqlite3": "^7.6.12",
+224
View File
@@ -60,6 +60,33 @@ importers:
specifier: ^4.3.0 specifier: ^4.3.0
version: 4.5.0(vue@3.5.13(typescript@5.7.3)) version: 4.5.0(vue@3.5.13(typescript@5.7.3))
devDependencies: devDependencies:
'@codemirror/lang-go':
specifier: ^6.0.1
version: 6.0.1
'@codemirror/lang-html':
specifier: ^6.4.9
version: 6.4.9
'@codemirror/lang-json':
specifier: ^6.0.1
version: 6.0.1
'@codemirror/lang-markdown':
specifier: ^6.3.2
version: 6.3.2
'@codemirror/lang-python':
specifier: ^6.1.7
version: 6.1.7
'@codemirror/lang-sass':
specifier: ^6.0.2
version: 6.0.2
'@codemirror/lang-vue':
specifier: ^0.1.3
version: 0.1.3
'@codemirror/lang-xml':
specifier: ^6.1.0
version: 6.1.0
'@codemirror/lang-yaml':
specifier: ^6.1.2
version: 6.1.2
'@element-plus/nuxt': '@element-plus/nuxt':
specifier: ^1.1.1 specifier: ^1.1.1
version: 1.1.1(@element-plus/icons-vue@2.3.1(vue@3.5.13(typescript@5.7.3)))(element-plus@2.9.3(vue@3.5.13(typescript@5.7.3)))(magicast@0.3.5)(rollup@4.30.1) version: 1.1.1(@element-plus/icons-vue@2.3.1(vue@3.5.13(typescript@5.7.3)))(element-plus@2.9.3(vue@3.5.13(typescript@5.7.3)))(magicast@0.3.5)(rollup@4.30.1)
@@ -241,9 +268,39 @@ packages:
'@codemirror/commands@6.8.0': '@codemirror/commands@6.8.0':
resolution: {integrity: sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==} resolution: {integrity: sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==}
'@codemirror/lang-css@6.3.1':
resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==}
'@codemirror/lang-go@6.0.1':
resolution: {integrity: sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==}
'@codemirror/lang-html@6.4.9':
resolution: {integrity: sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==}
'@codemirror/lang-javascript@6.2.2': '@codemirror/lang-javascript@6.2.2':
resolution: {integrity: sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==} resolution: {integrity: sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==}
'@codemirror/lang-json@6.0.1':
resolution: {integrity: sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==}
'@codemirror/lang-markdown@6.3.2':
resolution: {integrity: sha512-c/5MYinGbFxYl4itE9q/rgN/sMTjOr8XL5OWnC+EaRMLfCbVUmmubTJfdgpfcSS2SCaT7b+Q+xi3l6CgoE+BsA==}
'@codemirror/lang-python@6.1.7':
resolution: {integrity: sha512-mZnFTsL4lW5p9ch8uKNKeRU3xGGxr1QpESLilfON2E3fQzOa/OygEMkaDvERvXDJWJA9U9oN/D4w0ZuUzNO4+g==}
'@codemirror/lang-sass@6.0.2':
resolution: {integrity: sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==}
'@codemirror/lang-vue@0.1.3':
resolution: {integrity: sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==}
'@codemirror/lang-xml@6.1.0':
resolution: {integrity: sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==}
'@codemirror/lang-yaml@6.1.2':
resolution: {integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==}
'@codemirror/language@6.10.8': '@codemirror/language@6.10.8':
resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==} resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==}
@@ -612,15 +669,42 @@ packages:
'@lezer/common@1.2.3': '@lezer/common@1.2.3':
resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==} resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==}
'@lezer/css@1.1.9':
resolution: {integrity: sha512-TYwgljcDv+YrV0MZFFvYFQHCfGgbPMR6nuqLabBdmZoFH3EP1gvw8t0vae326Ne3PszQkbXfVBjCnf3ZVCr0bA==}
'@lezer/go@1.0.0':
resolution: {integrity: sha512-co9JfT3QqX1YkrMmourYw2Z8meGC50Ko4d54QEcQbEYpvdUvN4yb0NBZdn/9ertgvjsySxHsKzH3lbm3vqJ4Jw==}
'@lezer/highlight@1.2.1': '@lezer/highlight@1.2.1':
resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==} resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==}
'@lezer/html@1.3.10':
resolution: {integrity: sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==}
'@lezer/javascript@1.4.21': '@lezer/javascript@1.4.21':
resolution: {integrity: sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==} resolution: {integrity: sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==}
'@lezer/json@1.0.3':
resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
'@lezer/lr@1.4.2': '@lezer/lr@1.4.2':
resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==} resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==}
'@lezer/markdown@1.4.0':
resolution: {integrity: sha512-mk4MYeq6ZQdxgsgRAe0G7kqPRV6Desajfa14TcHoGGXIqqj1/2ARN31VFpmrXDgvXiGBWpA7RXtv0he+UdTkGw==}
'@lezer/python@1.1.15':
resolution: {integrity: sha512-aVQ43m2zk4FZYedCqL0KHPEUsqZOrmAvRhkhHlVPnDD1HODDyyQv5BRIuod4DadkgBEZd53vQOtXTonNbEgjrQ==}
'@lezer/sass@1.0.7':
resolution: {integrity: sha512-8HLlOkuX/SMHOggI2DAsXUw38TuURe+3eQ5hiuk9QmYOUyC55B1dYEIMkav5A4IELVaW4e1T4P9WRiI5ka4mdw==}
'@lezer/xml@1.0.6':
resolution: {integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==}
'@lezer/yaml@1.0.3':
resolution: {integrity: sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==}
'@mapbox/node-pre-gyp@2.0.0-rc.0': '@mapbox/node-pre-gyp@2.0.0-rc.0':
resolution: {integrity: sha512-nhSMNprz3WmeRvd8iUs5JqkKr0Ncx46JtPxM3AhXes84XpSJfmIwKeWXRpsr53S7kqPkQfPhzrMFUxSNb23qSA==} resolution: {integrity: sha512-nhSMNprz3WmeRvd8iUs5JqkKr0Ncx46JtPxM3AhXes84XpSJfmIwKeWXRpsr53S7kqPkQfPhzrMFUxSNb23qSA==}
engines: {node: '>=18'} engines: {node: '>=18'}
@@ -3772,6 +3856,34 @@ snapshots:
'@codemirror/view': 6.36.2 '@codemirror/view': 6.36.2
'@lezer/common': 1.2.3 '@lezer/common': 1.2.3
'@codemirror/lang-css@6.3.1':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@lezer/common': 1.2.3
'@lezer/css': 1.1.9
'@codemirror/lang-go@6.0.1':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@lezer/common': 1.2.3
'@lezer/go': 1.0.0
'@codemirror/lang-html@6.4.9':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/lang-css': 6.3.1
'@codemirror/lang-javascript': 6.2.2
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@codemirror/view': 6.36.2
'@lezer/common': 1.2.3
'@lezer/css': 1.1.9
'@lezer/html': 1.3.10
'@codemirror/lang-javascript@6.2.2': '@codemirror/lang-javascript@6.2.2':
dependencies: dependencies:
'@codemirror/autocomplete': 6.18.4 '@codemirror/autocomplete': 6.18.4
@@ -3782,6 +3894,65 @@ snapshots:
'@lezer/common': 1.2.3 '@lezer/common': 1.2.3
'@lezer/javascript': 1.4.21 '@lezer/javascript': 1.4.21
'@codemirror/lang-json@6.0.1':
dependencies:
'@codemirror/language': 6.10.8
'@lezer/json': 1.0.3
'@codemirror/lang-markdown@6.3.2':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/lang-html': 6.4.9
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@codemirror/view': 6.36.2
'@lezer/common': 1.2.3
'@lezer/markdown': 1.4.0
'@codemirror/lang-python@6.1.7':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@lezer/common': 1.2.3
'@lezer/python': 1.1.15
'@codemirror/lang-sass@6.0.2':
dependencies:
'@codemirror/lang-css': 6.3.1
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@lezer/common': 1.2.3
'@lezer/sass': 1.0.7
'@codemirror/lang-vue@0.1.3':
dependencies:
'@codemirror/lang-html': 6.4.9
'@codemirror/lang-javascript': 6.2.2
'@codemirror/language': 6.10.8
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@codemirror/lang-xml@6.1.0':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@codemirror/view': 6.36.2
'@lezer/common': 1.2.3
'@lezer/xml': 1.0.6
'@codemirror/lang-yaml@6.1.2':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.1
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/yaml': 1.0.3
'@codemirror/language@6.10.8': '@codemirror/language@6.10.8':
dependencies: dependencies:
'@codemirror/state': 6.5.1 '@codemirror/state': 6.5.1
@@ -4033,20 +4204,73 @@ snapshots:
'@lezer/common@1.2.3': {} '@lezer/common@1.2.3': {}
'@lezer/css@1.1.9':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/go@1.0.0':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/highlight@1.2.1': '@lezer/highlight@1.2.1':
dependencies: dependencies:
'@lezer/common': 1.2.3 '@lezer/common': 1.2.3
'@lezer/html@1.3.10':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/javascript@1.4.21': '@lezer/javascript@1.4.21':
dependencies: dependencies:
'@lezer/common': 1.2.3 '@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1 '@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2 '@lezer/lr': 1.4.2
'@lezer/json@1.0.3':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/lr@1.4.2': '@lezer/lr@1.4.2':
dependencies: dependencies:
'@lezer/common': 1.2.3 '@lezer/common': 1.2.3
'@lezer/markdown@1.4.0':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/python@1.1.15':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/sass@1.0.7':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/xml@1.0.6':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@lezer/yaml@1.0.3':
dependencies:
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
'@mapbox/node-pre-gyp@2.0.0-rc.0': '@mapbox/node-pre-gyp@2.0.0-rc.0':
dependencies: dependencies:
consola: 3.3.3 consola: 3.3.3
+43 -7
View File
@@ -21,7 +21,7 @@ export default class Html2VNode {
private buildMiddlewareMap(objs: (TagType | miaoVNodeType)[]) { private buildMiddlewareMap(objs: (TagType | miaoVNodeType)[]) {
const tagNameSet = new Set<string>() const tagNameSet = new Set<string>()
const middlewareMap = new Map<string, middlewareType>() const middlewareMap = new Map<string, middlewareType[]>()
for (const item of objs) { for (const item of objs) {
const { tagName = '' } = this.parseTag(item.tag); const { tagName = '' } = this.parseTag(item.tag);
tagNameSet.add(tagName) tagNameSet.add(tagName)
@@ -29,7 +29,11 @@ export default class Html2VNode {
for (const tagName of tagNameSet) { for (const tagName of tagNameSet) {
for (const middleware of this.middlewareList) { for (const middleware of this.middlewareList) {
if (middleware.filter(tagName)) { if (middleware.filter(tagName)) {
middlewareMap.set(tagName, middleware) if(!middlewareMap.has(tagName)) {
middlewareMap.set(tagName, [middleware])
} else {
middlewareMap.get(tagName)!.unshift(middleware)
}
} }
} }
} }
@@ -38,16 +42,26 @@ export default class Html2VNode {
private rander2VNode = ( private rander2VNode = (
wrinklesResult: (miaoVNodeType | string)[], wrinklesResult: (miaoVNodeType | string)[],
middlewareMap: Map<string, middlewareType> middlewareMap: Map<string, middlewareType[]>
): (VNode | string)[] => { ): (VNode | string)[] => {
return wrinklesResult.map((item: miaoVNodeType | string): VNode | string => { return wrinklesResult.map((item: miaoVNodeType | string): VNode | string => {
if (typeof item === 'string') { if (typeof item === 'string') {
return item; return item;
} }
const { tagName = '', tagAttrs } = this.parseTag(item.tag); const { tagName = '', tagAttrs } = this.parseTag(item.tag);
return middlewareMap.get(tagName)!.rander({ const middlewares = middlewareMap.get(tagName)
item, tagName, tagAttrs, middlewareMap for(const middleware of middlewares!) {
const _res = middleware.rander({
item,
tagName,
tagAttrs,
middlewareMap
}) })
if(_res) {
return _res
}
}
return ''
}) })
} }
@@ -75,6 +89,12 @@ export default class Html2VNode {
while (true) { while (true) {
const nextTag = this.getNextHtmlTag(currhtml); const nextTag = this.getNextHtmlTag(currhtml);
if (!nextTag) { if (!nextTag) {
if(currhtml) {
html2ObjResult.push({
tag: '',
children: currhtml,
})
}
break; break;
} }
const middleChild = currhtml.slice(0, nextTag.Index); const middleChild = currhtml.slice(0, nextTag.Index);
@@ -82,15 +102,30 @@ export default class Html2VNode {
html2ObjResult.push({ html2ObjResult.push({
tag: '', tag: '',
children: middleChild, children: middleChild,
// html: middleContent
}) })
} }
currhtml = currhtml.slice(nextTag.Index + nextTag.tag.length); currhtml = currhtml.slice(nextTag.Index + nextTag.tag.length);
html2ObjResult.push(nextTag) html2ObjResult.push(nextTag)
} }
html2ObjResult.forEach(item => {
// @ts-ignore
if(item.children &&typeof item.children==='string') {
// @ts-ignore
item.children = this.parseString(item.children)
}
})
return html2ObjResult; return html2ObjResult;
} }
private parseString = (target: string) => {
return target.replaceAll('&lt;', '<')
.replaceAll('&gt;', '>')
.replaceAll('&amp;', '&')
.replaceAll('&quot;', '"')
.replaceAll('&#39;', '\'')
}
private check = (html2ObjResult: (TagType | miaoVNodeType)[]) => { private check = (html2ObjResult: (TagType | miaoVNodeType)[]) => {
const stack = [] const stack = []
for (const item of html2ObjResult) { for (const item of html2ObjResult) {
@@ -176,13 +211,14 @@ type TagType = {
isClose: boolean; isClose: boolean;
} }
// 要优化也是以后优化了
export type middlewareType = { export type middlewareType = {
filter: (tagName: string) => boolean, filter: (tagName: string) => boolean,
rander: (option: { rander: (option: {
item: miaoVNodeType, item: miaoVNodeType,
tagName: string, tagName: string,
tagAttrs: { [key: string]: string }, tagAttrs: { [key: string]: string },
middlewareMap: Map<string, middlewareType> middlewareMap: Map<string, middlewareType[]>
} }
) => VNode | string ) => VNode | string
} }