UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

106 lines (99 loc) 3.67 kB
import { findTable } from '@atlaskit/editor-tables'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; /* * Returns the level of nesting of a given `nodeType` in the current position. * eg. table > table is nested 1 level, table > table > table is nested 2 levels. * * ```typescript * const nestingLevel = getParentOfTypeCount(schema.nodes.table)(position); * ``` */ export const getParentOfTypeCount = nodeType => $pos => { let count = 0; // Loop through parent nodes from bottom to top for (let depth = $pos.depth; depth > 0; depth--) { const node = $pos.node(depth); // Count the table nodes if (node.type === nodeType) { count++; } } return count; }; /* * Returns the (absolute) position directly after the top parent node of a given `nodeType` in the current position. * * ```typescript * const nestingLevel = getEndTopParentNodeOfType(schema.nodes.table)(position); * ``` */ export const getPositionAfterTopParentNodeOfType = nodeType => $pos => { // Loop through parent nodes from top to bottom for (let depth = 1; depth <= $pos.depth; depth++) { const node = $pos.node(depth); // Count the table nodes if (node.type === nodeType) { return $pos.after(depth); } } }; /* * Returns true if the current selection is inside a table nested within a table. * * ```typescript * const isNestedTable = isSelectionTableNestedInTable(state); * ``` */ export const isSelectionTableNestedInTable = state => { const table = findTable(state.selection); if (!table) { return false; } const parent = state.doc.resolve(table.pos).parent; const nodeTypes = state.schema.nodes; return [nodeTypes.tableHeader, nodeTypes.tableCell].includes(parent.type); }; /* * Returns true if the schema supports nesting tables inside table cells. * This is determined by checking if table cells can contain table nodes in their content model. * * ```typescript * const supportsNestedTables = isNestedTablesSupported(state.schema); * ``` */ export const isNestedTablesSupported = schema => { var _tableCell$contentMat, _tableHeader$contentM; const { table, tableCell, tableHeader } = schema.nodes; if (!table || !tableCell || !tableHeader) { return false; } // Check if table cells can contain table nodes by testing their content match const tableCellCanContainTable = ((_tableCell$contentMat = tableCell.contentMatch.matchType(table)) === null || _tableCell$contentMat === void 0 ? void 0 : _tableCell$contentMat.validEnd) === true; const tableHeaderCanContainTable = ((_tableHeader$contentM = tableHeader.contentMatch.matchType(table)) === null || _tableHeader$contentM === void 0 ? void 0 : _tableHeader$contentM.validEnd) === true; return tableCellCanContainTable || tableHeaderCanContainTable; }; /* * Returns true if the schema supports nesting a table inside a panel (panel_c1 variant), * AND the `platform_editor_nest_table_in_panel` experiment is enabled. * * ```typescript * const supportsTableInPanel = isPanelNestingTableSupported(state.schema); * ``` */ export const isPanelNestingTableSupported = schema => { var _panel_c1$contentMatc; const { table, panel_c1 } = schema.nodes; if (!table || !panel_c1) { return false; } // Confirm the PM schema actually allows table inside panel_c1 const panelC1CanContainTable = ((_panel_c1$contentMatc = panel_c1.contentMatch.matchType(table)) === null || _panel_c1$contentMatc === void 0 ? void 0 : _panel_c1$contentMatc.validEnd) === true; return panelC1CanContainTable && expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true); };