DocumentHistory.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. MWF.xApplication.process.Xform.widget = MWF.xApplication.process.Xform.widget || {};
  2. MWF.xApplication.process.Xform.widget.DocumentHistory = new Class({
  3. Implements: [Options, Events],
  4. options: {
  5. "speed": 1,
  6. "fxTime": 500,
  7. "inforTime": 2000
  8. },
  9. initialize: function(documentEditor, options){
  10. this.setOptions(options);
  11. this.documentEditor = documentEditor;
  12. this.css = this.documentEditor.css;
  13. },
  14. load: function(callback){
  15. this.getHistroyDocumentList(function(){
  16. if (this.historyDocumentList && this.historyDocumentList.length){
  17. this.getHistoryDataList(function(){
  18. this.createHistoryToolbar();
  19. this.createHistoryListNode();
  20. this.documentEditor.options.pageShow = "single";
  21. this.documentEditor.resetData();
  22. this.beginDiffHistory(function(){
  23. this.loadHistoryToolbar();
  24. this.loadHistoryList();
  25. if (callback) callback();
  26. }.bind(this));
  27. }.bind(this));
  28. }
  29. }.bind(this));
  30. },
  31. createHistoryToolbar: function(){
  32. this.documentEditor.documentToolbarNode = this.documentEditor.toolbarNode;
  33. this.toolbarNode = this.documentEditor.toolbarNode.clone(true);
  34. this.toolbarNode.inject(this.documentEditor.toolbarNode, "after");
  35. this.documentEditor.toolbarNode = this.toolbarNode;
  36. this.documentEditor.documentToolbarNode.hide();
  37. this.toolbarNode.empty();
  38. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.hide();
  39. },
  40. loadHistoryToolbar: function(){
  41. var html = "<span MWFnodetype=\"MWFToolBarButton\" MWFButtonImage=\"/x_component_process_Xform/$Form/default/documenteditoricon/play.png\" title=\""+MWF.xApplication.process.Xform.LP.documentHistory.play+"\" MWFButtonAction=\"play\"></span>";
  42. html += "<span MWFnodetype=\"MWFToolBarButton\" MWFButtonImage=\"/x_component_process_Xform/$Form/default/documenteditoricon/pause.png\" title=\""+MWF.xApplication.process.Xform.LP.documentHistory.pause+"\" MWFButtonAction=\"pause\"></span>";
  43. html += "<span MWFnodetype=\"MWFToolBarButton\" MWFButtonImage=\"/x_component_process_Xform/$Form/default/documenteditoricon/stop.png\" title=\""+MWF.xApplication.process.Xform.LP.documentHistory.stop+"\" MWFButtonAction=\"stopPlay\"></span>";
  44. html += "<span MWFnodetype=\"MWFToolBarSeparator\"></span>";
  45. html += "<span MWFnodetype=\"MWFToolBarButton\" MWFButtonImage=\"/x_component_process_Xform/$Form/default/documenteditoricon/prev.png\" title=\""+MWF.xApplication.process.Xform.LP.documentHistory.prev+"\" MWFButtonAction=\"prev\"></span>";
  46. html += "<span MWFnodetype=\"MWFToolBarButton\" MWFButtonImage=\"/x_component_process_Xform/$Form/default/documenteditoricon/next.png\" title=\""+MWF.xApplication.process.Xform.LP.documentHistory.next+"\" MWFButtonAction=\"next\"></span>";
  47. html += "<span MWFnodetype=\"MWFToolBarSeparator\"></span>";
  48. html += "<span MWFnodetype=\"MWFToolBarButton\" MWFButtonImage=\"/x_component_process_Xform/$Form/default/documenteditoricon/exit.png\" title=\""+MWF.xApplication.process.Xform.LP.documentHistory.exit+"\" MWFButtonAction=\"exit\" MWFButtonText=\""+MWF.xApplication.process.Xform.LP.documentHistory.exit+"\"></span>";
  49. html += "<span MWFnodetype=\"MWFToolBarSeparator\"></span>";
  50. var text = MWF.xApplication.process.Xform.LP.documentHistory.diff_patch_count;
  51. text = text.replace(/{history}/, this.historyDataList.length).replace(/{diff}/, this.diffCount);
  52. html += "<span style='float: left; line-height: 24px; color: #666666; margin-left: 10px'>"+text+"</span>";
  53. this.toolbarNode.set("html", html);
  54. MWF.require("MWF.widget.Toolbar", function() {
  55. this.toolbar = new MWF.widget.Toolbar(this.toolbarNode, {"style": "documentEdit"}, this);
  56. this.toolbar.load();
  57. this.checkToolbar();
  58. }.bind(this));
  59. },
  60. checkToolbar: function(){
  61. if (this.toolbar){
  62. if (this.playing){
  63. if (this.stop){
  64. this.toolbar.childrenButton[0].enable();
  65. this.toolbar.childrenButton[1].disable();
  66. if (this.patchIndex==0 && this.diffIndex==0){
  67. this.toolbar.childrenButton[3].disable();
  68. if (this.diffPatch.length) this.toolbar.childrenButton[4].enable();
  69. }else{
  70. if (this.patchIndex<this.diffPatch.length-1){
  71. this.toolbar.childrenButton[3].enable();
  72. this.toolbar.childrenButton[4].enable();
  73. }else if (this.patchIndex<this.diffPatch.length && this.diffIndex < this.diffPatch[this.patchIndex].patch.diffs.length){
  74. this.toolbar.childrenButton[3].enable();
  75. this.toolbar.childrenButton[4].enable();
  76. }else{
  77. if (this.diffPatch.length) this.toolbar.childrenButton[3].enable();
  78. this.toolbar.childrenButton[4].disable();
  79. }
  80. }
  81. }else{
  82. this.toolbar.childrenButton[0].disable();
  83. this.toolbar.childrenButton[1].enable();
  84. this.toolbar.childrenButton[3].disable();
  85. this.toolbar.childrenButton[4].disable();
  86. }
  87. this.toolbar.childrenButton[2].enable();
  88. }else{
  89. this.toolbar.childrenButton[0].enable();
  90. this.toolbar.childrenButton[1].disable();
  91. this.toolbar.childrenButton[2].disable();
  92. if (this.patchIndex==0 && this.diffIndex==0){
  93. this.toolbar.childrenButton[3].disable();
  94. if (this.diffPatch.length) this.toolbar.childrenButton[4].enable();
  95. }else{
  96. if (this.patchIndex<this.diffPatch.length-1){
  97. this.toolbar.childrenButton[3].enable();
  98. this.toolbar.childrenButton[4].enable();
  99. }else if (this.patchIndex<this.diffPatch.length && this.diffIndex < this.diffPatch[this.patchIndex].patch.diffs.length){
  100. this.toolbar.childrenButton[3].enable();
  101. this.toolbar.childrenButton[4].enable();
  102. }else{
  103. if (this.diffPatch.length) this.toolbar.childrenButton[3].enable();
  104. this.toolbar.childrenButton[4].disable();
  105. }
  106. }
  107. }
  108. }
  109. },
  110. createHistoryListNode: function(){
  111. this.historyListAreaNode = new Element("div", {"styles": this.css.historyListAreaNode}).inject(this.documentEditor.contentNode, "before");
  112. this.documentEditor.contentNode.setStyle("width", "auto");
  113. this.documentEditor.zoom(1);
  114. this.documentEditor._checkScale();
  115. var size = this.documentEditor.node.getSize();
  116. var toolbarSize = this.documentEditor.toolbarNode.getSize();
  117. var h = size.y-toolbarSize.y;
  118. this.historyListAreaNode.setStyle("height", ""+h+"px");
  119. this.historyListTitleAreaNode = new Element("div", {"styles": this.css.historyListTitleAreaNode}).inject(this.historyListAreaNode);
  120. this.historyListContentAreaNode = new Element("div", {"styles": this.css.historyListContentAreaNode}).inject(this.historyListAreaNode);
  121. },
  122. loadHistoryList: function(){
  123. var original = this.historyDataList[0];
  124. this.diffPatch.each();
  125. },
  126. createHistoryListItem: function(){
  127. },
  128. getHistoryDataList: function(callback){
  129. if (this.documentEditor.historyDataList){
  130. this.getHistoryDataListFinish(this.documentEditor.historyDataList);
  131. if (callback) callback();
  132. }else{
  133. var historyDataList = [];
  134. var getDataCount = 0;
  135. var idx = 0;
  136. var checkBeginDiffHistory = function(){
  137. if (getDataCount>=this.historyDocumentList.length){
  138. this.getHistoryDataListFinish(historyDataList);
  139. if (callback) callback();
  140. }
  141. }.bind(this);
  142. for (var i=this.historyDocumentList.length-1; i>=0; i--){
  143. historyDataList.push(null);
  144. this.getHistroyDocumentData(this.historyDocumentList[i].id, function(){
  145. getDataCount++;
  146. checkBeginDiffHistory();
  147. }.bind(this), idx, historyDataList);
  148. idx++;
  149. }
  150. }
  151. },
  152. getHistoryDataListFinish: function(historyDataList){
  153. this.documentEditor.historyDataList = historyDataList;
  154. this.historyDataList = historyDataList;
  155. var currentData = {
  156. "data": this.documentEditor.data.filetext,
  157. "person": layout.session.user.distinguishedName,
  158. "activityName": this.documentEditor.form.businessData.activity.name,
  159. "createTime" : (new Date()).format("db")
  160. }
  161. this.historyDataList.push(currentData);
  162. },
  163. getHistroyDocumentData: function(id, callback, i, historyDataList){
  164. o2.Actions.load("x_processplatform_assemble_surface").DocumentVersionAction.get(id, function(json){
  165. if (historyDataList) historyDataList[i] = json.data;
  166. if (callback) callback(json.data);
  167. }.bind(this));
  168. },
  169. getHistroyDocumentList: function(callback){
  170. if (!this.documentEditor.historyDocumentList){
  171. var id = this.documentEditor.form.businessData.work.job;
  172. o2.Actions.load("x_processplatform_assemble_surface").DocumentVersionAction.listWithJobCategory(id, this.json.id, function(json){
  173. this.historyDocumentList = json.data;
  174. this.documentEditor.historyDocumentList = json.data;
  175. if (callback) callback();
  176. }.bind(this));
  177. }else{
  178. this.historyDocumentList = this.documentEditor.historyDocumentList;
  179. if (callback) callback();
  180. }
  181. },
  182. beginDiffHistory: function(callback){
  183. o2.load("/o2_lib/diff-match-patch/diff_match_patch_uncompressed.js", function(){
  184. this.initAnimation();
  185. if (callback) callback();
  186. }.bind(this));
  187. },
  188. initAnimation: function(){
  189. this.diffPatch = this.diffHistroy();
  190. this.diffCount = 0;
  191. this.diffPatch.each(function(patch){
  192. patch.patch.diffs.each(function(diff){
  193. if (diff[0]!=0) this.diffCount++;
  194. }.bind(this));
  195. }.bind(this));
  196. // this.initData();
  197. // this.initAnimationStatus();
  198. },
  199. initData: function(){
  200. this.currentHistoryData = this.historyDataList[0].data;
  201. this.documentEditor.layout_filetext.set("html", this.currentHistoryData);
  202. },
  203. initAnimationStatus: function(){
  204. this.patchIndex = 0;
  205. this.diffIndex = 0;
  206. this.currentDiffs = null;
  207. this.stop = false;
  208. this.step = false;
  209. this.playing = false;
  210. this.reverse = false;
  211. this.options.fxTime = 500;
  212. this.options.inforTime = 2000;
  213. this.checkToolbar();
  214. },
  215. doAnimationAuto: function(){
  216. this.playing = true;
  217. this.checkToolbar();
  218. this.doPatchAnimation(function(){
  219. this.patchIndex = 0;
  220. this.diffIndex = 0;
  221. this.playing = false;
  222. this.documentEditor.resetData();
  223. this.checkToolbar();
  224. }.bind(this));
  225. },
  226. do: function(){
  227. if (this.nextPlayPrefixFunction){
  228. this.nextPlayPrefixFunction();
  229. this.nextPlayPrefixFunction = null;
  230. }else{
  231. this.doAnimationAuto();
  232. }
  233. },
  234. play: function(){
  235. this.reverse = false;
  236. this.stop = false;
  237. // this.checkToolbar();
  238. this.options.fxTime = 500;
  239. this.options.inforTime = 2000;
  240. this.toolbar.childrenButton[0].disable();
  241. this.toolbar.childrenButton[3].disable();
  242. this.toolbar.childrenButton[4].disable();
  243. if (!this.playing){
  244. this.initData();
  245. this.initAnimationStatus();
  246. }
  247. this.do();
  248. },
  249. stopPlay: function(){
  250. if (this.playing){
  251. this.stop = true;
  252. this.playing = false;
  253. if (this.nextPlayPrefixFunction){
  254. this.nextPlayPrefixFunction();
  255. this.nextPlayPrefixFunction = null;
  256. }
  257. this.patchIndex = 0;
  258. this.diffIndex = 0;
  259. this.toolbar.childrenButton[1].disable();
  260. this.toolbar.childrenButton[2].disable();
  261. }
  262. },
  263. pause: function(){
  264. if (this.playing){
  265. this.stop = true;
  266. this.toolbar.childrenButton[1].disable();
  267. this.toolbar.childrenButton[2].disable();
  268. }
  269. },
  270. next: function(){
  271. this.reverse = false;
  272. this.options.fxTime = 0;
  273. this.options.inforTime = 0;
  274. this.stop = true;
  275. this.toolbar.childrenButton[3].disable();
  276. this.toolbar.childrenButton[4].disable();
  277. if (!this.playing){
  278. this.initData();
  279. this.initAnimationStatus();
  280. }
  281. this.do();
  282. },
  283. prev: function(){
  284. this.reverse = true;
  285. this.options.fxTime = 0;
  286. this.options.inforTime = 0;
  287. this.stop = true;
  288. this.toolbar.childrenButton[3].disable();
  289. this.toolbar.childrenButton[4].disable();
  290. if (!this.playing) this.initData();
  291. this.do();
  292. },
  293. exit: function(){
  294. this.initAnimationStatus();
  295. this.options.fxTime = 0;
  296. this.options.inforTime = 0;
  297. if (this.nextPlayPrefixFunction){
  298. this.nextPlayPrefixFunction(function(){
  299. this.documentEditor.toolbarNode = this.documentEditor.documentToolbarNode;
  300. this.documentEditor.toolbarNode.show();
  301. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.show();
  302. this.documentEditor.resizeToolbar();
  303. }.bind(this));
  304. this.nextPlayPrefixFunction = null;
  305. }else{
  306. this.documentEditor.toolbarNode = this.documentEditor.documentToolbarNode;
  307. this.documentEditor.toolbarNode.show();
  308. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.show();
  309. this.documentEditor.resizeToolbar();
  310. }
  311. this.historyListAreaNode.destroy();
  312. this.historyListAreaNode = null;
  313. this.documentEditor.zoom(1);
  314. this.documentEditor._checkScale();
  315. this.documentEditor.resetData();
  316. this.toolbarNode.hide();
  317. },
  318. active: function(callback){
  319. this.getHistroyDocumentList(function(){
  320. if (this.historyDocumentList && this.historyDocumentList.length){
  321. this.getHistoryDataList(function(){
  322. this.documentEditor.options.pageShow = "single";
  323. this.documentEditor.resetData();
  324. this.beginDiffHistory(function(){
  325. this.documentEditor.resetData();
  326. this.toolbarNode.show();
  327. this.documentEditor.documentToolbarNode = this.documentEditor.toolbarNode;
  328. this.documentEditor.documentToolbarNode.hide();
  329. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.hide();
  330. this.documentEditor.toolbarNode = this.toolbarNode;
  331. this.documentEditor.resizeToolbar();
  332. var text = MWF.xApplication.process.Xform.LP.documentHistory.diff_patch_count;
  333. text = text.replace(/{history}/, this.historyDataList.length).replace(/{diff}/, this.diffCount);
  334. this.toolbarNode.getLast().set("html", text);
  335. if (callback) callback();
  336. }.bind(this));
  337. }.bind(this));
  338. }
  339. }.bind(this));
  340. },
  341. doAnimationStep: function(i){
  342. this.doPatchAnimationStep(i);
  343. this.documentEditor.resetData();
  344. this.checkToolbar();
  345. },
  346. diffHistroy: function(){
  347. var diffPatch = [];
  348. for (var i=1; i<this.historyDataList.length; i++){
  349. var earlyDataText = this.historyDataList[i-1].data;
  350. var laterData = this.historyDataList[i];
  351. var dmp = new diff_match_patch();
  352. // dmp.Diff_Timeout = parseFloat(10);
  353. // dmp.Diff_EditCost = parseFloat(4);
  354. var diff_d = dmp.diff_main(earlyDataText, laterData.data);
  355. dmp.diff_cleanupSemantic(diff_d);
  356. var patch_list = dmp.patch_make(earlyDataText, laterData.data, diff_d);
  357. patch_list.each(function(patch){
  358. diffPatch.push({"patch":patch, "obj": laterData});
  359. }.bind(this));
  360. }
  361. return diffPatch;
  362. },
  363. doPatchAnimation: function(callback){
  364. var patchObj = this.diffPatch[this.patchIndex];
  365. var patch = patchObj.patch;
  366. var obj = patchObj.obj;
  367. this.currentDiffs = patch.diffs;
  368. this.diffIndex = (this.reverse) ? patch.diffs.length-1 : 0;
  369. // var inforDiv = this.createPatchInforNode(obj);
  370. //
  371. // var fx = new Fx.Tween(inforDiv, {property: 'opacity'});
  372. // fx.start(0,1).chain(function(){
  373. var start = (this.reverse) ? patch.start1+patch.length2 : patch.start1;
  374. this.doDiffsAnimation(obj, start, function(){
  375. //inforDiv.destroy();
  376. if (this.reverse){
  377. this.patchIndex--;
  378. if (this.patchIndex>=0){
  379. this.currentHistoryData = this.documentEditor.layout_filetext.get("html");
  380. this.doPatchAnimation(callback);
  381. }else{
  382. if (callback) callback();
  383. }
  384. }else{
  385. this.patchIndex++;
  386. if (this.patchIndex<this.diffPatch.length){
  387. this.currentHistoryData = this.documentEditor.layout_filetext.get("html");
  388. this.doPatchAnimation(callback);
  389. }else{
  390. if (callback) callback();
  391. }
  392. }
  393. }.bind(this));
  394. },
  395. doPatchAnimationStep: function(i){
  396. if (this.patchIndex>this.diffPatch.length || this.patchIndex<0){
  397. this.initAnimationStatus();
  398. this.documentEditor.resetData();
  399. this.checkToolbar();
  400. }else{
  401. var patchObj = this.diffPatch[this.patchIndex];
  402. var patch = patchObj.patch;
  403. var obj = patchObj.obj;
  404. this.currentDiffs = patch.diffs;
  405. this.diffIndex = 0;
  406. this.doDiffsAnimation(obj, patch.start1);
  407. this.patchIndex = this.patchIndex+i;
  408. }
  409. },
  410. createDiifInforNode: function(obj, node, color, insertInfor){
  411. var insertInforDiv = new Element("div", { "styles": this.css.historyInforNode }).inject(this.documentEditor.node);
  412. insertInforDiv.setStyle("background", color);
  413. insertInfor = insertInfor.replace(/{name}/, o2.name.cn(obj.person))
  414. .replace(/{activity}/, obj.activityName)
  415. .replace(/{time}/, obj.createTime);
  416. insertInforDiv.set("html", insertInfor);
  417. insertInforDiv.position({
  418. "relativeTo": node,
  419. "position": 'upperCenter',
  420. "edge": 'bottomCenter',
  421. "offset": {
  422. "x": 0, "y": -10
  423. }
  424. });
  425. return insertInforDiv;
  426. },
  427. doDiffsAnimation: function(obj, start, callback){
  428. var diff = this.currentDiffs[this.diffIndex];
  429. var filetextNode = this.documentEditor.layout_filetext;
  430. switch (diff[0]) {
  431. case DIFF_INSERT:
  432. var text = diff[1];
  433. if (this.reverse){
  434. start -= text.length;
  435. var left = this.currentHistoryData.substring(0, start);
  436. var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  437. var right = this.currentHistoryData.substring(start+diff[1].length);
  438. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  439. }else{
  440. var left = this.currentHistoryData.substring(0, start);
  441. var right = this.currentHistoryData.substring(start);
  442. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  443. }
  444. var ins = filetextNode.getElement("ins");
  445. ins.scrollIn();
  446. this.doInsetAnimation(ins, diff[1], function(invisible){
  447. var insertInforDiv = null;
  448. if (!invisible){
  449. insertInforDiv = this.createDiifInforNode(obj, ins, "#e2edfb", MWF.xApplication.process.Xform.LP.documentHistory.insertContent);
  450. }
  451. window.setTimeout(function(){
  452. var endFunction = function(cb){
  453. if (insertInforDiv) insertInforDiv.fade("out");
  454. var fx = new Fx.Tween(ins, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  455. fx.start(1.1).chain(function(){
  456. if (insertInforDiv) insertInforDiv.destroy();
  457. if (this.reverse){
  458. ins.destroy();
  459. this.currentHistoryData = filetextNode.get("html");
  460. }else{
  461. data = filetextNode.get("html");
  462. this.currentHistoryData = data.replace(/<ins[\s\S]*\/ins>/m, text);
  463. filetextNode.set("html", this.currentHistoryData);
  464. }
  465. if (this.playing){
  466. if (this.reverse){
  467. this.diffIndex--;
  468. if (this.diffIndex>=0){
  469. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  470. //this.doDiffsAnimation(obj, start, callback);
  471. }else{
  472. if (callback) callback();
  473. }
  474. }else{
  475. start += text.length;
  476. this.diffIndex++;
  477. if (this.diffIndex<this.currentDiffs.length){
  478. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  479. //this.doDiffsAnimation(obj, start, callback);
  480. }else{
  481. if (callback) callback();
  482. }
  483. }
  484. }else{
  485. this.initAnimationStatus();
  486. this.documentEditor.resetData();
  487. }
  488. if (cb) cb();
  489. }.bind(this));
  490. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  491. }.bind(this)
  492. if (!this.stop || !this.playing) {
  493. endFunction();
  494. } else{
  495. this.nextPlayPrefixFunction = endFunction;
  496. }
  497. this.checkToolbar();
  498. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  499. }.bind(this));
  500. break;
  501. case DIFF_DELETE:
  502. var text = diff[1];
  503. if (this.reverse){
  504. var left = this.currentHistoryData.substring(0, start);
  505. //var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  506. var right = this.currentHistoryData.substring(start);
  507. filetextNode.set("html", left+"<del style='color: red'>"+text+"</del>"+right);
  508. start -= text.length;
  509. }else{
  510. var left = this.currentHistoryData.substring(0, start);
  511. var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  512. var right = this.currentHistoryData.substring(start+diff[1].length);
  513. //start -= .length;
  514. filetextNode.set("html", left+"<del style='color: red'>"+middle+"</del>"+right);
  515. }
  516. var del = filetextNode.getElement("del");
  517. del.scrollIn();
  518. this.doDeleteAnimation(del, diff[1], obj, function(deleteInforDiv){
  519. // var deleteInforDiv = null;
  520. // if (!invisible){
  521. // deleteInforDiv = this.createDiifInforNode(obj, del, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent);
  522. // }
  523. var invisible = !deleteInforDiv;
  524. window.setTimeout(function(){
  525. var endFunction = function(cb){
  526. if (deleteInforDiv) deleteInforDiv.fade("out");
  527. var fx = new Fx.Tween(del, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  528. fx.start(0.5,0).chain(function(){
  529. if (deleteInforDiv) deleteInforDiv.destroy();
  530. if (this.reverse){
  531. data = filetextNode.get("html");
  532. this.currentHistoryData = data.replace(/<del[\s\S]*\/del>/m, text);
  533. filetextNode.set("html", this.currentHistoryData);
  534. }else{
  535. del.destroy();
  536. this.currentHistoryData = filetextNode.get("html");
  537. }
  538. if (this.playing){
  539. if (this.reverse){
  540. this.diffIndex--;
  541. if (this.diffIndex>=0){
  542. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  543. }else{
  544. if (callback) callback();
  545. }
  546. }else{
  547. this.diffIndex++;
  548. if (this.diffIndex<this.currentDiffs.length){
  549. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  550. }else{
  551. if (callback) callback();
  552. }
  553. }
  554. }else{
  555. this.initAnimationStatus();
  556. this.documentEditor.resetData();
  557. }
  558. if (cb) cb();
  559. }.bind(this));
  560. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  561. }.bind(this)
  562. if (!this.stop || !this.playing) {
  563. endFunction();
  564. } else{
  565. this.nextPlayPrefixFunction = endFunction;
  566. }
  567. this.checkToolbar();
  568. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  569. }.bind(this));
  570. break;
  571. case DIFF_EQUAL:
  572. if (this.reverse){
  573. start -= diff[1].length;
  574. this.diffIndex--;
  575. if (this.diffIndex>=0){
  576. this.doDiffsAnimation(obj, start, callback);
  577. }else{
  578. if (callback) callback();
  579. }
  580. }else{
  581. start += diff[1].length;
  582. this.diffIndex++;
  583. if (this.diffIndex<this.currentDiffs.length){
  584. this.doDiffsAnimation(obj, start, callback);
  585. }else{
  586. if (callback) callback();
  587. }
  588. }
  589. break;
  590. }
  591. },
  592. doInsetAnimation: function(node, str, callback){
  593. var tmp = new Element("div", {"html": str});
  594. if (!tmp.get("text").trim()){
  595. if (callback) callback(true);
  596. }else{
  597. var nodes = tmp.childNodes;
  598. this.doInsetNodeAnimation(node, nodes, 0, callback);
  599. }
  600. },
  601. doInsetNodeAnimation: function(ins, nodes, idx, callback){
  602. var node = nodes[idx];
  603. if (node.nodeType == Node.TEXT_NODE){
  604. this.doCharAnimation(ins, node.nodeValue, 0, function(){
  605. idx++;
  606. if (idx<nodes.length){
  607. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  608. }else{
  609. if (callback) callback();
  610. }
  611. }.bind(this));
  612. }else{
  613. var duration = this.options.speed*this.options.fxTime/nodes.length
  614. var span = new Element("span", {"styles": {"opacity": 0}}).inject(ins);
  615. span.appendChild(node);
  616. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  617. fx.start(0,1).chain(function(){
  618. idx++;
  619. if (idx<nodes.length){
  620. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  621. }else{
  622. if (callback) callback();
  623. }
  624. }.bind(this));
  625. }
  626. },
  627. doCharAnimation: function(node, str, idx, callback){
  628. var duration = this.options.speed*this.options.fxTime/str.length;
  629. var char = str.charAt(idx);
  630. var span = new Element("span", {"styles": {"opacity": 0}, "html": char}).inject(node);
  631. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  632. fx.start(0,1).chain(function(){
  633. idx++;
  634. if (idx<str.length){
  635. this.doCharAnimation(node, str, idx, callback);
  636. }else{
  637. if (callback) callback();
  638. }
  639. }.bind(this));
  640. },
  641. doDeleteAnimation: function(node, str, obj, callback){
  642. var tmp = new Element("div", {"html": str});
  643. if (!tmp.get("text").trim()){
  644. if (callback) callback(null);
  645. }else{
  646. deleteInforDiv = this.createDiifInforNode(obj, node, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent);
  647. var fx = new Fx.Tween(node, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  648. fx.start(1,0.5).chain(function(){
  649. if (callback) callback(deleteInforDiv);
  650. }.bind(this));
  651. }
  652. }
  653. });
  654. MWF.xApplication.process.Xform.widget.DocumentHistory.Item = new Class({
  655. initialize: function(history, patch){
  656. this.history = history;
  657. this.documentEditor = this.history.documentEditor;
  658. this.css = this.history.css;
  659. this.load();
  660. },
  661. load: function(){
  662. }
  663. })