UNPKG

@atlaskit/editor-plugin-block-menu

Version:

BlockMenu plugin for @atlaskit/editor-core

217 lines (215 loc) 9.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.listToListStep = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _transforms = require("@atlaskit/editor-common/transforms"); var _model = require("@atlaskit/editor-prosemirror/model"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _nodeChecks = require("../nodeChecks"); /** * Recursively converts nested lists to the target list type. * This function handles the conversion of both the list container and its items, * including any nested lists within those items. * * Important: taskList has a different nesting structure than bulletList/orderedList: * - taskList: nested taskLists are SIBLINGS of taskItems in the parent taskList * - bulletList/orderedList: nested lists are CHILDREN of listItems */ var _transformList = function transformList(node, targetListType, targetItemType, unsupportedContent) { var schema = node.type.schema; var taskListType = schema.nodes.taskList; var isSourceTaskList = node.type === taskListType; var isTargetTaskList = targetListType === taskListType.name; var convertFromTaskListStructure = function convertFromTaskListStructure(node, targetListType, targetItemType) { var schema = node.type.schema; var targetListNodeType = schema.nodes[targetListType]; var transformedContent = []; node.forEach(function (child) { if ((0, _nodeChecks.isListWithIndentation)(child.type.name, schema)) { // This is a nested list - it should become a child of the previous item if (transformedContent.length > 0) { var previousItem = transformedContent[transformedContent.length - 1]; // Convert the nested list and add it to the previous item's content var transformedNestedList = _transformList(child, targetListType, targetItemType, unsupportedContent); var newContent = previousItem.content.append(_model.Fragment.from([transformedNestedList])); var updatedItem = previousItem.type.create(previousItem.attrs, newContent); transformedContent[transformedContent.length - 1] = updatedItem; } // If there's no previous item, skip this nested list (orphaned) } else { var transformedItem = transformListItem(child, targetListType, targetItemType); if (transformedItem) { transformedContent.push(transformedItem); } } }); return targetListNodeType.create(node.attrs, transformedContent); }; var convertToTaskListStructure = function convertToTaskListStructure(node, targetListType, targetItemType) { var schema = node.type.schema; var targetListNodeType = schema.nodes[targetListType]; var transformedContent = []; node.forEach(function (itemNode) { var transformedItem = transformListItem(itemNode, targetListType, targetItemType, true); if (transformedItem) { transformedContent.push(transformedItem); } itemNode.forEach(function (child) { if ((0, _nodeChecks.isListWithIndentation)(child.type.name, schema)) { transformedContent.push(_transformList(child, targetListType, targetItemType, unsupportedContent)); } }); }); return targetListNodeType.create(node.attrs, transformedContent); }; var transformListItem = function transformListItem(itemNode, targetListType, targetItemType) { var excludeNestedLists = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; var schema = itemNode.type.schema; var targetItemNodeType = schema.nodes[targetItemType]; var isTargetTaskItem = targetItemType === 'taskItem'; var isSourceTaskItem = itemNode.type.name === 'taskItem'; var paragraphType = schema.nodes.paragraph; if (isTargetTaskItem) { var inlineContent = []; var blockMarks = itemNode.marks; itemNode.forEach(function (child) { if (child.type === paragraphType) { inlineContent.push.apply(inlineContent, (0, _toConsumableArray2.default)(child.children)); if (child.marks.length > 0) { blockMarks = child.marks; } } else if (child.isInline) { inlineContent.push(child); // Nested lists will be extracted and placed as siblings in the taskList } else if (!(0, _nodeChecks.isListWithIndentation)(child.type.name, schema)) { unsupportedContent.push(child); } }); var blockTaskItem = schema.nodes.blockTaskItem; if (blockTaskItem && blockMarks.length > 0 && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) { return (0, _transforms.createBlockTaskItem)({ content: inlineContent, marks: blockMarks, schema: schema }); } return targetItemNodeType.create({}, inlineContent); } var transformedContent = []; if (isSourceTaskItem) { transformedContent.push(paragraphType.create(null, itemNode.content)); } else { itemNode.forEach(function (child) { if ((0, _nodeChecks.isListWithIndentation)(child.type.name, schema)) { if (excludeNestedLists) { // Skip nested lists - they will be handled separately as siblings return; } transformedContent.push(_transformList(child, targetListType, targetItemType, unsupportedContent)); } else { transformedContent.push(child); } }); } if (transformedContent.length === 0) { transformedContent.push(paragraphType.create()); } return targetItemNodeType.create({}, transformedContent); }; var convertList = function convertList(node, schema, targetListType, targetItemType) { var targetListNodeType = schema.nodes[targetListType]; var transformedContent = []; node.forEach(function (childNode) { var transformedItem = (0, _nodeChecks.isListWithIndentation)(childNode.type.name, schema) ? _transformList(childNode, targetListType, targetItemType, unsupportedContent) : transformListItem(childNode, targetListType, targetItemType); if (transformedItem) { transformedContent.push(transformedItem); } }); return targetListNodeType.create(node.attrs, transformedContent); }; if (isSourceTaskList && !isTargetTaskList) { return convertFromTaskListStructure(node, targetListType, targetItemType); } else if (!isSourceTaskList && isTargetTaskList) { return convertToTaskListStructure(node, targetListType, targetItemType); } return convertList(node, schema, targetListType, targetItemType); }; /** * Transform step that converts between bulletList, orderedList, and taskList types. * This step maintains the order and indentation of the list by recursively * converting all nested lists while preserving the structure. It also handles * conversion between listItem and taskItem types. * * When converting to taskList/taskItem, unsupported content (images, codeBlocks) is filtered out. * * @example * Input (bulletList with nested bulletList): * - bulletList * - listItem "1" * - bulletList * - listItem "1.1" * - bulletList * - listItem "1.1.1" * - listItem "1.2" * - listItem "2" * * Output (orderedList with nested orderedList): * 1. orderedList * 1. listItem "1" * 1. orderedList * 1. listItem "1.1" * 1. orderedList * 1. listItem "1.1.1" * 2. listItem "1.2" * 2. listItem "2" * * @example * Input (bulletList with nested taskList): * - bulletList * - listItem "Regular item" * - taskList * - taskItem "Task 1" (checked) * - taskItem "Task 2" (unchecked) * * Output (orderedList with nested orderedList, taskItems converted to listItems): * 1. orderedList * 1. listItem "Regular item" * 1. orderedList * 1. listItem "Task 1" * 2. listItem "Task 2" * * @example * Input (bulletList to taskList, with paragraph extraction): * - bulletList * - listItem * - paragraph "Text content" * - listItem * - paragraph "Text" * - codeBlock "code" * - mediaSingle (image) * * Output (taskList with text extracted from paragraphs, unsupported content filtered): * - taskList * - taskItem "Text content" (text extracted from paragraph) * - taskItem "Text" (text extracted, codeBlock and image filtered out) * * @param nodes - The nodes to transform * @param context - The transformation context containing schema and target node type * @returns The transformed nodes */ var listToListStep = exports.listToListStep = function listToListStep(nodes, context) { var schema = context.schema, targetNodeTypeName = context.targetNodeTypeName; var unsupportedContent = []; var transformedNodes = nodes.map(function (node) { if ((0, _nodeChecks.isListWithIndentation)(node.type.name, schema)) { var targetItemType = targetNodeTypeName === 'taskList' ? 'taskItem' : 'listItem'; return _transformList(node, targetNodeTypeName, targetItemType, unsupportedContent); } return node; }); return [].concat((0, _toConsumableArray2.default)(transformedNodes), unsupportedContent); };