diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts b/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts index 26bc47f5ac42f9e9f2638ffc14a692629af19143..8149c332baa0e1ff11ba97267684f550fcf56b25 100755 --- a/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts +++ b/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts @@ -281,26 +281,29 @@ export class MateFunComponent { var y = cm.getCursor().ch; x = (Number(x) + 1).toString(); y = (Number(y) + 1).toString(); - var cursorPositionTranslate = this.translateService.get( - "i18n.msg.codemirror.cursorPosition" - ).value; - this.cursorPanelLabel.textContent = - cursorPositionTranslate + ": (" + x + "," + y + ")"; this.cursorPanel = this.codemirror.first.instance.addPanel(node, { position: "bottom", stable: true, }); - var that = this; - //agregamos el evento que setea la posición - this.codemirror.first.instance.on("cursorActivity", function (cm) { - var x = cm.getCursor().line; - var y = cm.getCursor().ch; - x = (Number(x) + 1).toString(); - y = (Number(y) + 1).toString(); - that.cursorPanel.node.innerText = - cursorPositionTranslate + ": (" + x + "," + y + ")"; - }); + + const that = this; + this.translateService + .get("i18n.msg.codemirror.cursorPosition") + .subscribe((res) => { + // Se configura la posición inicial del cursor + this.cursorPanelLabel.textContent = res + ": (" + x + "," + y + ")"; + + // Agregamos el evento que setea la posición + this.codemirror.first.instance.on("cursorActivity", (codeMirror) => { + let x = codeMirror.getCursor().line; + let y = codeMirror.getCursor().ch; + + x = (Number(x) + 1).toString(); + y = (Number(y) + 1).toString(); + that.cursorPanel.node.innerText = res + ": (" + x + "," + y + ")"; + }); + }); this.codemirror.first.instance.on("keyHandled", function (cm, name, evt) { if (name.code === "Digit1" && name.ctrlKey && name.shiftKey) { diff --git a/Frontend Angular 4/src/app/shared/services/ghci.service.ts b/Frontend Angular 4/src/app/shared/services/ghci.service.ts index 2e07626375a29fe5312801d6918f18b9c7f726eb..21a7aa298517f7c333c18245b6ce778fe7065402 100755 --- a/Frontend Angular 4/src/app/shared/services/ghci.service.ts +++ b/Frontend Angular 4/src/app/shared/services/ghci.service.ts @@ -23,12 +23,19 @@ export class GHCIService { private warnings: any = []; private codemirrorRef: any = null; private warningStepReaded: number = 0; + + /** + * Ante la aparición de un mensaje de error (OUTError), se espera por el + * próximo mensaje que deberá ser la descripción del error. Este mensaje + * comenzará con "OUT" + */ private waitingForError: boolean = false; + private waitingForWarning: boolean = false; private waitingForWarning2: boolean = false; private warningText: string = ""; private errorText: string = ""; - private lastError: number = -1; + private lastErrorLineNumber: number = -1; private lastErrorFile: string = ""; private lastWarning: number = -1; private lastWarningFile: string = ""; @@ -152,38 +159,47 @@ export class GHCIService { setTimeout(this.checkConsole.bind(this), 100); } } - hayError(text) { - var line = -1; + + hayError(text: string) { + // Si se está esperando por la descripción del error if (this.waitingForError) { - var line = this.lastError; + // WA para manejar el tema de las traducciones asincronicas. Dado que no, + // hay una buena forma de manejar las traducciones asincronicas con los + // returns asincronicos, se opta por "hardcodear" las traducciones según + // el idioma. Este mecanismo funcionaba previamente, pero desde Angular 5 + // las traducciones pasaron a ser asincronicas, cosa que no habÃa sido + // pensado para la arquitectura actual. + const language = this.authService.getLanguage(); + const traduccionColumna = language == "es" ? "columna" : "column"; + const traduccionEnColumna = language == "es" ? "En columna" : "In column"; + var columna = this.errorText - .split( - `${ - this.translateService.get("i18n.codemirror.command.column").value - }:` - )[1] + .split(`${traduccionColumna}:`)[1] .split("}")[0]; - var ErrorTextToShow = JSON.parse(text).resultado.split("OUT")[1].trim(); - var ErrorFinalText = - `${ - this.translateService.get("i18n.codemirror.command.inColumn").value - }` + - columna + - ": " + - ErrorTextToShow; + var errorTextToShow = JSON.parse(text).resultado.split("OUT")[1].trim(); + + var errorFinalText = + traduccionEnColumna + columna + ": " + errorTextToShow; if ( - this.currentFile.toLowerCase() == this.lastErrorFile.toLowerCase() && + this.currentFile.split(" ").join("").toLowerCase() == + this.lastErrorFile.toLowerCase() && this.codemirrorRef !== null ) { - var makeMarker = function () { + /** + * Crea un gutter para mostrar el mensaje de error + * @returns Gutter para mostrar el mensaje de error + */ + const makeMarker = () => { var marker = document.createElement("div"); - marker.id = "error_" + line.toString(); + + marker.id = "error_" + this.lastErrorLineNumber.toString(); marker.style.width = "15px"; - marker.title = ErrorFinalText; + marker.title = errorFinalText; marker.style.height = "15px"; - marker.style.marginLeft = "-5px"; + marker.style.marginLeft = "-15px"; + marker.style.marginTop = "1px"; marker.style.cursor = "pointer"; marker.style["background-image"] = "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=')"; @@ -191,52 +207,56 @@ export class GHCIService { "<a href='@' title='cuidado , advertencia matefun'></a>"; return marker; }; - this.codemirrorRef.setGutterMarker(line, "breakpoints", makeMarker()); + + this.codemirrorRef.setGutterMarker( + this.lastErrorLineNumber, + "breakpoints", + makeMarker() + ); this.waitingForError = false; - this.lastError = -1; + this.lastErrorLineNumber = -1; } } else { try { - var m = JSON.parse(text); - var file = m.resultado - .split( - `${ - this.translateService.get("i18n.codemirror.command.outError") - .value - }:` - )[1] - .trim() - .split(`${this.translateService.get("i18n.object.file").value}:`)[1] - .split(" ")[1]; + const message: { tipo: string; resultado: string } = JSON.parse(text); - var line = - m.resultado - .split( - `${ - this.translateService.get("i18n.codemirror.command.outError") - .value - }:` - )[1] - .trim() - .split( - `${ - this.translateService.get("i18n.codemirror.command.line").value - }:` - )[1] - .split(" ")[1] - 1; + // Se filtran los tipos de mensajes + if ( + message.tipo == "ack" || + !message.resultado.startsWith("OUTError") + ) { + return; + } + // Se espera ahora la descripción del error this.waitingForError = true; - this.lastError = line; - this.lastErrorFile = file; - this.errorText = m.resultado - .split( - `${ - this.translateService.get("i18n.codemirror.command.outError") - .value - }:` - )[1] - .trim(); + + // Se obtiene la traducción de file + this.translateService.get("i18n.object.file").subscribe((res) => { + const fileNameSeparator = "OUTError: {" + res + ": "; + + const fileNameAndMore = message.resultado.replace( + fileNameSeparator, + "" + ); + + const fileName = fileNameAndMore.split(" ")[0]; + + // Se obtiene la traducción de line + this.translateService + .get("i18n.codemirror.command.line") + .subscribe((line) => { + const lineNumber = + Number(fileNameAndMore.split(` ${line}: `)[1].split(" ")[0]) - + 1; + + this.lastErrorLineNumber = lineNumber; + this.lastErrorFile = fileName; + this.errorText = fileNameAndMore.trim(); + }); + }); } catch (err) {} + return false; } } @@ -251,6 +271,16 @@ export class GHCIService { var line = -1; var m = JSON.parse(text); + // WA para manejar el tema de las traducciones asincronicas. Dado que no, + // hay una buena forma de manejar las traducciones asincronicas con los + // returns asincronicos, se opta por "hardcodear" las traducciones según + // el idioma. Este mecanismo funcionaba previamente, pero desde Angular 5 + // las traducciones pasaron a ser asincronicas, cosa que no habÃa sido + // pensado para la arquitectura actual. + const language = this.authService.getLanguage(); + const traduccionColumna = language == "es" ? "columna" : "column"; + const traduccionEnColumna = language == "es" ? "En columna" : "In column"; + if (this.warningStepReaded === 1) { try { var warningText2 = m.resultado.split("OUT")[1].trim(); @@ -260,22 +290,11 @@ export class GHCIService { var line = this.lastWarning; var title = this.warningText; - var columna = title - .split( - `${ - this.translateService.get("i18n.codemirror.command.column").value - }:` - )[1] - .split("}")[0]; + var columna = title.split(`${traduccionColumna}:`)[1].split("}")[0]; var warningTextToShow = title.split("}")[1]; var warningFinalText = - `${ - this.translateService.get("i18n.codemirror.command.inColumn").value - }` + - columna + - ": " + - warningTextToShow; + traduccionEnColumna + columna + ": " + warningTextToShow; if ( this.currentFile.toLowerCase() == @@ -286,7 +305,8 @@ export class GHCIService { var marker = document.createElement("div"); marker.style.width = "15px"; marker.style.height = "15px"; - marker.style.marginLeft = "-5px"; + marker.style.marginLeft = "-15px"; + marker.style.marginTop = "1px"; marker.style.cursor = "pointer"; marker.innerHTML = "<a href='@' title='cuidado , advertencia matefun'></a>"; @@ -364,7 +384,7 @@ export class GHCIService { if (this.clear) { this.clearConsole(); } - var server_message = e.data; + const server_message = e.data; if (this.hayError(server_message)) { this.error = "Error";