UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

188 lines (182 loc) 9.17 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // #region Imports import { TableSortStep } from '@atlaskit/custom-steps'; import { isTextInput } from '@atlaskit/editor-common/utils'; // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils'; import { CellSelection } from '@atlaskit/editor-tables/cell-selection'; import { findTable } from '@atlaskit/editor-tables/utils'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { defaultTableSelection } from './default-table-selection'; import { pluginKey as tableResizingPluginKey } from './table-resizing/plugin-key'; import { isTableCollapsible } from './utils/collapse'; import { checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled } from './utils/nodes'; var nextTableSorting = function nextTableSorting(tr, table) { var tableSortStep = tr.steps.find(function (step) { return step instanceof TableSortStep; }); return tableSortStep && table && table.pos === tableSortStep.pos ? tableSortStep.next : undefined; }; var nextResizeHandleColumnIndex = function nextResizeHandleColumnIndex(tr, resizeHandleColumnIndex) { if (tr.getMeta(tableResizingPluginKey)) { return undefined; } return resizeHandleColumnIndex; }; var shouldCloseLegacyContextualMenu = function shouldCloseLegacyContextualMenu(_ref) { var pluginState = _ref.pluginState, targetCellPositionChanged = _ref.targetCellPositionChanged, tr = _ref.tr; return Boolean(pluginState.isContextualMenuOpen && (targetCellPositionChanged || tr.selectionSet && !(tr.selection instanceof CellSelection))); }; var updateTargetCellPosition = function updateTargetCellPosition(_ref2) { var tr = _ref2.tr, table = _ref2.table; return function (pluginState) { var tableNode = table && table.node; if (expValEquals('platform_editor_table_menu_updates', 'isEnabled', true)) { var _targetCellPosition; if (tableNode) { var _tr$doc$type$schema$n = tr.doc.type.schema.nodes, _tableCell = _tr$doc$type$schema$n.tableCell, _tableHeader = _tr$doc$type$schema$n.tableHeader; var _cell = findParentNodeOfType([_tableCell, _tableHeader])(tr.selection); _targetCellPosition = _cell ? _cell.pos : undefined; } var hasTargetCellChanged = pluginState.targetCellPosition !== _targetCellPosition; var hasActiveTableMenu = pluginState.activeTableMenu != null && pluginState.activeTableMenu.type !== 'none'; var shouldCloseMenu = hasActiveTableMenu && tr.selectionSet && (!tableNode || hasTargetCellChanged || !(tr.selection instanceof CellSelection)); if (!hasTargetCellChanged && !shouldCloseMenu) { return pluginState; } // The updated table menu is anchored to a table selection. When selection moves // to another cell, leaves the table, or changes from a CellSelection to a text cursor, // close the active menu so render state cannot point at a stale anchor. return _objectSpread(_objectSpread({}, pluginState), {}, { targetCellPosition: _targetCellPosition, activeTableMenu: shouldCloseMenu ? { type: 'none' } : pluginState.activeTableMenu }); } if (!tableNode) { return _objectSpread(_objectSpread({}, pluginState), {}, { targetCellPosition: undefined }); } var _tr$doc$type$schema$n2 = tr.doc.type.schema.nodes, tableCell = _tr$doc$type$schema$n2.tableCell, tableHeader = _tr$doc$type$schema$n2.tableHeader; var cell = findParentNodeOfType([tableCell, tableHeader])(tr.selection); var targetCellPosition = cell ? cell.pos : undefined; if (expValEquals('platform_editor_table_close_cell_menu_on_move_exp', 'isEnabled', true)) { var targetCellPositionChanged = pluginState.targetCellPosition !== targetCellPosition; var closeContextualMenu = shouldCloseLegacyContextualMenu({ pluginState: pluginState, targetCellPositionChanged: targetCellPositionChanged, tr: tr }); if (!targetCellPositionChanged && !closeContextualMenu) { return pluginState; } // Close the legacy contextual menu when moving cells because the cell background // color submenu can otherwise remain open against the previous cell selection. return _objectSpread(_objectSpread(_objectSpread({}, pluginState), closeContextualMenu ? { isContextualMenuOpen: false } : {}), {}, { targetCellPosition: targetCellPosition }); } if (pluginState.targetCellPosition === targetCellPosition) { return pluginState; } return _objectSpread(_objectSpread({}, pluginState), {}, { targetCellPosition: targetCellPosition }); }; }; var updateTableNodePluginState = function updateTableNodePluginState(_ref3) { var tr = _ref3.tr, table = _ref3.table; return function (pluginState) { var tableNode = table && table.node; if (!tableNode || isTextInput(tr)) { return pluginState; } return _objectSpread(_objectSpread(_objectSpread({}, pluginState), defaultTableSelection), {}, { tableNode: tableNode, ordering: nextTableSorting(tr, table), resizeHandleColumnIndex: nextResizeHandleColumnIndex(tr, pluginState.resizeHandleColumnIndex), isNumberColumnEnabled: checkIfNumberColumnEnabled(tr.selection), isHeaderColumnEnabled: checkIfHeaderColumnEnabled(tr.selection), isHeaderRowEnabled: checkIfHeaderRowEnabled(tr.selection) }); }; }; var updateCollapseHandler = function updateCollapseHandler(_ref4) { var tr = _ref4.tr, table = _ref4.table; return function (pluginState) { var tableNode = table && table.node; var schema = tr.doc.type.schema; var allowCollapse = pluginState.pluginConfig.allowCollapse; var isExpandInSchema = schema.nodes.expand !== undefined; var isCollapseEnabled = allowCollapse && isExpandInSchema; /** * If we don't have focus, or collapse isn't allowed, or a table node doesn't * exist, we don't need to waste extra checks below */ if (!pluginState.editorHasFocus || !isCollapseEnabled || !tableNode) { return pluginState; } var expandNodeType = schema.nodes.expand; var isTableCollapsed = expandNodeType && !!findParentNodeOfType(expandNodeType)(tr.selection); var trCanBeCollapsed = isTableCollapsible(tr).tableIsCollapsible; // We're focused on a table + we're not inside an expand var canCollapseTable = !!pluginState.tableNode && // is it already collapsed? !isTableCollapsed && !!trCanBeCollapsed; if (pluginState.isTableCollapsed !== isTableCollapsed || pluginState.canCollapseTable !== canCollapseTable) { return _objectSpread(_objectSpread({}, pluginState), {}, { isTableCollapsed: isTableCollapsed, canCollapseTable: canCollapseTable }); } return pluginState; }; }; var buildPluginState = function buildPluginState(builders) { return function (props) { return function (pluginState) { if (!props.table) { if (expValEquals('platform_editor_table_menu_updates', 'isEnabled', true)) { var shouldClearTargetCellPosition = pluginState.targetCellPosition !== undefined; var hasActiveTableMenu = pluginState.activeTableMenu != null && pluginState.activeTableMenu.type !== 'none'; if (!shouldClearTargetCellPosition && !hasActiveTableMenu) { return pluginState; } return _objectSpread(_objectSpread({}, pluginState), {}, { targetCellPosition: undefined, activeTableMenu: hasActiveTableMenu ? { type: 'none' } : pluginState.activeTableMenu }); } return pluginState.targetCellPosition ? _objectSpread(_objectSpread({}, pluginState), {}, { targetCellPosition: undefined }) : pluginState; } return builders.reduce(function (_pluginState, transform) { return transform(props)(_pluginState); }, pluginState); }; }; }; export var handleDocOrSelectionChanged = function handleDocOrSelectionChanged(tr, pluginState) { return buildPluginState([updateTargetCellPosition, updateTableNodePluginState, updateCollapseHandler])({ tr: tr, table: findTable(tr.selection) })(pluginState); };