GridEditorUtil.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /**
  2. * Utility for grid editor
  3. */
  4. class GridEditorUtil {
  5. constructor() {
  6. // https://regex101.com/r/7BN2fR/11
  7. this.lineBeginPartOfGridRE = /^:::(\s.*)editable-row$/;
  8. this.lineEndPartOfGridRE = /^:::$/;
  9. this.mappingAllGridDivisionPatterns = [
  10. {
  11. numberOfGridDivisions: 2,
  12. mapping: [[2, 10], [4, 8], [6, 6], [8, 4], [10, 2]],
  13. },
  14. {
  15. numberOfGridDivisions: 3,
  16. mapping: [[2, 5, 5], [5, 2, 5], [5, 5, 2], [4, 4, 4], [3, 3, 6], [3, 6, 3], [6, 3, 3]],
  17. },
  18. {
  19. numberOfGridDivisions: 4,
  20. mapping: [[2, 2, 4, 4], [4, 4, 2, 2], [2, 4, 2, 4], [4, 2, 4, 2], [3, 3, 3, 3], [2, 2, 2, 6], [6, 2, 2, 2]],
  21. },
  22. ];
  23. this.isInGridBlock = this.isInGridBlock.bind(this);
  24. this.replaceGridWithHtmlWithEditor = this.replaceGridWithHtmlWithEditor.bind(this);
  25. }
  26. /**
  27. * return boolean value whether the cursor position is in a grid block
  28. */
  29. isInGridBlock(editor) {
  30. const bog = this.getBog(editor);
  31. const eog = this.getEog(editor);
  32. return (JSON.stringify(bog) !== JSON.stringify(eog));
  33. }
  34. /**
  35. * return grid html where the cursor is
  36. */
  37. getGridHtml(editor) {
  38. const curPos = editor.getCursor();
  39. if (this.isInGridBlock(editor)) {
  40. const bog = this.getBog(editor);
  41. const eog = this.getEog(editor);
  42. // skip block begin sesion("::: editable-row")
  43. bog.line++;
  44. // skip block end sesion(":::")
  45. eog.line--;
  46. eog.ch = editor.getDoc().getLine(eog.line).length;
  47. return editor.getDoc().getRange(bog, eog);
  48. }
  49. return editor.getDoc().getLine(curPos.line);
  50. }
  51. /**
  52. * return the postion of the BOD(beginning of grid)
  53. */
  54. getBog(editor) {
  55. const curPos = editor.getCursor();
  56. const firstLine = editor.getDoc().firstLine();
  57. if (this.lineBeginPartOfGridRE.test(editor.getDoc().getLine(curPos.line))) {
  58. return { line: curPos.line, ch: 0 };
  59. }
  60. let line = curPos.line - 1;
  61. let isFound = false;
  62. for (; line >= firstLine; line--) {
  63. const strLine = editor.getDoc().getLine(line);
  64. if (this.lineBeginPartOfGridRE.test(strLine)) {
  65. isFound = true;
  66. break;
  67. }
  68. if (this.lineEndPartOfGridRE.test(strLine)) {
  69. isFound = false;
  70. break;
  71. }
  72. }
  73. if (!isFound) {
  74. return { line: curPos.line, ch: curPos.ch };
  75. }
  76. const bodLine = Math.max(firstLine, line);
  77. return { line: bodLine, ch: 0 };
  78. }
  79. /**
  80. * return the postion of the EOD(end of grid)
  81. */
  82. getEog(editor) {
  83. const curPos = editor.getCursor();
  84. const lastLine = editor.getDoc().lastLine();
  85. if (this.lineEndPartOfGridRE.test(editor.getDoc().getLine(curPos.line))) {
  86. return { line: curPos.line, ch: editor.getDoc().getLine(curPos.line).length };
  87. }
  88. let line = curPos.line + 1;
  89. let isFound = false;
  90. for (; line <= lastLine; line++) {
  91. const strLine = editor.getDoc().getLine(line);
  92. if (this.lineEndPartOfGridRE.test(strLine)) {
  93. isFound = true;
  94. break;
  95. }
  96. if (this.lineBeginPartOfGridRE.test(strLine)) {
  97. isFound = false;
  98. break;
  99. }
  100. }
  101. if (!isFound) {
  102. return { line: curPos.line, ch: curPos.ch };
  103. }
  104. const eodLine = Math.min(line, lastLine);
  105. const lineLength = editor.getDoc().getLine(eodLine).length;
  106. return { line: eodLine, ch: lineLength };
  107. }
  108. replaceGridWithHtmlWithEditor(editor, grid) {
  109. const curPos = editor.getCursor();
  110. editor.getDoc().replaceRange(grid.toString(), this.getBog(editor), this.getEog(editor));
  111. editor.getDoc().setCursor(curPos.line + 1, 2);
  112. }
  113. convertRatiosAndSizeToHTML(ratioNumbers, responsiveSize) {
  114. const cols = ratioNumbers.map((ratioNumber, i) => {
  115. const className = `col${responsiveSize !== 'xs' ? `-${responsiveSize}` : ''}-${ratioNumber} bsGrid${i + 1}`;
  116. return `<div class="${className}"></div>`;
  117. });
  118. return cols.join('\n');
  119. }
  120. }
  121. // singleton pattern
  122. const instance = new GridEditorUtil();
  123. Object.freeze(instance);
  124. export default instance;