$Statement.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. MWF.xApplication.ScriptEditor.statement = MWF.xApplication.ScriptEditor.statement || {};
  2. MWF.xApplication.ScriptEditor.statement.$Statement = new Class({
  3. Extends: MWF.widget.Common,
  4. Implements: [Options, Events],
  5. options: {
  6. "style": "default"
  7. },
  8. _loadPath: function(){
  9. this.path = "/x_component_ScriptEditor/statement/$Statement/";
  10. this.cssPath = "/x_component_ScriptEditor/statement/$Statement/"+this.options.style+"/css.wcss";
  11. },
  12. initialize: function(node, block, area, options){
  13. this.setOptions(options);
  14. this._loadPath();
  15. this._loadCss();
  16. this.node = node;
  17. this.area = area;
  18. this.block = block;
  19. this.editor = this.area.editor;
  20. this.areaNode = this.area.blockArea;
  21. this.subStatements = [];
  22. this.links = [];
  23. this.mortises = [];
  24. this.inputs = [];
  25. this.selectors = [];
  26. this.mortises = [];
  27. this.init();
  28. },
  29. init: function(){
  30. this.statementType = "operation";
  31. this.parseNodes();
  32. },
  33. reBuild: function(){
  34. if (this.area.currentLink){
  35. this.linkTo(this.area.currentLink);
  36. this.setPosition(this.area.currentLink);
  37. }else{
  38. if (this.topLink){
  39. this.setPosition({
  40. "link": this.topLink,
  41. "toLink": this.topLink.toLink
  42. });
  43. }
  44. }
  45. },
  46. buildStatement: function(){},
  47. load :function(){
  48. this.buildStatement();
  49. if (!this.checkAvailable()) return false;
  50. this.node.setStyles(this.css.node);
  51. if (this.area.currentLink) this.linkTo(this.area.currentLink);
  52. if (this.area.currentLink) this.setPosition(this.area.currentLink);
  53. this.reportLinks();
  54. var drag = new Drag(this.node, {
  55. "snap": "1",
  56. "stopPropagation": true,
  57. "onStart": function(dragging, e){
  58. this.readyDrag();
  59. this.setDrag(e);
  60. }.bind(this)
  61. });
  62. // this.node.addEvent("mousedown", function(e){
  63. // this.readyDrag();
  64. // this.setDrag(e);
  65. // e.stopPropagation();
  66. // }.bind(this));
  67. this.area.currentLink = null;
  68. this.area.setAreaSize();
  69. },
  70. checkAvailable: function(){
  71. if (this.topLink){
  72. if (!this.area.currentLink){
  73. this.destroy();
  74. return false;
  75. }
  76. }else{
  77. this.area.beginStatements.push(this);
  78. }
  79. return true;
  80. },
  81. setDrag: function(e){
  82. this.drag = new Drag.Move(this.node, {
  83. "stopPropagation": true,
  84. "droppables": [this.areaNode],
  85. "onStart": function(dragging){
  86. this.dragStart(dragging);
  87. }.bind(this),
  88. "onEnter": function(dragging, inObj){
  89. }.bind(this),
  90. "onLeave": function(dragging, inObj){
  91. }.bind(this),
  92. "onDrag": function(e){
  93. var links = this.getConnectedLinks();
  94. this.area.checkBlockDrag(this.node, this, links);
  95. }.bind(this),
  96. "onDrop": function(dragging, inObj){
  97. }.bind(this),
  98. "onComplete": function(e, event){
  99. this.dragComplete(event, this.node, this.drag);
  100. if (this.area) this.area.setAreaSize();
  101. }.bind(this),
  102. "onCancel": function(dragging){
  103. this.area.currentLink = null;
  104. this.area.currentMortise = null;
  105. this.reBuild();
  106. }.bind(this)
  107. });
  108. this.drag.start(e);
  109. e.stopPropagation();
  110. },
  111. readyDrag: function(){
  112. //var p = this.node.getPosition(this.node.getOffsetParent());
  113. var p = this.node.getPosition(this.areaNode);
  114. this.node.inject(this.areaNode);
  115. this.node.setStyles({
  116. "z-index": MWF.SES.zIndexPool.apply(),
  117. "position": "absolute",
  118. "left": ""+p.x+"px",
  119. "top": ""+p.y+"px"
  120. });
  121. },
  122. getConnectedLinks: function(){
  123. var links = this.links;
  124. if (this.centerLink){
  125. if (this.centerLink.toLink){
  126. links = links.concat(this.centerLink.toLink.statement.getConnectedLinks());
  127. }
  128. }
  129. if (this.bottomLink){
  130. if (this.bottomLink.toLink){
  131. links = links.concat(this.bottomLink.toLink.statement.getConnectedLinks());
  132. }
  133. }
  134. return links;
  135. },
  136. dragStart: function(dragNode){
  137. //this.readyDrag();
  138. //dragNode.setStyle("z-index", MWF.SES.zIndexPool.apply());
  139. //this.node.setStyles({"position": "absolute"});
  140. },
  141. dragComplete: function(event, dragNode, nodeDrag){
  142. var statement = dragNode.retrieve("statement");
  143. if (!this.editor.moduleAreaNode.isOutside(event)){
  144. this.destroy();
  145. }else{
  146. debugger;
  147. var p0 = dragNode.getPosition(dragNode.getOffsetParent());
  148. var p1 = this.areaNode.getPosition(this.node.getOffsetParent());
  149. if (p0.x-p1.x<10){
  150. var x = 0+p1.x+10;
  151. dragNode.setStyle("left", ""+x+"px");
  152. }
  153. if (p0.y-p1.y<10){
  154. var y = 0+p1.y+10;
  155. dragNode.setStyle("top", ""+y+"px");
  156. }
  157. this.reBuild();
  158. }
  159. },
  160. linkTo: function(link){
  161. if (link.linkType==="up-down"){
  162. link.toLink.linkDown(link.link);
  163. }
  164. if (link.linkType==="down-up"){
  165. link.toLink.linkUp(link.link);
  166. }
  167. if (link.linkType==="up-middle"){
  168. link.toLink.linkMiddle(link.link);
  169. }
  170. if (link.linkType==="middle-up"){
  171. link.toLink.linkUpAround(link.link);
  172. }
  173. },
  174. setPosition: function(link){
  175. this.node.inject(link.toLink.node, "top");
  176. if (link.link.statement.centerLink){
  177. if (link.link.statement.centerLink.toLink){
  178. link.link.statement.centerLink.toLink.statement.node.inject(link.link.statement.centerLink.node, "top");
  179. }
  180. }
  181. var bottomLink = link.link.statement.bottomLink;
  182. while (bottomLink && bottomLink.toLink){
  183. bottomLink.toLink.statement.node.inject(bottomLink.node, "top");
  184. bottomLink = bottomLink.toLink.statement.bottomLink;
  185. }
  186. if (link.link.statement.bottomLink){
  187. if (link.link.statement.bottomLink.toLink){
  188. link.link.statement.bottomLink.toLink.statement.node.inject(link.link.statement.bottomLink.node, "top");
  189. }
  190. }
  191. this.node.setStyles({"position": "static", "top": "auto", "left": "auto"});
  192. link.toLink.statement.notReadyLink();
  193. link.link.statement.notReadyLinkTo();
  194. },
  195. readyLink: function(link){
  196. if (link.toLink.type==="up") this.readyLinkNode = new Element("div", {"styles": this.css.readyLinkNode}).inject(link.toLink.node, "bottom");
  197. if (link.toLink.type==="middle") this.readyLinkNode = new Element("div", {"styles": this.css.readyLinkNode}).inject(link.toLink.node, "top");
  198. if (link.toLink.type==="down") this.readyLinkNode = new Element("div", {"styles": this.css.readyLinkNode}).inject(link.toLink.node, "top");
  199. },
  200. notReadyLink: function(link){
  201. if (this.readyLinkNode) this.readyLinkNode.destroy();
  202. },
  203. readyLinkTo: function(link){
  204. if (link.link.type==="up") this.readyLinkToNode = new Element("div", {"styles": this.css.readyLinkToNode}).inject(link.link.node, "bottom");
  205. if (link.link.type==="middle") this.readyLinkToNode = new Element("div", {"styles": this.css.readyLinkToNode}).inject(link.link.node, "top");
  206. if (link.link.type==="down") this.readyLinkToNode = new Element("div", {"styles": this.css.readyLinkToNode}).inject(link.link.node, "top");
  207. },
  208. notReadyLinkTo: function(link){
  209. if (this.readyLinkToNode) this.readyLinkToNode.destroy();
  210. },
  211. normal: function(){
  212. if (this.tableNode){
  213. this.tableNode.setStyle("height", "auto");
  214. }
  215. },
  216. destroy: function(){
  217. if (this.topLink){
  218. if (this.topLink.toLink){
  219. this.topLink.toLink.toLink = null;
  220. }
  221. }
  222. if (this.centerLink){
  223. if (this.centerLink.toLink){
  224. this.centerLink.toLink.statement.destroy();
  225. }
  226. }
  227. if (this.bottomLink){
  228. if (this.bottomLink.toLink){
  229. this.bottomLink.toLink.statement.destroy();
  230. }
  231. }
  232. this.links.each(function(link){
  233. this.area.links.erase(link);
  234. }.bind(this));
  235. this.mortises.each(function(mortise){
  236. this.area.mortises.erase(mortise);
  237. }.bind(this));
  238. this.area.statementNodes.erase(this.node);
  239. this.area.statements.erase(this);
  240. this.area.clearCurrentLink();
  241. this.node.destroy();
  242. if (this.area) this.area.setAreaSize();
  243. MWF.release(this);
  244. },
  245. setLinkStyle: function(){}
  246. });
  247. MWF.xApplication.ScriptEditor.statement.$Statement.$Operation = new Class({
  248. Extends: MWF.xApplication.ScriptEditor.statement.$Statement,
  249. parseNodes: function(){
  250. this.contentNode = this.node.getFirst();
  251. this.table = this.contentNode.getElement("table");
  252. this.createLinks();
  253. this.loadContents();
  254. },
  255. createLinks: function(){
  256. this.downLinkStatementNode = new Element("div", {"styles": this.css.linkStatementNode_down}).inject(this.node);
  257. this.upLinkStatementNode = new Element("div", {"styles": this.css.linkStatementNode_up}).inject(this.node, "top");
  258. this.downLink = new MWF.xApplication.ScriptEditor.statement.Link(this, "down", this.downLinkStatementNode);
  259. this.upLink = new MWF.xApplication.ScriptEditor.statement.Link(this, "up", this.upLinkStatementNode);
  260. this.links.push(this.upLink);
  261. this.links.push(this.downLink);
  262. this.topLink = this.upLink;
  263. this.bottomLink = this.downLink;
  264. },
  265. loadContents: function(){
  266. this.loadInputs();
  267. this.loadSelectors();
  268. this.loadMortises();
  269. this.loadInputMortises();
  270. },
  271. loadInputs: function(){
  272. var inputs = this.node.getElements(".MWFBlockContent_input");
  273. inputs.each(function(input){
  274. var inputNode = input.getElement("input");
  275. inputNode.set("readonly", false);
  276. inputNode.setStyle("max-width", "none");
  277. inputNode.addEvents({
  278. "mousedown": function(e){e.stopPropagation();},
  279. "keyup": function(e){
  280. var width = MWF.getTextSize(this.get("value")).x;
  281. this.setStyle("width", ""+width+"px");
  282. e.stopPropagation();
  283. }
  284. });
  285. this.inputs.push(input.getFirst());
  286. }.bind(this));
  287. },
  288. loadSelectors: function(){
  289. var selectors = this.node.getElements(".MWFBlockContent_select");
  290. selectors.each(function(selector){
  291. selector.getFirst().addEvents({"mousedown": function(e){e.stopPropagation();}.bind(this)});
  292. this.selectors.push(selector.getFirst());
  293. }.bind(this));
  294. },
  295. loadMortises: function(){
  296. var mortises = this.node.getElements(".MWFBlockContent_mortise");
  297. mortises.each(function(mortiseNode){
  298. var content = this.block.data.contents[mortiseNode.cellIndex];
  299. var mortise = new MWF.xApplication.ScriptEditor.statement.Mortise(this, mortiseNode, content.tenonTypes, mortiseNode.getFirst());
  300. this.mortises.push(mortise);
  301. this.area.mortises.push(mortise);
  302. }.bind(this));
  303. },
  304. loadInputMortises: function(){
  305. var inputMortises = this.node.getElements(".MWFBlockContent_inputMortise");
  306. inputMortises.each(function(inputMortiseNode){
  307. var inputNode = inputMortiseNode.getElement("input");
  308. inputNode.set("readonly", false);
  309. inputNode.setStyle("max-width", "none");
  310. inputNode.addEvents({
  311. "mousedown": function(e){e.stopPropagation();},
  312. "keyup": function(e){
  313. var width = MWF.getTextSize(this.get("value")).x;
  314. this.setStyle("width", ""+width+"px");
  315. e.stopPropagation();
  316. }
  317. });
  318. var content = this.block.data.contents[inputMortiseNode.cellIndex];
  319. var inputMortise = new MWF.xApplication.ScriptEditor.statement.Mortise(this, inputMortiseNode, content.tenonTypes, inputMortiseNode.getFirst());
  320. this.mortises.push(inputMortise);
  321. this.area.mortises.push(inputMortise);
  322. }.bind(this));
  323. },
  324. buildStatement: function(){},
  325. reportLinks: function(){
  326. this.area.links.include(this.downLink.rePosition());
  327. this.area.links.include(this.upLink.rePosition());
  328. }
  329. });
  330. MWF.xApplication.ScriptEditor.statement.$Statement.$Expression = new Class({
  331. Extends: MWF.xApplication.ScriptEditor.statement.$Statement.$Operation,
  332. createLinks: function(){
  333. this.tenon = this.node;
  334. },
  335. reBuild: function(){
  336. debugger;
  337. if (this.area.currentMortise){
  338. this.tenonTo(this.area.currentMortise);
  339. this.setPosition(this.area.currentMortise);
  340. }else{
  341. if (this.toMortise){
  342. this.tenonTo(this.toMortise);
  343. this.setPosition(this.toMortise);
  344. }else{
  345. this.destroy();
  346. }
  347. }
  348. },
  349. load :function(){
  350. this.buildStatement();
  351. if (!this.checkAvailable()) return false;
  352. this.node.setStyles(this.css.node);
  353. if (this.area.currentMortise){
  354. this.tenonTo(this.area.currentMortise);
  355. this.setPosition(this.area.currentMortise);
  356. }
  357. this.node.addEvent("mousedown", function(e){
  358. this.readyDrag();
  359. this.setDrag(e);
  360. e.stopPropagation();
  361. }.bind(this));
  362. this.area.currentMortise = null;
  363. },
  364. checkAvailable: function(){
  365. debugger;
  366. if (!this.area.currentMortise){
  367. this.destroy();
  368. return false;
  369. }
  370. return true;
  371. },
  372. tenonTo: function(mortise){
  373. if (this.toMortise){
  374. this.toMortise.tenonStatement = null;
  375. }
  376. mortise.tenonStatement = this;
  377. this.toMortise = mortise;
  378. },
  379. setPosition: function(mortise){
  380. mortise.unshine();
  381. mortise.tenon();
  382. },
  383. readyDrag: function(){
  384. this.toMortise.split();
  385. },
  386. });
  387. MWF.xApplication.ScriptEditor.statement.$Statement.$Enumerate = new Class({
  388. Extends: MWF.xApplication.ScriptEditor.statement.$Statement.$Operation
  389. });
  390. MWF.xApplication.ScriptEditor.statement.$Statement.$Top = new Class({
  391. Extends: MWF.xApplication.ScriptEditor.statement.$Statement.$Operation,
  392. parseNodes: function(){
  393. var divs = this.node.getElements("div");
  394. this.topNode = divs[0];
  395. this.contentNode = divs[1];
  396. this.table = this.contentNode.getElement("table");
  397. this.createLinks();
  398. this.loadContents();
  399. },
  400. createLinks: function(){
  401. this.linkStatementNode = new Element("div", {"styles": this.css.linkStatementNode_down}).inject(this.node);
  402. this.link = new MWF.xApplication.ScriptEditor.statement.Link(this, "down", this.linkStatementNode);
  403. this.links.push(this.link);
  404. this.topLink = null;
  405. this.bottomLink = this.link;
  406. },
  407. reportLinks: function(){
  408. this.area.links.include(this.link.rePosition());
  409. },
  410. readyLink: function(link){
  411. this.readyLinkNode = new Element("div", {"styles": this.css.readyLinkNode}).inject(this.linkStatementNode, "top");
  412. },
  413. readyLinkTo: function(link){
  414. this.readyLinkToNode = new Element("div", {"styles": this.css.readyLinkToNode}).inject(this.linkStatementNode, "top");
  415. }
  416. });
  417. MWF.xApplication.ScriptEditor.statement.$Statement.$Around = new Class({
  418. Extends: MWF.xApplication.ScriptEditor.statement.$Statement.$Operation,
  419. parseNodes: function(){
  420. this.beginNode = this.node.getFirst();
  421. this.beginContentNode = this.beginNode.getFirst();
  422. this.table = this.beginContentNode.getElement("table");
  423. this.contentNode = this.beginContentNode;
  424. this.middleNode = this.beginNode.getNext();
  425. this.tableNode = this.middleNode.getElement("table");
  426. var tds = this.tableNode.getElements("td");
  427. this.middleLeftNode = tds[0];
  428. this.middleRightNode = tds[1];
  429. this.subContentNode = this.middleRightNode.getFirst();
  430. this.endNode = this.middleNode.getNext();
  431. this.endContentNode = this.endNode.getFirst();
  432. this.conditionNode = this.beginContentNode.getFirst().getNext();
  433. this.createLinks();
  434. this.loadContents();
  435. },
  436. createLinks: function(){
  437. this.beginUplinkStatementNode = new Element("div", {"styles": this.css.linkStatementNode_up}).inject(this.beginNode, "before");
  438. this.middlelinkStatementNode = new Element("div", {"styles": this.css.linkStatementNode_down}).inject(this.subContentNode);
  439. this.endDownlinkStatementNode = new Element("div", {"styles": this.css.linkStatementNode_down}).inject(this.endNode, "after");
  440. this.upLink = new MWF.xApplication.ScriptEditor.statement.Link(this, "up", this.beginUplinkStatementNode);
  441. this.middleLink = new MWF.xApplication.ScriptEditor.statement.Link(this, "middle", this.middlelinkStatementNode);
  442. this.downLink = new MWF.xApplication.ScriptEditor.statement.Link(this, "down", this.endDownlinkStatementNode);
  443. this.links.push(this.upLink);
  444. this.links.push(this.middleLink);
  445. this.links.push(this.downLink);
  446. this.topLink = this.upLink;
  447. this.centerLink = this.middleLink;
  448. this.bottomLink = this.downLink;
  449. },
  450. reportLinks: function(){
  451. this.area.links.include(this.upLink.rePosition());
  452. this.area.links.include(this.middleLink.rePosition());
  453. this.area.links.include(this.downLink.rePosition());
  454. },
  455. readyLink: function(link){
  456. if (link.linkType==="up-down" || link.linkType==="up-middle"){
  457. this.readyLinkNode = new Element("div", {"styles": this.css.readyLinkNode}).inject(link.toLink.node, "top");
  458. }
  459. if (link.linkType==="down-up" || link.linkType==="middle-up"){
  460. this.readyLinkNode = new Element("div", {"styles": this.css.readyLinkNode}).inject(link.toLink.node, "bottom");
  461. }
  462. },
  463. readyLinkTo: function(link){
  464. if (link.linkType==="up-down" || link.linkType==="up-middle"){
  465. this.readyLinkToNode = new Element("div", {"styles": this.css.readyLinkToNode}).inject(link.link.node, "bottom");
  466. if (link.link.statement.centerLink && !link.link.statement.centerLink.toLink){
  467. if (link.toLink.toLink){
  468. if (link.toLink.toLink.statement!==this){
  469. var height = link.toLink.toLink.statement.node.getSize().y;
  470. this.tableNode.setStyle("height", ""+height+"px");
  471. }
  472. }
  473. }
  474. }
  475. },
  476. notReadyLinkTo: function(link){
  477. if (this.readyLinkToNode) this.readyLinkToNode.destroy();
  478. if (link){
  479. if (link.link.type==="middle"){
  480. this.tableNode.setStyle("height", "auto");
  481. }
  482. }else{
  483. this.tableNode.setStyle("height", "auto");
  484. }
  485. },
  486. getStatementGroupHeight: function(group){
  487. var first = group[0];
  488. var last = group[group.length-1];
  489. var topP = first.node.getPosition(this.areaNode);
  490. var bottomP = last.node.getPosition(this.areaNode);
  491. var bottomSize = last.node.getSize();
  492. return bottomP.y+bottomSize.y-topP.y
  493. }
  494. });
  495. MWF.xApplication.ScriptEditor.statement.$Statement.$EnumerateAround = new Class({
  496. Extends: MWF.xApplication.ScriptEditor.statement.$Statement.$Around
  497. });