109 lines
3.8 KiB
TypeScript
109 lines
3.8 KiB
TypeScript
import { BaseElement } from "../../../shared/_base";
|
|
import './code-editor.less';
|
|
import * as monaco from 'monaco-editor';
|
|
import { OutputFrame } from "../output-frame/output-frame";
|
|
import { debounceManager } from "../../../shared/ensure-debounce";
|
|
import * as sessionApi from '../../../shared/session-api';
|
|
import { isSessionPage } from "../../../shared/page";
|
|
import { sanityConvert } from "../../../shared/sanity-code-check";
|
|
|
|
export class CodeEditor extends BaseElement {
|
|
|
|
public input: string = "";
|
|
public language: string = "";
|
|
public editor!: monaco.editor.IStandaloneCodeEditor;
|
|
public lastInputCache: any;
|
|
|
|
onInit(): void {
|
|
|
|
this.initWorkers();
|
|
this.language = this.tagName.substring(0, this.tagName.indexOf("-")).toLocaleLowerCase();
|
|
this.lastInputCache = localStorage.getItem(this.language + "LastInputCache");
|
|
this.input = this.setInitInput();
|
|
|
|
this.setInitSettings();
|
|
|
|
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
|
|
|
|
this.editor = monaco.editor.create(this, {
|
|
value: isSessionPage() ? "" : this.input,
|
|
language: this.language,
|
|
automaticLayout: true,
|
|
contextmenu: false,
|
|
readOnly: isSessionPage(),
|
|
minimap: {
|
|
enabled: false
|
|
},
|
|
autoIndent: "full",
|
|
theme: prefersDarkScheme.matches ? 'vs-dark' : 'vs-light'
|
|
});
|
|
|
|
var debounce = debounceManager(1000);
|
|
this.editor.onDidChangeModelContent((e) => {
|
|
if (!isSessionPage()) {
|
|
this.input = this.editor.getValue();
|
|
this.lastInputCache = this.input;
|
|
localStorage.setItem(this.language + "LastInputCache", this.input);
|
|
debounce.ensureDebounce(() => {
|
|
sessionApi.setSessionData(this.language, this.input);
|
|
this.outputFrame.setContent(this.language, this.language.toLowerCase() === "javascript" ? sanityConvert(this.input) : this.input);
|
|
});
|
|
}
|
|
});
|
|
|
|
this.waitFor(this.outputFrame, () => {
|
|
this.outputFrame.setContent(this.language, isSessionPage() ? "" : (this.language.toLowerCase() === "javascript" ? sanityConvert(this.input) : this.input));
|
|
});
|
|
|
|
}
|
|
|
|
setInput(input: any) {
|
|
if (this.input !== input) {
|
|
this.input = input;
|
|
this.lastInputCache = this.input;
|
|
localStorage.setItem(this.language + "LastInputCache", this.input);
|
|
this.editor.setValue(input);
|
|
this.outputFrame.setContent(this.language, this.language.toLowerCase() === "javascript" ? sanityConvert(this.input) : this.input);
|
|
}
|
|
}
|
|
|
|
setInitInput(): string {
|
|
if (!isSessionPage() && sessionApi.hasSession()) {
|
|
return this.lastInputCache;
|
|
}
|
|
else {
|
|
return "";
|
|
}
|
|
|
|
}
|
|
|
|
setInitSettings(): void {
|
|
|
|
}
|
|
|
|
|
|
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';
|
|
}
|
|
};
|
|
}
|
|
|
|
get outputFrame(): OutputFrame {
|
|
return <OutputFrame>this.find("output-frame");
|
|
}
|
|
} |