UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

68 lines (65 loc) 2.58 kB
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; const IGNORE_NODES = ['tableRow', 'listItem', 'caption', 'media']; const blockLeafNodes = ['blockCard', 'rule', 'extension']; const blockLeafNodeNext = ['blockCard', 'rule', 'extension', 'syncBlock']; const DISABLE_CHILD_DROP_TARGET = ['orderedList', 'bulletList']; /** * This function returns the surrounding nodes of a given resolved position in the editor. * It provides the position, node, parent, before and after nodes, index, and depth. * @param state current editor state * @param $pos a resolved position in the editor state. * @returns {SurroundingNodes} An object containing the surrounding nodes information. * @example * const surroundingNodes = findSurroundingNodes(state, $pos); */ export const findSurroundingNodes = (state, $pos, nodeType) => { const depth = $pos.depth; const blockLeafNodeList = editorExperiment('platform_synced_block_patch_6', true, { exposure: true }) ? blockLeafNodeNext : blockLeafNodes; // special cases like hr rule here if (blockLeafNodeList.includes(nodeType || '') || $pos.pos === 0) { const parent = $pos.node(depth); const node = $pos.nodeAfter; const index = $pos.index(); const before = index > 0 ? parent.child(index - 1) : null; const after = index < parent.childCount - 1 ? parent.child(index + 1) : null; return { pos: $pos.pos, node, parent, before, after, index, depth }; } const isRootNode = depth === 1; const node = $pos.node(depth); // go through the path to find the first node that is not allow child drop target // From top to bottom, we check the node types at each depth for (let i = 1; i < depth; i++) { const nodeType = $pos.node(i).type.name; if (DISABLE_CHILD_DROP_TARGET.includes(nodeType)) { return findSurroundingNodes(state, state.doc.resolve($pos.before(i + 1)), nodeType); } } if (IGNORE_NODES.includes(node.type.name) && !isRootNode) { // If the node is an ignored node, we return the surrounding nodes of its parent return findSurroundingNodes(state, state.doc.resolve($pos.before(depth - 1))); } const pos = depth > 0 ? $pos.before(depth) : 0; const parent = isRootNode ? state.doc : $pos.node(depth - 1); const index = $pos.index(depth - 1); const before = index > 0 ? parent.child(index - 1) : null; const after = index < parent.childCount - 1 ? parent.child(index + 1) : null; return { pos, node, parent, before, after, index, depth }; };