commands.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083
  1. import $ from 'jquery';
  2. import { Types } from './types';
  3. import * as Models from './ivprog_elements';
  4. import { LocalizedStrings } from './../services/localizedStringsService';
  5. import * as GlobalsManagement from './globals';
  6. import * as VariablesManagement from './variables';
  7. import * as CommentsManagement from './commands/comment';
  8. import * as ReadersManagement from './commands/reader';
  9. import * as WritersManagement from './commands/writer';
  10. import * as AttributionsManagement from './commands/attribution';
  11. import * as IftruesManagement from './commands/iftrue';
  12. import * as RepeatNtimesManagement from './commands/repeatNtimes';
  13. import * as WhiletruesManagement from './commands/whiletrue';
  14. import * as DowhiletruesManagement from './commands/dowhiletrue';
  15. import * as SwitchesManagement from './commands/switch';
  16. import * as FunctioncallsManagement from './commands/functioncall';
  17. import * as VariableValueMenuManagement from './commands/variable_value_menu';
  18. import * as BreaksManagement from './commands/break';
  19. import * as ReturnsManagement from './commands/return';
  20. var has_element_created_draged = false;
  21. var which_element_is_draged = null;
  22. export function removeCommand (command, function_obj, dom_obj) {
  23. if (function_obj.commands.indexOf(command) > -1) {
  24. function_obj.commands.splice(function_obj.commands.indexOf(command), 1);
  25. return true;
  26. }
  27. // Utilize dois parantNode, pois o primeiro é o div de comandos
  28. try {
  29. if (dom_obj.parent().parent().data('command').commands_block.indexOf(command) > -1) {
  30. dom_obj.parent().parent().data('command').commands_block.splice
  31. (dom_obj.parent().parent().data('command').commands_block.indexOf(command), 1);
  32. return true;
  33. }
  34. } catch (err) {}
  35. try {
  36. if (dom_obj.parent().parent().data('command').type == Models.COMMAND_TYPES.iftrue) {
  37. if (dom_obj.parent().parent().data('command').commands_else.indexOf(command) > -1) {
  38. dom_obj.parent().parent().data('command').commands_else.splice
  39. (dom_obj.parent().parent().data('command').commands_else.indexOf(command), 1);
  40. return true;
  41. }
  42. }
  43. } catch (err) {}
  44. if (dom_obj.parent().data('switchcase')) {
  45. console.log("o que encontrei: ");
  46. console.log(dom_obj.parent().data('switchcase'));
  47. dom_obj.parent().data('switchcase').commands_block.splice(dom_obj.parent().data('switchcase').commands_block.indexOf(command), 1);
  48. return true;
  49. }
  50. return false;
  51. }
  52. export function createFloatingCommand (function_obj, function_container, command_type, mouse_event) {
  53. var floatingObject;
  54. switch (command_type) {
  55. case Models.COMMAND_TYPES.break:
  56. floatingObject = BreaksManagement.createFloatingCommand();
  57. break;
  58. case Models.COMMAND_TYPES.comment:
  59. floatingObject = CommentsManagement.createFloatingCommand();
  60. break;
  61. case Models.COMMAND_TYPES.reader:
  62. floatingObject = ReadersManagement.createFloatingCommand();
  63. break;
  64. case Models.COMMAND_TYPES.writer:
  65. floatingObject = WritersManagement.createFloatingCommand();
  66. break;
  67. case Models.COMMAND_TYPES.attribution:
  68. floatingObject = AttributionsManagement.createFloatingCommand();
  69. break;
  70. case Models.COMMAND_TYPES.iftrue:
  71. floatingObject = IftruesManagement.createFloatingCommand();
  72. break;
  73. case Models.COMMAND_TYPES.repeatNtimes:
  74. floatingObject = RepeatNtimesManagement.createFloatingCommand();
  75. break;
  76. case Models.COMMAND_TYPES.whiletrue:
  77. floatingObject = WhiletruesManagement.createFloatingCommand();
  78. break;
  79. case Models.COMMAND_TYPES.dowhiletrue:
  80. floatingObject = DowhiletruesManagement.createFloatingCommand();
  81. break;
  82. case Models.COMMAND_TYPES.switch:
  83. floatingObject = SwitchesManagement.createFloatingCommand();
  84. break;
  85. case Models.COMMAND_TYPES.functioncall:
  86. floatingObject = FunctioncallsManagement.createFloatingCommand();
  87. break;
  88. case Models.COMMAND_TYPES.return:
  89. floatingObject = ReturnsManagement.createFloatingCommand();
  90. break;
  91. }
  92. floatingObject.draggable({
  93. drag: function(evt) {
  94. borderMouseDragCommand(function_obj, function_container, evt);
  95. },
  96. stop: function(evt) {
  97. function_container.find('.over_command_drag').each(function( index ) {
  98. $(this).removeClass('over_command_drag');
  99. });
  100. }
  101. }).appendTo("body");
  102. floatingObject.mouseup(function(evt) {
  103. manageCommand(function_obj, function_container, evt, command_type);
  104. });
  105. floatingObject.css("position", "absolute");
  106. mouse_event.type = "mousedown.draggable";
  107. mouse_event.target = floatingObject[0];
  108. floatingObject.css("left", mouse_event.pageX - 15);
  109. floatingObject.css("top", mouse_event.pageY - 15);
  110. floatingObject.trigger(mouse_event);
  111. }
  112. function borderMouseDragCommand (function_obj, function_container, evt) {
  113. function_container.find('.over_command_drag').each(function( index ) {
  114. $(this).removeClass('over_command_drag');
  115. });
  116. var prev = null;
  117. function_container.find('.commands_list_div').each(function( index ) {
  118. prev = $(this);
  119. var objLeft = prev.offset().left;
  120. var objTop = prev.offset().top;
  121. var objRight = objLeft + prev.width();
  122. var objBottom = objTop + prev.height();
  123. if (evt.pageX > objLeft && evt.pageX < objRight && evt.pageY > objTop && evt.pageY < objBottom) {
  124. prev.addClass("over_command_drag");
  125. }
  126. });
  127. function_container.find('.command_container').each(function( index ) {
  128. var obj = $(this);
  129. var objLeft = obj.offset().left;
  130. var objTop = obj.offset().top;
  131. var objRight = objLeft + obj.width();
  132. var objBottom = objTop + obj.height();
  133. if (evt.pageX > objLeft && evt.pageX < objRight && evt.pageY > objTop && evt.pageY < objBottom) {
  134. prev.removeClass('over_command_drag');
  135. obj.addClass("over_command_drag");
  136. return;
  137. }
  138. });
  139. }
  140. // before_after_inside: 1 -> before, 2 -> after, 3 -> inside
  141. export function renderCommand (command, element_reference, before_after_inside, function_obj) {
  142. var createdElement;
  143. switch (command.type) {
  144. case Models.COMMAND_TYPES.comment:
  145. createdElement = CommentsManagement.renderCommand(command, function_obj);
  146. break;
  147. case Models.COMMAND_TYPES.break:
  148. createdElement = BreaksManagement.renderCommand(command, function_obj);
  149. break;
  150. case Models.COMMAND_TYPES.reader:
  151. createdElement = ReadersManagement.renderCommand(command, function_obj);
  152. break;
  153. case Models.COMMAND_TYPES.writer:
  154. createdElement = WritersManagement.renderCommand(command, function_obj);
  155. break;
  156. case Models.COMMAND_TYPES.attribution:
  157. createdElement = AttributionsManagement.renderCommand(command, function_obj);
  158. break;
  159. case Models.COMMAND_TYPES.functioncall:
  160. createdElement = FunctioncallsManagement.renderCommand(command, function_obj);
  161. break;
  162. case Models.COMMAND_TYPES.iftrue:
  163. createdElement = IftruesManagement.renderCommand(command, function_obj);
  164. break;
  165. case Models.COMMAND_TYPES.repeatNtimes:
  166. createdElement = RepeatNtimesManagement.renderCommand(command, function_obj);
  167. break;
  168. case Models.COMMAND_TYPES.whiletrue:
  169. createdElement = WhiletruesManagement.renderCommand(command, function_obj);
  170. break;
  171. case Models.COMMAND_TYPES.dowhiletrue:
  172. createdElement = DowhiletruesManagement.renderCommand(command, function_obj);
  173. break;
  174. case Models.COMMAND_TYPES.switch:
  175. createdElement = SwitchesManagement.renderCommand(command, function_obj);
  176. break;
  177. case Models.COMMAND_TYPES.return:
  178. createdElement = ReturnsManagement.renderCommand(command, function_obj);
  179. break;
  180. }
  181. switch (before_after_inside) {
  182. case 1:
  183. createdElement.insertBefore(element_reference);
  184. break;
  185. case 2:
  186. createdElement.insertAfter(element_reference);
  187. break;
  188. case 3:
  189. element_reference.append(createdElement);
  190. break;
  191. }
  192. createdElement.find('.button_remove_command').mouseover(function() {
  193. createdElement.css({'opacity':'.8'});
  194. });
  195. createdElement.find('.button_remove_command').mouseout(function() {
  196. createdElement.css({'opacity':'1'});
  197. });
  198. }
  199. export function genericCreateCommand (command_type) {
  200. switch (command_type) {
  201. case Models.COMMAND_TYPES.break:
  202. return new Models.Break();
  203. case Models.COMMAND_TYPES.comment:
  204. return new Models.Comment(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.only_value, LocalizedStrings.getUI('text_comment'), null, null, false));
  205. case Models.COMMAND_TYPES.reader:
  206. return new Models.Reader(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.only_variable, null, null, null, false));
  207. case Models.COMMAND_TYPES.writer:
  208. return new Models.Writer([new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true)]);
  209. case Models.COMMAND_TYPES.attribution:
  210. return new Models.Attribution(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.only_variable, null, null, null, false),
  211. []);
  212. case Models.COMMAND_TYPES.functioncall:
  213. return new Models.FunctionCall(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.only_function, null, null, null, false), null);
  214. case Models.COMMAND_TYPES.iftrue:
  215. return new Models.IfTrue(new Models.ConditionalExpression(null), null, null);
  216. case Models.COMMAND_TYPES.repeatNtimes:
  217. return new Models.RepeatNTimes(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.only_variable, null, null, null, false),
  218. new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.only_variable, null, null, null, false),
  219. null, new Models.ConditionalExpression(null), null, null);
  220. case Models.COMMAND_TYPES.whiletrue:
  221. return new Models.WhileTrue(new Models.ConditionalExpression(null), null);
  222. case Models.COMMAND_TYPES.dowhiletrue:
  223. return new Models.DoWhileTrue(new Models.ConditionalExpression(null), null);
  224. case Models.COMMAND_TYPES.switch:
  225. var sc = [new Models.SwitchCase(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true))];
  226. return new Models.Switch(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.variable_and_function, null, null, null, true), sc);
  227. case Models.COMMAND_TYPES.return:
  228. return new Models.Return(new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true));
  229. }
  230. }
  231. function manageCommand (function_obj, function_container, event, command_type) {
  232. $( ".created_element" ).each(function( index ) {
  233. $(this).remove();
  234. });
  235. var el = $(document.elementFromPoint(event.clientX, event.clientY));
  236. console.log('soltou no: ');
  237. console.log(el);
  238. console.log(el.data('fun'));
  239. // Primeiro verificar se ele soltou no espaço da função correta:
  240. var hier = el.parentsUntil(".all_functions");
  241. var esta_correto = false;
  242. var esta_na_div_correta = false;
  243. if (el.hasClass("commands_list_div")) {
  244. esta_na_div_correta = true;
  245. }
  246. for (var i = 0; i < hier.length; i++) {
  247. var temp = $(hier[i]);
  248. if (temp.hasClass("commands_list_div")) {
  249. esta_na_div_correta = true;
  250. }
  251. if (temp.data('fun') == function_obj) {
  252. esta_correto = true;
  253. break;
  254. }
  255. }
  256. if (!esta_correto) {
  257. has_element_created_draged = false;
  258. which_element_is_draged = null;
  259. return;
  260. } else {
  261. if (!esta_na_div_correta) {
  262. has_element_created_draged = false;
  263. which_element_is_draged = null;
  264. return;
  265. }
  266. }
  267. // Agora é descobrir qual o escopo para adicionar o comando:
  268. // Se o elemento clicado possuir o atributo "fun", então, é direto na div dos comandos:
  269. if (typeof el.data('fun') !== 'undefined') {
  270. // Se a lista de comandos estiver vazia, então é o primeiro.
  271. // Portanto, ele deve soltar o elemento obrigatoriamente no objeto vazio
  272. if ((el.data('fun').commands == null) || (el.data('fun').commands.length == 0)) {
  273. // pode adicionar
  274. el.data('fun').commands = [];
  275. var new_cmd = genericCreateCommand(command_type);
  276. el.data('fun').commands.push(new_cmd);
  277. renderCommand(new_cmd, $(function_container).find('.commands_list_div'), 3, function_obj);
  278. } else { // Entra nesse else, caso já existam outros comandos no bloco:
  279. findNearbyCommandToAddInFunctionScope(el, event, $(function_container).find('.commands_list_div'), function_obj, command_type);
  280. }
  281. } else {
  282. console.log("soltou em um comando");
  283. // descobrir em qual comando ele soltou:
  284. var hier_find = el.parentsUntil(".commands_list_div");
  285. var hierarquia_bottom_up = [];
  286. if (typeof el.data('command') !== 'undefined') {
  287. hierarquia_bottom_up.push(el.data('command'));
  288. }
  289. for (var i = 0; i < hier_find.length; i++) {
  290. if (typeof $(hier_find[i]).data('command') !== 'undefined') {
  291. hierarquia_bottom_up.push($(hier_find[i]).data('command'));
  292. }
  293. }
  294. console.log("comando em que soltou: ");
  295. console.log(hierarquia_bottom_up[0]);
  296. console.log("hierarquia de baixo para cima na árvore, de onde ele soltou: ");
  297. for (var i = 0; i < hierarquia_bottom_up.length; i++) {
  298. console.log(hierarquia_bottom_up[i]);
  299. }
  300. // Se for do tipo break, verificar se está no contexto correto:
  301. // Caso não esteja no contexto, apenas retorna sem dar continuidade:
  302. var is_correct_context = false;
  303. if (command_type == Models.COMMAND_TYPES.break) {
  304. for (var i = 0; i < hierarquia_bottom_up.length; i++) {
  305. if ((hierarquia_bottom_up[i].type == Models.COMMAND_TYPES.repeatNtimes)
  306. || (hierarquia_bottom_up[i].type == Models.COMMAND_TYPES.whiletrue)
  307. || (hierarquia_bottom_up[i].type == Models.COMMAND_TYPES.dowhiletrue)
  308. || (hierarquia_bottom_up[i].type == Models.COMMAND_TYPES.switch)) {
  309. is_correct_context = true;
  310. break;
  311. }
  312. }
  313. if (!is_correct_context) {
  314. console.error("Context not allowed to insert BREAK COMMAND!");
  315. return;
  316. }
  317. }
  318. // se a hierarquia possuir apenas um elemento, então está na raiz dos comandos:
  319. if (hierarquia_bottom_up.length == 1) {
  320. console.log('QQ1');
  321. var sub_elemento = false;
  322. for (var i = 0; i < hier_find.length; i++) {
  323. if (typeof $(hier_find[i]).data('command') !== 'undefined') {
  324. console.log('QQ2');
  325. findBeforeOrAfterCommandToAdd(hier_find[i], event, function_obj, command_type);
  326. sub_elemento = true;
  327. break;
  328. }
  329. }
  330. if (!sub_elemento) {
  331. console.log('QQ3');
  332. findBeforeOrAfterCommandToAdd(el[0], event, function_obj, command_type);
  333. }
  334. } else {
  335. console.log('QQ4');
  336. // caso exista mais de um elemento na hierarquia:
  337. if (typeof $(el).data('command') !== 'undefined') {
  338. console.log('QQ5');
  339. console.log("PPP1");
  340. insertCommandInBlockHierar(el[0], event, function_obj, command_type, hier_find, hierarquia_bottom_up);
  341. } else {
  342. console.log('QQ6');
  343. var sub_elemento = false;
  344. for (var i = 0; i < hier_find.length; i++) {
  345. if (typeof $(hier_find[i]).data('command') !== 'undefined') {
  346. console.log('QQ7');
  347. insertCommandInBlockHierar(hier_find[i], event, function_obj, command_type, hier_find, hierarquia_bottom_up);
  348. sub_elemento = true;
  349. break;
  350. }
  351. }
  352. }
  353. }
  354. }
  355. has_element_created_draged = false;
  356. which_element_is_draged = null;
  357. }
  358. function insertCommandInBlockHierar (el, event, function_obj, command_type, hier_dom, hier_obj) {
  359. var el_jq = $(el);
  360. var command_parent = el_jq.data('command');
  361. if ((el_jq.data('command').type == Models.COMMAND_TYPES.repeatNtimes) ||
  362. (el_jq.data('command').type == Models.COMMAND_TYPES.whiletrue) ||
  363. (el_jq.data('command').type == Models.COMMAND_TYPES.dowhiletrue) ||
  364. (el_jq.data('command').type == Models.COMMAND_TYPES.switch) ) {
  365. console.log('QQ17');
  366. if ((el_jq.data('command').type == Models.COMMAND_TYPES.repeatNtimes) ||
  367. (el_jq.data('command').type == Models.COMMAND_TYPES.whiletrue) ||
  368. (el_jq.data('command').type == Models.COMMAND_TYPES.dowhiletrue) ) {
  369. console.log('QQ18');
  370. // Se não tiver outro comando ainda no bloco, só adiciona:
  371. if (command_parent.commands_block == null || command_parent.commands_block.length == 0) {
  372. command_parent.commands_block = [];
  373. var recentComand = genericCreateCommand(command_type);
  374. command_parent.commands_block.push(recentComand);
  375. renderCommand(recentComand, el_jq.find('.block_commands'), 3, function_obj);
  376. } else { // Se já tem algum comando no bloco:
  377. findNearbyCommandToAddInBlockScope(el, event, el, function_obj, command_type, command_parent);
  378. }
  379. } else {
  380. // QUANDO FOR BLOCO DO TIPO IF OU SWITCH/CASE:
  381. addCommandToSwitchCase(event, function_obj, command_type);
  382. }
  383. } else {
  384. console.log('QQ19');
  385. // entra neste bloco, se soltou o comando sobre outro comando dentro de um subbloco:
  386. findBeforeOrAfterCommandToAddInsertBlock(el, event, function_obj, command_type);
  387. }
  388. }
  389. function findNearbyCommandToAddInBlockScope (el, event, node_list_commands, function_obj, command_type, command_parent) {
  390. var all_sub = $(node_list_commands).find('div.command_container');
  391. var menor_distancia = 999999999;
  392. var elemento_menor_distancia = null;
  393. var antes = true;
  394. var t_bot;
  395. var t_top;
  396. // Descobrindo o elemento mais próximo:
  397. for (var i = 0; i < all_sub.length; i++) {
  398. t_top = all_sub[i].getBoundingClientRect().top;
  399. t_bot = all_sub[i].getBoundingClientRect().top + all_sub[i].getBoundingClientRect().height;
  400. if ((t_top - event.clientY) < menor_distancia) {
  401. menor_distancia = event.clientY - t_top;
  402. elemento_menor_distancia = all_sub[i];
  403. }
  404. }
  405. var borda_inferior = elemento_menor_distancia.parentNode.getBoundingClientRect().top + elemento_menor_distancia.parentNode.getBoundingClientRect().height;
  406. // Está mais próximo da borda de baixo, ou seja.. inserir por último:
  407. if ((borda_inferior - event.clientY) < menor_distancia) {
  408. var recentComand = genericCreateCommand(command_type);
  409. command_parent.commands_block.push(recentComand);
  410. //
  411. renderCommand(recentComand, node_list_commands, 3, function_obj);
  412. } else {
  413. var recentComand = genericCreateCommand(command_type);
  414. var index = command_parent.commands_block.indexOf($(elemento_menor_distancia).data('command'));
  415. if (index > -1) {
  416. command_parent.commands_block.splice(index, 0, recentComand);
  417. }
  418. renderCommand(recentComand, elemento_menor_distancia, 1, function_obj);
  419. }
  420. }
  421. function findBeforeOrAfterCommandToAddInsertBlock (el, event, function_obj, command_type) {
  422. var el_jq = $(el);
  423. var command_parent = $(el.parentNode.parentNode).data('command');
  424. var command_target = el_jq.data('command');
  425. var temp_parent = $(el.parentNode.parentNode);
  426. var is_in_else = false;
  427. if (!command_parent) {
  428. command_parent = el_jq.data('command');
  429. temp_parent = el_jq;
  430. var hier = el_jq.parentsUntil(".command_container");
  431. for (var i = 0; i < hier.length; i++) {
  432. var temp = $(hier[i]);
  433. if (typeof temp.data('else') != 'undefined') {
  434. is_in_else = true;
  435. }
  436. if (typeof temp.data('command') != 'undefined') {
  437. command_parent = temp.data('command');
  438. temp_parent = temp;
  439. }
  440. }
  441. }
  442. var hier = el_jq.parentsUntil(".command_container");
  443. for (var i = 0; i < hier.length; i++) {
  444. var temp = $(hier[i]);
  445. if (typeof temp.data('else') != 'undefined') {
  446. is_in_else = true;
  447. }
  448. }
  449. if (command_parent == command_target) {
  450. var hier = el_jq.parentsUntil(".command_container");
  451. for (var i = 0; i < hier.length; i++) {
  452. var temp = $(hier[i]);
  453. if (typeof temp.data('else') !== 'undefined') {
  454. is_in_else = true;
  455. break;
  456. }
  457. }
  458. }
  459. if ((command_parent.type != Models.COMMAND_TYPES.iftrue) && (command_parent.type != Models.COMMAND_TYPES.switch)) {
  460. var hier = temp_parent.parentsUntil(".all_cases_div");
  461. console.log("vou procurar!!");
  462. for (var i = 0; i < hier.length; i++) {
  463. console.log("estou vasculhando...");
  464. var temp = $(hier[i]);
  465. if (typeof temp.data('switchcase') !== 'undefined') {
  466. console.log("encontrei");
  467. command_parent = temp.data('switchcase');
  468. is_in_else = false;
  469. break;
  470. }
  471. }
  472. }
  473. console.log('debugging:');
  474. console.log('el_jq');
  475. console.log(el_jq);
  476. console.log('command_parent');
  477. console.log(command_parent);
  478. console.log('command_target');
  479. console.log(command_target);
  480. var menor_distancia = 999999999;
  481. var antes = true;
  482. var t_bot;
  483. var t_top;
  484. t_top = el.getBoundingClientRect().top;
  485. t_bot = el.getBoundingClientRect().top + el.getBoundingClientRect().height;
  486. var d_top = event.clientY - t_top; // distancia topo
  487. var d_bot = t_bot - event.clientY; // distancia baixo
  488. // Está mais próximo da borda de baixo, ou seja.. inserir por último:
  489. if (d_top < d_bot) {
  490. var recentComand = genericCreateCommand(command_type);
  491. console.log('MMM1');
  492. if (is_in_else) {
  493. console.log('MMM2');
  494. if (command_parent == command_target) {
  495. console.log('MMM3');
  496. if (command_parent.commands_else == null || command_parent.commands_else.length == 0) {
  497. command_parent.commands_else = [];
  498. var recentComand = genericCreateCommand(command_type);
  499. command_parent.commands_else.push(recentComand);
  500. renderCommand(recentComand, el_jq, 3, function_obj);
  501. } else { // Se já tem algum comando no bloco:
  502. findInBlockCorrectPlace(el_jq, event, function_obj, command_type, true);
  503. }
  504. return;
  505. }
  506. console.log('MMM7');
  507. var index = command_parent.commands_else.indexOf(command_target);
  508. if (index > -1) {
  509. command_parent.commands_else.splice(index, 0, recentComand);
  510. }
  511. renderCommand(recentComand, el, 1, function_obj);
  512. } else {
  513. console.log('MMM4');
  514. if (command_parent == command_target) {
  515. console.log('Nxxxx5');
  516. if (command_parent.commands_block == null || command_parent.commands_block.length == 0) {
  517. command_parent.commands_block = [];
  518. console.log('SSS4');
  519. var recentComand = genericCreateCommand(command_type);
  520. command_parent.commands_block.push(recentComand);
  521. renderCommand(recentComand, el_jq, 3, function_obj);
  522. } else {
  523. console.log('SSS5');
  524. findInBlockCorrectPlace(el_jq, event, function_obj, command_type);
  525. }
  526. return;
  527. }
  528. console.log('MMM6');
  529. var index = command_parent.commands_block.indexOf(command_target);
  530. if (index > -1) {
  531. command_parent.commands_block.splice(index, 0, recentComand);
  532. }
  533. renderCommand(recentComand, el, 1, function_obj);
  534. }
  535. } else {
  536. console.log('XXX1');
  537. var recentComand = genericCreateCommand(command_type);
  538. if (is_in_else) {
  539. if (command_parent == command_target) {
  540. console.log('MMM3');
  541. if (command_parent.commands_else == null || command_parent.commands_else.length == 0) {
  542. command_parent.commands_else = [];
  543. console.log('SSS1');
  544. var recentComand = genericCreateCommand(command_type);
  545. command_parent.commands_else.push(recentComand);
  546. renderCommand(recentComand, el_jq, 3, function_obj);
  547. } else { // Se já tem algum comando no bloco:
  548. console.log('SSS2');
  549. findInBlockCorrectPlace(el_jq, event, function_obj, command_type, true);
  550. }
  551. return;
  552. }
  553. console.log('XXX2');
  554. var index = command_parent.commands_else.indexOf(command_target);
  555. if (index > -1) {
  556. command_parent.commands_else.splice((index + 1), 0, recentComand);
  557. }
  558. renderCommand(recentComand, el, 2, function_obj);
  559. } else {
  560. if (command_parent == command_target) {
  561. console.log('Nxxxx78');
  562. if (command_parent.commands_block == null || command_parent.commands_block.length == 0) {
  563. command_parent.commands_block = [];
  564. var recentComand = genericCreateCommand(command_type);
  565. command_parent.commands_block.push(recentComand);
  566. console.log('SSS6');
  567. renderCommand(recentComand, el_jq, 3, function_obj);
  568. } else {
  569. console.log('SSS7');
  570. findInBlockCorrectPlace(el_jq, event, function_obj, command_type);
  571. }
  572. return;
  573. }
  574. console.log('XXX3');
  575. var index = command_parent.commands_block.indexOf(command_target);
  576. if (index > -1) {
  577. command_parent.commands_block.splice((index + 1), 0, recentComand);
  578. }
  579. renderCommand(recentComand, el, 2, function_obj);
  580. }
  581. }
  582. }
  583. function insertCommandInBlock (el, event, function_obj, command_type) {
  584. var el_jq = $(el);
  585. var command_parent = el_jq.data('command');
  586. if ((el_jq.data('command').type == Models.COMMAND_TYPES.repeatNtimes) ||
  587. (el_jq.data('command').type == Models.COMMAND_TYPES.whiletrue) ||
  588. (el_jq.data('command').type == Models.COMMAND_TYPES.dowhiletrue) ) {
  589. // Se não tiver outro comando ainda no bloco, só adiciona:
  590. if (command_parent.commands_block == null || command_parent.commands_block.length == 0) {
  591. command_parent.commands_block = [];
  592. var recentComand = genericCreateCommand(command_type);
  593. command_parent.commands_block.push(recentComand);
  594. renderCommand(recentComand, el_jq.find('.block_commands'), 3, function_obj);
  595. } else { // Se já tem algum comando no bloco:
  596. findInBlockCorrectPlace(el, event, function_obj, command_type);
  597. }
  598. } else if (el_jq.data('command').type == Models.COMMAND_TYPES.iftrue) {
  599. console.log('QQ9');
  600. // no if ou no else?
  601. var correct_div = $(document.elementFromPoint(event.pageX, event.pageY));
  602. var is_in_if = true;
  603. if (correct_div.data('if')) {
  604. is_in_if = true;
  605. } else if (correct_div.data('else')) {
  606. is_in_if = false;
  607. } else {
  608. var hier = correct_div.parentsUntil(".command_container");
  609. for (var i = 0; i < hier.length; i++) {
  610. var temp = $(hier[i]);
  611. if (typeof temp.data('if') !== 'undefined') {
  612. is_in_if = true;
  613. break;
  614. }
  615. if (typeof temp.data('else') !== 'undefined') {
  616. is_in_if = false;
  617. break;
  618. }
  619. }
  620. }
  621. if (is_in_if) {
  622. if (command_parent.commands_block == null || command_parent.commands_block.length == 0) {
  623. command_parent.commands_block = [];
  624. var recentComand = genericCreateCommand(command_type);
  625. command_parent.commands_block.push(recentComand);
  626. renderCommand(recentComand, el_jq.find('.commands_if'), 3, function_obj);
  627. } else { // Se já tem algum comando no bloco:
  628. findInBlockCorrectPlace(el_jq.find('.commands_if'), event, function_obj, command_type);
  629. }
  630. } else {
  631. if (command_parent.commands_else == null || command_parent.commands_else.length == 0) {
  632. command_parent.commands_else = [];
  633. var recentComand = genericCreateCommand(command_type);
  634. command_parent.commands_else.push(recentComand);
  635. renderCommand(recentComand, el_jq.find('.commands_else'), 3, function_obj);
  636. } else { // Se já tem algum comando no bloco:
  637. findInBlockCorrectPlace(el_jq.find('.commands_else'), event, function_obj, command_type, true);
  638. }
  639. }
  640. } else { // é do tipo switch
  641. console.log("está tentando inserir em um switch que está na raiz!");
  642. addCommandToSwitchCase(event, function_obj, command_type);
  643. }
  644. }
  645. function addCommandToSwitchCase (event, function_obj, command_type) {
  646. var el = $(document.elementFromPoint(event.clientX, event.clientY));
  647. var which_case = el.data('switchcase');
  648. var case_div = el;
  649. if (!which_case) {
  650. var hier_find = el.parentsUntil(".all_cases_div");
  651. for (var i = 0; i < hier_find.length; i++) {
  652. if (typeof $(hier_find[i]).data('switchcase') !== 'undefined') {
  653. which_case = $(hier_find[i]).data('switchcase');
  654. case_div = $(hier_find[i]);
  655. break;
  656. }
  657. }
  658. }
  659. if (which_case.commands_block == null || which_case.commands_block.length < 1) {
  660. which_case.commands_block = [];
  661. var recentComand = genericCreateCommand(command_type);
  662. which_case.commands_block.push(recentComand);
  663. renderCommand(recentComand, case_div.find('.case_commands_block'), 3, function_obj);
  664. } else {
  665. findInBlockCorrectPlaceInSwitchCase(which_case, case_div, event, function_obj, command_type);
  666. }
  667. }
  668. function findInBlockCorrectPlaceInSwitchCase (which_case, case_div, event, function_obj, command_type) {
  669. var all_sub = case_div.find('div.command_container');
  670. var menor_distancia = 999999999;
  671. var elemento_menor_distancia = null;
  672. var antes = true;
  673. var t_bot;
  674. var t_top;
  675. // Descobrindo o elemento mais próximo:
  676. for (var i = 0; i < all_sub.length; i++) {
  677. t_top = all_sub[i].getBoundingClientRect().top;
  678. t_bot = all_sub[i].getBoundingClientRect().top + all_sub[i].getBoundingClientRect().height;
  679. if ((t_top - event.clientY) < menor_distancia) {
  680. menor_distancia = event.clientY - t_top;
  681. elemento_menor_distancia = all_sub[i];
  682. }
  683. }
  684. var borda_inferior = elemento_menor_distancia.parentNode.getBoundingClientRect().top + elemento_menor_distancia.parentNode.getBoundingClientRect().height;
  685. // Está mais próximo da borda de baixo, ou seja.. inserir por último:
  686. if ((borda_inferior - event.clientY) < menor_distancia) {
  687. var recentComand = genericCreateCommand(command_type);
  688. which_case.commands_block.push(recentComand);
  689. renderCommand(recentComand, $(case_div.find('.case_commands_block')[0]), 3, function_obj);
  690. } else {
  691. var recentComand = genericCreateCommand(command_type);
  692. var index = which_case.commands_block.indexOf($(elemento_menor_distancia).data('command'));
  693. if (index > -1) {
  694. which_case.commands_block.splice(index, 0, recentComand);
  695. renderCommand(recentComand, elemento_menor_distancia, 1, function_obj);
  696. }
  697. }
  698. }
  699. function findInBlockCorrectPlace (el, event, function_obj, command_type, is_in_else = false) {
  700. var el_jq = $(el);
  701. var all_sub = el_jq.find('div.command_container');
  702. var menor_distancia = 999999999;
  703. var elemento_menor_distancia = null;
  704. var antes = true;
  705. var t_bot;
  706. var t_top;
  707. // Descobrindo o elemento mais próximo:
  708. for (var i = 0; i < all_sub.length; i++) {
  709. t_top = all_sub[i].getBoundingClientRect().top;
  710. t_bot = all_sub[i].getBoundingClientRect().top + all_sub[i].getBoundingClientRect().height;
  711. if ((t_top - event.clientY) < menor_distancia) {
  712. menor_distancia = event.clientY - t_top;
  713. elemento_menor_distancia = all_sub[i];
  714. }
  715. }
  716. var borda_inferior = elemento_menor_distancia.parentNode.getBoundingClientRect().top + elemento_menor_distancia.parentNode.getBoundingClientRect().height;
  717. console.log("menor_distancia: ");
  718. console.log(elemento_menor_distancia);
  719. // Está mais próximo da borda de baixo, ou seja.. inserir por último:
  720. if ((borda_inferior - event.clientY) < menor_distancia) {
  721. console.log('QQ11');
  722. var recentComand = genericCreateCommand(command_type);
  723. var command_parent = el_jq.data('command');
  724. if (is_in_else) {
  725. console.log('QQ15');
  726. command_parent.commands_else.push(recentComand);
  727. console.log('el_jq');
  728. console.log(el_jq);
  729. console.log("$(el_jq.find('.commands_else')[0]):: ");
  730. console.log($(el_jq.find('.commands_else')[0]));
  731. renderCommand(recentComand, el_jq, 3, function_obj);
  732. } else {
  733. console.log('QQ16');
  734. command_parent.commands_block.push(recentComand);
  735. renderCommand(recentComand, $(el_jq.find('.block_commands')[0]), 3, function_obj);
  736. }
  737. } else {
  738. console.log('QQ12');
  739. var recentComand = genericCreateCommand(command_type);
  740. var command_parent = el_jq.data('command');
  741. if (is_in_else) {
  742. var index = command_parent.commands_else.indexOf($(elemento_menor_distancia).data('command'));
  743. if (index > -1) {
  744. command_parent.commands_else.splice(index, 0, recentComand);
  745. renderCommand(recentComand, elemento_menor_distancia, 1, function_obj);
  746. }
  747. } else {
  748. var index = command_parent.commands_block.indexOf($(elemento_menor_distancia).data('command'));
  749. if (index > -1) {
  750. command_parent.commands_block.splice(index, 0, recentComand);
  751. renderCommand(recentComand, elemento_menor_distancia, 1, function_obj);
  752. }
  753. }
  754. }
  755. }
  756. function findBeforeOrAfterCommandToAdd (el, event, function_obj, command_type) {
  757. switch ($(el).data('command').type) {
  758. case Models.COMMAND_TYPES.iftrue:
  759. case Models.COMMAND_TYPES.switch:
  760. case Models.COMMAND_TYPES.repeatNtimes:
  761. case Models.COMMAND_TYPES.whiletrue:
  762. case Models.COMMAND_TYPES.dowhiletrue:
  763. insertCommandInBlock(el, event, function_obj, command_type);
  764. return;
  765. }
  766. var menor_distancia = 999999999;
  767. var antes = true;
  768. var t_bot;
  769. var t_top;
  770. t_top = el.getBoundingClientRect().top;
  771. t_bot = el.getBoundingClientRect().top + el.getBoundingClientRect().height;
  772. var d_top = event.clientY - t_top; // distancia topo
  773. var d_bot = t_bot - event.clientY; // distancia baixo
  774. // Está mais próximo da borda de baixo, ou seja.. inserir por último:
  775. if (d_top < d_bot) {
  776. var recentComand = genericCreateCommand(command_type);
  777. var index = function_obj.commands.indexOf($(el).data('command'));
  778. if (index > -1) {
  779. function_obj.commands.splice(index, 0, recentComand);
  780. }
  781. renderCommand(recentComand, el, 1, function_obj);
  782. } else {
  783. var recentComand = genericCreateCommand(command_type);
  784. var index = function_obj.commands.indexOf($(el).data('command'));
  785. if (index > -1) {
  786. function_obj.commands.splice((index + 1), 0, recentComand);
  787. }
  788. renderCommand(recentComand, el, 2, function_obj);
  789. }
  790. }
  791. function findNearbyCommandToAddInFunctionScope (el, event, node_list_commands, function_obj, command_type) {
  792. var all_sub = $(node_list_commands).find('div.command_container');
  793. var menor_distancia = 999999999;
  794. var elemento_menor_distancia = null;
  795. var antes = true;
  796. var t_bot;
  797. var t_top;
  798. // Descobrindo o elemento mais próximo:
  799. for (var i = 0; i < all_sub.length; i++) {
  800. t_top = all_sub[i].getBoundingClientRect().top;
  801. t_bot = all_sub[i].getBoundingClientRect().top + all_sub[i].getBoundingClientRect().height;
  802. if ((t_top - event.clientY) < menor_distancia) {
  803. menor_distancia = event.clientY - t_top;
  804. elemento_menor_distancia = all_sub[i];
  805. }
  806. }
  807. var borda_inferior = elemento_menor_distancia.parentNode.getBoundingClientRect().top + elemento_menor_distancia.parentNode.getBoundingClientRect().height;
  808. // Está mais próximo da borda de baixo, ou seja.. inserir por último:
  809. if ((borda_inferior - event.clientY) < menor_distancia) {
  810. var recentComand = genericCreateCommand(command_type);
  811. function_obj.commands.push(recentComand);
  812. //
  813. renderCommand(recentComand, node_list_commands, 3, function_obj);
  814. } else {
  815. var recentComand = genericCreateCommand(command_type);
  816. var index = function_obj.commands.indexOf($(elemento_menor_distancia).data('command'));
  817. if (index > -1) {
  818. function_obj.commands.splice(index, 0, recentComand);
  819. }
  820. renderCommand(recentComand, elemento_menor_distancia, 1, function_obj);
  821. }
  822. }