@atlaskit/editor-plugin-block-controls
Version:
Block controls plugin for @atlaskit/editor-core
204 lines (199 loc) • 9.53 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.canCreateNodeWithContentInsideAnotherNode = void 0;
exports.canMoveNodeToIndex = canMoveNodeToIndex;
exports.canMoveSliceToIndex = canMoveSliceToIndex;
exports.transformSliceExpandToNestedExpand = exports.transformFragmentExpandToNestedExpand = exports.transformExpandToNestedExpand = exports.memoizedTransformExpandToNestedExpand = exports.isNestedExpand = exports.isLayoutColumn = exports.isInsideTable = exports.isInSameLayout = exports.isFontSizeMarkActive = exports.isExpand = exports.isDoc = void 0;
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
var _nesting = require("@atlaskit/editor-common/nesting");
var _model = require("@atlaskit/editor-prosemirror/model");
var _utils = require("@atlaskit/editor-prosemirror/utils");
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
var isInsideTable = exports.isInsideTable = function isInsideTable(nodeType) {
var _nodeType$schema$node = nodeType.schema.nodes,
tableCell = _nodeType$schema$node.tableCell,
tableHeader = _nodeType$schema$node.tableHeader;
return [tableCell, tableHeader].indexOf(nodeType) >= 0;
};
var isLayoutColumn = exports.isLayoutColumn = function isLayoutColumn(nodeType) {
return nodeType === nodeType.schema.nodes.layoutColumn;
};
var isDoc = exports.isDoc = function isDoc(nodeType) {
return nodeType === nodeType.schema.nodes.doc;
};
var isExpand = exports.isExpand = function isExpand(nodeType) {
return nodeType === nodeType.schema.nodes.expand;
};
var isNestedExpand = exports.isNestedExpand = function isNestedExpand(nodeType) {
return nodeType === nodeType.schema.nodes.nestedExpand;
};
var isFontSizeMarkActive = exports.isFontSizeMarkActive = function isFontSizeMarkActive(node) {
return node.type.name === 'paragraph' && node.marks.some(function (mark) {
return mark.type.name === 'fontSize';
});
};
var isInSameLayout = exports.isInSameLayout = function isInSameLayout($from, $to) {
var fromNode = $from.nodeAfter;
var toNode = $to.nodeAfter;
return !!(fromNode && toNode && fromNode.type.name === 'layoutColumn' && ['layoutSection', 'layoutColumn'].includes(toNode.type.name) && (
// fromNode can either be in the same layoutSection as toNode or is a layoutColumn inside the toNode (type layoutSection)
$from.sameParent($to) || $from.parent === toNode));
};
/**
* This function converts an expand into a nested expand,
* although it may fail based on the expand's content.
* @param expandNode the node to transform.
* @returns an nested expand node
* @throws RangeError: Invalid content for node nestedExpand
*/
var transformExpandToNestedExpand = exports.transformExpandToNestedExpand = function transformExpandToNestedExpand(expandNode) {
var _expandNode$type$sche = expandNode.type.schema.nodes,
expand = _expandNode$type$sche.expand,
nestedExpand = _expandNode$type$sche.nestedExpand;
if (expandNode.type === expand) {
return nestedExpand.createChecked(expandNode.attrs, expandNode.content, expandNode.marks);
}
return null;
};
var transformFragmentExpandToNestedExpand = exports.transformFragmentExpandToNestedExpand = function transformFragmentExpandToNestedExpand(fragment) {
var children = [];
try {
fragment.forEach(function (node) {
if (isExpand(node.type)) {
var nestedExpandNode = transformExpandToNestedExpand(node);
if (nestedExpandNode) {
children.push(nestedExpandNode);
}
} else {
children.push(node);
}
});
} catch (e) {
return null;
}
return _model.Fragment.fromArray(children);
};
var transformSliceExpandToNestedExpand = exports.transformSliceExpandToNestedExpand = function transformSliceExpandToNestedExpand(slice) {
var fragment = transformFragmentExpandToNestedExpand(slice.content);
if (!fragment) {
return null;
}
return new _model.Slice(fragment, slice.openStart, slice.openEnd);
};
var memoizedTransformExpandToNestedExpand = exports.memoizedTransformExpandToNestedExpand = (0, _memoizeOne.default)(function (node) {
try {
return transformExpandToNestedExpand(node);
} catch (e) {
return null;
}
});
var canCreateNodeWithContentInsideAnotherNode = exports.canCreateNodeWithContentInsideAnotherNode = function canCreateNodeWithContentInsideAnotherNode(nodeTypesToCreate, nodeWithTargetFragment) {
try {
return !!nodeTypesToCreate.every(function (nodeTypeToCreate) {
return nodeTypeToCreate.createChecked({}, nodeWithTargetFragment);
});
} catch (e) {
return false;
}
};
function canMoveNodeToIndex(destParent, indexIntoParent, srcNode, $destNodePos, destNode) {
var srcNodeType = srcNode.type;
var schema = srcNodeType.schema;
var _schema$nodes = schema.nodes,
table = _schema$nodes.table,
tableCell = _schema$nodes.tableCell,
tableHeader = _schema$nodes.tableHeader,
expand = _schema$nodes.expand,
nestedExpand = _schema$nodes.nestedExpand,
doc = _schema$nodes.doc,
panel = _schema$nodes.panel,
layoutColumn = _schema$nodes.layoutColumn,
layoutSection = _schema$nodes.layoutSection;
var destParentNodeType = destParent === null || destParent === void 0 ? void 0 : destParent.type;
var activeNodeType = srcNode === null || srcNode === void 0 ? void 0 : srcNode.type;
var layoutColumnContent = srcNode.content;
var isNestingTablesSupported = (0, _nesting.isNestedTablesSupported)(schema);
if (activeNodeType === layoutColumn && (0, _experiments.editorExperiment)('advanced_layouts', true)) {
// Allow drag layout column and drop into layout section
if ((destNode === null || destNode === void 0 ? void 0 : destNode.type) === layoutSection || destParentNodeType === doc) {
return true;
}
if (destParentNodeType === tableCell || destParentNodeType === tableHeader) {
var contentContainsExpand = (0, _utils.findChildrenByType)(srcNode, expand).length > 0;
//convert expand to nestedExpand if there are expands inside the layout column
// otherwise, the createChecked will fail as expand is not a valid child of tableCell/tableHeader, but nestedExpand is
var convertedFragment = contentContainsExpand ? transformFragmentExpandToNestedExpand(layoutColumnContent) : layoutColumnContent;
if (!convertedFragment) {
return false;
}
return canCreateNodeWithContentInsideAnotherNode([tableCell, tableHeader], convertedFragment);
}
if (destParentNodeType === panel) {
return canCreateNodeWithContentInsideAnotherNode([panel], layoutColumnContent);
}
if (destParentNodeType === expand) {
return canCreateNodeWithContentInsideAnotherNode([expand], layoutColumnContent);
}
if (destParentNodeType === nestedExpand) {
return canCreateNodeWithContentInsideAnotherNode([nestedExpand], layoutColumnContent);
}
}
// NOTE: this will block drop targets from showing for dragging a table into another table
// unless nested tables are supported and the nesting depth does not exceed 1
if ((destParentNodeType === tableCell || destParentNodeType === tableHeader) && activeNodeType === table) {
var nestingDepth = (0, _nesting.getParentOfTypeCount)(table)($destNodePos);
if (!isNestingTablesSupported || isNestingTablesSupported && nestingDepth > 1) {
return false;
}
}
if (isInsideTable(destParent.type) && isExpand(srcNodeType)) {
if (memoizedTransformExpandToNestedExpand(srcNode)) {
srcNodeType = nestedExpand;
} else {
return false;
}
} else if ((isDoc(destParent.type) || isLayoutColumn(destParent.type)) && isNestedExpand(srcNodeType)) {
srcNodeType = expand;
}
return destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType);
}
function canMoveSliceToIndex(slice, sliceFromPos, sliceToPos, destParent, indexIntoParent, $destNodePos, destNode) {
var _slice$content$firstC;
var canMoveNodes = true;
var doc = $destNodePos.doc;
var nodesPos = [];
// Drag multiple nodes to be inside themselves not allowed
if ($destNodePos.pos < sliceToPos && $destNodePos.pos >= sliceFromPos) {
return false;
}
// Multiple layout columns do not drop correctly.
if (((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.type.name) === 'layoutColumn') {
return false;
}
for (var i = 0; i < slice.content.childCount; i++) {
var node = slice.content.maybeChild(i);
if (i === 0) {
nodesPos[i] = sliceFromPos;
} else {
var _slice$content$maybeC;
nodesPos[i] = nodesPos[i - 1] + (((_slice$content$maybeC = slice.content.maybeChild(i - 1)) === null || _slice$content$maybeC === void 0 ? void 0 : _slice$content$maybeC.nodeSize) || 0);
}
if (node && node.isInline) {
// If the node is an inline node, we need to find the parent node
// as passing in them into canMoveNodeToIndex will return false
var $nodePos = doc.resolve(nodesPos[i]);
var parentNode = $nodePos.parent;
if (!parentNode || parentNode && !canMoveNodeToIndex(destParent, indexIntoParent, parentNode, $destNodePos, destNode)) {
canMoveNodes = false;
break;
}
} else if (node && !canMoveNodeToIndex(destParent, indexIntoParent, node, $destNodePos, destNode)) {
canMoveNodes = false;
break;
}
}
return canMoveNodes;
}