diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2023-10-29 14:12:40 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-29 14:12:40 +0900 |
| commit | 1a8243f1cace06c2eb872177d39536f76c9a8f5d (patch) | |
| tree | d75937ed6b116a98e3139d98b34bea4344c86f3e /packages/frontend/src/components/MkCode.core.vue | |
| parent | enhance(frontend): tweak about-misskey page (diff) | |
| download | sharkey-1a8243f1cace06c2eb872177d39536f76c9a8f5d.tar.gz sharkey-1a8243f1cace06c2eb872177d39536f76c9a8f5d.tar.bz2 sharkey-1a8243f1cace06c2eb872177d39536f76c9a8f5d.zip | |
MkCodeのパースエンジンをShikiに変更 (#12102)
* (swap) prism -> shiki
* fix styles
* (bump) aiscript-vscode to v0.0.5
* refactor
* replace prism-editor (beta)
* Update scratchpad.vue
* (enhance) MkCodeEditor自動インデント改行
* (fix) lint
* (add) scratchpad: MkStickyContainer
* Update CHANGELOG.md
* clean up
---------
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Diffstat (limited to 'packages/frontend/src/components/MkCode.core.vue')
| -rw-r--r-- | packages/frontend/src/components/MkCode.core.vue | 85 |
1 files changed, 77 insertions, 8 deletions
diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue index a1300be1f6..4ec3540419 100644 --- a/packages/frontend/src/components/MkCode.core.vue +++ b/packages/frontend/src/components/MkCode.core.vue @@ -5,21 +5,90 @@ SPDX-License-Identifier: AGPL-3.0-only <!-- eslint-disable vue/no-v-html --> <template> -<code v-if="inline" :class="`language-${prismLang}`" style="overflow-wrap: anywhere;" v-html="html"></code> -<pre v-else :class="`language-${prismLang}`"><code :class="`language-${prismLang}`" v-html="html"></code></pre> +<div :class="['codeBlockRoot', { 'codeEditor': codeEditor }]" v-html="html"></div> </template> <script lang="ts" setup> -import { computed } from 'vue'; -import Prism from 'prismjs'; -import 'prismjs/themes/prism-okaidia.css'; +import { ref, computed, watch } from 'vue'; +import { BUNDLED_LANGUAGES } from 'shiki'; +import type { Lang as ShikiLang } from 'shiki'; +import { getHighlighter } from '@/scripts/code-highlighter.js'; const props = defineProps<{ code: string; lang?: string; - inline?: boolean; + codeEditor?: boolean; }>(); -const prismLang = computed(() => Prism.languages[props.lang] ? props.lang : 'js'); -const html = computed(() => Prism.highlight(props.code, Prism.languages[prismLang.value], prismLang.value)); +const highlighter = await getHighlighter(); + +const codeLang = ref<ShikiLang | 'aiscript'>('js'); +const html = computed(() => highlighter.codeToHtml(props.code, { + lang: codeLang.value, + theme: 'dark-plus', +})); + +async function fetchLanguage(to: string): Promise<void> { + const language = to as ShikiLang; + + // Check for the loaded languages, and load the language if it's not loaded yet. + if (!highlighter.getLoadedLanguages().includes(language)) { + // Check if the language is supported by Shiki + const bundles = BUNDLED_LANGUAGES.filter((bundle) => { + // Languages are specified by their id, they can also have aliases (i. e. "js" and "javascript") + return bundle.id === language || bundle.aliases?.includes(language); + }); + if (bundles.length > 0) { + await highlighter.loadLanguage(language); + codeLang.value = language; + } else { + codeLang.value = 'js'; + } + } else { + codeLang.value = language; + } +} + +watch(() => props.lang, (to) => { + if (codeLang.value === to || !to) return; + return new Promise((resolve) => { + fetchLanguage(to).then(() => resolve); + }); +}, { immediate: true, }); </script> + +<style scoped lang="scss"> +.codeBlockRoot :deep(.shiki) { + padding: 1em; + margin: .5em 0; + overflow: auto; + border-radius: .3em; + + & pre, + & code { + font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; + } +} + +.codeBlockRoot.codeEditor { + min-width: 100%; + height: 100%; + + & :deep(.shiki) { + padding: 12px; + margin: 0; + border-radius: 6px; + min-height: 130px; + pointer-events: none; + min-width: calc(100% - 24px); + height: 100%; + display: inline-block; + line-height: 1.5em; + font-size: 1em; + overflow: visible; + text-rendering: inherit; + text-transform: inherit; + white-space: pre; + } +} +</style> |