UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

119 lines (118 loc) 7.48 kB
import { fg } from '@atlaskit/platform-feature-flags/fg'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure'; import { getNodeTypeWithLevel } from './decorations-common'; var OPAQUE_BLOCKS = new Set(['table', 'bulletList', 'orderedList', 'taskList', 'decisionList', 'mediaSingle']); var EXCLUDED_BLOCKS = new Set(['listItem', 'tableRow', 'tableCell', 'tableHeader', 'caption']); var isPanelNodeTypeName = function isPanelNodeTypeName(nodeTypeName) { return nodeTypeName === 'panel' || nodeTypeName === 'panel_c1' && expValEqualsNoExposure('platform_editor_controls_reliable_anchor', 'isEnabled', true) && fg('platform_editor_controls_reliable_anchor_patch_1'); }; var redirectParagraphToWrappedMedia = function redirectParagraphToWrappedMedia(view, $target, targetPosition) { var node = view.state.doc.nodeAt(targetPosition); if (!node || node.type.name !== 'paragraph') { return { position: targetPosition, node: node }; } var index = $target.index(); for (var _i = 0, _arr = [index - 1, index + 1]; _i < _arr.length; _i++) { var siblingIndex = _arr[_i]; if (siblingIndex < 0 || siblingIndex >= $target.parent.childCount) { continue; } var sibling = $target.parent.child(siblingIndex); if ((sibling.type.name === 'mediaSingle' || sibling.type.name === 'embedCard') && (sibling.attrs.layout === 'wrap-left' || sibling.attrs.layout === 'wrap-right')) { return { position: siblingIndex < index ? targetPosition - sibling.nodeSize : targetPosition + node.nodeSize, node: sibling }; } } return { position: targetPosition, node: node }; }; /** Resolves hover from PM structure so the first hover can create its sparse candidate. */ export var handleSparseMouseOver = function handleSparseMouseOver(view, event, api) { var _api$editorDisabled$s, _api$editorDisabled, _api$editorViewMode, _api$showDiff$sharedS, _api$showDiff, _api$userIntent, _$pos$nodeAfter, _controls$activeNode, _anchors$get, _anchors$get2; var controls = api === null || api === void 0 ? void 0 : api.blockControls.sharedState.currentState(); if (!api || controls !== null && controls !== void 0 && controls.isDragging || !(event.target instanceof Element) || event.target === view.dom) { return false; } var editorDisabled = (_api$editorDisabled$s = (_api$editorDisabled = api.editorDisabled) === null || _api$editorDisabled === void 0 || (_api$editorDisabled = _api$editorDisabled.sharedState.currentState()) === null || _api$editorDisabled === void 0 ? void 0 : _api$editorDisabled.editorDisabled) !== null && _api$editorDisabled$s !== void 0 ? _api$editorDisabled$s : false; var editorViewMode = (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode; if (editorDisabled && (editorViewMode !== 'view' || !(controls !== null && controls !== void 0 && controls.rightSideControlsEnabled))) { return false; } var isDisplayingDiff = (_api$showDiff$sharedS = (_api$showDiff = api.showDiff) === null || _api$showDiff === void 0 || (_api$showDiff = _api$showDiff.sharedState.currentState()) === null || _api$showDiff === void 0 ? void 0 : _api$showDiff.isDisplayingChanges) !== null && _api$showDiff$sharedS !== void 0 ? _api$showDiff$sharedS : false; var currentUserIntent = (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || (_api$userIntent = _api$userIntent.sharedState.currentState()) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.currentUserIntent; if ((isDisplayingDiff || currentUserIntent === 'reviewing') && expValEqualsNoExposure('platform_editor_diff_plugin_extended', 'isEnabled', true)) { return false; } var position; try { position = view.posAtDOM(event.target, 0); } catch (_unused) { return false; } var $pos = view.state.doc.resolve(position); var targetPosition; var opaque = false; for (var depth = 1; depth <= $pos.depth; depth++) { var _node = $pos.node(depth); if (!_node.isBlock || EXCLUDED_BLOCKS.has(_node.type.name)) { continue; } targetPosition = $pos.before(depth); if (OPAQUE_BLOCKS.has(_node.type.name)) { opaque = true; break; } } if (!opaque && (_$pos$nodeAfter = $pos.nodeAfter) !== null && _$pos$nodeAfter !== void 0 && _$pos$nodeAfter.isBlock && !EXCLUDED_BLOCKS.has($pos.nodeAfter.type.name)) { // Browser positions over non-editable node chrome can resolve to the first editable child. // Keep the ancestor unless that child actually owns the hovered DOM target. var nodeAfterDOM = view.nodeDOM(position); if (nodeAfterDOM instanceof Element && nodeAfterDOM.contains(event.target)) { targetPosition = position; } } if (targetPosition === undefined) { return false; } var initialNode = view.state.doc.nodeAt(targetPosition); if (!initialNode) { return false; } var target = redirectParagraphToWrappedMedia(view, view.state.doc.resolve(targetPosition), targetPosition); targetPosition = target.position; var node = target.node; if (!node || (controls === null || controls === void 0 || (_controls$activeNode = controls.activeNode) === null || _controls$activeNode === void 0 ? void 0 : _controls$activeNode.pos) === targetPosition) { return false; } var $target = view.state.doc.resolve(targetPosition); if ($target.depth > 0 && (node.type.name === 'paragraph' || node.type.name === 'heading') && node.content.size === 0) { return false; } var parentNode = $target.parent; var parentPosition = $target.depth > 0 ? $target.before($target.depth) : undefined; var parentDOM = parentPosition === undefined ? undefined : view.nodeDOM(parentPosition); if (isPanelNodeTypeName(parentNode.type.name) && !(parentDOM instanceof HTMLElement && parentDOM.classList.contains('ak-editor-panel__no-icon')) && $target.index() === 0) { return false; } if (node.type.name === 'layoutColumn' && parentNode.type.name === 'layoutSection' && parentNode.childCount === 1 && expValEqualsNoExposure('advanced_layouts', 'isEnabled', true) && !expValEquals('platform_editor_layout_column_menu', 'isEnabled', true)) { return false; } var anchors = controls === null || controls === void 0 ? void 0 : controls.surfaceAnchors; var anchorName = (_anchors$get = anchors === null || anchors === void 0 ? void 0 : anchors.get(targetPosition)) !== null && _anchors$get !== void 0 ? _anchors$get : api.core.actions.getAnchorIdForNode(node, targetPosition); var rootPos = $target.depth > 0 ? $target.before(1) : targetPosition; var rootNode = view.state.doc.nodeAt(rootPos); var rootAnchorName = (_anchors$get2 = anchors === null || anchors === void 0 ? void 0 : anchors.get(rootPos)) !== null && _anchors$get2 !== void 0 ? _anchors$get2 : rootNode ? api.core.actions.getAnchorIdForNode(rootNode, rootPos) : undefined; if (!anchorName || !rootNode) { return false; } api.core.actions.execute(api.blockControls.commands.showDragHandleAt(targetPosition, anchorName, getNodeTypeWithLevel(node), undefined, rootPos, rootAnchorName !== null && rootAnchorName !== void 0 ? rootAnchorName : anchorName, getNodeTypeWithLevel(rootNode))); return false; };