@atlaskit/editor-plugin-block-controls 3.16.2 → 3.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,54 @@
1
+ const IGNORE_NODES = ['tableRow', 'listItem', 'caption', 'media'];
2
+ const blockLeafNodes = ['blockCard', 'rule'];
3
+
4
+ /**
5
+ * This function returns the surrounding nodes of a given resolved position in the editor.
6
+ * It provides the position, node, parent, before and after nodes, index, and depth.
7
+ * @param state current editor state
8
+ * @param $pos a resolved position in the editor state.
9
+ * @returns {SurroundingNodes} An object containing the surrounding nodes information.
10
+ * @example
11
+ * const surroundingNodes = findSurroundingNodes(state, $pos);
12
+ */
13
+ export const findSurroundingNodes = (state, $pos, nodeType) => {
14
+ const depth = $pos.depth;
15
+
16
+ // special cases like hr rule here
17
+ if (blockLeafNodes.includes(nodeType || '') || $pos.pos === 0) {
18
+ const parent = $pos.node(depth);
19
+ const node = $pos.nodeAfter;
20
+ const index = $pos.index();
21
+ const before = index > 0 ? parent.child(index - 1) : null;
22
+ const after = index < parent.childCount - 1 ? parent.child(index + 1) : null;
23
+ return {
24
+ pos: $pos.pos,
25
+ node: node,
26
+ parent,
27
+ before,
28
+ after,
29
+ index,
30
+ depth: 1
31
+ };
32
+ }
33
+ const isRootNode = depth === 1;
34
+ const node = $pos.node(depth);
35
+ const isIgnoredNode = IGNORE_NODES.includes(node.type.name);
36
+ if (isIgnoredNode && !isRootNode) {
37
+ // If the node is an ignored node, we return the surrounding nodes of its parent
38
+ return findSurroundingNodes(state, state.doc.resolve($pos.before(depth - 1)));
39
+ }
40
+ const pos = $pos.before(depth);
41
+ const parent = isRootNode ? state.doc : $pos.node(depth - 1);
42
+ const index = $pos.index(depth - 1);
43
+ const before = index > 0 ? parent.child(index - 1) : null;
44
+ const after = index < parent.childCount - 1 ? parent.child(index + 1) : null;
45
+ return {
46
+ pos,
47
+ node,
48
+ parent,
49
+ before,
50
+ after,
51
+ index,
52
+ depth
53
+ };
54
+ };
@@ -11,11 +11,13 @@ import { fg } from '@atlaskit/platform-feature-flags';
11
11
  import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
12
12
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
13
13
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
14
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
15
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
15
16
  import { BLOCK_MENU_ENABLED } from '../ui/consts';
16
17
  import { findNodeDecs, nodeDecorations } from './decorations-anchor';
17
18
  import { dragHandleDecoration, emptyParagraphNodeDecorations, findHandleDec } from './decorations-drag-handle';
18
19
  import { dropTargetDecorations, findDropTargetDecs } from './decorations-drop-target';
20
+ import { getActiveDropTargetDecorations } from './decorations-drop-target-active';
19
21
  import { findQuickInsertInsertButtonDecoration, quickInsertButtonDecoration } from './decorations-quick-insert-button';
20
22
  import { handleMouseDown } from './handle-mouse-down';
21
23
  import { handleMouseOver } from './handle-mouse-over';
@@ -234,7 +236,7 @@ const getDecorationAtPos = (decorations, pos, to) => {
234
236
  return nodeDecAtActivePos;
235
237
  };
236
238
  export const apply = (api, formatMessage, tr, currentState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache) => {
237
- var _meta$multiSelectDnD, _activeNode, _activeNode2, _meta$activeNode$hand, _activeNode3, _activeNode4, _meta$isDragging, _meta$isDragging2, _meta$toggleMenu, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging, _meta$isShiftDown, _meta$lastDragCancell;
239
+ var _meta$multiSelectDnD, _activeNode, _activeNode2, _meta$activeNode$hand, _activeNode3, _activeNode4, _meta$isDragging2, _meta$isDragging3, _meta$toggleMenu, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging, _meta$isShiftDown, _meta$lastDragCancell;
238
240
  let {
239
241
  activeNode,
240
242
  decorations,
@@ -308,7 +310,15 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
308
310
  const hasJustFinishedResizing = resizerMeta === false;
309
311
  multiSelectDnD = (_meta$multiSelectDnD = meta === null || meta === void 0 ? void 0 : meta.multiSelectDnD) !== null && _meta$multiSelectDnD !== void 0 ? _meta$multiSelectDnD : multiSelectDnD;
310
312
  if (multiSelectDnD && flags.isMultiSelectEnabled) {
311
- multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || tr.selection.empty ? undefined : multiSelectDnD;
313
+ var _meta$isDragging;
314
+ if (((_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging) && expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
315
+ // When dragging, we want to keep the multiSelectDnD object unless both document and selection
316
+ // has changed, in which case we want to reset it.
317
+ const shouldResetMultiSelectDnD = tr.docChanged && tr.selectionSet && tr.selection.empty;
318
+ multiSelectDnD = shouldResetMultiSelectDnD ? undefined : multiSelectDnD;
319
+ } else {
320
+ multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || tr.selection.empty ? undefined : multiSelectDnD;
321
+ }
312
322
  }
313
323
  const maybeNodeCountChanged = !isAllText && numReplaceSteps > 0;
314
324
  let latestActiveNode;
@@ -424,17 +434,26 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
424
434
  }
425
435
 
426
436
  // Drop targets may be missing when the node count is being changed during a drag
427
- const isDropTargetsMissing = ((_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging) && maybeNodeCountChanged && !(meta !== null && meta !== void 0 && meta.nodeMoved);
437
+ const isDropTargetsMissing = ((_meta$isDragging2 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging2 !== void 0 ? _meta$isDragging2 : isDragging) && maybeNodeCountChanged && !(meta !== null && meta !== void 0 && meta.nodeMoved);
428
438
 
429
439
  // Remove drop target decorations when dragging stops or they need to be redrawn
430
440
  if ((meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || isDropTargetsMissing) {
431
441
  const dropTargetDecs = findDropTargetDecs(decorations);
432
442
  decorations = decorations.remove(dropTargetDecs);
433
443
  }
434
-
435
- // Add drop targets when dragging starts or some are missing
444
+ let currentActiveDropTargetNode = isDragging ? currentState.activeDropTargetNode : undefined;
436
445
  if (api) {
437
- if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
446
+ if (expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
447
+ if (meta !== null && meta !== void 0 && meta.activeDropTargetNode) {
448
+ currentActiveDropTargetNode = meta === null || meta === void 0 ? void 0 : meta.activeDropTargetNode;
449
+ const decos = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, formatMessage, nodeViewPortalProviderAPI, latestActiveNode);
450
+ decorations = decorations.remove(findDropTargetDecs(decorations));
451
+ if (decos.length > 0) {
452
+ decorations = decorations.add(newState.doc, decos);
453
+ }
454
+ }
455
+ } else if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
456
+ // Add drop targets when dragging starts or some are missing
438
457
  const decs = dropTargetDecorations(newState, api, formatMessage, nodeViewPortalProviderAPI, latestActiveNode, anchorRectCache);
439
458
  decorations = decorations.add(newState.doc, decs);
440
459
  }
@@ -470,7 +489,8 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
470
489
  return {
471
490
  decorations,
472
491
  activeNode: newActiveNode,
473
- isDragging: (_meta$isDragging2 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging2 !== void 0 ? _meta$isDragging2 : isDragging,
492
+ activeDropTargetNode: currentActiveDropTargetNode,
493
+ isDragging: (_meta$isDragging3 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging3 !== void 0 ? _meta$isDragging3 : isDragging,
474
494
  isMenuOpen: isMenuOpenNew,
475
495
  menuTriggerBy: editorExperiment('platform_editor_controls', 'variant1') ? (meta === null || meta === void 0 ? void 0 : (_meta$toggleMenu = meta.toggleMenu) === null || _meta$toggleMenu === void 0 ? void 0 : _meta$toggleMenu.anchorName) || menuTriggerBy : undefined,
476
496
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : editorHeight,
@@ -571,8 +591,25 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
571
591
  }
572
592
  return false;
573
593
  },
574
- dragenter(_view, event) {
575
- if (isAdvancedLayoutEnabled) {
594
+ dragenter(view, event) {
595
+ if (isHTMLElement(event.target) && expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
596
+ const targetElement = event.target.closest('[data-prosemirror-node-name]');
597
+ if (targetElement) {
598
+ var _api$blockControls$sh;
599
+ const nodeTypeName = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute('data-prosemirror-node-name');
600
+ const pos = view.posAtDOM(targetElement, -1);
601
+ const currentActiveDropTargetNode = api === null || api === void 0 ? void 0 : (_api$blockControls$sh = api.blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.activeDropTargetNode;
602
+ if ((currentActiveDropTargetNode === null || currentActiveDropTargetNode === void 0 ? void 0 : currentActiveDropTargetNode.pos) !== pos || (currentActiveDropTargetNode === null || currentActiveDropTargetNode === void 0 ? void 0 : currentActiveDropTargetNode.nodeTypeName) !== nodeTypeName) {
603
+ const activeDropTargetNode = {
604
+ pos,
605
+ nodeTypeName
606
+ };
607
+ view.dispatch(view.state.tr.setMeta(key, {
608
+ activeDropTargetNode
609
+ }));
610
+ }
611
+ }
612
+ } else if (isAdvancedLayoutEnabled) {
576
613
  if (isHTMLElement(event.target)) {
577
614
  const closestParentElement = event.target.closest('[data-drag-handler-anchor-depth="0"]');
578
615
  if (closestParentElement) {
@@ -651,8 +688,8 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
651
688
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
652
689
  }
653
690
  if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
654
- var _api$blockControls$sh;
655
- if (api !== null && api !== void 0 && (_api$blockControls$sh = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh !== void 0 && _api$blockControls$sh.isSelectedViaDragHandle) {
691
+ var _api$blockControls$sh2;
692
+ if (api !== null && api !== void 0 && (_api$blockControls$sh2 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh2 !== void 0 && _api$blockControls$sh2.isSelectedViaDragHandle) {
656
693
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
657
694
  }
658
695
  }
@@ -690,8 +727,8 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
690
727
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
691
728
  }
692
729
  if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
693
- var _api$blockControls$sh2;
694
- if (api !== null && api !== void 0 && (_api$blockControls$sh2 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh2 !== void 0 && _api$blockControls$sh2.isSelectedViaDragHandle) {
730
+ var _api$blockControls$sh3;
731
+ if (api !== null && api !== void 0 && (_api$blockControls$sh3 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh3 !== void 0 && _api$blockControls$sh3.isSelectedViaDragHandle) {
695
732
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
696
733
  }
697
734
  }
@@ -175,7 +175,7 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
175
175
  }
176
176
  },
177
177
  getSharedState: function getSharedState(editorState) {
178
- var _key$getState$isMenuO, _key$getState, _key$getState$menuTri, _key$getState2, _key$getState$activeN, _key$getState3, _key$getState$isDragg, _key$getState4, _key$getState$isPMDra, _key$getState5, _key$getState$multiSe, _key$getState6, _key$getState$isShift, _key$getState7, _key$getState$lastDra, _key$getState8, _interactionTrackingP, _key$getState$isSelec, _key$getState9;
178
+ var _key$getState$isMenuO, _key$getState, _key$getState$menuTri, _key$getState2, _key$getState$activeN, _key$getState3, _key$getState$activeD, _key$getState4, _key$getState$isDragg, _key$getState5, _key$getState$isPMDra, _key$getState6, _key$getState$multiSe, _key$getState7, _key$getState$isShift, _key$getState8, _key$getState$lastDra, _key$getState9, _interactionTrackingP, _key$getState$isSelec, _key$getState0;
179
179
  if (!editorState) {
180
180
  return undefined;
181
181
  }
@@ -183,13 +183,14 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
183
183
  isMenuOpen: (_key$getState$isMenuO = (_key$getState = key.getState(editorState)) === null || _key$getState === void 0 ? void 0 : _key$getState.isMenuOpen) !== null && _key$getState$isMenuO !== void 0 ? _key$getState$isMenuO : false,
184
184
  menuTriggerBy: (_key$getState$menuTri = (_key$getState2 = key.getState(editorState)) === null || _key$getState2 === void 0 ? void 0 : _key$getState2.menuTriggerBy) !== null && _key$getState$menuTri !== void 0 ? _key$getState$menuTri : undefined,
185
185
  activeNode: (_key$getState$activeN = (_key$getState3 = key.getState(editorState)) === null || _key$getState3 === void 0 ? void 0 : _key$getState3.activeNode) !== null && _key$getState$activeN !== void 0 ? _key$getState$activeN : undefined,
186
- isDragging: (_key$getState$isDragg = (_key$getState4 = key.getState(editorState)) === null || _key$getState4 === void 0 ? void 0 : _key$getState4.isDragging) !== null && _key$getState$isDragg !== void 0 ? _key$getState$isDragg : false,
187
- isPMDragging: (_key$getState$isPMDra = (_key$getState5 = key.getState(editorState)) === null || _key$getState5 === void 0 ? void 0 : _key$getState5.isPMDragging) !== null && _key$getState$isPMDra !== void 0 ? _key$getState$isPMDra : false,
188
- multiSelectDnD: (_key$getState$multiSe = (_key$getState6 = key.getState(editorState)) === null || _key$getState6 === void 0 ? void 0 : _key$getState6.multiSelectDnD) !== null && _key$getState$multiSe !== void 0 ? _key$getState$multiSe : undefined,
189
- isShiftDown: (_key$getState$isShift = (_key$getState7 = key.getState(editorState)) === null || _key$getState7 === void 0 ? void 0 : _key$getState7.isShiftDown) !== null && _key$getState$isShift !== void 0 ? _key$getState$isShift : undefined,
190
- lastDragCancelled: (_key$getState$lastDra = (_key$getState8 = key.getState(editorState)) === null || _key$getState8 === void 0 ? void 0 : _key$getState8.lastDragCancelled) !== null && _key$getState$lastDra !== void 0 ? _key$getState$lastDra : false,
186
+ activeDropTargetNode: (_key$getState$activeD = (_key$getState4 = key.getState(editorState)) === null || _key$getState4 === void 0 ? void 0 : _key$getState4.activeDropTargetNode) !== null && _key$getState$activeD !== void 0 ? _key$getState$activeD : undefined,
187
+ isDragging: (_key$getState$isDragg = (_key$getState5 = key.getState(editorState)) === null || _key$getState5 === void 0 ? void 0 : _key$getState5.isDragging) !== null && _key$getState$isDragg !== void 0 ? _key$getState$isDragg : false,
188
+ isPMDragging: (_key$getState$isPMDra = (_key$getState6 = key.getState(editorState)) === null || _key$getState6 === void 0 ? void 0 : _key$getState6.isPMDragging) !== null && _key$getState$isPMDra !== void 0 ? _key$getState$isPMDra : false,
189
+ multiSelectDnD: (_key$getState$multiSe = (_key$getState7 = key.getState(editorState)) === null || _key$getState7 === void 0 ? void 0 : _key$getState7.multiSelectDnD) !== null && _key$getState$multiSe !== void 0 ? _key$getState$multiSe : undefined,
190
+ isShiftDown: (_key$getState$isShift = (_key$getState8 = key.getState(editorState)) === null || _key$getState8 === void 0 ? void 0 : _key$getState8.isShiftDown) !== null && _key$getState$isShift !== void 0 ? _key$getState$isShift : undefined,
191
+ lastDragCancelled: (_key$getState$lastDra = (_key$getState9 = key.getState(editorState)) === null || _key$getState9 === void 0 ? void 0 : _key$getState9.lastDragCancelled) !== null && _key$getState$lastDra !== void 0 ? _key$getState$lastDra : false,
191
192
  isEditing: (_interactionTrackingP = interactionTrackingPluginKey.getState(editorState)) === null || _interactionTrackingP === void 0 ? void 0 : _interactionTrackingP.isEditing,
192
- isSelectedViaDragHandle: (_key$getState$isSelec = (_key$getState9 = key.getState(editorState)) === null || _key$getState9 === void 0 ? void 0 : _key$getState9.isSelectedViaDragHandle) !== null && _key$getState$isSelec !== void 0 ? _key$getState$isSelec : false
193
+ isSelectedViaDragHandle: (_key$getState$isSelec = (_key$getState0 = key.getState(editorState)) === null || _key$getState0 === void 0 ? void 0 : _key$getState0.isSelectedViaDragHandle) !== null && _key$getState$isSelec !== void 0 ? _key$getState$isSelec : false
193
194
  };
194
195
  },
195
196
  contentComponent: function contentComponent(_ref8) {
@@ -0,0 +1,149 @@
1
+ import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
2
+ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
3
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
4
+ import { getNodeAnchor, unmountDecorations } from './decorations-common';
5
+ import { createDropTargetDecoration } from './decorations-drop-target';
6
+ import { findSurroundingNodes } from './decorations-find-surrounding-nodes';
7
+ import { defaultActiveAnchorTracker } from './utils/active-anchor-tracker';
8
+ import { canMoveNodeToIndex, canMoveSliceToIndex, isInSameLayout } from './utils/validation';
9
+
10
+ /**
11
+ * List of parent node types that can have child nodes
12
+ */
13
+ var PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand', 'bodiedExtension'];
14
+
15
+ /**
16
+ * List of node types that does not allow drop targets at before or after the node.
17
+ */
18
+ var NODE_WITH_NO_PARENT_POS = ['tableCell', 'tableHeader', 'layoutColumn'];
19
+ var isContainerNode = function isContainerNode(node) {
20
+ return PARENT_WITH_END_DROP_TARGET.includes(node.type.name);
21
+ };
22
+ export var canMoveNodeOrSliceToPos = function canMoveNodeOrSliceToPos(state, node, parent, index, $toPos, activeNode) {
23
+ // For deciding to show drop targets or not when multiple nodes are selected
24
+ var selection = state.selection;
25
+ var _expandSelectionBound = expandSelectionBounds(selection.$anchor, selection.$head),
26
+ expandedAnchor = _expandSelectionBound.$anchor,
27
+ expandedHead = _expandSelectionBound.$head;
28
+ var selectionFrom = Math.min(expandedAnchor.pos, expandedHead.pos);
29
+ var selectionTo = Math.max(expandedAnchor.pos, expandedHead.pos);
30
+ var activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
31
+ var $activeNodePos = typeof activeNodePos === 'number' && state.doc.resolve(activeNodePos);
32
+ var activePMNode = $activeNodePos && $activeNodePos.nodeAfter;
33
+ var handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom && activeNodePos <= selectionTo;
34
+ if (editorExperiment('platform_editor_element_drag_and_drop_multiselect', true)) {
35
+ var selectionSlice = state.doc.slice(selectionFrom, selectionTo, false);
36
+ var selectionSliceChildCount = selectionSlice.content.childCount;
37
+ var canDropSingleNode = true;
38
+ var canDropMultipleNodes = true;
39
+
40
+ // when there is only one node in the slice, use the same logic as when multi select is not on
41
+ if (selectionSliceChildCount > 1 && handleInsideSelection) {
42
+ canDropMultipleNodes = canMoveSliceToIndex(selectionSlice, selectionFrom, selectionTo, parent, index, $toPos);
43
+ } else {
44
+ canDropSingleNode = !!(activePMNode && canMoveNodeToIndex(parent, index, activePMNode, $toPos, node));
45
+ }
46
+ if (!canDropMultipleNodes || !canDropSingleNode) {
47
+ return false;
48
+ }
49
+ } else {
50
+ var canDrop = activePMNode && canMoveNodeToIndex(parent, index, activePMNode, $toPos, node);
51
+ return canDrop;
52
+ }
53
+ return true;
54
+ };
55
+ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorations(activeDropTargetNode, state, api, formatMessage, nodeViewPortalProviderAPI, activeNode) {
56
+ unmountDecorations(nodeViewPortalProviderAPI, 'data-blocks-drop-target-container', 'data-blocks-drop-target-key');
57
+ var decs = [];
58
+ var activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
59
+ var $activeNodePos = typeof activeNodePos === 'number' && state.doc.resolve(activeNodePos);
60
+ var $toPos = state.doc.resolve(activeDropTargetNode.pos);
61
+ var _findSurroundingNodes = findSurroundingNodes(state, $toPos, activeDropTargetNode.nodeTypeName),
62
+ parent = _findSurroundingNodes.parent,
63
+ index = _findSurroundingNodes.index,
64
+ node = _findSurroundingNodes.node,
65
+ pos = _findSurroundingNodes.pos,
66
+ before = _findSurroundingNodes.before,
67
+ after = _findSurroundingNodes.after,
68
+ depth = _findSurroundingNodes.depth;
69
+
70
+ /**
71
+ * If the current node is a container node, we show the drop targets
72
+ * above the first child and below the last child.
73
+ */
74
+ if (isContainerNode(node)) {
75
+ // can move to before first child
76
+ if (node.firstChild && canMoveNodeOrSliceToPos(state, node.firstChild, node, 0, state.doc.resolve(pos + 1),
77
+ // +1 to get the position of the first child
78
+ activeNode)) {
79
+ decs.push(createDropTargetDecoration(pos + 1, {
80
+ api: api,
81
+ prevNode: undefined,
82
+ nextNode: node.firstChild,
83
+ parentNode: node,
84
+ formatMessage: formatMessage,
85
+ dropTargetStyle: 'default'
86
+ }, nodeViewPortalProviderAPI, 1));
87
+ }
88
+
89
+ // can move to after last child
90
+ if (node.lastChild && canMoveNodeOrSliceToPos(state, node.lastChild, node, node.childCount - 1, state.doc.resolve(pos + node.nodeSize - 1),
91
+ // -1 to get the position after last child
92
+ activeNode)) {
93
+ decs.push(createDropTargetDecoration(pos + node.nodeSize - 1, {
94
+ api: api,
95
+ prevNode: node.lastChild,
96
+ nextNode: undefined,
97
+ parentNode: node,
98
+ formatMessage: formatMessage,
99
+ dropTargetStyle: 'default'
100
+ }, nodeViewPortalProviderAPI, -1));
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Create drop target before and after the current node
106
+ */
107
+ if (!NODE_WITH_NO_PARENT_POS.includes(node.type.name)) {
108
+ var isSameLayout = $activeNodePos && isInSameLayout($activeNodePos, $toPos);
109
+ var isInSupportedContainer = ['tableCell', 'tableHeader', 'layoutColumn'].includes((parent === null || parent === void 0 ? void 0 : parent.type.name) || '');
110
+ var shouldShowFullHeight = isInSupportedContainer && (parent === null || parent === void 0 ? void 0 : parent.lastChild) === node && isEmptyParagraph(node);
111
+ if (canMoveNodeOrSliceToPos(state, node, parent, index, $toPos, activeNode)) {
112
+ decs.push(createDropTargetDecoration(pos, {
113
+ api: api,
114
+ prevNode: before || undefined,
115
+ nextNode: node,
116
+ parentNode: parent || undefined,
117
+ formatMessage: formatMessage,
118
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
119
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
120
+ }
121
+ if (canMoveNodeOrSliceToPos(state, node, parent, index + 1, state.doc.resolve(pos + node.nodeSize), activeNode)) {
122
+ decs.push(createDropTargetDecoration(pos + node.nodeSize, {
123
+ api: api,
124
+ prevNode: node,
125
+ nextNode: after || undefined,
126
+ parentNode: parent || undefined,
127
+ formatMessage: formatMessage,
128
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
129
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
130
+ }
131
+ }
132
+
133
+ // if the current node is not a top level node, we create one for advanced layout drop targets
134
+ if (depth > 1) {
135
+ var root = findSurroundingNodes(state, state.doc.resolve($toPos.before(2)));
136
+ decs.push(createDropTargetDecoration(root.pos, {
137
+ api: api,
138
+ prevNode: root.before || undefined,
139
+ nextNode: root.node,
140
+ parentNode: state.doc || undefined,
141
+ formatMessage: formatMessage,
142
+ dropTargetStyle: 'default'
143
+ }, nodeViewPortalProviderAPI, 0, undefined, false));
144
+ defaultActiveAnchorTracker.emit(getNodeAnchor(root.node));
145
+ } else {
146
+ defaultActiveAnchorTracker.emit(getNodeAnchor(node));
147
+ }
148
+ return decs;
149
+ };
@@ -0,0 +1,55 @@
1
+ var IGNORE_NODES = ['tableRow', 'listItem', 'caption', 'media'];
2
+ var blockLeafNodes = ['blockCard', 'rule'];
3
+
4
+ /**
5
+ * This function returns the surrounding nodes of a given resolved position in the editor.
6
+ * It provides the position, node, parent, before and after nodes, index, and depth.
7
+ * @param state current editor state
8
+ * @param $pos a resolved position in the editor state.
9
+ * @returns {SurroundingNodes} An object containing the surrounding nodes information.
10
+ * @example
11
+ * const surroundingNodes = findSurroundingNodes(state, $pos);
12
+ */
13
+ var _findSurroundingNodes = function findSurroundingNodes(state, $pos, nodeType) {
14
+ var depth = $pos.depth;
15
+
16
+ // special cases like hr rule here
17
+ if (blockLeafNodes.includes(nodeType || '') || $pos.pos === 0) {
18
+ var _parent = $pos.node(depth);
19
+ var _node = $pos.nodeAfter;
20
+ var _index = $pos.index();
21
+ var _before = _index > 0 ? _parent.child(_index - 1) : null;
22
+ var _after = _index < _parent.childCount - 1 ? _parent.child(_index + 1) : null;
23
+ return {
24
+ pos: $pos.pos,
25
+ node: _node,
26
+ parent: _parent,
27
+ before: _before,
28
+ after: _after,
29
+ index: _index,
30
+ depth: 1
31
+ };
32
+ }
33
+ var isRootNode = depth === 1;
34
+ var node = $pos.node(depth);
35
+ var isIgnoredNode = IGNORE_NODES.includes(node.type.name);
36
+ if (isIgnoredNode && !isRootNode) {
37
+ // If the node is an ignored node, we return the surrounding nodes of its parent
38
+ return _findSurroundingNodes(state, state.doc.resolve($pos.before(depth - 1)));
39
+ }
40
+ var pos = $pos.before(depth);
41
+ var parent = isRootNode ? state.doc : $pos.node(depth - 1);
42
+ var index = $pos.index(depth - 1);
43
+ var before = index > 0 ? parent.child(index - 1) : null;
44
+ var after = index < parent.childCount - 1 ? parent.child(index + 1) : null;
45
+ return {
46
+ pos: pos,
47
+ node: node,
48
+ parent: parent,
49
+ before: before,
50
+ after: after,
51
+ index: index,
52
+ depth: depth
53
+ };
54
+ };
55
+ export { _findSurroundingNodes as findSurroundingNodes };
@@ -14,11 +14,13 @@ import { fg } from '@atlaskit/platform-feature-flags';
14
14
  import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
15
15
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
16
16
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
17
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
17
18
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
18
19
  import { BLOCK_MENU_ENABLED } from '../ui/consts';
19
20
  import { findNodeDecs, nodeDecorations } from './decorations-anchor';
20
21
  import { dragHandleDecoration, emptyParagraphNodeDecorations, findHandleDec } from './decorations-drag-handle';
21
22
  import { dropTargetDecorations, findDropTargetDecs } from './decorations-drop-target';
23
+ import { getActiveDropTargetDecorations } from './decorations-drop-target-active';
22
24
  import { findQuickInsertInsertButtonDecoration, quickInsertButtonDecoration } from './decorations-quick-insert-button';
23
25
  import { handleMouseDown } from './handle-mouse-down';
24
26
  import { handleMouseOver } from './handle-mouse-over';
@@ -231,7 +233,7 @@ var getDecorationAtPos = function getDecorationAtPos(decorations, pos, to) {
231
233
  return nodeDecAtActivePos;
232
234
  };
233
235
  var _apply = function apply(api, formatMessage, tr, currentState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache) {
234
- var _meta$multiSelectDnD, _activeNode, _activeNode2, _meta$activeNode$hand, _activeNode3, _activeNode4, _meta$isDragging, _meta$isDragging2, _meta$toggleMenu, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging, _meta$isShiftDown, _meta$lastDragCancell;
236
+ var _meta$multiSelectDnD, _activeNode, _activeNode2, _meta$activeNode$hand, _activeNode3, _activeNode4, _meta$isDragging2, _meta$isDragging3, _meta$toggleMenu, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging, _meta$isShiftDown, _meta$lastDragCancell;
235
237
  var activeNode = currentState.activeNode,
236
238
  decorations = currentState.decorations,
237
239
  isResizerResizing = currentState.isResizerResizing,
@@ -300,7 +302,15 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
300
302
  var hasJustFinishedResizing = resizerMeta === false;
301
303
  multiSelectDnD = (_meta$multiSelectDnD = meta === null || meta === void 0 ? void 0 : meta.multiSelectDnD) !== null && _meta$multiSelectDnD !== void 0 ? _meta$multiSelectDnD : multiSelectDnD;
302
304
  if (multiSelectDnD && flags.isMultiSelectEnabled) {
303
- multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || tr.selection.empty ? undefined : multiSelectDnD;
305
+ var _meta$isDragging;
306
+ if (((_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging) && expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
307
+ // When dragging, we want to keep the multiSelectDnD object unless both document and selection
308
+ // has changed, in which case we want to reset it.
309
+ var shouldResetMultiSelectDnD = tr.docChanged && tr.selectionSet && tr.selection.empty;
310
+ multiSelectDnD = shouldResetMultiSelectDnD ? undefined : multiSelectDnD;
311
+ } else {
312
+ multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || tr.selection.empty ? undefined : multiSelectDnD;
313
+ }
304
314
  }
305
315
  var maybeNodeCountChanged = !isAllText && numReplaceSteps > 0;
306
316
  var latestActiveNode;
@@ -418,17 +428,26 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
418
428
  }
419
429
 
420
430
  // Drop targets may be missing when the node count is being changed during a drag
421
- var isDropTargetsMissing = ((_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging) && maybeNodeCountChanged && !(meta !== null && meta !== void 0 && meta.nodeMoved);
431
+ var isDropTargetsMissing = ((_meta$isDragging2 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging2 !== void 0 ? _meta$isDragging2 : isDragging) && maybeNodeCountChanged && !(meta !== null && meta !== void 0 && meta.nodeMoved);
422
432
 
423
433
  // Remove drop target decorations when dragging stops or they need to be redrawn
424
434
  if ((meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || isDropTargetsMissing) {
425
435
  var dropTargetDecs = findDropTargetDecs(decorations);
426
436
  decorations = decorations.remove(dropTargetDecs);
427
437
  }
428
-
429
- // Add drop targets when dragging starts or some are missing
438
+ var currentActiveDropTargetNode = isDragging ? currentState.activeDropTargetNode : undefined;
430
439
  if (api) {
431
- if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
440
+ if (expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
441
+ if (meta !== null && meta !== void 0 && meta.activeDropTargetNode) {
442
+ currentActiveDropTargetNode = meta === null || meta === void 0 ? void 0 : meta.activeDropTargetNode;
443
+ var decos = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, formatMessage, nodeViewPortalProviderAPI, latestActiveNode);
444
+ decorations = decorations.remove(findDropTargetDecs(decorations));
445
+ if (decos.length > 0) {
446
+ decorations = decorations.add(newState.doc, decos);
447
+ }
448
+ }
449
+ } else if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
450
+ // Add drop targets when dragging starts or some are missing
432
451
  var decs = dropTargetDecorations(newState, api, formatMessage, nodeViewPortalProviderAPI, latestActiveNode, anchorRectCache);
433
452
  decorations = decorations.add(newState.doc, decs);
434
453
  }
@@ -464,7 +483,8 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
464
483
  return {
465
484
  decorations: decorations,
466
485
  activeNode: newActiveNode,
467
- isDragging: (_meta$isDragging2 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging2 !== void 0 ? _meta$isDragging2 : isDragging,
486
+ activeDropTargetNode: currentActiveDropTargetNode,
487
+ isDragging: (_meta$isDragging3 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging3 !== void 0 ? _meta$isDragging3 : isDragging,
468
488
  isMenuOpen: isMenuOpenNew,
469
489
  menuTriggerBy: editorExperiment('platform_editor_controls', 'variant1') ? (meta === null || meta === void 0 || (_meta$toggleMenu = meta.toggleMenu) === null || _meta$toggleMenu === void 0 ? void 0 : _meta$toggleMenu.anchorName) || menuTriggerBy : undefined,
470
490
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : editorHeight,
@@ -564,8 +584,25 @@ export var createPlugin = function createPlugin(api, getIntl, nodeViewPortalProv
564
584
  }
565
585
  return false;
566
586
  },
567
- dragenter: function dragenter(_view, event) {
568
- if (isAdvancedLayoutEnabled) {
587
+ dragenter: function dragenter(view, event) {
588
+ if (isHTMLElement(event.target) && expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
589
+ var targetElement = event.target.closest('[data-prosemirror-node-name]');
590
+ if (targetElement) {
591
+ var _api$blockControls$sh;
592
+ var nodeTypeName = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute('data-prosemirror-node-name');
593
+ var pos = view.posAtDOM(targetElement, -1);
594
+ var currentActiveDropTargetNode = api === null || api === void 0 || (_api$blockControls$sh = api.blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.activeDropTargetNode;
595
+ if ((currentActiveDropTargetNode === null || currentActiveDropTargetNode === void 0 ? void 0 : currentActiveDropTargetNode.pos) !== pos || (currentActiveDropTargetNode === null || currentActiveDropTargetNode === void 0 ? void 0 : currentActiveDropTargetNode.nodeTypeName) !== nodeTypeName) {
596
+ var activeDropTargetNode = {
597
+ pos: pos,
598
+ nodeTypeName: nodeTypeName
599
+ };
600
+ view.dispatch(view.state.tr.setMeta(key, {
601
+ activeDropTargetNode: activeDropTargetNode
602
+ }));
603
+ }
604
+ }
605
+ } else if (isAdvancedLayoutEnabled) {
569
606
  if (isHTMLElement(event.target)) {
570
607
  var closestParentElement = event.target.closest('[data-drag-handler-anchor-depth="0"]');
571
608
  if (closestParentElement) {
@@ -639,8 +676,8 @@ export var createPlugin = function createPlugin(api, getIntl, nodeViewPortalProv
639
676
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
640
677
  }
641
678
  if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
642
- var _api$blockControls$sh;
643
- if (api !== null && api !== void 0 && (_api$blockControls$sh = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh !== void 0 && _api$blockControls$sh.isSelectedViaDragHandle) {
679
+ var _api$blockControls$sh2;
680
+ if (api !== null && api !== void 0 && (_api$blockControls$sh2 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh2 !== void 0 && _api$blockControls$sh2.isSelectedViaDragHandle) {
644
681
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
645
682
  }
646
683
  }
@@ -676,8 +713,8 @@ export var createPlugin = function createPlugin(api, getIntl, nodeViewPortalProv
676
713
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(_isDragHandle));
677
714
  }
678
715
  if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
679
- var _api$blockControls$sh2;
680
- if (api !== null && api !== void 0 && (_api$blockControls$sh2 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh2 !== void 0 && _api$blockControls$sh2.isSelectedViaDragHandle) {
716
+ var _api$blockControls$sh3;
717
+ if (api !== null && api !== void 0 && (_api$blockControls$sh3 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh3 !== void 0 && _api$blockControls$sh3.isSelectedViaDragHandle) {
681
718
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
682
719
  }
683
720
  }
@@ -22,6 +22,10 @@ export type ActiveNode = {
22
22
  rootAnchorName?: string;
23
23
  rootNodeType?: string;
24
24
  };
25
+ export type ActiveDropTargetNode = {
26
+ pos: number;
27
+ nodeTypeName: string | null;
28
+ };
25
29
  export type MultiSelectDnD = {
26
30
  anchor: number;
27
31
  head: number;
@@ -39,6 +43,7 @@ export interface PluginState {
39
43
  editorWidthLeft: number;
40
44
  editorWidthRight: number;
41
45
  activeNode?: ActiveNode;
46
+ activeDropTargetNode?: ActiveDropTargetNode;
42
47
  isResizerResizing: boolean;
43
48
  /**
44
49
  * @private
@@ -59,6 +64,7 @@ export type BlockControlsSharedState = {
59
64
  isMenuOpen: boolean;
60
65
  menuTriggerBy?: string;
61
66
  activeNode?: ActiveNode;
67
+ activeDropTargetNode?: ActiveDropTargetNode;
62
68
  isDragging: boolean;
63
69
  isPMDragging: boolean;
64
70
  multiSelectDnD?: MultiSelectDnD;
@@ -0,0 +1,9 @@
1
+ import { type IntlShape } from 'react-intl-next';
2
+ import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
3
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
4
+ import type { Node as PMNode, ResolvedPos } from '@atlaskit/editor-prosemirror/model';
5
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
6
+ import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
+ import type { ActiveDropTargetNode, ActiveNode, BlockControlsPlugin } from '../blockControlsPluginType';
8
+ export declare const canMoveNodeOrSliceToPos: (state: EditorState, node: PMNode, parent: PMNode, index: number, $toPos: ResolvedPos, activeNode?: ActiveNode) => boolean | null;
9
+ export declare const getActiveDropTargetDecorations: (activeDropTargetNode: ActiveDropTargetNode, state: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, formatMessage: IntlShape['formatMessage'], nodeViewPortalProviderAPI: PortalProviderAPI, activeNode?: ActiveNode) => Decoration[];
@@ -0,0 +1,22 @@
1
+ import type { Node as PMNode, ResolvedPos } from '@atlaskit/editor-prosemirror/model';
2
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
3
+ type SurroundingNodes = {
4
+ pos: number;
5
+ node: PMNode;
6
+ depth: number;
7
+ index: number;
8
+ parent: PMNode;
9
+ before: PMNode | null;
10
+ after: PMNode | null;
11
+ };
12
+ /**
13
+ * This function returns the surrounding nodes of a given resolved position in the editor.
14
+ * It provides the position, node, parent, before and after nodes, index, and depth.
15
+ * @param state current editor state
16
+ * @param $pos a resolved position in the editor state.
17
+ * @returns {SurroundingNodes} An object containing the surrounding nodes information.
18
+ * @example
19
+ * const surroundingNodes = findSurroundingNodes(state, $pos);
20
+ */
21
+ export declare const findSurroundingNodes: (state: EditorState, $pos: ResolvedPos, nodeType?: string | null) => SurroundingNodes;
22
+ export {};
@@ -5,7 +5,7 @@ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
5
5
  import type { EditorState, ReadonlyTransaction } from '@atlaskit/editor-prosemirror/state';
6
6
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
7
7
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
8
- import type { BlockControlsPlugin, PluginState } from '../blockControlsPluginType';
8
+ import type { ActiveDropTargetNode, BlockControlsPlugin, PluginState } from '../blockControlsPluginType';
9
9
  import { AnchorRectCache } from './utils/anchor-utils';
10
10
  export declare const key: PluginKey<PluginState>;
11
11
  export interface FlagType {
@@ -15,6 +15,7 @@ export declare const getDecorations: (state: EditorState) => DecorationSet | und
15
15
  export declare const apply: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, formatMessage: IntlShape['formatMessage'], tr: ReadonlyTransaction, currentState: PluginState, newState: EditorState, flags: FlagType, nodeViewPortalProviderAPI: PortalProviderAPI, anchorRectCache?: AnchorRectCache) => {
16
16
  decorations: DecorationSet;
17
17
  activeNode: any;
18
+ activeDropTargetNode: ActiveDropTargetNode | undefined;
18
19
  isDragging: any;
19
20
  isMenuOpen: boolean | undefined;
20
21
  menuTriggerBy: any;