DocumentHistory.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  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. var y = this.historyListContentAreaNode.getEdgeHeight();
  122. var title_y = this.historyListTitleAreaNode.getComputedSize().totalHeight;
  123. h = h-y-title_y;
  124. this.historyListContentAreaNode.setStyle("height", ""+h+"px");
  125. var text = MWF.xApplication.process.Xform.LP.documentHistory.diff_patch_count;
  126. text = text.replace(/{history}/, this.historyDataList.length).replace(/{diff}/, this.diffCount);
  127. var insertStr = MWF.xApplication.process.Xform.LP.documentHistory.insertTimes;
  128. var deleteStr = MWF.xApplication.process.Xform.LP.documentHistory.deleteTimes;
  129. insertStr = insertStr.replace(/{times}/, this.diffInsertCount);
  130. deleteStr = deleteStr.replace(/{times}/, this.diffDeleteCount);
  131. this.historyListTitleNode = new Element("div", {"styles": this.css.historyListTitleNode, "text": text}).inject(this.historyListAreaNode);
  132. this.historyListTitleInsertNode = new Element("div", {"styles": this.css.historyListTitleInsertNode, "text": text}).inject(this.historyListAreaNode);
  133. this.historyListTitleDeleteNode = new Element("div", {"styles": this.css.historyListTitleDeleteNode, "text": text}).inject(this.historyListAreaNode);
  134. documentHistory
  135. diffDeleteCount
  136. this.historyListTitleAreaNode.set("", text);
  137. },
  138. loadHistoryList: function(){
  139. var original = this.historyDataList[0];
  140. this.diffPatch.each(function(patchObj){
  141. this.createHistoryListItem(patchObj);
  142. }.bind(this));
  143. },
  144. createHistoryListItem: function(patchObj){
  145. new MWF.xApplication.process.Xform.widget.DocumentHistory.Item(this, patchObj);
  146. },
  147. getHistoryDataList: function(callback){
  148. if (this.documentEditor.historyDataList){
  149. this.getHistoryDataListFinish(this.documentEditor.historyDataList);
  150. if (callback) callback();
  151. }else{
  152. var historyDataList = [];
  153. var getDataCount = 0;
  154. var idx = 0;
  155. var checkBeginDiffHistory = function(){
  156. if (getDataCount>=this.historyDocumentList.length){
  157. this.getHistoryDataListFinish(historyDataList);
  158. if (callback) callback();
  159. }
  160. }.bind(this);
  161. for (var i=this.historyDocumentList.length-1; i>=0; i--){
  162. historyDataList.push(null);
  163. this.getHistroyDocumentData(this.historyDocumentList[i].id, function(){
  164. getDataCount++;
  165. checkBeginDiffHistory();
  166. }.bind(this), idx, historyDataList);
  167. idx++;
  168. }
  169. }
  170. },
  171. getHistoryDataListFinish: function(historyDataList){
  172. this.documentEditor.historyDataList = historyDataList;
  173. this.historyDataList = historyDataList;
  174. var currentData = {
  175. "data": this.documentEditor.data.filetext,
  176. "person": layout.session.user.distinguishedName,
  177. "activityName": this.documentEditor.form.businessData.activity.name,
  178. "createTime" : (new Date()).format("db")
  179. };
  180. this.historyDataList.push(currentData);
  181. },
  182. getHistroyDocumentData: function(id, callback, i, historyDataList){
  183. o2.Actions.load("x_processplatform_assemble_surface").DocumentVersionAction.get(id, function(json){
  184. if (historyDataList) historyDataList[i] = json.data;
  185. if (callback) callback(json.data);
  186. }.bind(this));
  187. },
  188. getHistroyDocumentList: function(callback){
  189. if (!this.documentEditor.historyDocumentList){
  190. var id = this.documentEditor.form.businessData.work.job;
  191. o2.Actions.load("x_processplatform_assemble_surface").DocumentVersionAction.listWithJobCategory(id, this.json.id, function(json){
  192. this.historyDocumentList = json.data;
  193. this.documentEditor.historyDocumentList = json.data;
  194. if (callback) callback();
  195. }.bind(this));
  196. }else{
  197. this.historyDocumentList = this.documentEditor.historyDocumentList;
  198. if (callback) callback();
  199. }
  200. },
  201. beginDiffHistory: function(callback){
  202. o2.load("/o2_lib/diff-match-patch/diff_match_patch_uncompressed.js", function(){
  203. this.initAnimation();
  204. if (callback) callback();
  205. }.bind(this));
  206. },
  207. initAnimation: function(){
  208. this.diffPatch = this.diffHistroy();
  209. this.diffCount = 0;
  210. this.diffInsertCount = 0;
  211. this.diffDeleteCount = 0;
  212. this.diffPatch.each(function(patch){
  213. patch.patch.diffs.each(function(diff){
  214. if (diff[0]!=0) this.diffCount++;
  215. if (diff[0]==-1) this.diffDeleteCount++;
  216. if (diff[0]==1) this.diffInsertCount++;
  217. }.bind(this));
  218. }.bind(this));
  219. // this.initData();
  220. this.initAnimationStatus();
  221. },
  222. initData: function(){
  223. this.currentHistoryData = this.historyDataList[0].data;
  224. this.documentEditor.layout_filetext.set("html", this.currentHistoryData);
  225. },
  226. initAnimationStatus: function(){
  227. this.patchIndex = 0;
  228. this.diffIndex = 0;
  229. this.currentDiffs = null;
  230. this.stop = false;
  231. this.step = false;
  232. this.playing = false;
  233. this.reverse = false;
  234. this.options.fxTime = 500;
  235. this.options.inforTime = 2000;
  236. this.checkToolbar();
  237. },
  238. doAnimationAuto: function(){
  239. this.playing = true;
  240. this.checkToolbar();
  241. this.doPatchAnimation(function(){
  242. this.patchIndex = 0;
  243. this.diffIndex = 0;
  244. this.playing = false;
  245. this.documentEditor.resetData();
  246. this.checkToolbar();
  247. }.bind(this));
  248. },
  249. do: function(){
  250. if (this.nextPlayPrefixFunction){
  251. this.nextPlayPrefixFunction();
  252. this.nextPlayPrefixFunction = null;
  253. }else{
  254. this.doAnimationAuto();
  255. }
  256. },
  257. play: function(){
  258. this.reverse = false;
  259. this.stop = false;
  260. // this.checkToolbar();
  261. this.options.fxTime = 500;
  262. this.options.inforTime = 2000;
  263. this.toolbar.childrenButton[0].disable();
  264. this.toolbar.childrenButton[3].disable();
  265. this.toolbar.childrenButton[4].disable();
  266. if (!this.playing){
  267. this.initData();
  268. this.initAnimationStatus();
  269. }
  270. this.do();
  271. },
  272. stopPlay: function(){
  273. if (this.playing){
  274. this.stop = true;
  275. this.playing = false;
  276. if (this.nextPlayPrefixFunction){
  277. this.nextPlayPrefixFunction();
  278. this.nextPlayPrefixFunction = null;
  279. }
  280. this.patchIndex = 0;
  281. this.diffIndex = 0;
  282. this.toolbar.childrenButton[1].disable();
  283. this.toolbar.childrenButton[2].disable();
  284. }
  285. },
  286. pause: function(){
  287. if (this.playing){
  288. this.stop = true;
  289. this.toolbar.childrenButton[1].disable();
  290. this.toolbar.childrenButton[2].disable();
  291. }
  292. },
  293. next: function(){
  294. this.reverse = false;
  295. this.options.fxTime = 0;
  296. this.options.inforTime = 0;
  297. this.stop = true;
  298. this.toolbar.childrenButton[3].disable();
  299. this.toolbar.childrenButton[4].disable();
  300. if (!this.playing) this.initData();
  301. this.do();
  302. },
  303. prev: function(){
  304. this.reverse = true;
  305. this.options.fxTime = 0;
  306. this.options.inforTime = 0;
  307. this.stop = true;
  308. this.toolbar.childrenButton[3].disable();
  309. this.toolbar.childrenButton[4].disable();
  310. if (!this.playing) this.initData();
  311. this.do();
  312. },
  313. exit: function(){
  314. this.initAnimationStatus();
  315. this.options.fxTime = 0;
  316. this.options.inforTime = 0;
  317. if (this.nextPlayPrefixFunction){
  318. this.nextPlayPrefixFunction(function(){
  319. this.documentEditor.toolbarNode = this.documentEditor.documentToolbarNode;
  320. this.documentEditor.toolbarNode.show();
  321. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.show();
  322. this.documentEditor.resizeToolbar();
  323. }.bind(this));
  324. this.nextPlayPrefixFunction = null;
  325. }else{
  326. this.documentEditor.toolbarNode = this.documentEditor.documentToolbarNode;
  327. this.documentEditor.toolbarNode.show();
  328. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.show();
  329. this.documentEditor.resizeToolbar();
  330. }
  331. this.historyListAreaNode.destroy();
  332. this.historyListAreaNode = null;
  333. this.documentEditor.zoom(1);
  334. this.documentEditor._checkScale();
  335. this.documentEditor.resetData();
  336. this.toolbarNode.hide();
  337. },
  338. active: function(callback){
  339. this.getHistroyDocumentList(function(){
  340. if (this.historyDocumentList && this.historyDocumentList.length){
  341. this.getHistoryDataList(function(){
  342. this.documentEditor.options.pageShow = "single";
  343. this.documentEditor.resetData();
  344. this.beginDiffHistory(function(){
  345. this.documentEditor.resetData();
  346. this.toolbarNode.show();
  347. this.documentEditor.documentToolbarNode = this.documentEditor.toolbarNode;
  348. this.documentEditor.documentToolbarNode.hide();
  349. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.hide();
  350. this.documentEditor.toolbarNode = this.toolbarNode;
  351. this.documentEditor.resizeToolbar();
  352. var text = MWF.xApplication.process.Xform.LP.documentHistory.diff_patch_count;
  353. text = text.replace(/{history}/, this.historyDataList.length).replace(/{diff}/, this.diffCount);
  354. this.toolbarNode.getLast().set("html", text);
  355. if (callback) callback();
  356. }.bind(this));
  357. }.bind(this));
  358. }
  359. }.bind(this));
  360. },
  361. doAnimationStep: function(i){
  362. this.doPatchAnimationStep(i);
  363. this.documentEditor.resetData();
  364. this.checkToolbar();
  365. },
  366. diffHistroy: function(){
  367. var diffPatch = [];
  368. for (var i=1; i<this.historyDataList.length; i++){
  369. var earlyDataText = this.historyDataList[i-1].data;
  370. var laterData = this.historyDataList[i];
  371. var dmp = new diff_match_patch();
  372. // dmp.Diff_Timeout = parseFloat(10);
  373. // dmp.Diff_EditCost = parseFloat(4);
  374. var diff_d = dmp.diff_main(earlyDataText, laterData.data);
  375. dmp.diff_cleanupSemantic(diff_d);
  376. var patch_list = dmp.patch_make(earlyDataText, laterData.data, diff_d);
  377. patch_list.each(function(patch){
  378. diffPatch.push({"patch":patch, "obj": laterData});
  379. }.bind(this));
  380. }
  381. return diffPatch;
  382. },
  383. doPatchAnimation: function(callback){
  384. var patchObj = this.diffPatch[this.patchIndex];
  385. var patch = patchObj.patch;
  386. var obj = patchObj.obj;
  387. this.currentDiffs = patch.diffs;
  388. this.diffIndex = (this.reverse) ? patch.diffs.length-1 : 0;
  389. // var inforDiv = this.createPatchInforNode(obj);
  390. //
  391. // var fx = new Fx.Tween(inforDiv, {property: 'opacity'});
  392. // fx.start(0,1).chain(function(){
  393. var start = (this.reverse) ? patch.start1+patch.length2 : patch.start1;
  394. this.doDiffsAnimation(obj, start, function(){
  395. //inforDiv.destroy();
  396. if (this.reverse){
  397. this.patchIndex--;
  398. if (this.patchIndex>=0){
  399. this.currentHistoryData = this.documentEditor.layout_filetext.get("html");
  400. this.doPatchAnimation(callback);
  401. }else{
  402. if (callback) callback();
  403. }
  404. }else{
  405. this.patchIndex++;
  406. if (this.patchIndex<this.diffPatch.length){
  407. this.currentHistoryData = this.documentEditor.layout_filetext.get("html");
  408. this.doPatchAnimation(callback);
  409. }else{
  410. if (callback) callback();
  411. }
  412. }
  413. }.bind(this));
  414. },
  415. doPatchAnimationStep: function(i){
  416. if (this.patchIndex>this.diffPatch.length || this.patchIndex<0){
  417. this.initAnimationStatus();
  418. this.documentEditor.resetData();
  419. this.checkToolbar();
  420. }else{
  421. var patchObj = this.diffPatch[this.patchIndex];
  422. var patch = patchObj.patch;
  423. var obj = patchObj.obj;
  424. this.currentDiffs = patch.diffs;
  425. this.diffIndex = 0;
  426. this.doDiffsAnimation(obj, patch.start1);
  427. this.patchIndex = this.patchIndex+i;
  428. }
  429. },
  430. createDiifInforNode: function(obj, node, color, insertInfor){
  431. var insertInforDiv = new Element("div", { "styles": this.css.historyInforNode }).inject(this.documentEditor.node);
  432. insertInforDiv.setStyle("background", color);
  433. insertInfor = insertInfor.replace(/{name}/, o2.name.cn(obj.person))
  434. .replace(/{activity}/, obj.activityName)
  435. .replace(/{time}/, obj.createTime);
  436. insertInforDiv.set("html", insertInfor);
  437. insertInforDiv.position({
  438. "relativeTo": node,
  439. "position": 'upperCenter',
  440. "edge": 'bottomCenter',
  441. "offset": {
  442. "x": 0, "y": -10
  443. }
  444. });
  445. return insertInforDiv;
  446. },
  447. doDiffsAnimation: function(obj, start, callback){
  448. var diff = this.currentDiffs[this.diffIndex];
  449. var filetextNode = this.documentEditor.layout_filetext;
  450. switch (diff[0]) {
  451. case DIFF_INSERT:
  452. var text = diff[1];
  453. if (this.reverse){
  454. start -= text.length;
  455. var left = this.currentHistoryData.substring(0, start);
  456. var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  457. var right = this.currentHistoryData.substring(start+diff[1].length);
  458. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  459. }else{
  460. var left = this.currentHistoryData.substring(0, start);
  461. var right = this.currentHistoryData.substring(start);
  462. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  463. }
  464. var ins = filetextNode.getElement("ins");
  465. ins.scrollIn();
  466. this.doInsetAnimation(ins, diff[1], function(invisible){
  467. var insertInforDiv = null;
  468. if (!invisible){
  469. insertInforDiv = this.createDiifInforNode(obj, ins, "#e2edfb", MWF.xApplication.process.Xform.LP.documentHistory.insertContent);
  470. }
  471. window.setTimeout(function(){
  472. var endFunction = function(cb){
  473. if (insertInforDiv) insertInforDiv.fade("out");
  474. var fx = new Fx.Tween(ins, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  475. fx.start(1.1).chain(function(){
  476. if (insertInforDiv) insertInforDiv.destroy();
  477. if (this.reverse){
  478. ins.destroy();
  479. this.currentHistoryData = filetextNode.get("html");
  480. }else{
  481. data = filetextNode.get("html");
  482. this.currentHistoryData = data.replace(/<ins[\s\S]*\/ins>/m, text);
  483. filetextNode.set("html", this.currentHistoryData);
  484. }
  485. if (this.playing){
  486. if (this.reverse){
  487. this.diffIndex--;
  488. if (this.diffIndex>=0){
  489. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  490. //this.doDiffsAnimation(obj, start, callback);
  491. }else{
  492. if (callback) callback();
  493. }
  494. }else{
  495. start += text.length;
  496. this.diffIndex++;
  497. if (this.diffIndex<this.currentDiffs.length){
  498. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  499. //this.doDiffsAnimation(obj, start, callback);
  500. }else{
  501. if (callback) callback();
  502. }
  503. }
  504. }else{
  505. this.initAnimationStatus();
  506. this.documentEditor.resetData();
  507. }
  508. if (cb) cb();
  509. }.bind(this));
  510. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  511. }.bind(this)
  512. if (!this.stop || !this.playing) {
  513. endFunction();
  514. } else{
  515. this.nextPlayPrefixFunction = endFunction;
  516. }
  517. this.checkToolbar();
  518. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  519. }.bind(this));
  520. break;
  521. case DIFF_DELETE:
  522. var text = diff[1];
  523. if (this.reverse){
  524. var left = this.currentHistoryData.substring(0, start);
  525. //var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  526. var right = this.currentHistoryData.substring(start);
  527. filetextNode.set("html", left+"<del style='color: red'>"+text+"</del>"+right);
  528. start -= text.length;
  529. }else{
  530. var left = this.currentHistoryData.substring(0, start);
  531. var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  532. var right = this.currentHistoryData.substring(start+diff[1].length);
  533. //start -= .length;
  534. filetextNode.set("html", left+"<del style='color: red'>"+middle+"</del>"+right);
  535. }
  536. var del = filetextNode.getElement("del");
  537. del.scrollIn();
  538. this.doDeleteAnimation(del, diff[1], obj, function(deleteInforDiv){
  539. // var deleteInforDiv = null;
  540. // if (!invisible){
  541. // deleteInforDiv = this.createDiifInforNode(obj, del, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent);
  542. // }
  543. var invisible = !deleteInforDiv;
  544. window.setTimeout(function(){
  545. var endFunction = function(cb){
  546. if (deleteInforDiv) deleteInforDiv.fade("out");
  547. var fx = new Fx.Tween(del, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  548. fx.start(0.5,0).chain(function(){
  549. if (deleteInforDiv) deleteInforDiv.destroy();
  550. if (this.reverse){
  551. data = filetextNode.get("html");
  552. this.currentHistoryData = data.replace(/<del[\s\S]*\/del>/m, text);
  553. filetextNode.set("html", this.currentHistoryData);
  554. }else{
  555. del.destroy();
  556. this.currentHistoryData = filetextNode.get("html");
  557. }
  558. if (this.playing){
  559. if (this.reverse){
  560. this.diffIndex--;
  561. if (this.diffIndex>=0){
  562. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  563. }else{
  564. if (callback) callback();
  565. }
  566. }else{
  567. this.diffIndex++;
  568. if (this.diffIndex<this.currentDiffs.length){
  569. window.setTimeout(function(){this.doDiffsAnimation(obj, start, callback);}.bind(this), this.options.speed*this.options.fxTime);
  570. }else{
  571. if (callback) callback();
  572. }
  573. }
  574. }else{
  575. this.initAnimationStatus();
  576. this.documentEditor.resetData();
  577. }
  578. if (cb) cb();
  579. }.bind(this));
  580. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  581. }.bind(this)
  582. if (!this.stop || !this.playing) {
  583. endFunction();
  584. } else{
  585. this.nextPlayPrefixFunction = endFunction;
  586. }
  587. this.checkToolbar();
  588. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  589. }.bind(this));
  590. break;
  591. case DIFF_EQUAL:
  592. if (this.reverse){
  593. start -= diff[1].length;
  594. this.diffIndex--;
  595. if (this.diffIndex>=0){
  596. this.doDiffsAnimation(obj, start, callback);
  597. }else{
  598. if (callback) callback();
  599. }
  600. }else{
  601. start += diff[1].length;
  602. this.diffIndex++;
  603. if (this.diffIndex<this.currentDiffs.length){
  604. this.doDiffsAnimation(obj, start, callback);
  605. }else{
  606. if (callback) callback();
  607. }
  608. }
  609. break;
  610. }
  611. },
  612. doInsetAnimation: function(node, str, callback){
  613. var tmp = new Element("div", {"html": str});
  614. if (!tmp.get("text").trim()){
  615. if (callback) callback(true);
  616. }else{
  617. var nodes = tmp.childNodes;
  618. this.doInsetNodeAnimation(node, nodes, 0, callback);
  619. }
  620. },
  621. doInsetNodeAnimation: function(ins, nodes, idx, callback){
  622. var node = nodes[idx];
  623. if (node.nodeType == Node.TEXT_NODE){
  624. this.doCharAnimation(ins, node.nodeValue, 0, function(){
  625. idx++;
  626. if (idx<nodes.length){
  627. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  628. }else{
  629. if (callback) callback();
  630. }
  631. }.bind(this));
  632. }else{
  633. var duration = this.options.speed*this.options.fxTime/nodes.length
  634. var span = new Element("span", {"styles": {"opacity": 0}}).inject(ins);
  635. span.appendChild(node);
  636. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  637. fx.start(0,1).chain(function(){
  638. idx++;
  639. if (idx<nodes.length){
  640. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  641. }else{
  642. if (callback) callback();
  643. }
  644. }.bind(this));
  645. }
  646. },
  647. doCharAnimation: function(node, str, idx, callback){
  648. var duration = this.options.speed*this.options.fxTime/str.length;
  649. var char = str.charAt(idx);
  650. var span = new Element("span", {"styles": {"opacity": 0}, "html": char}).inject(node);
  651. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  652. fx.start(0,1).chain(function(){
  653. idx++;
  654. if (idx<str.length){
  655. this.doCharAnimation(node, str, idx, callback);
  656. }else{
  657. if (callback) callback();
  658. }
  659. }.bind(this));
  660. },
  661. doDeleteAnimation: function(node, str, obj, callback){
  662. var tmp = new Element("div", {"html": str});
  663. if (!tmp.get("text").trim()){
  664. if (callback) callback(null);
  665. }else{
  666. deleteInforDiv = this.createDiifInforNode(obj, node, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent);
  667. var fx = new Fx.Tween(node, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  668. fx.start(1,0.5).chain(function(){
  669. if (callback) callback(deleteInforDiv);
  670. }.bind(this));
  671. }
  672. }
  673. });
  674. MWF.xApplication.process.Xform.widget.DocumentHistory.Item = new Class({
  675. initialize: function(history, patchObj){
  676. this.history = history;
  677. this.documentEditor = this.history.documentEditor;
  678. this.css = this.history.css;
  679. this.patchObj = patchObj;
  680. this.load();
  681. },
  682. load: function(){
  683. var patch = this.patchObj.patch;
  684. var obj = this.patchObj.obj;
  685. this.node = new Element("div", {"styles": this.css.historyListItemNode}).inject(this.history.historyListContentAreaNode);
  686. var patchHtml = "<div style='font-weight: bold; height: 30px; line-height: 30px'>"+o2.name.cn(obj.person)+" ["+obj.activityName+"]</div><div style='height: 20px; line-height: 20px; color:#666666'>"+obj.createTime+"</div>"
  687. this.patchNode = new Element("div", {"styles": this.css.historyListItemPatchNode, "html": html}).inject(this.node);
  688. this.diffsNode = new Element("div", {"styles": this.css.historyListItemDiffsNode}).inject(this.node);
  689. patch.diffs.each(function(diff){
  690. diffNode = new Element("div", {"styles": this.css.historyListItemDiffNode}).inject(this.diffsNode);
  691. }.bind(this));
  692. }
  693. })