DocumentHistory.js 45 KB

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