@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
186 lines (183 loc) • 9.75 kB
JavaScript
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; }
import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
import { tableCellMinWidth } from '@atlaskit/editor-common/styles';
import { akEditorTableNumberColumnWidth } from '@atlaskit/editor-shared-styles';
import { updateColumnWidths } from '../../transforms/column-width';
import { getTableWidth } from '../../utils/nodes';
import { getLayoutSize } from '../utils/misc';
import { reduceSpace } from '../utils/resize-logic';
import { adjustColumnsWidths, getResizeState, getTotalWidth, updateColgroup } from '../utils/resize-state';
import { hasTableBeenResized, insertColgroupFromNode } from './colgroup';
import { syncStickyRowToTable } from './dom';
// Base function to trigger the actual scale on a table node.
// Will only resize/scale if a table has been previously resized.
var scale = function scale(tableRef, options, domAtPos) {
var isTableScalingEnabledOnCurrentTable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var shouldUseIncreasedScalingPercent = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var isCommentEditor = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var node = options.node,
containerWidth = options.containerWidth,
previousContainerWidth = options.previousContainerWidth,
prevNode = options.prevNode,
start = options.start,
layoutChanged = options.layoutChanged,
isTableResizingEnabled = options.isTableResizingEnabled;
var maxSize = isTableResizingEnabled ? getTableContainerWidth(node) : getLayoutSize(node.attrs.layout, containerWidth, {});
var prevTableWidth = getTableWidth(prevNode);
var previousMaxSize = isTableResizingEnabled ? getTableContainerWidth(node) : getLayoutSize(prevNode.attrs.layout, previousContainerWidth, {});
var newWidth = maxSize;
// adjust table width if layout is updated
var hasOverflow = prevTableWidth > previousMaxSize;
if (layoutChanged && hasOverflow) {
// No keep overflow if the old content can be in the new size
var canFitInNewSize = prevTableWidth < maxSize;
if (canFitInNewSize) {
newWidth = maxSize;
} else {
// Keep the same scale.
var overflowScale = prevTableWidth / previousMaxSize;
newWidth = Math.floor(newWidth * overflowScale);
}
}
if (node.attrs.isNumberColumnEnabled) {
newWidth -= akEditorTableNumberColumnWidth;
}
var resizeState = getResizeState({
minWidth: tableCellMinWidth,
maxSize: maxSize,
table: node,
tableRef: tableRef,
start: start,
domAtPos: domAtPos,
isTableScalingEnabled: isTableScalingEnabledOnCurrentTable,
shouldUseIncreasedScalingPercent: shouldUseIncreasedScalingPercent,
isCommentEditor: isCommentEditor
});
return scaleTableTo(resizeState, newWidth);
};
var scaleWithParent = function scaleWithParent(tableRef, parentWidth, table, start, domAtPos) {
var isTableScalingEnabledOnCurrentTable = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var shouldUseIncreasedScalingPercent = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
var isCommentEditor = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
var resizeState = getResizeState({
minWidth: tableCellMinWidth,
maxSize: parentWidth,
table: table,
tableRef: tableRef,
start: start,
domAtPos: domAtPos,
isTableScalingEnabled: isTableScalingEnabledOnCurrentTable,
shouldUseIncreasedScalingPercent: shouldUseIncreasedScalingPercent,
isCommentEditor: isCommentEditor
});
if (table.attrs.isNumberColumnEnabled) {
parentWidth -= akEditorTableNumberColumnWidth;
}
return scaleTableTo(resizeState, Math.floor(parentWidth));
};
// Scales the table to a given size and updates its colgroup DOM node
export function scaleTableTo(state, maxSize) {
var scaleFactor = maxSize / getTotalWidth(state);
var newState = _objectSpread(_objectSpread({}, state), {}, {
maxSize: maxSize,
cols: state.cols.map(function (col) {
var minWidth = col.minWidth,
width = col.width;
var newColWidth = Math.floor(width * scaleFactor);
if (newColWidth < minWidth) {
newColWidth = minWidth;
}
return _objectSpread(_objectSpread({}, col), {}, {
width: newColWidth
});
})
});
var newTotalWidth = getTotalWidth(newState);
if (newTotalWidth > maxSize) {
newState = reduceSpace(newState, newTotalWidth - maxSize);
}
return adjustColumnsWidths(newState, maxSize);
}
export var previewScaleTable = function previewScaleTable(tableRef, options, domAtPos) {
var isTableScalingEnabled = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var allowFixedColumnWidthOption = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var isCommentEditor = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var node = options.node,
start = options.start,
parentWidth = options.parentWidth;
if (!tableRef) {
return;
}
if (parentWidth) {
var isNumberColumnEnabled = node.attrs.isNumberColumnEnabled;
var width = isNumberColumnEnabled ? parentWidth - akEditorTableNumberColumnWidth : parentWidth;
tableRef.style.width = "".concat(width, "px");
}
var isTableScalingEnabledOnCurrentTable = isTableScalingEnabled;
var isTableScalingWithFixedColumnWidthsOptionEnabled = isTableScalingEnabled && allowFixedColumnWidthOption;
if (isTableScalingWithFixedColumnWidthsOptionEnabled) {
isTableScalingEnabledOnCurrentTable = isTableScalingEnabled && node.attrs.displayMode !== 'fixed';
}
// If the table hasn't been resize, the colgroup 48px width values will gracefully scale down.
// If we are scaling the table down with isTableScalingEnabled, the colgroup widths may be scaled to a value that is not 48px.
if (!hasTableBeenResized(node) && !isTableScalingEnabledOnCurrentTable) {
syncStickyRowToTable(tableRef);
return;
}
var shouldUseIncreasedScalingPercent = isTableScalingWithFixedColumnWidthsOptionEnabled || isTableScalingEnabled && isCommentEditor;
var resizeState = parentWidth ? scaleWithParent(tableRef, parentWidth, node, start, domAtPos, false,
// Here isTableScalingEnabled = false
shouldUseIncreasedScalingPercent) : scale(tableRef, options, domAtPos, false, shouldUseIncreasedScalingPercent);
if (resizeState) {
updateColgroup(resizeState, tableRef, node, false, 1);
}
};
// Scale the table to meet new requirements (col, layout change etc)
export var scaleTable = function scaleTable(tableRef, options, domAtPos, api) {
var isTableScalingEnabledOnCurrentTable = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var shouldUseIncreasedScalingPercent = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var isCommentEditor = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
return function (tr) {
if (!tableRef) {
return tr;
}
var node = options.node,
start = options.start,
parentWidth = options.parentWidth,
layoutChanged = options.layoutChanged;
// If a table has not been resized yet, columns should be auto.
if (hasTableBeenResized(node) === false) {
// If its not a re-sized table, we still want to re-create cols
// To force reflow of columns upon delete.
if (!isTableScalingEnabledOnCurrentTable) {
var isTableScalingEnabled = false;
insertColgroupFromNode(tableRef, node, isTableScalingEnabled, undefined, shouldUseIncreasedScalingPercent, isCommentEditor);
}
tr.setMeta('scrollIntoView', false);
return tr;
}
var resizeState;
if (parentWidth) {
resizeState = scaleWithParent(tableRef, parentWidth, node, start, domAtPos, isTableScalingEnabledOnCurrentTable, shouldUseIncreasedScalingPercent);
} else {
resizeState = scale(tableRef, options, domAtPos, isTableScalingEnabledOnCurrentTable, shouldUseIncreasedScalingPercent);
}
if (resizeState) {
tr = updateColumnWidths(resizeState, node, start, api)(tr);
if (tr.docChanged) {
tr.setMeta('scrollIntoView', false);
// TODO: ED-8995 - We need to do this check to reduce the number of race conditions when working with tables.
// This metadata is been used in the sendTransaction function in the Collab plugin
/* Added !layoutChanged check here to solve unnecessary scroll bar after publish when click on breakout button multiple times and publish
scaleTable is only called once every time a breakout button is clicked, so it is safe not to add the meta 'scaleTable' to the tr.
Leaving the tr.setMeta('scaleTable', true) here for race conditions that we aren't aware of.
*/
!layoutChanged && tr.setMeta('scaleTable', true);
return tr;
}
}
return tr;
};
};