UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

122 lines (118 loc) 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getShouldMoveNode = exports.getPosWhenMoveNodeUp = exports.getPosWhenMoveNodeDown = exports.getNodeBoundsFromSelection = exports.canMoveNodeUpOrDown = void 0; var _state = require("@atlaskit/editor-prosemirror/state"); var _utils = require("@atlaskit/editor-tables/utils"); var _experiments = require("@atlaskit/tmp-editor-statsig/experiments"); var _selection = require("../../pm-plugins/utils/selection"); /** * Gets the current node position and bounds from the selection using the preserved selection logic. * This ensures consistency with how the block controls plugin handles selection boundaries. * * Special handling for tables: When moving a table as a block, we need the outer table node's * position, not the internal cell selection that createPreservedSelection returns. * * @param selection The current editor selection * @returns An object with from and to positions, or undefined if selection is invalid */ var getNodeBoundsFromSelection = exports.getNodeBoundsFromSelection = function getNodeBoundsFromSelection(selection) { // Special case: if a table is selected, we want to move the entire table node var tableInfo = (0, _utils.findTable)(selection); if (tableInfo && (0, _utils.isTableSelected)(selection)) { var tablePos = tableInfo.pos; var tableTo = tablePos + tableInfo.node.nodeSize; return { from: tablePos, to: tableTo }; } // Special case: if a media node (file) is selected, we need to get the parent mediaGroup // This handles the case where clicking on a file creates a NodeSelection of the media node // but we want to move the entire mediaGroup that wraps it if (selection instanceof _state.NodeSelection && selection.node.type.name === 'media' && selection.node.attrs.type === 'file' && (0, _experiments.editorExperiment)('platform_editor_block_menu', true)) { // The media node is wrapped in a mediaGroup, so we need to get the parent position var mediaGroupPos = selection.$from.pos - 1; var mediaGroupNode = selection.$from.doc.nodeAt(mediaGroupPos); if (mediaGroupNode && mediaGroupNode.type.name === 'mediaGroup') { return { from: mediaGroupPos, to: mediaGroupPos + mediaGroupNode.nodeSize }; } } // Use createPreservedSelection to get properly expanded block boundaries var preservedSelection = (0, _selection.createPreservedSelection)(selection.$from, selection.$to); if (!preservedSelection) { return undefined; } return { from: preservedSelection.from, to: preservedSelection.to }; }; var getPosWhenMoveNodeUp = exports.getPosWhenMoveNodeUp = function getPosWhenMoveNodeUp($currentNodePos, currentNodePos) { var nodeIndex = $currentNodePos.index(); var nodeBefore = $currentNodePos.depth > 1 && nodeIndex === 0 ? $currentNodePos.node($currentNodePos.depth) : $currentNodePos.nodeBefore; if ((nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.type.name) === 'layoutColumn' && (0, _experiments.editorExperiment)('platform_editor_block_menu', true)) { return -1; } return nodeBefore ? currentNodePos - nodeBefore.nodeSize : -1; }; var getPosWhenMoveNodeDown = exports.getPosWhenMoveNodeDown = function getPosWhenMoveNodeDown(_ref) { var $currentNodePos = _ref.$currentNodePos, nodeAfterPos = _ref.nodeAfterPos, tr = _ref.tr; var endOfDoc = $currentNodePos.end(); if (nodeAfterPos > endOfDoc) { return -1; } var nodeAfter = tr.doc.nodeAt(nodeAfterPos); if ((0, _experiments.editorExperiment)('platform_editor_block_menu', true)) { var nodeAtCurrentPos = tr.doc.nodeAt($currentNodePos.pos); // if move empty line down to another empty line, move to the position of the next empty line if ((nodeAtCurrentPos === null || nodeAtCurrentPos === void 0 ? void 0 : nodeAtCurrentPos.content.size) === 0 && nodeAtCurrentPos.type.name !== 'extension' && (nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.content.size) === 0 && nodeAfter.type.name !== 'extension') { return nodeAfterPos; } } // if not the last node, move to the end of the next node return nodeAfter ? nodeAfterPos + nodeAfter.nodeSize : -1; }; var getShouldMoveNode = exports.getShouldMoveNode = function getShouldMoveNode(_ref2) { var currentNodePos = _ref2.currentNodePos, moveToPos = _ref2.moveToPos, tr = _ref2.tr; // only move the node if the destination is at the same depth, not support moving a nested node to a parent node return moveToPos > -1 && tr.doc.resolve(currentNodePos).depth === tr.doc.resolve(moveToPos).depth; }; var canMoveNodeUpOrDown = exports.canMoveNodeUpOrDown = function canMoveNodeUpOrDown(tr) { var nodeBounds = getNodeBoundsFromSelection(tr.selection); if (!nodeBounds || nodeBounds.from <= -1) { return { moveUp: false, moveDown: false }; } var currentNodePos = nodeBounds.from; var $currentNodePos = tr.doc.resolve(currentNodePos); var nodeAfterPos = nodeBounds.to; var moveUpPos = getPosWhenMoveNodeUp($currentNodePos, currentNodePos); var moveDownPos = getPosWhenMoveNodeDown({ $currentNodePos: $currentNodePos, nodeAfterPos: nodeAfterPos, tr: tr }); return { moveUp: getShouldMoveNode({ currentNodePos: currentNodePos, moveToPos: moveUpPos, tr: tr }), moveDown: getShouldMoveNode({ currentNodePos: currentNodePos, moveToPos: moveDownPos, tr: tr }) }; };