attribution.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. import * as Models from '../ivprog_elements';
  2. import { LocalizedStrings } from '../../services/localizedStringsService';
  3. import * as VariableValueMenu from './variable_value_menu';
  4. import * as VariableValueMenuManagement from './variable_value_menu';
  5. import * as CommandsManagement from '../commands';
  6. import * as ExpressionManagement from './generic_expression';
  7. import * as CodeGenerator from '../code_generator';
  8. import { renderAlgorithm } from '../algorithm';
  9. export function createFloatingCommand () {
  10. return $('<div class="ui attribution created_element"> <i class="ui icon small arrow left"></i> <span> x <&#8212; 1 + 1 </span></div>');
  11. }
  12. export function renderCommand (command, function_obj) {
  13. var el = $('<div class="ui attribution command_container"><i class="ui icon small arrow left command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="var_attributed"></div> <span class="text_attr_receives span_command_spec">'+LocalizedStrings.getUI('text_receives')+'</span> '
  14. + '<div class="expression_elements"></div> <span class="textual_expression"></span> <i class="ui icon i cursor button_write_expression"></i> <i class="ui icon unlock button_alternate_expression"></i> </div>');
  15. el.data('command', command);
  16. VariableValueMenu.renderMenu(command, command.variable, el.find('.var_attributed'), function_obj);
  17. if (!command.expression || command.expression.length < 1) {
  18. var exp = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true);
  19. command.expression.push(exp);
  20. }
  21. addHandlers(command, function_obj, el);
  22. ExpressionManagement.renderExpression(command, function_obj, el.find('.expression_elements'), command.expression);
  23. if (command.lockexpression) {
  24. if (command.expression) {
  25. try {
  26. var text = CodeGenerator.elementExpressionCode(command.expression);
  27. if (text) {
  28. $(el.find('.expression_elements')[0]).toggle();
  29. $(el.find('.textual_expression')[0]).text(text);
  30. $(el.find('.textual_expression')[0]).toggle();
  31. $(el.find('.button_alternate_expression')[0]).toggleClass('unlock').toggleClass('lock');
  32. }
  33. } catch (e) {
  34. command.lockexpression = false;
  35. }
  36. }
  37. }
  38. return el;
  39. }
  40. export function manageExpressionElements (command, ref_object, dom_object, menu_var_or_value, function_obj, selectedItem, expression_element) {
  41. var index_to_move = expression_element.itens.indexOf(ref_object);
  42. switch (selectedItem.data('exp')) {
  43. case Models.EXPRESSION_ELEMENTS.exp_op_exp:
  44. var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.exp_op_exp, [expression_element.itens[index_to_move],
  45. Models.ARITHMETIC_TYPES.plus,
  46. new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
  47. expression_element.itens[index_to_move] = exp;
  48. break;
  49. case Models.EXPRESSION_ELEMENTS.op_exp:
  50. var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.op_exp, [Models.ARITHMETIC_TYPES.plus,
  51. expression_element.itens[index_to_move] ]);
  52. expression_element.itens[index_to_move] = exp;
  53. break;
  54. case Models.EXPRESSION_ELEMENTS.par_exp_par:
  55. var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.par_exp_par, [expression_element.itens[index_to_move]]);
  56. expression_element.itens[index_to_move] = exp;
  57. break;
  58. }
  59. renderExpressionElements(command, function_obj, dom_object);
  60. }
  61. function renderExpressionElements (command, function_obj, el) {
  62. var expression_div = el.find('.expression_elements');
  63. var command_container;
  64. if (el.hasClass("command_container") == false) {
  65. var hier = el.parentsUntil(".command_container");
  66. for (var i = 0; i < hier.length; i++) {
  67. if ($(hier[i]).hasClass("command_container")) {
  68. command_container = $(hier[i]);
  69. break;
  70. }
  71. if ($(hier[i]).hasClass("expression_elements")) {
  72. expression_div = $(hier[i]);
  73. break;
  74. }
  75. }
  76. }
  77. if (command_container) {
  78. expression_div = command_container.find('.expression_elements');
  79. }
  80. expression_div.text('');
  81. for (var i = 0; i < command.expression.length; i++) {
  82. var temp = $('<div class="expression_element"></div>');
  83. temp.data('ref_element', command.expression[i]);
  84. temp.data('ref_index', i);
  85. expression_div.append(temp);
  86. renderElement(command, function_obj, temp, command.expression[i]);
  87. }
  88. }
  89. function renderOperator (command, function_obj, temp_op, expression_element, index_op) {
  90. var context_menu = '<div class="ui dropdown"><div class="text">';
  91. switch (expression_element.itens[index_op]) {
  92. case Models.ARITHMETIC_TYPES.plus:
  93. context_menu += '+';
  94. break;
  95. case Models.ARITHMETIC_TYPES.minus:
  96. context_menu += '-';
  97. break;
  98. case Models.ARITHMETIC_TYPES.multiplication:
  99. context_menu += '*';
  100. break;
  101. case Models.ARITHMETIC_TYPES.division:
  102. context_menu += '/';
  103. break;
  104. case Models.ARITHMETIC_TYPES.module:
  105. context_menu += '%';
  106. break;
  107. case Models.ARITHMETIC_TYPES.none:
  108. context_menu += '...';
  109. break;
  110. }
  111. context_menu += '</div><div class="menu">';
  112. context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.plus+'">+</div>';
  113. context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.minus+'">-</div>';
  114. context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.multiplication+'">*</div>';
  115. context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.division+'">/</div>';
  116. context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.module+'">%</div>';
  117. context_menu += '<div class="item" data-value="'+Models.ARITHMETIC_TYPES.none+'" data-text="...">Nenhum</div>';
  118. context_menu += '</div></div>';
  119. context_menu = $(context_menu);
  120. temp_op.append(context_menu);
  121. context_menu.dropdown({
  122. onChange: function(value, text, $selectedItem) {
  123. expression_element.itens[index_op] = value;
  124. }
  125. });
  126. }
  127. function renderMenuAddExpression (command, function_obj, el, dom_append_menu, expression_append_new_expression) {
  128. if (el.hasClass("command_container") == false) {
  129. var hier = el.parentsUntil(".commands_list_div");
  130. for (var i = 0; i < hier.length; i++) {
  131. if ($(hier[i]).hasClass("command_container")) {
  132. el = $(hier[i]);
  133. break;
  134. }
  135. }
  136. }
  137. if (dom_append_menu.hasClass("expression_elements") == false) {
  138. var hier = el.parentsUntil(".commands_list_div");
  139. for (var i = 0; i < hier.length; i++) {
  140. if ($(hier[i]).hasClass("expression_elements")) {
  141. dom_append_menu = $(hier[i]);
  142. break;
  143. }
  144. }
  145. }
  146. var context_menu = '<div class="ui dropdown"><div class="text"></div><i class="ui icon arrow alternate circle right outline"></i><div class="menu">';
  147. context_menu += '<div class="item" data-value="'+Models.EXPRESSION_ELEMENTS.exp_op_exp+'">EXP OP EXP</div>';
  148. context_menu += '<div class="item" data-value="'+Models.EXPRESSION_ELEMENTS.op_exp+'">OP EXP</div>';
  149. context_menu += '<div class="item" data-value="'+Models.EXPRESSION_ELEMENTS.par_exp_par+'">( EXP )</div>';
  150. context_menu += '</div></div>';
  151. context_menu = $(context_menu);
  152. dom_append_menu.append(context_menu);
  153. context_menu.dropdown({
  154. onChange: function(value, text, $selectedItem) {
  155. switch (value) {
  156. case Models.EXPRESSION_ELEMENTS.exp_op_exp:
  157. var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.exp_op_exp, [new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true),
  158. Models.ARITHMETIC_TYPES.plus,
  159. new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
  160. expression_append_new_expression.push(exp);
  161. break;
  162. case Models.EXPRESSION_ELEMENTS.op_exp:
  163. var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.op_exp, [Models.ARITHMETIC_TYPES.plus,
  164. new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
  165. expression_append_new_expression.push(exp);
  166. break;
  167. case Models.EXPRESSION_ELEMENTS.par_exp_par:
  168. var exp = new Models.ExpressionElement(Models.EXPRESSION_ELEMENTS.par_exp_par, [new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
  169. expression_append_new_expression.push(exp);
  170. break;
  171. }
  172. renderExpressionElements(command, function_obj, el);
  173. }
  174. });
  175. }
  176. function renderElement (command, function_obj, el, expression_element) {
  177. switch (expression_element.type_exp) {
  178. case Models.EXPRESSION_ELEMENTS.exp_op_exp:
  179. var temp_op = $('<div class="component_element"></div>');
  180. var temp_exp_1 = $('<div class="component_element"></div>');
  181. var temp_exp_2 = $('<div class="component_element"></div>');
  182. el.append(temp_exp_1);
  183. el.append(temp_op);
  184. el.append(temp_exp_2);
  185. if (expression_element.itens[0].type) {
  186. VariableValueMenu.renderMenu(command, expression_element.itens[0], temp_exp_1, function_obj, 2, expression_element);
  187. } else {
  188. renderElement(command, function_obj, temp_exp_1, expression_element.itens[0]);
  189. }
  190. renderOperator(command, function_obj, temp_op, expression_element, 1);
  191. if (expression_element.itens[2].type) {
  192. VariableValueMenu.renderMenu(command, expression_element.itens[2], temp_exp_2, function_obj, 2, expression_element);
  193. } else {
  194. renderElement(command, function_obj, temp_exp_2, expression_element.itens[2]);
  195. }
  196. break;
  197. case Models.EXPRESSION_ELEMENTS.op_exp:
  198. var temp_op = $('<div class="component_element"></div>');
  199. var temp_exp = $('<div class="component_element"></div>');
  200. el.append(temp_op);
  201. el.append(temp_exp);
  202. renderOperator(command, function_obj, temp_op, expression_element, 0);
  203. if (expression_element.itens[1].type) {
  204. VariableValueMenu.renderMenu(command, expression_element.itens[1], temp_exp, function_obj, 2, expression_element);
  205. } else {
  206. renderElement(command, function_obj, temp_exp, expression_element.itens[1]);
  207. }
  208. break;
  209. case Models.EXPRESSION_ELEMENTS.par_exp_par:
  210. var temp_par_1 = $('<div class="component_element"> ( </div>');
  211. var temp_exp = $('<div class="component_element"></div>');
  212. var temp_par_2 = $('<div class="component_element"> ) </div>');
  213. el.append(temp_par_1);
  214. el.append(temp_exp);
  215. for (var j = 0; j < expression_element.itens.length; j++) {
  216. if (expression_element.itens[j].type) {
  217. VariableValueMenu.renderMenu(command, expression_element.itens[j], temp_exp, function_obj, 2, expression_element);
  218. } else {
  219. renderElement(command, function_obj, temp_exp, expression_element.itens[j]);
  220. }
  221. }
  222. //renderMenuAddExpression(command, function_obj, el, el, expression_element.itens);
  223. el.append(temp_par_2);
  224. break;
  225. }
  226. }
  227. function renderExpression (command, function_obj, el) {
  228. var expression_div = el.find('.expression_elements');
  229. expression_div.text('');
  230. var menu_add_item = $('<div class="menu_add_item"></div>');
  231. menu_add_item.data('index_add', 0);
  232. expression_div.append(menu_add_item);
  233. for (var i = 0; i < command.expression.length; i++) {
  234. if (command.expression[i].type) {
  235. var temp = $('<div class="expression_element"></div>');
  236. temp.data('ref_element', command.expression[i]);
  237. temp.data('ref_index', i);
  238. expression_div.append(temp);
  239. VariableValueMenu.renderMenu(command, command.expression[i], temp, function_obj);
  240. } else if (command.expression[i] == "(" || command.expression[i] == ")") {
  241. var temp = $('<div class="expression_element">'+command.expression[i]+'</div>');
  242. temp.data('ref_element', command.expression[i]);
  243. temp.data('ref_index', i);
  244. expression_div.append(temp);
  245. } else {
  246. var temp = '<div class="expression_element">';
  247. switch(command.expression[i]) {
  248. case Models.ARITHMETIC_TYPES.plus:
  249. temp += '+';
  250. break;
  251. case Models.ARITHMETIC_TYPES.minus:
  252. temp += '-';
  253. break;
  254. case Models.ARITHMETIC_TYPES.multiplication:
  255. temp += '*';
  256. break;
  257. case Models.ARITHMETIC_TYPES.division:
  258. temp += '/';
  259. break;
  260. case Models.ARITHMETIC_TYPES.module:
  261. temp += '%';
  262. break;
  263. }
  264. temp += '</div>';
  265. temp = $(temp);
  266. temp.data('ref_element', command.expression[i]);
  267. temp.data('ref_index', i);
  268. expression_div.append(temp);
  269. }
  270. var menu_add_item_seq = $('<div class="menu_add_item"></div>');
  271. var index_temp = (i + 1);
  272. menu_add_item_seq.data('index_add', index_temp);
  273. expression_div.append(menu_add_item_seq);
  274. }
  275. addMenuItens(command, function_obj, el);
  276. }
  277. function addMenuItens (command, function_obj, expression_div) {
  278. var divs_expression = expression_div.find('.menu_add_item');
  279. for (var i = 0; i < divs_expression.length; i++) {
  280. var temp = $(divs_expression[i]).data('index_add');
  281. var context_menu = '<div class="ui dropdown context_menu_clear"><i class="ui icon plus square outline"></i><div class="menu">';
  282. context_menu += '<div class="item" data-option="value" data-index="'+temp+'">'+LocalizedStrings.getUI('text_value')+'</div>';
  283. context_menu += '<div class="item" data-option="operator" data-index="'+temp+'">'+LocalizedStrings.getUI('text_operator')+'</div>';
  284. context_menu += '<div class="item" data-option="parentheses" data-index="'+temp+'">'+LocalizedStrings.getUI('text_parentheses')+'</div>';
  285. context_menu += '</div></div>';
  286. context_menu = $(context_menu);
  287. $(divs_expression[i]).append(context_menu);
  288. context_menu.dropdown({
  289. on: 'hover',
  290. onChange: function(value, text, $selectedItem) {
  291. switch ($selectedItem.data('option')) {
  292. case "value":
  293. command.expression.splice($selectedItem.data('index'), 0, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true));
  294. renderExpression(command, function_obj, expression_div);
  295. break;
  296. case "operator":
  297. command.expression.splice($selectedItem.data('index'), 0, Models.ARITHMETIC_TYPES.plus);
  298. renderExpression(command, function_obj, expression_div);
  299. break;
  300. case "parentheses":
  301. command.expression.splice($selectedItem.data('index'), 0, "(");
  302. command.expression.splice($selectedItem.data('index') + 1, 0, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true));
  303. command.expression.splice($selectedItem.data('index') + 2, 0, ")");
  304. renderExpression(command, function_obj, expression_div);
  305. break;
  306. }
  307. }
  308. });
  309. }
  310. }
  311. function addHandlers (command, function_obj, attribution_dom) {
  312. attribution_dom.find('.button_write_expression').on('click', function() {
  313. var afterWhichElement;
  314. var lockButton = $(attribution_dom.find('.button_alternate_expression')[0]);
  315. var editButton = $(this);
  316. afterWhichElement = attribution_dom.find('.expression_elements');
  317. if (command.lockexpression) {
  318. afterWhichElement = attribution_dom.find('.textual_expression');
  319. }
  320. var text = "";
  321. if (command.expression) {
  322. try {
  323. text = CodeGenerator.elementExpressionCode(command.expression);
  324. } catch(ex) {
  325. text = "";
  326. }
  327. }
  328. var input = $('<input type="text" value="'+text+'" spellcheck="false" autocomplete="off" >');
  329. input.keyup(function(evt) {
  330. if (evt.keyCode == 27) { // esc
  331. input.remove();
  332. afterWhichElement.css('display', 'inline');
  333. lockButton.css('display', 'inline');
  334. editButton.css('display', 'inline');
  335. }
  336. if (evt.keyCode == 13) { // enter
  337. var parsed = null;
  338. parsed = ExpressionManagement.expressionParserToVisual(input.val(), function_obj, input);
  339. if (parsed) {
  340. command.expression = parsed;
  341. renderAlgorithm();
  342. }
  343. }
  344. });
  345. input.insertAfter(afterWhichElement);
  346. input.focus();
  347. var len = text.length;
  348. input[0].setSelectionRange(len, len);
  349. afterWhichElement.css('display', 'none');
  350. lockButton.css('display', 'none');
  351. editButton.css('display', 'none');
  352. });
  353. $(attribution_dom.find('.textual_expression')[0]).toggle();
  354. attribution_dom.find('.button_alternate_expression').on('click', function() {
  355. if (command.expression) {
  356. var text = CodeGenerator.elementExpressionCode(command.expression);
  357. if (text) {
  358. $(attribution_dom.find('.expression_elements')[0]).toggle();
  359. $(attribution_dom.find('.textual_expression')[0]).text(text);
  360. $(attribution_dom.find('.textual_expression')[0]).toggle();
  361. $(this).toggleClass('unlock').toggleClass('lock');
  362. command.lockexpression = !command.lockexpression;
  363. }
  364. }
  365. });
  366. attribution_dom.find('.button_remove_command').on('click', function() {
  367. if (CommandsManagement.removeCommand(command, function_obj, attribution_dom)) {
  368. attribution_dom.fadeOut(400, function() {
  369. attribution_dom.remove();
  370. });
  371. }
  372. });
  373. attribution_dom.find('.button_refresh_attribution').on('click', function() {
  374. renderExpressionElements(command, function_obj, attribution_dom);
  375. });
  376. }
  377. export function renderMenuOperations (command, ref_object, dom_object, menu_var_or_value, function_obj, variable_selected) {
  378. /*console.log("recebido o seguinte DOM: ");
  379. console.log(dom_object);
  380. if (dom_object.hasClass('var_attributed')) {
  381. return;
  382. } else {
  383. var hier = dom_object.parentsUntil(".command_container");
  384. for (var i = 0; i < hier.length; i++) {
  385. if ($(hier[i]).hasClass('var_attributed') || $(hier[i]).hasClass('parameters_function_called')) {
  386. return;
  387. }
  388. }
  389. }
  390. dom_object.find('.context_menu_clear').remove();
  391. var menu_operations = '<div class="ui dropdown menu_operations"><div class="text"></div><i class="dropdown icon"></i><div class="menu">';
  392. for (var tm in Models.ARITHMETIC_TYPES) {
  393. menu_operations += '<div class="item" data-option="'+tm+'">'+LocalizedStrings.getUI('btn_arithmetic_' + tm)+'</div>';
  394. }
  395. menu_operations += '<div class="item" data-option="clear">'+LocalizedStrings.getUI('btn_clear')+'</div>';
  396. menu_operations += '</div></div>';
  397. menu_operations = $(menu_operations);
  398. dom_object.append(menu_operations);
  399. menu_operations.dropdown({
  400. onChange: function(value, text, $selectedItem) {
  401. switch ($($selectedItem).data('option')) {
  402. case "clear":
  403. $(dom_object).text('');
  404. VariableValueMenu.renderMenu(command, ref_object, dom_object, function_obj);
  405. break;
  406. default:
  407. createExpressionAround(command, ref_object, dom_object, function_obj);
  408. menu_operations.find('.text').text('');
  409. }
  410. }
  411. });*/
  412. }
  413. function createExpressionAround (command, ref_object, dom_object, function_obj) {
  414. $('<span> ( </span>').insertBefore(dom_object);
  415. $('<span> ) </span>').insertAfter(dom_object);
  416. VariableValueMenu.renderMenu(command, new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true), dom_object, function_obj);
  417. }