1 import {EditorDecorator} from "../framework/decorator";
2 import {EditorUiContext} from "../framework/core";
3 import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block";
4 import {BaseSelection} from "lexical";
5 import {$selectionContainsNode, $selectSingleNode} from "../../utils/selection";
8 export class CodeBlockDecorator extends EditorDecorator {
10 protected completedSetup: boolean = false;
11 protected latestCode: string = '';
12 protected latestLanguage: string = '';
15 protected editor: any = null;
17 setup(context: EditorUiContext, element: HTMLElement) {
18 const codeNode = this.getNode() as CodeBlockNode;
19 const preEl = element.querySelector('pre');
28 this.latestCode = codeNode.__code;
29 this.latestLanguage = codeNode.__language;
30 const lines = this.latestCode.split('\n').length;
31 const height = (lines * 19.2) + 18 + 24;
32 element.style.height = `${height}px`;
34 const startTime = Date.now();
36 element.addEventListener('click', event => {
37 context.editor.update(() => {
38 $selectSingleNode(this.getNode());
42 element.addEventListener('dblclick', event => {
43 context.editor.getEditorState().read(() => {
44 $openCodeEditorForNode(context.editor, (this.getNode() as CodeBlockNode));
48 const selectionChange = (selection: BaseSelection|null): void => {
49 element.classList.toggle('selected', $selectionContainsNode(selection, codeNode));
51 context.manager.onSelectionChange(selectionChange);
52 this.onDestroy(() => {
53 context.manager.offSelectionChange(selectionChange);
57 const renderEditor = (Code) => {
58 this.editor = Code.wysiwygView(element, document, this.latestCode, this.latestLanguage);
60 element.style.height = '';
65 window.importVersioned('code').then((Code) => {
66 const timeout = (Date.now() - startTime < 20) ? 20 : 0;
67 setTimeout(() => renderEditor(Code), timeout);
70 this.completedSetup = true;
74 const codeNode = this.getNode() as CodeBlockNode;
75 const code = codeNode.getCode();
76 const language = codeNode.getLanguage();
78 if (this.latestCode === code && this.latestLanguage === language) {
81 this.latestLanguage = language;
82 this.latestCode = code;
85 this.editor.setContent(code);
86 this.editor.setMode(language, code);
90 render(context: EditorUiContext, element: HTMLElement): void {
91 if (this.completedSetup) {
94 this.setup(context, element);