@atlaskit/editor-plugin-block-controls 3.19.4 → 3.19.6

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.
@@ -1,5 +1,6 @@
1
1
  const IGNORE_NODES = ['tableRow', 'listItem', 'caption', 'media'];
2
2
  const blockLeafNodes = ['blockCard', 'rule'];
3
+ const DISABLE_CHILD_DROP_TARGET = ['orderedList', 'bulletList'];
3
4
 
4
5
  /**
5
6
  * This function returns the surrounding nodes of a given resolved position in the editor.
@@ -22,22 +23,30 @@ export const findSurroundingNodes = (state, $pos, nodeType) => {
22
23
  const after = index < parent.childCount - 1 ? parent.child(index + 1) : null;
23
24
  return {
24
25
  pos: $pos.pos,
25
- node: node,
26
+ node,
26
27
  parent,
27
28
  before,
28
29
  after,
29
30
  index,
30
- depth: 1
31
+ depth
31
32
  };
32
33
  }
33
34
  const isRootNode = depth === 1;
34
35
  const node = $pos.node(depth);
35
- const isIgnoredNode = IGNORE_NODES.includes(node.type.name);
36
- if (isIgnoredNode && !isRootNode) {
36
+
37
+ // go through the path to find the first node that is not allow child drop target
38
+ // From top to bottom, we check the node types at each depth
39
+ for (let i = 1; i < depth; i++) {
40
+ const nodeType = $pos.node(i).type.name;
41
+ if (DISABLE_CHILD_DROP_TARGET.includes(nodeType)) {
42
+ return findSurroundingNodes(state, state.doc.resolve($pos.before(i + 1)), nodeType);
43
+ }
44
+ }
45
+ if (IGNORE_NODES.includes(node.type.name) && !isRootNode) {
37
46
  // If the node is an ignored node, we return the surrounding nodes of its parent
38
47
  return findSurroundingNodes(state, state.doc.resolve($pos.before(depth - 1)));
39
48
  }
40
- const pos = $pos.before(depth);
49
+ const pos = depth > 0 ? $pos.before(depth) : 0;
41
50
  const parent = isRootNode ? state.doc : $pos.node(depth - 1);
42
51
  const index = $pos.index(depth - 1);
43
52
  const before = index > 0 ? parent.child(index - 1) : null;
@@ -1,4 +1,3 @@
1
- import { fg } from '@atlaskit/platform-feature-flags';
2
1
  export const handleMouseDown = api => (view, event) => {
3
2
  if (!(event.target instanceof HTMLElement)) {
4
3
  return false;
@@ -13,7 +12,7 @@ export const handleMouseDown = api => (view, event) => {
13
12
  return false;
14
13
  }
15
14
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.showDragHandleAt(rootPos, '', (_rootNode$type$name = rootNode.type.name) !== null && _rootNode$type$name !== void 0 ? _rootNode$type$name : '', undefined, rootPos, '', (_rootNode$type$name2 = rootNode.type.name) !== null && _rootNode$type$name2 !== void 0 ? _rootNode$type$name2 : ''));
16
- } else if (fg('platform_editor_controls_patch_5')) {
15
+ } else {
17
16
  const isDragHandle = event.target.closest('[data-editor-block-ctrl-drag-handle]') !== null;
18
17
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
19
18
  }
@@ -250,8 +250,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
250
250
  menuTriggerBy,
251
251
  isPMDragging,
252
252
  isShiftDown,
253
- lastDragCancelled,
254
- isSelectedViaDragHandle
253
+ lastDragCancelled
255
254
  } = currentState;
256
255
  let isActiveNodeDeleted = false;
257
256
  const {
@@ -442,12 +441,22 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
442
441
  let currentActiveDropTargetNode = isDragging ? currentState.activeDropTargetNode : undefined;
443
442
  if (api) {
444
443
  if (expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
444
+ // If page is updated while dragging (likely by remote updates), we simply remove the drop targets
445
+ // and add them back when the use interacts with the editor again
446
+ if (isDropTargetsMissing) {
447
+ const oldDropTargetDecs = findDropTargetDecs(decorations);
448
+ decorations = decorations.remove(oldDropTargetDecs);
449
+ }
445
450
  if (meta !== null && meta !== void 0 && meta.activeDropTargetNode) {
446
451
  currentActiveDropTargetNode = meta === null || meta === void 0 ? void 0 : meta.activeDropTargetNode;
447
- const decos = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, formatMessage, nodeViewPortalProviderAPI, latestActiveNode);
448
- decorations = decorations.remove(findDropTargetDecs(decorations));
449
- if (decos.length > 0) {
450
- decorations = decorations.add(newState.doc, decos);
452
+ const oldDropTargetDecs = findDropTargetDecs(decorations);
453
+ const {
454
+ decsToAdd,
455
+ decsToRemove
456
+ } = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, oldDropTargetDecs, formatMessage, nodeViewPortalProviderAPI, latestActiveNode);
457
+ decorations = decorations.remove(decsToRemove);
458
+ if (decsToAdd.length > 0) {
459
+ decorations = decorations.add(newState.doc, decsToAdd);
451
460
  }
452
461
  }
453
462
  } else if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
@@ -483,7 +492,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
483
492
  } else if (meta !== null && meta !== void 0 && meta.toggleMenu) {
484
493
  isMenuOpenNew = !isMenuOpen;
485
494
  }
486
- const isSelectedViaDragHandleNew = (meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle) !== undefined && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5') ? meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle : isSelectedViaDragHandle;
495
+ const isSelectedViaDragHandle = (meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle) !== undefined && editorExperiment('platform_editor_controls', 'variant1') && (meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle);
487
496
  return {
488
497
  decorations,
489
498
  activeNode: newActiveNode,
@@ -500,7 +509,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
500
509
  multiSelectDnD,
501
510
  isShiftDown: (_meta$isShiftDown = meta === null || meta === void 0 ? void 0 : meta.isShiftDown) !== null && _meta$isShiftDown !== void 0 ? _meta$isShiftDown : isShiftDown,
502
511
  lastDragCancelled: (_meta$lastDragCancell = meta === null || meta === void 0 ? void 0 : meta.lastDragCancelled) !== null && _meta$lastDragCancell !== void 0 ? _meta$lastDragCancell : lastDragCancelled,
503
- isSelectedViaDragHandle: isSelectedViaDragHandleNew
512
+ isSelectedViaDragHandle
504
513
  };
505
514
  };
506
515
  export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
@@ -656,7 +665,7 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
656
665
  handleMouseOver(view, event, api);
657
666
  return false;
658
667
  },
659
- mousedown: editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_2') ? handleMouseDown(api) : undefined,
668
+ mousedown: editorExperiment('platform_editor_controls', 'variant1') ? handleMouseDown(api) : undefined,
660
669
  keydown(view, event) {
661
670
  if (isMultiSelectEnabled) {
662
671
  if (event.shiftKey && event.ctrlKey) {
@@ -681,11 +690,11 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
681
690
  return true;
682
691
  }
683
692
  }
684
- if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
693
+ if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1')) {
685
694
  const isDragHandle = event.target.closest('[data-editor-block-ctrl-drag-handle="true"]') !== null;
686
695
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
687
696
  }
688
- if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
697
+ if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1')) {
689
698
  var _api$blockControls$sh2;
690
699
  if (api !== null && api !== void 0 && (_api$blockControls$sh2 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh2 !== void 0 && _api$blockControls$sh2.isSelectedViaDragHandle) {
691
700
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
@@ -720,11 +729,11 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
720
729
  return true;
721
730
  }
722
731
  }
723
- if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
732
+ if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1')) {
724
733
  const isDragHandle = event.target.closest('[data-editor-block-ctrl-drag-handle="true"]') !== null;
725
734
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
726
735
  }
727
- if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
736
+ if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1')) {
728
737
  var _api$blockControls$sh3;
729
738
  if (api !== null && api !== void 0 && (_api$blockControls$sh3 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh3 !== void 0 && _api$blockControls$sh3.isSelectedViaDragHandle) {
730
739
  api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
@@ -593,7 +593,7 @@ export const DragHandle = ({
593
593
  const node = parentPos !== undefined ? view.state.doc.nodeAt(parentPos) : undefined;
594
594
  const parentNodeType = node === null || node === void 0 ? void 0 : node.type.name;
595
595
  const supportsAnchor = CSS.supports('top', `anchor(${anchorName} start)`) && CSS.supports('left', `anchor(${anchorName} start)`);
596
- const safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_2') ? refreshAnchorName({
596
+ const safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') ? refreshAnchorName({
597
597
  getPos,
598
598
  view,
599
599
  anchorName
@@ -641,7 +641,7 @@ export const DragHandle = ({
641
641
  const node = parentPos !== undefined ? view.state.doc.nodeAt(parentPos) : undefined;
642
642
  const parentNodeType = node === null || node === void 0 ? void 0 : node.type.name;
643
643
  const supportsAnchor = CSS.supports('top', `anchor(${anchorName} start)`) && CSS.supports('left', `anchor(${anchorName} start)`);
644
- const safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_2') ? refreshAnchorName({
644
+ const safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') ? refreshAnchorName({
645
645
  getPos,
646
646
  view,
647
647
  anchorName
@@ -118,11 +118,11 @@ export const TypeAheadControl = ({
118
118
  // CHANGES - `removed editorExperiment('advanced_layouts', true) && isLayoutColumn` checks as quick insert button will not be positioned for layout column
119
119
  const calculatePosition = useCallback(() => {
120
120
  const supportsAnchor = CSS.supports('top', `anchor(${rootAnchorName} start)`) && CSS.supports('left', `anchor(${rootAnchorName} start)`);
121
- const safeAnchorName = fg('platform_editor_controls_patch_2') ? refreshAnchorName({
121
+ const safeAnchorName = refreshAnchorName({
122
122
  getPos,
123
123
  view,
124
124
  anchorName: rootAnchorName
125
- }) : rootAnchorName;
125
+ });
126
126
  const dom = view.dom.querySelector(`[data-drag-handler-anchor-name="${safeAnchorName}"]`);
127
127
  const hasResizer = rootNodeType === 'table' || rootNodeType === 'mediaSingle';
128
128
  const isExtension = rootNodeType === 'extension' || rootNodeType === 'bodiedExtension';
@@ -54,14 +54,20 @@ export var canMoveNodeOrSliceToPos = function canMoveNodeOrSliceToPos(state, nod
54
54
  }
55
55
  return true;
56
56
  };
57
- export var getActiveDropTargetDecorations = function getActiveDropTargetDecorations(activeDropTargetNode, state, api, formatMessage, nodeViewPortalProviderAPI, activeNode) {
57
+ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorations(activeDropTargetNode, state, api, existingDecs, formatMessage, nodeViewPortalProviderAPI, activeNode) {
58
58
  if (!fg('platform_editor_block_controls_drop_target_mem_fix')) {
59
59
  unmountDecorations(nodeViewPortalProviderAPI, 'data-blocks-drop-target-container', 'data-blocks-drop-target-key');
60
60
  }
61
- var decs = [];
61
+ var decsToAdd = [];
62
+ var decsToRemove = existingDecs.filter(function (dec) {
63
+ return !!dec;
64
+ });
62
65
  var activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
63
66
  var $activeNodePos = typeof activeNodePos === 'number' && state.doc.resolve(activeNodePos);
64
67
  var $toPos = state.doc.resolve(activeDropTargetNode.pos);
68
+ var existingDecsPos = decsToRemove.map(function (dec) {
69
+ return dec.from;
70
+ });
65
71
  var _findSurroundingNodes = findSurroundingNodes(state, $toPos, activeDropTargetNode.nodeTypeName),
66
72
  parent = _findSurroundingNodes.parent,
67
73
  index = _findSurroundingNodes.index,
@@ -76,32 +82,52 @@ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorati
76
82
  * above the first child and below the last child.
77
83
  */
78
84
  if (isContainerNode(node)) {
85
+ var isEmptyContainer = node.childCount === 0 || node.childCount === 1 && isEmptyParagraph(node.firstChild);
86
+
79
87
  // can move to before first child
80
- if (node.firstChild && canMoveNodeOrSliceToPos(state, node.firstChild, node, 0, state.doc.resolve(pos + 1),
81
- // +1 to get the position of the first child
82
- activeNode)) {
83
- decs.push(createDropTargetDecoration(pos + 1, {
84
- api: api,
85
- prevNode: undefined,
86
- nextNode: node.firstChild,
87
- parentNode: node,
88
- formatMessage: formatMessage,
89
- dropTargetStyle: 'default'
90
- }, nodeViewPortalProviderAPI, 1));
88
+ var posBeforeFirstChild = pos + 1; // +1 to get the position of the first child
89
+ if (node.firstChild && canMoveNodeOrSliceToPos(state, node.firstChild, node, 0, state.doc.resolve(posBeforeFirstChild), activeNode)) {
90
+ if (existingDecsPos.includes(posBeforeFirstChild)) {
91
+ // if the decoration already exists, we don't add it again.
92
+ decsToRemove = decsToRemove.filter(function (dec) {
93
+ return dec.from !== posBeforeFirstChild;
94
+ });
95
+ } else {
96
+ decsToAdd.push(createDropTargetDecoration(posBeforeFirstChild, {
97
+ api: api,
98
+ prevNode: undefined,
99
+ nextNode: node.firstChild,
100
+ parentNode: node,
101
+ formatMessage: formatMessage,
102
+ dropTargetStyle: isEmptyContainer ? 'remainingHeight' : 'default'
103
+ }, nodeViewPortalProviderAPI, 1));
104
+ }
91
105
  }
92
106
 
93
107
  // can move to after last child
94
- if (node.lastChild && canMoveNodeOrSliceToPos(state, node.lastChild, node, node.childCount - 1, state.doc.resolve(pos + node.nodeSize - 1),
95
- // -1 to get the position after last child
96
- activeNode)) {
97
- decs.push(createDropTargetDecoration(pos + node.nodeSize - 1, {
98
- api: api,
99
- prevNode: node.lastChild,
100
- nextNode: undefined,
101
- parentNode: node,
102
- formatMessage: formatMessage,
103
- dropTargetStyle: 'default'
104
- }, nodeViewPortalProviderAPI, -1));
108
+ // if the node is empty, we don't show the drop target at the end of the node
109
+ if (!isEmptyContainer) {
110
+ var posAfterLastChild = pos + node.nodeSize - 1; // -1 to get the position after last child
111
+
112
+ if (node.lastChild && canMoveNodeOrSliceToPos(state, node.lastChild, node, node.childCount - 1, state.doc.resolve(posAfterLastChild),
113
+ // -1 to get the position after last child
114
+ activeNode)) {
115
+ if (existingDecsPos.includes(posAfterLastChild)) {
116
+ // if the decoration already exists, we don't add it again.
117
+ decsToRemove = decsToRemove.filter(function (dec) {
118
+ return dec.from !== posAfterLastChild;
119
+ });
120
+ } else {
121
+ decsToAdd.push(createDropTargetDecoration(posAfterLastChild, {
122
+ api: api,
123
+ prevNode: node.lastChild,
124
+ nextNode: undefined,
125
+ parentNode: node,
126
+ formatMessage: formatMessage,
127
+ dropTargetStyle: 'remainingHeight'
128
+ }, nodeViewPortalProviderAPI, -1));
129
+ }
130
+ }
105
131
  }
106
132
  }
107
133
 
@@ -113,24 +139,41 @@ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorati
113
139
  var isInSupportedContainer = ['tableCell', 'tableHeader', 'layoutColumn'].includes((parent === null || parent === void 0 ? void 0 : parent.type.name) || '');
114
140
  var shouldShowFullHeight = isInSupportedContainer && (parent === null || parent === void 0 ? void 0 : parent.lastChild) === node && isEmptyParagraph(node);
115
141
  if (canMoveNodeOrSliceToPos(state, node, parent, index, $toPos, activeNode)) {
116
- decs.push(createDropTargetDecoration(pos, {
117
- api: api,
118
- prevNode: before || undefined,
119
- nextNode: node,
120
- parentNode: parent || undefined,
121
- formatMessage: formatMessage,
122
- dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
123
- }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
142
+ if (existingDecsPos.includes(pos)) {
143
+ // if the decoration already exists, we don't add it again.
144
+ decsToRemove = decsToRemove.filter(function (dec) {
145
+ return dec.from !== pos;
146
+ });
147
+ } else {
148
+ decsToAdd.push(createDropTargetDecoration(pos, {
149
+ api: api,
150
+ prevNode: before || undefined,
151
+ nextNode: node,
152
+ parentNode: parent || undefined,
153
+ formatMessage: formatMessage,
154
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
155
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
156
+ }
124
157
  }
125
- if (canMoveNodeOrSliceToPos(state, node, parent, index + 1, state.doc.resolve(pos + node.nodeSize), activeNode)) {
126
- decs.push(createDropTargetDecoration(pos + node.nodeSize, {
127
- api: api,
128
- prevNode: node,
129
- nextNode: after || undefined,
130
- parentNode: parent || undefined,
131
- formatMessage: formatMessage,
132
- dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
133
- }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
158
+
159
+ // if the node is a container node, we show the drop target after the node
160
+ var posAfterNode = pos + node.nodeSize;
161
+ if (canMoveNodeOrSliceToPos(state, node, parent, index + 1, state.doc.resolve(posAfterNode), activeNode)) {
162
+ if (existingDecsPos.includes(posAfterNode)) {
163
+ // if the decoration already exists, we don't add it again.
164
+ decsToRemove = decsToRemove.filter(function (dec) {
165
+ return dec.from !== posAfterNode;
166
+ });
167
+ } else {
168
+ decsToAdd.push(createDropTargetDecoration(posAfterNode, {
169
+ api: api,
170
+ prevNode: node,
171
+ nextNode: after || undefined,
172
+ parentNode: parent || undefined,
173
+ formatMessage: formatMessage,
174
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
175
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
176
+ }
134
177
  }
135
178
  }
136
179
  var rootNodeWithPos = {
@@ -141,14 +184,21 @@ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorati
141
184
  // if the current node is not a top level node, we create one for advanced layout drop targets
142
185
  if (depth > 1) {
143
186
  var root = findSurroundingNodes(state, state.doc.resolve($toPos.before(2)));
144
- decs.push(createDropTargetDecoration(root.pos, {
145
- api: api,
146
- prevNode: root.before || undefined,
147
- nextNode: root.node,
148
- parentNode: state.doc || undefined,
149
- formatMessage: formatMessage,
150
- dropTargetStyle: 'default'
151
- }, nodeViewPortalProviderAPI, 0, undefined, false));
187
+ if (existingDecsPos.includes(root.pos)) {
188
+ // if the decoration already exists, we don't add it again.
189
+ decsToRemove = decsToRemove.filter(function (dec) {
190
+ return dec.from !== root.pos;
191
+ });
192
+ } else {
193
+ decsToAdd.push(createDropTargetDecoration(root.pos, {
194
+ api: api,
195
+ prevNode: root.before || undefined,
196
+ nextNode: root.node,
197
+ parentNode: state.doc || undefined,
198
+ formatMessage: formatMessage,
199
+ dropTargetStyle: 'default'
200
+ }, nodeViewPortalProviderAPI, 0, undefined, false));
201
+ }
152
202
  rootNodeWithPos = {
153
203
  node: root.node,
154
204
  pos: root.pos
@@ -162,11 +212,19 @@ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorati
162
212
  layoutSectionNode.descendants(function (childNode, childPos, parent, index) {
163
213
  if (childNode.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && index !== 0 // Not the first node
164
214
  ) {
165
- decs.push(createLayoutDropTargetDecoration(rootNodeWithPos.pos + childPos + 1, {
166
- api: api,
167
- parent: parent,
168
- formatMessage: formatMessage
169
- }, nodeViewPortalProviderAPI, undefined));
215
+ var currentPos = rootNodeWithPos.pos + childPos + 1;
216
+ if (existingDecsPos.includes(currentPos)) {
217
+ // if the decoration already exists, we don't add it again.
218
+ decsToRemove = decsToRemove.filter(function (dec) {
219
+ return dec.from !== currentPos;
220
+ });
221
+ } else {
222
+ decsToAdd.push(createLayoutDropTargetDecoration(rootNodeWithPos.pos + childPos + 1, {
223
+ api: api,
224
+ parent: parent,
225
+ formatMessage: formatMessage
226
+ }, nodeViewPortalProviderAPI, undefined));
227
+ }
170
228
  }
171
229
  return false;
172
230
  });
@@ -174,5 +232,8 @@ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorati
174
232
  }
175
233
  }
176
234
  defaultActiveAnchorTracker.emit(getNodeAnchor(rootNodeWithPos.node));
177
- return decs;
235
+ return {
236
+ decsToAdd: decsToAdd,
237
+ decsToRemove: decsToRemove
238
+ };
178
239
  };
@@ -1,5 +1,6 @@
1
1
  var IGNORE_NODES = ['tableRow', 'listItem', 'caption', 'media'];
2
2
  var blockLeafNodes = ['blockCard', 'rule'];
3
+ var DISABLE_CHILD_DROP_TARGET = ['orderedList', 'bulletList'];
3
4
 
4
5
  /**
5
6
  * This function returns the surrounding nodes of a given resolved position in the editor.
@@ -27,17 +28,25 @@ var _findSurroundingNodes = function findSurroundingNodes(state, $pos, nodeType)
27
28
  before: _before,
28
29
  after: _after,
29
30
  index: _index,
30
- depth: 1
31
+ depth: depth
31
32
  };
32
33
  }
33
34
  var isRootNode = depth === 1;
34
35
  var node = $pos.node(depth);
35
- var isIgnoredNode = IGNORE_NODES.includes(node.type.name);
36
- if (isIgnoredNode && !isRootNode) {
36
+
37
+ // go through the path to find the first node that is not allow child drop target
38
+ // From top to bottom, we check the node types at each depth
39
+ for (var i = 1; i < depth; i++) {
40
+ var _nodeType = $pos.node(i).type.name;
41
+ if (DISABLE_CHILD_DROP_TARGET.includes(_nodeType)) {
42
+ return _findSurroundingNodes(state, state.doc.resolve($pos.before(i + 1)), _nodeType);
43
+ }
44
+ }
45
+ if (IGNORE_NODES.includes(node.type.name) && !isRootNode) {
37
46
  // If the node is an ignored node, we return the surrounding nodes of its parent
38
47
  return _findSurroundingNodes(state, state.doc.resolve($pos.before(depth - 1)));
39
48
  }
40
- var pos = $pos.before(depth);
49
+ var pos = depth > 0 ? $pos.before(depth) : 0;
41
50
  var parent = isRootNode ? state.doc : $pos.node(depth - 1);
42
51
  var index = $pos.index(depth - 1);
43
52
  var before = index > 0 ? parent.child(index - 1) : null;
@@ -1,4 +1,3 @@
1
- import { fg } from '@atlaskit/platform-feature-flags';
2
1
  export var handleMouseDown = function handleMouseDown(api) {
3
2
  return function (view, event) {
4
3
  if (!(event.target instanceof HTMLElement)) {
@@ -14,7 +13,7 @@ export var handleMouseDown = function handleMouseDown(api) {
14
13
  return false;
15
14
  }
16
15
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.showDragHandleAt(rootPos, '', (_rootNode$type$name = rootNode.type.name) !== null && _rootNode$type$name !== void 0 ? _rootNode$type$name : '', undefined, rootPos, '', (_rootNode$type$name2 = rootNode.type.name) !== null && _rootNode$type$name2 !== void 0 ? _rootNode$type$name2 : ''));
17
- } else if (fg('platform_editor_controls_patch_5')) {
16
+ } else {
18
17
  var isDragHandle = event.target.closest('[data-editor-block-ctrl-drag-handle]') !== null;
19
18
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
20
19
  }
@@ -244,8 +244,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
244
244
  menuTriggerBy = currentState.menuTriggerBy,
245
245
  isPMDragging = currentState.isPMDragging,
246
246
  isShiftDown = currentState.isShiftDown,
247
- lastDragCancelled = currentState.lastDragCancelled,
248
- isSelectedViaDragHandle = currentState.isSelectedViaDragHandle;
247
+ lastDragCancelled = currentState.lastDragCancelled;
249
248
  var isActiveNodeDeleted = false;
250
249
  var _getTrMetadata = getTrMetadata(tr),
251
250
  from = _getTrMetadata.from,
@@ -436,12 +435,21 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
436
435
  var currentActiveDropTargetNode = isDragging ? currentState.activeDropTargetNode : undefined;
437
436
  if (api) {
438
437
  if (expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
438
+ // If page is updated while dragging (likely by remote updates), we simply remove the drop targets
439
+ // and add them back when the use interacts with the editor again
440
+ if (isDropTargetsMissing) {
441
+ var oldDropTargetDecs = findDropTargetDecs(decorations);
442
+ decorations = decorations.remove(oldDropTargetDecs);
443
+ }
439
444
  if (meta !== null && meta !== void 0 && meta.activeDropTargetNode) {
440
445
  currentActiveDropTargetNode = meta === null || meta === void 0 ? void 0 : meta.activeDropTargetNode;
441
- var decos = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, formatMessage, nodeViewPortalProviderAPI, latestActiveNode);
442
- decorations = decorations.remove(findDropTargetDecs(decorations));
443
- if (decos.length > 0) {
444
- decorations = decorations.add(newState.doc, decos);
446
+ var _oldDropTargetDecs = findDropTargetDecs(decorations);
447
+ var _getActiveDropTargetD = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, _oldDropTargetDecs, formatMessage, nodeViewPortalProviderAPI, latestActiveNode),
448
+ decsToAdd = _getActiveDropTargetD.decsToAdd,
449
+ decsToRemove = _getActiveDropTargetD.decsToRemove;
450
+ decorations = decorations.remove(decsToRemove);
451
+ if (decsToAdd.length > 0) {
452
+ decorations = decorations.add(newState.doc, decsToAdd);
445
453
  }
446
454
  }
447
455
  } else if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
@@ -477,7 +485,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
477
485
  } else if (meta !== null && meta !== void 0 && meta.toggleMenu) {
478
486
  isMenuOpenNew = !isMenuOpen;
479
487
  }
480
- var isSelectedViaDragHandleNew = (meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle) !== undefined && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5') ? meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle : isSelectedViaDragHandle;
488
+ var isSelectedViaDragHandle = (meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle) !== undefined && editorExperiment('platform_editor_controls', 'variant1') && (meta === null || meta === void 0 ? void 0 : meta.isSelectedViaDragHandle);
481
489
  return {
482
490
  decorations: decorations,
483
491
  activeNode: newActiveNode,
@@ -494,7 +502,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
494
502
  multiSelectDnD: multiSelectDnD,
495
503
  isShiftDown: (_meta$isShiftDown = meta === null || meta === void 0 ? void 0 : meta.isShiftDown) !== null && _meta$isShiftDown !== void 0 ? _meta$isShiftDown : isShiftDown,
496
504
  lastDragCancelled: (_meta$lastDragCancell = meta === null || meta === void 0 ? void 0 : meta.lastDragCancelled) !== null && _meta$lastDragCancell !== void 0 ? _meta$lastDragCancell : lastDragCancelled,
497
- isSelectedViaDragHandle: isSelectedViaDragHandleNew
505
+ isSelectedViaDragHandle: isSelectedViaDragHandle
498
506
  };
499
507
  };
500
508
  export { _apply as apply };
@@ -645,7 +653,7 @@ export var createPlugin = function createPlugin(api, getIntl, nodeViewPortalProv
645
653
  handleMouseOver(view, event, api);
646
654
  return false;
647
655
  },
648
- mousedown: editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_2') ? handleMouseDown(api) : undefined,
656
+ mousedown: editorExperiment('platform_editor_controls', 'variant1') ? handleMouseDown(api) : undefined,
649
657
  keydown: function keydown(view, event) {
650
658
  if (isMultiSelectEnabled) {
651
659
  if (event.shiftKey && event.ctrlKey) {
@@ -669,11 +677,11 @@ export var createPlugin = function createPlugin(api, getIntl, nodeViewPortalProv
669
677
  return true;
670
678
  }
671
679
  }
672
- if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
680
+ if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1')) {
673
681
  var isDragHandle = event.target.closest('[data-editor-block-ctrl-drag-handle="true"]') !== null;
674
682
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(isDragHandle));
675
683
  }
676
- if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
684
+ if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1')) {
677
685
  var _api$blockControls$sh2;
678
686
  if (api !== null && api !== void 0 && (_api$blockControls$sh2 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh2 !== void 0 && _api$blockControls$sh2.isSelectedViaDragHandle) {
679
687
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
@@ -706,11 +714,11 @@ export var createPlugin = function createPlugin(api, getIntl, nodeViewPortalProv
706
714
  return true;
707
715
  }
708
716
  }
709
- if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
717
+ if ((event.key === 'Enter' || event.key === ' ') && event.target instanceof HTMLElement && editorExperiment('platform_editor_controls', 'variant1')) {
710
718
  var _isDragHandle = event.target.closest('[data-editor-block-ctrl-drag-handle="true"]') !== null;
711
719
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(_isDragHandle));
712
720
  }
713
- if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_5')) {
721
+ if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown' || event.key === 'ArrowUp') && editorExperiment('platform_editor_controls', 'variant1')) {
714
722
  var _api$blockControls$sh3;
715
723
  if (api !== null && api !== void 0 && (_api$blockControls$sh3 = api.blockControls.sharedState.currentState()) !== null && _api$blockControls$sh3 !== void 0 && _api$blockControls$sh3.isSelectedViaDragHandle) {
716
724
  api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.blockControls.commands.setSelectedViaDragHandle(false));
@@ -606,7 +606,7 @@ export var DragHandle = function DragHandle(_ref) {
606
606
  var node = parentPos !== undefined ? view.state.doc.nodeAt(parentPos) : undefined;
607
607
  var parentNodeType = node === null || node === void 0 ? void 0 : node.type.name;
608
608
  var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
609
- var safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_2') ? refreshAnchorName({
609
+ var safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') ? refreshAnchorName({
610
610
  getPos: getPos,
611
611
  view: view,
612
612
  anchorName: anchorName
@@ -652,7 +652,7 @@ export var DragHandle = function DragHandle(_ref) {
652
652
  var node = parentPos !== undefined ? view.state.doc.nodeAt(parentPos) : undefined;
653
653
  var parentNodeType = node === null || node === void 0 ? void 0 : node.type.name;
654
654
  var supportsAnchor = CSS.supports('top', "anchor(".concat(anchorName, " start)")) && CSS.supports('left', "anchor(".concat(anchorName, " start)"));
655
- var safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_2') ? refreshAnchorName({
655
+ var safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') ? refreshAnchorName({
656
656
  getPos: getPos,
657
657
  view: view,
658
658
  anchorName: anchorName
@@ -124,11 +124,11 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
124
124
  // CHANGES - `removed editorExperiment('advanced_layouts', true) && isLayoutColumn` checks as quick insert button will not be positioned for layout column
125
125
  var calculatePosition = useCallback(function () {
126
126
  var supportsAnchor = CSS.supports('top', "anchor(".concat(rootAnchorName, " start)")) && CSS.supports('left', "anchor(".concat(rootAnchorName, " start)"));
127
- var safeAnchorName = fg('platform_editor_controls_patch_2') ? refreshAnchorName({
127
+ var safeAnchorName = refreshAnchorName({
128
128
  getPos: getPos,
129
129
  view: view,
130
130
  anchorName: rootAnchorName
131
- }) : rootAnchorName;
131
+ });
132
132
  var dom = view.dom.querySelector("[data-drag-handler-anchor-name=\"".concat(safeAnchorName, "\"]"));
133
133
  var hasResizer = rootNodeType === 'table' || rootNodeType === 'mediaSingle';
134
134
  var isExtension = rootNodeType === 'extension' || rootNodeType === 'bodiedExtension';
@@ -6,4 +6,7 @@ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
6
6
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
7
  import type { ActiveDropTargetNode, ActiveNode, BlockControlsPlugin } from '../blockControlsPluginType';
8
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[];
9
+ export declare const getActiveDropTargetDecorations: (activeDropTargetNode: ActiveDropTargetNode, state: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, existingDecs: Decoration[], formatMessage: IntlShape['formatMessage'], nodeViewPortalProviderAPI: PortalProviderAPI, activeNode?: ActiveNode) => {
10
+ decsToAdd: Decoration[];
11
+ decsToRemove: Decoration[];
12
+ };
@@ -6,4 +6,7 @@ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
6
6
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
7
  import type { ActiveDropTargetNode, ActiveNode, BlockControlsPlugin } from '../blockControlsPluginType';
8
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[];
9
+ export declare const getActiveDropTargetDecorations: (activeDropTargetNode: ActiveDropTargetNode, state: EditorState, api: ExtractInjectionAPI<BlockControlsPlugin>, existingDecs: Decoration[], formatMessage: IntlShape['formatMessage'], nodeViewPortalProviderAPI: PortalProviderAPI, activeNode?: ActiveNode) => {
10
+ decsToAdd: Decoration[];
11
+ decsToRemove: Decoration[];
12
+ };