1 import {EditorDecorator} from "../framework/decorator";
2 import {EditorUiContext} from "../framework/core";
3 import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block";
4 import {selectionContainsNode, selectSingleNode} from "../../helpers";
5 import {context} from "esbuild";
6 import {BaseSelection} from "lexical";
9 export class CodeBlockDecorator extends EditorDecorator {
11 protected completedSetup: boolean = false;
12 protected latestCode: string = '';
13 protected latestLanguage: string = '';
16 protected editor: any = null;
18 setup(context: EditorUiContext, element: HTMLElement) {
19 const codeNode = this.getNode() as CodeBlockNode;
20 const preEl = element.querySelector('pre');
29 this.latestCode = codeNode.__code;
30 this.latestLanguage = codeNode.__language;
31 const lines = this.latestCode.split('\n').length;
32 const height = (lines * 19.2) + 18 + 24;
33 element.style.height = `${height}px`;
35 const startTime = Date.now();
37 element.addEventListener('click', event => {
38 context.editor.update(() => {
39 selectSingleNode(this.getNode());
43 element.addEventListener('dblclick', event => {
44 context.editor.getEditorState().read(() => {
45 $openCodeEditorForNode(context.editor, (this.getNode() as CodeBlockNode));
49 const selectionChange = (selection: BaseSelection|null): void => {
50 element.classList.toggle('selected', selectionContainsNode(selection, codeNode));
52 context.manager.onSelectionChange(selectionChange);
53 this.onDestroy(() => {
54 context.manager.offSelectionChange(selectionChange);
58 const renderEditor = (Code) => {
59 this.editor = Code.wysiwygView(element, document, this.latestCode, this.latestLanguage);
61 element.style.height = '';
66 window.importVersioned('code').then((Code) => {
67 const timeout = (Date.now() - startTime < 20) ? 20 : 0;
68 setTimeout(() => renderEditor(Code), timeout);
71 this.completedSetup = true;
75 const codeNode = this.getNode() as CodeBlockNode;
76 const code = codeNode.getCode();
77 const language = codeNode.getLanguage();
79 if (this.latestCode === code && this.latestLanguage === language) {
82 this.latestLanguage = language;
83 this.latestCode = code;
86 this.editor.setContent(code);
87 this.editor.setMode(language, code);
91 render(context: EditorUiContext, element: HTMLElement): void {
92 if (this.completedSetup) {
95 this.setup(context, element);