DocumentHistory.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  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. if (this.historyInforDiv){
  505. this.historyInforDiv.dispose();
  506. this.historyInforDiv = null;
  507. }
  508. var insertInforDiv = new Element("div", { "styles": this.css.historyInforNode }).inject(this.documentEditor.node);
  509. insertInforDiv.setStyle("background", color);
  510. insertInfor = insertInfor.replace(/{name}/, o2.name.cn(obj.person))
  511. .replace(/{activity}/, obj.activityName)
  512. .replace(/{time}/, obj.createTime);
  513. insertInforDiv.set("html", insertInfor);
  514. insertInforDiv.position({
  515. "relativeTo": node,
  516. "position": 'upperCenter',
  517. "edge": 'bottomCenter',
  518. "offset": {
  519. "x": 0, "y": -10
  520. }
  521. });
  522. this.historyInforDiv = insertInforDiv;
  523. return insertInforDiv;
  524. },
  525. doDiffsAnimation: function(obj, start, callback){
  526. var diff = this.currentDiffs[this.diffIndex];
  527. var filetextNode = this.documentEditor.layout_filetext;
  528. switch (diff[0]) {
  529. case DIFF_INSERT:
  530. if (diff["item"]) diff["item"].showCurrent((!this.stopWhile || this.stopWhile == diff["id"]));
  531. if (this.originaDiff) this.originaDiff.hideCurrent();
  532. var text = diff[1];
  533. if (this.reverse){
  534. start -= text.length;
  535. var left = this.currentHistoryData.substring(0, start);
  536. var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  537. var right = this.currentHistoryData.substring(start+diff[1].length);
  538. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  539. }else{
  540. var left = this.currentHistoryData.substring(0, start);
  541. var right = this.currentHistoryData.substring(start);
  542. filetextNode.set("html", left+"<ins style='color:blue;'></ins>"+right);
  543. }
  544. var ins = filetextNode.getElement("ins");
  545. if (!this.stopWhile || this.stopWhile == diff["id"]) ins.scrollIn();
  546. this.doInsetAnimation(ins, diff[1], function(invisible){
  547. var insertInforDiv = null;
  548. if (!invisible && (!this.stopWhile || this.stopWhile == diff["id"]) ){
  549. insertInforDiv = this.createDiifInforNode(obj, ins, "#e2edfb", MWF.xApplication.process.Xform.LP.documentHistory.insertContent);
  550. }
  551. window.setTimeout(function(){
  552. var endFunction = function(cb){
  553. if (insertInforDiv) insertInforDiv.fade("out");
  554. var fx = new Fx.Tween(ins, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  555. fx.start(1.1).chain(function(){
  556. if (insertInforDiv) insertInforDiv.destroy();
  557. if (diff["item"]) diff["item"].hideCurrent();
  558. if (this.reverse){
  559. ins.destroy();
  560. this.currentHistoryData = filetextNode.get("html");
  561. }else{
  562. data = filetextNode.get("html");
  563. this.currentHistoryData = data.replace(/<ins[\s\S]*\/ins>/m, text);
  564. filetextNode.set("html", this.currentHistoryData);
  565. }
  566. if (this.playing){
  567. if (this.reverse){
  568. this.diffIndex--;
  569. if (this.diffIndex>=0){
  570. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  571. if (callback) callback();
  572. if (cb) cb();
  573. });}.bind(this), this.options.speed*this.options.fxTime);
  574. //this.doDiffsAnimation(obj, start, callback);
  575. }else{
  576. if (callback) callback();
  577. }
  578. }else{
  579. start += text.length;
  580. this.diffIndex++;
  581. if (this.diffIndex<this.currentDiffs.length){
  582. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  583. if (callback) callback();
  584. if (cb) cb();
  585. });}.bind(this), this.options.speed*this.options.fxTime);
  586. //this.doDiffsAnimation(obj, start, callback);
  587. }else{
  588. if (callback) callback();
  589. }
  590. }
  591. }else{
  592. this.initAnimationStatus();
  593. this.documentEditor.resetData();
  594. if (cb) cb();
  595. }
  596. }.bind(this));
  597. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  598. }.bind(this)
  599. if (this.stopWhile) if (this.stopWhile == diff["id"]) this.stop = true;
  600. if (!this.stop || !this.playing) {
  601. endFunction();
  602. } else{
  603. if (this.stopWhile){
  604. this.stopWhile = "";
  605. //this.playing = false;
  606. }
  607. this.nextPlayPrefixFunction = endFunction;
  608. }
  609. this.checkToolbar();
  610. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  611. }.bind(this));
  612. break;
  613. case DIFF_DELETE:
  614. if (diff["item"]) diff["item"].showCurrent((!this.stopWhile || this.stopWhile == diff["id"]));
  615. if (this.originaDiff) this.originaDiff.hideCurrent();
  616. var text = diff[1];
  617. if (this.reverse){
  618. var left = this.currentHistoryData.substring(0, start);
  619. //var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  620. var right = this.currentHistoryData.substring(start);
  621. filetextNode.set("html", left+"<del style='color: red'>"+text+"</del>"+right);
  622. start -= text.length;
  623. }else{
  624. var left = this.currentHistoryData.substring(0, start);
  625. var middle = this.currentHistoryData.substring(start, start+diff[1].length);
  626. var right = this.currentHistoryData.substring(start+diff[1].length);
  627. //start -= .length;
  628. filetextNode.set("html", left+"<del style='color: red'>"+middle+"</del>"+right);
  629. }
  630. var del = filetextNode.getElement("del");
  631. if (!this.stopWhile || this.stopWhile == diff["id"]) del.scrollIn();
  632. this.doDeleteAnimation(del, diff, obj, function(deleteInforDiv){
  633. // var deleteInforDiv = null;
  634. // if (!invisible){
  635. // deleteInforDiv = this.createDiifInforNode(obj, del, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent);
  636. // }
  637. var invisible = !deleteInforDiv;
  638. window.setTimeout(function(){
  639. var endFunction = function(cb){
  640. if (deleteInforDiv) deleteInforDiv.fade("out");
  641. var fx = new Fx.Tween(del, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  642. fx.start(0.5,0).chain(function(){
  643. if (deleteInforDiv) deleteInforDiv.destroy();
  644. if (diff["item"]) diff["item"].hideCurrent();
  645. if (this.reverse){
  646. data = filetextNode.get("html");
  647. this.currentHistoryData = data.replace(/<del[\s\S]*\/del>/m, text);
  648. filetextNode.set("html", this.currentHistoryData);
  649. }else{
  650. del.destroy();
  651. this.currentHistoryData = filetextNode.get("html");
  652. }
  653. if (this.playing){
  654. if (this.reverse){
  655. this.diffIndex--;
  656. if (this.diffIndex>=0){
  657. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  658. if (callback) callback();
  659. if (cb) cb();
  660. });}.bind(this), this.options.speed*this.options.fxTime);
  661. }else{
  662. if (callback) callback();
  663. }
  664. }else{
  665. this.diffIndex++;
  666. if (this.diffIndex<this.currentDiffs.length){
  667. window.setTimeout(function(){this.doDiffsAnimation(obj, start, function(){
  668. if (callback) callback();
  669. if (cb) cb();
  670. });}.bind(this), this.options.speed*this.options.fxTime);
  671. }else{
  672. if (callback) callback();
  673. }
  674. }
  675. }else{
  676. this.initAnimationStatus();
  677. this.documentEditor.resetData();
  678. if (cb) cb();
  679. }
  680. }.bind(this));
  681. if (this.nextPlayPrefixFunction) this.nextPlayPrefixFunction = null;
  682. }.bind(this)
  683. if (this.stopWhile){
  684. if (this.stopWhile == diff["id"]) this.stop = true;
  685. }
  686. if (!this.stop || !this.playing) {
  687. endFunction();
  688. } else{
  689. if (this.stopWhile){
  690. this.stopWhile = "";
  691. //this.playing = false;
  692. }
  693. this.nextPlayPrefixFunction = endFunction;
  694. }
  695. this.checkToolbar();
  696. }.bind(this), (invisible ? 100: this.options.speed*this.options.inforTime));
  697. }.bind(this));
  698. break;
  699. case DIFF_EQUAL:
  700. if (this.reverse){
  701. start -= diff[1].length;
  702. this.diffIndex--;
  703. if (this.diffIndex>=0){
  704. this.doDiffsAnimation(obj, start, callback);
  705. }else{
  706. if (callback) callback();
  707. }
  708. }else{
  709. start += diff[1].length;
  710. this.diffIndex++;
  711. if (this.diffIndex<this.currentDiffs.length){
  712. this.doDiffsAnimation(obj, start, callback);
  713. }else{
  714. if (callback) callback();
  715. }
  716. }
  717. break;
  718. }
  719. },
  720. doInsetAnimation: function(node, str, callback){
  721. var tmp = new Element("div", {"html": str});
  722. if (!tmp.get("text").trim()){
  723. if (callback) callback(true);
  724. }else{
  725. var nodes = tmp.childNodes;
  726. this.doInsetNodeAnimation(node, nodes, 0, callback);
  727. }
  728. },
  729. doInsetNodeAnimation: function(ins, nodes, idx, callback){
  730. var node = nodes[idx];
  731. if (node.nodeType == Node.TEXT_NODE){
  732. this.doCharAnimation(ins, node.nodeValue, 0, function(){
  733. idx++;
  734. if (idx<nodes.length){
  735. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  736. }else{
  737. if (callback) callback();
  738. }
  739. }.bind(this));
  740. }else{
  741. var duration = this.options.speed*this.options.fxTime/nodes.length;
  742. if (!duration){
  743. ins.appendChild(node);
  744. idx++;
  745. if (idx<nodes.length){
  746. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  747. }else{
  748. if (callback) callback();
  749. }
  750. }else{
  751. var span = new Element("span", {"styles": {"opacity": 0}}).inject(ins);
  752. span.appendChild(node);
  753. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  754. fx.start(0,1).chain(function(){
  755. idx++;
  756. if (idx<nodes.length){
  757. this.doInsetNodeAnimation(ins, nodes, idx, callback);
  758. }else{
  759. if (callback) callback();
  760. }
  761. }.bind(this));
  762. }
  763. }
  764. },
  765. doCharAnimation: function(node, str, idx, callback){
  766. var duration = this.options.speed*this.options.fxTime/str.length;
  767. if (!duration){
  768. node.set("html", str);
  769. idx = str.length;
  770. if (callback) callback();
  771. }else{
  772. var char = str.charAt(idx);
  773. var span = new Element("span", {"styles": {"opacity": 0}, "html": char}).inject(node);
  774. var fx = new Fx.Tween(span, {property: 'opacity', duration:duration});
  775. fx.start(0,1).chain(function(){
  776. idx++;
  777. if (idx<str.length){
  778. this.doCharAnimation(node, str, idx, callback);
  779. }else{
  780. if (callback) callback();
  781. }
  782. }.bind(this));
  783. }
  784. },
  785. doDeleteAnimation: function(node, diff, obj, callback){
  786. var str = diff[1];
  787. var tmp = new Element("div", {"html": str});
  788. if (!tmp.get("text").trim()){
  789. if (callback) callback(null);
  790. }else{
  791. var deleteInforDiv = (!this.stopWhile || this.stopWhile == diff["id"]) ? this.createDiifInforNode(obj, node, "#fbe0e7", MWF.xApplication.process.Xform.LP.documentHistory.deleteContent) : null;
  792. var fx = new Fx.Tween(node, {property: 'opacity', duration:this.options.speed*this.options.fxTime});
  793. fx.start(1,0.5).chain(function(){
  794. if (callback) callback(deleteInforDiv);
  795. }.bind(this));
  796. }
  797. }
  798. });
  799. MWF.xApplication.process.Xform.widget.DocumentHistory.Item = new Class({
  800. initialize: function(history, historyData){
  801. this.history = history;
  802. this.documentEditor = this.history.documentEditor;
  803. this.css = this.history.css;
  804. this.historyData = historyData;
  805. this.load();
  806. },
  807. load: function(){
  808. var patchs = this.historyData.json.patchObj || null;
  809. var obj = this.historyData;
  810. this.node = new Element("div", {"styles": this.css.historyListItemNode}).inject(this.history.historyListContentAreaNode);
  811. 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>"
  812. this.patchNode = new Element("div", {"styles": this.css.historyListItemPatchNode, "html": patchHtml}).inject(this.node);
  813. this.diffsNode = new Element("div", {"styles": this.css.historyListItemDiffsNode}).inject(this.node);
  814. var _self = this;
  815. if (patchs){
  816. patchs.each(function(patch){
  817. patch.diffs.each(function(diff){
  818. if (diff[0]!=0){
  819. diff["id"] = (new o2.widget.UUID()).toString();
  820. var tmp = new Element("div", {"html": diff[1]});
  821. infor = tmp.get("text");
  822. var infor = ((infor.length>50) ? infor.substring(0, 50)+"..." : infor);
  823. tmp.destroy();
  824. if (diff[0]==-1){
  825. infor = MWF.xApplication.process.Xform.LP.documentHistory.delete +": "+"<span style='color:red'><del>"+infor+"</del></span>"
  826. }else{
  827. infor = MWF.xApplication.process.Xform.LP.documentHistory.insert +": "+"<span style='color:blue'><ins>"+infor+"</ins></span>"
  828. }
  829. diffNode = new Element("div", {"styles": this.css.historyListItemDiffNode, "html": infor}).inject(this.diffsNode);
  830. diffNode.store("diff", diff);
  831. diff["item"] = {
  832. "node": diffNode,
  833. "showCurrent": function(show){
  834. var thisDiff = this.node.retrieve("diff");
  835. var color = (thisDiff[0]==-1) ? "#fbe0e7": "#e2edfb";
  836. this.node.setStyles({"background-color": color});
  837. var ss = _self.history.historyListContentAreaNode.getScrollSize();
  838. var s = _self.history.historyListContentAreaNode.getSize();
  839. if (ss.y>s.y) if (show) this.node.scrollIn();
  840. },
  841. "hideCurrent": function(){
  842. this.node.setStyles(_self.css.historyListItemDiffNode);
  843. }
  844. };
  845. diffNode.addEvents({
  846. // "mouseover": function(){
  847. // if (_self.history.stop){
  848. // var diff = this.retrieve("diff");
  849. // var color = (diff[0]==-1) ? "red": "blue";
  850. // this.setStyles({"border-color": color});
  851. // }
  852. // },
  853. // "mouseout": function(){ if (_self.history.stop) this.setStyles(_self.css.historyListItemDiffNode_out) },
  854. "click": function(){
  855. if (_self.history.stop){
  856. var diff = this.retrieve("diff");
  857. _self.history.to(diff);
  858. }
  859. }
  860. });
  861. }
  862. }.bind(this));
  863. }.bind(this));
  864. }else{
  865. infor = MWF.xApplication.process.Xform.LP.documentHistory.original;
  866. diffNode = new Element("div", {"styles": this.css.historyListItemDiffNode, "html": infor}).inject(this.diffsNode);
  867. this.history.originaDiff = {
  868. "node": diffNode,
  869. "showCurrent": function(){
  870. this.node.setStyles({"background-color": "#e2edfb"});
  871. //if (show) this.node.scrollIn();
  872. },
  873. "hideCurrent": function(){
  874. this.node.setStyles(_self.css.historyListItemDiffNode);
  875. }
  876. };
  877. diffNode.addEvents({
  878. "click": function(){
  879. if (_self.history.stop){
  880. _self.history.origina();
  881. }
  882. }
  883. });
  884. }
  885. }
  886. })