UNPKG

@atlaskit/editor-plugin-content-insertion

Version:

Content insertion plugin for @atlaskit/editor-core

128 lines (122 loc) 4.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.insertProseMirrorContent = exports.insertInlineNodeOrFragment = exports.insertBlockNode = void 0; var _insert = require("@atlaskit/editor-common/insert"); var _model = require("@atlaskit/editor-prosemirror/model"); var _state = require("@atlaskit/editor-prosemirror/state"); /* Copied from type-ahead */ function findInsertPoint(doc, pos, nodeToInsert) { var $pos = doc.resolve(pos); var createInsertPosition = function createInsertPosition(from, to) { return { from: from, to: to || from }; }; // Search for a valid position for nodeToInsert in progressively higher levels for (var level = $pos.depth; level >= 0; level--) { var nodeAtLevel = $pos.node(level); // Try to replace the empty paragraph in the level above // Scenario: // doc( // table( // row( // cell( // p('{<>}'), // ), // ) // ) // ) var levelAbove = Math.max(level - 1, 0); var parentNode = $pos.node(levelAbove); // Special case: when this is true, the 'to' position should be the end // of the empty paragraph var isNodeAtLevelEmptyParagraph = nodeAtLevel.type.name === 'paragraph' && nodeAtLevel.content.size === 0; var indexAtLevelAbove = $pos.index(levelAbove); var canReplaceNodeAtLevelAbove = parentNode.canReplaceWith(indexAtLevelAbove, indexAtLevelAbove, nodeToInsert.type); if (isNodeAtLevelEmptyParagraph && canReplaceNodeAtLevelAbove) { var from = $pos.posAtIndex(indexAtLevelAbove, levelAbove); return createInsertPosition(from, from + nodeAtLevel.nodeSize); } // Try to insert this node right after the node in the level above // Scenario: // doc( // panel( // p('{<>}'), // ) // ) var indexAfterAtLevelAbove = $pos.indexAfter(levelAbove); var canInsertNodeAtLevelAbove = parentNode.canReplaceWith(indexAfterAtLevelAbove, indexAfterAtLevelAbove, nodeToInsert.type); if (canInsertNodeAtLevelAbove) { return createInsertPosition($pos.posAtIndex(indexAfterAtLevelAbove, levelAbove)); } } return createInsertPosition(0); } var insertBlockNode = exports.insertBlockNode = function insertBlockNode(_ref) { var node = _ref.node, tr = _ref.tr, position = _ref.position; var start = position.$from.pos, end = position.$to.pos; if (node.isText) { return tr.replaceWith(start, end, node); } if (node.isBlock) { var mappedStart = start; var nodeNormalized = (0, _insert.normaliseNestedLayout)(tr, node); // Handle edge cases for hr and mediaSingle var inserted = (0, _insert.safeInsert)(nodeNormalized, mappedStart)(tr); if (inserted) { return tr; } var sliceInserted = _model.Slice.maxOpen(_model.Fragment.from(nodeNormalized)); var _findInsertPoint = findInsertPoint(tr.doc, mappedStart, nodeNormalized), from = _findInsertPoint.from, to = _findInsertPoint.to; tr.replaceWith(from, to, node); var openPosition = Math.min(from + (node.isAtom ? node.nodeSize : sliceInserted.openStart), tr.doc.content.size); var FORWARD_DIRECTION = 1; var nextSelection = _state.TextSelection.findFrom(tr.doc.resolve(openPosition), FORWARD_DIRECTION, true); if (nextSelection) { return tr.setSelection(nextSelection); } } return tr; }; var insertInlineNodeOrFragment = exports.insertInlineNodeOrFragment = function insertInlineNodeOrFragment(_ref2) { var maybeFragment = _ref2.maybeFragment, tr = _ref2.tr, position = _ref2.position, selectInlineNode = _ref2.selectInlineNode; var start = position.$from.pos, end = position.$to.pos; var fragment = maybeFragment instanceof _model.Node ? _model.Fragment.from(maybeFragment) : maybeFragment; tr.replaceWith(start, end, fragment); if (selectInlineNode) { return tr.setSelection(_state.NodeSelection.create(tr.doc, start)); } return tr.setSelection(_state.TextSelection.near(tr.doc.resolve(start + ((fragment === null || fragment === void 0 ? void 0 : fragment.size) || 0)))); }; var insertProseMirrorContent = exports.insertProseMirrorContent = function insertProseMirrorContent(_ref3) { var tr = _ref3.tr, node = _ref3.node, position = _ref3.position, selectNodeInserted = _ref3.selectNodeInserted; if (node instanceof _model.Node && node.isBlock) { insertBlockNode({ node: node, tr: tr, position: position }); } else { insertInlineNodeOrFragment({ maybeFragment: node, tr: tr, position: position, selectInlineNode: selectNodeInserted }); } };