You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sandkasten-web/src/app/components/editor/editor.component.ts

106 lines
3.4 KiB

import { Component, ViewChild } from '@angular/core';
import { CodeExecutionService } from 'src/app/services/codeExecution.service';
import { basicSetup } from 'codemirror';
import { Compartment, Extension } from '@codemirror/state';
import { CodeMirrorComponent } from '@sandkasten/codemirror6-editor';
import { LanguageDescription } from '@codemirror/language';
import { CODE_DEFAULTS, LANGUAGES } from '../languages';
import { SafeHTMLPipe } from '../../safe-html.pipe';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
@Component({
selector: "app-editor",
templateUrl: "./editor.component.html",
styleUrls: ["./editor.component.scss"],
standalone: true,
imports: [
CodeMirrorComponent,
ReactiveFormsModule,
FormsModule,
SafeHTMLPipe,
],
})
export class EditorComponent {
isLoaded: boolean = false; // Pour vérifier si le chargement est terminé
readonly languages: LanguageDescription[] = LANGUAGES;
// Mode par défaut
private _selectedLanguage = this.languages.find((lang) => lang.name === "JavaScript")!;
get selectedLanguage(): LanguageDescription {
return this._selectedLanguage;
}
set selectedLanguage(value: LanguageDescription) {
this._selectedLanguage = value;
if (value.name in CODE_DEFAULTS) {
this.editorContent = CODE_DEFAULTS[value.name as keyof typeof CODE_DEFAULTS];
}
this.selectedLanguage.load().then((language) => {
this.codemirror.editor?.dispatch({
effects: this.languageCompartment.reconfigure(language)
});
});
}
// Contenu de l'éditeur que l'on passera au serveur
editorContent: string = CODE_DEFAULTS[this.selectedLanguage.name as keyof typeof CODE_DEFAULTS];
resultContent: string = "";
// Message d'erreur
errorMessage: string = "";
@ViewChild(CodeMirrorComponent) private codemirror!: CodeMirrorComponent;
private readonly languageCompartment = new Compartment();
protected readonly extensions: Extension[] = [
basicSetup,
this.languageCompartment.of(this.selectedLanguage.support!)
];
constructor(
private codeExecutionService: CodeExecutionService
) {
}
// Efface le contenu de l'éditeur
clear(): void {
this.editorContent = "";
}
onRunButtonClicked() {
// Le code à exécuter est le contenu de l'éditeur
const codeToExecute = this.editorContent;
this.codeExecutionService.executeCode(codeToExecute, this.selectedLanguage.name);
this.resultContent = '';
}
loadFromFile(event: Event) {
const file = (event.target as HTMLInputElement).files![0];
for (const language of this.languages) {
if (language.extensions.some(ext => file.name.endsWith(`.${ext}`))) {
this.selectedLanguage = language;
const reader = new FileReader();
reader.onload = (event) => {
this.editorContent = event.target!.result as string;
this.errorMessage = '';
};
reader.readAsText(file);
return;
}
}
const extensions = this.languages.flatMap(lang => lang.extensions);
this.errorMessage =
`Unsupported language. Please select one of the following languages: ${extensions.join(', ')}.`;
console.error(this.errorMessage);
}
saveToFile() {
const blob = new Blob([this.editorContent], { type: 'text/plain' });
const a = document.createElement('a');
a.download = `code.${this.selectedLanguage.extensions![0]}`;
a.href = URL.createObjectURL(blob);
a.click();
}
}