@atlaskit/editor-plugin-block-controls
Version:
Block controls plugin for @atlaskit/editor-core
122 lines (118 loc) • 5.52 kB
JavaScript
"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
})
};
};