@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
315 lines (307 loc) • 16 kB
JavaScript
"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;
};
};