@atlaskit/editor-plugin-table 42.0.3 → 42.2.0
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.
- package/CHANGELOG.md +23 -0
- package/dist/cjs/nodeviews/TableComponent.js +31 -15
- package/dist/cjs/nodeviews/TableRow.js +9 -0
- package/dist/cjs/nodeviews/TableRowNativeStickyWithFallback.js +9 -0
- package/dist/cjs/nodeviews/is-focus-only-change.js +54 -0
- package/dist/cjs/pm-plugins/commands/misc.js +11 -4
- package/dist/cjs/ui/FloatingInsertButton/index.js +36 -1
- package/dist/es2019/nodeviews/TableComponent.js +30 -15
- package/dist/es2019/nodeviews/TableRow.js +9 -0
- package/dist/es2019/nodeviews/TableRowNativeStickyWithFallback.js +9 -0
- package/dist/es2019/nodeviews/is-focus-only-change.js +31 -0
- package/dist/es2019/pm-plugins/commands/misc.js +11 -4
- package/dist/es2019/ui/FloatingInsertButton/index.js +24 -1
- package/dist/esm/nodeviews/TableComponent.js +31 -15
- package/dist/esm/nodeviews/TableRow.js +9 -0
- package/dist/esm/nodeviews/TableRowNativeStickyWithFallback.js +9 -0
- package/dist/esm/nodeviews/is-focus-only-change.js +47 -0
- package/dist/esm/pm-plugins/commands/misc.js +11 -4
- package/dist/esm/ui/FloatingInsertButton/index.js +36 -1
- package/dist/types/nodeviews/TableRow.d.ts +1 -0
- package/dist/types/nodeviews/TableRowNativeStickyWithFallback.d.ts +1 -0
- package/dist/types/nodeviews/is-focus-only-change.d.ts +16 -0
- package/package.json +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-table
|
|
2
2
|
|
|
3
|
+
## 42.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`d0007ab586b5f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d0007ab586b5f) -
|
|
8
|
+
Behind the platform_editor_sticky_header_insert_column_exp experiment, keep the column insert
|
|
9
|
+
button visible when the table header row is sticky
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`0e3b42ec20124`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0e3b42ec20124) -
|
|
14
|
+
Reduce redundant table work caused by editor focus changes behind the
|
|
15
|
+
`platform_editor_improve_inp` experiment.
|
|
16
|
+
|
|
17
|
+
## 42.1.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- [`5eff440523b45`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5eff440523b45) -
|
|
22
|
+
Rescale full-page tables with measured column widths when the editor container width changes
|
|
23
|
+
without a window resize (for example, a side panel opening), behind
|
|
24
|
+
platform_editor_table_scale_on_container_resize
|
|
25
|
+
|
|
3
26
|
## 42.0.3
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -61,6 +61,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
61
61
|
// Prevent unnecessary parentWidth updates when table is nested inside of a node that is nested itself.
|
|
62
62
|
var NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MIN_THRESHOLD = 2;
|
|
63
63
|
var NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MAX_THRESHOLD = 20;
|
|
64
|
+
var MEASURED_COLUMN_WIDTH = /^[\.0-9]+px$/;
|
|
64
65
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
65
66
|
var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
66
67
|
function TableComponent(props) {
|
|
@@ -336,6 +337,16 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
336
337
|
(0, _defineProperty2.default)(_this, "tableNodeLayoutSize", function (node, containerWidth, options) {
|
|
337
338
|
return (0, _misc.getLayoutSize)(node.attrs.layout, containerWidth || _this.props.containerWidth.width, options || _this.props.options || {});
|
|
338
339
|
});
|
|
340
|
+
/**
|
|
341
|
+
* Full-page tables scale with their container through CSS `calc()` column widths. Once a
|
|
342
|
+
* colgroup has been rewritten with measured px widths (column resize, collab, column add or
|
|
343
|
+
* delete, window resize), CSS can no longer scale it and the colgroup must be updated in JS.
|
|
344
|
+
*/
|
|
345
|
+
(0, _defineProperty2.default)(_this, "hasMeasuredColumnWidths", function () {
|
|
346
|
+
var _this$table;
|
|
347
|
+
var firstColumn = (_this$table = _this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(':scope > colgroup > col');
|
|
348
|
+
return !!firstColumn && MEASURED_COLUMN_WIDTH.test(firstColumn.style.width);
|
|
349
|
+
});
|
|
339
350
|
(0, _defineProperty2.default)(_this, "shouldUpdateColgroup", function (params) {
|
|
340
351
|
var _this$props$options, _this$props$options2;
|
|
341
352
|
var isWindowResized = params.isWindowResized,
|
|
@@ -429,9 +440,9 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
429
440
|
}, {
|
|
430
441
|
key: "initialiseEventListenersAfterMount",
|
|
431
442
|
value: function initialiseEventListenersAfterMount() {
|
|
432
|
-
var _this$
|
|
433
|
-
_this$table2,
|
|
443
|
+
var _this$table2,
|
|
434
444
|
_this$table3,
|
|
445
|
+
_this$table4,
|
|
435
446
|
_this3 = this;
|
|
436
447
|
var _this$props6 = this.props,
|
|
437
448
|
allowColumnResizing = _this$props6.allowColumnResizing,
|
|
@@ -444,15 +455,15 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
444
455
|
|
|
445
456
|
// Ignored via go/ees005
|
|
446
457
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
447
|
-
this === null || this === void 0 || (_this$
|
|
458
|
+
this === null || this === void 0 || (_this$table2 = this.table) === null || _this$table2 === void 0 || _this$table2.addEventListener('mouseenter', this.handleMouseEnter);
|
|
448
459
|
|
|
449
460
|
// Ignored via go/ees005
|
|
450
461
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
451
|
-
this === null || this === void 0 || (_this$
|
|
462
|
+
this === null || this === void 0 || (_this$table3 = this.table) === null || _this$table3 === void 0 || _this$table3.addEventListener('mouseout', this.handleMouseOut);
|
|
452
463
|
|
|
453
464
|
// Ignored via go/ees005
|
|
454
465
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
455
|
-
this === null || this === void 0 || (_this$
|
|
466
|
+
this === null || this === void 0 || (_this$table4 = this.table) === null || _this$table4 === void 0 || _this$table4.addEventListener('mouseover', this.handleMouseOver);
|
|
456
467
|
if (this.wrapper) {
|
|
457
468
|
this.wrapperReisizeObserver = new ResizeObserver(function (entries) {
|
|
458
469
|
var _iterator2 = _createForOfIteratorHelper(entries),
|
|
@@ -511,7 +522,7 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
511
522
|
}, {
|
|
512
523
|
key: "componentWillUnmount",
|
|
513
524
|
value: function componentWillUnmount() {
|
|
514
|
-
var _this$resizeObserver, _this$wrapperReisizeO, _this$
|
|
525
|
+
var _this$resizeObserver, _this$wrapperReisizeO, _this$table5, _this$table6, _this$table7;
|
|
515
526
|
var _this$props7 = this.props,
|
|
516
527
|
allowColumnResizing = _this$props7.allowColumnResizing,
|
|
517
528
|
allowTableResizing = _this$props7.allowTableResizing,
|
|
@@ -559,15 +570,15 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
559
570
|
|
|
560
571
|
// Ignored via go/ees005
|
|
561
572
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
562
|
-
this === null || this === void 0 || (_this$
|
|
573
|
+
this === null || this === void 0 || (_this$table5 = this.table) === null || _this$table5 === void 0 || _this$table5.removeEventListener('mouseenter', this.handleMouseEnter);
|
|
563
574
|
|
|
564
575
|
// Ignored via go/ees005
|
|
565
576
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
566
|
-
this === null || this === void 0 || (_this$
|
|
577
|
+
this === null || this === void 0 || (_this$table6 = this.table) === null || _this$table6 === void 0 || _this$table6.removeEventListener('mouseout', this.handleMouseOut);
|
|
567
578
|
|
|
568
579
|
// Ignored via go/ees005
|
|
569
580
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
570
|
-
this === null || this === void 0 || (_this$
|
|
581
|
+
this === null || this === void 0 || (_this$table7 = this.table) === null || _this$table7 === void 0 || _this$table7.removeEventListener('mouseover', this.handleMouseOver);
|
|
571
582
|
|
|
572
583
|
// Ignored via go/ees005
|
|
573
584
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -605,6 +616,7 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
605
616
|
key: "handleColgroupUpdates",
|
|
606
617
|
value: function handleColgroupUpdates() {
|
|
607
618
|
var _this$containerWidth,
|
|
619
|
+
_this$containerWidth2,
|
|
608
620
|
_this4 = this;
|
|
609
621
|
var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
610
622
|
var _this$props9 = this.props,
|
|
@@ -641,16 +653,20 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
641
653
|
containerLineLength = containerWidth.lineLength;
|
|
642
654
|
var isLineLengthChanged = ((_this$containerWidth = this.containerWidth) === null || _this$containerWidth === void 0 ? void 0 : _this$containerWidth.lineLength) !== containerLineLength;
|
|
643
655
|
var isFullWidthModeAndLineLengthChanged = this.updateColGroupFromFullWidthChange && isLineLengthChanged;
|
|
644
|
-
var
|
|
656
|
+
var previousContainerWidth = (_this$containerWidth2 = this.containerWidth) === null || _this$containerWidth2 === void 0 ? void 0 : _this$containerWidth2.width;
|
|
657
|
+
var isFullPageEditor = !(options !== null && options !== void 0 && options.isCommentEditor) && !(options !== null && options !== void 0 && options.isChromelessEditor);
|
|
658
|
+
var isContainerResized = (0, _fg.fg)('platform_editor_table_scale_on_container_resize') && isFullPageEditor && !!previousContainerWidth && previousContainerWidth !== containerWidthValue && this.hasMeasuredColumnWidths();
|
|
659
|
+
var isWindowOrContainerResized = this.state.windowResized || isContainerResized;
|
|
660
|
+
var maybeScale = isTableSquashed || isTableWidthChanged || isTableResizedFullWidth && !(options !== null && options !== void 0 && options.isCommentEditor) || isNumberColumnChanged || isNumberOfColumnsChanged || isWindowOrContainerResized;
|
|
645
661
|
if (force || maybeScale || isFullWidthModeAndLineLengthChanged) {
|
|
646
|
-
var _this$
|
|
647
|
-
var isWidthChanged = ((_this$
|
|
662
|
+
var _this$containerWidth3, _this$props0, _this$props$options3, _this$props$options4, _this$props$options5;
|
|
663
|
+
var isWidthChanged = ((_this$containerWidth3 = this.containerWidth) === null || _this$containerWidth3 === void 0 ? void 0 : _this$containerWidth3.width) !== containerWidthValue;
|
|
648
664
|
var wasTableResized = (0, _colgroup.hasTableBeenResized)(this.node);
|
|
649
665
|
var isTableResized = (0, _colgroup.hasTableBeenResized)(tableNode);
|
|
650
666
|
var isColumnsDistributed = wasTableResized && !isTableResized;
|
|
651
667
|
var isTableDisplayModeChanged = this.node.attrs.displayMode !== tableNode.attrs.displayMode;
|
|
652
668
|
var shouldUpdateColgroup = this.shouldUpdateColgroup({
|
|
653
|
-
isWindowResized:
|
|
669
|
+
isWindowResized: isWindowOrContainerResized,
|
|
654
670
|
isWidthChanged: isWidthChanged,
|
|
655
671
|
isTableWidthChanged: isTableWidthChanged,
|
|
656
672
|
isColumnsDistributed: isColumnsDistributed,
|
|
@@ -779,14 +795,14 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
779
795
|
var view = this.props.view;
|
|
780
796
|
var shouldRecreateResizeCols = !allowTableResizing || !isResizing || isNoOfColumnsChanged && isResizing;
|
|
781
797
|
if (shouldRecreateResizeCols) {
|
|
782
|
-
var _this$
|
|
798
|
+
var _this$table8, _this$props$options10, _this$props$options11;
|
|
783
799
|
var start = getPos() || 0;
|
|
784
800
|
var depth = view.state.doc.resolve(start).depth;
|
|
785
801
|
shouldScale = depth === 0 && shouldScale;
|
|
786
802
|
(0, _colgroup.insertColgroupFromNode)(this.table, currentTable, shouldScale, undefined, shouldUseIncreasedScalingPercent, options === null || options === void 0 ? void 0 : options.isCommentEditor);
|
|
787
803
|
|
|
788
804
|
// Deferred from setDomAttrs — remove only once colgroup is updated and table has left content mode.
|
|
789
|
-
if ((_this$
|
|
805
|
+
if ((_this$table8 = this.table) !== null && _this$table8 !== void 0 && _this$table8.hasAttribute('data-initial-width-mode') && !(0, _contentMode.isTableInContentMode)({
|
|
790
806
|
tableNode: currentTable,
|
|
791
807
|
isSupported: (0, _isContentModeSupported.isContentModeSupported)({
|
|
792
808
|
allowColumnResizing: !!allowColumnResizing,
|
|
@@ -27,6 +27,7 @@ var _dom2 = require("../pm-plugins/utils/dom");
|
|
|
27
27
|
var _nodes = require("../pm-plugins/utils/nodes");
|
|
28
28
|
var _types = require("../types");
|
|
29
29
|
var _consts = require("../ui/consts");
|
|
30
|
+
var _isFocusOnlyChange = require("./is-focus-only-change");
|
|
30
31
|
var _TableNodeViewBase = _interopRequireDefault(require("./TableNodeViewBase"));
|
|
31
32
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
32
33
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
@@ -57,6 +58,7 @@ var TableRow = exports.default = /*#__PURE__*/function (_TableNodeView) {
|
|
|
57
58
|
});
|
|
58
59
|
(0, _defineProperty2.default)(_this, "colControlsOffset", 0);
|
|
59
60
|
(0, _defineProperty2.default)(_this, "focused", false);
|
|
61
|
+
(0, _defineProperty2.default)(_this, "focusOnlyUpdateGuard", new _isFocusOnlyChange.FocusOnlyUpdateGuard());
|
|
60
62
|
(0, _defineProperty2.default)(_this, "topPosEditorElement", 0);
|
|
61
63
|
(0, _defineProperty2.default)(_this, "sentinels", {});
|
|
62
64
|
(0, _defineProperty2.default)(_this, "sentinelData", {
|
|
@@ -278,6 +280,8 @@ var TableRow = exports.default = /*#__PURE__*/function (_TableNodeView) {
|
|
|
278
280
|
}, {
|
|
279
281
|
key: "subscribe",
|
|
280
282
|
value: function subscribe() {
|
|
283
|
+
this.focusOnlyUpdateGuard.reset();
|
|
284
|
+
|
|
281
285
|
// Ignored via go/ees005
|
|
282
286
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
283
287
|
this.editorScrollableElement = (0, _utils.findOverflowScrollParent)(this.view.dom) || window;
|
|
@@ -313,6 +317,7 @@ var TableRow = exports.default = /*#__PURE__*/function (_TableNodeView) {
|
|
|
313
317
|
}, {
|
|
314
318
|
key: "unsubscribe",
|
|
315
319
|
value: function unsubscribe() {
|
|
320
|
+
this.focusOnlyUpdateGuard.reset();
|
|
316
321
|
if (!this.listening) {
|
|
317
322
|
return;
|
|
318
323
|
}
|
|
@@ -624,11 +629,15 @@ var TableRow = exports.default = /*#__PURE__*/function (_TableNodeView) {
|
|
|
624
629
|
}, {
|
|
625
630
|
key: "onTablePluginState",
|
|
626
631
|
value: function onTablePluginState(state) {
|
|
632
|
+
if (this.focusOnlyUpdateGuard.skipIfFocusOnly(state)) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
627
635
|
var tableRef = state.tableRef;
|
|
628
636
|
var tree = (0, _dom2.getTree)(this.dom);
|
|
629
637
|
if (!tree) {
|
|
630
638
|
return;
|
|
631
639
|
}
|
|
640
|
+
this.focusOnlyUpdateGuard.markProcessed(state);
|
|
632
641
|
|
|
633
642
|
// when header rows are toggled off - mark sentinels as unobserved
|
|
634
643
|
if (!state.isHeaderRowEnabled) {
|
|
@@ -31,6 +31,7 @@ var _dom2 = require("../pm-plugins/utils/dom");
|
|
|
31
31
|
var _nodes = require("../pm-plugins/utils/nodes");
|
|
32
32
|
var _types = require("../types");
|
|
33
33
|
var _consts = require("../ui/consts");
|
|
34
|
+
var _isFocusOnlyChange = require("./is-focus-only-change");
|
|
34
35
|
var _TableNodeViewBase = _interopRequireDefault(require("./TableNodeViewBase"));
|
|
35
36
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
36
37
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
@@ -63,6 +64,7 @@ var TableRowNativeStickyWithFallback = exports.default = /*#__PURE__*/function (
|
|
|
63
64
|
});
|
|
64
65
|
(0, _defineProperty2.default)(_this, "colControlsOffset", 0);
|
|
65
66
|
(0, _defineProperty2.default)(_this, "focused", false);
|
|
67
|
+
(0, _defineProperty2.default)(_this, "focusOnlyUpdateGuard", new _isFocusOnlyChange.FocusOnlyUpdateGuard());
|
|
66
68
|
(0, _defineProperty2.default)(_this, "topPosEditorElement", 0);
|
|
67
69
|
(0, _defineProperty2.default)(_this, "sentinels", {});
|
|
68
70
|
(0, _defineProperty2.default)(_this, "sentinelData", {
|
|
@@ -327,6 +329,8 @@ var TableRowNativeStickyWithFallback = exports.default = /*#__PURE__*/function (
|
|
|
327
329
|
key: "subscribe",
|
|
328
330
|
value: function subscribe() {
|
|
329
331
|
var _this4 = this;
|
|
332
|
+
this.focusOnlyUpdateGuard.reset();
|
|
333
|
+
|
|
330
334
|
// Ignored via go/ees005
|
|
331
335
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
332
336
|
this.editorScrollableElement = (0, _utils.findOverflowScrollParent)(this.view.dom) || window;
|
|
@@ -404,6 +408,7 @@ var TableRowNativeStickyWithFallback = exports.default = /*#__PURE__*/function (
|
|
|
404
408
|
}, {
|
|
405
409
|
key: "unsubscribe",
|
|
406
410
|
value: function unsubscribe() {
|
|
411
|
+
this.focusOnlyUpdateGuard.reset();
|
|
407
412
|
if (!this.listening) {
|
|
408
413
|
return;
|
|
409
414
|
}
|
|
@@ -864,11 +869,15 @@ var TableRowNativeStickyWithFallback = exports.default = /*#__PURE__*/function (
|
|
|
864
869
|
}, {
|
|
865
870
|
key: "onTablePluginState",
|
|
866
871
|
value: function onTablePluginState(state) {
|
|
872
|
+
if (this.focusOnlyUpdateGuard.skipIfFocusOnly(state)) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
867
875
|
var tableRef = state.tableRef;
|
|
868
876
|
var tree = (0, _dom2.getTree)(this.dom);
|
|
869
877
|
if (!tree) {
|
|
870
878
|
return;
|
|
871
879
|
}
|
|
880
|
+
this.focusOnlyUpdateGuard.markProcessed(state);
|
|
872
881
|
|
|
873
882
|
// when header rows are toggled off - mark sentinels as unobserved
|
|
874
883
|
if (!state.isHeaderRowEnabled) {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.shallowEqualExcept = exports.isFocusOnlyChange = exports.FocusOnlyUpdateGuard = void 0;
|
|
8
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
11
|
+
var shallowEqualExcept = exports.shallowEqualExcept = function shallowEqualExcept(previousValue, currentValue, ignoredKey) {
|
|
12
|
+
var previousKeys = Object.keys(previousValue);
|
|
13
|
+
var currentKeys = Object.keys(currentValue);
|
|
14
|
+
return previousKeys.length === currentKeys.length && currentKeys.every(function (key) {
|
|
15
|
+
return key === ignoredKey || Object.prototype.hasOwnProperty.call(previousValue, key) && Object.is(previousValue[key], currentValue[key]);
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns true when editor focus is the only table plugin state value that changed.
|
|
21
|
+
*
|
|
22
|
+
* Table reducers preserve references for unchanged values. If a reducer rebuilds a value, this
|
|
23
|
+
* returns false and callers take the original full-work path rather than skipping incorrectly.
|
|
24
|
+
*/
|
|
25
|
+
var isFocusOnlyChange = exports.isFocusOnlyChange = function isFocusOnlyChange(previousState, currentState) {
|
|
26
|
+
return previousState.editorHasFocus !== currentState.editorHasFocus && shallowEqualExcept(previousState, currentState, 'editorHasFocus');
|
|
27
|
+
};
|
|
28
|
+
var FocusOnlyUpdateGuard = exports.FocusOnlyUpdateGuard = /*#__PURE__*/function () {
|
|
29
|
+
function FocusOnlyUpdateGuard() {
|
|
30
|
+
(0, _classCallCheck2.default)(this, FocusOnlyUpdateGuard);
|
|
31
|
+
}
|
|
32
|
+
return (0, _createClass2.default)(FocusOnlyUpdateGuard, [{
|
|
33
|
+
key: "skipIfFocusOnly",
|
|
34
|
+
value: /** Returns true and records the state when this is a skippable focus-only update. */
|
|
35
|
+
function skipIfFocusOnly(state) {
|
|
36
|
+
var lastProcessedState = this.lastProcessedState;
|
|
37
|
+
if (lastProcessedState !== undefined && isFocusOnlyChange(lastProcessedState, state) && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_improve_inp')) {
|
|
38
|
+
this.lastProcessedState = state;
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}, {
|
|
44
|
+
key: "markProcessed",
|
|
45
|
+
value: function markProcessed(state) {
|
|
46
|
+
this.lastProcessedState = state;
|
|
47
|
+
}
|
|
48
|
+
}, {
|
|
49
|
+
key: "reset",
|
|
50
|
+
value: function reset() {
|
|
51
|
+
this.lastProcessedState = undefined;
|
|
52
|
+
}
|
|
53
|
+
}]);
|
|
54
|
+
}();
|
|
@@ -25,6 +25,7 @@ var _removeTable = require("@atlaskit/editor-tables/utils/remove-table");
|
|
|
25
25
|
var _selectNodes = require("@atlaskit/editor-tables/utils/select-nodes");
|
|
26
26
|
var _selectionCell = require("@atlaskit/editor-tables/utils/selection-cell");
|
|
27
27
|
var _setCellAttrs = require("@atlaskit/editor-tables/utils/set-cell-attrs");
|
|
28
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
28
29
|
var _types = require("../../types");
|
|
29
30
|
var _plugin = require("../decorations/plugin");
|
|
30
31
|
var _columnResizing = require("../decorations/utils/column-resizing");
|
|
@@ -55,11 +56,17 @@ var selectColumnWithMergedEdgeRows = function selectColumnWithMergedEdgeRows(tr,
|
|
|
55
56
|
return transformedTr.setSelection(new _cellSelection.CellSelection(transformedTr.doc.resolve(lastCell.pos), transformedTr.doc.resolve(firstCell.pos)));
|
|
56
57
|
};
|
|
57
58
|
var setEditorFocus = exports.setEditorFocus = function setEditorFocus(editorHasFocus) {
|
|
58
|
-
return (0, _pluginFactory.createCommand)({
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
return (0, _pluginFactory.createCommand)(function (state) {
|
|
60
|
+
var pluginState = (0, _pluginFactory.getPluginState)(state);
|
|
61
|
+
if (pluginState.editorHasFocus === editorHasFocus && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_improve_inp')) {
|
|
62
|
+
return false;
|
|
62
63
|
}
|
|
64
|
+
return {
|
|
65
|
+
type: 'SET_EDITOR_FOCUS',
|
|
66
|
+
data: {
|
|
67
|
+
editorHasFocus: editorHasFocus
|
|
68
|
+
}
|
|
69
|
+
};
|
|
63
70
|
});
|
|
64
71
|
};
|
|
65
72
|
var setTableRef = exports.setTableRef = function setTableRef(ref) {
|
|
@@ -32,6 +32,37 @@ var _getPopupOptions = _interopRequireDefault(require("./getPopupOptions"));
|
|
|
32
32
|
var _InsertButton = require("./InsertButton");
|
|
33
33
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
34
34
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
35
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
36
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
37
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
38
|
+
/**
|
|
39
|
+
* Distance from the table top to the top of the row containing `cell`, summed from row heights.
|
|
40
|
+
* Viewport rects cannot be used: a stuck header row is fixed to the viewport while the table scrolls.
|
|
41
|
+
*/
|
|
42
|
+
var getRowOffsetFromTableTop = function getRowOffsetFromTableTop(cell, table) {
|
|
43
|
+
var anchorRow = (0, _dom.closestElement)(cell, 'tr');
|
|
44
|
+
if (!(table instanceof HTMLTableElement) || !anchorRow) {
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
var offset = 0;
|
|
48
|
+
var _iterator = _createForOfIteratorHelper(table.rows),
|
|
49
|
+
_step;
|
|
50
|
+
try {
|
|
51
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
52
|
+
var row = _step.value;
|
|
53
|
+
if (row === anchorRow) {
|
|
54
|
+
return offset;
|
|
55
|
+
}
|
|
56
|
+
offset += row.offsetHeight;
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
_iterator.e(err);
|
|
60
|
+
} finally {
|
|
61
|
+
_iterator.f();
|
|
62
|
+
}
|
|
63
|
+
return 0;
|
|
64
|
+
};
|
|
65
|
+
|
|
35
66
|
// Ignored via go/ees005
|
|
36
67
|
// eslint-disable-next-line @repo/internal/react/no-class-components, @typescript-eslint/no-explicit-any
|
|
37
68
|
var FloatingInsertButton = exports.FloatingInsertButton = /*#__PURE__*/function (_React$Component) {
|
|
@@ -142,7 +173,11 @@ var FloatingInsertButton = exports.FloatingInsertButton = /*#__PURE__*/function
|
|
|
142
173
|
// ↑ button should render at row 0/table top
|
|
143
174
|
var verticalOffsetCorrection = 0;
|
|
144
175
|
if (type === 'column' && (0, _expValEquals.expValEquals)('platform_editor_table_menu_updates', 'isEnabled', true)) {
|
|
145
|
-
|
|
176
|
+
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_sticky_header_insert_column_exp')) {
|
|
177
|
+
verticalOffsetCorrection = getRowOffsetFromTableTop(targetCellRef, tableRef);
|
|
178
|
+
} else {
|
|
179
|
+
verticalOffsetCorrection = Math.max(0, targetCellRef.getBoundingClientRect().top - tableRef.getBoundingClientRect().top);
|
|
180
|
+
}
|
|
146
181
|
}
|
|
147
182
|
// Preserve the original popup placement: overflow row inserts and column inserts
|
|
148
183
|
// sit above the header; other row inserts sit below it.
|
|
@@ -42,6 +42,7 @@ import { TableStickyScrollbar } from './TableStickyScrollbar';
|
|
|
42
42
|
// Prevent unnecessary parentWidth updates when table is nested inside of a node that is nested itself.
|
|
43
43
|
const NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MIN_THRESHOLD = 2;
|
|
44
44
|
const NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MAX_THRESHOLD = 20;
|
|
45
|
+
const MEASURED_COLUMN_WIDTH = /^[\d.]+px$/u;
|
|
45
46
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
46
47
|
class TableComponent extends React.Component {
|
|
47
48
|
constructor(props) {
|
|
@@ -325,6 +326,16 @@ class TableComponent extends React.Component {
|
|
|
325
326
|
});
|
|
326
327
|
});
|
|
327
328
|
_defineProperty(this, "tableNodeLayoutSize", (node, containerWidth, options) => getLayoutSize(node.attrs.layout, containerWidth || this.props.containerWidth.width, options || this.props.options || {}));
|
|
329
|
+
/**
|
|
330
|
+
* Full-page tables scale with their container through CSS `calc()` column widths. Once a
|
|
331
|
+
* colgroup has been rewritten with measured px widths (column resize, collab, column add or
|
|
332
|
+
* delete, window resize), CSS can no longer scale it and the colgroup must be updated in JS.
|
|
333
|
+
*/
|
|
334
|
+
_defineProperty(this, "hasMeasuredColumnWidths", () => {
|
|
335
|
+
var _this$table;
|
|
336
|
+
const firstColumn = (_this$table = this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(':scope > colgroup > col');
|
|
337
|
+
return !!firstColumn && MEASURED_COLUMN_WIDTH.test(firstColumn.style.width);
|
|
338
|
+
});
|
|
328
339
|
_defineProperty(this, "shouldUpdateColgroup", params => {
|
|
329
340
|
var _this$props$options, _this$props$options2;
|
|
330
341
|
const {
|
|
@@ -405,7 +416,7 @@ class TableComponent extends React.Component {
|
|
|
405
416
|
this.dispatchTableRefUpdate();
|
|
406
417
|
}
|
|
407
418
|
initialiseEventListenersAfterMount() {
|
|
408
|
-
var _this$
|
|
419
|
+
var _this$table2, _this$table3, _this$table4;
|
|
409
420
|
const {
|
|
410
421
|
allowColumnResizing,
|
|
411
422
|
allowTableResizing,
|
|
@@ -418,15 +429,15 @@ class TableComponent extends React.Component {
|
|
|
418
429
|
|
|
419
430
|
// Ignored via go/ees005
|
|
420
431
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
421
|
-
this === null || this === void 0 ? void 0 : (_this$
|
|
432
|
+
this === null || this === void 0 ? void 0 : (_this$table2 = this.table) === null || _this$table2 === void 0 ? void 0 : _this$table2.addEventListener('mouseenter', this.handleMouseEnter);
|
|
422
433
|
|
|
423
434
|
// Ignored via go/ees005
|
|
424
435
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
425
|
-
this === null || this === void 0 ? void 0 : (_this$
|
|
436
|
+
this === null || this === void 0 ? void 0 : (_this$table3 = this.table) === null || _this$table3 === void 0 ? void 0 : _this$table3.addEventListener('mouseout', this.handleMouseOut);
|
|
426
437
|
|
|
427
438
|
// Ignored via go/ees005
|
|
428
439
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
429
|
-
this === null || this === void 0 ? void 0 : (_this$
|
|
440
|
+
this === null || this === void 0 ? void 0 : (_this$table4 = this.table) === null || _this$table4 === void 0 ? void 0 : _this$table4.addEventListener('mouseover', this.handleMouseOver);
|
|
430
441
|
if (this.wrapper) {
|
|
431
442
|
this.wrapperReisizeObserver = new ResizeObserver(entries => {
|
|
432
443
|
for (const entry of entries) {
|
|
@@ -474,7 +485,7 @@ class TableComponent extends React.Component {
|
|
|
474
485
|
eventDispatcher.on(stickyHeadersPluginKey.key, this.onStickyState);
|
|
475
486
|
}
|
|
476
487
|
componentWillUnmount() {
|
|
477
|
-
var _this$resizeObserver, _this$wrapperReisizeO, _this$
|
|
488
|
+
var _this$resizeObserver, _this$wrapperReisizeO, _this$table5, _this$table6, _this$table7;
|
|
478
489
|
const {
|
|
479
490
|
allowColumnResizing,
|
|
480
491
|
allowTableResizing,
|
|
@@ -523,15 +534,15 @@ class TableComponent extends React.Component {
|
|
|
523
534
|
|
|
524
535
|
// Ignored via go/ees005
|
|
525
536
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
526
|
-
this === null || this === void 0 ? void 0 : (_this$
|
|
537
|
+
this === null || this === void 0 ? void 0 : (_this$table5 = this.table) === null || _this$table5 === void 0 ? void 0 : _this$table5.removeEventListener('mouseenter', this.handleMouseEnter);
|
|
527
538
|
|
|
528
539
|
// Ignored via go/ees005
|
|
529
540
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
530
|
-
this === null || this === void 0 ? void 0 : (_this$
|
|
541
|
+
this === null || this === void 0 ? void 0 : (_this$table6 = this.table) === null || _this$table6 === void 0 ? void 0 : _this$table6.removeEventListener('mouseout', this.handleMouseOut);
|
|
531
542
|
|
|
532
543
|
// Ignored via go/ees005
|
|
533
544
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
534
|
-
this === null || this === void 0 ? void 0 : (_this$
|
|
545
|
+
this === null || this === void 0 ? void 0 : (_this$table7 = this.table) === null || _this$table7 === void 0 ? void 0 : _this$table7.removeEventListener('mouseover', this.handleMouseOver);
|
|
535
546
|
|
|
536
547
|
// Ignored via go/ees005
|
|
537
548
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -564,7 +575,7 @@ class TableComponent extends React.Component {
|
|
|
564
575
|
}
|
|
565
576
|
}
|
|
566
577
|
handleColgroupUpdates(force = false) {
|
|
567
|
-
var _this$containerWidth;
|
|
578
|
+
var _this$containerWidth, _this$containerWidth2;
|
|
568
579
|
const {
|
|
569
580
|
getNode,
|
|
570
581
|
containerWidth,
|
|
@@ -602,16 +613,20 @@ class TableComponent extends React.Component {
|
|
|
602
613
|
} = containerWidth;
|
|
603
614
|
const isLineLengthChanged = ((_this$containerWidth = this.containerWidth) === null || _this$containerWidth === void 0 ? void 0 : _this$containerWidth.lineLength) !== containerLineLength;
|
|
604
615
|
const isFullWidthModeAndLineLengthChanged = this.updateColGroupFromFullWidthChange && isLineLengthChanged;
|
|
605
|
-
const
|
|
616
|
+
const previousContainerWidth = (_this$containerWidth2 = this.containerWidth) === null || _this$containerWidth2 === void 0 ? void 0 : _this$containerWidth2.width;
|
|
617
|
+
const isFullPageEditor = !(options !== null && options !== void 0 && options.isCommentEditor) && !(options !== null && options !== void 0 && options.isChromelessEditor);
|
|
618
|
+
const isContainerResized = fg('platform_editor_table_scale_on_container_resize') && isFullPageEditor && !!previousContainerWidth && previousContainerWidth !== containerWidthValue && this.hasMeasuredColumnWidths();
|
|
619
|
+
const isWindowOrContainerResized = this.state.windowResized || isContainerResized;
|
|
620
|
+
const maybeScale = isTableSquashed || isTableWidthChanged || isTableResizedFullWidth && !(options !== null && options !== void 0 && options.isCommentEditor) || isNumberColumnChanged || isNumberOfColumnsChanged || isWindowOrContainerResized;
|
|
606
621
|
if (force || maybeScale || isFullWidthModeAndLineLengthChanged) {
|
|
607
|
-
var _this$
|
|
608
|
-
const isWidthChanged = ((_this$
|
|
622
|
+
var _this$containerWidth3, _this$props, _this$props$options3, _this$props$options4, _this$props$options5;
|
|
623
|
+
const isWidthChanged = ((_this$containerWidth3 = this.containerWidth) === null || _this$containerWidth3 === void 0 ? void 0 : _this$containerWidth3.width) !== containerWidthValue;
|
|
609
624
|
const wasTableResized = hasTableBeenResized(this.node);
|
|
610
625
|
const isTableResized = hasTableBeenResized(tableNode);
|
|
611
626
|
const isColumnsDistributed = wasTableResized && !isTableResized;
|
|
612
627
|
const isTableDisplayModeChanged = this.node.attrs.displayMode !== tableNode.attrs.displayMode;
|
|
613
628
|
const shouldUpdateColgroup = this.shouldUpdateColgroup({
|
|
614
|
-
isWindowResized:
|
|
629
|
+
isWindowResized: isWindowOrContainerResized,
|
|
615
630
|
isWidthChanged,
|
|
616
631
|
isTableWidthChanged,
|
|
617
632
|
isColumnsDistributed,
|
|
@@ -742,14 +757,14 @@ class TableComponent extends React.Component {
|
|
|
742
757
|
} = this.props;
|
|
743
758
|
const shouldRecreateResizeCols = !allowTableResizing || !isResizing || isNoOfColumnsChanged && isResizing;
|
|
744
759
|
if (shouldRecreateResizeCols) {
|
|
745
|
-
var _this$
|
|
760
|
+
var _this$table8, _this$props$options12, _this$props$options13;
|
|
746
761
|
const start = getPos() || 0;
|
|
747
762
|
const depth = view.state.doc.resolve(start).depth;
|
|
748
763
|
shouldScale = depth === 0 && shouldScale;
|
|
749
764
|
insertColgroupFromNode(this.table, currentTable, shouldScale, undefined, shouldUseIncreasedScalingPercent, options === null || options === void 0 ? void 0 : options.isCommentEditor);
|
|
750
765
|
|
|
751
766
|
// Deferred from setDomAttrs — remove only once colgroup is updated and table has left content mode.
|
|
752
|
-
if ((_this$
|
|
767
|
+
if ((_this$table8 = this.table) !== null && _this$table8 !== void 0 && _this$table8.hasAttribute('data-initial-width-mode') && !isTableInContentMode({
|
|
753
768
|
tableNode: currentTable,
|
|
754
769
|
isSupported: isContentModeSupported({
|
|
755
770
|
allowColumnResizing: !!allowColumnResizing,
|
|
@@ -15,6 +15,7 @@ import { getTop, getTree } from '../pm-plugins/utils/dom';
|
|
|
15
15
|
import { getTableRowIndex, supportedHeaderRow } from '../pm-plugins/utils/nodes';
|
|
16
16
|
import { TableCssClassName as ClassName, TableCssClassName } from '../types';
|
|
17
17
|
import { stickyHeaderBorderBottomWidth, stickyRowOffsetTop, tableControlsSpacing, tableScrollbarOffset } from '../ui/consts';
|
|
18
|
+
import { FocusOnlyUpdateGuard } from './is-focus-only-change';
|
|
18
19
|
import TableNodeView from './TableNodeViewBase';
|
|
19
20
|
// limit scroll event calls
|
|
20
21
|
const HEADER_ROW_SCROLL_THROTTLE_TIMEOUT = 200;
|
|
@@ -41,6 +42,7 @@ export default class TableRow extends TableNodeView {
|
|
|
41
42
|
});
|
|
42
43
|
_defineProperty(this, "colControlsOffset", 0);
|
|
43
44
|
_defineProperty(this, "focused", false);
|
|
45
|
+
_defineProperty(this, "focusOnlyUpdateGuard", new FocusOnlyUpdateGuard());
|
|
44
46
|
_defineProperty(this, "topPosEditorElement", 0);
|
|
45
47
|
_defineProperty(this, "sentinels", {});
|
|
46
48
|
_defineProperty(this, "sentinelData", {
|
|
@@ -247,6 +249,8 @@ export default class TableRow extends TableNodeView {
|
|
|
247
249
|
return true;
|
|
248
250
|
}
|
|
249
251
|
subscribe() {
|
|
252
|
+
this.focusOnlyUpdateGuard.reset();
|
|
253
|
+
|
|
250
254
|
// Ignored via go/ees005
|
|
251
255
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
252
256
|
this.editorScrollableElement = findOverflowScrollParent(this.view.dom) || window;
|
|
@@ -280,6 +284,7 @@ export default class TableRow extends TableNodeView {
|
|
|
280
284
|
});
|
|
281
285
|
}
|
|
282
286
|
unsubscribe() {
|
|
287
|
+
this.focusOnlyUpdateGuard.reset();
|
|
283
288
|
if (!this.listening) {
|
|
284
289
|
return;
|
|
285
290
|
}
|
|
@@ -578,11 +583,15 @@ export default class TableRow extends TableNodeView {
|
|
|
578
583
|
/* receive external events */
|
|
579
584
|
|
|
580
585
|
onTablePluginState(state) {
|
|
586
|
+
if (this.focusOnlyUpdateGuard.skipIfFocusOnly(state)) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
581
589
|
const tableRef = state.tableRef;
|
|
582
590
|
const tree = getTree(this.dom);
|
|
583
591
|
if (!tree) {
|
|
584
592
|
return;
|
|
585
593
|
}
|
|
594
|
+
this.focusOnlyUpdateGuard.markProcessed(state);
|
|
586
595
|
|
|
587
596
|
// when header rows are toggled off - mark sentinels as unobserved
|
|
588
597
|
if (!state.isHeaderRowEnabled) {
|
|
@@ -19,6 +19,7 @@ import { areAllRectsZero, getTop, getTree } from '../pm-plugins/utils/dom';
|
|
|
19
19
|
import { getTableRowIndex, supportedHeaderRow } from '../pm-plugins/utils/nodes';
|
|
20
20
|
import { TableCssClassName as ClassName, TableCssClassName } from '../types';
|
|
21
21
|
import { stickyHeaderBorderBottomWidth, stickyRowOffsetTop, tableControlsSpacing, tableScrollbarOffset } from '../ui/consts';
|
|
22
|
+
import { FocusOnlyUpdateGuard } from './is-focus-only-change';
|
|
22
23
|
import TableNodeView from './TableNodeViewBase';
|
|
23
24
|
// limit scroll event calls
|
|
24
25
|
const HEADER_ROW_SCROLL_THROTTLE_TIMEOUT = 200;
|
|
@@ -47,6 +48,7 @@ export default class TableRowNativeStickyWithFallback extends TableNodeView {
|
|
|
47
48
|
});
|
|
48
49
|
_defineProperty(this, "colControlsOffset", 0);
|
|
49
50
|
_defineProperty(this, "focused", false);
|
|
51
|
+
_defineProperty(this, "focusOnlyUpdateGuard", new FocusOnlyUpdateGuard());
|
|
50
52
|
_defineProperty(this, "topPosEditorElement", 0);
|
|
51
53
|
_defineProperty(this, "sentinels", {});
|
|
52
54
|
_defineProperty(this, "sentinelData", {
|
|
@@ -296,6 +298,8 @@ export default class TableRowNativeStickyWithFallback extends TableNodeView {
|
|
|
296
298
|
return true;
|
|
297
299
|
}
|
|
298
300
|
subscribe() {
|
|
301
|
+
this.focusOnlyUpdateGuard.reset();
|
|
302
|
+
|
|
299
303
|
// Ignored via go/ees005
|
|
300
304
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
301
305
|
this.editorScrollableElement = findOverflowScrollParent(this.view.dom) || window;
|
|
@@ -371,6 +375,7 @@ export default class TableRowNativeStickyWithFallback extends TableNodeView {
|
|
|
371
375
|
});
|
|
372
376
|
}
|
|
373
377
|
unsubscribe() {
|
|
378
|
+
this.focusOnlyUpdateGuard.reset();
|
|
374
379
|
if (!this.listening) {
|
|
375
380
|
return;
|
|
376
381
|
}
|
|
@@ -809,11 +814,15 @@ export default class TableRowNativeStickyWithFallback extends TableNodeView {
|
|
|
809
814
|
/* receive external events */
|
|
810
815
|
|
|
811
816
|
onTablePluginState(state) {
|
|
817
|
+
if (this.focusOnlyUpdateGuard.skipIfFocusOnly(state)) {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
812
820
|
const tableRef = state.tableRef;
|
|
813
821
|
const tree = getTree(this.dom);
|
|
814
822
|
if (!tree) {
|
|
815
823
|
return;
|
|
816
824
|
}
|
|
825
|
+
this.focusOnlyUpdateGuard.markProcessed(state);
|
|
817
826
|
|
|
818
827
|
// when header rows are toggled off - mark sentinels as unobserved
|
|
819
828
|
if (!state.isHeaderRowEnabled) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
2
|
+
export const shallowEqualExcept = (previousValue, currentValue, ignoredKey) => {
|
|
3
|
+
const previousKeys = Object.keys(previousValue);
|
|
4
|
+
const currentKeys = Object.keys(currentValue);
|
|
5
|
+
return previousKeys.length === currentKeys.length && currentKeys.every(key => key === ignoredKey || Object.prototype.hasOwnProperty.call(previousValue, key) && Object.is(previousValue[key], currentValue[key]));
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns true when editor focus is the only table plugin state value that changed.
|
|
10
|
+
*
|
|
11
|
+
* Table reducers preserve references for unchanged values. If a reducer rebuilds a value, this
|
|
12
|
+
* returns false and callers take the original full-work path rather than skipping incorrectly.
|
|
13
|
+
*/
|
|
14
|
+
export const isFocusOnlyChange = (previousState, currentState) => previousState.editorHasFocus !== currentState.editorHasFocus && shallowEqualExcept(previousState, currentState, 'editorHasFocus');
|
|
15
|
+
export class FocusOnlyUpdateGuard {
|
|
16
|
+
/** Returns true and records the state when this is a skippable focus-only update. */
|
|
17
|
+
skipIfFocusOnly(state) {
|
|
18
|
+
const lastProcessedState = this.lastProcessedState;
|
|
19
|
+
if (lastProcessedState !== undefined && isFocusOnlyChange(lastProcessedState, state) && isExperimentEnabled('platform_editor_improve_inp')) {
|
|
20
|
+
this.lastProcessedState = state;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
markProcessed(state) {
|
|
26
|
+
this.lastProcessedState = state;
|
|
27
|
+
}
|
|
28
|
+
reset() {
|
|
29
|
+
this.lastProcessedState = undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -16,6 +16,7 @@ import { removeTable } from '@atlaskit/editor-tables/utils/remove-table';
|
|
|
16
16
|
import { selectColumns as selectColumnsTransform, selectColumn as selectColumnTransform, selectRows as selectRowsTransform, selectRow as selectRowTransform } from '@atlaskit/editor-tables/utils/select-nodes';
|
|
17
17
|
import { selectionCell } from '@atlaskit/editor-tables/utils/selection-cell';
|
|
18
18
|
import { setCellAttrs } from '@atlaskit/editor-tables/utils/set-cell-attrs';
|
|
19
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
19
20
|
import { TableCssClassName as ClassName, TableDecorations } from '../../types';
|
|
20
21
|
import { getDecorations } from '../decorations/plugin';
|
|
21
22
|
import { buildColumnResizingDecorations, clearColumnResizingDecorations } from '../decorations/utils/column-resizing';
|
|
@@ -42,11 +43,17 @@ const selectColumnWithMergedEdgeRows = (tr, column, expand) => {
|
|
|
42
43
|
}
|
|
43
44
|
return transformedTr.setSelection(new CellSelection(transformedTr.doc.resolve(lastCell.pos), transformedTr.doc.resolve(firstCell.pos)));
|
|
44
45
|
};
|
|
45
|
-
export const setEditorFocus = editorHasFocus => createCommand({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
export const setEditorFocus = editorHasFocus => createCommand(state => {
|
|
47
|
+
const pluginState = getPluginState(state);
|
|
48
|
+
if (pluginState.editorHasFocus === editorHasFocus && isExperimentEnabled('platform_editor_improve_inp')) {
|
|
49
|
+
return false;
|
|
49
50
|
}
|
|
51
|
+
return {
|
|
52
|
+
type: 'SET_EDITOR_FOCUS',
|
|
53
|
+
data: {
|
|
54
|
+
editorHasFocus
|
|
55
|
+
}
|
|
56
|
+
};
|
|
50
57
|
});
|
|
51
58
|
export const setTableRef = ref => createCommand(state => {
|
|
52
59
|
const tableRef = ref;
|
|
@@ -18,6 +18,25 @@ import { TableCssClassName as ClassName } from '../../types';
|
|
|
18
18
|
import { getTableZIndexes } from '../sticky-header-z-index';
|
|
19
19
|
import getPopupOptions from './getPopupOptions';
|
|
20
20
|
import { DragAndDropInsertButton } from './InsertButton';
|
|
21
|
+
/**
|
|
22
|
+
* Distance from the table top to the top of the row containing `cell`, summed from row heights.
|
|
23
|
+
* Viewport rects cannot be used: a stuck header row is fixed to the viewport while the table scrolls.
|
|
24
|
+
*/
|
|
25
|
+
const getRowOffsetFromTableTop = (cell, table) => {
|
|
26
|
+
const anchorRow = closestElement(cell, 'tr');
|
|
27
|
+
if (!(table instanceof HTMLTableElement) || !anchorRow) {
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
let offset = 0;
|
|
31
|
+
for (const row of table.rows) {
|
|
32
|
+
if (row === anchorRow) {
|
|
33
|
+
return offset;
|
|
34
|
+
}
|
|
35
|
+
offset += row.offsetHeight;
|
|
36
|
+
}
|
|
37
|
+
return 0;
|
|
38
|
+
};
|
|
39
|
+
|
|
21
40
|
// Ignored via go/ees005
|
|
22
41
|
// eslint-disable-next-line @repo/internal/react/no-class-components, @typescript-eslint/no-explicit-any
|
|
23
42
|
export class FloatingInsertButton extends React.Component {
|
|
@@ -127,7 +146,11 @@ export class FloatingInsertButton extends React.Component {
|
|
|
127
146
|
// ↑ button should render at row 0/table top
|
|
128
147
|
let verticalOffsetCorrection = 0;
|
|
129
148
|
if (type === 'column' && expValEquals('platform_editor_table_menu_updates', 'isEnabled', true)) {
|
|
130
|
-
|
|
149
|
+
if (isExperimentEnabled('platform_editor_sticky_header_insert_column_exp')) {
|
|
150
|
+
verticalOffsetCorrection = getRowOffsetFromTableTop(targetCellRef, tableRef);
|
|
151
|
+
} else {
|
|
152
|
+
verticalOffsetCorrection = Math.max(0, targetCellRef.getBoundingClientRect().top - tableRef.getBoundingClientRect().top);
|
|
153
|
+
}
|
|
131
154
|
}
|
|
132
155
|
// Preserve the original popup placement: overflow row inserts and column inserts
|
|
133
156
|
// sit above the header; other row inserts sit below it.
|
|
@@ -55,6 +55,7 @@ import { TableStickyScrollbar } from './TableStickyScrollbar';
|
|
|
55
55
|
// Prevent unnecessary parentWidth updates when table is nested inside of a node that is nested itself.
|
|
56
56
|
var NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MIN_THRESHOLD = 2;
|
|
57
57
|
var NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MAX_THRESHOLD = 20;
|
|
58
|
+
var MEASURED_COLUMN_WIDTH = /^[\.0-9]+px$/;
|
|
58
59
|
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
59
60
|
var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
60
61
|
function TableComponent(props) {
|
|
@@ -330,6 +331,16 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
330
331
|
_defineProperty(_this, "tableNodeLayoutSize", function (node, containerWidth, options) {
|
|
331
332
|
return getLayoutSize(node.attrs.layout, containerWidth || _this.props.containerWidth.width, options || _this.props.options || {});
|
|
332
333
|
});
|
|
334
|
+
/**
|
|
335
|
+
* Full-page tables scale with their container through CSS `calc()` column widths. Once a
|
|
336
|
+
* colgroup has been rewritten with measured px widths (column resize, collab, column add or
|
|
337
|
+
* delete, window resize), CSS can no longer scale it and the colgroup must be updated in JS.
|
|
338
|
+
*/
|
|
339
|
+
_defineProperty(_this, "hasMeasuredColumnWidths", function () {
|
|
340
|
+
var _this$table;
|
|
341
|
+
var firstColumn = (_this$table = _this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(':scope > colgroup > col');
|
|
342
|
+
return !!firstColumn && MEASURED_COLUMN_WIDTH.test(firstColumn.style.width);
|
|
343
|
+
});
|
|
333
344
|
_defineProperty(_this, "shouldUpdateColgroup", function (params) {
|
|
334
345
|
var _this$props$options, _this$props$options2;
|
|
335
346
|
var isWindowResized = params.isWindowResized,
|
|
@@ -423,9 +434,9 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
423
434
|
}, {
|
|
424
435
|
key: "initialiseEventListenersAfterMount",
|
|
425
436
|
value: function initialiseEventListenersAfterMount() {
|
|
426
|
-
var _this$
|
|
427
|
-
_this$table2,
|
|
437
|
+
var _this$table2,
|
|
428
438
|
_this$table3,
|
|
439
|
+
_this$table4,
|
|
429
440
|
_this3 = this;
|
|
430
441
|
var _this$props6 = this.props,
|
|
431
442
|
allowColumnResizing = _this$props6.allowColumnResizing,
|
|
@@ -438,15 +449,15 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
438
449
|
|
|
439
450
|
// Ignored via go/ees005
|
|
440
451
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
441
|
-
this === null || this === void 0 || (_this$
|
|
452
|
+
this === null || this === void 0 || (_this$table2 = this.table) === null || _this$table2 === void 0 || _this$table2.addEventListener('mouseenter', this.handleMouseEnter);
|
|
442
453
|
|
|
443
454
|
// Ignored via go/ees005
|
|
444
455
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
445
|
-
this === null || this === void 0 || (_this$
|
|
456
|
+
this === null || this === void 0 || (_this$table3 = this.table) === null || _this$table3 === void 0 || _this$table3.addEventListener('mouseout', this.handleMouseOut);
|
|
446
457
|
|
|
447
458
|
// Ignored via go/ees005
|
|
448
459
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
449
|
-
this === null || this === void 0 || (_this$
|
|
460
|
+
this === null || this === void 0 || (_this$table4 = this.table) === null || _this$table4 === void 0 || _this$table4.addEventListener('mouseover', this.handleMouseOver);
|
|
450
461
|
if (this.wrapper) {
|
|
451
462
|
this.wrapperReisizeObserver = new ResizeObserver(function (entries) {
|
|
452
463
|
var _iterator2 = _createForOfIteratorHelper(entries),
|
|
@@ -505,7 +516,7 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
505
516
|
}, {
|
|
506
517
|
key: "componentWillUnmount",
|
|
507
518
|
value: function componentWillUnmount() {
|
|
508
|
-
var _this$resizeObserver, _this$wrapperReisizeO, _this$
|
|
519
|
+
var _this$resizeObserver, _this$wrapperReisizeO, _this$table5, _this$table6, _this$table7;
|
|
509
520
|
var _this$props7 = this.props,
|
|
510
521
|
allowColumnResizing = _this$props7.allowColumnResizing,
|
|
511
522
|
allowTableResizing = _this$props7.allowTableResizing,
|
|
@@ -553,15 +564,15 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
553
564
|
|
|
554
565
|
// Ignored via go/ees005
|
|
555
566
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
556
|
-
this === null || this === void 0 || (_this$
|
|
567
|
+
this === null || this === void 0 || (_this$table5 = this.table) === null || _this$table5 === void 0 || _this$table5.removeEventListener('mouseenter', this.handleMouseEnter);
|
|
557
568
|
|
|
558
569
|
// Ignored via go/ees005
|
|
559
570
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
560
|
-
this === null || this === void 0 || (_this$
|
|
571
|
+
this === null || this === void 0 || (_this$table6 = this.table) === null || _this$table6 === void 0 || _this$table6.removeEventListener('mouseout', this.handleMouseOut);
|
|
561
572
|
|
|
562
573
|
// Ignored via go/ees005
|
|
563
574
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
564
|
-
this === null || this === void 0 || (_this$
|
|
575
|
+
this === null || this === void 0 || (_this$table7 = this.table) === null || _this$table7 === void 0 || _this$table7.removeEventListener('mouseover', this.handleMouseOver);
|
|
565
576
|
|
|
566
577
|
// Ignored via go/ees005
|
|
567
578
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -599,6 +610,7 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
599
610
|
key: "handleColgroupUpdates",
|
|
600
611
|
value: function handleColgroupUpdates() {
|
|
601
612
|
var _this$containerWidth,
|
|
613
|
+
_this$containerWidth2,
|
|
602
614
|
_this4 = this;
|
|
603
615
|
var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
604
616
|
var _this$props9 = this.props,
|
|
@@ -635,16 +647,20 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
635
647
|
containerLineLength = containerWidth.lineLength;
|
|
636
648
|
var isLineLengthChanged = ((_this$containerWidth = this.containerWidth) === null || _this$containerWidth === void 0 ? void 0 : _this$containerWidth.lineLength) !== containerLineLength;
|
|
637
649
|
var isFullWidthModeAndLineLengthChanged = this.updateColGroupFromFullWidthChange && isLineLengthChanged;
|
|
638
|
-
var
|
|
650
|
+
var previousContainerWidth = (_this$containerWidth2 = this.containerWidth) === null || _this$containerWidth2 === void 0 ? void 0 : _this$containerWidth2.width;
|
|
651
|
+
var isFullPageEditor = !(options !== null && options !== void 0 && options.isCommentEditor) && !(options !== null && options !== void 0 && options.isChromelessEditor);
|
|
652
|
+
var isContainerResized = fg('platform_editor_table_scale_on_container_resize') && isFullPageEditor && !!previousContainerWidth && previousContainerWidth !== containerWidthValue && this.hasMeasuredColumnWidths();
|
|
653
|
+
var isWindowOrContainerResized = this.state.windowResized || isContainerResized;
|
|
654
|
+
var maybeScale = isTableSquashed || isTableWidthChanged || isTableResizedFullWidth && !(options !== null && options !== void 0 && options.isCommentEditor) || isNumberColumnChanged || isNumberOfColumnsChanged || isWindowOrContainerResized;
|
|
639
655
|
if (force || maybeScale || isFullWidthModeAndLineLengthChanged) {
|
|
640
|
-
var _this$
|
|
641
|
-
var isWidthChanged = ((_this$
|
|
656
|
+
var _this$containerWidth3, _this$props0, _this$props$options3, _this$props$options4, _this$props$options5;
|
|
657
|
+
var isWidthChanged = ((_this$containerWidth3 = this.containerWidth) === null || _this$containerWidth3 === void 0 ? void 0 : _this$containerWidth3.width) !== containerWidthValue;
|
|
642
658
|
var wasTableResized = hasTableBeenResized(this.node);
|
|
643
659
|
var isTableResized = hasTableBeenResized(tableNode);
|
|
644
660
|
var isColumnsDistributed = wasTableResized && !isTableResized;
|
|
645
661
|
var isTableDisplayModeChanged = this.node.attrs.displayMode !== tableNode.attrs.displayMode;
|
|
646
662
|
var shouldUpdateColgroup = this.shouldUpdateColgroup({
|
|
647
|
-
isWindowResized:
|
|
663
|
+
isWindowResized: isWindowOrContainerResized,
|
|
648
664
|
isWidthChanged: isWidthChanged,
|
|
649
665
|
isTableWidthChanged: isTableWidthChanged,
|
|
650
666
|
isColumnsDistributed: isColumnsDistributed,
|
|
@@ -773,14 +789,14 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
|
|
|
773
789
|
var view = this.props.view;
|
|
774
790
|
var shouldRecreateResizeCols = !allowTableResizing || !isResizing || isNoOfColumnsChanged && isResizing;
|
|
775
791
|
if (shouldRecreateResizeCols) {
|
|
776
|
-
var _this$
|
|
792
|
+
var _this$table8, _this$props$options10, _this$props$options11;
|
|
777
793
|
var start = getPos() || 0;
|
|
778
794
|
var depth = view.state.doc.resolve(start).depth;
|
|
779
795
|
shouldScale = depth === 0 && shouldScale;
|
|
780
796
|
insertColgroupFromNode(this.table, currentTable, shouldScale, undefined, shouldUseIncreasedScalingPercent, options === null || options === void 0 ? void 0 : options.isCommentEditor);
|
|
781
797
|
|
|
782
798
|
// Deferred from setDomAttrs — remove only once colgroup is updated and table has left content mode.
|
|
783
|
-
if ((_this$
|
|
799
|
+
if ((_this$table8 = this.table) !== null && _this$table8 !== void 0 && _this$table8.hasAttribute('data-initial-width-mode') && !isTableInContentMode({
|
|
784
800
|
tableNode: currentTable,
|
|
785
801
|
isSupported: isContentModeSupported({
|
|
786
802
|
allowColumnResizing: !!allowColumnResizing,
|
|
@@ -22,6 +22,7 @@ import { getTop, getTree } from '../pm-plugins/utils/dom';
|
|
|
22
22
|
import { getTableRowIndex, supportedHeaderRow } from '../pm-plugins/utils/nodes';
|
|
23
23
|
import { TableCssClassName as ClassName, TableCssClassName } from '../types';
|
|
24
24
|
import { stickyHeaderBorderBottomWidth, stickyRowOffsetTop, tableControlsSpacing, tableScrollbarOffset } from '../ui/consts';
|
|
25
|
+
import { FocusOnlyUpdateGuard } from './is-focus-only-change';
|
|
25
26
|
import TableNodeView from './TableNodeViewBase';
|
|
26
27
|
// limit scroll event calls
|
|
27
28
|
var HEADER_ROW_SCROLL_THROTTLE_TIMEOUT = 200;
|
|
@@ -50,6 +51,7 @@ var TableRow = /*#__PURE__*/function (_TableNodeView) {
|
|
|
50
51
|
});
|
|
51
52
|
_defineProperty(_this, "colControlsOffset", 0);
|
|
52
53
|
_defineProperty(_this, "focused", false);
|
|
54
|
+
_defineProperty(_this, "focusOnlyUpdateGuard", new FocusOnlyUpdateGuard());
|
|
53
55
|
_defineProperty(_this, "topPosEditorElement", 0);
|
|
54
56
|
_defineProperty(_this, "sentinels", {});
|
|
55
57
|
_defineProperty(_this, "sentinelData", {
|
|
@@ -271,6 +273,8 @@ var TableRow = /*#__PURE__*/function (_TableNodeView) {
|
|
|
271
273
|
}, {
|
|
272
274
|
key: "subscribe",
|
|
273
275
|
value: function subscribe() {
|
|
276
|
+
this.focusOnlyUpdateGuard.reset();
|
|
277
|
+
|
|
274
278
|
// Ignored via go/ees005
|
|
275
279
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
276
280
|
this.editorScrollableElement = findOverflowScrollParent(this.view.dom) || window;
|
|
@@ -306,6 +310,7 @@ var TableRow = /*#__PURE__*/function (_TableNodeView) {
|
|
|
306
310
|
}, {
|
|
307
311
|
key: "unsubscribe",
|
|
308
312
|
value: function unsubscribe() {
|
|
313
|
+
this.focusOnlyUpdateGuard.reset();
|
|
309
314
|
if (!this.listening) {
|
|
310
315
|
return;
|
|
311
316
|
}
|
|
@@ -617,11 +622,15 @@ var TableRow = /*#__PURE__*/function (_TableNodeView) {
|
|
|
617
622
|
}, {
|
|
618
623
|
key: "onTablePluginState",
|
|
619
624
|
value: function onTablePluginState(state) {
|
|
625
|
+
if (this.focusOnlyUpdateGuard.skipIfFocusOnly(state)) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
620
628
|
var tableRef = state.tableRef;
|
|
621
629
|
var tree = getTree(this.dom);
|
|
622
630
|
if (!tree) {
|
|
623
631
|
return;
|
|
624
632
|
}
|
|
633
|
+
this.focusOnlyUpdateGuard.markProcessed(state);
|
|
625
634
|
|
|
626
635
|
// when header rows are toggled off - mark sentinels as unobserved
|
|
627
636
|
if (!state.isHeaderRowEnabled) {
|
|
@@ -26,6 +26,7 @@ import { areAllRectsZero, getTop, getTree } from '../pm-plugins/utils/dom';
|
|
|
26
26
|
import { getTableRowIndex, supportedHeaderRow } from '../pm-plugins/utils/nodes';
|
|
27
27
|
import { TableCssClassName as ClassName, TableCssClassName } from '../types';
|
|
28
28
|
import { stickyHeaderBorderBottomWidth, stickyRowOffsetTop, tableControlsSpacing, tableScrollbarOffset } from '../ui/consts';
|
|
29
|
+
import { FocusOnlyUpdateGuard } from './is-focus-only-change';
|
|
29
30
|
import TableNodeView from './TableNodeViewBase';
|
|
30
31
|
// limit scroll event calls
|
|
31
32
|
var HEADER_ROW_SCROLL_THROTTLE_TIMEOUT = 200;
|
|
@@ -56,6 +57,7 @@ var TableRowNativeStickyWithFallback = /*#__PURE__*/function (_TableNodeView) {
|
|
|
56
57
|
});
|
|
57
58
|
_defineProperty(_this, "colControlsOffset", 0);
|
|
58
59
|
_defineProperty(_this, "focused", false);
|
|
60
|
+
_defineProperty(_this, "focusOnlyUpdateGuard", new FocusOnlyUpdateGuard());
|
|
59
61
|
_defineProperty(_this, "topPosEditorElement", 0);
|
|
60
62
|
_defineProperty(_this, "sentinels", {});
|
|
61
63
|
_defineProperty(_this, "sentinelData", {
|
|
@@ -320,6 +322,8 @@ var TableRowNativeStickyWithFallback = /*#__PURE__*/function (_TableNodeView) {
|
|
|
320
322
|
key: "subscribe",
|
|
321
323
|
value: function subscribe() {
|
|
322
324
|
var _this4 = this;
|
|
325
|
+
this.focusOnlyUpdateGuard.reset();
|
|
326
|
+
|
|
323
327
|
// Ignored via go/ees005
|
|
324
328
|
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
325
329
|
this.editorScrollableElement = findOverflowScrollParent(this.view.dom) || window;
|
|
@@ -397,6 +401,7 @@ var TableRowNativeStickyWithFallback = /*#__PURE__*/function (_TableNodeView) {
|
|
|
397
401
|
}, {
|
|
398
402
|
key: "unsubscribe",
|
|
399
403
|
value: function unsubscribe() {
|
|
404
|
+
this.focusOnlyUpdateGuard.reset();
|
|
400
405
|
if (!this.listening) {
|
|
401
406
|
return;
|
|
402
407
|
}
|
|
@@ -857,11 +862,15 @@ var TableRowNativeStickyWithFallback = /*#__PURE__*/function (_TableNodeView) {
|
|
|
857
862
|
}, {
|
|
858
863
|
key: "onTablePluginState",
|
|
859
864
|
value: function onTablePluginState(state) {
|
|
865
|
+
if (this.focusOnlyUpdateGuard.skipIfFocusOnly(state)) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
860
868
|
var tableRef = state.tableRef;
|
|
861
869
|
var tree = getTree(this.dom);
|
|
862
870
|
if (!tree) {
|
|
863
871
|
return;
|
|
864
872
|
}
|
|
873
|
+
this.focusOnlyUpdateGuard.markProcessed(state);
|
|
865
874
|
|
|
866
875
|
// when header rows are toggled off - mark sentinels as unobserved
|
|
867
876
|
if (!state.isHeaderRowEnabled) {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
4
|
+
export var shallowEqualExcept = function shallowEqualExcept(previousValue, currentValue, ignoredKey) {
|
|
5
|
+
var previousKeys = Object.keys(previousValue);
|
|
6
|
+
var currentKeys = Object.keys(currentValue);
|
|
7
|
+
return previousKeys.length === currentKeys.length && currentKeys.every(function (key) {
|
|
8
|
+
return key === ignoredKey || Object.prototype.hasOwnProperty.call(previousValue, key) && Object.is(previousValue[key], currentValue[key]);
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns true when editor focus is the only table plugin state value that changed.
|
|
14
|
+
*
|
|
15
|
+
* Table reducers preserve references for unchanged values. If a reducer rebuilds a value, this
|
|
16
|
+
* returns false and callers take the original full-work path rather than skipping incorrectly.
|
|
17
|
+
*/
|
|
18
|
+
export var isFocusOnlyChange = function isFocusOnlyChange(previousState, currentState) {
|
|
19
|
+
return previousState.editorHasFocus !== currentState.editorHasFocus && shallowEqualExcept(previousState, currentState, 'editorHasFocus');
|
|
20
|
+
};
|
|
21
|
+
export var FocusOnlyUpdateGuard = /*#__PURE__*/function () {
|
|
22
|
+
function FocusOnlyUpdateGuard() {
|
|
23
|
+
_classCallCheck(this, FocusOnlyUpdateGuard);
|
|
24
|
+
}
|
|
25
|
+
return _createClass(FocusOnlyUpdateGuard, [{
|
|
26
|
+
key: "skipIfFocusOnly",
|
|
27
|
+
value: /** Returns true and records the state when this is a skippable focus-only update. */
|
|
28
|
+
function skipIfFocusOnly(state) {
|
|
29
|
+
var lastProcessedState = this.lastProcessedState;
|
|
30
|
+
if (lastProcessedState !== undefined && isFocusOnlyChange(lastProcessedState, state) && isExperimentEnabled('platform_editor_improve_inp')) {
|
|
31
|
+
this.lastProcessedState = state;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}, {
|
|
37
|
+
key: "markProcessed",
|
|
38
|
+
value: function markProcessed(state) {
|
|
39
|
+
this.lastProcessedState = state;
|
|
40
|
+
}
|
|
41
|
+
}, {
|
|
42
|
+
key: "reset",
|
|
43
|
+
value: function reset() {
|
|
44
|
+
this.lastProcessedState = undefined;
|
|
45
|
+
}
|
|
46
|
+
}]);
|
|
47
|
+
}();
|
|
@@ -20,6 +20,7 @@ import { removeTable } from '@atlaskit/editor-tables/utils/remove-table';
|
|
|
20
20
|
import { selectColumns as selectColumnsTransform, selectColumn as selectColumnTransform, selectRows as selectRowsTransform, selectRow as selectRowTransform } from '@atlaskit/editor-tables/utils/select-nodes';
|
|
21
21
|
import { selectionCell } from '@atlaskit/editor-tables/utils/selection-cell';
|
|
22
22
|
import { setCellAttrs } from '@atlaskit/editor-tables/utils/set-cell-attrs';
|
|
23
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
23
24
|
import { TableCssClassName as ClassName, TableDecorations } from '../../types';
|
|
24
25
|
import { getDecorations } from '../decorations/plugin';
|
|
25
26
|
import { buildColumnResizingDecorations, clearColumnResizingDecorations } from '../decorations/utils/column-resizing';
|
|
@@ -48,11 +49,17 @@ var selectColumnWithMergedEdgeRows = function selectColumnWithMergedEdgeRows(tr,
|
|
|
48
49
|
return transformedTr.setSelection(new CellSelection(transformedTr.doc.resolve(lastCell.pos), transformedTr.doc.resolve(firstCell.pos)));
|
|
49
50
|
};
|
|
50
51
|
export var setEditorFocus = function setEditorFocus(editorHasFocus) {
|
|
51
|
-
return createCommand({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
return createCommand(function (state) {
|
|
53
|
+
var pluginState = getPluginState(state);
|
|
54
|
+
if (pluginState.editorHasFocus === editorHasFocus && isExperimentEnabled('platform_editor_improve_inp')) {
|
|
55
|
+
return false;
|
|
55
56
|
}
|
|
57
|
+
return {
|
|
58
|
+
type: 'SET_EDITOR_FOCUS',
|
|
59
|
+
data: {
|
|
60
|
+
editorHasFocus: editorHasFocus
|
|
61
|
+
}
|
|
62
|
+
};
|
|
56
63
|
});
|
|
57
64
|
};
|
|
58
65
|
export var setTableRef = function setTableRef(ref) {
|
|
@@ -7,6 +7,9 @@ import _inherits from "@babel/runtime/helpers/inherits";
|
|
|
7
7
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
8
8
|
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
9
9
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
10
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
11
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
12
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
10
13
|
import React from 'react';
|
|
11
14
|
import { injectIntl } from 'react-intl';
|
|
12
15
|
import { ACTION, ACTION_SUBJECT, CONTENT_COMPONENT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics/types/enums';
|
|
@@ -25,6 +28,34 @@ import { TableCssClassName as ClassName } from '../../types';
|
|
|
25
28
|
import { getTableZIndexes } from '../sticky-header-z-index';
|
|
26
29
|
import getPopupOptions from './getPopupOptions';
|
|
27
30
|
import { DragAndDropInsertButton } from './InsertButton';
|
|
31
|
+
/**
|
|
32
|
+
* Distance from the table top to the top of the row containing `cell`, summed from row heights.
|
|
33
|
+
* Viewport rects cannot be used: a stuck header row is fixed to the viewport while the table scrolls.
|
|
34
|
+
*/
|
|
35
|
+
var getRowOffsetFromTableTop = function getRowOffsetFromTableTop(cell, table) {
|
|
36
|
+
var anchorRow = closestElement(cell, 'tr');
|
|
37
|
+
if (!(table instanceof HTMLTableElement) || !anchorRow) {
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
var offset = 0;
|
|
41
|
+
var _iterator = _createForOfIteratorHelper(table.rows),
|
|
42
|
+
_step;
|
|
43
|
+
try {
|
|
44
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
45
|
+
var row = _step.value;
|
|
46
|
+
if (row === anchorRow) {
|
|
47
|
+
return offset;
|
|
48
|
+
}
|
|
49
|
+
offset += row.offsetHeight;
|
|
50
|
+
}
|
|
51
|
+
} catch (err) {
|
|
52
|
+
_iterator.e(err);
|
|
53
|
+
} finally {
|
|
54
|
+
_iterator.f();
|
|
55
|
+
}
|
|
56
|
+
return 0;
|
|
57
|
+
};
|
|
58
|
+
|
|
28
59
|
// Ignored via go/ees005
|
|
29
60
|
// eslint-disable-next-line @repo/internal/react/no-class-components, @typescript-eslint/no-explicit-any
|
|
30
61
|
export var FloatingInsertButton = /*#__PURE__*/function (_React$Component) {
|
|
@@ -135,7 +166,11 @@ export var FloatingInsertButton = /*#__PURE__*/function (_React$Component) {
|
|
|
135
166
|
// ↑ button should render at row 0/table top
|
|
136
167
|
var verticalOffsetCorrection = 0;
|
|
137
168
|
if (type === 'column' && expValEquals('platform_editor_table_menu_updates', 'isEnabled', true)) {
|
|
138
|
-
|
|
169
|
+
if (isExperimentEnabled('platform_editor_sticky_header_insert_column_exp')) {
|
|
170
|
+
verticalOffsetCorrection = getRowOffsetFromTableTop(targetCellRef, tableRef);
|
|
171
|
+
} else {
|
|
172
|
+
verticalOffsetCorrection = Math.max(0, targetCellRef.getBoundingClientRect().top - tableRef.getBoundingClientRect().top);
|
|
173
|
+
}
|
|
139
174
|
}
|
|
140
175
|
// Preserve the original popup placement: overflow row inserts and column inserts
|
|
141
176
|
// sit above the header; other row inserts sit below it.
|
|
@@ -18,6 +18,7 @@ export default class TableRow extends TableNodeView<HTMLTableRowElement> impleme
|
|
|
18
18
|
private editorScrollableElement?;
|
|
19
19
|
private colControlsOffset;
|
|
20
20
|
private focused;
|
|
21
|
+
private readonly focusOnlyUpdateGuard;
|
|
21
22
|
private topPosEditorElement;
|
|
22
23
|
private isSticky;
|
|
23
24
|
private intersectionObserver?;
|
|
@@ -18,6 +18,7 @@ export default class TableRowNativeStickyWithFallback extends TableNodeView<HTML
|
|
|
18
18
|
private editorScrollableElement?;
|
|
19
19
|
private colControlsOffset;
|
|
20
20
|
private focused;
|
|
21
|
+
private readonly focusOnlyUpdateGuard;
|
|
21
22
|
private topPosEditorElement;
|
|
22
23
|
private isLegacySticky;
|
|
23
24
|
private intersectionObserver?;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TablePluginState } from '../types';
|
|
2
|
+
export declare const shallowEqualExcept: <T extends object>(previousValue: T, currentValue: T, ignoredKey: keyof T) => boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Returns true when editor focus is the only table plugin state value that changed.
|
|
5
|
+
*
|
|
6
|
+
* Table reducers preserve references for unchanged values. If a reducer rebuilds a value, this
|
|
7
|
+
* returns false and callers take the original full-work path rather than skipping incorrectly.
|
|
8
|
+
*/
|
|
9
|
+
export declare const isFocusOnlyChange: (previousState: TablePluginState, currentState: TablePluginState) => boolean;
|
|
10
|
+
export declare class FocusOnlyUpdateGuard {
|
|
11
|
+
private lastProcessedState;
|
|
12
|
+
/** Returns true and records the state when this is a skippable focus-only update. */
|
|
13
|
+
skipIfFocusOnly(state: TablePluginState): boolean;
|
|
14
|
+
markProcessed(state: TablePluginState): void;
|
|
15
|
+
reset(): void;
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-table",
|
|
3
|
-
"version": "42.0
|
|
3
|
+
"version": "42.2.0",
|
|
4
4
|
"description": "Table plugin for the @atlaskit/editor",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^3.2.0",
|
|
54
54
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^3.0.0",
|
|
55
55
|
"@atlaskit/primitives": "^22.6.0",
|
|
56
|
-
"@atlaskit/tmp-editor-statsig": "^248.
|
|
56
|
+
"@atlaskit/tmp-editor-statsig": "^248.1.0",
|
|
57
57
|
"@atlaskit/toggle": "^17.3.0",
|
|
58
58
|
"@atlaskit/tokens": "^20.8.0",
|
|
59
59
|
"@atlaskit/tooltip": "^24.4.0",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"uuid": "^11.1.1"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@atlaskit/editor-common": "^134.
|
|
71
|
+
"@atlaskit/editor-common": "^134.2.0",
|
|
72
72
|
"react": "^18.2.0 || ^19.2.0",
|
|
73
73
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
74
74
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
@@ -99,6 +99,9 @@
|
|
|
99
99
|
"platform_editor_table_view_mode_scaling_fix": {
|
|
100
100
|
"type": "boolean"
|
|
101
101
|
},
|
|
102
|
+
"platform_editor_table_scale_on_container_resize": {
|
|
103
|
+
"type": "boolean"
|
|
104
|
+
},
|
|
102
105
|
"platform-dst-top-layer-tooltip": {
|
|
103
106
|
"type": "boolean"
|
|
104
107
|
}
|