@atlaskit/editor-plugin-block-menu
Version:
BlockMenu plugin for @atlaskit/editor-core
127 lines (125 loc) • 7.01 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import { isNodeTypeValidChildOf } from '@atlaskit/editor-common/utils/node-type-utils';
import { Fragment } from '@atlaskit/editor-prosemirror/model';
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { getTargetNodeTypeNameInContext } from '../transform-node-utils/utils';
import { TRANSFORMATION_MATRIX, TRANSFORMATION_MATRIX_PANEL_C1 } from './TRANSFORMATION_MATRIX';
import { getNodeName, toNodeTypeValue } from './types';
var LIST_NODE_TYPE_NAMES = new Set(['bulletList', 'orderedList', 'taskList', 'decisionList', 'listItem', 'taskItem', 'blockTaskItem', 'decisionItem']);
var shouldRecurseThroughListNode = function shouldRecurseThroughListNode(node) {
return LIST_NODE_TYPE_NAMES.has(node.type.name);
};
var _applyTargetNodeMarks = function applyTargetNodeMarks(node, targetNodeType, marksToAdd, marksToRemove, schema) {
var shouldRecurseIntoChildren = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : function () {
return true;
};
var nextNode = node;
if (node.type === targetNodeType) {
var marksAfterRemovals = (marksToRemove !== null && marksToRemove !== void 0 ? marksToRemove : []).reduce(function (currentMarks, name) {
var markType = schema.marks[name];
return markType ? markType.removeFromSet(currentMarks) : currentMarks;
}, node.marks);
var marks = Object.entries(marksToAdd !== null && marksToAdd !== void 0 ? marksToAdd : {}).reduce(function (currentMarks, _ref) {
var _ref2 = _slicedToArray(_ref, 2),
name = _ref2[0],
attrs = _ref2[1];
var markType = schema.marks[name];
return markType ? markType.create(attrs).addToSet(markType.removeFromSet(currentMarks)) : currentMarks;
}, marksAfterRemovals);
nextNode = node.mark(marks);
}
if (!shouldRecurseIntoChildren(nextNode) || nextNode.childCount === 0) {
return nextNode;
}
var children = [];
nextNode.forEach(function (child) {
return children.push(_applyTargetNodeMarks(child, targetNodeType, marksToAdd, marksToRemove, schema, shouldRecurseIntoChildren));
});
return nextNode.copy(Fragment.fromArray(children));
};
// Upgrade broken-out panel nodes to panel_c1 if the parent node allows it
export var upgradePanelNodesToPanelC1 = function upgradePanelNodesToPanelC1(nodes, parentNode, schema) {
if (!schema.nodes['panel_c1'] || !expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
return nodes;
}
return nodes.map(function (node) {
if (node.type.name === 'panel') {
var shouldUsePanelC1 = !parentNode || isNodeTypeValidChildOf('panel_c1', parentNode, schema);
if (shouldUsePanelC1) {
var _schema$nodes$panel_c;
return (_schema$nodes$panel_c = schema.nodes['panel_c1'].createAndFill(node.attrs, node.content, node.marks)) !== null && _schema$nodes$panel_c !== void 0 ? _schema$nodes$panel_c : node;
}
}
return node;
});
};
/**
* Convert a list of nodes to a target node type.
* If no steps are found, the source nodes are returned unchanged.
* If steps are found, they are applied to the source nodes in order.
* If a step returns an empty array, the source nodes are returned.
* If a step returns a non-empty array, that array is returned.
* @param args - The conversion arguments
* @param args.sourceNodes - The list of nodes to convert
* @param args.targetNodeType - The type of node to convert into
* @param args.schema - The schema to use for the conversion
* @param args.isNested - Whether the conversion is nested
* @param args.targetAttrs - The attributes to use for the conversion
* @param args.marksToAdd - Block marks to add or replace on converted target nodes
* @param args.marksToRemove - Block marks to remove from converted target nodes
* @param args.parentNode - The parent node of the selected node
* @returns The converted list of nodes
*/
export var convertNodesToTargetType = function convertNodesToTargetType(_ref3) {
var _steps$reduce;
var sourceNodes = _ref3.sourceNodes,
targetNodeType = _ref3.targetNodeType,
schema = _ref3.schema,
isNested = _ref3.isNested,
targetAttrs = _ref3.targetAttrs,
marksToAdd = _ref3.marksToAdd,
marksToRemove = _ref3.marksToRemove,
parentNode = _ref3.parentNode;
var sourceNode = sourceNodes.at(0);
if (!sourceNode) {
return sourceNodes;
}
var selectedNodeTypeName = toNodeTypeValue(getNodeName(sourceNodes));
var initialTargetNodeTypeName = toNodeTypeValue(targetNodeType.name);
var targetNodeTypeName = getTargetNodeTypeNameInContext(initialTargetNodeTypeName, isNested, parentNode, schema);
if (!selectedNodeTypeName || !targetNodeTypeName) {
return sourceNodes;
}
var steps = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? TRANSFORMATION_MATRIX_PANEL_C1[selectedNodeTypeName][targetNodeTypeName] : TRANSFORMATION_MATRIX[selectedNodeTypeName][targetNodeTypeName];
var shouldApplyTargetNodeMarkChanges = isExperimentEnabled('platform_editor_block_menu_small_text') && Boolean(marksToAdd || marksToRemove);
var context = {
// sourceNode is incorrect now - what to do here?
fromNode: sourceNode,
includeBlockTaskItems: shouldApplyTargetNodeMarkChanges,
targetNodeTypeName: targetNodeTypeName,
schema: schema,
targetAttrs: targetAttrs
};
if (!shouldApplyTargetNodeMarkChanges) {
if (!steps || steps.length === 0) {
return sourceNodes;
}
var _resultNodes = steps.reduce(function (nodes, step) {
return step(nodes, context);
}, sourceNodes);
return upgradePanelNodesToPanelC1(_resultNodes, parentNode, schema);
}
var shouldLimitTargetNodeMarkRecursion = targetNodeTypeName === 'paragraph' && ['multi', 'panel', 'panel_c1', 'expand', 'nestedExpand', 'blockquote', 'layoutSection'].includes(selectedNodeTypeName);
var resultNodes = (_steps$reduce = steps === null || steps === void 0 ? void 0 : steps.reduce(function (nodes, step) {
return step(nodes, context);
}, sourceNodes)) !== null && _steps$reduce !== void 0 ? _steps$reduce : sourceNodes;
var upgradedNodes = steps !== null && steps !== void 0 && steps.length ? upgradePanelNodesToPanelC1(resultNodes, parentNode, schema) : resultNodes;
return upgradedNodes.map(function (node) {
return _applyTargetNodeMarks(node, targetNodeType, marksToAdd, marksToRemove, schema, shouldLimitTargetNodeMarkRecursion ? shouldRecurseThroughListNode : undefined);
});
};
export var isTransformDisabledBasedOnStepsConfig = function isTransformDisabledBasedOnStepsConfig(selectedNodeType, targetNodeType) {
var steps = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? TRANSFORMATION_MATRIX_PANEL_C1[selectedNodeType][targetNodeType] : TRANSFORMATION_MATRIX[selectedNodeType][targetNodeType];
return !steps || steps.length === 0;
};