code-editor.ts

142 lines | 5.849 kB Blame History Raw Download
import { BaseElement } from "../../../shared/_base";
import './code-editor.less';
import * as monaco from 'monaco-editor';
import { OutputFrame } from "../output-frame/output-frame";
import initScript from './injects/editor-init.txt';

export class CodeEditor extends BaseElement {

    public input: string = initScript;

    onInit(): void {


        this.initWorkers();

        const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");

        var editor = monaco.editor.create(this, {
            value: this.input,
            language: 'javascript',
            automaticLayout: true,
            contextmenu: false,
            minimap: {
                enabled: false
            },
            autoIndent: "full",
            theme: prefersDarkScheme.matches ? 'vs-dark' : 'vs-white'
        });

        monaco.languages.registerCompletionItemProvider("javascript", {
            triggerCharacters: ["."],
            provideCompletionItems: (model, position, context, token) => (
                {
                    suggestions: [
                        {
                            label: 'for',
                            kind: monaco.languages.CompletionItemKind.Snippet,
                            insertText: 'for (let i = 0; i < ${1:array}.length; i++) {\n\t$0\n}',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
                        },
                        {
                            label: 'forr',
                            kind: monaco.languages.CompletionItemKind.Snippet,
                            insertText: 'for (var i = ${1:array}.length - 1; i >= 0; i--) {\n\t$0\n}',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
                        },
                        {
                            label: 'rect',
                            detail: "details",
                            kind: monaco.languages.CompletionItemKind.Function,
                            insertText: 'rect(${1:x}, ${2:y}, ${3:width}, ${4:height})',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
                        },
                        {
                            label: 'box',
                            detail: "details",
                            kind: monaco.languages.CompletionItemKind.Function,
                            insertText: 'box(${1:x}, ${2:y}, ${3:width}, ${4:height})',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
                        },
                        {
                            label: 'width',
                            detail: "gets the width of the canvas",
                            kind: monaco.languages.CompletionItemKind.Function,
                            insertText: 'width()',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.KeepWhitespace
                        },
                        {
                            label: 'height',
                            detail: "gets the height of the canvas",
                            kind: monaco.languages.CompletionItemKind.Function,
                            insertText: 'height()',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.KeepWhitespace
                        },
                        {
                            label: 'center',
                            detail: "gets the center of the canvas",
                            kind: monaco.languages.CompletionItemKind.Function,
                            insertText: 'center()',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.KeepWhitespace
                        },
                        {
                            label: 'rand',
                            detail: "gets a random number between two numbers",
                            kind: monaco.languages.CompletionItemKind.Function,
                            insertText: 'rand(${1:from}, ${1:to})',
                            range: <any>null,
                            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
                        }
                    ]
                }
            )
        });


        editor.onDidChangeModelContent((e) => {
            this.input = editor.getValue();
            this.outputFrame.setScript(this.input);
        });

        this.waitFor(this.outputFrame, () => {
            this.outputFrame.setScript(this.input);
        });

    }

    initWorkers() {
        // @ts-ignore
        self.MonacoEnvironment = {
            getWorkerUrl: function (moduleId: any, label: string) {
                if (label === 'json') {
                    return './json.worker.bundle.js';
                }
                if (label === 'css' || label === 'scss' || label === 'less') {
                    return './css.worker.bundle.js';
                }
                if (label === 'html' || label === 'handlebars' || label === 'razor') {
                    return './html.worker.bundle.js';
                }
                if (label === 'typescript' || label === 'javascript') {
                    return './ts.worker.bundle.js';
                }
                return './editor.worker.bundle.js';
            }
        };
    }

    onUpdate(): void {
        console.log("APP ROOT UPDATE");
    }

    get outputFrame(): OutputFrame {
        return <OutputFrame>this.findSibling("output-frame");
    }
}