@atlaskit/editor-plugin-block-menu
Version:
BlockMenu plugin for @atlaskit/editor-core
78 lines (73 loc) • 2.76 kB
JavaScript
import { isTextNode } from '../utils';
/**
* Creates a decisionItem with the given inline content.
*/
const createDecisionItem = (inlineContent, schema) => {
const decisionItemType = schema.nodes.decisionItem;
if (!decisionItemType) {
return null;
}
const canContentBeWrappedInDecisionItem = decisionItemType.validContent(inlineContent);
// Check if the content is valid for decisionItem
if (!canContentBeWrappedInDecisionItem) {
return null;
}
return decisionItemType.createAndFill({}, inlineContent);
};
/**
* Creates a decisionList containing the given decisionItems.
*/
const createDecisionListWithItems = (decisionItems, schema) => {
const decisionListType = schema.nodes.decisionList;
if (!decisionListType || decisionItems.length === 0) {
return null;
}
return decisionListType.createAndFill({}, decisionItems);
};
/**
* Wraps blockquote content into decisionList:
* - Text nodes (paragraph, heading) have their inline content extracted and wrapped in decisionItems
* - Consecutive text nodes are grouped into a single decisionList with multiple decisionItems
* - All other nodes break out (lists, code blocks, media, tables, macros, containers, etc.)
*
* The logic follows the transform rules:
* - Only flatten text nodes into decisionItem (since that's the intent - converting text to decisions)
* - Structures that can't be represented in a decisionItem should break out unchanged
* - When a break-out node is encountered, flush accumulated decisionItems into a decisionList
*
* Example: blockquote(p('a'), p('b'), ul(...), p('c')) → [decisionList(decisionItem('a'), decisionItem('b')), ul(...), decisionList(decisionItem('c'))]
*/
export const wrapBlockquoteToDecisionListStep = (nodes, context) => {
const {
schema
} = context;
const decisionItemType = schema.nodes.decisionItem;
if (!decisionItemType) {
return nodes;
}
const result = [];
let currentDecisionItems = [];
const flushCurrentDecisionList = () => {
if (currentDecisionItems.length > 0) {
const decisionList = createDecisionListWithItems(currentDecisionItems, schema);
if (decisionList) {
result.push(decisionList);
}
currentDecisionItems = [];
}
};
nodes.forEach(node => {
const decisionItem = isTextNode(node) ? createDecisionItem(node.content, schema) : null;
if (decisionItem) {
// Accumulate consecutive decisionItems
currentDecisionItems.push(decisionItem);
} else {
// Content can't be wrapped in decisionItem - break out the node
flushCurrentDecisionList();
result.push(node);
}
});
// Flush any remaining decisionItems
flushCurrentDecisionList();
return result.length > 0 ? result : nodes;
};