handsontable 0.0.0-next-fad35d5-20240924 → 0.0.0-next-d7edb4b-20240927

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of handsontable might be problematic. Click here for more details.

Files changed (127) hide show
  1. package/3rdparty/walkontable/src/calculator/calculationType/renderedColumns.js +0 -23
  2. package/3rdparty/walkontable/src/calculator/calculationType/renderedColumns.mjs +0 -23
  3. package/3rdparty/walkontable/src/calculator/calculationType/renderedRows.js +0 -23
  4. package/3rdparty/walkontable/src/calculator/calculationType/renderedRows.mjs +0 -23
  5. package/3rdparty/walkontable/src/core/_base.js +0 -7
  6. package/3rdparty/walkontable/src/core/_base.mjs +0 -7
  7. package/3rdparty/walkontable/src/facade/core.js +0 -3
  8. package/3rdparty/walkontable/src/facade/core.mjs +0 -3
  9. package/3rdparty/walkontable/src/overlay/_base.js +0 -3
  10. package/3rdparty/walkontable/src/overlay/_base.mjs +0 -3
  11. package/3rdparty/walkontable/src/selection/border/border.js +45 -33
  12. package/3rdparty/walkontable/src/selection/border/border.mjs +46 -34
  13. package/3rdparty/walkontable/src/selection/scanner.js +11 -46
  14. package/3rdparty/walkontable/src/selection/scanner.mjs +11 -46
  15. package/3rdparty/walkontable/src/settings.js +0 -8
  16. package/3rdparty/walkontable/src/settings.mjs +0 -8
  17. package/3rdparty/walkontable/src/table/master.js +1 -1
  18. package/3rdparty/walkontable/src/table/master.mjs +2 -2
  19. package/3rdparty/walkontable/src/table.js +3 -6
  20. package/3rdparty/walkontable/src/table.mjs +3 -6
  21. package/3rdparty/walkontable/src/viewport.js +4 -26
  22. package/3rdparty/walkontable/src/viewport.mjs +4 -26
  23. package/base.js +4 -4
  24. package/base.mjs +3 -3
  25. package/core.d.ts +1 -1
  26. package/core.js +12 -13
  27. package/core.mjs +4 -5
  28. package/dataMap/metaManager/metaSchema.js +2 -68
  29. package/dataMap/metaManager/metaSchema.mjs +2 -68
  30. package/dataMap/metaManager/mods/dynamicCellMeta.js +3 -2
  31. package/dataMap/metaManager/mods/dynamicCellMeta.mjs +1 -1
  32. package/dist/handsontable.css +2 -2
  33. package/dist/handsontable.full.css +2 -2
  34. package/dist/handsontable.full.js +2685 -3046
  35. package/dist/handsontable.full.min.css +2 -2
  36. package/dist/handsontable.full.min.js +75 -75
  37. package/dist/handsontable.js +2687 -3048
  38. package/dist/handsontable.min.css +2 -2
  39. package/dist/handsontable.min.js +18 -18
  40. package/editorManager.js +2 -2
  41. package/editorManager.mjs +2 -2
  42. package/editors/autocompleteEditor/autocompleteEditor.js +31 -14
  43. package/editors/autocompleteEditor/autocompleteEditor.mjs +31 -14
  44. package/editors/baseEditor/baseEditor.js +17 -24
  45. package/editors/baseEditor/baseEditor.mjs +18 -25
  46. package/editors/dropdownEditor/dropdownEditor.js +3 -2
  47. package/editors/dropdownEditor/dropdownEditor.mjs +1 -1
  48. package/editors/handsontableEditor/handsontableEditor.js +24 -0
  49. package/editors/handsontableEditor/handsontableEditor.mjs +24 -0
  50. package/editors/registry.js +2 -2
  51. package/editors/registry.mjs +1 -1
  52. package/editors/textEditor/textEditor.js +2 -2
  53. package/editors/textEditor/textEditor.mjs +3 -3
  54. package/helpers/dom/element.js +4 -17
  55. package/helpers/dom/element.mjs +4 -16
  56. package/helpers/mixed.js +1 -1
  57. package/helpers/mixed.mjs +1 -1
  58. package/index.d.ts +1 -2
  59. package/package.json +1 -1
  60. package/{core/hooks/index.d.ts → pluginHooks.d.ts} +21 -17
  61. package/{core/hooks/constants.mjs → pluginHooks.js} +489 -16
  62. package/{core/hooks/constants.js → pluginHooks.mjs} +486 -20
  63. package/plugins/autoColumnSize/autoColumnSize.js +27 -18
  64. package/plugins/autoColumnSize/autoColumnSize.mjs +27 -18
  65. package/plugins/autoRowSize/autoRowSize.js +22 -16
  66. package/plugins/autoRowSize/autoRowSize.mjs +23 -17
  67. package/plugins/autofill/autofill.js +5 -4
  68. package/plugins/autofill/autofill.mjs +1 -1
  69. package/plugins/base/base.d.ts +1 -1
  70. package/plugins/base/base.js +0 -39
  71. package/plugins/base/base.mjs +1 -40
  72. package/plugins/base/index.js +1 -2
  73. package/plugins/base/index.mjs +1 -1
  74. package/plugins/bindRowsWithHeaders/bindRowsWithHeaders.js +5 -2
  75. package/plugins/bindRowsWithHeaders/bindRowsWithHeaders.mjs +5 -2
  76. package/plugins/columnSorting/columnSorting.js +4 -3
  77. package/plugins/columnSorting/columnSorting.mjs +1 -1
  78. package/plugins/comments/comments.js +15 -7
  79. package/plugins/comments/comments.mjs +16 -8
  80. package/plugins/contextMenu/contextMenu.js +7 -6
  81. package/plugins/contextMenu/contextMenu.mjs +1 -1
  82. package/plugins/contextMenu/menu/menu.js +1 -1
  83. package/plugins/contextMenu/menu/menu.mjs +2 -2
  84. package/plugins/contextMenu/menu/positioner.js +4 -2
  85. package/plugins/contextMenu/menu/positioner.mjs +4 -2
  86. package/plugins/copyPaste/copyPaste.js +23 -29
  87. package/plugins/copyPaste/copyPaste.mjs +15 -21
  88. package/plugins/dropdownMenu/dropdownMenu.js +7 -6
  89. package/plugins/dropdownMenu/dropdownMenu.mjs +1 -1
  90. package/plugins/formulas/formulas.js +7 -7
  91. package/plugins/formulas/formulas.mjs +1 -1
  92. package/plugins/hiddenColumns/hiddenColumns.js +30 -19
  93. package/plugins/hiddenColumns/hiddenColumns.mjs +26 -15
  94. package/plugins/hiddenRows/hiddenRows.js +29 -18
  95. package/plugins/hiddenRows/hiddenRows.mjs +25 -14
  96. package/plugins/manualColumnFreeze/manualColumnFreeze.js +5 -5
  97. package/plugins/manualColumnFreeze/manualColumnFreeze.mjs +1 -1
  98. package/plugins/manualColumnMove/manualColumnMove.js +3 -3
  99. package/plugins/manualColumnMove/manualColumnMove.mjs +1 -1
  100. package/plugins/manualRowMove/manualRowMove.js +5 -5
  101. package/plugins/manualRowMove/manualRowMove.mjs +3 -3
  102. package/plugins/mergeCells/cellsCollection.js +3 -15
  103. package/plugins/mergeCells/cellsCollection.mjs +4 -16
  104. package/plugins/mergeCells/mergeCells.d.ts +2 -6
  105. package/plugins/mergeCells/mergeCells.js +55 -78
  106. package/plugins/mergeCells/mergeCells.mjs +53 -76
  107. package/plugins/mergeCells/renderer.js +3 -13
  108. package/plugins/mergeCells/renderer.mjs +3 -13
  109. package/plugins/persistentState/persistentState.js +4 -4
  110. package/plugins/persistentState/persistentState.mjs +1 -1
  111. package/plugins/undoRedo/undoRedo.js +5 -4
  112. package/plugins/undoRedo/undoRedo.mjs +3 -3
  113. package/renderers/checkboxRenderer/checkboxRenderer.js +2 -2
  114. package/renderers/checkboxRenderer/checkboxRenderer.mjs +1 -1
  115. package/settings.d.ts +1 -3
  116. package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.js +1 -1
  117. package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.mjs +1 -1
  118. package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.js +1 -1
  119. package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.mjs +1 -1
  120. package/shortcutContexts/commands/scrollToFocusedCell.js +4 -4
  121. package/shortcutContexts/commands/scrollToFocusedCell.mjs +4 -4
  122. package/tableView.js +43 -38
  123. package/tableView.mjs +43 -38
  124. package/core/hooks/bucket.js +0 -180
  125. package/core/hooks/bucket.mjs +0 -176
  126. package/core/hooks/index.js +0 -385
  127. package/core/hooks/index.mjs +0 -381
package/index.d.ts CHANGED
@@ -78,7 +78,7 @@ import * as dom from './helpers/dom';
78
78
  import CellCoords from './3rdparty/walkontable/src/cell/coords';
79
79
  import CellRange from './3rdparty/walkontable/src/cell/range';
80
80
  import EventManager from './eventManager';
81
- import { Hooks, Events } from './core/hooks';
81
+ import { Hooks } from './pluginHooks';
82
82
  // plugins
83
83
  import {
84
84
  AutoColumnSize as _AutoColumnSize,
@@ -547,6 +547,5 @@ declare class Handsontable extends Core {
547
547
  export {
548
548
  CellCoords,
549
549
  CellRange,
550
- Events,
551
550
  };
552
551
  export default Handsontable;
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/handsontable/handsontable/issues"
11
11
  },
12
12
  "author": "Handsoncode <hello@handsontable.com>",
13
- "version": "0.0.0-next-fad35d5-20240924",
13
+ "version": "0.0.0-next-d7edb4b-20240927",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
@@ -1,33 +1,33 @@
1
1
  import { ExportedChange } from 'hyperformula';
2
- import CellCoords from '../../3rdparty/walkontable/src/cell/coords';
3
- import CellRange from '../../3rdparty/walkontable/src/cell/range';
4
- import { ViewportColumnsCalculator } from '../../3rdparty/walkontable/src/calculator/viewportColumns';
5
- import Core from '../../core';
6
- import { SelectionController } from '../../selection';
2
+ import CellCoords from './3rdparty/walkontable/src/cell/coords';
3
+ import CellRange from './3rdparty/walkontable/src/cell/range';
4
+ import { ViewportColumnsCalculator } from './3rdparty/walkontable/src/calculator/viewportColumns';
5
+ import Core from './core';
6
+ import { SelectionController } from './selection';
7
7
  import {
8
8
  ContextMenu,
9
9
  PredefinedMenuItemKey as ContextMenuPredefinedMenuItemKey,
10
10
  MenuItemConfig as ContextMenuMenuItemConfig,
11
- } from '../../plugins/contextMenu';
11
+ } from './plugins/contextMenu';
12
12
  import {
13
13
  DropdownMenu,
14
- } from '../../plugins/dropdownMenu';
14
+ } from './plugins/dropdownMenu';
15
15
  import {
16
16
  Config as ColumnSortingConfig,
17
- } from '../../plugins/columnSorting';
17
+ } from './plugins/columnSorting';
18
18
  import {
19
19
  ColumnConditions as FiltersColumnConditions,
20
- } from '../../plugins/filters';
20
+ } from './plugins/filters';
21
21
  import {
22
22
  Action as UndoRedoAction,
23
- } from '../../plugins/undoRedo';
23
+ } from './plugins/undoRedo';
24
24
  import {
25
25
  Settings as MergeCellsSettings,
26
- } from '../../plugins/mergeCells';
26
+ } from './plugins/mergeCells';
27
27
  import {
28
28
  GridSettings,
29
29
  CellProperties,
30
- } from '../../settings';
30
+ } from './settings';
31
31
 
32
32
  import {
33
33
  CellValue,
@@ -36,7 +36,11 @@ import {
36
36
  ChangeSource,
37
37
  RangeType,
38
38
  OverlayType,
39
- } from '../../common';
39
+ } from './common';
40
+
41
+ type Bucket = {
42
+ [P in keyof Events]: Array<Events[P]>;
43
+ };
40
44
 
41
45
  interface HookHighlightRowHeaderMeta {
42
46
  selectionType: string;
@@ -243,8 +247,7 @@ export interface Events {
243
247
  modifyFocusedElement?: (row: number, column: number, focusedElement: HTMLElement) => void | HTMLElement;
244
248
  modifyData?: (row: number, column: number, valueHolder: { value: CellValue }, ioMode: 'get' | 'set') => void;
245
249
  modifyFocusOnTabNavigation?: (tabActivationDir: 'from_above' | 'from_below', visualCoords: CellCoords) => void;
246
- modifyGetCellCoords?: (row: number, column: number, topmost: boolean, source: string | undefined) => void | [number, number] | [number, number, number, number];
247
- modifyGetCoordsElement?: (row: number, column: number) => void | [number, number];
250
+ modifyGetCellCoords?: (row: number, column: number, topmost: boolean) => void | [number, number] | [number, number, number, number];
248
251
  modifyRowData?: (row: number) => void;
249
252
  modifyRowHeader?: (row: number) => void;
250
253
  modifyRowHeaderWidth?: (rowHeaderWidth: number) => void;
@@ -261,14 +264,15 @@ export interface Events {
261
264
 
262
265
  export class Hooks {
263
266
  add<K extends keyof Events>(key: K, callback: Events[K] | Array<Events[K]>, context?: Core, orderIndex?: number): Hooks;
264
- addAsFixed<K extends keyof Events>(key: K, callback: Events[K] | Array<Events[K]>, context?: Core, orderIndex?: number): Hooks;
267
+ createEmptyBucket(): Bucket;
265
268
  deregister(key: string): void;
266
269
  destroy(context?: Core): void;
270
+ getBucket(context?: Core): Bucket;
267
271
  getRegistered(): Array<keyof Events>;
268
272
  has(key: keyof Events, context?: Core): boolean;
269
273
  isDeprecated(key: keyof Events): boolean;
270
274
  isRegistered(key: keyof Events): boolean;
271
- once<K extends keyof Events>(key: K, callback: Events[K] | Array<Events[K]>, context?: Core): Hooks;
275
+ once<K extends keyof Events>(key: K, callback: Events[K] | Array<Events[K]>, context?: Core): void;
272
276
  register(key: string): void;
273
277
  remove(key: keyof Events, callback: () => void, context?: Core): boolean;
274
278
  run(context: Core, key: keyof Events, p1?: any, p2?: any, p3?: any, p4?: any, p5?: any, p6?: any): any;
@@ -1,3 +1,18 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ require("core-js/modules/es.error.cause.js");
5
+ require("core-js/modules/es.array.push.js");
6
+ require("core-js/modules/es.array.unscopables.flat-map.js");
7
+ var _array = require("./helpers/array");
8
+ var _object = require("./helpers/object");
9
+ var _string = require("./helpers/string");
10
+ var _console = require("./helpers/console");
11
+ var _templateLiteralTag = require("./helpers/templateLiteralTag");
12
+ var _function = require("./helpers/function");
13
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
14
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
15
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
1
16
  /* eslint-disable jsdoc/require-description-complete-sentence */
2
17
  /**
3
18
  * @description
@@ -110,7 +125,8 @@
110
125
  * ...
111
126
  */
112
127
 
113
- export const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-sentence */
128
+ // @TODO: Move plugin description hooks to plugin?
129
+ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-sentence */
114
130
  /**
115
131
  * Fired after resetting a cell's meta. This happens when the {@link Core#updateSettings} method is called.
116
132
  *
@@ -1453,22 +1469,9 @@ export const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-com
1453
1469
  * @param {boolean} topmost If set to `true`, it returns the TD element from the topmost overlay. For example,
1454
1470
  * if the wanted cell is in the range of fixed rows, it will return a TD element
1455
1471
  * from the `top` overlay.
1456
- * @param {string} source String that identifies how this coords change will be processed. Possible values:
1457
- * `meta` the change will affect the cell meta and data; `render` the change will affect the
1458
- * DOM element that will be returned by the `getCell` method.
1459
1472
  * @returns {undefined|number[]}
1460
1473
  */
1461
1474
  'modifyGetCellCoords',
1462
- /**
1463
- * Used to modify the returned cell coordinates of clicked cells (TD or TH elements).
1464
- *
1465
- * @event Hooks#modifyGetCoordsElement
1466
- * @since 14.6.0
1467
- * @param {number} row Visual row index.
1468
- * @param {number} column Visual column index.
1469
- * @returns {undefined|number[]}
1470
- */
1471
- 'modifyGetCoordsElement',
1472
1475
  /**
1473
1476
  * Used to modify the cell coordinates when the table is activated (going into the listen mode).
1474
1477
  *
@@ -2632,6 +2635,15 @@ export const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-com
2632
2635
  */
2633
2636
  'modifyAutoColumnSizeSeed'];
2634
2637
 
2638
+ /**
2639
+ * Template warning message for removed hooks.
2640
+ *
2641
+ * @type {string}
2642
+ */
2643
+ const REMOVED_MESSAGE = (0, _templateLiteralTag.toSingleLine)`The plugin hook "[hookName]" was removed in Handsontable [removedInVersion].\x20
2644
+ Please consult release notes https://github.com/handsontable/handsontable/releases/tag/[removedInVersion] to\x20
2645
+ learn about the migration path.`;
2646
+
2635
2647
  /**
2636
2648
  * The list of the hooks which are removed from the API. The warning message is printed out in
2637
2649
  * the developer console when the hook is used.
@@ -2641,7 +2653,7 @@ export const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-com
2641
2653
  *
2642
2654
  * @type {Map<string, string>}
2643
2655
  */
2644
- export const REMOVED_HOOKS = new Map([['modifyRow', '8.0.0'], ['modifyCol', '8.0.0'], ['unmodifyRow', '8.0.0'], ['unmodifyCol', '8.0.0'], ['skipLengthCache', '8.0.0'], ['hiddenColumn', '8.0.0'], ['hiddenRow', '8.0.0']]);
2656
+ const REMOVED_HOOKS = new Map([['modifyRow', '8.0.0'], ['modifyCol', '8.0.0'], ['unmodifyRow', '8.0.0'], ['unmodifyCol', '8.0.0'], ['skipLengthCache', '8.0.0'], ['hiddenColumn', '8.0.0'], ['hiddenRow', '8.0.0']]);
2645
2657
 
2646
2658
  /* eslint-disable jsdoc/require-description-complete-sentence */
2647
2659
  /**
@@ -2664,4 +2676,465 @@ export const REMOVED_HOOKS = new Map([['modifyRow', '8.0.0'], ['modifyCol', '8.0
2664
2676
  * @type {Map<string, string>}
2665
2677
  */
2666
2678
  /* eslint-enable jsdoc/require-description-complete-sentence */
2667
- export const DEPRECATED_HOOKS = new Map([[]]);
2679
+ const DEPRECATED_HOOKS = new Map([[]]);
2680
+ const callbackOrder = new WeakMap();
2681
+ class Hooks {
2682
+ static getSingleton() {
2683
+ return getGlobalSingleton();
2684
+ }
2685
+
2686
+ /**
2687
+ * @type {object}
2688
+ */
2689
+
2690
+ /**
2691
+ *
2692
+ */
2693
+ constructor() {
2694
+ _defineProperty(this, "globalBucket", void 0);
2695
+ this.globalBucket = this.createEmptyBucket();
2696
+ }
2697
+
2698
+ /**
2699
+ * Returns a new object with empty handlers related to every registered hook name.
2700
+ *
2701
+ * @returns {object} The empty bucket object.
2702
+ *
2703
+ * @example
2704
+ * ```js
2705
+ * Handsontable.hooks.createEmptyBucket();
2706
+ * // Results:
2707
+ * {
2708
+ * ...
2709
+ * afterCreateCol: [],
2710
+ * afterCreateRow: [],
2711
+ * beforeInit: [],
2712
+ * ...
2713
+ * }
2714
+ * ```
2715
+ */
2716
+ createEmptyBucket() {
2717
+ const bucket = Object.create(null);
2718
+
2719
+ // eslint-disable-next-line no-return-assign
2720
+ (0, _array.arrayEach)(REGISTERED_HOOKS, hook => {
2721
+ bucket[hook] = [];
2722
+ this.initOrderMap(bucket, hook);
2723
+ });
2724
+ return bucket;
2725
+ }
2726
+
2727
+ /**
2728
+ * Get hook bucket based on the context of the object or if argument is `undefined`, get the global hook bucket.
2729
+ *
2730
+ * @param {object} [context=null] A Handsontable instance.
2731
+ * @returns {object} Returns a global or Handsontable instance bucket.
2732
+ */
2733
+ getBucket() {
2734
+ let context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
2735
+ if (context) {
2736
+ if (!context.pluginHookBucket) {
2737
+ context.pluginHookBucket = this.createEmptyBucket();
2738
+ }
2739
+ return context.pluginHookBucket;
2740
+ }
2741
+ return this.globalBucket;
2742
+ }
2743
+
2744
+ /**
2745
+ * Adds a listener (globally or locally) to a specified hook name.
2746
+ * If the `context` parameter is provided, the hook will be added only to the instance it references.
2747
+ * Otherwise, the callback will be used everytime the hook fires on any Handsontable instance.
2748
+ * You can provide an array of callback functions as the `callback` argument, this way they will all be fired
2749
+ * once the hook is triggered.
2750
+ *
2751
+ * @see Core#addHook
2752
+ * @param {string} key Hook name.
2753
+ * @param {Function|Array} callback Callback function or an array of functions.
2754
+ * @param {object} [context=null] The context for the hook callback to be added - a Handsontable instance or leave empty.
2755
+ * @param {number} [orderIndex] Order index of the callback.
2756
+ * If > 0, the callback will be added after the others, for example, with an index of 1, the callback will be added before the ones with an index of 2, 3, etc., but after the ones with an index of 0 and lower.
2757
+ * If < 0, the callback will be added before the others, for example, with an index of -1, the callback will be added after the ones with an index of -2, -3, etc., but before the ones with an index of 0 and higher.
2758
+ * If 0 or no order index is provided, the callback will be added between the "negative" and "positive" indexes.
2759
+ * @returns {Hooks} Instance of Hooks.
2760
+ *
2761
+ * @example
2762
+ * ```js
2763
+ * // single callback, added locally
2764
+ * Handsontable.hooks.add('beforeInit', myCallback, hotInstance);
2765
+ *
2766
+ * // single callback, added globally
2767
+ * Handsontable.hooks.add('beforeInit', myCallback);
2768
+ *
2769
+ * // multiple callbacks, added locally
2770
+ * Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback], hotInstance);
2771
+ *
2772
+ * // multiple callbacks, added globally
2773
+ * Handsontable.hooks.add('beforeInit', [myCallback, anotherCallback]);
2774
+ * ```
2775
+ */
2776
+ add(key, callback) {
2777
+ let context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2778
+ let orderIndex = arguments.length > 3 ? arguments[3] : undefined;
2779
+ if (Array.isArray(callback)) {
2780
+ (0, _array.arrayEach)(callback, c => this.add(key, c, context));
2781
+ } else {
2782
+ if (REMOVED_HOOKS.has(key)) {
2783
+ (0, _console.warn)((0, _string.substitute)(REMOVED_MESSAGE, {
2784
+ hookName: key,
2785
+ removedInVersion: REMOVED_HOOKS.get(key)
2786
+ }));
2787
+ }
2788
+ if (DEPRECATED_HOOKS.has(key)) {
2789
+ (0, _console.warn)(DEPRECATED_HOOKS.get(key));
2790
+ }
2791
+ const bucket = this.getBucket(context);
2792
+ if (typeof bucket[key] === 'undefined') {
2793
+ this.register(key);
2794
+ bucket[key] = [];
2795
+ this.initOrderMap(bucket, key);
2796
+ }
2797
+ callback.skip = false;
2798
+ if (bucket[key].indexOf(callback) === -1) {
2799
+ // only add a hook if it has not already been added (adding the same hook twice is now silently ignored)
2800
+ let foundInitialHook = false;
2801
+ if (callback.initialHook) {
2802
+ (0, _array.arrayEach)(bucket[key], (cb, i) => {
2803
+ if (cb.initialHook) {
2804
+ bucket[key][i] = callback;
2805
+ foundInitialHook = true;
2806
+ return false;
2807
+ }
2808
+ });
2809
+ }
2810
+ if (!foundInitialHook) {
2811
+ bucket[key].push(callback);
2812
+ }
2813
+ }
2814
+ this.setCallbackOrderIndex(bucket, key, callback, orderIndex);
2815
+ this.orderBucketByOrderIndex(bucket, key);
2816
+ }
2817
+ return this;
2818
+ }
2819
+
2820
+ /**
2821
+ * Adds a listener to a specified hook. After the hook runs this listener will be automatically removed from the bucket.
2822
+ *
2823
+ * @see Core#addHookOnce
2824
+ * @param {string} key Hook/Event name.
2825
+ * @param {Function|Array} callback Callback function.
2826
+ * @param {object} [context=null] A Handsontable instance.
2827
+ * @param {number} [orderIndex] Order index of the callback.
2828
+ * If > 0, the callback will be added after the others, for example, with an index of 1, the callback will be added before the ones with an index of 2, 3, etc., but after the ones with an index of 0 and lower.
2829
+ * If < 0, the callback will be added before the others, for example, with an index of -1, the callback will be added after the ones with an index of -2, -3, etc., but before the ones with an index of 0 and higher.
2830
+ * If 0 or no order index is provided, the callback will be added between the "negative" and "positive" indexes.
2831
+ *
2832
+ * @example
2833
+ * ```js
2834
+ * Handsontable.hooks.once('beforeInit', myCallback, hotInstance);
2835
+ * ```
2836
+ */
2837
+ once(key, callback) {
2838
+ let context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2839
+ let orderIndex = arguments.length > 3 ? arguments[3] : undefined;
2840
+ if (Array.isArray(callback)) {
2841
+ (0, _array.arrayEach)(callback, c => this.once(key, c, context));
2842
+ } else {
2843
+ callback.runOnce = true;
2844
+ this.add(key, callback, context, orderIndex);
2845
+ }
2846
+ }
2847
+
2848
+ /**
2849
+ * Removes a listener from a hook with a given name. If the `context` argument is provided, it removes a listener from a local hook assigned to the given Handsontable instance.
2850
+ *
2851
+ * @see Core#removeHook
2852
+ * @param {string} key Hook/Event name.
2853
+ * @param {Function} callback Callback function (needs the be the function that was previously added to the hook).
2854
+ * @param {object} [context=null] Handsontable instance.
2855
+ * @returns {boolean} Returns `true` if hook was removed, `false` otherwise.
2856
+ *
2857
+ * @example
2858
+ * ```js
2859
+ * Handsontable.hooks.remove('beforeInit', myCallback);
2860
+ * ```
2861
+ */
2862
+ remove(key, callback) {
2863
+ let context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
2864
+ const bucket = this.getBucket(context);
2865
+ if (typeof bucket[key] !== 'undefined') {
2866
+ if (bucket[key].indexOf(callback) >= 0) {
2867
+ callback.skip = true;
2868
+ return true;
2869
+ }
2870
+ }
2871
+ return false;
2872
+ }
2873
+
2874
+ /**
2875
+ * Checks whether there are any registered listeners for the provided hook name.
2876
+ * If the `context` parameter is provided, it only checks for listeners assigned to the given Handsontable instance.
2877
+ *
2878
+ * @param {string} key Hook name.
2879
+ * @param {object} [context=null] A Handsontable instance.
2880
+ * @returns {boolean} `true` for success, `false` otherwise.
2881
+ */
2882
+ has(key) {
2883
+ let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
2884
+ const bucket = this.getBucket(context);
2885
+ return !!(bucket[key] !== undefined && bucket[key].length);
2886
+ }
2887
+
2888
+ /**
2889
+ * Runs all local and global callbacks assigned to the hook identified by the `key` parameter.
2890
+ * It returns either a return value from the last called callback or the first parameter (`p1`) passed to the `run` function.
2891
+ *
2892
+ * @see Core#runHooks
2893
+ * @param {object} context Handsontable instance.
2894
+ * @param {string} key Hook/Event name.
2895
+ * @param {*} [p1] Parameter to be passed as an argument to the callback function.
2896
+ * @param {*} [p2] Parameter to be passed as an argument to the callback function.
2897
+ * @param {*} [p3] Parameter to be passed as an argument to the callback function.
2898
+ * @param {*} [p4] Parameter to be passed as an argument to the callback function.
2899
+ * @param {*} [p5] Parameter to be passed as an argument to the callback function.
2900
+ * @param {*} [p6] Parameter to be passed as an argument to the callback function.
2901
+ * @returns {*} Either a return value from the last called callback or `p1`.
2902
+ *
2903
+ * @example
2904
+ * ```js
2905
+ * Handsontable.hooks.run(hot, 'beforeInit');
2906
+ * ```
2907
+ */
2908
+ run(context, key, p1, p2, p3, p4, p5, p6) {
2909
+ {
2910
+ const globalHandlers = this.globalBucket[key];
2911
+ const length = globalHandlers ? globalHandlers.length : 0;
2912
+ let index = 0;
2913
+ if (length) {
2914
+ // Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
2915
+ while (index < length) {
2916
+ if (!globalHandlers[index] || globalHandlers[index].skip) {
2917
+ index += 1;
2918
+ /* eslint-disable no-continue */
2919
+ continue;
2920
+ }
2921
+ const res = (0, _function.fastCall)(globalHandlers[index], context, p1, p2, p3, p4, p5, p6);
2922
+ if (res !== undefined) {
2923
+ // eslint-disable-next-line no-param-reassign
2924
+ p1 = res;
2925
+ }
2926
+ if (globalHandlers[index] && globalHandlers[index].runOnce) {
2927
+ this.remove(key, globalHandlers[index]);
2928
+ }
2929
+ index += 1;
2930
+ }
2931
+ }
2932
+ }
2933
+ {
2934
+ const localHandlers = this.getBucket(context)[key];
2935
+ const length = localHandlers ? localHandlers.length : 0;
2936
+ let index = 0;
2937
+ if (length) {
2938
+ // Do not optimise this loop with arrayEach or arrow function! If you do You'll decrease perf because of GC.
2939
+ while (index < length) {
2940
+ if (!localHandlers[index] || localHandlers[index].skip) {
2941
+ index += 1;
2942
+ /* eslint-disable no-continue */
2943
+ continue;
2944
+ }
2945
+ const res = (0, _function.fastCall)(localHandlers[index], context, p1, p2, p3, p4, p5, p6);
2946
+ if (res !== undefined) {
2947
+ // eslint-disable-next-line no-param-reassign
2948
+ p1 = res;
2949
+ }
2950
+ if (localHandlers[index] && localHandlers[index].runOnce) {
2951
+ this.remove(key, localHandlers[index], context);
2952
+ }
2953
+ index += 1;
2954
+ }
2955
+ }
2956
+ }
2957
+ return p1;
2958
+ }
2959
+
2960
+ /**
2961
+ * Destroy all listeners connected to the context. If no context is provided, the global listeners will be destroyed.
2962
+ *
2963
+ * @param {object} [context=null] A Handsontable instance.
2964
+ * @example
2965
+ * ```js
2966
+ * // destroy the global listeners
2967
+ * Handsontable.hooks.destroy();
2968
+ *
2969
+ * // destroy the local listeners
2970
+ * Handsontable.hooks.destroy(hotInstance);
2971
+ * ```
2972
+ */
2973
+ destroy() {
2974
+ let context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
2975
+ // eslint-disable-next-line no-return-assign
2976
+ (0, _object.objectEach)(this.getBucket(context), (value, key, bucket) => bucket[key].length = 0);
2977
+ }
2978
+
2979
+ /**
2980
+ * Registers a hook name (adds it to the list of the known hook names). Used by plugins.
2981
+ * It is not necessary to call register, but if you use it, your plugin hook will be used returned by
2982
+ * the `getRegistered` method. (which itself is used in the [demo](@/guides/getting-started/events-and-hooks/events-and-hooks.md)).
2983
+ *
2984
+ * @param {string} key The hook name.
2985
+ *
2986
+ * @example
2987
+ * ```js
2988
+ * Handsontable.hooks.register('myHook');
2989
+ * ```
2990
+ */
2991
+ register(key) {
2992
+ if (!this.isRegistered(key)) {
2993
+ REGISTERED_HOOKS.push(key);
2994
+ }
2995
+ }
2996
+
2997
+ /**
2998
+ * Deregisters a hook name (removes it from the list of known hook names).
2999
+ *
3000
+ * @param {string} key The hook name.
3001
+ *
3002
+ * @example
3003
+ * ```js
3004
+ * Handsontable.hooks.deregister('myHook');
3005
+ * ```
3006
+ */
3007
+ deregister(key) {
3008
+ if (this.isRegistered(key)) {
3009
+ REGISTERED_HOOKS.splice(REGISTERED_HOOKS.indexOf(key), 1);
3010
+ }
3011
+ }
3012
+
3013
+ /**
3014
+ * Returns a boolean value depending on if a hook by such name has been removed or deprecated.
3015
+ *
3016
+ * @param {string} hookName The hook name to check.
3017
+ * @returns {boolean} Returns `true` if the provided hook name was marked as deprecated or
3018
+ * removed from API, `false` otherwise.
3019
+ * @example
3020
+ * ```js
3021
+ * Handsontable.hooks.isDeprecated('skipLengthCache');
3022
+ *
3023
+ * // Results:
3024
+ * true
3025
+ * ```
3026
+ */
3027
+ isDeprecated(hookName) {
3028
+ return DEPRECATED_HOOKS.has(hookName) || REMOVED_HOOKS.has(hookName);
3029
+ }
3030
+
3031
+ /**
3032
+ * Returns a boolean depending on if a hook by such name has been registered.
3033
+ *
3034
+ * @param {string} hookName The hook name to check.
3035
+ * @returns {boolean} `true` for success, `false` otherwise.
3036
+ * @example
3037
+ * ```js
3038
+ * Handsontable.hooks.isRegistered('beforeInit');
3039
+ *
3040
+ * // Results:
3041
+ * true
3042
+ * ```
3043
+ */
3044
+ isRegistered(hookName) {
3045
+ return REGISTERED_HOOKS.indexOf(hookName) >= 0;
3046
+ }
3047
+
3048
+ /**
3049
+ * Returns an array of registered hooks.
3050
+ *
3051
+ * @returns {Array} An array of registered hooks.
3052
+ *
3053
+ * @example
3054
+ * ```js
3055
+ * Handsontable.hooks.getRegistered();
3056
+ *
3057
+ * // Results:
3058
+ * [
3059
+ * ...
3060
+ * 'beforeInit',
3061
+ * 'beforeRender',
3062
+ * 'beforeSetRangeEnd',
3063
+ * 'beforeDrawBorders',
3064
+ * 'beforeChange',
3065
+ * ...
3066
+ * ]
3067
+ * ```
3068
+ */
3069
+ getRegistered() {
3070
+ return REGISTERED_HOOKS;
3071
+ }
3072
+
3073
+ /**
3074
+ * Sets the order index of the callback in the bucket object.
3075
+ *
3076
+ * @private
3077
+ * @param {object} bucket The bucket object.
3078
+ * @param {string} key Hook name.
3079
+ * @param {Function} callback Callback function.
3080
+ * @param {number|undefined} orderIndex Order index of the callback.
3081
+ */
3082
+ setCallbackOrderIndex(bucket, key, callback, orderIndex) {
3083
+ const normalizedOrderIndex = Number.isInteger(orderIndex) ? orderIndex : 0;
3084
+ const orderMap = this.getCallbackOrderMap(bucket, key);
3085
+ orderMap.set(normalizedOrderIndex, [...(orderMap.get(normalizedOrderIndex) || []), callback]);
3086
+ }
3087
+
3088
+ /**
3089
+ * Reorders the callbacks in the bucket object by their order index.
3090
+ *
3091
+ * @private
3092
+ * @param {objcet} bucket The bucket object.
3093
+ * @param {string} key Hook name.
3094
+ */
3095
+ orderBucketByOrderIndex(bucket, key) {
3096
+ const orderMap = this.getCallbackOrderMap(bucket, key);
3097
+ if (orderMap === undefined || orderMap.size === 0 || orderMap.size === 1 && orderMap.has(0)) {
3098
+ return;
3099
+ }
3100
+ bucket[key] = [...orderMap].sort((a, b) => a[0] - b[0]).flatMap(_ref => {
3101
+ let [, callbacks] = _ref;
3102
+ return callbacks;
3103
+ });
3104
+ }
3105
+
3106
+ /**
3107
+ * Extends the bucket object with the order property.
3108
+ *
3109
+ * @private
3110
+ * @param {object} bucket The bucket object.
3111
+ * @param {string} hook The hook name.
3112
+ */
3113
+ initOrderMap(bucket, hook) {
3114
+ if (!callbackOrder.has(bucket)) {
3115
+ callbackOrder.set(bucket, []);
3116
+ }
3117
+ callbackOrder.get(bucket)[hook] = new Map();
3118
+ }
3119
+
3120
+ /**
3121
+ * Returns the order map for the provided hook.
3122
+ *
3123
+ * @private
3124
+ * @param {object} bucket The bucket object.
3125
+ * @param {string} hook The hook name.
3126
+ * @returns {Map<number, Array<Function>>} Returns the order map for the provided hook.
3127
+ */
3128
+ getCallbackOrderMap(bucket, hook) {
3129
+ return callbackOrder.get(bucket)[hook];
3130
+ }
3131
+ }
3132
+ const globalSingleton = new Hooks();
3133
+
3134
+ /**
3135
+ * @returns {Hooks}
3136
+ */
3137
+ function getGlobalSingleton() {
3138
+ return globalSingleton;
3139
+ }
3140
+ var _default = exports.default = Hooks;