1 import {EditorDecorator} from "../framework/decorator";
2 import {EditorUiContext} from "../framework/core";
3 import {$openCodeEditorForNode, CodeBlockNode} from "../../nodes/code-block";
4 import {$isDecoratorNode, 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 requestAnimationFrame(() => {
38 context.editor.update(() => {
39 $selectSingleNode(this.getNode());
44 element.addEventListener('dblclick', event => {
45 context.editor.getEditorState().read(() => {
46 $openCodeEditorForNode(context.editor, (this.getNode() as CodeBlockNode));
50 const selectionChange = (selection: BaseSelection|null): void => {
51 element.classList.toggle('selected', $selectionContainsNode(selection, codeNode));
53 context.manager.onSelectionChange(selectionChange);
54 this.onDestroy(() => {
55 context.manager.offSelectionChange(selectionChange);
59 const renderEditor = (Code) => {
60 this.editor = Code.wysiwygView(element, document, this.latestCode, this.latestLanguage);
62 element.style.height = '';
67 window.importVersioned('code').then((Code) => {
68 const timeout = (Date.now() - startTime < 20) ? 20 : 0;
69 setTimeout(() => renderEditor(Code), timeout);
72 this.completedSetup = true;
76 const codeNode = this.getNode() as CodeBlockNode;
77 const code = codeNode.getCode();
78 const language = codeNode.getLanguage();
80 if (this.latestCode === code && this.latestLanguage === language) {
83 this.latestLanguage = language;
84 this.latestCode = code;
87 this.editor.setContent(code);
88 this.editor.setMode(language, code);
92 render(context: EditorUiContext, element: HTMLElement): void {
93 if (this.completedSetup) {
96 this.setup(context, element);