@atlaskit/editor-plugin-table 12.2.6 → 12.2.7
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 +8 -0
- package/package.json +4 -4
- package/afm-cc/tsconfig.json +0 -123
- package/afm-dev-agents/tsconfig.json +0 -123
- package/afm-jira/tsconfig.json +0 -123
- package/afm-passionfruit/tsconfig.json +0 -123
- package/afm-post-office/tsconfig.json +0 -123
- package/afm-rovo-extension/tsconfig.json +0 -123
- package/afm-townsquare/tsconfig.json +0 -123
- package/afm-volt/tsconfig.json +0 -114
- package/build/tsconfig.json +0 -23
- package/docs/0-intro.tsx +0 -57
- package/src/index.ts +0 -21
- package/src/nodeviews/ExternalDropTargets.tsx +0 -91
- package/src/nodeviews/OverflowShadowsObserver.ts +0 -156
- package/src/nodeviews/TableCell.ts +0 -134
- package/src/nodeviews/TableComponent.tsx +0 -1590
- package/src/nodeviews/TableComponentWithSharedState.tsx +0 -278
- package/src/nodeviews/TableContainer.tsx +0 -926
- package/src/nodeviews/TableNodeViewBase.ts +0 -29
- package/src/nodeviews/TableResizer.tsx +0 -884
- package/src/nodeviews/TableRow.ts +0 -830
- package/src/nodeviews/TableStickyScrollbar.ts +0 -211
- package/src/nodeviews/__mocks__/OverflowShadowsObserver.ts +0 -15
- package/src/nodeviews/__mocks__/OverridableMock.ts +0 -26
- package/src/nodeviews/table-container-styles.ts +0 -9
- package/src/nodeviews/table-node-views.ts +0 -76
- package/src/nodeviews/table.tsx +0 -530
- package/src/nodeviews/toDOM.ts +0 -244
- package/src/nodeviews/types.ts +0 -36
- package/src/nodeviews/update-overflow-shadows.ts +0 -11
- package/src/pm-plugins/analytics/actions.ts +0 -21
- package/src/pm-plugins/analytics/commands.ts +0 -47
- package/src/pm-plugins/analytics/plugin-factory.ts +0 -9
- package/src/pm-plugins/analytics/plugin-key.ts +0 -5
- package/src/pm-plugins/analytics/plugin.ts +0 -80
- package/src/pm-plugins/analytics/reducer.ts +0 -27
- package/src/pm-plugins/analytics/types.ts +0 -20
- package/src/pm-plugins/analytics/utils/moved-event.ts +0 -51
- package/src/pm-plugins/commands/clear.ts +0 -43
- package/src/pm-plugins/commands/collapse.ts +0 -17
- package/src/pm-plugins/commands/column-resize.ts +0 -478
- package/src/pm-plugins/commands/commands-with-analytics.ts +0 -715
- package/src/pm-plugins/commands/delete.ts +0 -42
- package/src/pm-plugins/commands/display-mode.ts +0 -18
- package/src/pm-plugins/commands/go-to-next-cell.ts +0 -198
- package/src/pm-plugins/commands/hover.ts +0 -242
- package/src/pm-plugins/commands/index.ts +0 -51
- package/src/pm-plugins/commands/insert.ts +0 -438
- package/src/pm-plugins/commands/misc.ts +0 -811
- package/src/pm-plugins/commands/referentiality.ts +0 -15
- package/src/pm-plugins/commands/selection.ts +0 -537
- package/src/pm-plugins/commands/sort.ts +0 -102
- package/src/pm-plugins/commands/split-cell.ts +0 -28
- package/src/pm-plugins/commands/toggle.ts +0 -109
- package/src/pm-plugins/create-plugin-config.ts +0 -17
- package/src/pm-plugins/decorations/plugin.ts +0 -107
- package/src/pm-plugins/decorations/utils/column-controls.ts +0 -91
- package/src/pm-plugins/decorations/utils/column-resizing.ts +0 -71
- package/src/pm-plugins/decorations/utils/compose-decorations.ts +0 -9
- package/src/pm-plugins/decorations/utils/types.ts +0 -16
- package/src/pm-plugins/default-table-selection.ts +0 -14
- package/src/pm-plugins/drag-and-drop/actions.ts +0 -48
- package/src/pm-plugins/drag-and-drop/commands-with-analytics.ts +0 -222
- package/src/pm-plugins/drag-and-drop/commands.ts +0 -194
- package/src/pm-plugins/drag-and-drop/consts.ts +0 -7
- package/src/pm-plugins/drag-and-drop/plugin-factory.ts +0 -33
- package/src/pm-plugins/drag-and-drop/plugin-key.ts +0 -5
- package/src/pm-plugins/drag-and-drop/plugin.ts +0 -398
- package/src/pm-plugins/drag-and-drop/reducer.ts +0 -38
- package/src/pm-plugins/drag-and-drop/types.ts +0 -18
- package/src/pm-plugins/drag-and-drop/utils/autoscrollers.ts +0 -49
- package/src/pm-plugins/drag-and-drop/utils/getDragBehaviour.ts +0 -9
- package/src/pm-plugins/drag-and-drop/utils/monitor.ts +0 -73
- package/src/pm-plugins/handlers.ts +0 -161
- package/src/pm-plugins/keymap.ts +0 -436
- package/src/pm-plugins/main.ts +0 -433
- package/src/pm-plugins/plugin-factory.ts +0 -42
- package/src/pm-plugins/plugin-key.ts +0 -8
- package/src/pm-plugins/reducer.ts +0 -145
- package/src/pm-plugins/safari-delete-composition-text-issue-workaround.ts +0 -102
- package/src/pm-plugins/sticky-headers/commands.ts +0 -8
- package/src/pm-plugins/sticky-headers/plugin-key.ts +0 -5
- package/src/pm-plugins/sticky-headers/plugin-state.ts +0 -52
- package/src/pm-plugins/sticky-headers/plugin.ts +0 -12
- package/src/pm-plugins/sticky-headers/types.ts +0 -20
- package/src/pm-plugins/sticky-headers/util.ts +0 -18
- package/src/pm-plugins/table-analytics.ts +0 -100
- package/src/pm-plugins/table-local-id.ts +0 -213
- package/src/pm-plugins/table-resizing/commands.ts +0 -116
- package/src/pm-plugins/table-resizing/event-handlers.ts +0 -352
- package/src/pm-plugins/table-resizing/plugin-factory.ts +0 -29
- package/src/pm-plugins/table-resizing/plugin-key.ts +0 -5
- package/src/pm-plugins/table-resizing/plugin.ts +0 -94
- package/src/pm-plugins/table-resizing/reducer.ts +0 -37
- package/src/pm-plugins/table-resizing/utils/colgroup.ts +0 -306
- package/src/pm-plugins/table-resizing/utils/column-state.ts +0 -120
- package/src/pm-plugins/table-resizing/utils/consts.ts +0 -11
- package/src/pm-plugins/table-resizing/utils/content-width.ts +0 -118
- package/src/pm-plugins/table-resizing/utils/dom.ts +0 -132
- package/src/pm-plugins/table-resizing/utils/misc.ts +0 -282
- package/src/pm-plugins/table-resizing/utils/resize-column.ts +0 -34
- package/src/pm-plugins/table-resizing/utils/resize-logic.ts +0 -289
- package/src/pm-plugins/table-resizing/utils/resize-state.ts +0 -417
- package/src/pm-plugins/table-resizing/utils/scale-table.ts +0 -290
- package/src/pm-plugins/table-resizing/utils/types.ts +0 -25
- package/src/pm-plugins/table-resizing/utils/unit-to-number.ts +0 -1
- package/src/pm-plugins/table-selection-keymap.ts +0 -64
- package/src/pm-plugins/table-size-selector.ts +0 -39
- package/src/pm-plugins/table-width-in-comment-fix.ts +0 -113
- package/src/pm-plugins/table-width.ts +0 -153
- package/src/pm-plugins/transforms/column-width.ts +0 -249
- package/src/pm-plugins/transforms/delete-columns.ts +0 -281
- package/src/pm-plugins/transforms/delete-rows.ts +0 -154
- package/src/pm-plugins/transforms/fix-tables.ts +0 -249
- package/src/pm-plugins/transforms/merge.ts +0 -301
- package/src/pm-plugins/transforms/replace-table.ts +0 -38
- package/src/pm-plugins/transforms/split.ts +0 -90
- package/src/pm-plugins/utils/alignment.ts +0 -33
- package/src/pm-plugins/utils/analytics.ts +0 -238
- package/src/pm-plugins/utils/collapse.ts +0 -93
- package/src/pm-plugins/utils/column-controls.ts +0 -250
- package/src/pm-plugins/utils/create.ts +0 -64
- package/src/pm-plugins/utils/decoration.ts +0 -672
- package/src/pm-plugins/utils/dom.ts +0 -251
- package/src/pm-plugins/utils/drag-menu.tsx +0 -491
- package/src/pm-plugins/utils/get-allow-add-column-custom-step.ts +0 -10
- package/src/pm-plugins/utils/guidelines.ts +0 -30
- package/src/pm-plugins/utils/merged-cells.ts +0 -239
- package/src/pm-plugins/utils/nodes.ts +0 -162
- package/src/pm-plugins/utils/paste.ts +0 -386
- package/src/pm-plugins/utils/row-controls.ts +0 -211
- package/src/pm-plugins/utils/selection.ts +0 -17
- package/src/pm-plugins/utils/snapping.ts +0 -136
- package/src/pm-plugins/utils/table.ts +0 -60
- package/src/pm-plugins/utils/update-plugin-state-decorations.ts +0 -13
- package/src/pm-plugins/view-mode-sort/consts.ts +0 -3
- package/src/pm-plugins/view-mode-sort/index.ts +0 -291
- package/src/pm-plugins/view-mode-sort/plugin-key.ts +0 -7
- package/src/pm-plugins/view-mode-sort/types.ts +0 -23
- package/src/pm-plugins/view-mode-sort/utils.ts +0 -136
- package/src/tablePlugin.tsx +0 -971
- package/src/tablePluginType.ts +0 -102
- package/src/types/index.ts +0 -592
- package/src/ui/ColumnResizeWidget/index.tsx +0 -61
- package/src/ui/ContentComponent.tsx +0 -311
- package/src/ui/DragHandle/HandleIconComponent.tsx +0 -21
- package/src/ui/DragHandle/index.tsx +0 -391
- package/src/ui/DragPreview/index.tsx +0 -51
- package/src/ui/FloatingAlignmentButtons/FloatingAlignmentButtons.tsx +0 -59
- package/src/ui/FloatingContextualButton/FixedButton.tsx +0 -203
- package/src/ui/FloatingContextualButton/index.tsx +0 -168
- package/src/ui/FloatingContextualButton/styles.ts +0 -69
- package/src/ui/FloatingContextualMenu/ContextualMenu.tsx +0 -931
- package/src/ui/FloatingContextualMenu/index.tsx +0 -141
- package/src/ui/FloatingContextualMenu/styles.ts +0 -77
- package/src/ui/FloatingDeleteButton/DeleteButton.tsx +0 -54
- package/src/ui/FloatingDeleteButton/getPopUpOptions.ts +0 -65
- package/src/ui/FloatingDeleteButton/index.tsx +0 -383
- package/src/ui/FloatingDeleteButton/types.ts +0 -3
- package/src/ui/FloatingDragMenu/DragMenu.tsx +0 -668
- package/src/ui/FloatingDragMenu/DropdownMenu.tsx +0 -221
- package/src/ui/FloatingDragMenu/index.tsx +0 -136
- package/src/ui/FloatingDragMenu/styles.ts +0 -83
- package/src/ui/FloatingInsertButton/InsertButton.tsx +0 -263
- package/src/ui/FloatingInsertButton/getPopupOptions.ts +0 -131
- package/src/ui/FloatingInsertButton/index.tsx +0 -314
- package/src/ui/FloatingToolbarLabel/FloatingToolbarLabel.tsx +0 -31
- package/src/ui/SizeSelector/index.tsx +0 -74
- package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +0 -397
- package/src/ui/TableFloatingColumnControls/ColumnDropTargets/ColumnDropTarget.tsx +0 -105
- package/src/ui/TableFloatingColumnControls/ColumnDropTargets/index.tsx +0 -63
- package/src/ui/TableFloatingColumnControls/index.tsx +0 -151
- package/src/ui/TableFloatingControls/CornerControls/ClassicCornerControls.tsx +0 -106
- package/src/ui/TableFloatingControls/CornerControls/DragCornerControls.tsx +0 -143
- package/src/ui/TableFloatingControls/CornerControls/types.ts +0 -12
- package/src/ui/TableFloatingControls/FloatingControlsWithSelection.tsx +0 -88
- package/src/ui/TableFloatingControls/NumberColumn/index.tsx +0 -175
- package/src/ui/TableFloatingControls/RowControls/ClassicControls.tsx +0 -131
- package/src/ui/TableFloatingControls/RowControls/DragControls.tsx +0 -429
- package/src/ui/TableFloatingControls/RowDropTarget/index.tsx +0 -96
- package/src/ui/TableFloatingControls/index.tsx +0 -275
- package/src/ui/TableFullWidthLabel/index.tsx +0 -38
- package/src/ui/common-styles.ts +0 -1218
- package/src/ui/consts.ts +0 -109
- package/src/ui/event-handlers.ts +0 -662
- package/src/ui/global-styles.tsx +0 -55
- package/src/ui/hooks/useInternalTablePluginStateSelector.ts +0 -38
- package/src/ui/icons/AddColLeftIcon.tsx +0 -37
- package/src/ui/icons/AddColRightIcon.tsx +0 -37
- package/src/ui/icons/AddRowAboveIcon.tsx +0 -22
- package/src/ui/icons/AddRowBelowIcon.tsx +0 -39
- package/src/ui/icons/DragHandleDisabledIcon.tsx +0 -25
- package/src/ui/icons/DragHandleIcon.tsx +0 -16
- package/src/ui/icons/DragInMotionIcon.tsx +0 -54
- package/src/ui/icons/MergeCellsIcon.tsx +0 -26
- package/src/ui/icons/MinimisedHandle.tsx +0 -15
- package/src/ui/icons/SortingIconWrapper.tsx +0 -43
- package/src/ui/icons/SplitCellIcon.tsx +0 -34
- package/src/ui/toolbar.tsx +0 -1153
- package/src/ui/ui-styles.ts +0 -960
- package/tsconfig.app.json +0 -135
- package/tsconfig.dev.json +0 -54
- package/tsconfig.json +0 -18
|
@@ -1,1590 +0,0 @@
|
|
|
1
|
-
import type { CSSProperties } from 'react';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
|
|
4
|
-
import classnames from 'classnames';
|
|
5
|
-
import memoizeOne from 'memoize-one';
|
|
6
|
-
import rafSchedule from 'raf-schd';
|
|
7
|
-
import type { IntlShape } from 'react-intl-next';
|
|
8
|
-
import { injectIntl } from 'react-intl-next';
|
|
9
|
-
|
|
10
|
-
import type { TableColumnOrdering } from '@atlaskit/custom-steps';
|
|
11
|
-
import { ACTION_SUBJECT, EVENT_TYPE, TABLE_ACTION } from '@atlaskit/editor-common/analytics';
|
|
12
|
-
import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
13
|
-
import { tintDirtyTransaction } from '@atlaskit/editor-common/collab';
|
|
14
|
-
import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
|
|
15
|
-
import { getParentOfTypeCount } from '@atlaskit/editor-common/nesting';
|
|
16
|
-
import { nodeVisibilityManager } from '@atlaskit/editor-common/node-visibility';
|
|
17
|
-
import { getParentNodeWidth, getTableContainerWidth } from '@atlaskit/editor-common/node-width';
|
|
18
|
-
import { tableMarginSides } from '@atlaskit/editor-common/styles';
|
|
19
|
-
import type { EditorContainerWidth, GetEditorFeatureFlags } from '@atlaskit/editor-common/types';
|
|
20
|
-
import { browser, isValidPosition } from '@atlaskit/editor-common/utils';
|
|
21
|
-
import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
|
|
22
|
-
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
23
|
-
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
24
|
-
import {
|
|
25
|
-
akEditorTableNumberColumnWidth,
|
|
26
|
-
akEditorTableToolbarSize as tableToolbarSize,
|
|
27
|
-
} from '@atlaskit/editor-shared-styles';
|
|
28
|
-
import { findTable, isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
29
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
30
|
-
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
|
31
|
-
import type { CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
|
|
32
|
-
import UFOLoadHold from '@atlaskit/react-ufo/load-hold';
|
|
33
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
34
|
-
import { token } from '@atlaskit/tokens';
|
|
35
|
-
|
|
36
|
-
import { autoSizeTable, clearHoverSelection } from '../pm-plugins/commands';
|
|
37
|
-
import { autoScrollerFactory } from '../pm-plugins/drag-and-drop/utils/autoscrollers';
|
|
38
|
-
import { getPluginState } from '../pm-plugins/plugin-factory';
|
|
39
|
-
import { pluginKey as stickyHeadersPluginKey } from '../pm-plugins/sticky-headers/plugin-key';
|
|
40
|
-
import type { RowStickyState, StickyPluginState } from '../pm-plugins/sticky-headers/types';
|
|
41
|
-
import { findStickyHeaderForTable } from '../pm-plugins/sticky-headers/util';
|
|
42
|
-
import { META_KEYS } from '../pm-plugins/table-analytics';
|
|
43
|
-
import {
|
|
44
|
-
insertColgroupFromNode,
|
|
45
|
-
hasTableBeenResized,
|
|
46
|
-
} from '../pm-plugins/table-resizing/utils/colgroup';
|
|
47
|
-
import {
|
|
48
|
-
COLUMN_MIN_WIDTH,
|
|
49
|
-
TABLE_EDITOR_MARGIN,
|
|
50
|
-
TABLE_OFFSET_IN_COMMENT_EDITOR,
|
|
51
|
-
} from '../pm-plugins/table-resizing/utils/consts';
|
|
52
|
-
import { updateControls } from '../pm-plugins/table-resizing/utils/dom';
|
|
53
|
-
import {
|
|
54
|
-
getLayoutSize,
|
|
55
|
-
getScalingPercentForTableWithoutWidth,
|
|
56
|
-
getTableScalingPercent,
|
|
57
|
-
} from '../pm-plugins/table-resizing/utils/misc';
|
|
58
|
-
import { getResizeState, updateColgroup } from '../pm-plugins/table-resizing/utils/resize-state';
|
|
59
|
-
import { scaleTable } from '../pm-plugins/table-resizing/utils/scale-table';
|
|
60
|
-
import {
|
|
61
|
-
containsHeaderRow,
|
|
62
|
-
isTableNested,
|
|
63
|
-
isTableNestedInMoreThanOneNode,
|
|
64
|
-
tablesHaveDifferentColumnWidths,
|
|
65
|
-
tablesHaveDifferentNoOfColumns,
|
|
66
|
-
tablesHaveDifferentNoOfRows,
|
|
67
|
-
} from '../pm-plugins/utils/nodes';
|
|
68
|
-
import { getAssistiveMessage } from '../pm-plugins/utils/table';
|
|
69
|
-
import type { CellHoverMeta, PluginInjectionAPI } from '../types';
|
|
70
|
-
import { TableCssClassName as ClassName, ShadowEvent } from '../types';
|
|
71
|
-
import {
|
|
72
|
-
handleMouseOut,
|
|
73
|
-
handleMouseOver,
|
|
74
|
-
isTableInFocus,
|
|
75
|
-
withCellTracking,
|
|
76
|
-
} from '../ui/event-handlers';
|
|
77
|
-
import TableFloatingColumnControls from '../ui/TableFloatingColumnControls';
|
|
78
|
-
// Ignored via go/ees005
|
|
79
|
-
// eslint-disable-next-line import/no-named-as-default
|
|
80
|
-
import TableFloatingControls from '../ui/TableFloatingControls';
|
|
81
|
-
|
|
82
|
-
import { ExternalDropTargets } from './ExternalDropTargets';
|
|
83
|
-
import { OverflowShadowsObserver } from './OverflowShadowsObserver';
|
|
84
|
-
import { TableContainer } from './TableContainer';
|
|
85
|
-
import { TableStickyScrollbar } from './TableStickyScrollbar';
|
|
86
|
-
import type { TableOptions } from './types';
|
|
87
|
-
|
|
88
|
-
const isIE11 = browser.ie_version === 11;
|
|
89
|
-
// When table is inserted via paste, keyboard shortcut or quickInsert,
|
|
90
|
-
// componentDidUpdate is called multiple times. The isOverflowing value is correct only on the last update.
|
|
91
|
-
// To make sure we capture the last update, we use setTimeout.
|
|
92
|
-
const initialOverflowCaptureTimeroutDelay = 300;
|
|
93
|
-
|
|
94
|
-
// This is a hard switch for controlling whether the overflow analytics should be dispatched. There has been 6months of data
|
|
95
|
-
// already collected which we could use but have not. This has been disabled rather then removed entirely in the event that
|
|
96
|
-
// the current collected data becomes stale and we want to start collecting fresh data again in future.
|
|
97
|
-
// PLEASE NOTE: that the current way this alaytics has been configured WILL cause reflows to occur. This is why the has been disabled.
|
|
98
|
-
const isOverflowAnalyticsEnabled = false;
|
|
99
|
-
|
|
100
|
-
// Prevent unnecessary parentWidth updates when table is nested inside of a node that is nested itself.
|
|
101
|
-
const NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MIN_THRESHOLD = 2;
|
|
102
|
-
const NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MAX_THRESHOLD = 20;
|
|
103
|
-
|
|
104
|
-
interface ComponentProps {
|
|
105
|
-
view: EditorView;
|
|
106
|
-
getNode: () => PmNode;
|
|
107
|
-
allowColumnResizing?: boolean;
|
|
108
|
-
eventDispatcher: EventDispatcher;
|
|
109
|
-
getPos: () => number | undefined;
|
|
110
|
-
options?: TableOptions;
|
|
111
|
-
|
|
112
|
-
contentDOM: (node: HTMLElement | null) => void;
|
|
113
|
-
containerWidth: EditorContainerWidth;
|
|
114
|
-
allowControls?: boolean;
|
|
115
|
-
|
|
116
|
-
allowTableResizing?: boolean;
|
|
117
|
-
allowTableAlignment?: boolean;
|
|
118
|
-
|
|
119
|
-
isHeaderRowEnabled: boolean;
|
|
120
|
-
isHeaderColumnEnabled: boolean;
|
|
121
|
-
isMediaFullscreen?: boolean;
|
|
122
|
-
isDragAndDropEnabled?: boolean;
|
|
123
|
-
isTableScalingEnabled?: boolean;
|
|
124
|
-
tableActive: boolean;
|
|
125
|
-
ordering?: TableColumnOrdering;
|
|
126
|
-
isResizing?: boolean;
|
|
127
|
-
getEditorFeatureFlags: GetEditorFeatureFlags;
|
|
128
|
-
dispatchAnalyticsEvent: DispatchAnalyticsEvent;
|
|
129
|
-
pluginInjectionApi?: PluginInjectionAPI;
|
|
130
|
-
intl: IntlShape;
|
|
131
|
-
|
|
132
|
-
// marking props as optional to ensure backward compatibility when platform_editor_table_use_shared_state_hook_fg disabled
|
|
133
|
-
isInDanger?: boolean;
|
|
134
|
-
hoveredRows?: number[];
|
|
135
|
-
hoveredCell?: CellHoverMeta;
|
|
136
|
-
isTableHovered?: boolean;
|
|
137
|
-
isWholeTableInDanger?: boolean;
|
|
138
|
-
selection?: Selection;
|
|
139
|
-
limitedMode?: boolean;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
interface TableState {
|
|
143
|
-
scroll: number;
|
|
144
|
-
parentWidth?: number;
|
|
145
|
-
stickyHeader?: RowStickyState;
|
|
146
|
-
[ShadowEvent.SHOW_BEFORE_SHADOW]: boolean;
|
|
147
|
-
[ShadowEvent.SHOW_AFTER_SHADOW]: boolean;
|
|
148
|
-
tableWrapperWidth?: number;
|
|
149
|
-
tableWrapperHeight?: number;
|
|
150
|
-
windowResized?: boolean;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Generate a unique ID to prevent collisions when multiple plugin versions exist on the same page
|
|
154
|
-
const generateUniqueTableId = () => {
|
|
155
|
-
// Use crypto.randomUUID() if available, fallback to Math.random() based approach
|
|
156
|
-
if (!globalThis.crypto || typeof globalThis.crypto.randomUUID !== 'function') {
|
|
157
|
-
// Fallback: for older environments (IE).
|
|
158
|
-
// Not the best fallback, but the crypto.randomUUID is widely available
|
|
159
|
-
return (Math.random() + 1).toString(36).substring(20);
|
|
160
|
-
}
|
|
161
|
-
return crypto.randomUUID();
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// Ignored via go/ees005
|
|
165
|
-
// eslint-disable-next-line @repo/internal/react/no-class-components
|
|
166
|
-
class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
167
|
-
static displayName = 'TableComponent';
|
|
168
|
-
|
|
169
|
-
state: TableState = {
|
|
170
|
-
scroll: 0,
|
|
171
|
-
parentWidth: undefined,
|
|
172
|
-
[ShadowEvent.SHOW_BEFORE_SHADOW]: false,
|
|
173
|
-
[ShadowEvent.SHOW_AFTER_SHADOW]: false,
|
|
174
|
-
tableWrapperWidth: undefined,
|
|
175
|
-
tableWrapperHeight: undefined,
|
|
176
|
-
windowResized: false,
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
private wrapper?: HTMLDivElement | null;
|
|
180
|
-
private table?: HTMLTableElement | null;
|
|
181
|
-
private node: PmNode;
|
|
182
|
-
private containerWidth?: EditorContainerWidth;
|
|
183
|
-
private wasResizing?: boolean;
|
|
184
|
-
private tableNodeWidth?: number;
|
|
185
|
-
private layoutSize?: number;
|
|
186
|
-
private overflowShadowsObserver?: OverflowShadowsObserver;
|
|
187
|
-
private stickyScrollbar?: TableStickyScrollbar;
|
|
188
|
-
|
|
189
|
-
private isInitialOverflowSent: boolean;
|
|
190
|
-
private isNestedInTable: boolean;
|
|
191
|
-
private initialOverflowCaptureTimerId?: ReturnType<typeof setTimeout>;
|
|
192
|
-
private resizeObserver?: ResizeObserver;
|
|
193
|
-
|
|
194
|
-
private wrapperWidth?: number;
|
|
195
|
-
private wrapperReisizeObserver?: ResizeObserver;
|
|
196
|
-
|
|
197
|
-
private updateColGroupFromFullWidthChange?: boolean;
|
|
198
|
-
|
|
199
|
-
private dragAndDropCleanupFn?: CleanupFn;
|
|
200
|
-
private nodeVisibilityObserverCleanupFn?: CleanupFn;
|
|
201
|
-
private holdCompleted = false;
|
|
202
|
-
private dispatchEventName = `tableResized-${generateUniqueTableId()}`;
|
|
203
|
-
|
|
204
|
-
constructor(props: ComponentProps) {
|
|
205
|
-
super(props);
|
|
206
|
-
const { options, containerWidth, getNode } = props;
|
|
207
|
-
this.node = getNode();
|
|
208
|
-
this.containerWidth = containerWidth;
|
|
209
|
-
|
|
210
|
-
const tablePos = props.getPos();
|
|
211
|
-
|
|
212
|
-
this.isNestedInTable = tablePos
|
|
213
|
-
? getParentOfTypeCount(props.view.state.schema.nodes.table)(
|
|
214
|
-
props.view.state.doc.resolve(tablePos),
|
|
215
|
-
) > 0
|
|
216
|
-
: false;
|
|
217
|
-
|
|
218
|
-
this.isInitialOverflowSent = false;
|
|
219
|
-
|
|
220
|
-
if (!this.updateColGroupFromFullWidthChange) {
|
|
221
|
-
this.updateColGroupFromFullWidthChange =
|
|
222
|
-
options?.isFullWidthModeEnabled && !options?.wasFullWidthModeEnabled;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// store table size using previous full-width mode so can detect if it has changed.
|
|
226
|
-
const isFullWidthModeEnabled = options ? options.wasFullWidthModeEnabled : false;
|
|
227
|
-
this.layoutSize = this.tableNodeLayoutSize(this.node, containerWidth.width, {
|
|
228
|
-
isFullWidthModeEnabled,
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
this.resizeObserver = new ResizeObserver((entries) => {
|
|
232
|
-
for (const entry of entries) {
|
|
233
|
-
this.setState((prev) => {
|
|
234
|
-
return prev?.tableWrapperWidth === entry.contentRect?.width &&
|
|
235
|
-
prev?.tableWrapperHeight === entry.contentRect?.height
|
|
236
|
-
? prev
|
|
237
|
-
: {
|
|
238
|
-
...prev,
|
|
239
|
-
tableWrapperWidth: entry.contentRect.width,
|
|
240
|
-
tableWrapperHeight: entry.contentRect.height,
|
|
241
|
-
};
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
// Disable inline table editing and resizing controls in Firefox
|
|
247
|
-
// https://github.com/ProseMirror/prosemirror/issues/432
|
|
248
|
-
if ('execCommand' in document) {
|
|
249
|
-
['enableObjectResizing', 'enableInlineTableEditing'].forEach((cmd) => {
|
|
250
|
-
if (document.queryCommandSupported(cmd)) {
|
|
251
|
-
document.execCommand(cmd, false, 'false');
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
private handleMouseOut = (event: Event) => {
|
|
258
|
-
if (!isTableInFocus(this.props.view)) {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
return handleMouseOut(this.props.view, event);
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
private handleMouseOver = (event: Event) => {
|
|
265
|
-
if (!isTableInFocus(this.props.view)) {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
return withCellTracking(handleMouseOver)(this.props.view, event);
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
componentDidMount() {
|
|
272
|
-
const { observe } = nodeVisibilityManager(this.props.view.dom);
|
|
273
|
-
if (this.table) {
|
|
274
|
-
this.nodeVisibilityObserverCleanupFn = observe({
|
|
275
|
-
element: this.table,
|
|
276
|
-
onFirstVisible: () => {
|
|
277
|
-
this.initialiseEventListenersAfterMount();
|
|
278
|
-
// force width calculcation - missed resize event under firefox when
|
|
279
|
-
// table is nested within bodied extension
|
|
280
|
-
if (this.wrapper && fg('platform_editor_nodevisibility_resize_sync')) {
|
|
281
|
-
this.wrapperWidth = this.wrapper?.clientWidth;
|
|
282
|
-
}
|
|
283
|
-
},
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
initialiseEventListenersAfterMount() {
|
|
289
|
-
const {
|
|
290
|
-
allowColumnResizing,
|
|
291
|
-
allowTableResizing,
|
|
292
|
-
eventDispatcher,
|
|
293
|
-
isDragAndDropEnabled,
|
|
294
|
-
getNode,
|
|
295
|
-
getEditorFeatureFlags,
|
|
296
|
-
isTableScalingEnabled,
|
|
297
|
-
} = this.props;
|
|
298
|
-
|
|
299
|
-
// Ignored via go/ees005
|
|
300
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
301
|
-
this?.table?.addEventListener('mouseenter', this.handleMouseEnter);
|
|
302
|
-
|
|
303
|
-
// Ignored via go/ees005
|
|
304
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
305
|
-
this?.table?.addEventListener('mouseout', this.handleMouseOut);
|
|
306
|
-
|
|
307
|
-
// Ignored via go/ees005
|
|
308
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
309
|
-
this?.table?.addEventListener('mouseover', this.handleMouseOver);
|
|
310
|
-
|
|
311
|
-
const { tableWithFixedColumnWidthsOption = false } = getEditorFeatureFlags();
|
|
312
|
-
|
|
313
|
-
if (!expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true)) {
|
|
314
|
-
if (isTableScalingEnabled && !tableWithFixedColumnWidthsOption) {
|
|
315
|
-
this.handleColgroupUpdates(true);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (
|
|
319
|
-
isTableScalingEnabled &&
|
|
320
|
-
tableWithFixedColumnWidthsOption &&
|
|
321
|
-
getNode().attrs.displayMode !== 'fixed'
|
|
322
|
-
) {
|
|
323
|
-
this.handleColgroupUpdates(true);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (this.wrapper) {
|
|
328
|
-
this.wrapperReisizeObserver = new ResizeObserver((entries) => {
|
|
329
|
-
for (const entry of entries) {
|
|
330
|
-
this.wrapperWidth = entry.contentRect?.width;
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
this.wrapperReisizeObserver.observe(this.wrapper);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
if (allowColumnResizing && this.wrapper && !isIE11) {
|
|
338
|
-
// Ignored via go/ees005
|
|
339
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
340
|
-
this.wrapper.addEventListener('scroll', this.handleScrollDebounced, {
|
|
341
|
-
passive: true,
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
if (fg('disable-sticky-scrollbar-for-nested-tables')) {
|
|
345
|
-
if (this.table && !this.isNestedInTable) {
|
|
346
|
-
this.stickyScrollbar = new TableStickyScrollbar(this.wrapper, this.props.view);
|
|
347
|
-
}
|
|
348
|
-
} else {
|
|
349
|
-
if (this.table) {
|
|
350
|
-
this.stickyScrollbar = new TableStickyScrollbar(this.wrapper, this.props.view);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if (isDragAndDropEnabled) {
|
|
355
|
-
this.dragAndDropCleanupFn = combine(
|
|
356
|
-
...autoScrollerFactory({
|
|
357
|
-
tableWrapper: this.wrapper,
|
|
358
|
-
getNode,
|
|
359
|
-
}),
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if (allowColumnResizing) {
|
|
365
|
-
/**
|
|
366
|
-
* We no longer use `containerWidth` as a variable to determine an update for table resizing (avoids unnecessary updates).
|
|
367
|
-
* Instead we use the resize event to only trigger updates when necessary.
|
|
368
|
-
*/
|
|
369
|
-
if (!allowTableResizing) {
|
|
370
|
-
// Ignored via go/ees005
|
|
371
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
372
|
-
window.addEventListener('resize', this.handleWindowResizeDebounced);
|
|
373
|
-
}
|
|
374
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
375
|
-
window.addEventListener('resize', this.handleWindowResizeNewDebounced);
|
|
376
|
-
this.handleTableResizingDebounced();
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
const currentStickyState = stickyHeadersPluginKey.getState(this.props.view.state);
|
|
380
|
-
|
|
381
|
-
if (currentStickyState) {
|
|
382
|
-
this.onStickyState(currentStickyState);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// Ignored via go/ees005
|
|
386
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
387
|
-
eventDispatcher.on((stickyHeadersPluginKey as any).key, this.onStickyState);
|
|
388
|
-
|
|
389
|
-
if (isOverflowAnalyticsEnabled) {
|
|
390
|
-
const initialIsOveflowing =
|
|
391
|
-
this.state[ShadowEvent.SHOW_BEFORE_SHADOW] || this.state[ShadowEvent.SHOW_AFTER_SHADOW];
|
|
392
|
-
|
|
393
|
-
this.setTimerToSendInitialOverflowCaptured(initialIsOveflowing);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
componentWillUnmount() {
|
|
398
|
-
const { allowColumnResizing, allowTableResizing, eventDispatcher, isDragAndDropEnabled } =
|
|
399
|
-
this.props;
|
|
400
|
-
if (this.wrapper && !isIE11) {
|
|
401
|
-
// Ignored via go/ees005
|
|
402
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
403
|
-
this.wrapper.removeEventListener('scroll', this.handleScrollDebounced);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
if (isDragAndDropEnabled && this.dragAndDropCleanupFn) {
|
|
407
|
-
this.dragAndDropCleanupFn();
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (this.nodeVisibilityObserverCleanupFn) {
|
|
411
|
-
this.nodeVisibilityObserverCleanupFn();
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
this.resizeObserver?.disconnect();
|
|
415
|
-
this.wrapperReisizeObserver?.disconnect();
|
|
416
|
-
|
|
417
|
-
if (this.stickyScrollbar) {
|
|
418
|
-
this.stickyScrollbar.dispose();
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
this.handleScrollDebounced.cancel();
|
|
422
|
-
this.scaleTableDebounced.cancel();
|
|
423
|
-
this.handleTableResizingDebounced.cancel();
|
|
424
|
-
this.handleAutoSizeDebounced.cancel();
|
|
425
|
-
if (!allowTableResizing) {
|
|
426
|
-
this.handleWindowResizeDebounced.cancel();
|
|
427
|
-
}
|
|
428
|
-
this.handleWindowResizeNewDebounced.cancel();
|
|
429
|
-
|
|
430
|
-
if (!allowTableResizing && allowColumnResizing) {
|
|
431
|
-
// Ignored via go/ees005
|
|
432
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
433
|
-
window.removeEventListener('resize', this.handleWindowResizeDebounced);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
if (allowColumnResizing) {
|
|
437
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
438
|
-
window.removeEventListener('resize', this.handleWindowResizeNewDebounced);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// Ignored via go/ees005
|
|
442
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
443
|
-
this?.table?.removeEventListener('mouseenter', this.handleMouseEnter);
|
|
444
|
-
|
|
445
|
-
// Ignored via go/ees005
|
|
446
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
447
|
-
this?.table?.removeEventListener('mouseout', this.handleMouseOut);
|
|
448
|
-
|
|
449
|
-
// Ignored via go/ees005
|
|
450
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
451
|
-
this?.table?.removeEventListener('mouseover', this.handleMouseOver);
|
|
452
|
-
|
|
453
|
-
if (this.overflowShadowsObserver) {
|
|
454
|
-
this.overflowShadowsObserver.dispose();
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// Ignored via go/ees005
|
|
458
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
459
|
-
eventDispatcher.off((stickyHeadersPluginKey as any).key, this.onStickyState);
|
|
460
|
-
|
|
461
|
-
if (this.initialOverflowCaptureTimerId) {
|
|
462
|
-
clearTimeout(this.initialOverflowCaptureTimerId);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
handleMouseEnter = () => {
|
|
467
|
-
const node = this.props.getNode();
|
|
468
|
-
const pos = this.props.getPos();
|
|
469
|
-
const tr = this.props.view.state.tr;
|
|
470
|
-
const tableId = node.attrs.localId;
|
|
471
|
-
tr.setMeta('mouseEnterTable', [tableId, node, pos]);
|
|
472
|
-
this.props.view.dispatch(tr);
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
// Should be called only when table node width is reset to undefined in Comment Editor
|
|
476
|
-
// Maybe replaced by handleColgroupUpdates as we implement new table's support in Comment Editor.
|
|
477
|
-
removeInlineTableWidth() {
|
|
478
|
-
const { isResizing, getNode, view, getPos } = this.props;
|
|
479
|
-
if (!this.table) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const tableNode = getNode();
|
|
484
|
-
const newTableWidth = tableNode.attrs.width;
|
|
485
|
-
|
|
486
|
-
const start = getPos() || 0;
|
|
487
|
-
const depth = view.state.doc.resolve(start).depth;
|
|
488
|
-
if (depth !== 0) {
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
if (!isResizing && newTableWidth === null) {
|
|
493
|
-
this.table.style.width = '';
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
handleColgroupUpdates(force = false) {
|
|
498
|
-
const { getNode, containerWidth, isResizing, view, getPos, getEditorFeatureFlags, options } =
|
|
499
|
-
this.props;
|
|
500
|
-
|
|
501
|
-
if (!this.table) {
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
// Remove any widths styles after resizing preview is completed
|
|
506
|
-
this.table.style.width = '';
|
|
507
|
-
const tableNode = getNode();
|
|
508
|
-
const start = getPos() || 0;
|
|
509
|
-
const depth = view.state.doc.resolve(start).depth;
|
|
510
|
-
|
|
511
|
-
if (depth !== 0) {
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
let tableNodeWidth = getTableContainerWidth(tableNode);
|
|
516
|
-
const isTableResizedFullWidth = tableNodeWidth === 1800 && this.wasResizing && !isResizing;
|
|
517
|
-
|
|
518
|
-
// Needed for undo / redo
|
|
519
|
-
const isTableWidthChanged = tableNodeWidth !== this.tableNodeWidth;
|
|
520
|
-
|
|
521
|
-
const tableRenderWidth = options?.isCommentEditor
|
|
522
|
-
? containerWidth.width - (TABLE_OFFSET_IN_COMMENT_EDITOR + 1) // should be the same as this.table.parentElement?.clientWidth - 1, subtract 1 to avoid overflow
|
|
523
|
-
: containerWidth.width - TABLE_EDITOR_MARGIN;
|
|
524
|
-
|
|
525
|
-
tableNodeWidth =
|
|
526
|
-
options?.isCommentEditor && !tableNode.attrs.width ? tableRenderWidth : tableNodeWidth;
|
|
527
|
-
|
|
528
|
-
const isTableSquashed = tableRenderWidth < tableNodeWidth;
|
|
529
|
-
const isNumberColumnChanged =
|
|
530
|
-
tableNode.attrs.isNumberColumnEnabled !== this.node.attrs.isNumberColumnEnabled;
|
|
531
|
-
const isNumberOfColumnsChanged = tablesHaveDifferentNoOfColumns(tableNode, this.node);
|
|
532
|
-
|
|
533
|
-
const { width: containerWidthValue, lineLength: containerLineLength } = containerWidth;
|
|
534
|
-
const isLineLengthChanged = this.containerWidth?.lineLength !== containerLineLength;
|
|
535
|
-
|
|
536
|
-
const isFullWidthModeAndLineLengthChanged =
|
|
537
|
-
this.updateColGroupFromFullWidthChange &&
|
|
538
|
-
isLineLengthChanged &&
|
|
539
|
-
fg('platform_editor_table_overflow_in_full_width_fix');
|
|
540
|
-
|
|
541
|
-
const maybeScale =
|
|
542
|
-
isTableSquashed ||
|
|
543
|
-
isTableWidthChanged ||
|
|
544
|
-
(isTableResizedFullWidth && !options?.isCommentEditor) ||
|
|
545
|
-
isNumberColumnChanged ||
|
|
546
|
-
isNumberOfColumnsChanged ||
|
|
547
|
-
(expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true) &&
|
|
548
|
-
this.state.windowResized);
|
|
549
|
-
|
|
550
|
-
if (force || maybeScale || isFullWidthModeAndLineLengthChanged) {
|
|
551
|
-
const isWidthChanged = this.containerWidth?.width !== containerWidthValue;
|
|
552
|
-
const wasTableResized = hasTableBeenResized(this.node);
|
|
553
|
-
const isTableResized = hasTableBeenResized(tableNode);
|
|
554
|
-
const isColumnsDistributed = wasTableResized && !isTableResized;
|
|
555
|
-
const isTableDisplayModeChanged = this.node.attrs.displayMode !== tableNode.attrs.displayMode;
|
|
556
|
-
|
|
557
|
-
const shouldUpdateColgroup = this.shouldUpdateColgroup({
|
|
558
|
-
isWindowResized: this.state.windowResized,
|
|
559
|
-
isWidthChanged,
|
|
560
|
-
isTableWidthChanged,
|
|
561
|
-
isColumnsDistributed,
|
|
562
|
-
isTableResizedFullWidth,
|
|
563
|
-
isTableDisplayModeChanged,
|
|
564
|
-
isNumberColumnChanged,
|
|
565
|
-
isNumberOfColumnsChanged,
|
|
566
|
-
isFullWidthModeAndLineLengthChanged,
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
const { tableWithFixedColumnWidthsOption = false } = getEditorFeatureFlags();
|
|
570
|
-
|
|
571
|
-
const isTableScalingWithFixedColumnWidthsOptionEnabled =
|
|
572
|
-
!!this.props.options?.isTableScalingEnabled && tableWithFixedColumnWidthsOption;
|
|
573
|
-
|
|
574
|
-
const shouldUseIncreasedScalingPercent =
|
|
575
|
-
isTableScalingWithFixedColumnWidthsOptionEnabled ||
|
|
576
|
-
(!!this.props.options?.isTableScalingEnabled && !!this.props.options?.isCommentEditor);
|
|
577
|
-
|
|
578
|
-
if (force || (!isResizing && shouldUpdateColgroup)) {
|
|
579
|
-
const resizeState = getResizeState({
|
|
580
|
-
minWidth: COLUMN_MIN_WIDTH,
|
|
581
|
-
// When numbered column enabled, we need to subtract the width of the numbered column
|
|
582
|
-
maxSize: tableNode.attrs.isNumberColumnEnabled
|
|
583
|
-
? tableRenderWidth - akEditorTableNumberColumnWidth
|
|
584
|
-
: tableRenderWidth,
|
|
585
|
-
table: tableNode,
|
|
586
|
-
tableRef: this.table,
|
|
587
|
-
start,
|
|
588
|
-
domAtPos: view.domAtPos.bind(view),
|
|
589
|
-
isTableScalingEnabled: true,
|
|
590
|
-
shouldUseIncreasedScalingPercent,
|
|
591
|
-
isCommentEditor: !!this.props.options?.isCommentEditor,
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
let shouldScaleOnColgroupUpdate = false;
|
|
595
|
-
if (this.props.options?.isTableScalingEnabled && !tableWithFixedColumnWidthsOption) {
|
|
596
|
-
shouldScaleOnColgroupUpdate = true;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
if (
|
|
600
|
-
isTableScalingWithFixedColumnWidthsOptionEnabled &&
|
|
601
|
-
tableNode.attrs.displayMode !== 'fixed'
|
|
602
|
-
) {
|
|
603
|
-
shouldScaleOnColgroupUpdate = true;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
if (this.props.options?.isTableScalingEnabled && this.props.options?.isCommentEditor) {
|
|
607
|
-
shouldScaleOnColgroupUpdate = true;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
let scalePercent = 1;
|
|
611
|
-
requestAnimationFrame(() => {
|
|
612
|
-
// Scaling percent has to be calculated inside requestAnimationFrame, otherwise
|
|
613
|
-
// renderWidth calculated as `tableRef?.parentElement?.clientWidth`
|
|
614
|
-
// inside of getTableScalingPercent returns 0.
|
|
615
|
-
if (
|
|
616
|
-
!this.props.options?.isCommentEditor ||
|
|
617
|
-
(this.props.options?.isCommentEditor && tableNode.attrs.width)
|
|
618
|
-
) {
|
|
619
|
-
scalePercent = getTableScalingPercent(
|
|
620
|
-
tableNode,
|
|
621
|
-
// Ignored via go/ees005
|
|
622
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
623
|
-
this.table!,
|
|
624
|
-
shouldUseIncreasedScalingPercent,
|
|
625
|
-
);
|
|
626
|
-
} else {
|
|
627
|
-
// Ignored via go/ees005
|
|
628
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
629
|
-
scalePercent = getScalingPercentForTableWithoutWidth(tableNode, this.table!);
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// Request animation frame required for Firefox
|
|
633
|
-
updateColgroup(
|
|
634
|
-
resizeState,
|
|
635
|
-
// Ignored via go/ees005
|
|
636
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
637
|
-
this.table!,
|
|
638
|
-
tableNode,
|
|
639
|
-
shouldScaleOnColgroupUpdate,
|
|
640
|
-
scalePercent,
|
|
641
|
-
);
|
|
642
|
-
|
|
643
|
-
if (expValEquals('cc_editor_ufo_hold_table_till_resize_complete', 'isEnabled', true)) {
|
|
644
|
-
// Mark table as updated for TableHold component (if no table exists yet, the colgroup update will not have done anything)
|
|
645
|
-
if (this.table && !this.holdCompleted) {
|
|
646
|
-
const customTableResizedEvent = new CustomEvent(this.dispatchEventName);
|
|
647
|
-
|
|
648
|
-
document.dispatchEvent(customTableResizedEvent);
|
|
649
|
-
this.holdCompleted = true;
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
if (isFullWidthModeAndLineLengthChanged) {
|
|
657
|
-
this.updateColGroupFromFullWidthChange = false;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
this.tableNodeWidth = tableNodeWidth;
|
|
661
|
-
this.wasResizing = isResizing;
|
|
662
|
-
this.containerWidth = containerWidth;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// Ignored via go/ees005
|
|
666
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
667
|
-
componentDidUpdate(_: any, prevState: TableState) {
|
|
668
|
-
const {
|
|
669
|
-
view,
|
|
670
|
-
getNode,
|
|
671
|
-
isMediaFullscreen,
|
|
672
|
-
allowColumnResizing,
|
|
673
|
-
allowTableResizing,
|
|
674
|
-
isResizing,
|
|
675
|
-
options,
|
|
676
|
-
isTableScalingEnabled, // we could use options.isTableScalingEnabled here
|
|
677
|
-
getPos,
|
|
678
|
-
getEditorFeatureFlags,
|
|
679
|
-
} = this.props;
|
|
680
|
-
let { isInDanger } = this.props;
|
|
681
|
-
|
|
682
|
-
const table = findTable(view.state.selection);
|
|
683
|
-
|
|
684
|
-
if (!fg('platform_editor_table_use_shared_state_hook_fg')) {
|
|
685
|
-
const pluginState = getPluginState(view.state);
|
|
686
|
-
isInDanger = pluginState.isInDanger;
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
let shouldScale = false;
|
|
690
|
-
let shouldHandleColgroupUpdates = false;
|
|
691
|
-
const { tableWithFixedColumnWidthsOption = false } = getEditorFeatureFlags();
|
|
692
|
-
|
|
693
|
-
if (isTableScalingEnabled && !tableWithFixedColumnWidthsOption) {
|
|
694
|
-
shouldScale = true;
|
|
695
|
-
shouldHandleColgroupUpdates = true;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
const isTableScalingWithFixedColumnWidthsOptionEnabled =
|
|
699
|
-
!!isTableScalingEnabled && tableWithFixedColumnWidthsOption;
|
|
700
|
-
const shouldUseIncreasedScalingPercent =
|
|
701
|
-
isTableScalingWithFixedColumnWidthsOptionEnabled ||
|
|
702
|
-
(!!isTableScalingEnabled && !!this.props.options?.isCommentEditor);
|
|
703
|
-
|
|
704
|
-
if (
|
|
705
|
-
isTableScalingWithFixedColumnWidthsOptionEnabled &&
|
|
706
|
-
getNode().attrs.displayMode !== 'fixed'
|
|
707
|
-
) {
|
|
708
|
-
shouldScale = true;
|
|
709
|
-
shouldHandleColgroupUpdates = true;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
if (
|
|
713
|
-
expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true) &&
|
|
714
|
-
this.state.windowResized
|
|
715
|
-
) {
|
|
716
|
-
shouldHandleColgroupUpdates = true;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
if (shouldHandleColgroupUpdates) {
|
|
720
|
-
this.handleColgroupUpdates();
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
if (isInDanger && !table) {
|
|
724
|
-
clearHoverSelection()(view.state, view.dispatch);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
if (
|
|
728
|
-
this.props.options?.isCommentEditor &&
|
|
729
|
-
allowTableResizing &&
|
|
730
|
-
!options?.isTableScalingEnabled
|
|
731
|
-
) {
|
|
732
|
-
this.removeInlineTableWidth();
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
if (this.wrapper?.parentElement && this.table && !this.overflowShadowsObserver) {
|
|
736
|
-
if (this.props.isDragAndDropEnabled) {
|
|
737
|
-
// requestAnimationFrame is used here to fix a race condition issue
|
|
738
|
-
// that happens when a table is nested in expand and expand's width is
|
|
739
|
-
// changed via breakout button
|
|
740
|
-
window.requestAnimationFrame(() => {
|
|
741
|
-
this.overflowShadowsObserver = new OverflowShadowsObserver(
|
|
742
|
-
this.updateShadowStateDebounced,
|
|
743
|
-
// Ignored via go/ees005
|
|
744
|
-
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
745
|
-
this.table as HTMLElement,
|
|
746
|
-
this.wrapper as HTMLDivElement,
|
|
747
|
-
);
|
|
748
|
-
});
|
|
749
|
-
} else {
|
|
750
|
-
this.overflowShadowsObserver = new OverflowShadowsObserver(
|
|
751
|
-
this.updateShadowState,
|
|
752
|
-
this.table,
|
|
753
|
-
this.wrapper,
|
|
754
|
-
);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
if (this.overflowShadowsObserver) {
|
|
759
|
-
this.overflowShadowsObserver.observeShadowSentinels(this.state.stickyHeader?.sticky);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
const currentTable = getNode();
|
|
763
|
-
const previousTable = this.node;
|
|
764
|
-
const isNoOfColumnsChanged = tablesHaveDifferentNoOfColumns(currentTable, previousTable);
|
|
765
|
-
const isNoOfRowsChanged = tablesHaveDifferentNoOfRows(currentTable, previousTable);
|
|
766
|
-
if (isNoOfColumnsChanged || isNoOfRowsChanged) {
|
|
767
|
-
this.props.pluginInjectionApi?.accessibilityUtils?.actions.ariaNotify(
|
|
768
|
-
getAssistiveMessage(previousTable, currentTable, this.props.intl),
|
|
769
|
-
{ priority: 'important' },
|
|
770
|
-
);
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
if (currentTable.attrs.__autoSize) {
|
|
774
|
-
// Wait for next tick to handle auto sizing, gives the browser time to do layout calc etc.
|
|
775
|
-
this.handleAutoSizeDebounced();
|
|
776
|
-
}
|
|
777
|
-
// re-drawing will cause media component get unmounted that will exit fullscreen mode if media is in fullscreen mode
|
|
778
|
-
// see https://product-fabric.atlassian.net/browse/MEX-1290
|
|
779
|
-
else if (allowColumnResizing && this.table && !isMediaFullscreen) {
|
|
780
|
-
// If col widths (e.g. via collab) or number of columns (e.g. delete a column) have changed,
|
|
781
|
-
// re-draw colgroup.
|
|
782
|
-
if (tablesHaveDifferentColumnWidths(currentTable, previousTable) || isNoOfColumnsChanged) {
|
|
783
|
-
const { view } = this.props;
|
|
784
|
-
const shouldRecreateResizeCols =
|
|
785
|
-
!allowTableResizing || !isResizing || (isNoOfColumnsChanged && isResizing);
|
|
786
|
-
|
|
787
|
-
if (shouldRecreateResizeCols) {
|
|
788
|
-
const start = getPos() || 0;
|
|
789
|
-
const depth = view.state.doc.resolve(start).depth;
|
|
790
|
-
shouldScale = depth === 0 && shouldScale;
|
|
791
|
-
insertColgroupFromNode(
|
|
792
|
-
this.table,
|
|
793
|
-
currentTable,
|
|
794
|
-
shouldScale,
|
|
795
|
-
undefined,
|
|
796
|
-
shouldUseIncreasedScalingPercent,
|
|
797
|
-
options?.isCommentEditor,
|
|
798
|
-
);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
updateControls()(view.state);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
this.handleTableResizingDebounced();
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
if (isOverflowAnalyticsEnabled) {
|
|
808
|
-
const newIsOverflowing =
|
|
809
|
-
this.state[ShadowEvent.SHOW_BEFORE_SHADOW] || this.state[ShadowEvent.SHOW_AFTER_SHADOW];
|
|
810
|
-
|
|
811
|
-
const prevIsOverflowing =
|
|
812
|
-
prevState[ShadowEvent.SHOW_BEFORE_SHADOW] || prevState[ShadowEvent.SHOW_AFTER_SHADOW];
|
|
813
|
-
|
|
814
|
-
if (this.initialOverflowCaptureTimerId) {
|
|
815
|
-
clearTimeout(this.initialOverflowCaptureTimerId);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
if (!this.isInitialOverflowSent) {
|
|
819
|
-
this.setTimerToSendInitialOverflowCaptured(newIsOverflowing);
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
if (this.isInitialOverflowSent && prevIsOverflowing !== newIsOverflowing) {
|
|
823
|
-
const {
|
|
824
|
-
dispatch,
|
|
825
|
-
state: { tr },
|
|
826
|
-
} = this.props.view;
|
|
827
|
-
|
|
828
|
-
dispatch(
|
|
829
|
-
tr.setMeta(META_KEYS.OVERFLOW_STATE_CHANGED, {
|
|
830
|
-
isOverflowing: newIsOverflowing,
|
|
831
|
-
wasOverflowing: prevIsOverflowing,
|
|
832
|
-
editorWidth: this.props.containerWidth.width || 0,
|
|
833
|
-
width: this.node.attrs.width || 0,
|
|
834
|
-
parentWidth: this.state?.parentWidth || 0,
|
|
835
|
-
}),
|
|
836
|
-
);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
private updateShadowState = (shadowKey: ShadowEvent, value: boolean) => {
|
|
842
|
-
if (this.state[shadowKey] === value) {
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
845
|
-
this.setState({ [shadowKey]: value } as Pick<TableState, typeof shadowKey>);
|
|
846
|
-
};
|
|
847
|
-
|
|
848
|
-
private createShadowSentinels = (table: HTMLTableElement | null) => {
|
|
849
|
-
if (table) {
|
|
850
|
-
const shadowSentinelLeft = document.createElement('span');
|
|
851
|
-
shadowSentinelLeft.className = ClassName.TABLE_SHADOW_SENTINEL_LEFT;
|
|
852
|
-
const shadowSentinelRight = document.createElement('span');
|
|
853
|
-
shadowSentinelRight.className = ClassName.TABLE_SHADOW_SENTINEL_RIGHT;
|
|
854
|
-
table.prepend(shadowSentinelLeft);
|
|
855
|
-
table.prepend(shadowSentinelRight);
|
|
856
|
-
}
|
|
857
|
-
};
|
|
858
|
-
|
|
859
|
-
private observeTable(table: HTMLTableElement | null) {
|
|
860
|
-
if (table) {
|
|
861
|
-
this.resizeObserver?.observe(table);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
onStickyState = (state: StickyPluginState) => {
|
|
866
|
-
const pos = this.props.getPos();
|
|
867
|
-
if (!isValidPosition(pos, this.props.view.state)) {
|
|
868
|
-
return;
|
|
869
|
-
}
|
|
870
|
-
const stickyHeader = findStickyHeaderForTable(state, pos);
|
|
871
|
-
if (stickyHeader !== this.state.stickyHeader) {
|
|
872
|
-
this.setState({ stickyHeader });
|
|
873
|
-
if (this.overflowShadowsObserver) {
|
|
874
|
-
this.overflowShadowsObserver.updateStickyShadows();
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
};
|
|
878
|
-
|
|
879
|
-
// Ignored via go/ees005
|
|
880
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
881
|
-
prevTableState: any = null;
|
|
882
|
-
|
|
883
|
-
render() {
|
|
884
|
-
const {
|
|
885
|
-
view,
|
|
886
|
-
getNode,
|
|
887
|
-
isResizing,
|
|
888
|
-
allowControls = true,
|
|
889
|
-
isHeaderRowEnabled,
|
|
890
|
-
ordering,
|
|
891
|
-
isHeaderColumnEnabled,
|
|
892
|
-
tableActive,
|
|
893
|
-
containerWidth,
|
|
894
|
-
options,
|
|
895
|
-
getPos,
|
|
896
|
-
pluginInjectionApi,
|
|
897
|
-
isDragAndDropEnabled,
|
|
898
|
-
getEditorFeatureFlags,
|
|
899
|
-
isTableScalingEnabled, // here we can use options.isTableScalingEnabled
|
|
900
|
-
allowTableResizing,
|
|
901
|
-
allowTableAlignment,
|
|
902
|
-
selection,
|
|
903
|
-
} = this.props;
|
|
904
|
-
|
|
905
|
-
let { isInDanger, hoveredRows, hoveredCell, isTableHovered, isWholeTableInDanger } = this.props;
|
|
906
|
-
|
|
907
|
-
const { showBeforeShadow, showAfterShadow } = this.state;
|
|
908
|
-
const node = getNode();
|
|
909
|
-
|
|
910
|
-
if (!fg('platform_editor_table_use_shared_state_hook_fg')) {
|
|
911
|
-
const pluginState = getPluginState(view.state);
|
|
912
|
-
isInDanger = pluginState.isInDanger;
|
|
913
|
-
hoveredRows = pluginState.hoveredRows;
|
|
914
|
-
hoveredCell = pluginState.hoveredCell;
|
|
915
|
-
isTableHovered = pluginState.isTableHovered;
|
|
916
|
-
isWholeTableInDanger = pluginState.isWholeTableInDanger;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
const tableRef = this.table || undefined;
|
|
920
|
-
const headerRow = tableRef
|
|
921
|
-
? tableRef.querySelector<HTMLTableRowElement>('tr[data-header-row]')
|
|
922
|
-
: undefined;
|
|
923
|
-
|
|
924
|
-
const hasHeaderRow = containsHeaderRow(node);
|
|
925
|
-
const rowControls = (
|
|
926
|
-
<TableFloatingControls
|
|
927
|
-
editorView={view}
|
|
928
|
-
tableRef={tableRef}
|
|
929
|
-
tableNode={node}
|
|
930
|
-
tableActive={tableActive}
|
|
931
|
-
hoveredRows={hoveredRows}
|
|
932
|
-
hoveredCell={hoveredCell}
|
|
933
|
-
isTableHovered={isTableHovered}
|
|
934
|
-
isInDanger={isInDanger}
|
|
935
|
-
isResizing={isResizing}
|
|
936
|
-
isNumberColumnEnabled={node.attrs.isNumberColumnEnabled}
|
|
937
|
-
isHeaderRowEnabled={isHeaderRowEnabled}
|
|
938
|
-
isDragAndDropEnabled={isDragAndDropEnabled}
|
|
939
|
-
ordering={ordering}
|
|
940
|
-
isHeaderColumnEnabled={isHeaderColumnEnabled}
|
|
941
|
-
hasHeaderRow={hasHeaderRow}
|
|
942
|
-
// pass `selection` and `tableHeight` to control re-render
|
|
943
|
-
selection={view.state.selection}
|
|
944
|
-
headerRowHeight={headerRow ? headerRow.offsetHeight : undefined}
|
|
945
|
-
stickyHeader={!this.props.limitedMode ? this.state.stickyHeader : undefined}
|
|
946
|
-
tableWrapperWidth={this.state.tableWrapperWidth}
|
|
947
|
-
api={pluginInjectionApi}
|
|
948
|
-
isChromelessEditor={options?.isChromelessEditor}
|
|
949
|
-
/>
|
|
950
|
-
);
|
|
951
|
-
const tableContainerWidth = getTableContainerWidth(node);
|
|
952
|
-
const colControls = isDragAndDropEnabled ? (
|
|
953
|
-
<TableFloatingColumnControls
|
|
954
|
-
editorView={view}
|
|
955
|
-
tableRef={tableRef}
|
|
956
|
-
getNode={getNode}
|
|
957
|
-
tableActive={tableActive}
|
|
958
|
-
isInDanger={isInDanger}
|
|
959
|
-
hoveredRows={hoveredRows}
|
|
960
|
-
hoveredCell={hoveredCell}
|
|
961
|
-
isTableHovered={isTableHovered}
|
|
962
|
-
isResizing={isResizing}
|
|
963
|
-
ordering={ordering}
|
|
964
|
-
hasHeaderRow={hasHeaderRow}
|
|
965
|
-
// pass `selection` to control re-render
|
|
966
|
-
selection={view.state.selection}
|
|
967
|
-
headerRowHeight={headerRow ? headerRow.offsetHeight : undefined}
|
|
968
|
-
stickyHeader={!this.props.limitedMode ? this.state.stickyHeader : undefined}
|
|
969
|
-
getEditorFeatureFlags={getEditorFeatureFlags}
|
|
970
|
-
tableContainerWidth={tableContainerWidth}
|
|
971
|
-
isNumberColumnEnabled={node.attrs.isNumberColumnEnabled}
|
|
972
|
-
getScrollOffset={() => this.wrapper?.scrollLeft || 0}
|
|
973
|
-
tableWrapperHeight={this.state.tableWrapperHeight}
|
|
974
|
-
api={pluginInjectionApi}
|
|
975
|
-
isChromelessEditor={options?.isChromelessEditor}
|
|
976
|
-
/>
|
|
977
|
-
) : null;
|
|
978
|
-
|
|
979
|
-
const shadowPadding = allowControls && tableActive ? -tableToolbarSize : tableMarginSides;
|
|
980
|
-
|
|
981
|
-
const shadowStyle = memoizeOne(
|
|
982
|
-
(visible) => ({ visibility: visible ? 'visible' : 'hidden' }) as CSSProperties,
|
|
983
|
-
);
|
|
984
|
-
|
|
985
|
-
/**
|
|
986
|
-
* ED-19838
|
|
987
|
-
* There is a getPos issue coming from this code. We need to apply this workaround for now and apply a patch
|
|
988
|
-
* before CR6 lands in production
|
|
989
|
-
*/
|
|
990
|
-
let tablePos: number | undefined;
|
|
991
|
-
try {
|
|
992
|
-
tablePos = getPos ? getPos() : undefined;
|
|
993
|
-
} catch (e) {
|
|
994
|
-
tablePos = undefined;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
const isNested = isTableNested(view.state, tablePos);
|
|
998
|
-
|
|
999
|
-
const topShadowPadding = isDragAndDropEnabled ? 0 : shadowPadding;
|
|
1000
|
-
const topOffset = 0;
|
|
1001
|
-
|
|
1002
|
-
const topStickyShadowPosition =
|
|
1003
|
-
!this.props.limitedMode &&
|
|
1004
|
-
this.state.stickyHeader &&
|
|
1005
|
-
topOffset + this.state.stickyHeader.padding + topShadowPadding + 2;
|
|
1006
|
-
|
|
1007
|
-
const { tableWithFixedColumnWidthsOption = false } = getEditorFeatureFlags();
|
|
1008
|
-
|
|
1009
|
-
const shouldUseIncreasedScalingPercent =
|
|
1010
|
-
!!isTableScalingEnabled &&
|
|
1011
|
-
(tableWithFixedColumnWidthsOption || !!this.props.options?.isCommentEditor);
|
|
1012
|
-
|
|
1013
|
-
return (
|
|
1014
|
-
<TableContainer
|
|
1015
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1016
|
-
className={classnames(ClassName.TABLE_CONTAINER, {
|
|
1017
|
-
[ClassName.WITH_CONTROLS]: allowControls && tableActive,
|
|
1018
|
-
[ClassName.TABLE_STICKY]:
|
|
1019
|
-
!this.props.limitedMode && this.state.stickyHeader && hasHeaderRow,
|
|
1020
|
-
[ClassName.HOVERED_DELETE_BUTTON]: isInDanger,
|
|
1021
|
-
[ClassName.TABLE_SELECTED]: isTableSelected(selection ?? view.state.selection),
|
|
1022
|
-
[ClassName.NESTED_TABLE_WITH_CONTROLS]:
|
|
1023
|
-
tableActive && allowControls && this.isNestedInTable,
|
|
1024
|
-
})}
|
|
1025
|
-
editorView={view}
|
|
1026
|
-
getPos={getPos}
|
|
1027
|
-
node={node}
|
|
1028
|
-
// Ignored via go/ees005
|
|
1029
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1030
|
-
tableRef={tableRef!}
|
|
1031
|
-
containerWidth={containerWidth}
|
|
1032
|
-
isNested={isNested}
|
|
1033
|
-
pluginInjectionApi={pluginInjectionApi}
|
|
1034
|
-
tableWrapperHeight={this.state.tableWrapperHeight}
|
|
1035
|
-
isTableResizingEnabled={allowTableResizing}
|
|
1036
|
-
isResizing={isResizing}
|
|
1037
|
-
isWindowResized={this.state.windowResized}
|
|
1038
|
-
isTableScalingEnabled={isTableScalingEnabled}
|
|
1039
|
-
isTableWithFixedColumnWidthsOptionEnabled={tableWithFixedColumnWidthsOption}
|
|
1040
|
-
isWholeTableInDanger={isWholeTableInDanger}
|
|
1041
|
-
isTableAlignmentEnabled={allowTableAlignment}
|
|
1042
|
-
shouldUseIncreasedScalingPercent={shouldUseIncreasedScalingPercent}
|
|
1043
|
-
isCommentEditor={options?.isCommentEditor}
|
|
1044
|
-
isChromelessEditor={options?.isChromelessEditor}
|
|
1045
|
-
>
|
|
1046
|
-
{expValEquals('cc_editor_ufo_hold_table_till_resize_complete', 'isEnabled', true) ? (
|
|
1047
|
-
<TableHold dispatchEventName={this.dispatchEventName} />
|
|
1048
|
-
) : null}
|
|
1049
|
-
<div
|
|
1050
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1051
|
-
className={ClassName.TABLE_STICKY_SENTINEL_TOP}
|
|
1052
|
-
data-testid="sticky-sentinel-top"
|
|
1053
|
-
/>
|
|
1054
|
-
{fg('disable-sticky-scrollbar-for-nested-tables') ? (
|
|
1055
|
-
!this.isNestedInTable && (
|
|
1056
|
-
<div
|
|
1057
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1058
|
-
className={ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_TOP}
|
|
1059
|
-
data-testid="sticky-scrollbar-sentinel-top"
|
|
1060
|
-
/>
|
|
1061
|
-
)
|
|
1062
|
-
) : (
|
|
1063
|
-
<div
|
|
1064
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1065
|
-
className={ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_TOP}
|
|
1066
|
-
data-testid="sticky-scrollbar-sentinel-top"
|
|
1067
|
-
/>
|
|
1068
|
-
)}
|
|
1069
|
-
|
|
1070
|
-
{allowControls && rowControls}
|
|
1071
|
-
{isDragAndDropEnabled && (
|
|
1072
|
-
<ExternalDropTargets
|
|
1073
|
-
editorView={view}
|
|
1074
|
-
node={node}
|
|
1075
|
-
getScrollOffset={() => {
|
|
1076
|
-
return this.wrapper?.scrollLeft || 0;
|
|
1077
|
-
}}
|
|
1078
|
-
getTableWrapperWidth={() => {
|
|
1079
|
-
return this.wrapper?.clientWidth || 760;
|
|
1080
|
-
}}
|
|
1081
|
-
/>
|
|
1082
|
-
)}
|
|
1083
|
-
<div
|
|
1084
|
-
contentEditable={false}
|
|
1085
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1086
|
-
style={shadowStyle(showBeforeShadow)}
|
|
1087
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1088
|
-
className={
|
|
1089
|
-
options?.isChromelessEditor && !isDragAndDropEnabled
|
|
1090
|
-
? ClassName.TABLE_LEFT_SHADOW + ' ' + ClassName.TABLE_CHROMELESS
|
|
1091
|
-
: ClassName.TABLE_LEFT_SHADOW
|
|
1092
|
-
}
|
|
1093
|
-
/>
|
|
1094
|
-
{this.state.stickyHeader && (
|
|
1095
|
-
<div
|
|
1096
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1097
|
-
className={`${ClassName.TABLE_LEFT_SHADOW} ${ClassName.TABLE_STICKY_SHADOW}`}
|
|
1098
|
-
style={{
|
|
1099
|
-
visibility: showBeforeShadow && hasHeaderRow ? 'visible' : 'hidden',
|
|
1100
|
-
top: `${topStickyShadowPosition}px`,
|
|
1101
|
-
paddingBottom: `${isDragAndDropEnabled && token('space.025', '2px')}`,
|
|
1102
|
-
}}
|
|
1103
|
-
/>
|
|
1104
|
-
)}
|
|
1105
|
-
<div
|
|
1106
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1107
|
-
className={classnames(ClassName.TABLE_NODE_WRAPPER)}
|
|
1108
|
-
ref={(elem) => {
|
|
1109
|
-
this.wrapper = elem;
|
|
1110
|
-
if (elem) {
|
|
1111
|
-
this.props.contentDOM(elem);
|
|
1112
|
-
const tableElement = elem.querySelector('table');
|
|
1113
|
-
|
|
1114
|
-
if (tableElement !== this.table) {
|
|
1115
|
-
this.table = tableElement;
|
|
1116
|
-
this.createShadowSentinels(this.table);
|
|
1117
|
-
this.observeTable(this.table);
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
}}
|
|
1121
|
-
>
|
|
1122
|
-
{allowControls && colControls}
|
|
1123
|
-
</div>
|
|
1124
|
-
{fg('disable-sticky-scrollbar-for-nested-tables') ? (
|
|
1125
|
-
!this.isNestedInTable ? (
|
|
1126
|
-
<div
|
|
1127
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1128
|
-
className={ClassName.TABLE_STICKY_SCROLLBAR_CONTAINER}
|
|
1129
|
-
data-vc-nvs="true"
|
|
1130
|
-
style={{
|
|
1131
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1132
|
-
height: token('space.250', '20px'), // MAX_BROWSER_SCROLLBAR_HEIGHT
|
|
1133
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1134
|
-
display: 'none',
|
|
1135
|
-
// prevent unwanted scroll during table resize without removing scrollbar container from the dom
|
|
1136
|
-
width: isResizing ? token('space.0', '0px') : '100%',
|
|
1137
|
-
}}
|
|
1138
|
-
>
|
|
1139
|
-
<div
|
|
1140
|
-
style={{
|
|
1141
|
-
width: tableRef?.clientWidth,
|
|
1142
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1143
|
-
height: '100%',
|
|
1144
|
-
}}
|
|
1145
|
-
data-vc-nvs="true"
|
|
1146
|
-
></div>
|
|
1147
|
-
</div>
|
|
1148
|
-
) : (
|
|
1149
|
-
<div
|
|
1150
|
-
style={{
|
|
1151
|
-
width: tableRef?.clientWidth,
|
|
1152
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1153
|
-
height: '100%',
|
|
1154
|
-
}}
|
|
1155
|
-
data-vc-nvs="true"
|
|
1156
|
-
></div>
|
|
1157
|
-
)
|
|
1158
|
-
) : (
|
|
1159
|
-
<div
|
|
1160
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1161
|
-
className={ClassName.TABLE_STICKY_SCROLLBAR_CONTAINER}
|
|
1162
|
-
style={{
|
|
1163
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1164
|
-
height: token('space.250', '20px'), // MAX_BROWSER_SCROLLBAR_HEIGHT
|
|
1165
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1166
|
-
display: 'none',
|
|
1167
|
-
// prevent unwanted scroll during table resize without removing scrollbar container from the dom
|
|
1168
|
-
width: isResizing ? token('space.0', '0px') : '100%',
|
|
1169
|
-
}}
|
|
1170
|
-
data-vc-nvs="true"
|
|
1171
|
-
>
|
|
1172
|
-
<div
|
|
1173
|
-
style={{
|
|
1174
|
-
width: tableRef?.clientWidth,
|
|
1175
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1176
|
-
height: '100%',
|
|
1177
|
-
}}
|
|
1178
|
-
data-vc-nvs="true"
|
|
1179
|
-
></div>
|
|
1180
|
-
</div>
|
|
1181
|
-
)}
|
|
1182
|
-
<div
|
|
1183
|
-
contentEditable={false}
|
|
1184
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1185
|
-
style={shadowStyle(showAfterShadow)}
|
|
1186
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1187
|
-
className={
|
|
1188
|
-
options?.isChromelessEditor && !isDragAndDropEnabled
|
|
1189
|
-
? ClassName.TABLE_RIGHT_SHADOW + ' ' + ClassName.TABLE_CHROMELESS
|
|
1190
|
-
: ClassName.TABLE_RIGHT_SHADOW
|
|
1191
|
-
}
|
|
1192
|
-
/>
|
|
1193
|
-
{this.state.stickyHeader && (
|
|
1194
|
-
<div
|
|
1195
|
-
style={{
|
|
1196
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1197
|
-
position: 'absolute',
|
|
1198
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
1199
|
-
right: token('space.400', '32px'), // tableOverflowShadowWidthWide
|
|
1200
|
-
}}
|
|
1201
|
-
>
|
|
1202
|
-
<div
|
|
1203
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1204
|
-
className={`${ClassName.TABLE_RIGHT_SHADOW} ${ClassName.TABLE_STICKY_SHADOW}`}
|
|
1205
|
-
style={{
|
|
1206
|
-
visibility: showAfterShadow && hasHeaderRow ? 'visible' : 'hidden',
|
|
1207
|
-
top: `${topStickyShadowPosition}px`,
|
|
1208
|
-
paddingBottom: `${isDragAndDropEnabled && token('space.025', '2px')}`,
|
|
1209
|
-
}}
|
|
1210
|
-
/>
|
|
1211
|
-
</div>
|
|
1212
|
-
)}
|
|
1213
|
-
|
|
1214
|
-
<div
|
|
1215
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1216
|
-
className={ClassName.TABLE_STICKY_SENTINEL_BOTTOM}
|
|
1217
|
-
data-testid="sticky-sentinel-bottom"
|
|
1218
|
-
/>
|
|
1219
|
-
{fg('disable-sticky-scrollbar-for-nested-tables') ? (
|
|
1220
|
-
!this.isNestedInTable && (
|
|
1221
|
-
<div
|
|
1222
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1223
|
-
className={ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_BOTTOM}
|
|
1224
|
-
data-testid="sticky-scrollbar-sentinel-bottom"
|
|
1225
|
-
/>
|
|
1226
|
-
)
|
|
1227
|
-
) : (
|
|
1228
|
-
<div
|
|
1229
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
1230
|
-
className={ClassName.TABLE_STICKY_SCROLLBAR_SENTINEL_BOTTOM}
|
|
1231
|
-
data-testid="sticky-scrollbar-sentinel-bottom"
|
|
1232
|
-
/>
|
|
1233
|
-
)}
|
|
1234
|
-
</TableContainer>
|
|
1235
|
-
);
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
private handleScroll = (event: Event) => {
|
|
1239
|
-
if (!this.wrapper || event.target !== this.wrapper) {
|
|
1240
|
-
return;
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
if (this.stickyScrollbar) {
|
|
1244
|
-
this.stickyScrollbar.scrollLeft(this.wrapper.scrollLeft);
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
if (this.table) {
|
|
1248
|
-
// sync sticky header row to table scroll
|
|
1249
|
-
const headers = this.table.querySelectorAll('tr[data-header-row]');
|
|
1250
|
-
for (let i = 0; i < headers.length; i++) {
|
|
1251
|
-
// Ignored via go/ees005
|
|
1252
|
-
// eslint-disable-next-line @atlaskit/editor/no-as-casting
|
|
1253
|
-
const header = headers[i] as HTMLElement;
|
|
1254
|
-
|
|
1255
|
-
header.scrollLeft = this.wrapper.scrollLeft;
|
|
1256
|
-
header.style.marginRight = '2px';
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
this.setState({
|
|
1261
|
-
[ShadowEvent.SHOW_BEFORE_SHADOW]: this.wrapper.scrollLeft !== 0,
|
|
1262
|
-
});
|
|
1263
|
-
};
|
|
1264
|
-
|
|
1265
|
-
private handleTableResizing = () => {
|
|
1266
|
-
const { getNode, containerWidth, options, allowTableResizing } = this.props;
|
|
1267
|
-
// Ignored via go/ees005
|
|
1268
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1269
|
-
const prevNode = this.node!;
|
|
1270
|
-
const node = getNode();
|
|
1271
|
-
const prevAttrs = prevNode.attrs;
|
|
1272
|
-
|
|
1273
|
-
const isNested = isTableNested(this.props.view.state, this.props.getPos());
|
|
1274
|
-
|
|
1275
|
-
let parentWidth = this.getParentNodeWidth();
|
|
1276
|
-
|
|
1277
|
-
if (isNested && isTableNestedInMoreThanOneNode(this.props.view.state, this.props.getPos())) {
|
|
1278
|
-
const resizeObsWrapperWidth = this.wrapperWidth || 0;
|
|
1279
|
-
|
|
1280
|
-
const wrapperWidthDiffBetweenRerenders = Math.abs(
|
|
1281
|
-
resizeObsWrapperWidth - (this.state.parentWidth || 0),
|
|
1282
|
-
);
|
|
1283
|
-
const isOusideOfThreshold =
|
|
1284
|
-
wrapperWidthDiffBetweenRerenders <=
|
|
1285
|
-
NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MIN_THRESHOLD ||
|
|
1286
|
-
wrapperWidthDiffBetweenRerenders > NESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MAX_THRESHOLD;
|
|
1287
|
-
// 1. Check isOusideOfThreshold is added to prevent undersired state update.
|
|
1288
|
-
// When table is nested in the extenstion and the table column is being resized,
|
|
1289
|
-
// space available within extension can change and cause undesirable state update.
|
|
1290
|
-
// MIN_THRESNESTED_TABLE_IN_NESTED_PARENT_WIDTH_DIFF_MIN_THRESHOLDHOLD value is required
|
|
1291
|
-
// as the resizeObsWrapperWidth can differ between page reloads by 2px.
|
|
1292
|
-
|
|
1293
|
-
// 2. Check resizeObsWrapperWidth > 1 is added to prevent parentWidth update when table unmounts.
|
|
1294
|
-
// When a is nested table in a nested expand and the expand collabses, the table unmounts and
|
|
1295
|
-
// resizeObsWrapperWidth becomes 1.
|
|
1296
|
-
parentWidth =
|
|
1297
|
-
isOusideOfThreshold && resizeObsWrapperWidth > 1
|
|
1298
|
-
? resizeObsWrapperWidth
|
|
1299
|
-
: this.state.parentWidth;
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
const parentWidthChanged = parentWidth && parentWidth !== this.state.parentWidth;
|
|
1303
|
-
|
|
1304
|
-
const layoutSize = this.tableNodeLayoutSize(node, containerWidth.width, options);
|
|
1305
|
-
|
|
1306
|
-
const hasNumberedColumnChanged =
|
|
1307
|
-
prevAttrs.isNumberColumnEnabled !== node.attrs.isNumberColumnEnabled;
|
|
1308
|
-
|
|
1309
|
-
const noOfColumnsChanged = tablesHaveDifferentNoOfColumns(node, prevNode);
|
|
1310
|
-
|
|
1311
|
-
if (
|
|
1312
|
-
// We need to react if our parent changes
|
|
1313
|
-
// Scales the cols widths relative to the new parent width.
|
|
1314
|
-
parentWidthChanged ||
|
|
1315
|
-
// Enabling / disabling this feature reduces or adds size to the table.
|
|
1316
|
-
hasNumberedColumnChanged ||
|
|
1317
|
-
// This last check is also to cater for dynamic text sizing changing the 'default' layout width
|
|
1318
|
-
// Usually happens on window resize.
|
|
1319
|
-
layoutSize !== this.layoutSize ||
|
|
1320
|
-
noOfColumnsChanged
|
|
1321
|
-
) {
|
|
1322
|
-
const shouldScaleTable =
|
|
1323
|
-
(!allowTableResizing || (allowTableResizing && isNested)) &&
|
|
1324
|
-
!hasNumberedColumnChanged &&
|
|
1325
|
-
!noOfColumnsChanged;
|
|
1326
|
-
|
|
1327
|
-
// If column has been inserted/deleted avoid multi dispatch
|
|
1328
|
-
if (shouldScaleTable) {
|
|
1329
|
-
this.scaleTable(
|
|
1330
|
-
{
|
|
1331
|
-
parentWidth,
|
|
1332
|
-
},
|
|
1333
|
-
hasNumberedColumnChanged,
|
|
1334
|
-
);
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
|
-
// only when table resizing is enabled and toggle numbered column to run scaleTable
|
|
1338
|
-
if (allowTableResizing && hasNumberedColumnChanged) {
|
|
1339
|
-
if (!hasTableBeenResized(prevNode)) {
|
|
1340
|
-
this.scaleTable(
|
|
1341
|
-
{
|
|
1342
|
-
parentWidth: node.attrs.width,
|
|
1343
|
-
},
|
|
1344
|
-
true,
|
|
1345
|
-
);
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
this.updateParentWidth(parentWidth);
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
this.node = node;
|
|
1353
|
-
this.containerWidth = containerWidth;
|
|
1354
|
-
this.layoutSize = layoutSize;
|
|
1355
|
-
};
|
|
1356
|
-
|
|
1357
|
-
// Function gets called when table is nested.
|
|
1358
|
-
private scaleTable = (scaleOptions: { parentWidth?: number }, isUserTriggered = false) => {
|
|
1359
|
-
const { view, getNode, getPos, containerWidth, options } = this.props;
|
|
1360
|
-
const node = getNode();
|
|
1361
|
-
const { state, dispatch } = view;
|
|
1362
|
-
const pos = getPos();
|
|
1363
|
-
|
|
1364
|
-
if (typeof pos !== 'number' || !isValidPosition(pos, state)) {
|
|
1365
|
-
return;
|
|
1366
|
-
}
|
|
1367
|
-
const domAtPos = view.domAtPos.bind(view);
|
|
1368
|
-
const { width } = containerWidth;
|
|
1369
|
-
|
|
1370
|
-
this.scaleTableDebounced.cancel();
|
|
1371
|
-
|
|
1372
|
-
const tr = scaleTable(
|
|
1373
|
-
this.table,
|
|
1374
|
-
{
|
|
1375
|
-
...scaleOptions,
|
|
1376
|
-
node,
|
|
1377
|
-
prevNode: this.node || node,
|
|
1378
|
-
start: pos + 1,
|
|
1379
|
-
containerWidth: width,
|
|
1380
|
-
// Ignored via go/ees005
|
|
1381
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1382
|
-
previousContainerWidth: this.containerWidth!.width || width,
|
|
1383
|
-
...options,
|
|
1384
|
-
},
|
|
1385
|
-
domAtPos,
|
|
1386
|
-
this.props.pluginInjectionApi,
|
|
1387
|
-
false, // isTableScalingEnabled doesn't change the behavior of nested tables
|
|
1388
|
-
false, // shouldUseIncreasedScalingPercent set to false for nested tables
|
|
1389
|
-
)(state.tr);
|
|
1390
|
-
|
|
1391
|
-
if (!isUserTriggered) {
|
|
1392
|
-
tintDirtyTransaction(tr);
|
|
1393
|
-
if (fg('platform_editor_fix_table_resizing_undo')) {
|
|
1394
|
-
// Avoid adding this transaction separately to the history as these are automatic updates
|
|
1395
|
-
// as a consequence of another action
|
|
1396
|
-
tr.setMeta('addToHistory', false);
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
dispatch(tr);
|
|
1401
|
-
};
|
|
1402
|
-
|
|
1403
|
-
private setTimerToSendInitialOverflowCaptured = (isOverflowing: boolean) => {
|
|
1404
|
-
const { dispatchAnalyticsEvent, containerWidth, allowTableResizing } = this.props;
|
|
1405
|
-
const parentWidth = this.state?.parentWidth || 0;
|
|
1406
|
-
|
|
1407
|
-
this.initialOverflowCaptureTimerId = setTimeout(() => {
|
|
1408
|
-
dispatchAnalyticsEvent({
|
|
1409
|
-
action: TABLE_ACTION.INITIAL_OVERFLOW_CAPTURED,
|
|
1410
|
-
actionSubject: ACTION_SUBJECT.TABLE,
|
|
1411
|
-
actionSubjectId: null,
|
|
1412
|
-
eventType: EVENT_TYPE.TRACK,
|
|
1413
|
-
attributes: {
|
|
1414
|
-
editorWidth: containerWidth.width || 0,
|
|
1415
|
-
isOverflowing,
|
|
1416
|
-
tableResizingEnabled: allowTableResizing || false,
|
|
1417
|
-
width: this.node.attrs.width || 0,
|
|
1418
|
-
parentWidth,
|
|
1419
|
-
},
|
|
1420
|
-
});
|
|
1421
|
-
|
|
1422
|
-
this.isInitialOverflowSent = true;
|
|
1423
|
-
}, initialOverflowCaptureTimeroutDelay);
|
|
1424
|
-
};
|
|
1425
|
-
|
|
1426
|
-
private handleAutoSize = () => {
|
|
1427
|
-
if (this.table) {
|
|
1428
|
-
const { view, getNode, getPos, containerWidth } = this.props;
|
|
1429
|
-
const node = getNode();
|
|
1430
|
-
const pos = getPos();
|
|
1431
|
-
if (!isValidPosition(pos, view.state)) {
|
|
1432
|
-
return;
|
|
1433
|
-
}
|
|
1434
|
-
autoSizeTable(view, node, this.table, pos, {
|
|
1435
|
-
containerWidth: containerWidth.width,
|
|
1436
|
-
});
|
|
1437
|
-
}
|
|
1438
|
-
};
|
|
1439
|
-
|
|
1440
|
-
private handleWindowResize = () => {
|
|
1441
|
-
const { getNode, containerWidth } = this.props;
|
|
1442
|
-
const node = getNode();
|
|
1443
|
-
const layoutSize = this.tableNodeLayoutSize(node);
|
|
1444
|
-
|
|
1445
|
-
if (containerWidth.width > layoutSize) {
|
|
1446
|
-
return;
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
const parentWidth = this.getParentNodeWidth();
|
|
1450
|
-
this.scaleTableDebounced({
|
|
1451
|
-
parentWidth: parentWidth,
|
|
1452
|
-
});
|
|
1453
|
-
};
|
|
1454
|
-
|
|
1455
|
-
// This is a new handler for window resize events that sets the windowResized state immediately
|
|
1456
|
-
// This is needed to update colgroup on window resize, to enforce the table scaling
|
|
1457
|
-
private handleWindowResizeNew = () => {
|
|
1458
|
-
// Set resizing to true immediately
|
|
1459
|
-
if (!this.state.windowResized) {
|
|
1460
|
-
this.setState({
|
|
1461
|
-
windowResized: true,
|
|
1462
|
-
});
|
|
1463
|
-
}
|
|
1464
|
-
};
|
|
1465
|
-
|
|
1466
|
-
private getParentNodeWidth = () => {
|
|
1467
|
-
const {
|
|
1468
|
-
getPos,
|
|
1469
|
-
containerWidth,
|
|
1470
|
-
options,
|
|
1471
|
-
view: { state },
|
|
1472
|
-
} = this.props;
|
|
1473
|
-
const pos = getPos();
|
|
1474
|
-
if (!isValidPosition(pos, state)) {
|
|
1475
|
-
return;
|
|
1476
|
-
}
|
|
1477
|
-
const parentNodeWith = getParentNodeWidth(
|
|
1478
|
-
pos,
|
|
1479
|
-
state,
|
|
1480
|
-
containerWidth,
|
|
1481
|
-
options && options.isFullWidthModeEnabled,
|
|
1482
|
-
);
|
|
1483
|
-
|
|
1484
|
-
return parentNodeWith;
|
|
1485
|
-
};
|
|
1486
|
-
|
|
1487
|
-
private updateParentWidth = (width?: number) => {
|
|
1488
|
-
this.setState({ parentWidth: width });
|
|
1489
|
-
};
|
|
1490
|
-
|
|
1491
|
-
private tableNodeLayoutSize = (node: PmNode, containerWidth?: number, options?: TableOptions) =>
|
|
1492
|
-
getLayoutSize(
|
|
1493
|
-
node.attrs.layout,
|
|
1494
|
-
containerWidth || this.props.containerWidth.width,
|
|
1495
|
-
options || this.props.options || {},
|
|
1496
|
-
);
|
|
1497
|
-
|
|
1498
|
-
private shouldUpdateColgroup = (params: {
|
|
1499
|
-
isWindowResized: boolean | undefined;
|
|
1500
|
-
isWidthChanged: boolean;
|
|
1501
|
-
isTableWidthChanged: boolean;
|
|
1502
|
-
isColumnsDistributed: boolean;
|
|
1503
|
-
isTableResizedFullWidth: boolean | undefined;
|
|
1504
|
-
isTableDisplayModeChanged: boolean;
|
|
1505
|
-
isNumberColumnChanged: boolean;
|
|
1506
|
-
isNumberOfColumnsChanged: boolean;
|
|
1507
|
-
isFullWidthModeAndLineLengthChanged: boolean | undefined;
|
|
1508
|
-
}): boolean => {
|
|
1509
|
-
const {
|
|
1510
|
-
isWindowResized,
|
|
1511
|
-
isWidthChanged,
|
|
1512
|
-
isTableWidthChanged,
|
|
1513
|
-
isColumnsDistributed,
|
|
1514
|
-
isTableResizedFullWidth,
|
|
1515
|
-
isTableDisplayModeChanged,
|
|
1516
|
-
isNumberColumnChanged,
|
|
1517
|
-
isNumberOfColumnsChanged,
|
|
1518
|
-
isFullWidthModeAndLineLengthChanged,
|
|
1519
|
-
} = params;
|
|
1520
|
-
|
|
1521
|
-
const isFullPageEditor =
|
|
1522
|
-
!this.props.options?.isCommentEditor && !this.props.options?.isChromelessEditor;
|
|
1523
|
-
|
|
1524
|
-
if (expValEquals('platform_editor_tables_scaling_css', 'isEnabled', true) && isFullPageEditor) {
|
|
1525
|
-
return (
|
|
1526
|
-
!!isWindowResized ||
|
|
1527
|
-
isColumnsDistributed ||
|
|
1528
|
-
!!isTableResizedFullWidth ||
|
|
1529
|
-
isTableDisplayModeChanged ||
|
|
1530
|
-
isNumberColumnChanged ||
|
|
1531
|
-
isNumberOfColumnsChanged ||
|
|
1532
|
-
!!isFullWidthModeAndLineLengthChanged
|
|
1533
|
-
);
|
|
1534
|
-
}
|
|
1535
|
-
return (
|
|
1536
|
-
isWidthChanged ||
|
|
1537
|
-
isTableWidthChanged ||
|
|
1538
|
-
isColumnsDistributed ||
|
|
1539
|
-
!!isTableResizedFullWidth ||
|
|
1540
|
-
isTableDisplayModeChanged ||
|
|
1541
|
-
isNumberColumnChanged ||
|
|
1542
|
-
isNumberOfColumnsChanged ||
|
|
1543
|
-
!!isFullWidthModeAndLineLengthChanged
|
|
1544
|
-
);
|
|
1545
|
-
};
|
|
1546
|
-
|
|
1547
|
-
private scaleTableDebounced = rafSchedule(this.scaleTable);
|
|
1548
|
-
private handleTableResizingDebounced = rafSchedule(this.handleTableResizing);
|
|
1549
|
-
private handleScrollDebounced = rafSchedule(this.handleScroll);
|
|
1550
|
-
private handleAutoSizeDebounced = rafSchedule(this.handleAutoSize);
|
|
1551
|
-
private handleWindowResizeDebounced = rafSchedule(this.handleWindowResize);
|
|
1552
|
-
private handleWindowResizeNewDebounced = rafSchedule(this.handleWindowResizeNew);
|
|
1553
|
-
private updateShadowStateDebounced = rafSchedule(this.updateShadowState);
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
export default injectIntl(TableComponent);
|
|
1557
|
-
|
|
1558
|
-
/**
|
|
1559
|
-
* This is needed because of how currently the table is resized post client boot up with code that exists outside react
|
|
1560
|
-
*
|
|
1561
|
-
* This can be deleted once https://home.atlassian.com/o/2346a038-3c8c-498b-a79b-e7847859868d/s/a436116f-02ce-4520-8fbb-7301462a1674/project/ATLAS-97756/updates
|
|
1562
|
-
* is rolled out (and doesn't need to be used in the test arm of that change).
|
|
1563
|
-
*/
|
|
1564
|
-
const TableHold = React.memo(function TableHold({
|
|
1565
|
-
dispatchEventName,
|
|
1566
|
-
}: {
|
|
1567
|
-
dispatchEventName: string;
|
|
1568
|
-
}) {
|
|
1569
|
-
const [tableUpdateConfirmed, setTableUpdateConfirmed] = React.useState(false);
|
|
1570
|
-
|
|
1571
|
-
React.useEffect(() => {
|
|
1572
|
-
const customEventListener = () => {
|
|
1573
|
-
setTableUpdateConfirmed(true);
|
|
1574
|
-
};
|
|
1575
|
-
|
|
1576
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
1577
|
-
document.addEventListener(dispatchEventName, customEventListener);
|
|
1578
|
-
|
|
1579
|
-
return () => {
|
|
1580
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
1581
|
-
document.removeEventListener(dispatchEventName, customEventListener);
|
|
1582
|
-
};
|
|
1583
|
-
}, [dispatchEventName]);
|
|
1584
|
-
|
|
1585
|
-
if (tableUpdateConfirmed === false) {
|
|
1586
|
-
return <UFOLoadHold name="editor_table_resize" />;
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
return null;
|
|
1590
|
-
});
|