UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

139 lines (130 loc) 5.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.showDragHandleAtSelection = void 0; var _utils = require("@atlaskit/editor-prosemirror/utils"); var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); var _decorationsAnchor = require("../pm-plugins/decorations-anchor"); var _main = require("../pm-plugins/main"); var _getNestedNodePosition = require("../pm-plugins/utils/getNestedNodePosition"); var _domAttrName = require("../ui/utils/dom-attr-name"); var findParentPosForHandle = function findParentPosForHandle(state) { var _activeNode$handleOpt; var $from = state.selection.$from; var _ref = _main.key.getState(state) || {}, activeNode = _ref.activeNode; // if a node handle is already focused, return the parent pos of that node (with focused handle) if (activeNode && (_activeNode$handleOpt = activeNode.handleOptions) !== null && _activeNode$handleOpt !== void 0 && _activeNode$handleOpt.isFocused) { var $activeNodePos = state.doc.resolve(activeNode.pos); // if the handle is at the top level already, do nothing if ($activeNodePos.depth === 0) { return undefined; } return $activeNodePos.before(); } // if we are in second level of nested node, we should focus the node at level 1 if ($from.depth <= 1) { return $from.before(1); } // if we are inside a table, we should focus the table's handle var parentTableNode = (0, _utils.findParentNodeOfType)([state.schema.nodes.table])(state.selection); if (parentTableNode) { return parentTableNode.pos; } // else find closest parent node return (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? // With native anchor enabled, all nodes have anchor name attribute despite no drag handle support, e.g. listItem, caption, // as opposed to old approach, node decoration is only added to the node that have drag handle, // hence, we need to return the exact position of the node that can have drag handle (0, _getNestedNodePosition.getNestedNodeStartingPosition)({ selection: state.selection, schema: state.schema, resolve: state.doc.resolve.bind(state.doc) }) : (0, _getNestedNodePosition.getNestedNodePosition)({ selection: state.selection, schema: state.schema, resolve: state.doc.resolve.bind(state.doc) }); }; var findNextAnchorDecoration = function findNextAnchorDecoration(state) { var decorations = (0, _main.getDecorations)(state); if (!decorations) { return undefined; } var nextHandleNodePos = findParentPosForHandle(state); if (nextHandleNodePos === undefined) { return undefined; } var nextHandleNode = state.doc.nodeAt(nextHandleNodePos); var nodeDecorations = nextHandleNode && (0, _decorationsAnchor.findNodeDecs)(state, decorations, nextHandleNodePos, nextHandleNodePos + nextHandleNode.nodeSize); if (!nodeDecorations || nodeDecorations.length === 0) { return undefined; } // ensure the decoration covers the position of the look up node nodeDecorations = nodeDecorations.filter(function (decoration) { return decoration.from <= nextHandleNodePos; }); if (nodeDecorations.length === 0) { return undefined; } // sort the decorations by the position of the node // so we can find the closest decoration to the node nodeDecorations.sort(function (a, b) { if (a.from === b.from) { return a.to - b.to; } return b.from - a.from; }); // return the closest decoration to the node return nodeDecorations[0]; }; var findNextAnchorNode = function findNextAnchorNode(view) { var nextHandleNodePos = findParentPosForHandle(view.state); if (nextHandleNodePos === undefined) { return undefined; } var dom = view.nodeDOM(nextHandleNodePos); if (!(dom instanceof HTMLElement)) { return undefined; } var nodeDOM = dom.closest("[".concat(_domAttrName.NODE_ANCHOR_ATTR_NAME, "]")); if (!nodeDOM) { return undefined; } var nodeType = nodeDOM === null || nodeDOM === void 0 ? void 0 : nodeDOM.getAttribute(_domAttrName.NODE_NODE_TYPE_ATTR_NAME); var anchorName = nodeDOM === null || nodeDOM === void 0 ? void 0 : nodeDOM.getAttribute(_domAttrName.NODE_ANCHOR_ATTR_NAME); if (nodeType && anchorName) { return { pos: nextHandleNodePos, nodeType: nodeType, anchorName: anchorName }; } }; var showDragHandleAtSelection = exports.showDragHandleAtSelection = function showDragHandleAtSelection(api) { return function (state, _, view) { if (view && (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) { var anchorNode = findNextAnchorNode(view); if (api && anchorNode) { var pos = anchorNode.pos, anchorName = anchorNode.anchorName, nodeType = anchorNode.nodeType; api.core.actions.execute(api.blockControls.commands.showDragHandleAt(pos, anchorName, nodeType, { isFocused: true })); return true; } return false; } else { var decoration = findNextAnchorDecoration(state); if (api && decoration) { api.core.actions.execute(api.blockControls.commands.showDragHandleAt(decoration.from, decoration.spec.anchorName, decoration.spec.nodeTypeWithLevel, { isFocused: true })); return true; } return false; } }; };