d48b7615d542f83e90770be5b55e3db2d9012e5c27677796da8117a7c849ea957437654d2064e904d0b4cd0fc9c2372f802c62bec994c80024e3433bfcb5c2 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import {addClass} from './../../../helpers/dom/element';
  2. import Border from './border';
  3. import CellCoords from './cell/coords';
  4. import CellRange from './cell/range';
  5. /**
  6. * @class Selection
  7. */
  8. class Selection {
  9. /**
  10. * @param {Object} settings
  11. * @param {CellRange} cellRange
  12. */
  13. constructor(settings, cellRange) {
  14. this.settings = settings;
  15. this.cellRange = cellRange || null;
  16. this.instanceBorders = {};
  17. }
  18. /**
  19. * Each Walkontable clone requires it's own border for every selection. This method creates and returns selection
  20. * borders per instance
  21. *
  22. * @param {Walkontable} wotInstance
  23. * @returns {Border}
  24. */
  25. getBorder(wotInstance) {
  26. if (this.instanceBorders[wotInstance.guid]) {
  27. return this.instanceBorders[wotInstance.guid];
  28. }
  29. // where is this returned?
  30. this.instanceBorders[wotInstance.guid] = new Border(wotInstance, this.settings);
  31. }
  32. /**
  33. * Checks if selection is empty
  34. *
  35. * @returns {Boolean}
  36. */
  37. isEmpty() {
  38. return this.cellRange === null;
  39. }
  40. /**
  41. * Adds a cell coords to the selection
  42. *
  43. * @param {CellCoords} coords
  44. */
  45. add(coords) {
  46. if (this.isEmpty()) {
  47. this.cellRange = new CellRange(coords, coords, coords);
  48. } else {
  49. this.cellRange.expand(coords);
  50. }
  51. }
  52. /**
  53. * If selection range from or to property equals oldCoords, replace it with newCoords. Return boolean
  54. * information about success
  55. *
  56. * @param {CellCoords} oldCoords
  57. * @param {CellCoords} newCoords
  58. * @returns {Boolean}
  59. */
  60. replace(oldCoords, newCoords) {
  61. if (!this.isEmpty()) {
  62. if (this.cellRange.from.isEqual(oldCoords)) {
  63. this.cellRange.from = newCoords;
  64. return true;
  65. }
  66. if (this.cellRange.to.isEqual(oldCoords)) {
  67. this.cellRange.to = newCoords;
  68. return true;
  69. }
  70. }
  71. return false;
  72. }
  73. /**
  74. * Clears selection
  75. */
  76. clear() {
  77. this.cellRange = null;
  78. }
  79. /**
  80. * Returns the top left (TL) and bottom right (BR) selection coordinates
  81. *
  82. * @returns {Array} Returns array of coordinates for example `[1, 1, 5, 5]`
  83. */
  84. getCorners() {
  85. let topLeft = this.cellRange.getTopLeftCorner();
  86. let bottomRight = this.cellRange.getBottomRightCorner();
  87. return [
  88. topLeft.row,
  89. topLeft.col,
  90. bottomRight.row,
  91. bottomRight.col,
  92. ];
  93. }
  94. /**
  95. * Adds class name to cell element at given coords
  96. *
  97. * @param {Walkontable} wotInstance Walkontable instance
  98. * @param {Number} sourceRow Cell row coord
  99. * @param {Number} sourceColumn Cell column coord
  100. * @param {String} className Class name
  101. */
  102. addClassAtCoords(wotInstance, sourceRow, sourceColumn, className) {
  103. let TD = wotInstance.wtTable.getCell(new CellCoords(sourceRow, sourceColumn));
  104. if (typeof TD === 'object') {
  105. addClass(TD, className);
  106. }
  107. }
  108. /**
  109. * @param wotInstance
  110. */
  111. draw(wotInstance) {
  112. if (this.isEmpty()) {
  113. if (this.settings.border) {
  114. let border = this.getBorder(wotInstance);
  115. if (border) {
  116. border.disappear();
  117. }
  118. }
  119. return;
  120. }
  121. let renderedRows = wotInstance.wtTable.getRenderedRowsCount();
  122. let renderedColumns = wotInstance.wtTable.getRenderedColumnsCount();
  123. let corners = this.getCorners();
  124. let sourceRow,
  125. sourceCol,
  126. TH;
  127. for (let column = 0; column < renderedColumns; column++) {
  128. sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(column);
  129. if (sourceCol >= corners[1] && sourceCol <= corners[3]) {
  130. TH = wotInstance.wtTable.getColumnHeader(sourceCol);
  131. if (TH) {
  132. let newClasses = [];
  133. if (this.settings.highlightHeaderClassName) {
  134. newClasses.push(this.settings.highlightHeaderClassName);
  135. }
  136. if (this.settings.highlightColumnClassName) {
  137. newClasses.push(this.settings.highlightColumnClassName);
  138. }
  139. addClass(TH, newClasses);
  140. }
  141. }
  142. }
  143. for (let row = 0; row < renderedRows; row++) {
  144. sourceRow = wotInstance.wtTable.rowFilter.renderedToSource(row);
  145. if (sourceRow >= corners[0] && sourceRow <= corners[2]) {
  146. TH = wotInstance.wtTable.getRowHeader(sourceRow);
  147. if (TH) {
  148. let newClasses = [];
  149. if (this.settings.highlightHeaderClassName) {
  150. newClasses.push(this.settings.highlightHeaderClassName);
  151. }
  152. if (this.settings.highlightRowClassName) {
  153. newClasses.push(this.settings.highlightRowClassName);
  154. }
  155. addClass(TH, newClasses);
  156. }
  157. }
  158. for (let column = 0; column < renderedColumns; column++) {
  159. sourceCol = wotInstance.wtTable.columnFilter.renderedToSource(column);
  160. if (sourceRow >= corners[0] && sourceRow <= corners[2] && sourceCol >= corners[1] && sourceCol <= corners[3]) {
  161. // selected cell
  162. if (this.settings.className) {
  163. this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.className);
  164. }
  165. } else if (sourceRow >= corners[0] && sourceRow <= corners[2]) {
  166. // selection is in this row
  167. if (this.settings.highlightRowClassName) {
  168. this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightRowClassName);
  169. }
  170. } else if (sourceCol >= corners[1] && sourceCol <= corners[3]) {
  171. // selection is in this column
  172. if (this.settings.highlightColumnClassName) {
  173. this.addClassAtCoords(wotInstance, sourceRow, sourceCol, this.settings.highlightColumnClassName);
  174. }
  175. }
  176. }
  177. }
  178. wotInstance.getSetting('onBeforeDrawBorders', corners, this.settings.className);
  179. if (this.settings.border) {
  180. let border = this.getBorder(wotInstance);
  181. if (border) {
  182. // warning! border.appear modifies corners!
  183. border.appear(corners);
  184. }
  185. }
  186. }
  187. }
  188. export default Selection;