postil.js 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  1. import { rowLocation, colLocation, mouseposition } from '../global/location';
  2. import editor from '../global/editor';
  3. import formula from '../global/formula';
  4. import { luckysheetRangeLast } from '../global/cursorPos';
  5. import { luckysheetrefreshgrid } from '../global/refresh';
  6. import { setluckysheet_scroll_status } from '../methods/set';
  7. import { getSheetIndex } from '../methods/get';
  8. import { getObjType } from '../utils/util';
  9. import luckysheetFreezen from './freezen';
  10. import menuButton from './menuButton';
  11. import {checkProtectionAuthorityNormal} from './protection';
  12. import server from './server';
  13. import Store from '../store';
  14. import method from '../global/method';
  15. //批注
  16. const luckysheetPostil = {
  17. defaultWidth: 144,
  18. defaultHeight: 84,
  19. currentObj: null,
  20. currentWinW: null,
  21. currentWinH: null,
  22. resize: null,
  23. resizeXY: null,
  24. move: false,
  25. moveXY: null,
  26. init: function(){
  27. let _this = this;
  28. //点击批注框 聚焦
  29. $("#luckysheet-postil-showBoxs").off("mousedown.showPs").on("mousedown.showPs", ".luckysheet-postil-show", function(event){
  30. if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, "editObjects",false)){
  31. return;
  32. }
  33. _this.currentObj = $(this).find(".luckysheet-postil-show-main");
  34. if($(this).hasClass("luckysheet-postil-show-active")){
  35. event.stopPropagation();
  36. return;
  37. }
  38. _this.removeActivePs();
  39. $(this).addClass("luckysheet-postil-show-active");
  40. $(this).find(".luckysheet-postil-dialog-resize").show();
  41. $(this).find(".arrowCanvas").css("z-index", 200);
  42. $(this).find(".luckysheet-postil-show-main").css("z-index", 200);
  43. event.stopPropagation();
  44. });
  45. $("#luckysheet-postil-showBoxs").off("mouseup.showPs").on("mouseup.showPs", ".luckysheet-postil-show", function(event){
  46. if(event.which == "3"){
  47. event.stopPropagation();
  48. }
  49. });
  50. //批注框 改变大小
  51. $("#luckysheet-postil-showBoxs").off("mousedown.resize").on("mousedown.resize", ".luckysheet-postil-show .luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item", function(event){
  52. if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, "editObjects",false)){
  53. return;
  54. }
  55. _this.currentObj = $(this).closest(".luckysheet-postil-show-main");
  56. _this.currentWinW = $("#luckysheet-cell-main")[0].scrollWidth;
  57. _this.currentWinH = $("#luckysheet-cell-main")[0].scrollHeight;
  58. _this.resize = $(this).data("type");
  59. let scrollTop = $("#luckysheet-cell-main").scrollTop(),
  60. scrollLeft = $("#luckysheet-cell-main").scrollLeft();
  61. let mouse = mouseposition(event.pageX, event.pageY);
  62. let x = mouse[0] + scrollLeft;
  63. let y = mouse[1] + scrollTop;
  64. let position = _this.currentObj.position();
  65. let width = _this.currentObj.width();
  66. let height = _this.currentObj.height();
  67. _this.resizeXY = [
  68. x,
  69. y,
  70. width,
  71. height,
  72. position.left + scrollLeft,
  73. position.top + scrollTop,
  74. scrollLeft,
  75. scrollTop
  76. ];
  77. setluckysheet_scroll_status(true);
  78. if($(this).closest(".luckysheet-postil-show").hasClass("luckysheet-postil-show-active")){
  79. event.stopPropagation();
  80. return;
  81. }
  82. _this.removeActivePs();
  83. $(this).closest(".luckysheet-postil-show").addClass("luckysheet-postil-show-active");
  84. $(this).closest(".luckysheet-postil-show").find(".luckysheet-postil-dialog-resize").show();
  85. $(this).closest(".luckysheet-postil-show").find(".arrowCanvas").css("z-index", 200);
  86. $(this).closest(".luckysheet-postil-show").find(".luckysheet-postil-show-main").css("z-index", 200);
  87. event.stopPropagation();
  88. });
  89. //批注框 移动
  90. $("#luckysheet-postil-showBoxs").off("mousedown.move").on("mousedown.move", ".luckysheet-postil-show .luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item", function(event){
  91. if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, "editObjects",false)){
  92. return;
  93. }
  94. _this.currentObj = $(this).closest(".luckysheet-postil-show-main");
  95. _this.currentWinW = $("#luckysheet-cell-main")[0].scrollWidth;
  96. _this.currentWinH = $("#luckysheet-cell-main")[0].scrollHeight;
  97. _this.move = true;
  98. let scrollTop = $("#luckysheet-cell-main").scrollTop(),
  99. scrollLeft = $("#luckysheet-cell-main").scrollLeft();
  100. let offset = _this.currentObj.offset();
  101. let position = _this.currentObj.position();
  102. _this.moveXY = [
  103. event.pageX - offset.left,
  104. event.pageY - offset.top,
  105. position.left,
  106. position.top,
  107. scrollLeft,
  108. scrollTop
  109. ];
  110. setluckysheet_scroll_status(true);
  111. if($(this).closest(".luckysheet-postil-show").hasClass("luckysheet-postil-show-active")){
  112. event.stopPropagation();
  113. return;
  114. }
  115. _this.removeActivePs();
  116. $(this).closest(".luckysheet-postil-show").addClass("luckysheet-postil-show-active");
  117. $(this).closest(".luckysheet-postil-show").find(".luckysheet-postil-dialog-resize").show();
  118. $(this).closest(".luckysheet-postil-show").find(".arrowCanvas").css("z-index", 200);
  119. $(this).closest(".luckysheet-postil-show").find(".luckysheet-postil-show-main").css("z-index", 200);
  120. event.stopPropagation();
  121. });
  122. },
  123. overshow: function(event){
  124. let _this = this;
  125. $("#luckysheet-postil-overshow").remove();
  126. if($(event.target).closest("#luckysheet-cell-main").length == 0){
  127. return;
  128. }
  129. let mouse = mouseposition(event.pageX, event.pageY);
  130. let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
  131. let scrollTop = $("#luckysheet-cell-main").scrollTop();
  132. let x = mouse[0];
  133. let y = mouse[1];
  134. let offsetX = 0;
  135. let offsetY = 0;
  136. if(luckysheetFreezen.freezenverticaldata != null && mouse[0] < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){
  137. offsetX = scrollLeft;
  138. } else {
  139. x += scrollLeft;
  140. }
  141. if(luckysheetFreezen.freezenhorizontaldata != null && mouse[1] < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){
  142. offsetY = scrollTop;
  143. } else {
  144. y += scrollTop;
  145. }
  146. let row_index = rowLocation(y)[2];
  147. let col_index = colLocation(x)[2];
  148. let margeset = menuButton.mergeborer(Store.flowdata, row_index, col_index);
  149. if(!!margeset){
  150. row_index = margeset.row[2];
  151. col_index = margeset.column[2];
  152. }
  153. if(Store.flowdata[row_index] == null || Store.flowdata[row_index][col_index] == null || Store.flowdata[row_index][col_index].ps == null){
  154. return;
  155. }
  156. let postil = Store.flowdata[row_index][col_index].ps;
  157. if(postil["isshow"] || $("#luckysheet-postil-show_"+ row_index +"_"+ col_index).length > 0){
  158. return;
  159. }
  160. let value = postil["value"] == null ? "" : postil["value"];
  161. let row = Store.visibledatarow[row_index],
  162. row_pre = row_index - 1 == -1 ? 0 : Store.visibledatarow[row_index - 1];
  163. let col = Store.visibledatacolumn[col_index],
  164. col_pre = col_index - 1 == -1 ? 0 : Store.visibledatacolumn[col_index - 1];
  165. if(!!margeset){
  166. row = margeset.row[1];
  167. row_pre = margeset.row[0];
  168. col = margeset.column[1];
  169. col_pre = margeset.column[0];
  170. }
  171. let toX = col + offsetX;
  172. let toY = row_pre + offsetY;
  173. let fromX = toX + 18 * Store.zoomRatio;
  174. let fromY = toY - 18 * Store.zoomRatio;
  175. if(fromY < 0){
  176. fromY = 2;
  177. }
  178. let width = postil["width"] == null ? _this.defaultWidth * Store.zoomRatio : postil["width"] * Store.zoomRatio;
  179. let height = postil["height"] == null ? _this.defaultHeight * Store.zoomRatio : postil["height"] * Store.zoomRatio;
  180. let size = _this.getArrowCanvasSize(fromX, fromY, toX, toY);
  181. let commentDivs = '';
  182. let valueLines = value.split('\n');
  183. for (let line of valueLines) {
  184. commentDivs += '<div>' + _this.htmlEscape(line) + '</div>';
  185. }
  186. let html = '<div id="luckysheet-postil-overshow">' +
  187. '<canvas class="arrowCanvas" width="'+ size[2] +'" height="'+ size[3] +'" style="position:absolute;left:'+ size[0] +'px;top:'+ size[1] +'px;z-index:100;pointer-events:none;"></canvas>' +
  188. '<div style="width:'+ (width - 12) +'px;min-height:'+ (height - 12) +'px;color:#000;padding:5px;border:1px solid #000;background-color:rgb(255,255,225);position:absolute;left:'+ fromX +'px;top:'+ fromY +'px;z-index:100;">'+ commentDivs +'</div>' +
  189. '</div>';
  190. $(html).appendTo($("#luckysheet-cell-main"));
  191. let ctx = $("#luckysheet-postil-overshow .arrowCanvas").get(0).getContext("2d");
  192. _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);
  193. },
  194. getArrowCanvasSize: function(fromX, fromY, toX, toY){
  195. let left = toX - 5;
  196. if(fromX < toX){
  197. left = fromX - 5;
  198. }
  199. let top = toY - 5;
  200. if(fromY < toY){
  201. top = fromY - 5;
  202. }
  203. let width = Math.abs(fromX - toX) + 10;
  204. let height = Math.abs(fromY - toY) + 10;
  205. let x1 = width - 5;
  206. let x2 = 5;
  207. if(fromX < toX){
  208. x1 = 5;
  209. x2 = width - 5;
  210. }
  211. let y1 = height - 5;
  212. let y2 = 5;
  213. if(fromY < toY){
  214. y1 = 5;
  215. y2 = height - 5;
  216. }
  217. return [left, top, width, height, x1, y1, x2, y2];
  218. },
  219. drawArrow: function(ctx, fromX, fromY, toX, toY, theta, headlen, width, color){
  220. theta = getObjType(theta) == "undefined" ? 30 : theta;
  221. headlen = getObjType(headlen) == "undefined" ? 6 : headlen;
  222. width = getObjType(width) == "undefined" ? 1 : width;
  223. color = getObjType(color) == "undefined" ? "#000" : color;
  224. // 计算各角度和对应的P2,P3坐标
  225. let angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
  226. angle1 = (angle + theta) * Math.PI / 180,
  227. angle2 = (angle - theta) * Math.PI / 180,
  228. topX = headlen * Math.cos(angle1),
  229. topY = headlen * Math.sin(angle1),
  230. botX = headlen * Math.cos(angle2),
  231. botY = headlen * Math.sin(angle2);
  232. ctx.save();
  233. ctx.beginPath();
  234. let arrowX = fromX - topX,
  235. arrowY = fromY - topY;
  236. ctx.moveTo(arrowX, arrowY);
  237. ctx.moveTo(fromX, fromY);
  238. ctx.lineTo(toX, toY);
  239. ctx.lineWidth = width;
  240. ctx.strokeStyle = color;
  241. ctx.stroke();
  242. arrowX = toX + topX;
  243. arrowY = toY + topY;
  244. ctx.moveTo(arrowX, arrowY);
  245. ctx.lineTo(toX, toY);
  246. arrowX = toX + botX;
  247. arrowY = toY + botY;
  248. ctx.lineTo(arrowX, arrowY);
  249. ctx.fillStyle = color;
  250. ctx.fill();
  251. ctx.restore();
  252. },
  253. buildAllPs: function(data){
  254. let _this = this;
  255. $("#luckysheet-cell-main #luckysheet-postil-showBoxs").empty();
  256. for(let r = 0; r < data.length; r++){
  257. for(let c = 0; c < data[0].length; c++){
  258. if(data[r][c] != null && data[r][c].ps != null){
  259. let postil = data[r][c].ps;
  260. _this.buildPs(r, c, postil);
  261. }
  262. }
  263. }
  264. _this.init();
  265. },
  266. buildPs: function(r, c, postil){
  267. if($("#luckysheet-postil-show_"+ r +"_"+ c).length > 0){
  268. $("#luckysheet-postil-show_"+ r +"_"+ c).remove();
  269. }
  270. if(postil == null){
  271. return;
  272. }
  273. let _this = this;
  274. let isshow = postil["isshow"] == null ? false : postil["isshow"];
  275. if(isshow){
  276. let row = Store.visibledatarow[r],
  277. row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];
  278. let col = Store.visibledatacolumn[c],
  279. col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];
  280. let margeset = menuButton.mergeborer(Store.flowdata, r, c);
  281. if(!!margeset){
  282. row = margeset.row[1];
  283. row_pre = margeset.row[0];
  284. col = margeset.column[1];
  285. col_pre = margeset.column[0];
  286. }
  287. let toX = col;
  288. let toY = row_pre;
  289. let left = postil["left"] == null ? toX + 18 * Store.zoomRatio : postil["left"] * Store.zoomRatio;
  290. let top = postil["top"] == null ? toY - 18 * Store.zoomRatio : postil["top"] * Store.zoomRatio;
  291. let width = postil["width"] == null ? _this.defaultWidth * Store.zoomRatio : postil["width"] * Store.zoomRatio;
  292. let height = postil["height"] == null ? _this.defaultHeight * Store.zoomRatio : postil["height"] * Store.zoomRatio;
  293. let value = postil["value"] == null ? "" : postil["value"];
  294. if(top < 0){
  295. top = 2;
  296. }
  297. let size = _this.getArrowCanvasSize(left, top, toX, toY);
  298. let commentDivs = '';
  299. let valueLines = value.split('\n');
  300. for (let line of valueLines) {
  301. commentDivs += '<div>' + _this.htmlEscape(line) + '</div>';
  302. }
  303. let html = '<div id="luckysheet-postil-show_'+ r +'_'+ c +'" class="luckysheet-postil-show">' +
  304. '<canvas class="arrowCanvas" width="'+ size[2] +'" height="'+ size[3] +'" style="position:absolute;left:'+ size[0] +'px;top:'+ size[1] +'px;z-index:100;pointer-events:none;"></canvas>' +
  305. '<div class="luckysheet-postil-show-main" style="width:'+ width +'px;height:'+ height +'px;color:#000;padding:5px;border:1px solid #000;background-color:rgb(255,255,225);position:absolute;left:'+ left +'px;top:'+ top +'px;box-sizing:border-box;z-index:100;">' +
  306. '<div class="luckysheet-postil-dialog-move">' +
  307. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-t" data-type="t"></div>' +
  308. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-r" data-type="r"></div>' +
  309. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-b" data-type="b"></div>' +
  310. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-l" data-type="l"></div>' +
  311. '</div>' +
  312. '<div class="luckysheet-postil-dialog-resize" style="display:none;">' +
  313. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lt" data-type="lt"></div>' +
  314. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mt" data-type="mt"></div>' +
  315. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lm" data-type="lm"></div>' +
  316. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rm" data-type="rm"></div>' +
  317. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rt" data-type="rt"></div>' +
  318. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lb" data-type="lb"></div>' +
  319. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mb" data-type="mb"></div>' +
  320. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rb" data-type="rb"></div>' +
  321. '</div>' +
  322. '<div style="width:100%;height:100%;overflow:hidden;">' +
  323. '<div class="formulaInputFocus" style="width:'+ (width - 12) +'px;height:'+ (height - 12) +'px;line-height:20px;box-sizing:border-box;text-align: center;;word-break:break-all;" spellcheck="false" contenteditable="true">' +
  324. commentDivs +
  325. '</div>' +
  326. '</div>' +
  327. '</div>' +
  328. '</div>';
  329. $(html).appendTo($("#luckysheet-cell-main #luckysheet-postil-showBoxs"));
  330. let ctx = $("#luckysheet-postil-show_"+ r +"_"+ c +" .arrowCanvas").get(0).getContext("2d");
  331. _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);
  332. }
  333. },
  334. newPs: function(r, c){
  335. if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, "editObjects")){
  336. return;
  337. }
  338. // Hook function
  339. if(!method.createHookFunction('commentInsertBefore',r,c, )){
  340. return;
  341. }
  342. let _this = this;
  343. let row = Store.visibledatarow[r],
  344. row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];
  345. let col = Store.visibledatacolumn[c],
  346. col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];
  347. let margeset = menuButton.mergeborer(Store.flowdata, r, c);
  348. if(!!margeset){
  349. row = margeset.row[1];
  350. row_pre = margeset.row[0];
  351. col = margeset.column[1];
  352. col_pre = margeset.column[0];
  353. }
  354. let toX = col;
  355. let toY = row_pre;
  356. let fromX = toX + 18 * Store.zoomRatio;
  357. let fromY = toY - 18 * Store.zoomRatio;
  358. if(fromY < 0){
  359. fromY = 2;
  360. }
  361. let width = _this.defaultWidth * Store.zoomRatio;
  362. let height = _this.defaultHeight * Store.zoomRatio;
  363. let size = _this.getArrowCanvasSize(fromX, fromY, toX, toY);
  364. let html = '<div id="luckysheet-postil-show_'+ r +'_'+ c +'" class="luckysheet-postil-show luckysheet-postil-show-active">' +
  365. '<canvas class="arrowCanvas" width="'+ size[2] +'" height="'+ size[3] +'" style="position:absolute;left:'+ size[0] +'px;top:'+ size[1] +'px;z-index:100;pointer-events:none;"></canvas>' +
  366. '<div class="luckysheet-postil-show-main" style="width:'+ width +'px;height:'+ height +'px;color:#000;padding:5px;border:1px solid #000;background-color:rgb(255,255,225);position:absolute;left:'+ fromX +'px;top:'+ fromY +'px;box-sizing:border-box;z-index:100;">' +
  367. '<div class="luckysheet-postil-dialog-move">' +
  368. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-t" data-type="t"></div>' +
  369. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-r" data-type="r"></div>' +
  370. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-b" data-type="b"></div>' +
  371. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-l" data-type="l"></div>' +
  372. '</div>' +
  373. '<div class="luckysheet-postil-dialog-resize">' +
  374. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lt" data-type="lt"></div>' +
  375. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mt" data-type="mt"></div>' +
  376. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lm" data-type="lm"></div>' +
  377. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rm" data-type="rm"></div>' +
  378. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rt" data-type="rt"></div>' +
  379. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lb" data-type="lb"></div>' +
  380. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mb" data-type="mb"></div>' +
  381. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rb" data-type="rb"></div>' +
  382. '</div>' +
  383. '<div style="width:100%;height:100%;overflow:hidden;">' +
  384. '<div class="formulaInputFocus" style="width:132px;height:72px;line-height:20px;box-sizing:border-box;text-align: center;word-break:break-all;" spellcheck="false" contenteditable="true">' +
  385. '</div>' +
  386. '</div>' +
  387. '</div>' +
  388. '</div>';
  389. $(html).appendTo($("#luckysheet-cell-main #luckysheet-postil-showBoxs"));
  390. let ctx = $("#luckysheet-postil-show_"+ r +"_"+ c +" .arrowCanvas").get(0).getContext("2d");
  391. _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);
  392. $("#luckysheet-postil-show_"+ r +"_"+ c +" .formulaInputFocus").focus();
  393. _this.init();
  394. let d = editor.deepCopyFlowData(Store.flowdata);
  395. let rc = [];
  396. if(d[r][c] == null){
  397. d[r][c] = {};
  398. }
  399. d[r][c].ps = { "left": null, "top": null, "width": null, "height": null, "value": "", "isshow": false };
  400. rc.push(r + "_" + c);
  401. _this.ref(d, rc);
  402. // Hook function
  403. setTimeout(() => {
  404. method.createHookFunction('commentInsertAfter',r,c, d[r][c])
  405. }, 0);
  406. },
  407. editPs: function(r, c){
  408. let _this = this;
  409. if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, "editObjects")){
  410. return;
  411. }
  412. if($("#luckysheet-postil-show_"+ r +"_"+ c).length > 0){
  413. $("#luckysheet-postil-show_"+ r +"_"+ c).show();
  414. $("#luckysheet-postil-show_"+ r +"_"+ c).addClass("luckysheet-postil-show-active");
  415. $("#luckysheet-postil-show_"+ r +"_"+ c).find(".luckysheet-postil-dialog-resize").show();
  416. }
  417. else{
  418. let postil = Store.flowdata[r][c].ps;
  419. let row = Store.visibledatarow[r],
  420. row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];
  421. let col = Store.visibledatacolumn[c],
  422. col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];
  423. let margeset = menuButton.mergeborer(Store.flowdata, r, c);
  424. if(!!margeset){
  425. row = margeset.row[1];
  426. row_pre = margeset.row[0];
  427. col = margeset.column[1];
  428. col_pre = margeset.column[0];
  429. }
  430. let toX = col;
  431. let toY = row_pre;
  432. let left = postil["left"] == null ? toX + 18 * Store.zoomRatio : postil["left"] * Store.zoomRatio;
  433. let top = postil["top"] == null ? toY - 18 * Store.zoomRatio : postil["top"] * Store.zoomRatio;
  434. let width = postil["width"] == null ? _this.defaultWidth * Store.zoomRatio : postil["width"] * Store.zoomRatio;
  435. let height = postil["height"] == null ? _this.defaultHeight * Store.zoomRatio : postil["height"] * Store.zoomRatio;
  436. let value = postil["value"] == null ? "" : postil["value"];
  437. if(top < 0){
  438. top = 2;
  439. }
  440. let size = _this.getArrowCanvasSize(left, top, toX, toY);
  441. let commentDivs = '';
  442. let valueLines = value.split('\n');
  443. for (let line of valueLines) {
  444. commentDivs += '<div>' + _this.htmlEscape(line) + '</div>';
  445. }
  446. let html = '<div id="luckysheet-postil-show_'+ r +'_'+ c +'" class="luckysheet-postil-show luckysheet-postil-show-active">' +
  447. '<canvas class="arrowCanvas" width="'+ size[2] +'" height="'+ size[3] +'" style="position:absolute;left:'+ size[0] +'px;top:'+ size[1] +'px;z-index:100;pointer-events:none;"></canvas>' +
  448. '<div class="luckysheet-postil-show-main" style="width:'+ width +'px;height:'+ height +'px;color:#000;padding:5px;border:1px solid #000;background-color:rgb(255,255,225);position:absolute;left:'+ left +'px;top:'+ top +'px;box-sizing:border-box;z-index:100;">' +
  449. '<div class="luckysheet-postil-dialog-move">' +
  450. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-t" data-type="t"></div>' +
  451. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-r" data-type="r"></div>' +
  452. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-b" data-type="b"></div>' +
  453. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-l" data-type="l"></div>' +
  454. '</div>' +
  455. '<div class="luckysheet-postil-dialog-resize">' +
  456. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lt" data-type="lt"></div>' +
  457. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mt" data-type="mt"></div>' +
  458. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lm" data-type="lm"></div>' +
  459. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rm" data-type="rm"></div>' +
  460. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rt" data-type="rt"></div>' +
  461. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lb" data-type="lb"></div>' +
  462. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mb" data-type="mb"></div>' +
  463. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rb" data-type="rb"></div>' +
  464. '</div>' +
  465. '<div style="width:100%;height:100%;overflow:hidden;">' +
  466. '<div class="formulaInputFocus" style="width:'+ (width - 12) +'px;height:'+ (height - 12) +'px;line-height:20px;box-sizing:border-box;text-align: center;;word-break:break-all;" spellcheck="false" contenteditable="true">' +
  467. commentDivs +
  468. '</div>' +
  469. '</div>' +
  470. '</div>' +
  471. '</div>';
  472. $(html).appendTo($("#luckysheet-cell-main #luckysheet-postil-showBoxs"));
  473. let ctx = $("#luckysheet-postil-show_"+ r +"_"+ c +" .arrowCanvas").get(0).getContext("2d");
  474. _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);
  475. }
  476. $("#luckysheet-postil-show_"+ r +"_"+ c +" .formulaInputFocus").focus();
  477. luckysheetRangeLast($("#luckysheet-postil-show_"+ r +"_"+ c +" .formulaInputFocus").get(0));
  478. _this.init();
  479. },
  480. delPs: function(r, c){
  481. if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, "editObjects")){
  482. return;
  483. }
  484. // Hook function
  485. if(!method.createHookFunction('commentDeleteBefore',r,c,Store.flowdata[r][c])){
  486. return;
  487. }
  488. if($("#luckysheet-postil-show_"+ r +"_"+ c).length > 0){
  489. $("#luckysheet-postil-show_"+ r +"_"+ c).remove();
  490. }
  491. let d = editor.deepCopyFlowData(Store.flowdata);
  492. let rc = [];
  493. delete d[r][c].ps;
  494. rc.push(r + "_" + c);
  495. this.ref(d, rc);
  496. // Hook function
  497. setTimeout(() => {
  498. method.createHookFunction('commentDeleteAfter',r,c, Store.flowdata[r][c])
  499. }, 0);
  500. },
  501. showHidePs: function(r, c){
  502. let _this = this;
  503. let postil = Store.flowdata[r][c].ps;
  504. let isshow = postil["isshow"];
  505. let d = editor.deepCopyFlowData(Store.flowdata);
  506. let rc = [];
  507. if(isshow){
  508. d[r][c].ps.isshow = false;
  509. $("#luckysheet-postil-show_"+ r +"_"+ c).remove();
  510. }
  511. else{
  512. d[r][c].ps.isshow = true;
  513. let row = Store.visibledatarow[r],
  514. row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];
  515. let col = Store.visibledatacolumn[c],
  516. col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];
  517. let margeset = menuButton.mergeborer(Store.flowdata, r, c);
  518. if(!!margeset){
  519. row = margeset.row[1];
  520. row_pre = margeset.row[0];
  521. col = margeset.column[1];
  522. col_pre = margeset.column[0];
  523. }
  524. let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
  525. let scrollTop = $("#luckysheet-cell-main").scrollTop();
  526. let toX = col;
  527. let toY = row_pre;
  528. if(luckysheetFreezen.freezenverticaldata != null && toX < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){
  529. toX += scrollLeft;
  530. }
  531. if(luckysheetFreezen.freezenhorizontaldata != null && toY < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){
  532. toY += scrollTop;
  533. }
  534. let left = postil["left"] == null ? toX + 18 * Store.zoomRatio : postil["left"] * Store.zoomRatio;
  535. let top = postil["top"] == null ? toY - 18 * Store.zoomRatio : postil["top"] * Store.zoomRatio;
  536. let width = postil["width"] == null ? _this.defaultWidth * Store.zoomRatio : postil["width"] * Store.zoomRatio;
  537. let height = postil["height"] == null ? _this.defaultHeight * Store.zoomRatio : postil["height"] * Store.zoomRatio;
  538. let value = postil["value"] == null ? "" : postil["value"];
  539. if(top < 0){
  540. top = 2;
  541. }
  542. let size = _this.getArrowCanvasSize(left, top, toX, toY);
  543. let commentDivs = '';
  544. let valueLines = value.split('\n');
  545. for (let line of valueLines) {
  546. commentDivs += '<div>' + _this.htmlEscape(line) + '</div>';
  547. }
  548. let html = '<div id="luckysheet-postil-show_'+ r +'_'+ c +'" class="luckysheet-postil-show">' +
  549. '<canvas class="arrowCanvas" width="'+ size[2] +'" height="'+ size[3] +'" style="position:absolute;left:'+ size[0] +'px;top:'+ size[1] +'px;z-index:100;pointer-events:none;"></canvas>' +
  550. '<div class="luckysheet-postil-show-main" style="width:'+ width +'px;height:'+ height +'px;color:#000;padding:5px;border:1px solid #000;background-color:rgb(255,255,225);position:absolute;left:'+ left +'px;top:'+ top +'px;box-sizing:border-box;z-index:100;">' +
  551. '<div class="luckysheet-postil-dialog-move">' +
  552. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-t" data-type="t"></div>' +
  553. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-r" data-type="r"></div>' +
  554. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-b" data-type="b"></div>' +
  555. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-l" data-type="l"></div>' +
  556. '</div>' +
  557. '<div class="luckysheet-postil-dialog-resize" style="display:none;">' +
  558. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lt" data-type="lt"></div>' +
  559. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mt" data-type="mt"></div>' +
  560. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lm" data-type="lm"></div>' +
  561. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rm" data-type="rm"></div>' +
  562. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rt" data-type="rt"></div>' +
  563. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lb" data-type="lb"></div>' +
  564. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mb" data-type="mb"></div>' +
  565. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rb" data-type="rb"></div>' +
  566. '</div>' +
  567. '<div style="width:100%;height:100%;overflow:hidden;">' +
  568. '<div class="formulaInputFocus" style="width:'+ (width - 12) +'px;height:'+ (height - 12) +'px;line-height:20px;box-sizing:border-box;text-align: center;;word-break:break-all;" spellcheck="false" contenteditable="true">' +
  569. commentDivs +
  570. '</div>' +
  571. '</div>' +
  572. '</div>' +
  573. '</div>';
  574. $(html).appendTo($("#luckysheet-cell-main #luckysheet-postil-showBoxs"));
  575. let ctx = $("#luckysheet-postil-show_"+ r +"_"+ c +" .arrowCanvas").get(0).getContext("2d");
  576. _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);
  577. _this.init();
  578. }
  579. rc.push(r + "_" + c);
  580. _this.ref(d, rc);
  581. },
  582. showHideAllPs: function(){
  583. let _this = this;
  584. let d = editor.deepCopyFlowData(Store.flowdata);
  585. let isAllShow = true;
  586. let allPs = [];
  587. for(let r = 0; r < d.length; r++){
  588. for(let c = 0; c < d[0].length; c++){
  589. if(d[r] != null && d[r][c] != null && d[r][c].ps != null){
  590. allPs.push(r + "_" + c);
  591. if(!d[r][c].ps.isshow){
  592. isAllShow = false;
  593. }
  594. }
  595. }
  596. }
  597. let rc = [];
  598. if(allPs.length > 0){
  599. if(isAllShow){ //全部显示,操作为隐藏所有批注
  600. $("#luckysheet-cell-main #luckysheet-postil-showBoxs").empty();
  601. for(let i = 0; i < allPs.length; i++){
  602. let rowIndex = allPs[i].split("_")[0];
  603. let colIndex = allPs[i].split("_")[1];
  604. let postil = d[rowIndex][colIndex].ps;
  605. if(postil["isshow"]){
  606. d[rowIndex][colIndex].ps.isshow = false;
  607. rc.push(allPs[i]);
  608. }
  609. }
  610. }
  611. else{ //部分显示或全部隐藏,操作位显示所有批注
  612. for(let i = 0; i < allPs.length; i++){
  613. let rowIndex = allPs[i].split("_")[0];
  614. let colIndex = allPs[i].split("_")[1];
  615. let postil = d[rowIndex][colIndex].ps;
  616. if(!postil["isshow"]){
  617. let row = Store.visibledatarow[rowIndex],
  618. row_pre = rowIndex - 1 == -1 ? 0 : Store.visibledatarow[rowIndex - 1];
  619. let col = Store.visibledatacolumn[colIndex],
  620. col_pre = colIndex - 1 == -1 ? 0 : Store.visibledatacolumn[colIndex - 1];
  621. let margeset = menuButton.mergeborer(Store.flowdata, rowIndex, colIndex);
  622. if(!!margeset){
  623. row = margeset.row[1];
  624. row_pre = margeset.row[0];
  625. col = margeset.column[1];
  626. col_pre = margeset.column[0];
  627. }
  628. let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
  629. let scrollTop = $("#luckysheet-cell-main").scrollTop();
  630. let toX = col;
  631. let toY = row_pre;
  632. if(luckysheetFreezen.freezenverticaldata != null && toX < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){
  633. toX += scrollLeft;
  634. }
  635. if(luckysheetFreezen.freezenhorizontaldata != null && toY < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){
  636. toY += scrollTop;
  637. }
  638. let left = postil["left"] == null ? toX + 18 * Store.zoomRatio : postil["left"] * Store.zoomRatio;
  639. let top = postil["top"] == null ? toY - 18 * Store.zoomRatio : postil["top"] * Store.zoomRatio;
  640. let width = postil["width"] == null ? _this.defaultWidth * Store.zoomRatio : postil["width"] * Store.zoomRatio;
  641. let height = postil["height"] == null ? _this.defaultHeight * Store.zoomRatio : postil["height"] * Store.zoomRatio;
  642. let value = postil["value"] == null ? "" : postil["value"];
  643. if(top < 0){
  644. top = 2;
  645. }
  646. let size = _this.getArrowCanvasSize(left, top, toX, toY);
  647. let commentDivs = '';
  648. let valueLines = value.split('\n');
  649. for (let line of valueLines) {
  650. commentDivs += '<div>' + _this.htmlEscape(line) + '</div>';
  651. }
  652. let html = '<div id="luckysheet-postil-show_'+ rowIndex +'_'+ colIndex +'" class="luckysheet-postil-show">' +
  653. '<canvas class="arrowCanvas" width="'+ size[2] +'" height="'+ size[3] +'" style="position:absolute;left:'+ size[0] +'px;top:'+ size[1] +'px;z-index:100;pointer-events:none;"></canvas>' +
  654. '<div class="luckysheet-postil-show-main" style="width:'+ width +'px;height:'+ height +'px;color:#000;padding:5px;border:1px solid #000;background-color:rgb(255,255,225);position:absolute;left:'+ left +'px;top:'+ top +'px;box-sizing:border-box;z-index:100;">' +
  655. '<div class="luckysheet-postil-dialog-move">' +
  656. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-t" data-type="t"></div>' +
  657. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-r" data-type="r"></div>' +
  658. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-b" data-type="b"></div>' +
  659. '<div class="luckysheet-postil-dialog-move-item luckysheet-postil-dialog-move-item-l" data-type="l"></div>' +
  660. '</div>' +
  661. '<div class="luckysheet-postil-dialog-resize" style="display:none;">' +
  662. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lt" data-type="lt"></div>' +
  663. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mt" data-type="mt"></div>' +
  664. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lm" data-type="lm"></div>' +
  665. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rm" data-type="rm"></div>' +
  666. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rt" data-type="rt"></div>' +
  667. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-lb" data-type="lb"></div>' +
  668. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-mb" data-type="mb"></div>' +
  669. '<div class="luckysheet-postil-dialog-resize-item luckysheet-postil-dialog-resize-item-rb" data-type="rb"></div>' +
  670. '</div>' +
  671. '<div style="width:100%;height:100%;overflow:hidden;">' +
  672. '<div class="formulaInputFocus" style="width:'+ (width - 12) +'px;height:'+ (height - 12) +'px;line-height:20px;box-sizing:border-box;text-align: center;;word-break:break-all;" spellcheck="false" contenteditable="true">' +
  673. commentDivs +
  674. '</div>' +
  675. '</div>' +
  676. '</div>' +
  677. '</div>';
  678. $(html).appendTo($("#luckysheet-cell-main #luckysheet-postil-showBoxs"));
  679. let ctx = $("#luckysheet-postil-show_"+ rowIndex +"_"+ colIndex +" .arrowCanvas").get(0).getContext("2d");
  680. _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);
  681. d[rowIndex][colIndex].ps.isshow = true;
  682. rc.push(allPs[i]);
  683. }
  684. }
  685. }
  686. }
  687. _this.ref(d, rc);
  688. _this.init();
  689. },
  690. removeActivePs: function(){
  691. if($("#luckysheet-postil-showBoxs .luckysheet-postil-show-active").length > 0){
  692. let id = $("#luckysheet-postil-showBoxs .luckysheet-postil-show-active").attr("id");
  693. let r = id.split("luckysheet-postil-show_")[1].split("_")[0];
  694. let c = id.split("luckysheet-postil-show_")[1].split("_")[1];
  695. // interpret <div> as new line
  696. let value = $("#" + id).find(".formulaInputFocus").html().replaceAll('<div>', '\n').replaceAll(/<(.*)>.*?|<(.*) \/>/g, '').trim();
  697. // Hook function
  698. if(!method.createHookFunction('commentUpdateBefore',r,c,value)){
  699. if (!Store.flowdata[r][c].ps.isshow) {
  700. $("#" + id).remove();
  701. }
  702. return;
  703. }
  704. const previousCell = $.extend(true,{},Store.flowdata[r][c]);
  705. $("#" + id).removeClass("luckysheet-postil-show-active");
  706. $("#" + id).find(".luckysheet-postil-dialog-resize").hide();
  707. $("#" + id).find(".arrowCanvas").css("z-index", 100);
  708. $("#" + id).find(".luckysheet-postil-show-main").css("z-index", 100);
  709. let d = editor.deepCopyFlowData(Store.flowdata);
  710. let rc = [];
  711. d[r][c].ps.value = value;
  712. rc.push(r + "_" + c);
  713. this.ref(d, rc);
  714. if(!d[r][c].ps.isshow){
  715. $("#" + id).remove();
  716. }
  717. // Hook function
  718. setTimeout(() => {
  719. method.createHookFunction('commentUpdateAfter',r,c, previousCell, d[r][c])
  720. }, 0);
  721. }
  722. },
  723. ref: function(data, rc){
  724. if (Store.clearjfundo) {
  725. Store.jfundo.length = 0;
  726. Store.jfredo.push({
  727. "type": "postil",
  728. "data": Store.flowdata,
  729. "curdata": data,
  730. "sheetIndex": Store.currentSheetIndex,
  731. "rc": rc
  732. });
  733. }
  734. //flowdata
  735. Store.flowdata = data;
  736. editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据
  737. Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = Store.flowdata;
  738. // formula.execFunctionGroupData = Store.flowdata;
  739. //共享编辑模式
  740. if(server.allowUpdate){
  741. for(let i = 0; i < rc.length; i++){
  742. let r = rc[i].split("_")[0];
  743. let c = rc[i].split("_")[1];
  744. server.saveParam("v", Store.currentSheetIndex, Store.flowdata[r][c], { "r": r, "c": c });
  745. }
  746. }
  747. //刷新表格
  748. setTimeout(function () {
  749. luckysheetrefreshgrid();
  750. }, 1);
  751. },
  752. positionSync: function(){
  753. let _this = this;
  754. $("#luckysheet-postil-showBoxs .luckysheet-postil-show").each(function(i, e){
  755. let id = $(e).attr("id");
  756. let r = id.split("luckysheet-postil-show_")[1].split("_")[0];
  757. let c = id.split("luckysheet-postil-show_")[1].split("_")[1];
  758. let cell = Store.flowdata[r][c];
  759. if(cell != null && cell.ps != null){
  760. _this.buildPs(r, c, cell.ps);
  761. }
  762. else{
  763. $("#" + id).hide();
  764. }
  765. });
  766. },
  767. htmlEscape: function(text){
  768. return text.replace(/[<>"&]/g, function(match, pos, originalText){
  769. console.log(match, pos, originalText)
  770. switch(match){
  771. case '<': {
  772. return '&lt';
  773. }
  774. case '>': {
  775. return '&gt';
  776. }
  777. case '&': {
  778. return '&amp';
  779. }
  780. case '\"': {
  781. return '&quot;';
  782. }
  783. }
  784. })
  785. }
  786. }
  787. export default luckysheetPostil;