From 77588c1890cd75a7ac58a1d91dec217037510e78 Mon Sep 17 00:00:00 2001 From: ocavue Date: Tue, 2 Jan 2024 00:46:37 +0800 Subject: [PATCH] fix: trigger code block highlighting when the highlighter is ready (#2539) --- composables/shikiji.ts | 14 ++++--- composables/tiptap/shikiji-parser.ts | 8 ++-- package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++-------------- 4 files changed, 45 insertions(+), 41 deletions(-) diff --git a/composables/shikiji.ts b/composables/shikiji.ts index 6a2476d5..be620e4f 100644 --- a/composables/shikiji.ts +++ b/composables/shikiji.ts @@ -5,7 +5,7 @@ const highlighter = ref() const registeredLang = ref(new Map()) let shikijiImport: Promise | undefined -export function useHighlighter(lang: Lang) { +export function useHighlighter(lang: Lang): { promise?: Promise; highlighter?: Highlighter } { if (!shikijiImport) { shikijiImport = import('shikiji') .then(async ({ getHighlighter }) => { @@ -21,13 +21,15 @@ export function useHighlighter(lang: Lang) { ], }) }) + + return { promise: shikijiImport } } if (!highlighter.value) - return undefined + return { promise: shikijiImport } if (!registeredLang.value.get(lang)) { - highlighter.value.loadLanguage(lang) + const promise = highlighter.value.loadLanguage(lang) .then(() => { registeredLang.value.set(lang, true) }) @@ -37,10 +39,10 @@ export function useHighlighter(lang: Lang) { registeredLang.value.set(fallbackLang, true) }) }) - return undefined + return { promise } } - return highlighter.value + return { highlighter: highlighter.value } } function useShikijiTheme() { @@ -60,7 +62,7 @@ function escapeHtml(text: string) { } export function highlightCode(code: string, lang: Lang) { - const highlighter = useHighlighter(lang) + const { highlighter } = useHighlighter(lang) if (!highlighter) return escapeHtml(code) diff --git a/composables/tiptap/shikiji-parser.ts b/composables/tiptap/shikiji-parser.ts index 1072d0cc..8aa48808 100644 --- a/composables/tiptap/shikiji-parser.ts +++ b/composables/tiptap/shikiji-parser.ts @@ -7,11 +7,13 @@ export const shikijiParser: Parser = (options) => { const lang = options.language ?? 'text' // Register the language if it's not yet registered - const highlighter = useHighlighter(lang as BuiltinLanguage) + const { highlighter, promise } = useHighlighter(lang as BuiltinLanguage) - // If the language is not loaded, we return an empty set of decorations + // If the highlighter or the language is not available, return a promise that + // will resolve when it's ready. When the promise resolves, the editor will + // re-parse the code block. if (!highlighter) - return [] + return promise ?? [] if (!parser) parser = createParser(highlighter) diff --git a/package.json b/package.json index eddbc754..06cb147c 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "page-lifecycle": "^0.1.2", "pinia": "^2.1.4", "postcss-nested": "^6.0.1", - "prosemirror-highlight": "^0.3.3", + "prosemirror-highlight": "^0.4.0", "rollup-plugin-node-polyfills": "^0.2.1", "shikiji": "^0.9.9", "simple-git": "^3.19.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 673424e6..73e7e593 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -180,8 +180,8 @@ importers: specifier: ^6.0.1 version: 6.0.1(postcss@8.4.32) prosemirror-highlight: - specifier: ^0.3.3 - version: 0.3.3(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.5)(shikiji@0.9.9) + specifier: ^0.4.0 + version: 0.4.0(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(shikiji@0.9.9) rollup-plugin-node-polyfills: specifier: ^0.2.1 version: 0.2.1 @@ -4403,14 +4403,14 @@ packages: prosemirror-keymap: 1.2.2 prosemirror-markdown: 1.11.1 prosemirror-menu: 1.2.2 - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-schema-basic: 1.2.2 prosemirror-schema-list: 1.3.0 prosemirror-state: 1.4.3 prosemirror-tables: 1.3.4 - prosemirror-trailing-node: 2.0.4(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.5) + prosemirror-trailing-node: 2.0.4(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7) prosemirror-transform: 1.7.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 transitivePeerDependencies: - supports-color dev: false @@ -12096,7 +12096,7 @@ packages: /prosemirror-commands@1.5.2: resolution: {integrity: sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==} dependencies: - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-state: 1.4.3 prosemirror-transform: 1.7.3 dev: false @@ -12106,20 +12106,20 @@ packages: dependencies: prosemirror-state: 1.4.3 prosemirror-transform: 1.7.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 dev: false /prosemirror-gapcursor@1.3.2: resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==} dependencies: prosemirror-keymap: 1.2.2 - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-state: 1.4.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 dev: false - /prosemirror-highlight@0.3.3(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.5)(shikiji@0.9.9): - resolution: {integrity: sha512-tOGyPvmRKZ49ubzKmFIwiwS7CNXlU9g/D4zZLaHGzXLVNVnBrmbDOajZ4eP0lylOAWPxZN+vrFZ9DwrtyikuoA==} + /prosemirror-highlight@0.4.0(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(shikiji@0.9.9): + resolution: {integrity: sha512-RHGi5QjcWnWgn6bMkjbC2+ehv9Piv3D5UN/dNJG2r738NCQCFye0dkFa6c1oURsvUuwpFiQREqp1YYGpGbZOuA==} peerDependencies: '@types/hast': ^3.0.0 highlight.js: ^11.9.0 @@ -12129,7 +12129,7 @@ packages: prosemirror-transform: ^1.8.0 prosemirror-view: ^1.32.4 refractor: ^4.8.1 - shiki: ^0.14.6 + shiki: ^0.14.0 shikiji: ^0.8.0 || ^0.9.0 peerDependenciesMeta: '@types/hast': @@ -12153,9 +12153,9 @@ packages: shikiji: optional: true dependencies: - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-state: 1.4.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 shikiji: 0.9.9 dev: false @@ -12164,7 +12164,7 @@ packages: dependencies: prosemirror-state: 1.4.3 prosemirror-transform: 1.7.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 rope-sequence: 1.3.4 dev: false @@ -12186,7 +12186,7 @@ packages: resolution: {integrity: sha512-CLOieKoaSSEusKyYcXIj8v2qHGLW+tnuffci+8678Sen48NEFQE7M3o0Nx0gj9v63iVDj+yLibj2gCe8eb3jIw==} dependencies: markdown-it: 13.0.1 - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 dev: false /prosemirror-menu@1.2.2: @@ -12198,8 +12198,8 @@ packages: prosemirror-state: 1.4.3 dev: false - /prosemirror-model@1.19.2: - resolution: {integrity: sha512-RXl0Waiss4YtJAUY3NzKH0xkJmsZupCIccqcIFoLTIKFlKNbIvFDRl27/kQy1FP8iUAxrjRRfIVvOebnnXJgqQ==} + /prosemirror-model@1.19.4: + resolution: {integrity: sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==} dependencies: orderedmap: 2.1.1 dev: false @@ -12207,13 +12207,13 @@ packages: /prosemirror-schema-basic@1.2.2: resolution: {integrity: sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==} dependencies: - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 dev: false /prosemirror-schema-list@1.3.0: resolution: {integrity: sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==} dependencies: - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-state: 1.4.3 prosemirror-transform: 1.7.3 dev: false @@ -12221,22 +12221,22 @@ packages: /prosemirror-state@1.4.3: resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} dependencies: - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-transform: 1.7.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 dev: false /prosemirror-tables@1.3.4: resolution: {integrity: sha512-z6uLSQ1BLC3rgbGwZmpfb+xkdvD7W/UOsURDfognZFYaTtc0gsk7u/t71Yijp2eLflVpffMk6X0u0+u+MMDvIw==} dependencies: prosemirror-keymap: 1.2.2 - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-state: 1.4.3 prosemirror-transform: 1.7.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 dev: false - /prosemirror-trailing-node@2.0.4(prosemirror-model@1.19.2)(prosemirror-state@1.4.3)(prosemirror-view@1.31.5): + /prosemirror-trailing-node@2.0.4(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7): resolution: {integrity: sha512-0Yl9w7IdHkaCdqR+NE3FOucePME4OmiGcybnF1iasarEILP5U8+4xTnl53yafULjmwcg1SrSG65Hg7Zk2H2v3g==} peerDependencies: prosemirror-model: ^1.19.0 @@ -12247,9 +12247,9 @@ packages: '@remirror/core-constants': 2.0.1 '@remirror/core-helpers': 2.0.3 escape-string-regexp: 4.0.0 - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-state: 1.4.3 - prosemirror-view: 1.31.5 + prosemirror-view: 1.32.7 transitivePeerDependencies: - supports-color dev: false @@ -12257,13 +12257,13 @@ packages: /prosemirror-transform@1.7.3: resolution: {integrity: sha512-qDapyx5lqYfxVeUWEw0xTGgeP2S8346QtE7DxkalsXlX89lpzkY6GZfulgfHyk1n4tf74sZ7CcXgcaCcGjsUtA==} dependencies: - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 dev: false - /prosemirror-view@1.31.5: - resolution: {integrity: sha512-tobRCDeCp61elR1d97XE/JTL9FDIfswZpWeNs7GKJjAJvWyMGHWYFCq29850p6bbG2bckP+i9n1vT56RifosbA==} + /prosemirror-view@1.32.7: + resolution: {integrity: sha512-pvxiOoD4shW41X5bYDjRQk3DSG4fMqxh36yPMt7VYgU3dWRmqFzWJM/R6zeo1KtC8nyk717ZbQND3CC9VNeptw==} dependencies: - prosemirror-model: 1.19.2 + prosemirror-model: 1.19.4 prosemirror-state: 1.4.3 prosemirror-transform: 1.7.3 dev: false