@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
106 lines (99 loc) • 3.67 kB
JavaScript
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);
};