// Imports import { generateUUID, htmlOlCommandsOperations } from "./../../main"; import { getOperationTypeByValue, getOperatorByHash, getOperatorTypeByValue, htmlAssignVariableScheme, htmlOperationKindScheme, htmlOperationTypeSelect, htmlOperatorValueInputScheme, htmlOperatorVariablesSelectScheme, operationScheme, Operators, operatorScheme, printOperationScheme, } from "./operations-schemes"; import { getVariableByHash, variables } from "../variables/variables"; // Imports export const operations = []; // Creating operation export function createOperation() { let operation = Object.assign({}, operationScheme); operation.hash = generateUUID().replaceAll("-", ""); // TODO: Fix operation.assignedVariable = variables[0]; operation.operators = []; operations.push(operation); let htmlOperation = htmlAssignVariableScheme(); htmlOperation = htmlOperation.replaceAll("", operation.hash); htmlOlCommandsOperations.insertAdjacentHTML("beforeend", htmlOperation); document .getElementById(`operation${operation.hash}AssignVariableSelect`) .addEventListener("change", (ev) => { updateOperationAssignValue( ev.target.getAttribute("operation-id"), ev.target.value ); }); document .getElementById(`operation${operation.hash}Delete`) .addEventListener("click", (ev) => { deleteOperation(ev.target.getAttribute("operation-id")); }); document .getElementById(`operation${operation.hash}Resume`) .addEventListener("focus", (ev) => { const operationHash = ev.target.getAttribute("operation-id"); manageOperationEditing(operationHash); }); document .getElementById(`operation${operation.hash}Display`) .addEventListener("keyup", (ev) => { const operationHash = ev.target.getAttribute("operation-id"); if (ev.key === "Enter") manageOperationEditing(operationHash, true); }); addOperatorKind(operation.hash); updateResume(operation.hash); // Changing focus to the variable type after creation for screen readers document .getElementById(`operation${operation.hash}AssignVariableSelect`) .focus(); } // Add operator kind to the operation export function addOperatorKind(hash) { let operation = getOperationByHash(hash); console.log(operation); let htmlOperationKind = htmlOperationKindScheme(operation); document .getElementById(`operation${operation.hash}OperatorsDiv`) .insertAdjacentHTML("beforeend", htmlOperationKind); document .getElementById(`operation${operation.hash}KindSelect`) .addEventListener("focusout", (ev) => { selectedOperationKind(ev.target.getAttribute("operation-id")); ev.target.parentElement.remove(); }); } // Function to be trigger when the operator kind is selected export function selectedOperationKind(operationHash) { let operation = getOperationByHash(operationHash); console.log(operation); let kindSelect = document.getElementById( `operation${operation.hash}KindSelect` ); // TODO: think into an way to make this dynamic if (kindSelect.value === "VARIABLE") { insertVariableAfterOperationKind(kindSelect, operation); } else if (kindSelect.value === "VALUE") { insertValueAfterOperationKind(kindSelect, operation); } } // Insert variable after operator kind select export function insertVariableAfterOperationKind(kindSelect, operation) { let operator = Object.assign({}, operatorScheme); operator.hash = generateUUID().replaceAll("-", ""); // TODO: Fix ? operator.variable = variables[0]; operator.type = getOperatorTypeByValue("VARIABLE"); let operatorVariableSelect = htmlOperatorVariablesSelectScheme( operation, operator ); operation.operators.push(operator); kindSelect.parentElement.parentElement.insertAdjacentHTML( "beforeend", operatorVariableSelect ); insertOperationTypeAtEndOfOperation(operation, operator); document .getElementById( `operation${operation.hash}Operator${operator.hash}VariableSelect` ) .addEventListener("change", (ev) => { updateOperationOperator( ev.target.getAttribute("operation-id"), ev.target.getAttribute("operator-id"), ev.target.value ); }); updateResume(operation.hash); // Changing focus to the variable select after select for screen readers document .getElementById( `operation${operation.hash}Operator${operator.hash}VariableSelect` ) .focus(); } // Insert value after operator kind select export function insertValueAfterOperationKind(kindSelect, operation) { let operator = Object.assign({}, operatorScheme); operator.hash = generateUUID().replaceAll("-", ""); operator.type = getOperatorTypeByValue("VALUE"); let operatorValueInput = htmlOperatorValueInputScheme(operation, operator); operation.operators.push(operator); kindSelect.parentElement.parentElement.insertAdjacentHTML( "beforeend", operatorValueInput ); kindSelect.parentElement.remove(); insertOperationTypeAtEndOfOperation(operation, operator); document .getElementById( `operation${operation.hash}Operator${operator.hash}ValueInput` ) .addEventListener("change", (ev) => { updateOperationOperator( ev.target.getAttribute("operation-id"), ev.target.getAttribute("operator-id"), ev.target.value ); }); updateResume(operation.hash); // Changing focus to the input value after select for screen readers document .getElementById( `operation${operation.hash}Operator${operator.hash}ValueInput` ) .focus(); } // Add final operation type end of the operation export function insertOperationTypeAtEndOfOperation(operation, afterOperator) { let operator = Object.assign({}, operatorScheme); operator.hash = generateUUID().replaceAll("-", ""); operator.type = getOperatorTypeByValue("OPERATOR"); operator.operator = getOperationTypeByValue("SEMICOLON"); let operationTypeInput = htmlOperationTypeSelect(operation, operator); operationTypeInput.replaceAll("", operator.hash); operation.operators.push(operator); if (afterOperator.type.value === "VARIABLE") { document .querySelector(`select[operator-id='${afterOperator.hash}']`) .parentElement.insertAdjacentHTML("afterend", operationTypeInput); } else if (afterOperator.type.value === "VALUE") { document .querySelector(`input[operator-id='${afterOperator.hash}']`) .parentElement.insertAdjacentHTML("afterend", operationTypeInput); } document .getElementById( `operation${operation.hash}Operator${operator.hash}OperationTypeSelect` ) .addEventListener("change", (ev) => { updateOperationOperator( ev.target.getAttribute("operation-id"), ev.target.getAttribute("operator-id"), ev.target.value ); }); } // *********************************************************************** // Listeners // *********************************************************************** export function updateOperationAssignValue(operationHash, newVariable) { let operation = getOperationByHash(operationHash); let variable = getVariableByHash(newVariable); operation.assignedVariable = variable; updateResume(operation.hash); } export function updateOperationOperator(operationHash, operatorHash, newValue) { let operation = getOperationByHash(operationHash); let operator = getOperatorByHash(operation, operatorHash); switch (operator.type.value) { case "VARIABLE": let variable = getVariableByHash(newValue); operator.variable = variable; break; case "VALUE": operator.value = newValue; break; case "OPERATOR": operator.operator = getOperationTypeByValue(newValue); const operationTypeSelect = document.getElementById( `operation${operation.hash}Operator${operator.hash}OperationTypeSelect` ); // If the operator isn't a semicolumn, it is the last item on the operator list and teh next elemtn is equal to null, // we need to add a new operator select if ( operator.operator.name !== ";" && operation.operators.indexOf(operator) === operation.operators.length - 1 && operationTypeSelect.parentElement.nextElementSibling == null ) addOperatorKind(operation.hash); else if ( operator.operator.name === ";" && operation.operators.indexOf(operator) === operation.operators.length - 1 && operationTypeSelect.parentElement.nextElementSibling != null ) operationTypeSelect.parentElement.nextElementSibling.remove(); else if ( operator.operator.name === ";" && operation.operators.indexOf(operator) !== operation.operators.length - 1 && operationTypeSelect.parentElement.nextElementSibling != null ) { let indexOfOperator = operation.operators.indexOf(operator) + 1; operation.operators.splice(indexOfOperator); let elementSibling = operationTypeSelect.parentElement.nextElementSibling; let nextElementSibling = operationTypeSelect.parentElement.nextElementSibling; while (nextElementSibling != null) { nextElementSibling = elementSibling.nextElementSibling; elementSibling.remove(); elementSibling = nextElementSibling; } } break; } updateResume(operation.hash); } // Here we remove all operation that include the variable received as parameter export function deleteOperationByVariable(variable) { const operationsToRemove = []; for (const i in operations) { console.log(operations[i]); if (operations[i].assignedVariable.hash === variable.hash) { document.getElementById(`operation${operations[i].hash}Li`).remove(); operationsToRemove.push(operations[i]); continue; } for (const j in operations[i].operators) { console.log(j); console.log(operations[i].operators[j]); if (operations[i].operators[j].type.value === Operators.VARIABLE) { if (operations[i].operators[j].variable.hash === variable.hash) { document.getElementById(`operation${operations[i].hash}Li`).remove(); operationsToRemove.push(operations[i]); // if (operation.operators.length > 2) { // // } else { // // } } } } } for (const i in operationsToRemove) { operations.splice(operations.indexOf(operationsToRemove[i]), 1); } } // Here we remove all operation that include the variable received as parameter export function deleteOperation(hash) { const operation = getOperationByHash(hash); document.getElementById(`operation${hash}Li`).remove(); operations.splice(operations.indexOf(operation), 1); } // Here we remove all operation export function deleteAllOperation() { for (let i = 0; i < operations.length; i++) { document.getElementById(`operation${operations[i].hash}Li`).remove(); } operations.length = 0; } // *********************************************************************** // Managing operation editing // *********************************************************************** const manageOperationEditing = (hash, enableForEditing = false) => { const operation = getOperationByHash(hash); const operationForm = document.getElementById( `operation${operation.hash}Form` ); switch (operation.type) { case "ASSIGN": if (operation.editing && !enableForEditing) { // Editing fields operationForm.childNodes[1].childNodes[1].style.display = "none"; operationForm.childNodes[1].childNodes[3].style.display = "none"; operationForm.childNodes[1].childNodes[5].style.display = "none"; // Resume field operationForm.childNodes[1].childNodes[7].style.display = "inline"; operation.editing = false; } else if (enableForEditing) { // Editing fields operationForm.childNodes[1].childNodes[1].style.display = "inline"; operationForm.childNodes[1].childNodes[3].style.display = "inline"; operationForm.childNodes[1].childNodes[5].style.display = "inline"; // Resume field operationForm.childNodes[1].childNodes[7].style.display = "none"; // Changing focus to firt child document .getElementById(`operation${operation.hash}AssignVariableSelect`) .focus(); operation.editing = true; } break; case "PRINT": if (operation.editing && !enableForEditing) { // Editing fields operationForm.childNodes[1].childNodes[1].style.display = "none"; operationForm.childNodes[1].childNodes[3].style.display = "none"; // Resume field operationForm.childNodes[1].childNodes[5].style.display = "inline"; operation.editing = false; } else if (enableForEditing) { // Editing fields operationForm.childNodes[1].childNodes[1].style.display = "inline"; operationForm.childNodes[1].childNodes[3].style.display = "inline"; // Resume field operationForm.childNodes[1].childNodes[5].style.display = "none"; // Changing focus to firt child document .getElementById(`operation${operation.hash}VariableSelectLabel`) .focus(); operation.editing = true; } break; } }; // *********************************************************************** // Updating variable resume // *********************************************************************** function updateResume(hash) { const resume = generateResume(hash); document.getElementById(`operation${hash}DisplayCode`).innerText = resume.display; document .getElementById(`operation${hash}Resume`) .setAttribute("title", resume.resume); } function generateResume(hash) { const operation = getOperationByHash(hash); let resume; let display; switch (operation.type) { case "ASSIGN": resume = `${operation.assignedVariable.name}, recebe: `; display = `${operation.assignedVariable.name} <- `; for (const i in operation.operators) { console.log(operation.operators[i]); switch (operation.operators[i].type.value) { case Operators.OPERATOR: resume += `${operation.operators[i].operator.friendlyName} `; display += `${operation.operators[i].operator.name} `; break; case Operators.VALUE: resume += `${operation.operators[i].value} `; display += `${operation.operators[i].value} `; break; case Operators.VARIABLE: resume += `${operation.operators[i].variable.name} `; display += `${operation.operators[i].variable.name} `; break; } } break; case "PRINT": resume = `Escreva a variável: ${operation.assignedVariable.name}`; display = `escreva (${operation.assignedVariable.name});`; break; } return { resume: resume, display: display }; } // *********************************************************************** // Print // *********************************************************************** export function createPrintOperation() { const operation = Object.assign({}, operationScheme); operation.hash = generateUUID().replaceAll("-", ""); operation.assignedVariable = variables.length > 0 ? variables[0] : null; operation.type = "PRINT"; operations.push(operation); const printOperation = printOperationScheme(operation); htmlOlCommandsOperations.insertAdjacentHTML("beforeend", printOperation); updateResume(operation.hash); // Changing focus to the variable type after creation for screen readers document .getElementById(`operation${operation.hash}VariableSelectLabel`) .focus(); document .getElementById(`operation${operation.hash}VariableSelect`) .addEventListener("change", (ev) => { updatePrintOperation( ev.target.getAttribute("operation-id"), ev.target.value ); }); document .getElementById(`operation${operation.hash}Delete`) .addEventListener("click", (ev) => { deleteOperation(ev.target.getAttribute("operation-id")); }); document .getElementById(`operation${operation.hash}Resume`) .addEventListener("focus", (ev) => { const operationHash = ev.target.getAttribute("operation-id"); manageOperationEditing(operationHash); }); document .getElementById(`operation${operation.hash}Display`) .addEventListener("keyup", (ev) => { const operationHash = ev.target.getAttribute("operation-id"); if (ev.key === "Enter") manageOperationEditing(operationHash, true); }); } // TODO: // terminal => basico function updatePrintOperation(hash, newValue) { const operation = getOperationByHash(hash); const variable = getVariableByHash(newValue); operation.assignedVariable = variable; updateResume(operation.hash); } // *********************************************************************** // Util // *********************************************************************** export function getOperationByHash(hash) { for (let i = 0; i < operations.length; i++) { if (operations[i].hash === hash) return operations[i]; } return null; } // ***********************************************************************