Add color in result (#6)
continuous-integration/drone/push Build is passing Details

Co-authored-by: bastien ollier <bastien.ollier@etu.uca.fr>
Reviewed-on: #6
Reviewed-by: Clément FRÉVILLE <clement.freville2@etu.uca.fr>
Co-authored-by: Bastien OLLIER <bastien.ollier@noreply.codefirst.iut.uca.fr>
Co-committed-by: Bastien OLLIER <bastien.ollier@noreply.codefirst.iut.uca.fr>
pull/7/head
Bastien OLLIER 1 year ago committed by Clément FRÉVILLE
parent cf74413fc7
commit d41629abd0

23
package-lock.json generated

@ -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",

@ -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",

@ -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,

@ -14,20 +14,7 @@
</ngx-codemirror>
</div>
<div>
<ngx-codemirror
[options]="{
theme: 'material',
lineNumbers: false,
lineWrapping: false,
mode: mode,
autofocus: true,
readOnly: true
}"
[(ngModel)]="resultContent"
>
</ngx-codemirror>
</div>
<pre [innerHTML]="resultContent | safeHTML"></pre>
<div>
<label for="language">Langage de programmation</label>

@ -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 = '';
}
}

@ -0,0 +1,8 @@
import { SafeHTMLPipe } from './safe-html.pipe';
describe('SafeHTMLPipe', () => {
it('create an instance', () => {
const pipe = new SafeHTMLPipe();
expect(pipe).toBeTruthy();
});
});

@ -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);
}
}

@ -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<string>();
private resultSubject = new Subject<ExecutionMessage>();
constructor(private http: HttpClient) {}
constructor() {}
executeCode(code: string, language: string) {
const sse = new SSE(this.apiUrl, {
@ -25,13 +29,17 @@ export class CodeExecutionService {
sse.addEventListener('message', (event: MessageEvent<string>) => {
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<string> {
getResult(): Observable<ExecutionMessage> {
return this.resultSubject.asObservable();
}
}

@ -19,6 +19,7 @@
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"allowSyntheticDefaultImports": true,
"lib": [
"ES2022",
"dom"

Loading…
Cancel
Save