UNPKG

@atlaskit/editor-plugin-table

Version:

Table plugin for the @atlaskit/editor

148 lines (145 loc) 6.77 kB
import { ACTION_SUBJECT, EVENT_TYPE, TABLE_ACTION } from '@atlaskit/editor-common/analytics'; import { TableSharedCssClassName } from '@atlaskit/editor-common/styles'; import { findTable } from '@atlaskit/editor-tables/utils'; import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure'; import { hasTableColumnBeenResized } from '../table-resizing/utils/colgroup'; import { applyTableMeasurement, getTableMeasurement } from '../transforms/content-mode'; import { ALIGN_START } from './alignment'; export const isTableInContentMode = ({ allowColumnResizing, allowTableResizing, isFullPageEditor, isTableNested, node }) => { if (!expValEqualsNoExposure('platform_editor_table_fit_to_content_auto_convert', 'isEnabled', true)) { return false; } if (!node || isTableNested) { return false; } return isContentModeSupported({ allowColumnResizing, allowTableResizing, isFullPageEditor }) && !hasTableBeenResized(node) && node.attrs.layout === ALIGN_START; }; export const isContentModeSupported = ({ allowColumnResizing, allowTableResizing, isFullPageEditor }) => { return allowColumnResizing && allowTableResizing && isFullPageEditor; }; export const hasTableBeenResized = node => node.attrs.width !== null || hasTableColumnBeenResized(node); /** * Iterates all top-level tables in the document, and for those in content mode, * measures rendered column widths and sets colwidth + table width attributes * in a single batched transaction. */ export const applyMeasuredWidthToAllTables = (view, pluginInjectionApi) => { const { state: { doc, schema } } = view; let tr = view.state.tr; const { table } = schema.nodes; let modified = false; const measuredTables = []; // modify only top-level tables doc.forEach((node, offset) => { if (node.type !== table || hasTableBeenResized(node) && node.attrs.layout !== ALIGN_START) { return; } const domNode = view.domAtPos(offset + 1).node; const tableWrapper = domNode instanceof HTMLElement ? domNode.closest(`.${TableSharedCssClassName.TABLE_VIEW_CONTENT_WRAP}`) : null; const tableRef = tableWrapper === null || tableWrapper === void 0 ? void 0 : tableWrapper.querySelector('table'); if (!tableRef) { return; } measuredTables.push({ node, offset, measurement: getTableMeasurement(tableRef) }); }); measuredTables.forEach(({ node, offset, measurement }) => { tr = applyTableMeasurement(tr, node, measurement, offset); modified = true; }); if (modified) { var _pluginInjectionApi$a, _pluginInjectionApi$a2, _pluginInjectionApi$w, _pluginInjectionApi$w2, _pluginInjectionApi$w3; pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : (_pluginInjectionApi$a2 = _pluginInjectionApi$a.actions) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.attachAnalyticsEvent({ action: TABLE_ACTION.FIT_TO_CONTENT_AUTO_CONVERTED, actionSubject: ACTION_SUBJECT.TABLE, actionSubjectId: null, eventType: EVENT_TYPE.TRACK, attributes: { editorContainerWidth: (_pluginInjectionApi$w = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$w2 = pluginInjectionApi.width) === null || _pluginInjectionApi$w2 === void 0 ? void 0 : (_pluginInjectionApi$w3 = _pluginInjectionApi$w2.sharedState.currentState()) === null || _pluginInjectionApi$w3 === void 0 ? void 0 : _pluginInjectionApi$w3.width) !== null && _pluginInjectionApi$w !== void 0 ? _pluginInjectionApi$w : 0, totalTablesResized: measuredTables.length, measurements: measuredTables.map(({ measurement }) => ({ tableWidth: measurement.tableWidth, totalColumnCount: measurement.colWidths.length })) } })(tr); view.dispatch(tr.setMeta('addToHistory', false)); } }; export const applyMeasuredWidthToSelectedTable = (view, api) => { var _api$analytics, _api$analytics$action, _api$width$sharedStat, _api$width, _api$width$sharedStat2; const tableObject = findTable(view.state.selection); if (!tableObject) { return; } const { node, pos } = tableObject; const tableState = api === null || api === void 0 ? void 0 : api.table.sharedState.currentState(); if (!(tableState !== null && tableState !== void 0 && tableState.tableRef)) { return; } const tableRef = tableState.tableRef; // Instead of dispatching a transaction to "strip widths" and then waiting // for a rAF to measure natural column widths, instea directly update the DOM elements and // take a measurement. const cols = Array.from(tableRef.querySelectorAll(':scope > colgroup > col')); const contentWrap = tableRef.closest(`.${TableSharedCssClassName.TABLE_VIEW_CONTENT_WRAP}`); const resizerContainer = contentWrap === null || contentWrap === void 0 ? void 0 : contentWrap.querySelector(`.${TableSharedCssClassName.TABLE_RESIZER_CONTAINER}`); const resizerItem = resizerContainer === null || resizerContainer === void 0 ? void 0 : resizerContainer.querySelector('.resizer-item.display-handle'); tableRef.style.width = ''; tableRef.style.tableLayout = 'auto'; cols.forEach(col => col.style.width = ''); if (resizerContainer) { resizerContainer.style.width = 'max-content'; resizerContainer.style.setProperty('--ak-editor-table-width', 'max-content'); } if (resizerItem) { resizerItem.style.width = 'max-content'; } const measurement = getTableMeasurement(tableRef); const tr = applyTableMeasurement(view.state.tr, node, measurement, pos); api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.attachAnalyticsEvent({ action: TABLE_ACTION.FIT_TO_CONTENT_ON_DEMAND, actionSubject: ACTION_SUBJECT.TABLE, actionSubjectId: null, eventType: EVENT_TYPE.TRACK, attributes: { editorContainerWidth: (_api$width$sharedStat = api === null || api === void 0 ? void 0 : (_api$width = api.width) === null || _api$width === void 0 ? void 0 : (_api$width$sharedStat2 = _api$width.sharedState.currentState()) === null || _api$width$sharedStat2 === void 0 ? void 0 : _api$width$sharedStat2.width) !== null && _api$width$sharedStat !== void 0 ? _api$width$sharedStat : 0, tableWidth: measurement.tableWidth, totalColumnCount: measurement.colWidths.length } })(tr); view.dispatch(tr); };