handsontable 0.0.0-next-e857cca-20230112 → 0.0.0-next-7385141-20230123

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.

package/helpers/mixed.js CHANGED
@@ -152,7 +152,7 @@ var domMessages = {
152
152
  function _injectProductInfo(key, element) {
153
153
  var hasValidType = !isEmpty(key);
154
154
  var isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
155
- var hotVersion = "0.0.0-next-e857cca-20230112";
155
+ var hotVersion = "0.0.0-next-7385141-20230123";
156
156
  var keyValidityDate;
157
157
  var consoleMessageState = 'invalid';
158
158
  var domMessageState = 'invalid';
package/helpers/mixed.mjs CHANGED
@@ -142,7 +142,7 @@ var domMessages = {
142
142
  export function _injectProductInfo(key, element) {
143
143
  var hasValidType = !isEmpty(key);
144
144
  var isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
145
- var hotVersion = "0.0.0-next-e857cca-20230112";
145
+ var hotVersion = "0.0.0-next-7385141-20230123";
146
146
  var keyValidityDate;
147
147
  var consoleMessageState = 'invalid';
148
148
  var domMessageState = 'invalid';
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-e857cca-20230112",
13
+ "version": "0.0.0-next-7385141-20230123",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
@@ -13,9 +13,7 @@ require("core-js/modules/es.symbol.description.js");
13
13
  require("core-js/modules/es.number.constructor.js");
14
14
  require("core-js/modules/es.symbol.iterator.js");
15
15
  require("core-js/modules/es.array.slice.js");
16
- require("core-js/modules/es.function.name.js");
17
16
  require("core-js/modules/es.array.from.js");
18
- require("core-js/modules/es.regexp.exec.js");
19
17
  exports.__esModule = true;
20
18
  exports.PLUGIN_PRIORITY = exports.PLUGIN_KEY = exports.MergeCells = void 0;
21
19
  require("core-js/modules/es.array.iterator.js");
@@ -25,6 +23,13 @@ require("core-js/modules/es.weak-map.js");
25
23
  require("core-js/modules/web.dom-collections.iterator.js");
26
24
  require("core-js/modules/es.array.includes.js");
27
25
  require("core-js/modules/es.string.includes.js");
26
+ require("core-js/modules/es.weak-set.js");
27
+ require("core-js/modules/web.dom-collections.for-each.js");
28
+ require("core-js/modules/es.set.js");
29
+ require("core-js/modules/es.array.map.js");
30
+ require("core-js/modules/es.function.name.js");
31
+ require("core-js/modules/es.regexp.exec.js");
32
+ require("core-js/modules/es.string.replace.js");
28
33
  var _base = require("../base");
29
34
  var _pluginHooks = _interopRequireDefault(require("../../pluginHooks"));
30
35
  var _cellsCollection = _interopRequireDefault(require("./cellsCollection"));
@@ -37,7 +42,13 @@ var _object = require("../../helpers/object");
37
42
  var _console = require("../../helpers/console");
38
43
  var _number = require("../../helpers/number");
39
44
  var _utils = require("./utils");
45
+ var _element = require("../../helpers/dom/element");
46
+ var _browser = require("../../helpers/browser");
40
47
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
48
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
49
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
50
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
51
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
41
52
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
42
53
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
43
54
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -58,6 +69,9 @@ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) ===
58
69
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
59
70
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
60
71
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
72
+ function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
73
+ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
74
+ function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
61
75
  _pluginHooks.default.getSingleton().register('beforeMergeCells');
62
76
  _pluginHooks.default.getSingleton().register('afterMergeCells');
63
77
  _pluginHooks.default.getSingleton().register('beforeUnmergeCells');
@@ -106,6 +120,7 @@ var SHORTCUTS_GROUP = PLUGIN_KEY;
106
120
  * ```
107
121
  * :::
108
122
  */
123
+ var _ifChromeForceRepaint = /*#__PURE__*/new WeakSet();
109
124
  var MergeCells = /*#__PURE__*/function (_BasePlugin) {
110
125
  _inherits(MergeCells, _BasePlugin);
111
126
  var _super = _createSuper(MergeCells);
@@ -113,6 +128,7 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
113
128
  var _this;
114
129
  _classCallCheck(this, MergeCells);
115
130
  _this = _super.call(this, hotInstance);
131
+ _classPrivateMethodInitSpec(_assertThisInitialized(_this), _ifChromeForceRepaint);
116
132
  privatePool.set(_assertThisInitialized(_this), {
117
133
  lastDesiredCoords: null
118
134
  });
@@ -259,7 +275,8 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
259
275
  /**
260
276
  * Updates the plugin's state.
261
277
  *
262
- * This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the following configuration options:
278
+ * This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the
279
+ * following configuration options:
263
280
  * - [`mergeCells`](@/api/options.md#mergecells)
264
281
  */
265
282
  }, {
@@ -272,6 +289,16 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
272
289
  _get(_getPrototypeOf(MergeCells.prototype), "updatePlugin", this).call(this);
273
290
  }
274
291
 
292
+ /**
293
+ * If the browser is recognized as Chrome, force an additional repaint to prevent showing the effects of a Chrome bug.
294
+ *
295
+ * Issue described in https://github.com/handsontable/dev-handsontable/issues/521.
296
+ *
297
+ * @private
298
+ */
299
+ }, {
300
+ key: "validateSetting",
301
+ value:
275
302
  /**
276
303
  * Validates a single setting object, represented by a single merged cell information object.
277
304
  *
@@ -279,9 +306,7 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
279
306
  * @param {object} setting An object with `row`, `col`, `rowspan` and `colspan` properties.
280
307
  * @returns {boolean}
281
308
  */
282
- }, {
283
- key: "validateSetting",
284
- value: function validateSetting(setting) {
309
+ function validateSetting(setting) {
285
310
  var valid = true;
286
311
  if (!setting) {
287
312
  return false;
@@ -429,8 +454,10 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
429
454
  * @private
430
455
  * @param {CellRange} cellRange Cell range to merge.
431
456
  * @param {boolean} [auto=false] `true` if is called automatically, e.g. At initialization.
432
- * @param {boolean} [preventPopulation=false] `true`, if the method should not run `populateFromArray` at the end, but rather return its arguments.
433
- * @returns {Array|boolean} Returns an array of [row, column, dataUnderCollection] if preventPopulation is set to true. If the the merging process went successful, it returns `true`, otherwise - `false`.
457
+ * @param {boolean} [preventPopulation=false] `true`, if the method should not run `populateFromArray` at the end,
458
+ * but rather return its arguments.
459
+ * @returns {Array|boolean} Returns an array of [row, column, dataUnderCollection] if preventPopulation is set to
460
+ * true. If the the merging process went successful, it returns `true`, otherwise - `false`.
434
461
  * @fires Hooks#beforeMergeCells
435
462
  * @fires Hooks#afterMergeCells
436
463
  */
@@ -476,6 +503,9 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
476
503
  } else {
477
504
  this.hot.populateFromArray(mergeParent.row, mergeParent.col, clearedData, void 0, void 0, this.pluginName);
478
505
  }
506
+ if (!auto) {
507
+ _classPrivateMethodGet(this, _ifChromeForceRepaint, _ifChromeForceRepaint2).call(this);
508
+ }
479
509
  this.hot.runHooks('afterMergeCells', cellRange, mergeParent, auto);
480
510
  return populationInfo;
481
511
  }
@@ -620,7 +650,8 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
620
650
  }
621
651
 
622
652
  /**
623
- * Modifies the information on whether the current selection contains multiple cells. The `afterIsMultipleSelection` hook callback.
653
+ * Modifies the information on whether the current selection contains multiple cells. The `afterIsMultipleSelection`
654
+ * hook callback.
624
655
  *
625
656
  * @private
626
657
  * @param {boolean} isMultiple Determines whether the current selection contains multiple cells.
@@ -844,7 +875,8 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
844
875
 
845
876
  /**
846
877
  * `beforeSetRangeEnd` hook callback.
847
- * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell.
878
+ * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the
879
+ * merged cell.
848
880
  *
849
881
  * Note: Please keep in mind that callback may modify both start and end range coordinates by the reference.
850
882
  *
@@ -1216,13 +1248,15 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1216
1248
  }
1217
1249
 
1218
1250
  /**
1219
- * `afterModifyTransformStart` hook callback. Fixes a problem with navigating through merged cells at the edges of the table
1220
- * with the ENTER/SHIFT+ENTER/TAB/SHIFT+TAB keys.
1251
+ * `afterModifyTransformStart` hook callback. Fixes a problem with navigating through merged cells at the edges of
1252
+ * the table with the ENTER/SHIFT+ENTER/TAB/SHIFT+TAB keys.
1221
1253
  *
1222
1254
  * @private
1223
1255
  * @param {CellCoords} coords Coordinates of the to-be-selected cell.
1224
- * @param {number} rowTransformDir Row transformation direction (negative value = up, 0 = none, positive value = down).
1225
- * @param {number} colTransformDir Column transformation direction (negative value = up, 0 = none, positive value = down).
1256
+ * @param {number} rowTransformDir Row transformation direction (negative value = up, 0 = none, positive value =
1257
+ * down).
1258
+ * @param {number} colTransformDir Column transformation direction (negative value = up, 0 = none, positive value =
1259
+ * down).
1226
1260
  */
1227
1261
  }, {
1228
1262
  key: "onAfterModifyTransformStart",
@@ -1254,9 +1288,11 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1254
1288
  * @private
1255
1289
  * @param {number} currentRow Visual row index of the currently processed cell.
1256
1290
  * @param {number} currentColumn Visual column index of the currently cell.
1257
- * @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
1291
+ * @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow,
1292
+ * endColumn]`.
1258
1293
  * @param {number|undefined} layerLevel Number indicating which layer of selection is currently processed.
1259
- * @returns {string|undefined} A `String`, which will act as an additional `className` to be added to the currently processed cell.
1294
+ * @returns {string|undefined} A `String`, which will act as an additional `className` to be added to the currently
1295
+ * processed cell.
1260
1296
  */
1261
1297
  }, {
1262
1298
  key: "onAfterDrawSelection",
@@ -1272,7 +1308,8 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1272
1308
  * `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
1273
1309
  *
1274
1310
  * @private
1275
- * @returns {string[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
1311
+ * @returns {string[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from
1312
+ * all the cells in the table.
1276
1313
  */
1277
1314
  }, {
1278
1315
  key: "onBeforeRemoveCellClassNames",
@@ -1292,4 +1329,44 @@ var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1292
1329
  }]);
1293
1330
  return MergeCells;
1294
1331
  }(_base.BasePlugin);
1295
- exports.MergeCells = MergeCells;
1332
+ exports.MergeCells = MergeCells;
1333
+ function _ifChromeForceRepaint2() {
1334
+ var _this8 = this;
1335
+ if (!(0, _browser.isChrome)()) {
1336
+ return;
1337
+ }
1338
+ var rowsToRefresh = [];
1339
+ var rowIndexesToRefresh = [];
1340
+ this.mergedCellsCollection.mergedCells.forEach(function (mergedCell) {
1341
+ var row = mergedCell.row,
1342
+ rowspan = mergedCell.rowspan;
1343
+ for (var r = row + 1; r < row + rowspan; r++) {
1344
+ rowIndexesToRefresh.push(r);
1345
+ }
1346
+ });
1347
+
1348
+ // Remove duplicates
1349
+ rowIndexesToRefresh = _toConsumableArray(new Set(rowIndexesToRefresh));
1350
+ rowIndexesToRefresh.forEach(function (rowIndex) {
1351
+ var renderableRowIndex = _this8.hot.rowIndexMapper.getRenderableFromVisualIndex(rowIndex);
1352
+ _this8.hot.view._wt.wtOverlays.getOverlays(true).map(function (overlay) {
1353
+ return (overlay === null || overlay === void 0 ? void 0 : overlay.name) === 'master' ? overlay : overlay.clone.wtTable;
1354
+ }).forEach(function (wtTableRef) {
1355
+ var rowToRefresh = wtTableRef.getRow(renderableRowIndex);
1356
+ if (rowToRefresh) {
1357
+ // Modify the TR's `background` property to later modify it asynchronously.
1358
+ // The background color is getting modified only with the alpha, so the change should not be visible (and is
1359
+ // covered by the TDs' background color).
1360
+ rowToRefresh.style.background = (0, _element.getStyle)(rowToRefresh, 'backgroundColor').replace(')', ', 0.99)');
1361
+ rowsToRefresh.push(rowToRefresh);
1362
+ }
1363
+ });
1364
+ });
1365
+
1366
+ // Asynchronously revert the TRs' `background` property to force a fresh repaint.
1367
+ this.hot._registerTimeout(function () {
1368
+ rowsToRefresh.forEach(function (rowElement) {
1369
+ rowElement.style.background = (0, _element.getStyle)(rowElement, 'backgroundColor').replace(', 0.99)', ')');
1370
+ });
1371
+ }, 1);
1372
+ }
@@ -1,4 +1,8 @@
1
1
  function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
2
6
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
7
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
8
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -19,6 +23,9 @@ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) ===
19
23
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
20
24
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
21
25
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
26
+ function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
27
+ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
28
+ function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
22
29
  import "core-js/modules/es.array.iterator.js";
23
30
  import "core-js/modules/es.object.to-string.js";
24
31
  import "core-js/modules/es.string.iterator.js";
@@ -26,6 +33,13 @@ import "core-js/modules/es.weak-map.js";
26
33
  import "core-js/modules/web.dom-collections.iterator.js";
27
34
  import "core-js/modules/es.array.includes.js";
28
35
  import "core-js/modules/es.string.includes.js";
36
+ import "core-js/modules/es.weak-set.js";
37
+ import "core-js/modules/web.dom-collections.for-each.js";
38
+ import "core-js/modules/es.set.js";
39
+ import "core-js/modules/es.array.map.js";
40
+ import "core-js/modules/es.function.name.js";
41
+ import "core-js/modules/es.regexp.exec.js";
42
+ import "core-js/modules/es.string.replace.js";
29
43
  import "core-js/modules/es.object.set-prototype-of.js";
30
44
  import "core-js/modules/es.object.get-prototype-of.js";
31
45
  import "core-js/modules/es.reflect.construct.js";
@@ -38,9 +52,7 @@ import "core-js/modules/es.symbol.description.js";
38
52
  import "core-js/modules/es.number.constructor.js";
39
53
  import "core-js/modules/es.symbol.iterator.js";
40
54
  import "core-js/modules/es.array.slice.js";
41
- import "core-js/modules/es.function.name.js";
42
55
  import "core-js/modules/es.array.from.js";
43
- import "core-js/modules/es.regexp.exec.js";
44
56
  import { BasePlugin } from "../base/index.mjs";
45
57
  import Hooks from "../../pluginHooks.mjs";
46
58
  import MergedCellsCollection from "./cellsCollection.mjs";
@@ -53,6 +65,8 @@ import { isObject, clone } from "../../helpers/object.mjs";
53
65
  import { warn } from "../../helpers/console.mjs";
54
66
  import { rangeEach } from "../../helpers/number.mjs";
55
67
  import { applySpanProperties } from "./utils.mjs";
68
+ import { getStyle } from "../../helpers/dom/element.mjs";
69
+ import { isChrome } from "../../helpers/browser.mjs";
56
70
  Hooks.getSingleton().register('beforeMergeCells');
57
71
  Hooks.getSingleton().register('afterMergeCells');
58
72
  Hooks.getSingleton().register('beforeUnmergeCells');
@@ -99,6 +113,7 @@ var SHORTCUTS_GROUP = PLUGIN_KEY;
99
113
  * ```
100
114
  * :::
101
115
  */
116
+ var _ifChromeForceRepaint = /*#__PURE__*/new WeakSet();
102
117
  export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
103
118
  _inherits(MergeCells, _BasePlugin);
104
119
  var _super = _createSuper(MergeCells);
@@ -106,6 +121,7 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
106
121
  var _this;
107
122
  _classCallCheck(this, MergeCells);
108
123
  _this = _super.call(this, hotInstance);
124
+ _classPrivateMethodInitSpec(_assertThisInitialized(_this), _ifChromeForceRepaint);
109
125
  privatePool.set(_assertThisInitialized(_this), {
110
126
  lastDesiredCoords: null
111
127
  });
@@ -252,7 +268,8 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
252
268
  /**
253
269
  * Updates the plugin's state.
254
270
  *
255
- * This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the following configuration options:
271
+ * This method is executed when [`updateSettings()`](@/api/core.md#updatesettings) is invoked with any of the
272
+ * following configuration options:
256
273
  * - [`mergeCells`](@/api/options.md#mergecells)
257
274
  */
258
275
  }, {
@@ -265,6 +282,16 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
265
282
  _get(_getPrototypeOf(MergeCells.prototype), "updatePlugin", this).call(this);
266
283
  }
267
284
 
285
+ /**
286
+ * If the browser is recognized as Chrome, force an additional repaint to prevent showing the effects of a Chrome bug.
287
+ *
288
+ * Issue described in https://github.com/handsontable/dev-handsontable/issues/521.
289
+ *
290
+ * @private
291
+ */
292
+ }, {
293
+ key: "validateSetting",
294
+ value:
268
295
  /**
269
296
  * Validates a single setting object, represented by a single merged cell information object.
270
297
  *
@@ -272,9 +299,7 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
272
299
  * @param {object} setting An object with `row`, `col`, `rowspan` and `colspan` properties.
273
300
  * @returns {boolean}
274
301
  */
275
- }, {
276
- key: "validateSetting",
277
- value: function validateSetting(setting) {
302
+ function validateSetting(setting) {
278
303
  var valid = true;
279
304
  if (!setting) {
280
305
  return false;
@@ -422,8 +447,10 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
422
447
  * @private
423
448
  * @param {CellRange} cellRange Cell range to merge.
424
449
  * @param {boolean} [auto=false] `true` if is called automatically, e.g. At initialization.
425
- * @param {boolean} [preventPopulation=false] `true`, if the method should not run `populateFromArray` at the end, but rather return its arguments.
426
- * @returns {Array|boolean} Returns an array of [row, column, dataUnderCollection] if preventPopulation is set to true. If the the merging process went successful, it returns `true`, otherwise - `false`.
450
+ * @param {boolean} [preventPopulation=false] `true`, if the method should not run `populateFromArray` at the end,
451
+ * but rather return its arguments.
452
+ * @returns {Array|boolean} Returns an array of [row, column, dataUnderCollection] if preventPopulation is set to
453
+ * true. If the the merging process went successful, it returns `true`, otherwise - `false`.
427
454
  * @fires Hooks#beforeMergeCells
428
455
  * @fires Hooks#afterMergeCells
429
456
  */
@@ -469,6 +496,9 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
469
496
  } else {
470
497
  this.hot.populateFromArray(mergeParent.row, mergeParent.col, clearedData, void 0, void 0, this.pluginName);
471
498
  }
499
+ if (!auto) {
500
+ _classPrivateMethodGet(this, _ifChromeForceRepaint, _ifChromeForceRepaint2).call(this);
501
+ }
472
502
  this.hot.runHooks('afterMergeCells', cellRange, mergeParent, auto);
473
503
  return populationInfo;
474
504
  }
@@ -613,7 +643,8 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
613
643
  }
614
644
 
615
645
  /**
616
- * Modifies the information on whether the current selection contains multiple cells. The `afterIsMultipleSelection` hook callback.
646
+ * Modifies the information on whether the current selection contains multiple cells. The `afterIsMultipleSelection`
647
+ * hook callback.
617
648
  *
618
649
  * @private
619
650
  * @param {boolean} isMultiple Determines whether the current selection contains multiple cells.
@@ -837,7 +868,8 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
837
868
 
838
869
  /**
839
870
  * `beforeSetRangeEnd` hook callback.
840
- * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the merged cell.
871
+ * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the
872
+ * merged cell.
841
873
  *
842
874
  * Note: Please keep in mind that callback may modify both start and end range coordinates by the reference.
843
875
  *
@@ -1209,13 +1241,15 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1209
1241
  }
1210
1242
 
1211
1243
  /**
1212
- * `afterModifyTransformStart` hook callback. Fixes a problem with navigating through merged cells at the edges of the table
1213
- * with the ENTER/SHIFT+ENTER/TAB/SHIFT+TAB keys.
1244
+ * `afterModifyTransformStart` hook callback. Fixes a problem with navigating through merged cells at the edges of
1245
+ * the table with the ENTER/SHIFT+ENTER/TAB/SHIFT+TAB keys.
1214
1246
  *
1215
1247
  * @private
1216
1248
  * @param {CellCoords} coords Coordinates of the to-be-selected cell.
1217
- * @param {number} rowTransformDir Row transformation direction (negative value = up, 0 = none, positive value = down).
1218
- * @param {number} colTransformDir Column transformation direction (negative value = up, 0 = none, positive value = down).
1249
+ * @param {number} rowTransformDir Row transformation direction (negative value = up, 0 = none, positive value =
1250
+ * down).
1251
+ * @param {number} colTransformDir Column transformation direction (negative value = up, 0 = none, positive value =
1252
+ * down).
1219
1253
  */
1220
1254
  }, {
1221
1255
  key: "onAfterModifyTransformStart",
@@ -1247,9 +1281,11 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1247
1281
  * @private
1248
1282
  * @param {number} currentRow Visual row index of the currently processed cell.
1249
1283
  * @param {number} currentColumn Visual column index of the currently cell.
1250
- * @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow, endColumn]`.
1284
+ * @param {Array} cornersOfSelection Array of the current selection in a form of `[startRow, startColumn, endRow,
1285
+ * endColumn]`.
1251
1286
  * @param {number|undefined} layerLevel Number indicating which layer of selection is currently processed.
1252
- * @returns {string|undefined} A `String`, which will act as an additional `className` to be added to the currently processed cell.
1287
+ * @returns {string|undefined} A `String`, which will act as an additional `className` to be added to the currently
1288
+ * processed cell.
1253
1289
  */
1254
1290
  }, {
1255
1291
  key: "onAfterDrawSelection",
@@ -1265,7 +1301,8 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1265
1301
  * `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
1266
1302
  *
1267
1303
  * @private
1268
- * @returns {string[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
1304
+ * @returns {string[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from
1305
+ * all the cells in the table.
1269
1306
  */
1270
1307
  }, {
1271
1308
  key: "onBeforeRemoveCellClassNames",
@@ -1284,4 +1321,44 @@ export var MergeCells = /*#__PURE__*/function (_BasePlugin) {
1284
1321
  }
1285
1322
  }]);
1286
1323
  return MergeCells;
1287
- }(BasePlugin);
1324
+ }(BasePlugin);
1325
+ function _ifChromeForceRepaint2() {
1326
+ var _this8 = this;
1327
+ if (!isChrome()) {
1328
+ return;
1329
+ }
1330
+ var rowsToRefresh = [];
1331
+ var rowIndexesToRefresh = [];
1332
+ this.mergedCellsCollection.mergedCells.forEach(function (mergedCell) {
1333
+ var row = mergedCell.row,
1334
+ rowspan = mergedCell.rowspan;
1335
+ for (var r = row + 1; r < row + rowspan; r++) {
1336
+ rowIndexesToRefresh.push(r);
1337
+ }
1338
+ });
1339
+
1340
+ // Remove duplicates
1341
+ rowIndexesToRefresh = _toConsumableArray(new Set(rowIndexesToRefresh));
1342
+ rowIndexesToRefresh.forEach(function (rowIndex) {
1343
+ var renderableRowIndex = _this8.hot.rowIndexMapper.getRenderableFromVisualIndex(rowIndex);
1344
+ _this8.hot.view._wt.wtOverlays.getOverlays(true).map(function (overlay) {
1345
+ return (overlay === null || overlay === void 0 ? void 0 : overlay.name) === 'master' ? overlay : overlay.clone.wtTable;
1346
+ }).forEach(function (wtTableRef) {
1347
+ var rowToRefresh = wtTableRef.getRow(renderableRowIndex);
1348
+ if (rowToRefresh) {
1349
+ // Modify the TR's `background` property to later modify it asynchronously.
1350
+ // The background color is getting modified only with the alpha, so the change should not be visible (and is
1351
+ // covered by the TDs' background color).
1352
+ rowToRefresh.style.background = getStyle(rowToRefresh, 'backgroundColor').replace(')', ', 0.99)');
1353
+ rowsToRefresh.push(rowToRefresh);
1354
+ }
1355
+ });
1356
+ });
1357
+
1358
+ // Asynchronously revert the TRs' `background` property to force a fresh repaint.
1359
+ this.hot._registerTimeout(function () {
1360
+ rowsToRefresh.forEach(function (rowElement) {
1361
+ rowElement.style.background = getStyle(rowElement, 'backgroundColor').replace(', 0.99)', ')');
1362
+ });
1363
+ }, 1);
1364
+ }
@@ -151,6 +151,15 @@ var createShortcutManager = function createShortcutManager(_ref) {
151
151
  isCtrlPressed: function isCtrlPressed() {
152
152
  return !isCtrlKeySilenced && (keyRecorder.isPressed('control') || keyRecorder.isPressed('meta'));
153
153
  },
154
+ /**
155
+ * Release every previously pressed key.
156
+ *
157
+ * @type {Function}
158
+ * @memberof ShortcutManager#
159
+ */
160
+ releasePressedKeys: function releasePressedKeys() {
161
+ return keyRecorder.releasePressedKeys();
162
+ },
154
163
  /**
155
164
  * Destroy a context manager instance.
156
165
  *
@@ -146,6 +146,15 @@ export var createShortcutManager = function createShortcutManager(_ref) {
146
146
  isCtrlPressed: function isCtrlPressed() {
147
147
  return !isCtrlKeySilenced && (keyRecorder.isPressed('control') || keyRecorder.isPressed('meta'));
148
148
  },
149
+ /**
150
+ * Release every previously pressed key.
151
+ *
152
+ * @type {Function}
153
+ * @memberof ShortcutManager#
154
+ */
155
+ releasePressedKeys: function releasePressedKeys() {
156
+ return keyRecorder.releasePressedKeys();
157
+ },
149
158
  /**
150
159
  * Destroy a context manager instance.
151
160
  *
@@ -160,6 +160,9 @@ function useRecorder(ownerWindow, handleEvent, beforeKeyDown, afterKeyDown, call
160
160
  unmount: unmount,
161
161
  isPressed: function isPressed(key) {
162
162
  return modifierKeysObserver.isPressed(key);
163
+ },
164
+ releasePressedKeys: function releasePressedKeys() {
165
+ return modifierKeysObserver.releaseAll();
163
166
  }
164
167
  };
165
168
  }
@@ -156,6 +156,9 @@ export function useRecorder(ownerWindow, handleEvent, beforeKeyDown, afterKeyDow
156
156
  unmount: unmount,
157
157
  isPressed: function isPressed(key) {
158
158
  return modifierKeysObserver.isPressed(key);
159
+ },
160
+ releasePressedKeys: function releasePressedKeys() {
161
+ return modifierKeysObserver.releaseAll();
159
162
  }
160
163
  };
161
164
  }