UNPKG

@atlaskit/editor-plugin-paste

Version:

Paste plugin for @atlaskit/editor-core

148 lines (144 loc) 6.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.insertSliceForLists = insertSliceForLists; exports.insertSliceForTaskInsideList = insertSliceForTaskInsideList; exports.insertSliceInsideBlockquote = insertSliceInsideBlockquote; exports.updateSelectionAfterReplace = updateSelectionAfterReplace; var _commands = require("@atlaskit/editor-common/commands"); 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"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _index = require("../index"); var _lists = require("./lists"); function insertSliceForLists(_ref) { var _slice$content$firstC; var tr = _ref.tr, slice = _ref.slice, schema = _ref.schema; var selection = tr.selection, _tr$selection = tr.selection, $to = _tr$selection.$to, $from = _tr$selection.$from; var _ref2 = selection, $cursor = _ref2.$cursor; var panelNode = (0, _index.isSelectionInsidePanel)(selection); var selectionIsInsideList = $from.blockRange($to, _utils.isListNode); if (!$cursor && selectionIsInsideList) { return (0, _lists.insertSliceIntoRangeSelectionInsideList)({ tr: tr, slice: slice }); } // if inside an empty panel, try and insert content inside it rather than replace it if (panelNode && (0, _index.isEmptyNode)(panelNode) && $from.node() === $to.node()) { return (0, _lists.insertSliceInsideOfPanelNodeSelected)(panelNode)({ tr: tr, slice: slice, schema: schema }); } if (!$cursor || selectionIsInsideList) { return tr.replaceSelection(slice); } if ((0, _index.isEmptyNode)(tr.doc.resolve($cursor.pos).node())) { return (0, _lists.insertSliceIntoEmptyNode)({ tr: tr, slice: slice }); } // When pasting a single list item into an action or decision, we skip the special "insert at node edge" // logic so that prosemirror pastes the list's content into the action/decision, rather than // pasting a whole list node directly after the action/decision item. (But we still preserve the // existing "insert at" node edge" behaviour if dealing with a list with more than one item, so that // it still inserts whole list node after the action/decision item). var pastingIntoActionOrDecision = Boolean((0, _utils2.findParentNodeOfType)([schema.nodes.taskList, schema.nodes.decisionList])(selection)); var oneListItem = slice.content.childCount === 1 && (0, _utils.isListNode)(slice.content.firstChild) && ((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.childCount) === 1; if (!(pastingIntoActionOrDecision && oneListItem) && (0, _index.isCursorSelectionAtTextStartOrEnd)(selection)) { return (0, _lists.insertSliceAtNodeEdge)({ tr: tr, slice: slice }); } tr.replaceSelection(slice); } var stripFontSizeInsideBlockquoteLists = function stripFontSizeInsideBlockquoteLists(tr, blockquotePos) { var _tr$doc$type$schema = tr.doc.type.schema, fontSize = _tr$doc$type$schema.marks.fontSize, _tr$doc$type$schema$n = _tr$doc$type$schema.nodes, paragraph = _tr$doc$type$schema$n.paragraph, listItem = _tr$doc$type$schema$n.listItem, taskItem = _tr$doc$type$schema$n.taskItem, blockTaskItem = _tr$doc$type$schema$n.blockTaskItem; var listItemParentNodeTypes = [listItem, taskItem, blockTaskItem]; if (!fontSize || !(0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) { return; } var containingBlockquote = tr.doc.nodeAt(blockquotePos); if (!containingBlockquote) { return; } var from = blockquotePos + 1; var to = blockquotePos + containingBlockquote.nodeSize - 1; (0, _commands.createToggleBlockMarkOnRangeNext)(fontSize, function () { return false; }, function (_schema, node, parent) { return node.type === paragraph && !!parent && listItemParentNodeTypes.some(function (nodeType) { return nodeType === parent.type; }); })(from, to, tr); }; function insertSliceInsideBlockquote(_ref3) { var tr = _ref3.tr, slice = _ref3.slice; //insert blockquote explicitly and set the selection in blockquote since replaceSelection will only insert the list var schema = tr.doc.type.schema; tr.replaceSelection(new _model.Slice(_model.Fragment.from(schema.nodes.blockquote.createAndFill()), 0, 0)); updateSelectionAfterReplace({ tr: tr }); tr.replaceSelection(slice); if ((0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) { var insertedBlockquotePos = (0, _utils2.findParentNodeOfType)(schema.nodes.blockquote)(tr.selection); if (!insertedBlockquotePos) { return; } stripFontSizeInsideBlockquoteLists(tr, insertedBlockquotePos.pos); } } function updateSelectionAfterReplace(_ref4) { var tr = _ref4.tr; // ProseMirror doesn't give a proper way to tell us where something was inserted. // However, we can know "how" it inserted something. // // So, instead of weird depth calculations, we can use the step produced by the transform. // For instance: // The `replaceStep.to and replaceStep.from`, tell us the real position // where the content will be insert. // Then, we can use the `tr.mapping.map` to the updated position after the replace operation var replaceStep = tr.steps[0]; if (!(replaceStep instanceof _transform.ReplaceStep)) { return tr; } var nextPosition = tr.mapping.map(replaceStep.to); // The findFrom will make search for both: TextSelection and NodeSelections. var nextSelection = _state.Selection.findFrom(tr.doc.resolve(Math.min(nextPosition, tr.doc.content.size)), -1); if (nextSelection) { tr.setSelection(nextSelection); } } function insertSliceForTaskInsideList(_ref5) { var tr = _ref5.tr, slice = _ref5.slice; var schema = tr.doc.type.schema; //To avoid the list being replaced with the tasklist, enclose the slice within a taskItem. var selectionBeforeReplace = tr.selection.from; tr.replaceSelection(new _model.Slice(_model.Fragment.from(schema.nodes.taskItem.createAndFill()), 0, 0)); var nextSelection = _state.Selection.near(tr.doc.resolve(selectionBeforeReplace + 1)); tr.setSelection(nextSelection); tr.replaceSelection(slice); }