UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

315 lines (307 loc) 16 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.addColumnAfter = void 0; exports.addColumnAt = addColumnAt; exports.insertTableWithSize = exports.insertTableWithNestingSupport = exports.insertRow = exports.insertColumn = exports.createTable = exports.addColumnBefore = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _customSteps = require("@atlaskit/custom-steps"); var _analytics = require("@atlaskit/editor-common/analytics"); var _nesting = require("@atlaskit/editor-common/nesting"); var _state = require("@atlaskit/editor-prosemirror/state"); var _utils = require("@atlaskit/editor-prosemirror/utils"); var _tableMap = require("@atlaskit/editor-tables/table-map"); var _utils2 = require("@atlaskit/editor-tables/utils"); var _commands = require("../analytics/commands"); var _tableAnalytics = require("../table-analytics"); var _columnWidth = require("../transforms/column-width"); var _create = require("../utils/create"); var _getAllowAddColumnCustomStep = require("../utils/get-allow-add-column-custom-step"); var _nodes = require("../utils/nodes"); var _rowControls = require("../utils/row-controls"); 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) { (0, _defineProperty2.default)(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 function addColumnAtCustomStep(column) { return function (tr) { var table = (0, _utils2.findTable)(tr.selection); if (table) { return tr.step(_customSteps.AddColumnStep.create(tr.doc, table.pos, column)); } return tr; }; } function addColumnAt(api) { var isTableScalingEnabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var isTableFixedColumnWidthsOptionEnabled = arguments.length > 2 ? arguments[2] : undefined; var shouldUseIncreasedScalingPercent = arguments.length > 3 ? arguments[3] : undefined; var isCommentEditor = arguments.length > 4 ? arguments[4] : undefined; return function (column) { var allowAddColumnCustomStep = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var view = arguments.length > 2 ? arguments[2] : undefined; return function (tr) { var updatedTr = tr; if (allowAddColumnCustomStep) { updatedTr = addColumnAtCustomStep(column)(updatedTr); } else { updatedTr = (0, _utils2.addColumnAt)(column)(updatedTr); } var table = (0, _utils2.findTable)(updatedTr.selection); if (table) { // [ED-8288] Update colwidths manually to avoid multiple dispatch in TableComponent updatedTr = (0, _columnWidth.rescaleColumns)(isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent, api, isCommentEditor)(table, view)(updatedTr); } if (view) { updatedTr = (0, _commands.updateRowOrColumnMovedTransform)({ type: 'column' }, 'addRowOrColumn')(view.state, updatedTr); } updatedTr.setMeta(_tableAnalytics.META_KEYS.OVERFLOW_TRIGGER, { name: _analytics.TABLE_OVERFLOW_CHANGE_TRIGGER.ADDED_COLUMN }); return updatedTr; }; }; } // :: (EditorState, dispatch: ?(tr: Transaction)) → bool // Command to add a column before the column with the selection. var addColumnBefore = exports.addColumnBefore = function addColumnBefore(api) { var isTableScalingEnabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var isTableFixedColumnWidthsOptionEnabled = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var shouldUseIncreasedScalingPercent = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; var isCommentEditor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; return function (state, dispatch, view) { var table = (0, _utils2.findTable)(state.selection); if (!table) { return false; } if (dispatch) { var rect = (0, _utils2.selectedRect)(state); dispatch(addColumnAt(api, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent, isCommentEditor)(rect.left, (0, _getAllowAddColumnCustomStep.getAllowAddColumnCustomStep)(state), view)(state.tr)); } return true; }; }; // :: (EditorState, dispatch: ?(tr: Transaction)) → bool // Command to add a column after the column with the selection. var addColumnAfter = exports.addColumnAfter = function addColumnAfter(api, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent, isCommentEditor) { return function (state, dispatch, view) { var table = (0, _utils2.findTable)(state.selection); if (!table) { return false; } if (dispatch) { var rect = (0, _utils2.selectedRect)(state); dispatch(addColumnAt(api, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent, isCommentEditor)(rect.right, (0, _getAllowAddColumnCustomStep.getAllowAddColumnCustomStep)(state), view)(state.tr)); } return true; }; }; var insertColumn = exports.insertColumn = function insertColumn(api) { var isTableScalingEnabled = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var isTableFixedColumnWidthsOptionEnabled = arguments.length > 2 ? arguments[2] : undefined; var shouldUseIncreasedScalingPercent = arguments.length > 3 ? arguments[3] : undefined; var isCommentEditor = arguments.length > 4 ? arguments[4] : undefined; return function (column) { return function (state, dispatch, view) { var tr = addColumnAt(api, isTableScalingEnabled, isTableFixedColumnWidthsOptionEnabled, shouldUseIncreasedScalingPercent, isCommentEditor)(column, (0, _getAllowAddColumnCustomStep.getAllowAddColumnCustomStep)(state), view)(state.tr); var table = (0, _utils2.findTable)(tr.selection); if (!table) { return false; } // move the cursor to the newly created column var pos = _tableMap.TableMap.get(table.node).positionAt(0, column, table.node); if (dispatch) { dispatch(tr.setSelection(_state.Selection.near(tr.doc.resolve(table.start + pos)))); } return true; }; }; }; var insertRow = exports.insertRow = function insertRow(row, moveCursorToTheNewRow) { return function (state, dispatch) { // Don't clone the header row var headerRowEnabled = (0, _nodes.checkIfHeaderRowEnabled)(state.selection); var clonePreviousRow = headerRowEnabled && row > 1 || !headerRowEnabled && row > 0; // When the table have header row // we should not add row on the position zero if (row === 0 && headerRowEnabled) { return false; } var tr = clonePreviousRow ? (0, _rowControls.copyPreviousRow)(state.schema)(row)(state.tr) : (0, _utils2.addRowAt)(row, undefined)(state.tr); var table = (0, _utils2.findTable)(tr.selection); if (!table) { return false; } if (dispatch) { var selection = state.selection; if (moveCursorToTheNewRow) { // move the cursor to the newly created row var pos = _tableMap.TableMap.get(table.node).positionAt(row, 0, table.node); tr.setSelection(_state.Selection.near(tr.doc.resolve(table.start + pos))); } else { tr.setSelection(selection.map(tr.doc, tr.mapping)); } (0, _commands.updateRowOrColumnMovedTransform)({ type: 'row' }, 'addRowOrColumn')(state, tr); dispatch(tr); } return true; }; }; /** * @private * @deprecated This function is deprecated - please use insertTableWithNestingSupport instead. * (To be removed with feature gate: `platform_editor_use_nested_table_pm_nodes`) */ var createTable = exports.createTable = function createTable(isTableScalingEnabled, isTableAlignmentEnabled, isFullWidthModeEnabled, isMaxWidthModeEnabled, editorAnalyticsAPI, isCommentEditor, isChromelessEditor, isTableResizingEnabled) { return function (state, dispatch) { var table = (0, _create.createTableWithWidth)({ isTableScalingEnabled: isTableScalingEnabled, isTableAlignmentEnabled: isTableAlignmentEnabled, isFullWidthModeEnabled: isFullWidthModeEnabled, isMaxWidthModeEnabled: isMaxWidthModeEnabled, isCommentEditor: isCommentEditor, isChromelessEditor: isChromelessEditor, isTableResizingEnabled: isTableResizingEnabled })(state.schema); if (dispatch) { var tr = (0, _utils.safeInsert)(table)(state.tr).scrollIntoView(); if (editorAnalyticsAPI) { editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({ action: _analytics.ACTION.INSERTED, actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT, actionSubjectId: _analytics.ACTION_SUBJECT_ID.TABLE, attributes: { inputMethod: _analytics.INPUT_METHOD.SHORTCUT }, eventType: _analytics.EVENT_TYPE.TRACK })(tr); } dispatch(tr); } return true; }; }; /** * @private * @deprecated This function is deprecated - please use insertTableWithNestingSupport instead. * (To be removed with feature gate: `platform_editor_use_nested_table_pm_nodes`) */ var insertTableWithSize = exports.insertTableWithSize = function insertTableWithSize(isFullWidthModeEnabled, isMaxWidthModeEnabled, isTableScalingEnabled, isTableAlignmentEnabled, editorAnalyticsAPI, isCommentEditor, isChromelessEditor) { return function (rowsCount, colsCount, inputMethod) { return function (_ref) { var tr = _ref.tr; var tableNode = (0, _create.createTableWithWidth)({ isTableScalingEnabled: isTableScalingEnabled, isFullWidthModeEnabled: isFullWidthModeEnabled, isMaxWidthModeEnabled: isMaxWidthModeEnabled, isTableAlignmentEnabled: isTableAlignmentEnabled, isCommentEditor: isCommentEditor, isChromelessEditor: isChromelessEditor, createTableProps: { rowsCount: rowsCount, colsCount: colsCount } })(tr.doc.type.schema); var newTr = (0, _utils.safeInsert)(tableNode)(tr).scrollIntoView(); if (inputMethod) { editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({ action: _analytics.ACTION.INSERTED, actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT, actionSubjectId: _analytics.ACTION_SUBJECT_ID.TABLE, attributes: { inputMethod: inputMethod, totalRowCount: rowsCount, totalColumnCount: colsCount }, eventType: _analytics.EVENT_TYPE.TRACK })(newTr); } return newTr; }; }; }; /** * Unified command to insert a new table into the editor. * * @param {object} options - Configuration options for table insertion. * @param {boolean} [options.isTableScalingEnabled=false] - Flag to enable table scaling. * @param {boolean} [options.isTableAlignmentEnabled=false] - Flag to enable table alignment. * @param {boolean} [options.isFullWidthModeEnabled=false] - Flag to enable full-width mode for the table. * @param {boolean} [options.isCommentEditor=false] - Flag to indicate if the editor is in comment mode. * @param {boolean} [options.isChromelessEditor=false] - Flag to indicate if the editor is chromeless. * @param {boolean} [options.isTableResizingEnabled=false] - Flag to enable table resizing. * @param {object} [options.createTableProps={}] - Additional properties for table creation, including table size. * @param {object} api - PluginInjectinoApi object for content insertion commands. * @param {object} analyticsPayload - Payload for analytics tracking. * * @returns {Function} A function that takes a transaction and inserts a table. */ var insertTableWithNestingSupport = exports.insertTableWithNestingSupport = function insertTableWithNestingSupport(_ref2, api, analyticsPayload) { var _ref2$isTableScalingE = _ref2.isTableScalingEnabled, isTableScalingEnabled = _ref2$isTableScalingE === void 0 ? false : _ref2$isTableScalingE, _ref2$isTableAlignmen = _ref2.isTableAlignmentEnabled, isTableAlignmentEnabled = _ref2$isTableAlignmen === void 0 ? false : _ref2$isTableAlignmen, _ref2$isFullWidthMode = _ref2.isFullWidthModeEnabled, isFullWidthModeEnabled = _ref2$isFullWidthMode === void 0 ? false : _ref2$isFullWidthMode, _ref2$isMaxWidthModeE = _ref2.isMaxWidthModeEnabled, isMaxWidthModeEnabled = _ref2$isMaxWidthModeE === void 0 ? false : _ref2$isMaxWidthModeE, _ref2$isCommentEditor = _ref2.isCommentEditor, isCommentEditor = _ref2$isCommentEditor === void 0 ? false : _ref2$isCommentEditor, _ref2$isChromelessEdi = _ref2.isChromelessEditor, isChromelessEditor = _ref2$isChromelessEdi === void 0 ? false : _ref2$isChromelessEdi, _ref2$isTableResizing = _ref2.isTableResizingEnabled, isTableResizingEnabled = _ref2$isTableResizing === void 0 ? false : _ref2$isTableResizing, _ref2$createTableProp = _ref2.createTableProps, createTableProps = _ref2$createTableProp === void 0 ? {} : _ref2$createTableProp; return function (_ref3) { var _api$contentInsertion; var tr = _ref3.tr; var schema = tr.doc.type.schema; // If the cursor is inside a table var insertAt; var isNestedTable = false; if ((0, _utils.hasParentNodeOfType)(schema.nodes.table)(tr.selection) && (0, _nesting.isNestedTablesSupported)(schema)) { // If trying to nest deeper than one level, we insert the table after the top table if ((0, _nesting.getParentOfTypeCount)(schema.nodes.table)(tr.selection.$from) > 1) { var positionAfterTopTable = (0, _nesting.getPositionAfterTopParentNodeOfType)(schema.nodes.table)(tr.selection.$from); if (!positionAfterTopTable) { return tr; } insertAt = _state.TextSelection.create(tr.doc, positionAfterTopTable); } else { // Table can be nested in parent table isNestedTable = true; } } var node = (0, _create.createTableWithWidth)({ isTableScalingEnabled: isTableScalingEnabled, isTableAlignmentEnabled: isTableAlignmentEnabled, isFullWidthModeEnabled: isFullWidthModeEnabled, isMaxWidthModeEnabled: isMaxWidthModeEnabled, isCommentEditor: isCommentEditor, isChromelessEditor: isChromelessEditor, isTableResizingEnabled: isTableResizingEnabled, isNestedTable: isNestedTable, createTableProps: createTableProps })(schema); api === null || api === void 0 || (_api$contentInsertion = api.contentInsertion) === null || _api$contentInsertion === void 0 || (_api$contentInsertion = _api$contentInsertion.commands) === null || _api$contentInsertion === void 0 || _api$contentInsertion.insert({ node: node, options: { selectNodeInserted: false, analyticsPayload: analyticsPayload ? _objectSpread(_objectSpread({}, analyticsPayload), {}, { attributes: _objectSpread(_objectSpread({}, analyticsPayload.attributes), {}, { localId: node.attrs.localId }) }) : undefined, insertAt: insertAt } })({ tr: tr }); return tr; }; };