diff --git a/package-lock.json b/package-lock.json
index b7b5a1a..49a7f13 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,6 +21,7 @@
"@emailjs/browser": "^3.12.1",
"@ngx-translate/core": "^15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
+ "ansi-to-html": "^0.7.2",
"codemirror": "^5.65.16",
"rxjs": "~7.8.1",
"sse.js": "^2.2.0",
@@ -4070,6 +4071,28 @@
"node": ">=4"
}
},
+ "node_modules/ansi-to-html": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.7.2.tgz",
+ "integrity": "sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g==",
+ "dependencies": {
+ "entities": "^2.2.0"
+ },
+ "bin": {
+ "ansi-to-html": "bin/ansi-to-html"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ansi-to-html/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
diff --git a/package.json b/package.json
index 961b408..e51187b 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"@emailjs/browser": "^3.12.1",
"@ngx-translate/core": "^15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
+ "ansi-to-html": "^0.7.2",
"codemirror": "^5.65.16",
"rxjs": "~7.8.1",
"sse.js": "^2.2.0",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index c39c84a..2ed0287 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -24,6 +24,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { TranslationService } from './services/translation.service';
+import { SafeHTMLPipe } from './safe-html.pipe';
@NgModule({
declarations: [
@@ -37,8 +38,8 @@ import { TranslationService } from './services/translation.service';
FormComponent,
PrivacyPolicyComponent,
TermsOfServiceComponent,
- OurStoryComponent
-
+ OurStoryComponent,
+ SafeHTMLPipe
],
imports: [
BrowserModule,
diff --git a/src/app/components/editor/editor.component.html b/src/app/components/editor/editor.component.html
index d02a36c..3945bba 100644
--- a/src/app/components/editor/editor.component.html
+++ b/src/app/components/editor/editor.component.html
@@ -14,20 +14,7 @@
-
-
-
-
+
diff --git a/src/app/components/editor/editor.component.ts b/src/app/components/editor/editor.component.ts
index 07f941c..593b443 100644
--- a/src/app/components/editor/editor.component.ts
+++ b/src/app/components/editor/editor.component.ts
@@ -3,6 +3,8 @@ import { Router } from "@angular/router";
import { CodeExecutionService } from "src/app/services/codeExecution.service";
import "codemirror/mode/shell/shell.js";
import "codemirror/mode/clike/clike.js";
+import Convert from 'ansi-to-html';
+
// Exemple de code pour chaque langage autorisé
const codeDefaults = {
@@ -68,6 +70,13 @@ export class EditorComponent implements OnInit {
ngOnInit(): void {
// Appel à changeMode pour mettre à jour le contenu de l'éditeur et le mode
this.changeMode();
+ const convert = new Convert();
+
+ this.codeExecutionService.getResult().subscribe((result) => {
+ if (result.type !== 'exit') {
+ this.resultContent += convert.toHtml(result.text);
+ }
+ });
}
// Change le langage de l'éditeur
@@ -160,8 +169,6 @@ export class EditorComponent implements OnInit {
this.codeExecutionService.executeCode(codeToExecute, this.mode);
- this.codeExecutionService.getResult().subscribe((result) => {
- this.resultContent = result;
- });
+ this.resultContent = '';
}
}
diff --git a/src/app/safe-html.pipe.spec.ts b/src/app/safe-html.pipe.spec.ts
new file mode 100644
index 0000000..400afdd
--- /dev/null
+++ b/src/app/safe-html.pipe.spec.ts
@@ -0,0 +1,8 @@
+import { SafeHTMLPipe } from './safe-html.pipe';
+
+describe('SafeHTMLPipe', () => {
+ it('create an instance', () => {
+ const pipe = new SafeHTMLPipe();
+ expect(pipe).toBeTruthy();
+ });
+});
diff --git a/src/app/safe-html.pipe.ts b/src/app/safe-html.pipe.ts
new file mode 100644
index 0000000..963ebbd
--- /dev/null
+++ b/src/app/safe-html.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from '@angular/core';
+import { DomSanitizer } from '@angular/platform-browser';
+
+@Pipe({
+ name: 'safeHTML',
+})
+export class SafeHTMLPipe implements PipeTransform {
+
+ constructor(protected sanitizer: DomSanitizer) {}
+
+ transform(value: unknown, ...args: unknown[]): unknown {
+ return this.sanitizer.bypassSecurityTrustHtml(value as string);
+ }
+
+}
diff --git a/src/app/services/codeExecution.service.ts b/src/app/services/codeExecution.service.ts
index f7f1b97..4ec25ad 100644
--- a/src/app/services/codeExecution.service.ts
+++ b/src/app/services/codeExecution.service.ts
@@ -1,16 +1,20 @@
import { Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http';
import { SSE } from 'sse.js';
import { Observable, Subject } from 'rxjs';
+export type ExecutionMessage = {
+ type: 'stdout' | 'stderr' | 'exit',
+ text: string
+};
+
@Injectable({
providedIn: 'root',
})
export class CodeExecutionService {
private apiUrl = 'http://localhost:3000/run';
- private resultSubject = new Subject();
+ private resultSubject = new Subject();
- constructor(private http: HttpClient) {}
+ constructor() {}
executeCode(code: string, language: string) {
const sse = new SSE(this.apiUrl, {
@@ -21,17 +25,21 @@ export class CodeExecutionService {
},
payload: JSON.stringify({ code, language }),
});
-
+
sse.addEventListener('message', (event: MessageEvent) => {
const result = event.data;
- // Émettre le résultat à tous les abonnés
+ // @ts-ignore
+ const type = event.id;
const text = decodeURIComponent(result.replace(/%00/g, ''));
- this.resultSubject.next(text);
+ if (type === 'end') {
+ sse.close();
+ }
+ this.resultSubject.next({ type, text });
});
}
- getResult(): Observable {
+ getResult(): Observable {
return this.resultSubject.asObservable();
}
}
diff --git a/tsconfig.json b/tsconfig.json
index ed966d4..64a863e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -19,6 +19,7 @@
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
+ "allowSyntheticDefaultImports": true,
"lib": [
"ES2022",
"dom"