operations.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. // Imports
  2. import {generateUUID, htmlOlCommandsOperations} from './../../main';
  3. import {
  4. getOperationTypeByValue, getOperatorByHash,
  5. getOperatorTypeByValue,
  6. htmlAssignVariableScheme,
  7. htmlOperationKindScheme, htmlOperationTypeSelect, htmlOperatorValueInputScheme,
  8. htmlOperatorVariablesSelectScheme,
  9. operationScheme, Operators, operatorScheme, printOperationScheme
  10. } from "./operations-schemes";
  11. import {getVariableByHash, variables} from "../variables/variables";
  12. // Imports
  13. export const operations = [];
  14. // Creating operation
  15. export function createOperation () {
  16. let operation = Object.assign({}, operationScheme);
  17. operation.hash = generateUUID().replaceAll('-', '');
  18. // TODO: Fix
  19. operation.assignedVariable = variables[0];
  20. operation.operators = [];
  21. operations.push(operation);
  22. let htmlOperation = htmlAssignVariableScheme();
  23. htmlOperation = htmlOperation.replaceAll('<operationId>', operation.hash);
  24. htmlOlCommandsOperations.insertAdjacentHTML('beforeend', htmlOperation);
  25. document.getElementById(`operation${operation.hash}AssignVariableSelect`).addEventListener('change', ev => {
  26. updateOperationAssignValue(ev.target.getAttribute('operation-id'), ev.target.value);
  27. });
  28. document.getElementById(`operation${operation.hash}Delete`).addEventListener('click', ev => {
  29. deleteOperation(ev.target.getAttribute('operation-id'));
  30. });
  31. addOperatorKind(operation.hash);
  32. updateResume(operation.hash);
  33. // Changing focus to the variable type after creation for screen readers
  34. document.getElementById(`operation${operation.hash}AssignVariableSelect`).focus();
  35. }
  36. // Add operator kind to the operation
  37. export function addOperatorKind (hash) {
  38. let operation = getOperationByHash(hash);
  39. console.log(operation);
  40. let htmlOperationKind = htmlOperationKindScheme(operation);
  41. document.getElementById(`operation${operation.hash}OperatorsDiv`).insertAdjacentHTML('beforeend', htmlOperationKind);
  42. document.getElementById(`operation${operation.hash}KindSelect`).addEventListener('change', ev => {
  43. selectedOperationKind(ev.target.getAttribute('operation-id'));
  44. });
  45. }
  46. // Function to be trigger when the operator kind is selected
  47. export function selectedOperationKind (operationHash) {
  48. let operation = getOperationByHash(operationHash);
  49. console.log(operation);
  50. let kindSelect = document.getElementById(`operation${operation.hash}KindSelect`);
  51. // TODO: think into an way to make this dynamic
  52. if (kindSelect.value === 'VARIABLE') {
  53. insertVariableAfterOperationKind(kindSelect, operation);
  54. } else if (kindSelect.value === 'VALUE') {
  55. insertValueAfterOperationKind(kindSelect, operation);
  56. }
  57. }
  58. // Insert variable after operator kind select
  59. export function insertVariableAfterOperationKind (kindSelect, operation) {
  60. let operator = Object.assign({}, operatorScheme);
  61. operator.hash = generateUUID().replaceAll('-', '');
  62. // TODO: Fix ?
  63. operator.variable = variables[0];
  64. operator.type = getOperatorTypeByValue('VARIABLE');
  65. let operatorVariableSelect = htmlOperatorVariablesSelectScheme(operation, operator);
  66. operation.operators.push(operator);
  67. kindSelect.parentElement.parentElement.insertAdjacentHTML('beforeend', operatorVariableSelect);
  68. kindSelect.parentElement.remove();
  69. insertOperationTypeAtEndOfOperation(operation, operator);
  70. document.getElementById(`operation${operation.hash}Operator${operator.hash}VariableSelect`).addEventListener('change', ev => {
  71. updateOperationOperator(ev.target.getAttribute('operation-id'), ev.target.getAttribute('operator-id'), ev.target.value)
  72. });
  73. updateResume(operation.hash);
  74. // Changing focus to the variable select after select for screen readers
  75. document.getElementById(`operation${operation.hash}Operator${operator.hash}VariableSelect`).focus();
  76. }
  77. // Insert value after operator kind select
  78. export function insertValueAfterOperationKind (kindSelect, operation) {
  79. let operator = Object.assign({}, operatorScheme);
  80. operator.hash = generateUUID().replaceAll('-', '');
  81. operator.type = getOperatorTypeByValue('VALUE');
  82. let operatorValueInput = htmlOperatorValueInputScheme(operation, operator);
  83. operation.operators.push(operator);
  84. kindSelect.parentElement.parentElement.insertAdjacentHTML('beforeend', operatorValueInput);
  85. kindSelect.parentElement.remove();
  86. insertOperationTypeAtEndOfOperation(operation, operator);
  87. document.getElementById(`operation${operation.hash}Operator${operator.hash}ValueInput`).addEventListener('change', ev => {
  88. updateOperationOperator(ev.target.getAttribute('operation-id'), ev.target.getAttribute('operator-id'), ev.target.value)
  89. });
  90. updateResume(operation.hash);
  91. // Changing focus to the input value after select for screen readers
  92. document.getElementById(`operation${operation.hash}Operator${operator.hash}ValueInput`).focus();
  93. }
  94. // Add final operation type end of the operation
  95. export function insertOperationTypeAtEndOfOperation (operation, afterOperator) {
  96. let operator = Object.assign({}, operatorScheme);
  97. operator.hash = generateUUID().replaceAll('-', '');
  98. operator.type = getOperatorTypeByValue('OPERATOR');
  99. operator.operator = getOperationTypeByValue('SEMICOLON');
  100. let operationTypeInput = htmlOperationTypeSelect(operation, operator);
  101. operationTypeInput.replaceAll('<operatorId>', operator.hash);
  102. operation.operators.push(operator);
  103. if (afterOperator.type.value === 'VARIABLE') {
  104. document.querySelector(`select[operator-id='${afterOperator.hash}']`).parentElement.insertAdjacentHTML('afterend', operationTypeInput);
  105. } else if (afterOperator.type.value === 'VALUE') {
  106. document.querySelector(`input[operator-id='${afterOperator.hash}']`).parentElement.insertAdjacentHTML('afterend', operationTypeInput);
  107. }
  108. document.getElementById(`operation${operation.hash}Operator${operator.hash}OperationTypeSelect`).addEventListener('change', ev => {
  109. updateOperationOperator(ev.target.getAttribute('operation-id'), ev.target.getAttribute('operator-id'), ev.target.value)
  110. });
  111. }
  112. // ***********************************************************************
  113. // Listeners
  114. // ***********************************************************************
  115. export function updateOperationAssignValue (operationHash, newVariable) {
  116. let operation = getOperationByHash(operationHash);
  117. let variable = getVariableByHash(newVariable);
  118. operation.assignedVariable = variable;
  119. updateResume(operation.hash);
  120. }
  121. export function updateOperationOperator (operationHash, operatorHash, newValue) {
  122. let operation = getOperationByHash(operationHash);
  123. let operator = getOperatorByHash(operation, operatorHash);
  124. switch (operator.type.value) {
  125. case 'VARIABLE':
  126. let variable = getVariableByHash(newValue);
  127. operator.variable = variable;
  128. break;
  129. case 'VALUE':
  130. operator.value = newValue;
  131. break;
  132. case 'OPERATOR':
  133. operator.operator = getOperationTypeByValue(newValue);
  134. const operationTypeSelect = document.getElementById(`operation${operation.hash}Operator${operator.hash}OperationTypeSelect`);
  135. // If the operator isn't a semicolumn, it is the last item on the operator list and teh next elemtn is equal to null,
  136. // we need to add a new operator select
  137. if (operator.operator.name !== ';'
  138. && (operation.operators.indexOf(operator) === (operation.operators.length - 1))
  139. && operationTypeSelect.parentElement.nextElementSibling == null)
  140. addOperatorKind(operation.hash);
  141. else if (operator.operator.name === ';'
  142. && (operation.operators.indexOf(operator) === (operation.operators.length - 1))
  143. && operationTypeSelect.parentElement.nextElementSibling != null)
  144. operationTypeSelect.parentElement.nextElementSibling.remove();
  145. else if (operator.operator.name === ';'
  146. && (operation.operators.indexOf(operator) !== (operation.operators.length - 1))
  147. && operationTypeSelect.parentElement.nextElementSibling != null) {
  148. let indexOfOperator = operation.operators.indexOf(operator) + 1;
  149. operation.operators.splice(indexOfOperator);
  150. let elementSibling = operationTypeSelect.parentElement.nextElementSibling;
  151. let nextElementSibling = operationTypeSelect.parentElement.nextElementSibling;
  152. while(nextElementSibling != null) {
  153. nextElementSibling = elementSibling.nextElementSibling;
  154. elementSibling.remove();
  155. elementSibling = nextElementSibling;
  156. }
  157. }
  158. break;
  159. }
  160. updateResume(operation.hash);
  161. }
  162. // Here we remove all operation that include the variable received as parameter
  163. export function deleteOperationByVariable (variable) {
  164. const operationsToRemove = [];
  165. for (const i in operations) {
  166. console.log(operations[i]);
  167. if (operations[i].assignedVariable.hash === variable.hash) {
  168. document.getElementById(`operation${operations[i].hash}Li`).remove();
  169. operationsToRemove.push(operations[i]);
  170. continue;
  171. }
  172. for (const j in operations[i].operators) {
  173. console.log(j);
  174. console.log(operations[i].operators[j]);
  175. if (operations[i].operators[j].type.value === Operators.VARIABLE) {
  176. if (operations[i].operators[j].variable.hash === variable.hash) {
  177. document.getElementById(`operation${operations[i].hash}Li`).remove();
  178. operationsToRemove.push(operations[i]);
  179. // if (operation.operators.length > 2) {
  180. //
  181. // } else {
  182. //
  183. // }
  184. }
  185. }
  186. }
  187. }
  188. for (const i in operationsToRemove) {
  189. operations.splice(operations.indexOf(operationsToRemove[i]), 1);
  190. }
  191. }
  192. // Here we remove all operation that include the variable received as parameter
  193. export function deleteOperation (hash) {
  194. const operation = getOperationByHash(hash);
  195. document.getElementById(`operation${hash}Li`).remove();
  196. operations.splice(operations.indexOf(operation), 1);
  197. }
  198. // Here we remove all operation
  199. export function deleteAllOperation () {
  200. for (let i = 0; i < operations.length; i++) {
  201. document.getElementById(`operation${operations[i].hash}Li`).remove();
  202. }
  203. operations.length = 0;
  204. }
  205. // ***********************************************************************
  206. // Updating variable resume
  207. // ***********************************************************************
  208. function updateResume (hash) {
  209. document.getElementById(`operation${hash}Resume`).setAttribute('title', generateResume(hash));
  210. }
  211. function generateResume (hash) {
  212. const operation = getOperationByHash(hash);
  213. let resume;
  214. switch (operation.type) {
  215. case 'ASSIGN':
  216. resume = `${operation.assignedVariable.name} recebe `;
  217. for (const i in operation.operators) {
  218. console.log(operation.operators[i]);
  219. switch (operation.operators[i].type.value) {
  220. case Operators.OPERATOR:
  221. resume += `${operation.operators[i].operator.friendlyName} `;
  222. break;
  223. case Operators.VALUE:
  224. resume += `${operation.operators[i].value} `;
  225. break;
  226. case Operators.VARIABLE:
  227. resume += `${operation.operators[i].variable.name} `;
  228. break;
  229. }
  230. }
  231. break;
  232. case 'PRINT':
  233. resume = `Escreva ${operation.assignedVariable.name}`
  234. }
  235. return resume;
  236. }
  237. // ***********************************************************************
  238. // Print
  239. // ***********************************************************************
  240. export function createPrintOperation () {
  241. const operation = Object.assign({}, operationScheme);
  242. operation.hash = generateUUID().replaceAll('-', '');
  243. operation.assignedVariable = variables.length > 0 ? variables[0] : null;
  244. operation.type = 'PRINT';
  245. operations.push(operation);
  246. const printOperation = printOperationScheme(operation);
  247. htmlOlCommandsOperations.insertAdjacentHTML('beforeend', printOperation);
  248. updateResume(operation.hash);
  249. // Changing focus to the variable type after creation for screen readers
  250. document.getElementById(`operation${operation.hash}VariableSelectLabel`).focus();
  251. document.getElementById(`operation${operation.hash}VariableSelect`).addEventListener('change', ev => {
  252. updatePrintOperation(ev.target.getAttribute('operation-id'), ev.target.value);
  253. });
  254. document.getElementById(`operation${operation.hash}Delete`).addEventListener('click', ev => {
  255. deleteOperation(ev.target.getAttribute('operation-id'));
  256. });
  257. }
  258. // TODO:
  259. // terminal => basico
  260. function updatePrintOperation (hash, newValue) {
  261. const operation = getOperationByHash(hash);
  262. const variable = getVariableByHash(newValue);
  263. operation.assignedVariable = variable;
  264. updateResume(operation.hash);
  265. }
  266. // ***********************************************************************
  267. // Util
  268. // ***********************************************************************
  269. export function getOperationByHash (hash) {
  270. for (let i = 0; i < operations.length; i++) {
  271. if (operations[i].hash === hash)
  272. return operations[i];
  273. }
  274. return null;
  275. }
  276. // ***********************************************************************