DocumentHistory.js 45 KB

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