@atlaskit/editor-plugin-paste
Version:
Paste plugin for @atlaskit/editor-core
122 lines (116 loc) • 5.73 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.insertSliceAtNodeEdge = insertSliceAtNodeEdge;
exports.insertSliceInsideOfPanelNodeSelected = insertSliceInsideOfPanelNodeSelected;
exports.insertSliceIntoEmptyNode = insertSliceIntoEmptyNode;
exports.insertSliceIntoRangeSelectionInsideList = insertSliceIntoRangeSelectionInsideList;
var _utils = require("@atlaskit/editor-common/utils");
var _model = require("@atlaskit/editor-prosemirror/model");
var _state = require("@atlaskit/editor-prosemirror/state");
var _transform = require("@atlaskit/editor-prosemirror/transform");
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
function insertSliceIntoEmptyNode(_ref) {
var tr = _ref.tr,
slice = _ref.slice;
tr.replaceSelection(slice);
}
function insertSliceAtNodeEdge(_ref2) {
var tr = _ref2.tr,
slice = _ref2.slice;
var selection = tr.selection;
var _ref3 = selection,
$cursor = _ref3.$cursor;
if (!$cursor) {
return;
}
var position = !$cursor.nodeBefore ? $cursor.before() : $cursor.after();
tr.replaceRange(position, position, slice);
var startSlicePosition = tr.doc.resolve(Math.min(position + slice.content.size - slice.openEnd, tr.doc.content.size));
var direction = -1;
tr.setSelection(_state.TextSelection.near(startSlicePosition, direction));
}
function insertSliceIntoRangeSelectionInsideList(_ref4) {
var tr = _ref4.tr,
slice = _ref4.slice;
var _tr$selection = tr.selection,
$to = _tr$selection.$to,
$from = _tr$selection.$from,
to = _tr$selection.to,
from = _tr$selection.from;
// when the selection is inside of the same list item
// we can use a normal replace
if ($from.sameParent($to) || $from.depth === $to.depth) {
return tr.replaceSelection(slice);
}
// if pasting a list inside another list, ensure no empty list items get added
var newRange = $from.blockRange($to);
if (!newRange) {
return;
}
var startPos = from;
var endPos = $to.nodeAfter ? to : to + 2;
var newSlice = tr.doc.slice(endPos, newRange.end);
tr.deleteRange(startPos, newRange.end);
var mapped = tr.mapping.map(startPos);
tr.replaceRange(mapped, mapped, slice);
if (newSlice.size <= 0) {
return;
}
var newSelection = _state.TextSelection.near(tr.doc.resolve(tr.mapping.map(mapped)), -1);
// @ts-ignore - [unblock prosemirror bump] assigning to readonly prop
newSlice.openEnd = newSlice.openStart;
tr.replaceRange(newSelection.from, newSelection.from, newSlice);
tr.setSelection(_state.TextSelection.near(tr.doc.resolve(newSelection.from), -1));
}
function insertSliceInsideOfPanelNodeSelected(panelNode) {
return function (_ref5) {
var tr = _ref5.tr,
slice = _ref5.slice,
schema = _ref5.schema;
var selection = tr.selection,
_tr$selection2 = tr.selection,
$to = _tr$selection2.$to,
$from = _tr$selection2.$from;
var panelPosition = selection.from;
// if content of slice isn't valid for a panel node, insert the invalid node and following content after
if (panelNode && !panelNode.type.validContent(_model.Fragment.from(slice.content))) {
var _parentNode$firstChil;
var insertPosition = $to.pos + 1;
/* Adapting above logic to handle MBE, as it currently assumes that slice can be safely inserted after the panel node, which is not the case for MBE
If insertPosition is in MBE and current slice contains invalid content for MBE, we need to insert the slice after the MBE node
*/
if (schema) {
var mbeParentOfPanel = (0, _utils2.findParentNodeOfType)(schema.nodes.multiBodiedExtension)(selection);
if (mbeParentOfPanel && !mbeParentOfPanel.node.type.validContent(_model.Fragment.from(slice.content))) {
insertPosition = mbeParentOfPanel.start + mbeParentOfPanel.node.nodeSize - 1;
}
}
tr.replaceRange(insertPosition, insertPosition, slice);
// need to delete the empty paragraph at the top of the panel
var parentNode = tr.doc.resolve($from.before()).node();
if (parentNode && parentNode.childCount > 1 && ((_parentNode$firstChil = parentNode.firstChild) === null || _parentNode$firstChil === void 0 ? void 0 : _parentNode$firstChil.type.name) === 'paragraph' && (0, _utils.isEmptyParagraph)(parentNode.firstChild)) {
var startPosDelete = tr.doc.resolve($from.before()).posAtIndex(0);
var endPosDelete = tr.doc.resolve($from.before()).posAtIndex(1);
var SIZE_OF_EMPTY_PARAGRAPH = 2; // {startPos}<p>{startPos + 1}</p>{endPos}
if (endPosDelete - startPosDelete === SIZE_OF_EMPTY_PARAGRAPH) {
tr.delete(startPosDelete, endPosDelete);
}
}
tr.setSelection(_state.TextSelection.near(tr.doc.resolve(insertPosition + slice.content.size - slice.openStart - slice.openEnd + 1)));
return;
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
var temporaryDoc = new _transform.Transform(tr.doc.type.createAndFill());
temporaryDoc.replaceRange(0, temporaryDoc.doc.content.size, slice);
var sliceWithoutInvalidListSurrounding = temporaryDoc.doc.slice(0);
var newPanel = panelNode.copy(sliceWithoutInvalidListSurrounding.content);
var panelNodeSelected = selection instanceof _state.NodeSelection ? selection.node : null;
var replaceFrom = panelNodeSelected ? panelPosition : tr.doc.resolve(panelPosition).start();
var replaceTo = panelNodeSelected ? panelPosition + panelNodeSelected.nodeSize : replaceFrom;
tr.replaceRangeWith(replaceFrom, replaceTo, newPanel);
tr.setSelection(_state.TextSelection.near(tr.doc.resolve($from.pos + newPanel.content.size), -1));
};
}