DocumentHistory.js 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  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();
  23. this.loadHistoryToolbar();
  24. this.loadHistoryList();
  25. if (callback) callback();
  26. }.bind(this));
  27. }
  28. }.bind(this));
  29. },
  30. createHistoryToolbar: function(){
  31. this.documentEditor.documentToolbarNode = this.documentEditor.toolbarNode;
  32. this.toolbarNode = this.documentEditor.toolbarNode.clone(true);
  33. this.toolbarNode.inject(this.documentEditor.toolbarNode, "after");
  34. this.documentEditor.toolbarNode = this.toolbarNode;
  35. this.documentEditor.documentToolbarNode.hide();
  36. this.toolbarNode.empty();
  37. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.hide();
  38. },
  39. loadHistoryToolbar: function(){
  40. 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>";
  41. 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>";
  42. 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>";
  43. html += "<span MWFnodetype=\"MWFToolBarSeparator\"></span>";
  44. 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>";
  45. 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>";
  46. html += "<span MWFnodetype=\"MWFToolBarSeparator\"></span>";
  47. 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>";
  48. html += "<span MWFnodetype=\"MWFToolBarSeparator\"></span>";
  49. var text = MWF.xApplication.process.Xform.LP.documentHistory.diff_patch_count;
  50. text = text.replace(/{history}/, this.historyDataList.length).replace(/{diff}/, this.diffCount);
  51. html += "<span style='float: left; line-height: 24px; color: #666666; margin-left: 10px'>"+text+"</span>";
  52. this.toolbarNode.set("html", html);
  53. MWF.require("MWF.widget.Toolbar", function() {
  54. this.toolbar = new MWF.widget.Toolbar(this.toolbarNode, {"style": "documentEdit"}, this);
  55. this.toolbar.load();
  56. this.checkToolbar();
  57. }.bind(this));
  58. },
  59. checkToolbar: function(){
  60. if (this.toolbar){
  61. if (this.playing){
  62. if (this.stop){
  63. this.toolbar.childrenButton[0].enable();
  64. this.toolbar.childrenButton[1].disable();
  65. if (this.patchIndex==0 && this.diffIndex==0){
  66. this.toolbar.childrenButton[3].disable();
  67. if (this.diffPatch.length) this.toolbar.childrenButton[4].enable();
  68. }else{
  69. if (this.patchIndex<this.diffPatch.length-1){
  70. this.toolbar.childrenButton[3].enable();
  71. this.toolbar.childrenButton[4].enable();
  72. }else if (this.patchIndex<this.diffPatch.length && this.diffIndex < this.diffPatch[this.patchIndex].patch.diffs.length){
  73. this.toolbar.childrenButton[3].enable();
  74. this.toolbar.childrenButton[4].enable();
  75. }else{
  76. if (this.diffPatch.length) this.toolbar.childrenButton[3].enable();
  77. this.toolbar.childrenButton[4].disable();
  78. }
  79. }
  80. }else{
  81. this.toolbar.childrenButton[0].disable();
  82. this.toolbar.childrenButton[1].enable();
  83. this.toolbar.childrenButton[3].disable();
  84. this.toolbar.childrenButton[4].disable();
  85. }
  86. this.toolbar.childrenButton[2].enable();
  87. }else{
  88. this.toolbar.childrenButton[0].enable();
  89. this.toolbar.childrenButton[1].disable();
  90. this.toolbar.childrenButton[2].disable();
  91. if (this.patchIndex==0 && this.diffIndex==0){
  92. this.toolbar.childrenButton[3].disable();
  93. if (this.diffPatch.length) this.toolbar.childrenButton[4].enable();
  94. }else{
  95. if (this.patchIndex<this.diffPatch.length-1){
  96. this.toolbar.childrenButton[3].enable();
  97. this.toolbar.childrenButton[4].enable();
  98. }else if (this.patchIndex<this.diffPatch.length && this.diffIndex < this.diffPatch[this.patchIndex].patch.diffs.length){
  99. this.toolbar.childrenButton[3].enable();
  100. this.toolbar.childrenButton[4].enable();
  101. }else{
  102. if (this.diffPatch.length) this.toolbar.childrenButton[3].enable();
  103. this.toolbar.childrenButton[4].disable();
  104. }
  105. }
  106. }
  107. }
  108. },
  109. createHistoryListNode: function(){
  110. this.historyListAreaNode = new Element("div", {"styles": this.css.historyListAreaNode}).inject(this.documentEditor.contentNode, "before");
  111. this.documentEditor.contentNode.setStyle("width", "auto");
  112. this.documentEditor.zoom(1);
  113. this.documentEditor._checkScale();
  114. var size = this.documentEditor.node.getSize();
  115. var toolbarSize = this.documentEditor.toolbarNode.getSize();
  116. var h = size.y-toolbarSize.y;
  117. this.historyListAreaNode.setStyle("height", ""+h+"px");
  118. this.historyListTitleAreaNode = new Element("div", {"styles": this.css.historyListTitleAreaNode}).inject(this.historyListAreaNode);
  119. this.historyListContentAreaNode = new Element("div", {"styles": this.css.historyListContentAreaNode}).inject(this.historyListAreaNode);
  120. var y = this.historyListContentAreaNode.getEdgeHeight();
  121. var title_y = this.historyListTitleAreaNode.getComputedSize().totalHeight;
  122. h = h-y-title_y;
  123. this.historyListContentAreaNode.setStyle("height", ""+h+"px");
  124. this.historyListTitleNode = new Element("div", {"styles": this.css.historyListTitleNode}).inject(this.historyListTitleAreaNode);
  125. this.historyListTitleInsertNode = new Element("div", {"styles": this.css.historyListTitleInsertNode}).inject(this.historyListTitleAreaNode);
  126. this.historyListTitleDeleteNode = new Element("div", {"styles": this.css.historyListTitleDeleteNode}).inject(this.historyListTitleAreaNode);
  127. },
  128. loadHistoryList: function(){
  129. var text = MWF.xApplication.process.Xform.LP.documentHistory.diff_patch_count;
  130. text = text.replace(/{history}/, this.historyDataList.length).replace(/{diff}/, this.diffCount);
  131. var insertStr = MWF.xApplication.process.Xform.LP.documentHistory.insertTimes;
  132. var deleteStr = MWF.xApplication.process.Xform.LP.documentHistory.deleteTimes;
  133. insertStr = insertStr.replace(/{times}/, this.diffInsertCount);
  134. deleteStr = deleteStr.replace(/{times}/, this.diffDeleteCount);
  135. this.historyListTitleNode.set("text", text);
  136. this.historyListTitleInsertNode.set("text", insertStr);
  137. this.historyListTitleDeleteNode.set("text", deleteStr);
  138. //var original = this.historyDataList[0];
  139. //this.createHistoryListItem(original);
  140. this.historyDataList.each(function(historyData){
  141. this.createHistoryListItem(historyData);
  142. }.bind(this));
  143. // this.diffPatch.each(function(patchObj){
  144. // this.createHistoryListItem(patchObj);
  145. // }.bind(this));
  146. },
  147. createHistoryListItem: function(historyData){
  148. new MWF.xApplication.process.Xform.widget.DocumentHistory.Item(this, historyData);
  149. },
  150. getHistoryDataList: function(callback){
  151. // if (this.historyDataList && this.historyDataList.length){
  152. // this.getHistoryDataListFinish(this.historyDataList);
  153. // if (callback) callback();
  154. // }else{
  155. var historyDataList = [];
  156. var getDataCount = 0;
  157. var idx = 0;
  158. var checkBeginDiffHistory = function(){
  159. if (getDataCount>=this.historyDocumentList.length){
  160. this.getHistoryDataListFinish(historyDataList, callback);
  161. }
  162. }.bind(this);
  163. for (var i=this.historyDocumentList.length-1; i>=0; i--){
  164. historyDataList.push(null);
  165. this.getHistroyDocumentData(this.historyDocumentList[i].id, function(){
  166. getDataCount++;
  167. checkBeginDiffHistory();
  168. }.bind(this), idx, historyDataList);
  169. idx++;
  170. }
  171. //}
  172. },
  173. getHistoryDataListFinish: function(historyDataList, callback){
  174. this.historyDataList = historyDataList;
  175. this.originaHistoryData = historyDataList[0].json.data || null;
  176. if (this.documentEditor.allowEdit){
  177. o2.load("/o2_lib/diff-match-patch/diff_match_patch_uncompressed.js", function(){
  178. var originaData = this.documentEditor.form.businessData.originalData[this.documentEditor.json.id];
  179. var data = this.documentEditor.data.filetext;
  180. var earlyData = originaData.filetext;
  181. if (data!=earlyData){
  182. var dmp = new diff_match_patch();
  183. var diff_d = dmp.diff_main(earlyData, data);
  184. dmp.diff_cleanupSemantic(diff_d);
  185. var patch_list = dmp.patch_make(earlyData, data, diff_d);
  186. if (patch_list.length){
  187. var patch = dmp.patch_toText(patch_list);
  188. var patchData = JSON.stringify({"patchs": patch});
  189. var currentData = {
  190. "data": patchData,
  191. "json": {"patchs": patch},
  192. "person": layout.session.user.distinguishedName,
  193. "activityName": this.documentEditor.form.businessData.activity.name,
  194. "createTime" : (new Date()).format("db")
  195. };
  196. this.historyDataList.push(currentData);
  197. }
  198. }
  199. if (callback) callback();
  200. }.bind(this));
  201. }else{
  202. if (callback) callback();
  203. }
  204. },
  205. getHistroyDocumentData: function(id, callback, i, historyDataList){
  206. o2.Actions.load("x_processplatform_assemble_surface").DocumentVersionAction.get(id, function(json){
  207. var obj = JSON.parse(json.data.data);
  208. json.data.json = obj;
  209. if (historyDataList) historyDataList[i] = json.data;
  210. if (callback) callback(json.data);
  211. }.bind(this));
  212. },
  213. getHistroyDocumentList: function(callback){
  214. //if (!this.historyDocumentList){
  215. var id = this.documentEditor.form.businessData.work.job;
  216. o2.Actions.load("x_processplatform_assemble_surface").DocumentVersionAction.listWithJobCategory(id, this.documentEditor.json.id, function(json){
  217. this.historyDocumentList = json.data;
  218. if (callback) callback();
  219. }.bind(this));
  220. //}else{
  221. // if (callback) callback();
  222. //}
  223. },
  224. beginDiffHistory: function(){
  225. //o2.load("/o2_lib/diff-match-patch/diff_match_patch_uncompressed.js", function(){
  226. this.initAnimation();
  227. //if (callback) callback();
  228. //}.bind(this));
  229. },
  230. initAnimation: function(){
  231. this.diffPatch = this.diffHistroy();
  232. this.diffCount = 0;
  233. this.diffInsertCount = 0;
  234. this.diffDeleteCount = 0;
  235. this.diffPatch.each(function(patch){
  236. patch.patch.diffs.each(function(diff){
  237. if (diff[0]!=0) this.diffCount++;
  238. if (diff[0]==-1) this.diffDeleteCount++;
  239. if (diff[0]==1) this.diffInsertCount++;
  240. }.bind(this));
  241. }.bind(this));
  242. // this.initData();
  243. this.initAnimationStatus();
  244. },
  245. initData: function(){
  246. this.currentHistoryData = this.originaHistoryData;
  247. this.documentEditor.layout_filetext.set("html", this.currentHistoryData);
  248. this.patchIndex = 0;
  249. this.diffIndex = 0;
  250. if (this.originaDiff) this.originaDiff.showCurrent();
  251. },
  252. initAnimationStatus: function(){
  253. this.patchIndex = 0;
  254. this.diffIndex = 0;
  255. this.currentDiffs = null;
  256. this.stop = true;
  257. this.step = false;
  258. this.playing = false;
  259. this.reverse = false;
  260. this.options.fxTime = 500;
  261. this.options.inforTime = 2000;
  262. this.checkToolbar();
  263. },
  264. doAnimationAuto: function(){
  265. this.playing = true;
  266. this.checkToolbar();
  267. this.doPatchAnimation(function(){
  268. this.patchIndex = 0;
  269. this.diffIndex = 0;
  270. this.playing = false;
  271. this.stop = true;
  272. this.documentEditor.resetData();
  273. this.checkToolbar();
  274. }.bind(this));
  275. },
  276. do: function(){
  277. if (this.nextPlayPrefixFunction){
  278. this.nextPlayPrefixFunction();
  279. this.nextPlayPrefixFunction = null;
  280. }else{
  281. this.doAnimationAuto();
  282. }
  283. },
  284. play: function(){
  285. if (!this.playing){
  286. this.initData();
  287. this.initAnimationStatus();
  288. }
  289. this.reverse = false;
  290. this.stop = false;
  291. this.stopWhile = "";
  292. this.options.fxTime = 500;
  293. this.options.inforTime = 2000;
  294. this.toolbar.childrenButton[0].disable();
  295. this.toolbar.childrenButton[3].disable();
  296. this.toolbar.childrenButton[4].disable();
  297. this.do();
  298. },
  299. stopPlay: function(){
  300. if (this.playing){
  301. this.stop = true;
  302. this.playing = false;
  303. if (this.nextPlayPrefixFunction){
  304. this.nextPlayPrefixFunction();
  305. this.nextPlayPrefixFunction = null;
  306. }
  307. this.patchIndex = 0;
  308. this.diffIndex = 0;
  309. this.toolbar.childrenButton[1].disable();
  310. this.toolbar.childrenButton[2].disable();
  311. }
  312. },
  313. pause: function(){
  314. if (this.playing){
  315. this.stop = true;
  316. this.toolbar.childrenButton[1].disable();
  317. this.toolbar.childrenButton[2].disable();
  318. }
  319. },
  320. next: function(){
  321. this.reverse = false;
  322. this.options.fxTime = 0;
  323. this.options.inforTime = 0;
  324. this.stop = true;
  325. this.toolbar.childrenButton[3].disable();
  326. this.toolbar.childrenButton[4].disable();
  327. if (!this.playing) this.initData();
  328. this.do();
  329. },
  330. prev: function(){
  331. this.reverse = true;
  332. this.options.fxTime = 0;
  333. this.options.inforTime = 0;
  334. this.stop = true;
  335. this.toolbar.childrenButton[3].disable();
  336. this.toolbar.childrenButton[4].disable();
  337. if (!this.playing) this.initData();
  338. this.do();
  339. },
  340. to: function(diff){
  341. if (this.nextPlayPrefixFunction){
  342. this.playing = false;
  343. this.nextPlayPrefixFunction(function(){
  344. this.initData();
  345. this.initAnimationStatus();
  346. this.reverse = false;
  347. this.options.fxTime = 0;
  348. this.options.inforTime = 0;
  349. this.stop = false;
  350. this.stopWhile = diff.id;
  351. this.toolbar.childrenButton[3].disable();
  352. this.toolbar.childrenButton[4].disable();
  353. this.doAnimationAuto(diff.id);
  354. }.bind(this));
  355. //this.nextPlayPrefixFunction = null;
  356. }else{
  357. this.initData();
  358. this.initAnimationStatus();
  359. this.reverse = false;
  360. this.options.fxTime = 0;
  361. this.options.inforTime = 0;
  362. this.stop = false;
  363. this.stopWhile = diff.id;
  364. this.toolbar.childrenButton[3].disable();
  365. this.toolbar.childrenButton[4].disable();
  366. this.doAnimationAuto(diff.id);
  367. }
  368. },
  369. origina: function(){
  370. if (this.nextPlayPrefixFunction){
  371. this.playing = false;
  372. this.nextPlayPrefixFunction(function(){
  373. this.initData();
  374. this.initAnimationStatus();
  375. }.bind(this));
  376. this.nextPlayPrefixFunction = null;
  377. }else{
  378. this.initData();
  379. this.initAnimationStatus();
  380. }
  381. },
  382. exit: function(){
  383. this.initAnimationStatus();
  384. this.options.fxTime = 0;
  385. this.options.inforTime = 0;
  386. if (this.nextPlayPrefixFunction){
  387. this.nextPlayPrefixFunction(function(){
  388. this.documentEditor.toolbarNode = this.documentEditor.documentToolbarNode;
  389. this.documentEditor.toolbarNode.show();
  390. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.show();
  391. this.documentEditor.resizeToolbar();
  392. }.bind(this));
  393. this.nextPlayPrefixFunction = null;
  394. }else{
  395. this.documentEditor.toolbarNode = this.documentEditor.documentToolbarNode;
  396. this.documentEditor.toolbarNode.show();
  397. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.show();
  398. this.documentEditor.resizeToolbar();
  399. }
  400. this.historyListAreaNode.destroy();
  401. this.historyListAreaNode = null;
  402. this.documentEditor.zoom(1);
  403. this.documentEditor._checkScale();
  404. this.documentEditor.resetData();
  405. this.toolbarNode.hide();
  406. },
  407. active: function(callback){
  408. this.getHistroyDocumentList(function(){
  409. if (this.historyDocumentList && this.historyDocumentList.length){
  410. this.getHistoryDataList(function(){
  411. this.documentEditor.options.pageShow = "single";
  412. this.documentEditor.resetData();
  413. this.beginDiffHistory();
  414. this.documentEditor.resetData();
  415. this.toolbarNode.show();
  416. this.documentEditor.documentToolbarNode = this.documentEditor.toolbarNode;
  417. this.documentEditor.documentToolbarNode.hide();
  418. if (this.documentEditor.sidebarNode) this.documentEditor.sidebarNode.hide();
  419. this.documentEditor.toolbarNode = this.toolbarNode;
  420. this.documentEditor.resizeToolbar();
  421. var text = MWF.xApplication.process.Xform.LP.documentHistory.diff_patch_count;
  422. text = text.replace(/{history}/, this.historyDataList.length).replace(/{diff}/, this.diffCount);
  423. this.toolbarNode.getLast().set("html", text);
  424. this.createHistoryListNode();
  425. this.loadHistoryList();
  426. this.documentEditor.options.pageShow = "single";
  427. this.documentEditor.resetData();
  428. if (callback) callback();
  429. }.bind(this));
  430. }
  431. }.bind(this));
  432. },
  433. diffHistroy: function(){
  434. var diffPatch = [];
  435. //var historyPatchs = [];
  436. for (var i=1; i<this.historyDataList.length; i++){
  437. // var earlyDataText = this.historyDataList[i-1].data;
  438. // var laterData = this.historyDataList[i];
  439. //
  440. // var dmp = new diff_match_patch();
  441. // // dmp.Diff_Timeout = parseFloat(10);
  442. // // dmp.Diff_EditCost = parseFloat(4);
  443. // var diff_d = dmp.diff_main(earlyDataText, laterData.data);
  444. // dmp.diff_cleanupSemantic(diff_d);
  445. // var patch_list = dmp.patch_make(earlyDataText, laterData.data, diff_d);
  446. //historyPatchs.push({"patch_list": patch_list, "obj": laterData});
  447. var history = this.historyDataList[i];
  448. var data = history.json;
  449. history.json = data;
  450. if (data.patchs){
  451. var dmp = new diff_match_patch();
  452. var patch_list = dmp.patch_fromText(data.patchs);
  453. history.json.patchObj = patch_list;
  454. patch_list.each(function(patch){
  455. diffPatch.push({"patch":patch, "obj": history});
  456. }.bind(this));
  457. }
  458. }
  459. return diffPatch;
  460. },
  461. doPatchAnimation: function(callback){
  462. var patchObj = this.diffPatch[this.patchIndex];
  463. var patch = patchObj.patch;
  464. var obj = patchObj.obj;
  465. this.currentDiffs = patch.diffs;
  466. this.diffIndex = (this.reverse) ? patch.diffs.length-1 : 0;
  467. var start = (this.reverse) ? patch.start1+patch.length2 : patch.start1;
  468. this.doDiffsAnimation(obj, start, function(){
  469. if (this.reverse){
  470. this.patchIndex--;
  471. if (this.patchIndex>=0){
  472. this.currentHistoryData = this.documentEditor.layout_filetext.get("html");
  473. this.doPatchAnimation(callback);
  474. }else{
  475. if (callback) callback();
  476. }
  477. }else{
  478. this.patchIndex++;
  479. if (this.patchIndex<this.diffPatch.length){
  480. this.currentHistoryData = this.documentEditor.layout_filetext.get("html");
  481. this.doPatchAnimation(callback);
  482. }else{
  483. if (callback) callback();
  484. }
  485. }
  486. }.bind(this));
  487. },
  488. doPatchAnimationStep: function(i){
  489. if (this.patchIndex>this.diffPatch.length || this.patchIndex<0){
  490. this.initAnimationStatus();
  491. this.documentEditor.resetData();
  492. this.checkToolbar();
  493. }else{
  494. var patchObj = this.diffPatch[this.patchIndex];
  495. var patch = patchObj.patch;
  496. var obj = patchObj.obj;
  497. this.currentDiffs = patch.diffs;
  498. this.diffIndex = 0;
  499. this.doDiffsAnimation(obj, patch.start1);
  500. this.patchIndex = this.patchIndex+i;
  501. }
  502. },
  503. createDiifInforNode: function(obj, node, color, insertInfor){
  504. var insertInforDiv = new Element("div", { "styles": this.css.historyInforNode }).inject(this.documentEditor.node);
  505. insertInforDiv.setStyle("background", color);
  506. insertInfor = insertInfor.replace(/{name}/, o2.name.cn(obj.person))
  507. .replace(/{activity}/, obj.activityName)
  508. .replace(/{time}/, obj.createTime);
  509. insertInforDiv.set("html", insertInfor);
  510. insertInforDiv.position({
  511. "relativeTo": node,
  512. "position": 'upperCenter',
  513. "edge": 'bottomCenter',
  514. "offset": {
  515. "x": 0, "y": -10
  516. }
  517. });
  518. return insertInforDiv;
  519. },
  520. doDiffsAnimation: function(obj, start, callback){
  521. var diff = this.currentDiffs[this.diffIndex];
  522. var filetextNode = this.documentEditor.layout_filetext;
  523. switch (diff[0]) {
  524. case DIFF_INSERT:
  525. if (diff["item"]) diff["item"].showCurrent((!this.stopWhile || this.stopWhile == diff["id"]));
  526. if (this.originaDiff) this.originaDiff.hideCurrent();
  527. var text = diff[1];
  528. if (this.reverse){
  529. start -= text.length;
  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. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  534. }else{
  535. var left = this.currentHistoryData.substring(0, start);
  536. var right = this.currentHistoryData.substring(start);
  537. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  538. }
  539. var ins = filetextNode.getElement("ins");
  540. if (!this.stopWhile || this.stopWhile == diff["id"]) ins.scrollIn();
  541. this.doInsetAnimation(ins, diff[1], function(invisible){
  542. var insertInforDiv = null;
  543. if (!invisible && (!this.stopWhile || this.stopWhile == diff["id"]) ){
  544. insertInforDiv = this.createDiifInforNode(obj, ins, "#e2edfb", MWF.xApplication.process.Xform.LP.documentHistory.insertContent);
  545. }
  546. window.setTimeout(function(){
  547. var endFunction = function(cb){
  548. if (insertInforDiv) insertInforDiv.fade("out");
  549. var fx = new Fx.Tween(ins, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  550. fx.start(1.1).chain(function(){
  551. if (insertInforDiv) insertInforDiv.destroy();
  552. if (diff["item"]) diff["item"].hideCurrent();
  553. if (this.reverse){
  554. ins.destroy();
  555. this.currentHistoryData = filetextNode.get("html");
  556. }else{
  557. data = filetextNode.get("html");
  558. this.currentHistoryData = data.replace(/<ins[\s\S]*\/ins>/m, text);
  559. filetextNode.set("html", this.currentHistoryData);
  560. }
  561. if (this.playing){
  562. if (this.reverse){
  563. this.diffIndex--;
  564. if (this.diffIndex>=0){
  565. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  566. if (callback) callback();
  567. if (cb) cb();
  568. });}.bind(this), this.options.speed*this.options.fxTime);
  569. //this.doDiffsAnimation(obj, start, callback);
  570. }else{
  571. if (callback) callback();
  572. }
  573. }else{
  574. start += text.length;
  575. this.diffIndex++;
  576. if (this.diffIndex<this.currentDiffs.length){
  577. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  578. if (callback) callback();
  579. if (cb) cb();
  580. });}.bind(this), this.options.speed*this.options.fxTime);
  581. //this.doDiffsAnimation(obj, start, callback);
  582. }else{
  583. if (callback) callback();
  584. }
  585. }
  586. }else{
  587. this.initAnimationStatus();
  588. this.documentEditor.resetData();
  589. if (cb) cb();
  590. }
  591. }.bind(this));
  592. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  593. }.bind(this)
  594. if (this.stopWhile) if (this.stopWhile == diff["id"]) this.stop = true;
  595. if (!this.stop || !this.playing) {
  596. endFunction();
  597. } else{
  598. if (this.stopWhile){
  599. this.stopWhile = "";
  600. //this.playing = false;
  601. }
  602. this.nextPlayPrefixFunction = endFunction;
  603. }
  604. this.checkToolbar();
  605. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  606. }.bind(this));
  607. break;
  608. case DIFF_DELETE:
  609. if (diff["item"]) diff["item"].showCurrent((!this.stopWhile || this.stopWhile == diff["id"]));
  610. if (this.originaDiff) this.originaDiff.hideCurrent();
  611. var text = diff[1];
  612. if (this.reverse){
  613. var left = this.currentHistoryData.substring(0, start);
  614. //var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  615. var right = this.currentHistoryData.substring(start);
  616. filetextNode.set("html", left+"<del style='color: red'>"+text+"</del>"+right);
  617. start -= text.length;
  618. }else{
  619. var left = this.currentHistoryData.substring(0, start);
  620. var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  621. var right = this.currentHistoryData.substring(start+diff[1].length);
  622. //start -= .length;
  623. filetextNode.set("html", left+"<del style='color: red'>"+middle+"</del>"+right);
  624. }
  625. var del = filetextNode.getElement("del");
  626. if (!this.stopWhile || this.stopWhile == diff["id"]) del.scrollIn();
  627. this.doDeleteAnimation(del, diff, obj, function(deleteInforDiv){
  628. // var deleteInforDiv = null;
  629. // if (!invisible){
  630. // deleteInforDiv = this.createDiifInforNode(obj, del, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent);
  631. // }
  632. var invisible = !deleteInforDiv;
  633. window.setTimeout(function(){
  634. var endFunction = function(cb){
  635. if (deleteInforDiv) deleteInforDiv.fade("out");
  636. var fx = new Fx.Tween(del, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  637. fx.start(0.5,0).chain(function(){
  638. if (deleteInforDiv) deleteInforDiv.destroy();
  639. if (diff["item"]) diff["item"].hideCurrent();
  640. if (this.reverse){
  641. data = filetextNode.get("html");
  642. this.currentHistoryData = data.replace(/<del[\s\S]*\/del>/m, text);
  643. filetextNode.set("html", this.currentHistoryData);
  644. }else{
  645. del.destroy();
  646. this.currentHistoryData = filetextNode.get("html");
  647. }
  648. if (this.playing){
  649. if (this.reverse){
  650. this.diffIndex--;
  651. if (this.diffIndex>=0){
  652. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  653. if (callback) callback();
  654. if (cb) cb();
  655. });}.bind(this), this.options.speed*this.options.fxTime);
  656. }else{
  657. if (callback) callback();
  658. }
  659. }else{
  660. this.diffIndex++;
  661. if (this.diffIndex<this.currentDiffs.length){
  662. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  663. if (callback) callback();
  664. if (cb) cb();
  665. });}.bind(this), this.options.speed*this.options.fxTime);
  666. }else{
  667. if (callback) callback();
  668. }
  669. }
  670. }else{
  671. this.initAnimationStatus();
  672. this.documentEditor.resetData();
  673. if (cb) cb();
  674. }
  675. }.bind(this));
  676. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  677. }.bind(this)
  678. if (this.stopWhile){
  679. if (this.stopWhile == diff["id"]) this.stop = true;
  680. }
  681. if (!this.stop || !this.playing) {
  682. endFunction();
  683. } else{
  684. if (this.stopWhile){
  685. this.stopWhile = "";
  686. //this.playing = false;
  687. }
  688. this.nextPlayPrefixFunction = endFunction;
  689. }
  690. this.checkToolbar();
  691. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  692. }.bind(this));
  693. break;
  694. case DIFF_EQUAL:
  695. if (this.reverse){
  696. start -= diff[1].length;
  697. this.diffIndex--;
  698. if (this.diffIndex>=0){
  699. this.doDiffsAnimation(obj, start, callback);
  700. }else{
  701. if (callback) callback();
  702. }
  703. }else{
  704. start += diff[1].length;
  705. this.diffIndex++;
  706. if (this.diffIndex<this.currentDiffs.length){
  707. this.doDiffsAnimation(obj, start, callback);
  708. }else{
  709. if (callback) callback();
  710. }
  711. }
  712. break;
  713. }
  714. },
  715. doInsetAnimation: function(node, str, callback){
  716. var tmp = new Element("div", {"html": str});
  717. if (!tmp.get("text").trim()){
  718. if (callback) callback(true);
  719. }else{
  720. var nodes = tmp.childNodes;
  721. this.doInsetNodeAnimation(node, nodes, 0, callback);
  722. }
  723. },
  724. doInsetNodeAnimation: function(ins, nodes, idx, callback){
  725. var node = nodes[idx];
  726. if (node.nodeType == Node.TEXT_NODE){
  727. this.doCharAnimation(ins, node.nodeValue, 0, function(){
  728. idx++;
  729. if (idx<nodes.length){
  730. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  731. }else{
  732. if (callback) callback();
  733. }
  734. }.bind(this));
  735. }else{
  736. var duration = this.options.speed*this.options.fxTime/nodes.length
  737. var span = new Element("span", {"styles": {"opacity": 0}}).inject(ins);
  738. span.appendChild(node);
  739. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  740. fx.start(0,1).chain(function(){
  741. idx++;
  742. if (idx<nodes.length){
  743. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  744. }else{
  745. if (callback) callback();
  746. }
  747. }.bind(this));
  748. }
  749. },
  750. doCharAnimation: function(node, str, idx, callback){
  751. var duration = this.options.speed*this.options.fxTime/str.length;
  752. var char = str.charAt(idx);
  753. var span = new Element("span", {"styles": {"opacity": 0}, "html": char}).inject(node);
  754. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  755. fx.start(0,1).chain(function(){
  756. idx++;
  757. if (idx<str.length){
  758. this.doCharAnimation(node, str, idx, callback);
  759. }else{
  760. if (callback) callback();
  761. }
  762. }.bind(this));
  763. },
  764. doDeleteAnimation: function(node, diff, obj, callback){
  765. var str = diff[1];
  766. var tmp = new Element("div", {"html": str});
  767. if (!tmp.get("text").trim()){
  768. if (callback) callback(null);
  769. }else{
  770. var deleteInforDiv = (!this.stopWhile || this.stopWhile == diff["id"]) ? this.createDiifInforNode(obj, node, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent) : null;
  771. var fx = new Fx.Tween(node, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  772. fx.start(1,0.5).chain(function(){
  773. if (callback) callback(deleteInforDiv);
  774. }.bind(this));
  775. }
  776. }
  777. });
  778. MWF.xApplication.process.Xform.widget.DocumentHistory.Item = new Class({
  779. initialize: function(history, historyData){
  780. this.history = history;
  781. this.documentEditor = this.history.documentEditor;
  782. this.css = this.history.css;
  783. this.historyData = historyData;
  784. this.load();
  785. },
  786. load: function(){
  787. var patchs = this.historyData.json.patchObj || null;
  788. var obj = this.historyData;
  789. this.node = new Element("div", {"styles": this.css.historyListItemNode}).inject(this.history.historyListContentAreaNode);
  790. 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>"
  791. this.patchNode = new Element("div", {"styles": this.css.historyListItemPatchNode, "html": patchHtml}).inject(this.node);
  792. this.diffsNode = new Element("div", {"styles": this.css.historyListItemDiffsNode}).inject(this.node);
  793. var _self = this;
  794. if (patchs){
  795. patchs.each(function(patch){
  796. patch.diffs.each(function(diff){
  797. if (diff[0]!=0){
  798. diff["id"] = (new o2.widget.UUID()).toString();
  799. var tmp = new Element("div", {"html": diff[1]});
  800. infor = tmp.get("text");
  801. var infor = ((infor.length>50) ? infor.substring(0, 50)+"..." : infor);
  802. tmp.destroy();
  803. if (diff[0]==-1){
  804. infor = MWF.xApplication.process.Xform.LP.documentHistory.delete +": "+"<span style='color:red'><del>"+infor+"</del></span>"
  805. }else{
  806. infor = MWF.xApplication.process.Xform.LP.documentHistory.insert +": "+"<span style='color:blue'><ins>"+infor+"</ins></span>"
  807. }
  808. diffNode = new Element("div", {"styles": this.css.historyListItemDiffNode, "html": infor}).inject(this.diffsNode);
  809. diffNode.store("diff", diff);
  810. diff["item"] = {
  811. "node": diffNode,
  812. "showCurrent": function(show){
  813. var thisDiff = this.node.retrieve("diff");
  814. var color = (thisDiff[0]==-1) ? "#fbe0e7": "#e2edfb";
  815. this.node.setStyles({"background-color": color});
  816. var ss = _self.history.historyListContentAreaNode.getScrollSize();
  817. var s = _self.history.historyListContentAreaNode.getSize();
  818. if (ss.y>s.y) if (show) this.node.scrollIn();
  819. },
  820. "hideCurrent": function(){
  821. this.node.setStyles(_self.css.historyListItemDiffNode);
  822. }
  823. };
  824. diffNode.addEvents({
  825. // "mouseover": function(){
  826. // if (_self.history.stop){
  827. // var diff = this.retrieve("diff");
  828. // var color = (diff[0]==-1) ? "red": "blue";
  829. // this.setStyles({"border-color": color});
  830. // }
  831. // },
  832. // "mouseout": function(){ if (_self.history.stop) this.setStyles(_self.css.historyListItemDiffNode_out) },
  833. "click": function(){
  834. if (_self.history.stop){
  835. var diff = this.retrieve("diff");
  836. _self.history.to(diff);
  837. }
  838. }
  839. });
  840. }
  841. }.bind(this));
  842. }.bind(this));
  843. }else{
  844. infor = MWF.xApplication.process.Xform.LP.documentHistory.original;
  845. diffNode = new Element("div", {"styles": this.css.historyListItemDiffNode, "html": infor}).inject(this.diffsNode);
  846. this.history.originaDiff = {
  847. "node": diffNode,
  848. "showCurrent": function(){
  849. this.node.setStyles({"background-color": "#e2edfb"});
  850. //if (show) this.node.scrollIn();
  851. },
  852. "hideCurrent": function(){
  853. this.node.setStyles(_self.css.historyListItemDiffNode);
  854. }
  855. };
  856. diffNode.addEvents({
  857. "click": function(){
  858. if (_self.history.stop){
  859. _self.history.origina();
  860. }
  861. }
  862. });
  863. }
  864. }
  865. })