handsontable 0.0.0-next-542a54e-20250121 → 0.0.0-next-8d1d868-20250121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of handsontable might be problematic. Click here for more details.
- package/3rdparty/walkontable/src/core/_base.js +19 -0
- package/3rdparty/walkontable/src/core/_base.mjs +19 -0
- package/3rdparty/walkontable/src/overlay/_base.js +44 -8
- package/3rdparty/walkontable/src/overlay/_base.mjs +44 -8
- package/3rdparty/walkontable/src/overlay/bottom.js +0 -1
- package/3rdparty/walkontable/src/overlay/bottom.mjs +0 -1
- package/3rdparty/walkontable/src/overlay/bottomInlineStartCorner.js +0 -1
- package/3rdparty/walkontable/src/overlay/bottomInlineStartCorner.mjs +0 -1
- package/3rdparty/walkontable/src/overlay/inlineStart.js +0 -1
- package/3rdparty/walkontable/src/overlay/inlineStart.mjs +0 -1
- package/3rdparty/walkontable/src/overlay/top.js +0 -1
- package/3rdparty/walkontable/src/overlay/top.mjs +0 -1
- package/3rdparty/walkontable/src/overlay/topInlineStartCorner.js +0 -1
- package/3rdparty/walkontable/src/overlay/topInlineStartCorner.mjs +0 -1
- package/3rdparty/walkontable/src/overlays.js +355 -45
- package/3rdparty/walkontable/src/overlays.mjs +355 -45
- package/3rdparty/walkontable/src/table.js +94 -99
- package/3rdparty/walkontable/src/table.mjs +94 -99
- package/base.js +2 -2
- package/base.mjs +2 -2
- package/dist/handsontable.css +20 -4
- package/dist/handsontable.full.css +20 -4
- package/dist/handsontable.full.js +522 -166
- package/dist/handsontable.full.min.css +3 -3
- package/dist/handsontable.full.min.js +108 -108
- package/dist/handsontable.js +522 -166
- package/dist/handsontable.min.css +3 -3
- package/dist/handsontable.min.js +15 -15
- package/editors/baseEditor/baseEditor.js +2 -1
- package/editors/baseEditor/baseEditor.mjs +2 -1
- package/helpers/mixed.js +1 -1
- package/helpers/mixed.mjs +1 -1
- package/package.json +1 -1
- package/plugins/dragToScroll/dragToScroll.js +1 -1
- package/plugins/dragToScroll/dragToScroll.mjs +1 -1
- package/styles/handsontable.css +7 -2
- package/styles/handsontable.min.css +3 -3
- package/styles/ht-theme-horizon.css +2 -2
- package/styles/ht-theme-horizon.min.css +2 -2
- package/styles/ht-theme-main.css +2 -2
- package/styles/ht-theme-main.min.css +2 -2
- package/tableView.js +2 -2
- package/tableView.mjs +2 -2
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import "core-js/modules/es.error.cause.js";
|
|
2
2
|
import "core-js/modules/es.array.push.js";
|
|
3
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
4
|
+
import "core-js/modules/esnext.iterator.for-each.js";
|
|
5
|
+
import "core-js/modules/esnext.iterator.reduce.js";
|
|
3
6
|
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
|
|
4
7
|
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
5
8
|
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; }
|
|
@@ -19,6 +22,7 @@ import { InlineStartOverlay, TopOverlay, TopInlineStartCornerOverlay, BottomOver
|
|
|
19
22
|
* @class Overlays
|
|
20
23
|
*/
|
|
21
24
|
var _overlays = /*#__PURE__*/new WeakMap();
|
|
25
|
+
var _hasRenderingStateChanged = /*#__PURE__*/new WeakMap();
|
|
22
26
|
var _containerDomResizeCount = /*#__PURE__*/new WeakMap();
|
|
23
27
|
var _containerDomResizeCountTimeout = /*#__PURE__*/new WeakMap();
|
|
24
28
|
class Overlays {
|
|
@@ -93,6 +97,12 @@ class Overlays {
|
|
|
93
97
|
* @type {Settings}
|
|
94
98
|
*/
|
|
95
99
|
_defineProperty(this, "wtSettings", null);
|
|
100
|
+
/**
|
|
101
|
+
* Indicates whether the rendering state has changed for one of the overlays.
|
|
102
|
+
*
|
|
103
|
+
* @type {boolean}
|
|
104
|
+
*/
|
|
105
|
+
_classPrivateFieldInitSpec(this, _hasRenderingStateChanged, false);
|
|
96
106
|
/**
|
|
97
107
|
* The amount of times the ResizeObserver callback was fired in direct succession.
|
|
98
108
|
*
|
|
@@ -139,16 +149,32 @@ class Overlays {
|
|
|
139
149
|
this.domBindings = domBindings;
|
|
140
150
|
this.facadeGetter = facadeGetter;
|
|
141
151
|
this.wtTable = wtTable;
|
|
142
|
-
this.eventManager = eventManager;
|
|
143
|
-
this.destroyed = false;
|
|
144
152
|
const {
|
|
153
|
+
rootDocument,
|
|
145
154
|
rootWindow
|
|
146
155
|
} = this.domBindings;
|
|
156
|
+
|
|
157
|
+
// legacy support
|
|
158
|
+
this.instance = this.wot; // todo refactoring: move to facade
|
|
159
|
+
this.eventManager = eventManager;
|
|
160
|
+
|
|
161
|
+
// TODO refactoring: probably invalid place to this logic
|
|
162
|
+
this.scrollbarSize = getScrollbarWidth(rootDocument);
|
|
147
163
|
const isOverflowHidden = rootWindow.getComputedStyle(wtTable.wtRootElement.parentNode).getPropertyValue('overflow') === 'hidden';
|
|
148
164
|
this.scrollableElement = isOverflowHidden ? wtTable.holder : getScrollableElement(wtTable.TABLE);
|
|
149
165
|
this.initOverlays();
|
|
166
|
+
this.destroyed = false;
|
|
167
|
+
this.keyPressed = false;
|
|
168
|
+
this.spreaderLastSize = {
|
|
169
|
+
width: null,
|
|
170
|
+
height: null
|
|
171
|
+
};
|
|
172
|
+
this.verticalScrolling = false;
|
|
173
|
+
this.horizontalScrolling = false;
|
|
150
174
|
this.initBrowserLineHeight();
|
|
151
175
|
this.registerListeners();
|
|
176
|
+
this.lastScrollX = rootWindow.scrollX;
|
|
177
|
+
this.lastScrollY = rootWindow.scrollY;
|
|
152
178
|
}
|
|
153
179
|
|
|
154
180
|
/**
|
|
@@ -183,8 +209,8 @@ class Overlays {
|
|
|
183
209
|
* Https://developer.mozilla.org/pl/docs/Web/CSS/line-height#Values.
|
|
184
210
|
*/
|
|
185
211
|
const lineHeight = parseInt(computedStyle.lineHeight, 10);
|
|
186
|
-
const
|
|
187
|
-
this.browserLineHeight = lineHeight ||
|
|
212
|
+
const lineHeightFalback = parseInt(computedStyle.fontSize, 10) * 1.2;
|
|
213
|
+
this.browserLineHeight = lineHeight || lineHeightFalback;
|
|
188
214
|
}
|
|
189
215
|
|
|
190
216
|
/**
|
|
@@ -194,9 +220,15 @@ class Overlays {
|
|
|
194
220
|
*/
|
|
195
221
|
initOverlays() {
|
|
196
222
|
const args = [this.wot, this.facadeGetter, this.wtSettings, this.domBindings];
|
|
223
|
+
|
|
224
|
+
// todo refactoring: IOC, collection or factories.
|
|
225
|
+
// TODO refactoring, conceive about using generic collection of overlays.
|
|
197
226
|
this.topOverlay = new TopOverlay(...args);
|
|
198
227
|
this.bottomOverlay = new BottomOverlay(...args);
|
|
199
228
|
this.inlineStartOverlay = new InlineStartOverlay(...args);
|
|
229
|
+
|
|
230
|
+
// TODO discuss, the controversial here would be removing the lazy creation mechanism for corners.
|
|
231
|
+
// TODO cond. Has no any visual impact. They're initially hidden in same way like left, top, and bottom overlays.
|
|
200
232
|
this.topInlineStartCornerOverlay = new TopInlineStartCornerOverlay(...args, this.topOverlay, this.inlineStartOverlay);
|
|
201
233
|
this.bottomInlineStartCornerOverlay = new BottomInlineStartCornerOverlay(...args, this.bottomOverlay, this.inlineStartOverlay);
|
|
202
234
|
_classPrivateFieldSet(_overlays, this, [this.topOverlay, this.bottomOverlay, this.inlineStartOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay]);
|
|
@@ -205,20 +237,48 @@ class Overlays {
|
|
|
205
237
|
/**
|
|
206
238
|
* Runs logic for the overlays before the table is drawn.
|
|
207
239
|
*/
|
|
208
|
-
beforeDraw() {
|
|
240
|
+
beforeDraw() {
|
|
241
|
+
_classPrivateFieldSet(_hasRenderingStateChanged, this, _classPrivateFieldGet(_overlays, this).reduce((acc, overlay) => {
|
|
242
|
+
return overlay.hasRenderingStateChanged() || acc;
|
|
243
|
+
}, false));
|
|
244
|
+
_classPrivateFieldGet(_overlays, this).forEach(overlay => overlay.updateStateOfRendering('before'));
|
|
245
|
+
}
|
|
209
246
|
|
|
210
247
|
/**
|
|
211
248
|
* Runs logic for the overlays after the table is drawn.
|
|
212
249
|
*/
|
|
213
|
-
afterDraw() {
|
|
250
|
+
afterDraw() {
|
|
251
|
+
this.syncScrollWithMaster();
|
|
252
|
+
_classPrivateFieldGet(_overlays, this).forEach(overlay => {
|
|
253
|
+
const hasRenderingStateChanged = overlay.hasRenderingStateChanged();
|
|
254
|
+
overlay.updateStateOfRendering('after');
|
|
255
|
+
if (hasRenderingStateChanged && !overlay.needFullRender) {
|
|
256
|
+
overlay.reset();
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
214
260
|
|
|
215
261
|
/**
|
|
216
262
|
* Refresh and redraw table.
|
|
217
263
|
*/
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
264
|
+
refreshAll() {
|
|
265
|
+
if (!this.wot.drawn) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (!this.wtTable.holder.parentNode) {
|
|
269
|
+
// Walkontable was detached from DOM, but this handler was not removed
|
|
270
|
+
this.destroy();
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
this.wot.draw(true);
|
|
274
|
+
if (this.verticalScrolling) {
|
|
275
|
+
this.inlineStartOverlay.onScroll(); // todo the inlineStartOverlay.onScroll() fires hook. Why is it needed there, not in any another place?
|
|
276
|
+
}
|
|
277
|
+
if (this.horizontalScrolling) {
|
|
278
|
+
this.topOverlay.onScroll();
|
|
279
|
+
}
|
|
280
|
+
this.verticalScrolling = false;
|
|
281
|
+
this.horizontalScrolling = false;
|
|
222
282
|
}
|
|
223
283
|
|
|
224
284
|
/**
|
|
@@ -226,22 +286,39 @@ class Overlays {
|
|
|
226
286
|
*/
|
|
227
287
|
registerListeners() {
|
|
228
288
|
const {
|
|
289
|
+
rootDocument,
|
|
229
290
|
rootWindow
|
|
230
291
|
} = this.domBindings;
|
|
292
|
+
const {
|
|
293
|
+
mainTableScrollableElement: topOverlayScrollableElement
|
|
294
|
+
} = this.topOverlay;
|
|
295
|
+
const {
|
|
296
|
+
mainTableScrollableElement: inlineStartOverlayScrollableElement
|
|
297
|
+
} = this.inlineStartOverlay;
|
|
298
|
+
this.eventManager.addEventListener(rootDocument.documentElement, 'keydown', event => this.onKeyDown(event));
|
|
299
|
+
this.eventManager.addEventListener(rootDocument.documentElement, 'keyup', () => this.onKeyUp());
|
|
300
|
+
this.eventManager.addEventListener(rootDocument, 'visibilitychange', () => this.onKeyUp());
|
|
301
|
+
this.eventManager.addEventListener(topOverlayScrollableElement, 'scroll', event => this.onTableScroll(event), {
|
|
302
|
+
passive: true
|
|
303
|
+
});
|
|
304
|
+
if (topOverlayScrollableElement !== inlineStartOverlayScrollableElement) {
|
|
305
|
+
this.eventManager.addEventListener(inlineStartOverlayScrollableElement, 'scroll', event => this.onTableScroll(event), {
|
|
306
|
+
passive: true
|
|
307
|
+
});
|
|
308
|
+
}
|
|
231
309
|
const isHighPixelRatio = rootWindow.devicePixelRatio && rootWindow.devicePixelRatio > 1;
|
|
232
310
|
const isScrollOnWindow = this.scrollableElement === rootWindow;
|
|
233
311
|
const preventWheel = this.wtSettings.getSetting('preventWheel');
|
|
234
312
|
const wheelEventOptions = {
|
|
235
313
|
passive: isScrollOnWindow
|
|
236
314
|
};
|
|
237
|
-
this.eventManager.addEventListener(this.scrollableElement, 'scroll', event => {
|
|
238
|
-
this.wot.draw(true);
|
|
239
|
-
}, {
|
|
240
|
-
passive: true
|
|
241
|
-
});
|
|
242
315
|
if (preventWheel || isHighPixelRatio || !isChrome()) {
|
|
243
316
|
this.eventManager.addEventListener(this.wtTable.wtRootElement, 'wheel', event => this.onCloneWheel(event, preventWheel), wheelEventOptions);
|
|
244
317
|
}
|
|
318
|
+
const overlays = [this.topOverlay, this.bottomOverlay, this.inlineStartOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay];
|
|
319
|
+
overlays.forEach(overlay => {
|
|
320
|
+
this.eventManager.addEventListener(overlay.clone.wtTable.holder, 'wheel', event => this.onCloneWheel(event, preventWheel), wheelEventOptions);
|
|
321
|
+
});
|
|
245
322
|
let resizeTimeout;
|
|
246
323
|
this.eventManager.addEventListener(rootWindow, 'resize', () => {
|
|
247
324
|
requestAnimationFrame(() => {
|
|
@@ -258,6 +335,29 @@ class Overlays {
|
|
|
258
335
|
}
|
|
259
336
|
}
|
|
260
337
|
|
|
338
|
+
/**
|
|
339
|
+
* Scroll listener.
|
|
340
|
+
*
|
|
341
|
+
* @param {Event} event The mouse event object.
|
|
342
|
+
*/
|
|
343
|
+
onTableScroll(event) {
|
|
344
|
+
// There was if statement which controlled flow of this function. It avoided the execution of the next lines
|
|
345
|
+
// on mobile devices. It was changed. Broader description of this case is included within issue #4856.
|
|
346
|
+
const rootWindow = this.domBindings.rootWindow;
|
|
347
|
+
const masterHorizontal = this.inlineStartOverlay.mainTableScrollableElement;
|
|
348
|
+
const masterVertical = this.topOverlay.mainTableScrollableElement;
|
|
349
|
+
const target = event.target;
|
|
350
|
+
|
|
351
|
+
// For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
|
|
352
|
+
// by hot.refreshBorder
|
|
353
|
+
if (this.keyPressed) {
|
|
354
|
+
if (masterVertical !== rootWindow && target !== rootWindow && !event.target.contains(masterVertical) || masterHorizontal !== rootWindow && target !== rootWindow && !event.target.contains(masterHorizontal)) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
this.syncScrollPositions(event);
|
|
359
|
+
}
|
|
360
|
+
|
|
261
361
|
/**
|
|
262
362
|
* Wheel listener for cloned overlays.
|
|
263
363
|
*
|
|
@@ -268,12 +368,43 @@ class Overlays {
|
|
|
268
368
|
const {
|
|
269
369
|
rootWindow
|
|
270
370
|
} = this.domBindings;
|
|
371
|
+
|
|
372
|
+
// There was if statement which controlled flow of this function. It avoided the execution of the next lines
|
|
373
|
+
// on mobile devices. It was changed. Broader description of this case is included within issue #4856.
|
|
374
|
+
|
|
375
|
+
const masterHorizontal = this.inlineStartOverlay.mainTableScrollableElement;
|
|
376
|
+
const masterVertical = this.topOverlay.mainTableScrollableElement;
|
|
377
|
+
const target = event.target;
|
|
378
|
+
|
|
379
|
+
// For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
|
|
380
|
+
// by hot.refreshBorder
|
|
381
|
+
const shouldNotWheelVertically = masterVertical !== rootWindow && target !== rootWindow && !target.contains(masterVertical);
|
|
382
|
+
const shouldNotWheelHorizontally = masterHorizontal !== rootWindow && target !== rootWindow && !target.contains(masterHorizontal);
|
|
383
|
+
if (this.keyPressed && (shouldNotWheelVertically || shouldNotWheelHorizontally) || this.scrollableElement === rootWindow) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
271
386
|
const isScrollPossible = this.translateMouseWheelToScroll(event);
|
|
272
387
|
if (preventDefault || this.scrollableElement !== rootWindow && isScrollPossible) {
|
|
273
388
|
event.preventDefault();
|
|
274
389
|
}
|
|
275
390
|
}
|
|
276
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Key down listener.
|
|
394
|
+
*
|
|
395
|
+
* @param {Event} event The keyboard event object.
|
|
396
|
+
*/
|
|
397
|
+
onKeyDown(event) {
|
|
398
|
+
this.keyPressed = isKey(event.keyCode, 'ARROW_UP|ARROW_RIGHT|ARROW_DOWN|ARROW_LEFT');
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Key up listener.
|
|
403
|
+
*/
|
|
404
|
+
onKeyUp() {
|
|
405
|
+
this.keyPressed = false;
|
|
406
|
+
}
|
|
407
|
+
|
|
277
408
|
/**
|
|
278
409
|
* Translate wheel event into scroll event and sync scroll overlays position.
|
|
279
410
|
*
|
|
@@ -316,6 +447,130 @@ class Overlays {
|
|
|
316
447
|
this.scrollableElement.scrollLeft += delta;
|
|
317
448
|
return previousScroll !== this.scrollableElement.scrollLeft;
|
|
318
449
|
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Synchronize scroll position between master table and overlay table.
|
|
453
|
+
*
|
|
454
|
+
* @private
|
|
455
|
+
*/
|
|
456
|
+
syncScrollPositions() {
|
|
457
|
+
if (this.destroyed) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const {
|
|
461
|
+
rootWindow
|
|
462
|
+
} = this.domBindings;
|
|
463
|
+
const topHolder = this.topOverlay.clone.wtTable.holder; // todo rethink
|
|
464
|
+
const leftHolder = this.inlineStartOverlay.clone.wtTable.holder; // todo rethink
|
|
465
|
+
|
|
466
|
+
const [scrollLeft, scrollTop] = [this.scrollableElement.scrollLeft, this.scrollableElement.scrollTop];
|
|
467
|
+
this.horizontalScrolling = topHolder.scrollLeft !== scrollLeft || this.lastScrollX !== rootWindow.scrollX;
|
|
468
|
+
this.verticalScrolling = leftHolder.scrollTop !== scrollTop || this.lastScrollY !== rootWindow.scrollY;
|
|
469
|
+
this.lastScrollX = rootWindow.scrollX;
|
|
470
|
+
this.lastScrollY = rootWindow.scrollY;
|
|
471
|
+
if (this.horizontalScrolling) {
|
|
472
|
+
topHolder.scrollLeft = scrollLeft;
|
|
473
|
+
const bottomHolder = this.bottomOverlay.needFullRender ? this.bottomOverlay.clone.wtTable.holder : null; // todo rethink
|
|
474
|
+
|
|
475
|
+
if (bottomHolder) {
|
|
476
|
+
bottomHolder.scrollLeft = scrollLeft;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (this.verticalScrolling) {
|
|
480
|
+
leftHolder.scrollTop = scrollTop;
|
|
481
|
+
}
|
|
482
|
+
this.refreshAll();
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Synchronize overlay scrollbars with the master scrollbar.
|
|
487
|
+
*/
|
|
488
|
+
syncScrollWithMaster() {
|
|
489
|
+
if (!_classPrivateFieldGet(_hasRenderingStateChanged, this)) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const master = this.topOverlay.mainTableScrollableElement;
|
|
493
|
+
const {
|
|
494
|
+
scrollLeft,
|
|
495
|
+
scrollTop
|
|
496
|
+
} = master;
|
|
497
|
+
if (this.topOverlay.needFullRender) {
|
|
498
|
+
this.topOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; // todo rethink, *overlay.setScroll*()
|
|
499
|
+
}
|
|
500
|
+
if (this.bottomOverlay.needFullRender) {
|
|
501
|
+
this.bottomOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; // todo rethink, *overlay.setScroll*()
|
|
502
|
+
}
|
|
503
|
+
if (this.inlineStartOverlay.needFullRender) {
|
|
504
|
+
this.inlineStartOverlay.clone.wtTable.holder.scrollTop = scrollTop; // todo rethink, *overlay.setScroll*()
|
|
505
|
+
}
|
|
506
|
+
_classPrivateFieldSet(_hasRenderingStateChanged, this, false);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
*
|
|
511
|
+
*/
|
|
512
|
+
destroy() {
|
|
513
|
+
this.resizeObserver.disconnect();
|
|
514
|
+
this.eventManager.destroy();
|
|
515
|
+
// todo, probably all below `destroy` calls has no sense. To analyze
|
|
516
|
+
this.topOverlay.destroy();
|
|
517
|
+
if (this.bottomOverlay.clone) {
|
|
518
|
+
this.bottomOverlay.destroy();
|
|
519
|
+
}
|
|
520
|
+
this.inlineStartOverlay.destroy();
|
|
521
|
+
if (this.topInlineStartCornerOverlay) {
|
|
522
|
+
this.topInlineStartCornerOverlay.destroy();
|
|
523
|
+
}
|
|
524
|
+
if (this.bottomInlineStartCornerOverlay && this.bottomInlineStartCornerOverlay.clone) {
|
|
525
|
+
this.bottomInlineStartCornerOverlay.destroy();
|
|
526
|
+
}
|
|
527
|
+
this.destroyed = true;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* @param {boolean} [fastDraw=false] When `true`, try to refresh only the positions of borders without rerendering
|
|
532
|
+
* the data. It will only work if Table.draw() does not force
|
|
533
|
+
* rendering anyway.
|
|
534
|
+
*/
|
|
535
|
+
refresh() {
|
|
536
|
+
let fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
537
|
+
const wasSpreaderSizeUpdated = this.updateLastSpreaderSize();
|
|
538
|
+
if (wasSpreaderSizeUpdated) {
|
|
539
|
+
this.adjustElementsSize();
|
|
540
|
+
}
|
|
541
|
+
if (this.bottomOverlay.clone) {
|
|
542
|
+
this.bottomOverlay.refresh(fastDraw);
|
|
543
|
+
}
|
|
544
|
+
this.inlineStartOverlay.refresh(fastDraw);
|
|
545
|
+
this.topOverlay.refresh(fastDraw);
|
|
546
|
+
if (this.topInlineStartCornerOverlay) {
|
|
547
|
+
this.topInlineStartCornerOverlay.refresh(fastDraw);
|
|
548
|
+
}
|
|
549
|
+
if (this.bottomInlineStartCornerOverlay && this.bottomInlineStartCornerOverlay.clone) {
|
|
550
|
+
this.bottomInlineStartCornerOverlay.refresh(fastDraw);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Update the last cached spreader size with the current size.
|
|
556
|
+
*
|
|
557
|
+
* @returns {boolean} `true` if the lastSpreaderSize cache was updated, `false` otherwise.
|
|
558
|
+
*/
|
|
559
|
+
updateLastSpreaderSize() {
|
|
560
|
+
const spreader = this.wtTable.spreader;
|
|
561
|
+
const width = spreader.clientWidth;
|
|
562
|
+
const height = spreader.clientHeight;
|
|
563
|
+
const needsUpdating = width !== this.spreaderLastSize.width || height !== this.spreaderLastSize.height;
|
|
564
|
+
if (needsUpdating) {
|
|
565
|
+
this.spreaderLastSize.width = width;
|
|
566
|
+
this.spreaderLastSize.height = height;
|
|
567
|
+
}
|
|
568
|
+
return needsUpdating;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Adjust overlays elements size and master table size.
|
|
573
|
+
*/
|
|
319
574
|
adjustElementsSize() {
|
|
320
575
|
const {
|
|
321
576
|
wtViewport
|
|
@@ -335,44 +590,99 @@ class Overlays {
|
|
|
335
590
|
const proposedHiderWidth = headerRowSize + this.inlineStartOverlay.sumCellSizes(0, totalColumns);
|
|
336
591
|
const hiderElement = wtTable.hider;
|
|
337
592
|
const hiderStyle = hiderElement.style;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
593
|
+
const isScrolledBeyondHiderHeight = () => {
|
|
594
|
+
return isWindowScrolled ? false : this.scrollableElement.scrollTop > Math.max(0, proposedHiderHeight - wtTable.holder.clientHeight);
|
|
595
|
+
};
|
|
596
|
+
const isScrolledBeyondHiderWidth = () => {
|
|
597
|
+
return isWindowScrolled ? false : this.scrollableElement.scrollLeft > Math.max(0, proposedHiderWidth - wtTable.holder.clientWidth);
|
|
598
|
+
};
|
|
599
|
+
const columnHeaderBorderCompensation = isScrolledBeyondHiderHeight() ? 1 : 0;
|
|
600
|
+
const rowHeaderBorderCompensation = isScrolledBeyondHiderWidth() ? 1 : 0;
|
|
601
|
+
|
|
602
|
+
// If the elements are being adjusted after scrolling the table from the very beginning to the very end,
|
|
603
|
+
// we need to adjust the hider dimensions by the header border size. (https://github.com/handsontable/dev-handsontable/issues/1772)
|
|
604
|
+
hiderStyle.width = `${proposedHiderWidth + rowHeaderBorderCompensation}px`;
|
|
605
|
+
hiderStyle.height = `${proposedHiderHeight + columnHeaderBorderCompensation}px`;
|
|
606
|
+
this.topOverlay.adjustElementsSize();
|
|
607
|
+
this.inlineStartOverlay.adjustElementsSize();
|
|
608
|
+
this.bottomOverlay.adjustElementsSize();
|
|
355
609
|
}
|
|
356
610
|
|
|
357
611
|
/**
|
|
612
|
+
* Expand the hider vertically element by the provided delta value.
|
|
358
613
|
*
|
|
614
|
+
* @param {number} heightDelta The delta value to expand the hider element by.
|
|
359
615
|
*/
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
616
|
+
expandHiderVerticallyBy(heightDelta) {
|
|
617
|
+
const {
|
|
618
|
+
wtTable
|
|
619
|
+
} = this;
|
|
620
|
+
wtTable.hider.style.height = `${parseInt(wtTable.hider.style.height, 10) + heightDelta}px`;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Expand the hider horizontally element by the provided delta value.
|
|
625
|
+
*
|
|
626
|
+
* @param {number} widthDelta The delta value to expand the hider element by.
|
|
627
|
+
*/
|
|
628
|
+
expandHiderHorizontallyBy(widthDelta) {
|
|
629
|
+
const {
|
|
630
|
+
wtTable
|
|
631
|
+
} = this;
|
|
632
|
+
wtTable.hider.style.width = `${parseInt(wtTable.hider.style.width, 10) + widthDelta}px`;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
*
|
|
637
|
+
*/
|
|
638
|
+
applyToDOM() {
|
|
639
|
+
if (!this.wtTable.isVisible()) {
|
|
640
|
+
return;
|
|
367
641
|
}
|
|
368
|
-
this.
|
|
369
|
-
if (this.
|
|
370
|
-
this.
|
|
642
|
+
this.topOverlay.applyToDOM();
|
|
643
|
+
if (this.bottomOverlay.clone) {
|
|
644
|
+
this.bottomOverlay.applyToDOM();
|
|
371
645
|
}
|
|
372
|
-
|
|
373
|
-
|
|
646
|
+
this.inlineStartOverlay.applyToDOM();
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Get the parent overlay of the provided element.
|
|
651
|
+
*
|
|
652
|
+
* @param {HTMLElement} element An element to process.
|
|
653
|
+
* @returns {object|null}
|
|
654
|
+
*/
|
|
655
|
+
getParentOverlay(element) {
|
|
656
|
+
if (!element) {
|
|
657
|
+
return null;
|
|
374
658
|
}
|
|
375
|
-
this.
|
|
659
|
+
const overlays = [this.topOverlay, this.inlineStartOverlay, this.bottomOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay];
|
|
660
|
+
let result = null;
|
|
661
|
+
arrayEach(overlays, overlay => {
|
|
662
|
+
if (!overlay) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
if (overlay.clone && overlay.clone.wtTable.TABLE.contains(element)) {
|
|
666
|
+
// todo demeter
|
|
667
|
+
result = overlay.clone;
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
return result;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Synchronize the class names between the main overlay table and the tables on the other overlays.
|
|
675
|
+
*
|
|
676
|
+
*/
|
|
677
|
+
syncOverlayTableClassNames() {
|
|
678
|
+
const masterTable = this.wtTable.TABLE;
|
|
679
|
+
const overlays = [this.topOverlay, this.inlineStartOverlay, this.bottomOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay];
|
|
680
|
+
arrayEach(overlays, elem => {
|
|
681
|
+
if (!elem) {
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
elem.clone.wtTable.TABLE.className = masterTable.className; // todo demeter
|
|
685
|
+
});
|
|
376
686
|
}
|
|
377
687
|
}
|
|
378
688
|
export default Overlays;
|