table.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import Delta from 'quill-delta';
  2. import Quill from '../core/quill';
  3. import Module from '../core/module';
  4. import {
  5. TableCell,
  6. TableRow,
  7. TableBody,
  8. TableContainer,
  9. tableId,
  10. } from '../formats/table';
  11. class Table extends Module {
  12. static register(options) {
  13. Quill.register(TableCell, options);
  14. Quill.register(TableRow, options);
  15. Quill.register(TableBody, options);
  16. Quill.register(TableContainer, options);
  17. }
  18. constructor(...args) {
  19. super(...args);
  20. this.listenBalanceCells();
  21. }
  22. balanceTables() {
  23. this.quill.scroll.descendants(TableContainer).forEach(table => {
  24. table.balanceCells();
  25. });
  26. }
  27. deleteColumn() {
  28. const [table, , cell] = this.getTable();
  29. if (cell == null) return;
  30. table.deleteColumn(cell.cellOffset());
  31. this.quill.update(Quill.sources.USER);
  32. }
  33. deleteRow() {
  34. const [, row] = this.getTable();
  35. if (row == null) return;
  36. row.remove();
  37. this.quill.update(Quill.sources.USER);
  38. }
  39. deleteTable() {
  40. const [table] = this.getTable();
  41. if (table == null) return;
  42. const offset = table.offset();
  43. table.remove();
  44. this.quill.update(Quill.sources.USER);
  45. this.quill.setSelection(offset, Quill.sources.SILENT);
  46. }
  47. getTable(range = this.quill.getSelection()) {
  48. if (range == null) return [null, null, null, -1];
  49. const [cell, offset] = this.quill.getLine(range.index);
  50. if (cell == null || cell.statics.blotName !== TableCell.blotName) {
  51. return [null, null, null, -1];
  52. }
  53. const row = cell.parent;
  54. const table = row.parent.parent;
  55. return [table, row, cell, offset];
  56. }
  57. insertColumn(offset) {
  58. const range = this.quill.getSelection();
  59. const [table, row, cell] = this.getTable(range);
  60. if (cell == null) return;
  61. const column = cell.cellOffset();
  62. table.insertColumn(column + offset);
  63. this.quill.update(Quill.sources.USER);
  64. let shift = row.rowOffset();
  65. if (offset === 0) {
  66. shift += 1;
  67. }
  68. this.quill.setSelection(
  69. range.index + shift,
  70. range.length,
  71. Quill.sources.SILENT,
  72. );
  73. }
  74. insertColumnLeft() {
  75. this.insertColumn(0);
  76. }
  77. insertColumnRight() {
  78. this.insertColumn(1);
  79. }
  80. insertRow(offset) {
  81. const range = this.quill.getSelection();
  82. const [table, row, cell] = this.getTable(range);
  83. if (cell == null) return;
  84. const index = row.rowOffset();
  85. table.insertRow(index + offset);
  86. this.quill.update(Quill.sources.USER);
  87. if (offset > 0) {
  88. this.quill.setSelection(range, Quill.sources.SILENT);
  89. } else {
  90. this.quill.setSelection(
  91. range.index + row.children.length,
  92. range.length,
  93. Quill.sources.SILENT,
  94. );
  95. }
  96. }
  97. insertRowAbove() {
  98. this.insertRow(0);
  99. }
  100. insertRowBelow() {
  101. this.insertRow(1);
  102. }
  103. insertTable(rows, columns) {
  104. const range = this.quill.getSelection();
  105. if (range == null) return;
  106. const delta = new Array(rows).fill(0).reduce(memo => {
  107. const text = new Array(columns).fill('\n').join('');
  108. return memo.insert(text, { table: tableId() });
  109. }, new Delta().retain(range.index));
  110. this.quill.updateContents(delta, Quill.sources.USER);
  111. this.quill.setSelection(range.index, Quill.sources.SILENT);
  112. this.balanceTables();
  113. }
  114. listenBalanceCells() {
  115. this.quill.on(Quill.events.SCROLL_OPTIMIZE, mutations => {
  116. mutations.some(mutation => {
  117. if (['TD', 'TR', 'TBODY', 'TABLE'].includes(mutation.target.tagName)) {
  118. this.quill.once(Quill.events.TEXT_CHANGE, (delta, old, source) => {
  119. if (source !== Quill.sources.USER) return;
  120. this.balanceTables();
  121. });
  122. return true;
  123. }
  124. return false;
  125. });
  126. });
  127. }
  128. }
  129. export default Table;