@rtdui/editor
Version:
React rich text editor based on tiptap
77 lines (74 loc) • 2.27 kB
JavaScript
'use client';
import { bundledThemes, bundledLanguages, createHighlighter } from 'shiki';
import { findChildren } from '@tiptap/core';
let highlighter;
let highlighterPromise;
const loadingLanguages = /* @__PURE__ */ new Set();
const loadingThemes = /* @__PURE__ */ new Set();
function getShiki() {
return highlighter;
}
function loadHighlighter(opts) {
if (!highlighter && !highlighterPromise) {
const themes = opts.themes.filter(
(theme) => !!theme && theme in bundledThemes
);
const langs = opts.languages.filter(
(lang) => !!lang && lang in bundledLanguages
);
highlighterPromise = createHighlighter({ themes, langs }).then((h) => {
highlighter = h;
});
return highlighterPromise;
}
if (highlighterPromise) {
return highlighterPromise;
}
}
async function loadTheme(theme) {
if (highlighter && !highlighter.getLoadedThemes().includes(theme) && !loadingThemes.has(theme) && theme in bundledThemes) {
loadingThemes.add(theme);
await highlighter.loadTheme(theme);
loadingThemes.delete(theme);
return true;
}
return false;
}
async function loadLanguage(language) {
if (highlighter && !highlighter.getLoadedLanguages().includes(language) && !loadingLanguages.has(language) && language in bundledLanguages) {
loadingLanguages.add(language);
await highlighter.loadLanguage(language);
loadingLanguages.delete(language);
return true;
}
return false;
}
async function initHighlighter({
doc,
name,
defaultTheme,
defaultLanguage
}) {
const codeBlocks = findChildren(doc, (node) => node.type.name === name);
const themes = [
...codeBlocks.map((block) => block.node.attrs.theme),
defaultTheme,
"one-light",
"one-dark-pro"
];
const languages = [
...codeBlocks.map((block) => block.node.attrs.language),
defaultLanguage
];
if (!highlighter) {
const loader = loadHighlighter({ languages, themes });
await loader;
} else {
await Promise.all([
...themes.flatMap((theme) => loadTheme(theme)),
...languages.flatMap((language) => !!language && loadLanguage(language))
]);
}
}
export { getShiki, initHighlighter, loadHighlighter, loadLanguage, loadTheme };
//# sourceMappingURL=shiki-highlighter.mjs.map