highlight.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import { createHighlight } from './types';
  2. import { arrayEach } from './../../helpers/array';
  3. export const ACTIVE_HEADER_TYPE = 'active-header';
  4. export const AREA_TYPE = 'area';
  5. export const CELL_TYPE = 'cell';
  6. export const FILL_TYPE = 'fill';
  7. export const HEADER_TYPE = 'header';
  8. export const CUSTOM_SELECTION = 'custom-selection';
  9. /**
  10. * Highlight class responsible for managing Walkontable Selection classes.
  11. *
  12. * With Highlight object you can manipulate four different highlight types:
  13. * - `cell` can be added only to a single cell at a time and it defines currently selected cell;
  14. * - `fill` can occur only once and its highlight defines selection of autofill functionality (managed by the plugin with the same name);
  15. * - `areas` can be added to multiple cells at a time. This type highlights selected cell or multiple cells.
  16. * The multiple cells have to be defined as an uninterrupted order (regular shape). Otherwise, the new layer of
  17. * that type should be created to manage not-consecutive selection;
  18. * - `header` can occur multiple times. This type is designed to highlight only headers. Like `area` type it
  19. * can appear with multiple highlights (accessed under different level layers).
  20. *
  21. * @class Highlight
  22. * @util
  23. */
  24. class Highlight {
  25. constructor(options) {
  26. /**
  27. * Options consumed by Highlight class and Walkontable Selection classes.
  28. *
  29. * @type {Object}
  30. */
  31. this.options = options;
  32. /**
  33. * The property which describes which layer level of the visual selection will be modified.
  34. * This option is valid only for `area` and `header` highlight types which occurs multiple times on
  35. * the table (as a non-consecutive selection).
  36. *
  37. * An order of the layers is the same as the order of added new non-consecutive selections.
  38. *
  39. * @type {Number}
  40. * @default 0
  41. */
  42. this.layerLevel = 0;
  43. /**
  44. * `cell` highlight object which describes attributes for the currently selected cell.
  45. * It can only occur only once on the table.
  46. *
  47. * @type {Selection}
  48. */
  49. this.cell = createHighlight(CELL_TYPE, options);
  50. /**
  51. * `fill` highlight object which describes attributes for the borders for autofill functionality.
  52. * It can only occur only once on the table.
  53. *
  54. * @type {Selection}
  55. */
  56. this.fill = createHighlight(FILL_TYPE, options);
  57. /**
  58. * Collection of the `area` highlights. That objects describes attributes for the borders and selection of
  59. * the multiple selected cells. It can occur multiple times on the table.
  60. *
  61. * @type {Map.<number, Selection>}
  62. */
  63. this.areas = new Map();
  64. /**
  65. * Collection of the `header` highlights. That objects describes attributes for the selection of
  66. * the multiple selected rows and columns in the table header. It can occur multiple times on the table.
  67. *
  68. * @type {Map.<number, Selection>}
  69. */
  70. this.headers = new Map();
  71. /**
  72. * Collection of the `active-header` highlights. That objects describes attributes for the selection of
  73. * the multiple selected rows and columns in the table header. The table headers which have selected all items in
  74. * a row will be marked as `active-header`.
  75. *
  76. * @type {Map.<number, Selection>}
  77. */
  78. this.activeHeaders = new Map();
  79. /**
  80. * Collection of the `custom-selection`, holder for example borders added through CustomBorders plugin.
  81. *
  82. * @type {Selection[]}
  83. */
  84. this.customSelections = [];
  85. }
  86. /**
  87. * Check if highlight cell rendering is disabled for specyfied highlight type.
  88. *
  89. * @param {String} highlightType Highlight type. Possible values are: `cell`, `area`, `fill` or `header`.
  90. * @return {Boolean}
  91. */
  92. isEnabledFor(highlightType) {
  93. // Legacy compatibility.
  94. const type = highlightType === 'current' ? CELL_TYPE : highlightType;
  95. let disableHighlight = this.options.disableHighlight;
  96. if (typeof disableHighlight === 'string') {
  97. disableHighlight = [disableHighlight];
  98. }
  99. return disableHighlight === false || Array.isArray(disableHighlight) && !disableHighlight.includes(type);
  100. }
  101. /**
  102. * Set a new layer level to make access to the desire `area` and `header` highlights.
  103. *
  104. * @param {Number} [level=0] Layer level to use.
  105. * @returns {Highlight}
  106. */
  107. useLayerLevel(level = 0) {
  108. this.layerLevel = level;
  109. return this;
  110. }
  111. /**
  112. * Get Walkontable Selection instance created for controlling highlight of the currently selected/edited cell.
  113. *
  114. * @return {Selection}
  115. */
  116. getCell() {
  117. return this.cell;
  118. }
  119. /**
  120. * Get Walkontable Selection instance created for controlling highlight of the autofill functionality.
  121. *
  122. * @return {Selection}
  123. */
  124. getFill() {
  125. return this.fill;
  126. }
  127. /**
  128. * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
  129. * of the multiple selected cells.
  130. *
  131. * @return {Selection}
  132. */
  133. createOrGetArea() {
  134. const layerLevel = this.layerLevel;
  135. let area;
  136. if (this.areas.has(layerLevel)) {
  137. area = this.areas.get(layerLevel);
  138. } else {
  139. area = createHighlight(AREA_TYPE, { layerLevel, ...this.options });
  140. this.areas.set(layerLevel, area);
  141. }
  142. return area;
  143. }
  144. /**
  145. * Get all Walkontable Selection instances which describes the state of the visual highlight of the cells.
  146. *
  147. * @return {Selection[]}
  148. */
  149. getAreas() {
  150. return [...this.areas.values()];
  151. }
  152. /**
  153. * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
  154. * of the multiple selected header cells.
  155. *
  156. * @return {Selection}
  157. */
  158. createOrGetHeader() {
  159. const layerLevel = this.layerLevel;
  160. let header;
  161. if (this.headers.has(layerLevel)) {
  162. header = this.headers.get(layerLevel);
  163. } else {
  164. header = createHighlight(HEADER_TYPE, { ...this.options });
  165. this.headers.set(layerLevel, header);
  166. }
  167. return header;
  168. }
  169. /**
  170. * Get all Walkontable Selection instances which describes the state of the visual highlight of the headers.
  171. *
  172. * @return {Selection[]}
  173. */
  174. getHeaders() {
  175. return [...this.headers.values()];
  176. }
  177. /**
  178. * Get or create (if not exist in the cache) Walkontable Selection instance created for controlling highlight
  179. * of the multiple selected active header cells.
  180. *
  181. * @return {Selection}
  182. */
  183. createOrGetActiveHeader() {
  184. const layerLevel = this.layerLevel;
  185. let header;
  186. if (this.activeHeaders.has(layerLevel)) {
  187. header = this.activeHeaders.get(layerLevel);
  188. } else {
  189. header = createHighlight(ACTIVE_HEADER_TYPE, { ...this.options });
  190. this.activeHeaders.set(layerLevel, header);
  191. }
  192. return header;
  193. }
  194. /**
  195. * Get all Walkontable Selection instances which describes the state of the visual highlight of the active headers.
  196. *
  197. * @return {Selection[]}
  198. */
  199. getActiveHeaders() {
  200. return [...this.activeHeaders.values()];
  201. }
  202. /**
  203. * Get Walkontable Selection instance created for controlling highlight of the custom selection functionality.
  204. *
  205. * @return {Selection}
  206. */
  207. getCustomSelections() {
  208. return [...this.customSelections.values()];
  209. }
  210. /**
  211. * Add selection to the custom selection instance. The new selection are added to the end of the selection collection.
  212. *
  213. * @param {Object} options
  214. */
  215. addCustomSelection(options) {
  216. this.customSelections.push(createHighlight(CUSTOM_SELECTION, { ...options }));
  217. }
  218. /**
  219. * Perform cleaning visual highlights for the whole table.
  220. */
  221. clear() {
  222. this.cell.clear();
  223. this.fill.clear();
  224. arrayEach(this.areas.values(), highlight => void highlight.clear());
  225. arrayEach(this.headers.values(), highlight => void highlight.clear());
  226. arrayEach(this.activeHeaders.values(), highlight => void highlight.clear());
  227. }
  228. /**
  229. * This object can be iterate over using `for of` syntax or using internal `arrayEach` helper.
  230. */
  231. [Symbol.iterator]() {
  232. return [
  233. this.cell,
  234. this.fill,
  235. ...this.areas.values(),
  236. ...this.headers.values(),
  237. ...this.activeHeaders.values(),
  238. ...this.customSelections,
  239. ][Symbol.iterator]();
  240. }
  241. }
  242. export default Highlight;