@atlaskit/editor-plugin-block-controls
Version:
Block controls plugin for @atlaskit/editor-core
68 lines (65 loc) • 2.58 kB
JavaScript
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
};
};