@lobehub/editor
Version:
A powerful and extensible rich text editor built on Meta's Lexical framework, providing a modern editing experience with React integration.
49 lines • 1.86 kB
JavaScript
import { $isCodeNode } from '@lexical/code';
import { $findMatchingParent } from '@lexical/utils';
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
import { ShikiTokenizer } from "../plugin/CodeHighlighterShiki";
export var CustomShikiTokenizer = {
$tokenize: ShikiTokenizer.$tokenize,
$tokenizeSerialized: ShikiTokenizer.$tokenizeSerialized,
defaultLanguage: ShikiTokenizer.defaultLanguage,
defaultTheme: ShikiTokenizer.defaultTheme
};
export var UPDATE_CODEBLOCK_LANG = createCommand('UPDATE_CODEBLOCK_LANG');
export function registerCodeCommand(editor) {
var unregisterLangCommand = editor.registerCommand(UPDATE_CODEBLOCK_LANG, function (payload) {
CustomShikiTokenizer.defaultLanguage = payload.lang;
var codeNode = editor.getEditorState().read(function () {
var selection = $getSelection();
if ($isRangeSelection(selection)) {
if (selection.isCollapsed()) {
var node = $findMatchingParent(selection.anchor.getNode(), $isCodeNode);
return node;
} else {
var anchor = $findMatchingParent(selection.anchor.getNode(), $isCodeNode);
var focus = $findMatchingParent(selection.focus.getNode(), $isCodeNode);
if (anchor && focus && anchor === focus) {
return anchor;
}
return null;
}
}
return false;
});
if (!codeNode) {
return false;
}
// Need to defer execution due to possible transform execution order confusion from selection changes
queueMicrotask(function () {
editor.update(function () {
if ($isCodeNode(codeNode)) {
codeNode.setLanguage(payload.lang);
}
});
});
return true;
}, COMMAND_PRIORITY_EDITOR // Priority
);
return function () {
unregisterLangCommand();
};
}