PageRenderTime 68ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/js/seepy.js

https://bitbucket.org/jdpalmer/bluepy
JavaScript | 510 lines | 413 code | 74 blank | 23 comment | 73 complexity | afe56a5670fd91a2102e5c345a7d1261 MD5 | raw file
  1. (function() {
  2. //*************
  3. //***HELPERS***
  4. //*************
  5. $.event.props = $.event.props.join('|').replace('layerX|layerY|', '').split('|');
  6. //Global identifier
  7. var global_id = 0;
  8. //String helper functions for parseCode
  9. if (typeof String.prototype.startsWith != 'function') {
  10. String.prototype.startsWith = function (str){
  11. return this.indexOf(str) == 0;
  12. };
  13. String.prototype.after = function (str){
  14. return this.replace(str, "");
  15. };
  16. String.prototype.between = function (start, end){
  17. var startI = this.indexOf(start)+start.length;
  18. var endI = this.indexOf(end);
  19. return this.substring(startI, endI);
  20. };
  21. String.prototype.until = function (end){
  22. return this.substr();
  23. };
  24. String.prototype.contains = function (str){
  25. if(this.indexOf(str) != -1) {
  26. return true;
  27. }
  28. else {
  29. return false;
  30. }
  31. };
  32. }
  33. //************
  34. //***MODELS***
  35. //************
  36. Class = Backbone.Model.extend({
  37. defaults: function() {
  38. return {
  39. name: "New Class",
  40. code: "",
  41. rendered: false
  42. }
  43. },
  44. renameClass : function(new_name) {
  45. var code = this.get('code');
  46. var myData = code.split('\n');
  47. for(var i = 0; i < myData.length; i++) {
  48. if(myData[i].startsWith("class ")) {
  49. myData[i] = myData[i].replace(this.get('name'), new_name);
  50. break;
  51. }
  52. }
  53. var newCode = myData.join("\n");
  54. this.set('name', new_name);
  55. this.set('code', newCode);
  56. editor.setValue(this.get('code'));
  57. currViewing = this.cid;
  58. },
  59. newVariable : function(new_model) {
  60. var code = this.get('code');
  61. var myData = code.split('\n');
  62. var initLine = -1;
  63. for(var i = 0; i < myData.length; i++) {
  64. if(myData[i].startsWith("\tdef __init__")) initLine = i++;
  65. }
  66. initLine++;
  67. console.log(initLine);
  68. while(myData[initLine].startsWith("\t\t")) {
  69. initLine++;
  70. }
  71. var newLine = new Array();
  72. newLine.push("\t\tself."+new_model.get('name')+" = "+new_model.get('name'));
  73. myData = myData.slice(0, initLine).concat(newLine).concat(myData.slice(initLine, myData.length+1));
  74. var newCode = myData.join("\n");
  75. this.parseCode(newCode);
  76. editor.setValue(this.get('code'));
  77. currViewing = this.cid;
  78. },
  79. renameVariable : function(model, new_name) {
  80. var code = this.get('code');
  81. var myData = code.split('\n');
  82. var line = myData[model.get('line')];
  83. myData[model.get('line')] = line.replace(model.get('name'), new_name);
  84. var newCode = myData.join("\n");
  85. model.set('name', new_name);
  86. this.set('code', newCode);
  87. editor.setValue(this.get('code'));
  88. currViewing = this.cid;
  89. },
  90. deleteVariable : function(model) {
  91. //console.log("Removing variable '"+model.get('name')+"' on line "+model.get('line'));
  92. var code = this.get('code');
  93. var myData = code.split('\n');
  94. myData = myData.slice(0, model.get('line')).concat(myData.slice(model.get('line')+1, myData.length+1));
  95. //myData[model.get('line')-1] = myData[model.get('line')+1].replace("\n", "");
  96. var newCode = myData.join("\n");
  97. this.parseCode(newCode);
  98. editor.setValue(this.get('code'));
  99. currViewing = this.cid;
  100. },
  101. newFunction : function(new_model) {
  102. var code = this.get('code');
  103. var myData = code.split('\n');
  104. myData.push("\n\tdef "+new_model.get('name')+"("+new_model.get('parameters').join(", ")+"):\n");
  105. var newCode = myData.join("\n");
  106. this.parseCode(newCode);
  107. editor.setValue(this.get('code'));
  108. currViewing = this.cid;
  109. },
  110. editFunction : function(old_model, new_model) {
  111. var code = this.get('code');
  112. var myData = code.split('\n');
  113. var line = myData[old_model.get('line')];
  114. myData[old_model.get('line')] = line.replace(old_model.get('name'), new_model.get('name'));
  115. line = myData[old_model.get('line')];
  116. myData[old_model.get('line')] = line.replace("("+old_model.get('parameters').join(", ")+")", "("+new_model.get('parameters').join(", ")+")");
  117. var newCode = myData.join("\n");
  118. old_model.set('name', new_model.get('name'));
  119. this.set('code', newCode);
  120. editor.setValue(this.get('code'));
  121. currViewing = this.cid;
  122. },
  123. deleteFunction : function(model) {
  124. //console.log("Removing function '"+model.get('name')+"' on line "+model.get('line'));
  125. var code = this.get('code');
  126. var myData = code.split('\n');
  127. var funcLines = 1;
  128. for(var i = model.get('line')+1; i < myData.length; i++) {
  129. if(myData[i].startsWith("\t\t")) {
  130. funcLines++;
  131. }
  132. else {
  133. break;
  134. }
  135. }
  136. myData = myData.slice(0, model.get('line')).concat(myData.slice(model.get('line')+funcLines+1, myData.length+1));
  137. var newCode = myData.join("\n");
  138. this.parseCode(newCode);
  139. editor.setValue(this.get('code'));
  140. currViewing = this.cid;
  141. },
  142. parseCode : function(data) {
  143. if(this.get('code') == data) return;
  144. var i = 0;
  145. var myData = data.split('\n');
  146. var className = "New Class";
  147. var functions = new Array;
  148. var variables = new Array;
  149. for(i = 0; i < myData.length; i++) {
  150. var line = myData[i];
  151. if(line.startsWith("class") && line.contains(":")) {
  152. className = line.between("class ", ":");
  153. }
  154. else if(line.startsWith("\tdef") && line.contains("(") && line.contains(")") && line.contains(":")) {
  155. var funcName = line.between("\tdef ", "(");
  156. var perm = "+";
  157. if(funcName.startsWith("_")) {
  158. perm = "-";
  159. }
  160. var funcParams = line.between("(", ")").replace(" ", "").split(",");
  161. functions.push({name: funcName, parameters: funcParams, permission: perm, line: i++});
  162. if(funcName == "__init__") {
  163. line = myData[i];
  164. while(!line.startsWith("\tdef")) {
  165. if(line.startsWith("\t\tself.") && line.contains("=")) {
  166. var varName = line.between("\t\tself.", " =");
  167. variables.push({name: varName, line: i});
  168. }
  169. i++;
  170. line = myData[i];
  171. }
  172. i--;
  173. }
  174. }
  175. }
  176. this.functions = new Functions(functions);
  177. this.variables = new Variables(variables);
  178. this.inheritances = new Inheritances;
  179. this.set({name: className, code: data});
  180. return this;
  181. }
  182. });
  183. Variable = Backbone.Model.extend({
  184. defaults : function() {
  185. return {
  186. name : "newVar"
  187. }
  188. },
  189. initialize: function() {
  190. this.set('id', this.cid);
  191. //console.log("New Variable: "+this.get('name')+" "+this.get("id"));
  192. }
  193. });
  194. FunctionM = Backbone.Model.extend({
  195. defaults : function() {
  196. return {
  197. name: "newFunc",
  198. permission: "+"
  199. }
  200. },
  201. initialize: function() {
  202. this.set('id', this.cid);
  203. //console.log("New Function: "+this.get('name')+" "+this.get("id"));
  204. this.parameters = new Array;
  205. }
  206. });
  207. Inheritance = Backbone.Model.extend({
  208. defaults : function() {
  209. return {
  210. }
  211. }
  212. });
  213. //*****************
  214. //***COLLECTIONS***
  215. //*****************
  216. Classes = Backbone.Collection.extend({
  217. model : Class
  218. });
  219. Variables = Backbone.Collection.extend({
  220. model : Variable
  221. });
  222. Functions = Backbone.Collection.extend({
  223. model : FunctionM
  224. });
  225. Parameters = Backbone.Collection.extend({
  226. model : Variable
  227. });
  228. Inheritances = Backbone.Collection.extend({
  229. model : Inheritance
  230. });
  231. //***********
  232. //***VIEWS***
  233. //***********
  234. ClassesView = Backbone.View.extend({
  235. initialize: function() {
  236. this.collection.bind('reset', this.render, this);
  237. this.collection.bind('add', this.render, this);
  238. this.collection.bind('remove', this.render, this);
  239. this.render();
  240. },
  241. render: function() {
  242. this.collection.each(function(aClass) {
  243. if(!aClass.get('rendered')) {
  244. this.renderClass(aClass);
  245. aClass.set({rendered: true});
  246. }
  247. }, this);
  248. },
  249. renderClass: function(aClass) {
  250. var classView = new ClassView({model: aClass});
  251. this.$el.append(classView.render().el);
  252. }
  253. });
  254. ClassView = Backbone.View.extend({
  255. tagName: "div",
  256. className: "class",
  257. initialize: function() {
  258. this.id = this.model.cid;
  259. this.$el.attr('id', this.id);
  260. this.model.bind('change', this.render, this);
  261. },
  262. render: function() {
  263. var _this = this;
  264. var template = _.template( $("#classTemplate").html(), this.model.toJSON());
  265. this.el.innerHTML = template;
  266. this.$el
  267. .draggable({stack: ".class", containment: "#class_container"})
  268. .click(function() {
  269. var cid = $(this).attr('id');
  270. var bClass = classes.getByCid(cid);
  271. if(!(currViewing == cid)) {
  272. editor.setValue(bClass.get('code'));
  273. currViewing = bClass.cid;
  274. }
  275. })
  276. .contextMenu({menu: 'classMenu'}, function(action, el, pos) {
  277. var id = $(el).attr('id');
  278. var model = _this.model;
  279. if(action == "rename_class") {
  280. var answer = prompt("Rename class", model.get('name'));
  281. if(answer) _this.model.renameClass(answer);
  282. }
  283. else if(action == "delete_class") {
  284. var answer = confirm("Are you sure you want to delete class '"+model.get('name')+"'?");
  285. if(answer) {
  286. $("#"+_this.model.cid).remove();
  287. classes.remove(_this.model);
  288. editor.setValue("");
  289. }
  290. }
  291. else if(action == "new_variable") {
  292. var answer = prompt("New variable", "");
  293. if(answer) _this.model.newVariable(new Variable({name: answer}));
  294. }
  295. else if(action == "new_function") {
  296. var name = prompt("Function name", "");
  297. if(name) {
  298. var parameters = prompt("Function parameters", "")
  299. parameters = parameters.replace("(", "").replace(")", "").replace(" ", "").split(",");
  300. }
  301. if(name) _this.model.newFunction(new FunctionM({name: name, parameters: parameters}));
  302. }
  303. });
  304. //Variables
  305. var varsView = new VariablesView({collection: this.model.variables, el: this.$el.find(".var_list")});
  306. varsView.render();
  307. //Context Menu
  308. _this.$el.find(".variable").contextMenu({menu: 'variableMenu'}, function(action, el, pos) {
  309. var id = $(el).attr('id');
  310. var model = _this.model.variables.get(id);
  311. if(action == "rename_variable") {
  312. var answer = prompt("Rename variable", model.get('name'));
  313. if(answer) _this.model.renameVariable(model, answer);
  314. }
  315. else if(action == "delete_variable") {
  316. var answer = confirm("Are you sure you want to delete variable '"+model.get('name')+"'?");
  317. if(answer) _this.model.deleteVariable(model);;
  318. }
  319. else if(action == "new_variable") {
  320. var answer = prompt("New variable", "");
  321. if(answer) _this.model.newVariable(new Variable({name: answer}));
  322. }
  323. });
  324. //Functions
  325. var funcsView = new FunctionsView({collection: this.model.functions, el: this.$el.find(".func_list")});
  326. funcsView.render();
  327. //Context Menu
  328. _this.$el.find(".function").contextMenu({menu: 'functionMenu'}, function(action, el, pos) {
  329. var id = $(el).attr('id');
  330. var model = _this.model.functions.get(id);
  331. if(action == "edit_function") {
  332. var name = prompt("Function name", model.get('name'));
  333. if(name) {
  334. var parameters = prompt("Function parameters", model.get('parameters').join(", "));
  335. parameters = parameters.replace("(", "").replace(")", "").replace(" ", "").split(",");
  336. }
  337. if(name) _this.model.editFunction(model, new FunctionM({name: name, parameters: parameters}));
  338. }
  339. else if(action == "delete_function") {
  340. var model = _this.model.functions.get(id);
  341. var answer = confirm("Are you sure you want to delete function '"+model.get('name')+"'?");
  342. if(answer) _this.model.deleteFunction(model);
  343. }
  344. else if(action == "new_function") {
  345. var name = prompt("Function name", "");
  346. if(name) {
  347. var parameters = prompt("Function parameters", "")
  348. parameters = parameters.replace("(", "").replace(")", "").replace(" ", "").split(",");
  349. }
  350. if(name) _this.model.newFunction(new FunctionM({name: name, parameters: parameters}));
  351. }
  352. });
  353. return this;
  354. }
  355. });
  356. VariablesView = Backbone.View.extend({
  357. initialize: function() {
  358. this.collection.bind('reset', this.render, this);
  359. this.collection.bind('add', this.render, this);
  360. this.collection.bind('remove', this.render, this);
  361. },
  362. render: function() {
  363. var _this = this;
  364. _this.$el.empty();
  365. if(_this.collection.size() <= 0) {
  366. this.el.innerHTML += "<div class='plain'>No Variables</div>";
  367. }
  368. _this.collection.each(function(variable) {
  369. var v = new VariableView({model: variable, el: _this.el});
  370. v.render();
  371. });
  372. }
  373. });
  374. VariableView = Backbone.View.extend({
  375. initialize: function() {
  376. this.model.bind('change', this.render, this);
  377. },
  378. render: function() {
  379. var template = _.template( $("#variableTemplate").html(), this.model.toJSON());
  380. this.el.innerHTML += template;
  381. return this;
  382. }
  383. });
  384. FunctionsView = Backbone.View.extend({
  385. initialize: function() {
  386. this.collection.bind('reset', this.render, this);
  387. this.collection.bind('add', this.render, this);
  388. this.collection.bind('remove', this.render, this);
  389. },
  390. render: function() {
  391. var _this = this;
  392. _this.$el.empty();
  393. if(_this.collection.size() <= 0) {
  394. this.el.innerHTML += "<div class='plain'>No Functions</div>";
  395. }
  396. _this.collection.each(function(func) {
  397. var f = new FunctionView({model: func, el: _this.el});
  398. f.render();
  399. });
  400. }
  401. });
  402. FunctionView = Backbone.View.extend({
  403. initialize: function() {
  404. this.model.bind('change', this.render, this);
  405. },
  406. render: function() {
  407. var template = _.template( $("#functionTemplate").html(), this.model.toJSON());
  408. this.el.innerHTML += template;
  409. return this;
  410. }
  411. });
  412. ParametersView = Backbone.View.extend({
  413. initialize: function() {
  414. this.collection.bind('reset', this.render, this);
  415. this.collection.bind('add', this.render, this);
  416. var that = this;
  417. },
  418. render: function() {
  419. var that = this;
  420. this.collection.each(function(param) {
  421. var p = new ParameterView({model: param, el: $(".param_list") });
  422. p.render();
  423. });
  424. }
  425. });
  426. ParameterView = Backbone.View.extend({
  427. initialize: function() {
  428. this.model.bind('change', this.render, this);
  429. },
  430. render: function() {
  431. var template = _.template( $("#parameterTemplate").html(), this.model.toJSON());
  432. this.el.innerHTML += template;
  433. return this;
  434. }
  435. });
  436. }).call(this);