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';
import spiralBoxesSolutionScript from './injects/spiral-boxes-solution.txt';
import { debounceManager } from "../../../shared/ensure-debounce";
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}, ${2:to})',
range: <any>null,
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
},
{
label: 'spiralBoxesSolutionSnippet',
detail: "inserts solution of spiral boxes",
kind: monaco.languages.CompletionItemKind.Function,
insertText: spiralBoxesSolutionScript,
range: <any>null,
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
}
]
}
)
});
var debounce = debounceManager(1000);
editor.onDidChangeModelContent((e) => {
this.input = editor.getValue();
debounce.ensureDebounce(() => {
this.outputFrame.setScript(this.input);
});
});
this.waitFor(this.outputFrame, () => {
console.log("setting script");
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");
}
}