@atlaskit/editor-plugin-block-controls 3.19.3 → 3.19.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 3.19.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 3.19.4
10
+
11
+ ### Patch Changes
12
+
13
+ - [#172648](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/172648)
14
+ [`3606178de772b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3606178de772b) -
15
+ ED-27422: Clean up platform_editor_element_drag_and_drop_ed_23873
16
+
3
17
  ## 3.19.3
4
18
 
5
19
  ### Patch Changes
@@ -59,14 +59,20 @@ var canMoveNodeOrSliceToPos = exports.canMoveNodeOrSliceToPos = function canMove
59
59
  }
60
60
  return true;
61
61
  };
62
- var getActiveDropTargetDecorations = exports.getActiveDropTargetDecorations = function getActiveDropTargetDecorations(activeDropTargetNode, state, api, formatMessage, nodeViewPortalProviderAPI, activeNode) {
62
+ var getActiveDropTargetDecorations = exports.getActiveDropTargetDecorations = function getActiveDropTargetDecorations(activeDropTargetNode, state, api, existingDecs, formatMessage, nodeViewPortalProviderAPI, activeNode) {
63
63
  if (!(0, _platformFeatureFlags.fg)('platform_editor_block_controls_drop_target_mem_fix')) {
64
64
  (0, _decorationsCommon.unmountDecorations)(nodeViewPortalProviderAPI, 'data-blocks-drop-target-container', 'data-blocks-drop-target-key');
65
65
  }
66
- var decs = [];
66
+ var decsToAdd = [];
67
+ var decsToRemove = existingDecs.filter(function (dec) {
68
+ return !!dec;
69
+ });
67
70
  var activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
68
71
  var $activeNodePos = typeof activeNodePos === 'number' && state.doc.resolve(activeNodePos);
69
72
  var $toPos = state.doc.resolve(activeDropTargetNode.pos);
73
+ var existingDecsPos = decsToRemove.map(function (dec) {
74
+ return dec.from;
75
+ });
70
76
  var _findSurroundingNodes = (0, _decorationsFindSurroundingNodes.findSurroundingNodes)(state, $toPos, activeDropTargetNode.nodeTypeName),
71
77
  parent = _findSurroundingNodes.parent,
72
78
  index = _findSurroundingNodes.index,
@@ -81,32 +87,52 @@ var getActiveDropTargetDecorations = exports.getActiveDropTargetDecorations = fu
81
87
  * above the first child and below the last child.
82
88
  */
83
89
  if (isContainerNode(node)) {
90
+ var isEmptyContainer = node.childCount === 0 || node.childCount === 1 && (0, _utils.isEmptyParagraph)(node.firstChild);
91
+
84
92
  // can move to before first child
85
- if (node.firstChild && canMoveNodeOrSliceToPos(state, node.firstChild, node, 0, state.doc.resolve(pos + 1),
86
- // +1 to get the position of the first child
87
- activeNode)) {
88
- decs.push((0, _decorationsDropTarget.createDropTargetDecoration)(pos + 1, {
89
- api: api,
90
- prevNode: undefined,
91
- nextNode: node.firstChild,
92
- parentNode: node,
93
- formatMessage: formatMessage,
94
- dropTargetStyle: 'default'
95
- }, nodeViewPortalProviderAPI, 1));
93
+ var posBeforeFirstChild = pos + 1; // +1 to get the position of the first child
94
+ if (node.firstChild && canMoveNodeOrSliceToPos(state, node.firstChild, node, 0, state.doc.resolve(posBeforeFirstChild), activeNode)) {
95
+ if (existingDecsPos.includes(posBeforeFirstChild)) {
96
+ // if the decoration already exists, we don't add it again.
97
+ decsToRemove = decsToRemove.filter(function (dec) {
98
+ return dec.from !== posBeforeFirstChild;
99
+ });
100
+ } else {
101
+ decsToAdd.push((0, _decorationsDropTarget.createDropTargetDecoration)(posBeforeFirstChild, {
102
+ api: api,
103
+ prevNode: undefined,
104
+ nextNode: node.firstChild,
105
+ parentNode: node,
106
+ formatMessage: formatMessage,
107
+ dropTargetStyle: isEmptyContainer ? 'remainingHeight' : 'default'
108
+ }, nodeViewPortalProviderAPI, 1));
109
+ }
96
110
  }
97
111
 
98
112
  // can move to after last child
99
- if (node.lastChild && canMoveNodeOrSliceToPos(state, node.lastChild, node, node.childCount - 1, state.doc.resolve(pos + node.nodeSize - 1),
100
- // -1 to get the position after last child
101
- activeNode)) {
102
- decs.push((0, _decorationsDropTarget.createDropTargetDecoration)(pos + node.nodeSize - 1, {
103
- api: api,
104
- prevNode: node.lastChild,
105
- nextNode: undefined,
106
- parentNode: node,
107
- formatMessage: formatMessage,
108
- dropTargetStyle: 'default'
109
- }, nodeViewPortalProviderAPI, -1));
113
+ // if the node is empty, we don't show the drop target at the end of the node
114
+ if (!isEmptyContainer) {
115
+ var posAfterLastChild = pos + node.nodeSize - 1; // -1 to get the position after last child
116
+
117
+ if (node.lastChild && canMoveNodeOrSliceToPos(state, node.lastChild, node, node.childCount - 1, state.doc.resolve(posAfterLastChild),
118
+ // -1 to get the position after last child
119
+ activeNode)) {
120
+ if (existingDecsPos.includes(posAfterLastChild)) {
121
+ // if the decoration already exists, we don't add it again.
122
+ decsToRemove = decsToRemove.filter(function (dec) {
123
+ return dec.from !== posAfterLastChild;
124
+ });
125
+ } else {
126
+ decsToAdd.push((0, _decorationsDropTarget.createDropTargetDecoration)(posAfterLastChild, {
127
+ api: api,
128
+ prevNode: node.lastChild,
129
+ nextNode: undefined,
130
+ parentNode: node,
131
+ formatMessage: formatMessage,
132
+ dropTargetStyle: 'remainingHeight'
133
+ }, nodeViewPortalProviderAPI, -1));
134
+ }
135
+ }
110
136
  }
111
137
  }
112
138
 
@@ -118,24 +144,41 @@ var getActiveDropTargetDecorations = exports.getActiveDropTargetDecorations = fu
118
144
  var isInSupportedContainer = ['tableCell', 'tableHeader', 'layoutColumn'].includes((parent === null || parent === void 0 ? void 0 : parent.type.name) || '');
119
145
  var shouldShowFullHeight = isInSupportedContainer && (parent === null || parent === void 0 ? void 0 : parent.lastChild) === node && (0, _utils.isEmptyParagraph)(node);
120
146
  if (canMoveNodeOrSliceToPos(state, node, parent, index, $toPos, activeNode)) {
121
- decs.push((0, _decorationsDropTarget.createDropTargetDecoration)(pos, {
122
- api: api,
123
- prevNode: before || undefined,
124
- nextNode: node,
125
- parentNode: parent || undefined,
126
- formatMessage: formatMessage,
127
- dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
128
- }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
147
+ if (existingDecsPos.includes(pos)) {
148
+ // if the decoration already exists, we don't add it again.
149
+ decsToRemove = decsToRemove.filter(function (dec) {
150
+ return dec.from !== pos;
151
+ });
152
+ } else {
153
+ decsToAdd.push((0, _decorationsDropTarget.createDropTargetDecoration)(pos, {
154
+ api: api,
155
+ prevNode: before || undefined,
156
+ nextNode: node,
157
+ parentNode: parent || undefined,
158
+ formatMessage: formatMessage,
159
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
160
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
161
+ }
129
162
  }
130
- if (canMoveNodeOrSliceToPos(state, node, parent, index + 1, state.doc.resolve(pos + node.nodeSize), activeNode)) {
131
- decs.push((0, _decorationsDropTarget.createDropTargetDecoration)(pos + node.nodeSize, {
132
- api: api,
133
- prevNode: node,
134
- nextNode: after || undefined,
135
- parentNode: parent || undefined,
136
- formatMessage: formatMessage,
137
- dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
138
- }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
163
+
164
+ // if the node is a container node, we show the drop target after the node
165
+ var posAfterNode = pos + node.nodeSize;
166
+ if (canMoveNodeOrSliceToPos(state, node, parent, index + 1, state.doc.resolve(posAfterNode), activeNode)) {
167
+ if (existingDecsPos.includes(posAfterNode)) {
168
+ // if the decoration already exists, we don't add it again.
169
+ decsToRemove = decsToRemove.filter(function (dec) {
170
+ return dec.from !== posAfterNode;
171
+ });
172
+ } else {
173
+ decsToAdd.push((0, _decorationsDropTarget.createDropTargetDecoration)(posAfterNode, {
174
+ api: api,
175
+ prevNode: node,
176
+ nextNode: after || undefined,
177
+ parentNode: parent || undefined,
178
+ formatMessage: formatMessage,
179
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
180
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
181
+ }
139
182
  }
140
183
  }
141
184
  var rootNodeWithPos = {
@@ -146,14 +189,21 @@ var getActiveDropTargetDecorations = exports.getActiveDropTargetDecorations = fu
146
189
  // if the current node is not a top level node, we create one for advanced layout drop targets
147
190
  if (depth > 1) {
148
191
  var root = (0, _decorationsFindSurroundingNodes.findSurroundingNodes)(state, state.doc.resolve($toPos.before(2)));
149
- decs.push((0, _decorationsDropTarget.createDropTargetDecoration)(root.pos, {
150
- api: api,
151
- prevNode: root.before || undefined,
152
- nextNode: root.node,
153
- parentNode: state.doc || undefined,
154
- formatMessage: formatMessage,
155
- dropTargetStyle: 'default'
156
- }, nodeViewPortalProviderAPI, 0, undefined, false));
192
+ if (existingDecsPos.includes(root.pos)) {
193
+ // if the decoration already exists, we don't add it again.
194
+ decsToRemove = decsToRemove.filter(function (dec) {
195
+ return dec.from !== root.pos;
196
+ });
197
+ } else {
198
+ decsToAdd.push((0, _decorationsDropTarget.createDropTargetDecoration)(root.pos, {
199
+ api: api,
200
+ prevNode: root.before || undefined,
201
+ nextNode: root.node,
202
+ parentNode: state.doc || undefined,
203
+ formatMessage: formatMessage,
204
+ dropTargetStyle: 'default'
205
+ }, nodeViewPortalProviderAPI, 0, undefined, false));
206
+ }
157
207
  rootNodeWithPos = {
158
208
  node: root.node,
159
209
  pos: root.pos
@@ -167,11 +217,19 @@ var getActiveDropTargetDecorations = exports.getActiveDropTargetDecorations = fu
167
217
  layoutSectionNode.descendants(function (childNode, childPos, parent, index) {
168
218
  if (childNode.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && index !== 0 // Not the first node
169
219
  ) {
170
- decs.push((0, _decorationsDropTarget.createLayoutDropTargetDecoration)(rootNodeWithPos.pos + childPos + 1, {
171
- api: api,
172
- parent: parent,
173
- formatMessage: formatMessage
174
- }, nodeViewPortalProviderAPI, undefined));
220
+ var currentPos = rootNodeWithPos.pos + childPos + 1;
221
+ if (existingDecsPos.includes(currentPos)) {
222
+ // if the decoration already exists, we don't add it again.
223
+ decsToRemove = decsToRemove.filter(function (dec) {
224
+ return dec.from !== currentPos;
225
+ });
226
+ } else {
227
+ decsToAdd.push((0, _decorationsDropTarget.createLayoutDropTargetDecoration)(rootNodeWithPos.pos + childPos + 1, {
228
+ api: api,
229
+ parent: parent,
230
+ formatMessage: formatMessage
231
+ }, nodeViewPortalProviderAPI, undefined));
232
+ }
175
233
  }
176
234
  return false;
177
235
  });
@@ -179,5 +237,8 @@ var getActiveDropTargetDecorations = exports.getActiveDropTargetDecorations = fu
179
237
  }
180
238
  }
181
239
  _activeAnchorTracker.defaultActiveAnchorTracker.emit((0, _decorationsCommon.getNodeAnchor)(rootNodeWithPos.node));
182
- return decs;
240
+ return {
241
+ decsToAdd: decsToAdd,
242
+ decsToRemove: decsToRemove
243
+ };
183
244
  };
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.findSurroundingNodes = void 0;
7
7
  var IGNORE_NODES = ['tableRow', 'listItem', 'caption', 'media'];
8
8
  var blockLeafNodes = ['blockCard', 'rule'];
9
+ var DISABLE_CHILD_DROP_TARGET = ['orderedList', 'bulletList'];
9
10
 
10
11
  /**
11
12
  * This function returns the surrounding nodes of a given resolved position in the editor.
@@ -33,17 +34,25 @@ var _findSurroundingNodes = exports.findSurroundingNodes = function findSurround
33
34
  before: _before,
34
35
  after: _after,
35
36
  index: _index,
36
- depth: 1
37
+ depth: depth
37
38
  };
38
39
  }
39
40
  var isRootNode = depth === 1;
40
41
  var node = $pos.node(depth);
41
- var isIgnoredNode = IGNORE_NODES.includes(node.type.name);
42
- if (isIgnoredNode && !isRootNode) {
42
+
43
+ // go through the path to find the first node that is not allow child drop target
44
+ // From top to bottom, we check the node types at each depth
45
+ for (var i = 1; i < depth; i++) {
46
+ var _nodeType = $pos.node(i).type.name;
47
+ if (DISABLE_CHILD_DROP_TARGET.includes(_nodeType)) {
48
+ return _findSurroundingNodes(state, state.doc.resolve($pos.before(i + 1)), _nodeType);
49
+ }
50
+ }
51
+ if (IGNORE_NODES.includes(node.type.name) && !isRootNode) {
43
52
  // If the node is an ignored node, we return the surrounding nodes of its parent
44
53
  return _findSurroundingNodes(state, state.doc.resolve($pos.before(depth - 1)));
45
54
  }
46
- var pos = $pos.before(depth);
55
+ var pos = depth > 0 ? $pos.before(depth) : 0;
47
56
  var parent = isRootNode ? state.doc : $pos.node(depth - 1);
48
57
  var index = $pos.index(depth - 1);
49
58
  var before = index > 0 ? parent.child(index - 1) : null;
@@ -443,12 +443,21 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
443
443
  var currentActiveDropTargetNode = isDragging ? currentState.activeDropTargetNode : undefined;
444
444
  if (api) {
445
445
  if ((0, _expValEquals.expValEquals)('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
446
+ // If page is updated while dragging (likely by remote updates), we simply remove the drop targets
447
+ // and add them back when the use interacts with the editor again
448
+ if (isDropTargetsMissing) {
449
+ var oldDropTargetDecs = (0, _decorationsDropTarget.findDropTargetDecs)(decorations);
450
+ decorations = decorations.remove(oldDropTargetDecs);
451
+ }
446
452
  if (meta !== null && meta !== void 0 && meta.activeDropTargetNode) {
447
453
  currentActiveDropTargetNode = meta === null || meta === void 0 ? void 0 : meta.activeDropTargetNode;
448
- var decos = (0, _decorationsDropTargetActive.getActiveDropTargetDecorations)(meta.activeDropTargetNode, newState, api, formatMessage, nodeViewPortalProviderAPI, latestActiveNode);
449
- decorations = decorations.remove((0, _decorationsDropTarget.findDropTargetDecs)(decorations));
450
- if (decos.length > 0) {
451
- decorations = decorations.add(newState.doc, decos);
454
+ var _oldDropTargetDecs = (0, _decorationsDropTarget.findDropTargetDecs)(decorations);
455
+ var _getActiveDropTargetD = (0, _decorationsDropTargetActive.getActiveDropTargetDecorations)(meta.activeDropTargetNode, newState, api, _oldDropTargetDecs, formatMessage, nodeViewPortalProviderAPI, latestActiveNode),
456
+ decsToAdd = _getActiveDropTargetD.decsToAdd,
457
+ decsToRemove = _getActiveDropTargetD.decsToRemove;
458
+ decorations = decorations.remove(decsToRemove);
459
+ if (decsToAdd.length > 0) {
460
+ decorations = decorations.add(newState.doc, decsToAdd);
452
461
  }
453
462
  }
454
463
  } else if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
@@ -855,7 +855,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
855
855
  css: [(0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? dragHandleButtonStyles : dragHandleButtonStylesOld, (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') && dragHandleColor,
856
856
  // ED-26266: Fixed the drag handle highlight when selecting multiple line in Firefox
857
857
  // See https://product-fabric.atlassian.net/browse/ED-26266
858
- _browser.browser.gecko && (0, _platformFeatureFlags.fg)('platform_editor_dnd_handle_highlight_fix_firefox') && dragHandleMultiLineSelectionFixFirefox, (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn && layoutColumnDragHandleStyles, dragHandleSelected && hasHadInteraction && selectedStyles],
858
+ _browser.browser.gecko && dragHandleMultiLineSelectionFixFirefox, (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn && layoutColumnDragHandleStyles, dragHandleSelected && hasHadInteraction && selectedStyles],
859
859
  ref: buttonRef
860
860
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
861
861
  ,
@@ -55,14 +55,16 @@ export const canMoveNodeOrSliceToPos = (state, node, parent, index, $toPos, acti
55
55
  }
56
56
  return true;
57
57
  };
58
- export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api, formatMessage, nodeViewPortalProviderAPI, activeNode) => {
58
+ export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api, existingDecs, formatMessage, nodeViewPortalProviderAPI, activeNode) => {
59
59
  if (!fg('platform_editor_block_controls_drop_target_mem_fix')) {
60
60
  unmountDecorations(nodeViewPortalProviderAPI, 'data-blocks-drop-target-container', 'data-blocks-drop-target-key');
61
61
  }
62
- const decs = [];
62
+ const decsToAdd = [];
63
+ let decsToRemove = existingDecs.filter(dec => !!dec);
63
64
  const activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
64
65
  const $activeNodePos = typeof activeNodePos === 'number' && state.doc.resolve(activeNodePos);
65
66
  const $toPos = state.doc.resolve(activeDropTargetNode.pos);
67
+ const existingDecsPos = decsToRemove.map(dec => dec.from);
66
68
  const {
67
69
  parent,
68
70
  index,
@@ -78,32 +80,48 @@ export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api,
78
80
  * above the first child and below the last child.
79
81
  */
80
82
  if (isContainerNode(node)) {
83
+ const isEmptyContainer = node.childCount === 0 || node.childCount === 1 && isEmptyParagraph(node.firstChild);
84
+
81
85
  // can move to before first child
82
- if (node.firstChild && canMoveNodeOrSliceToPos(state, node.firstChild, node, 0, state.doc.resolve(pos + 1),
83
- // +1 to get the position of the first child
84
- activeNode)) {
85
- decs.push(createDropTargetDecoration(pos + 1, {
86
- api,
87
- prevNode: undefined,
88
- nextNode: node.firstChild,
89
- parentNode: node,
90
- formatMessage,
91
- dropTargetStyle: 'default'
92
- }, nodeViewPortalProviderAPI, 1));
86
+ const posBeforeFirstChild = pos + 1; // +1 to get the position of the first child
87
+ if (node.firstChild && canMoveNodeOrSliceToPos(state, node.firstChild, node, 0, state.doc.resolve(posBeforeFirstChild), activeNode)) {
88
+ if (existingDecsPos.includes(posBeforeFirstChild)) {
89
+ // if the decoration already exists, we don't add it again.
90
+ decsToRemove = decsToRemove.filter(dec => dec.from !== posBeforeFirstChild);
91
+ } else {
92
+ decsToAdd.push(createDropTargetDecoration(posBeforeFirstChild, {
93
+ api,
94
+ prevNode: undefined,
95
+ nextNode: node.firstChild,
96
+ parentNode: node,
97
+ formatMessage,
98
+ dropTargetStyle: isEmptyContainer ? 'remainingHeight' : 'default'
99
+ }, nodeViewPortalProviderAPI, 1));
100
+ }
93
101
  }
94
102
 
95
103
  // can move to after last child
96
- if (node.lastChild && canMoveNodeOrSliceToPos(state, node.lastChild, node, node.childCount - 1, state.doc.resolve(pos + node.nodeSize - 1),
97
- // -1 to get the position after last child
98
- activeNode)) {
99
- decs.push(createDropTargetDecoration(pos + node.nodeSize - 1, {
100
- api,
101
- prevNode: node.lastChild,
102
- nextNode: undefined,
103
- parentNode: node,
104
- formatMessage,
105
- dropTargetStyle: 'default'
106
- }, nodeViewPortalProviderAPI, -1));
104
+ // if the node is empty, we don't show the drop target at the end of the node
105
+ if (!isEmptyContainer) {
106
+ const posAfterLastChild = pos + node.nodeSize - 1; // -1 to get the position after last child
107
+
108
+ if (node.lastChild && canMoveNodeOrSliceToPos(state, node.lastChild, node, node.childCount - 1, state.doc.resolve(posAfterLastChild),
109
+ // -1 to get the position after last child
110
+ activeNode)) {
111
+ if (existingDecsPos.includes(posAfterLastChild)) {
112
+ // if the decoration already exists, we don't add it again.
113
+ decsToRemove = decsToRemove.filter(dec => dec.from !== posAfterLastChild);
114
+ } else {
115
+ decsToAdd.push(createDropTargetDecoration(posAfterLastChild, {
116
+ api,
117
+ prevNode: node.lastChild,
118
+ nextNode: undefined,
119
+ parentNode: node,
120
+ formatMessage,
121
+ dropTargetStyle: 'remainingHeight'
122
+ }, nodeViewPortalProviderAPI, -1));
123
+ }
124
+ }
107
125
  }
108
126
  }
109
127
 
@@ -115,24 +133,37 @@ export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api,
115
133
  const isInSupportedContainer = ['tableCell', 'tableHeader', 'layoutColumn'].includes((parent === null || parent === void 0 ? void 0 : parent.type.name) || '');
116
134
  const shouldShowFullHeight = isInSupportedContainer && (parent === null || parent === void 0 ? void 0 : parent.lastChild) === node && isEmptyParagraph(node);
117
135
  if (canMoveNodeOrSliceToPos(state, node, parent, index, $toPos, activeNode)) {
118
- decs.push(createDropTargetDecoration(pos, {
119
- api,
120
- prevNode: before || undefined,
121
- nextNode: node,
122
- parentNode: parent || undefined,
123
- formatMessage,
124
- dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
125
- }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
136
+ if (existingDecsPos.includes(pos)) {
137
+ // if the decoration already exists, we don't add it again.
138
+ decsToRemove = decsToRemove.filter(dec => dec.from !== pos);
139
+ } else {
140
+ decsToAdd.push(createDropTargetDecoration(pos, {
141
+ api,
142
+ prevNode: before || undefined,
143
+ nextNode: node,
144
+ parentNode: parent || undefined,
145
+ formatMessage,
146
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
147
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
148
+ }
126
149
  }
127
- if (canMoveNodeOrSliceToPos(state, node, parent, index + 1, state.doc.resolve(pos + node.nodeSize), activeNode)) {
128
- decs.push(createDropTargetDecoration(pos + node.nodeSize, {
129
- api,
130
- prevNode: node,
131
- nextNode: after || undefined,
132
- parentNode: parent || undefined,
133
- formatMessage,
134
- dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
135
- }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
150
+
151
+ // if the node is a container node, we show the drop target after the node
152
+ const posAfterNode = pos + node.nodeSize;
153
+ if (canMoveNodeOrSliceToPos(state, node, parent, index + 1, state.doc.resolve(posAfterNode), activeNode)) {
154
+ if (existingDecsPos.includes(posAfterNode)) {
155
+ // if the decoration already exists, we don't add it again.
156
+ decsToRemove = decsToRemove.filter(dec => dec.from !== posAfterNode);
157
+ } else {
158
+ decsToAdd.push(createDropTargetDecoration(posAfterNode, {
159
+ api,
160
+ prevNode: node,
161
+ nextNode: after || undefined,
162
+ parentNode: parent || undefined,
163
+ formatMessage,
164
+ dropTargetStyle: shouldShowFullHeight ? 'remainingHeight' : 'default'
165
+ }, nodeViewPortalProviderAPI, -1, undefined, isSameLayout));
166
+ }
136
167
  }
137
168
  }
138
169
  let rootNodeWithPos = {
@@ -143,14 +174,19 @@ export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api,
143
174
  // if the current node is not a top level node, we create one for advanced layout drop targets
144
175
  if (depth > 1) {
145
176
  const root = findSurroundingNodes(state, state.doc.resolve($toPos.before(2)));
146
- decs.push(createDropTargetDecoration(root.pos, {
147
- api,
148
- prevNode: root.before || undefined,
149
- nextNode: root.node,
150
- parentNode: state.doc || undefined,
151
- formatMessage,
152
- dropTargetStyle: 'default'
153
- }, nodeViewPortalProviderAPI, 0, undefined, false));
177
+ if (existingDecsPos.includes(root.pos)) {
178
+ // if the decoration already exists, we don't add it again.
179
+ decsToRemove = decsToRemove.filter(dec => dec.from !== root.pos);
180
+ } else {
181
+ decsToAdd.push(createDropTargetDecoration(root.pos, {
182
+ api,
183
+ prevNode: root.before || undefined,
184
+ nextNode: root.node,
185
+ parentNode: state.doc || undefined,
186
+ formatMessage,
187
+ dropTargetStyle: 'default'
188
+ }, nodeViewPortalProviderAPI, 0, undefined, false));
189
+ }
154
190
  rootNodeWithPos = {
155
191
  node: root.node,
156
192
  pos: root.pos
@@ -164,11 +200,17 @@ export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api,
164
200
  layoutSectionNode.descendants((childNode, childPos, parent, index) => {
165
201
  if (childNode.type.name === 'layoutColumn' && (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'layoutSection' && index !== 0 // Not the first node
166
202
  ) {
167
- decs.push(createLayoutDropTargetDecoration(rootNodeWithPos.pos + childPos + 1, {
168
- api,
169
- parent,
170
- formatMessage
171
- }, nodeViewPortalProviderAPI, undefined));
203
+ const currentPos = rootNodeWithPos.pos + childPos + 1;
204
+ if (existingDecsPos.includes(currentPos)) {
205
+ // if the decoration already exists, we don't add it again.
206
+ decsToRemove = decsToRemove.filter(dec => dec.from !== currentPos);
207
+ } else {
208
+ decsToAdd.push(createLayoutDropTargetDecoration(rootNodeWithPos.pos + childPos + 1, {
209
+ api,
210
+ parent,
211
+ formatMessage
212
+ }, nodeViewPortalProviderAPI, undefined));
213
+ }
172
214
  }
173
215
  return false;
174
216
  });
@@ -176,5 +218,8 @@ export const getActiveDropTargetDecorations = (activeDropTargetNode, state, api,
176
218
  }
177
219
  }
178
220
  defaultActiveAnchorTracker.emit(getNodeAnchor(rootNodeWithPos.node));
179
- return decs;
221
+ return {
222
+ decsToAdd,
223
+ decsToRemove
224
+ };
180
225
  };
@@ -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;
@@ -442,12 +442,22 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
442
442
  let currentActiveDropTargetNode = isDragging ? currentState.activeDropTargetNode : undefined;
443
443
  if (api) {
444
444
  if (expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
445
+ // If page is updated while dragging (likely by remote updates), we simply remove the drop targets
446
+ // and add them back when the use interacts with the editor again
447
+ if (isDropTargetsMissing) {
448
+ const oldDropTargetDecs = findDropTargetDecs(decorations);
449
+ decorations = decorations.remove(oldDropTargetDecs);
450
+ }
445
451
  if (meta !== null && meta !== void 0 && meta.activeDropTargetNode) {
446
452
  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);
453
+ const oldDropTargetDecs = findDropTargetDecs(decorations);
454
+ const {
455
+ decsToAdd,
456
+ decsToRemove
457
+ } = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, oldDropTargetDecs, formatMessage, nodeViewPortalProviderAPI, latestActiveNode);
458
+ decorations = decorations.remove(decsToRemove);
459
+ if (decsToAdd.length > 0) {
460
+ decorations = decorations.add(newState.doc, decsToAdd);
451
461
  }
452
462
  }
453
463
  } else if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
@@ -842,7 +842,7 @@ export const DragHandle = ({
842
842
  css: [editorExperiment('platform_editor_controls', 'variant1') ? dragHandleButtonStyles : dragHandleButtonStylesOld, editorExperiment('platform_editor_controls', 'variant1') && dragHandleColor,
843
843
  // ED-26266: Fixed the drag handle highlight when selecting multiple line in Firefox
844
844
  // See https://product-fabric.atlassian.net/browse/ED-26266
845
- browser.gecko && fg('platform_editor_dnd_handle_highlight_fix_firefox') && dragHandleMultiLineSelectionFixFirefox, editorExperiment('advanced_layouts', true) && isLayoutColumn && layoutColumnDragHandleStyles, dragHandleSelected && hasHadInteraction && selectedStyles],
845
+ browser.gecko && dragHandleMultiLineSelectionFixFirefox, editorExperiment('advanced_layouts', true) && isLayoutColumn && layoutColumnDragHandleStyles, dragHandleSelected && hasHadInteraction && selectedStyles],
846
846
  ref: buttonRef
847
847
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
848
848
  ,
@@ -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;
@@ -436,12 +436,21 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
436
436
  var currentActiveDropTargetNode = isDragging ? currentState.activeDropTargetNode : undefined;
437
437
  if (api) {
438
438
  if (expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true)) {
439
+ // If page is updated while dragging (likely by remote updates), we simply remove the drop targets
440
+ // and add them back when the use interacts with the editor again
441
+ if (isDropTargetsMissing) {
442
+ var oldDropTargetDecs = findDropTargetDecs(decorations);
443
+ decorations = decorations.remove(oldDropTargetDecs);
444
+ }
439
445
  if (meta !== null && meta !== void 0 && meta.activeDropTargetNode) {
440
446
  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);
447
+ var _oldDropTargetDecs = findDropTargetDecs(decorations);
448
+ var _getActiveDropTargetD = getActiveDropTargetDecorations(meta.activeDropTargetNode, newState, api, _oldDropTargetDecs, formatMessage, nodeViewPortalProviderAPI, latestActiveNode),
449
+ decsToAdd = _getActiveDropTargetD.decsToAdd,
450
+ decsToRemove = _getActiveDropTargetD.decsToRemove;
451
+ decorations = decorations.remove(decsToRemove);
452
+ if (decsToAdd.length > 0) {
453
+ decorations = decorations.add(newState.doc, decsToAdd);
445
454
  }
446
455
  }
447
456
  } else if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing) {
@@ -852,7 +852,7 @@ export var DragHandle = function DragHandle(_ref) {
852
852
  css: [editorExperiment('platform_editor_controls', 'variant1') ? dragHandleButtonStyles : dragHandleButtonStylesOld, editorExperiment('platform_editor_controls', 'variant1') && dragHandleColor,
853
853
  // ED-26266: Fixed the drag handle highlight when selecting multiple line in Firefox
854
854
  // See https://product-fabric.atlassian.net/browse/ED-26266
855
- browser.gecko && fg('platform_editor_dnd_handle_highlight_fix_firefox') && dragHandleMultiLineSelectionFixFirefox, editorExperiment('advanced_layouts', true) && isLayoutColumn && layoutColumnDragHandleStyles, dragHandleSelected && hasHadInteraction && selectedStyles],
855
+ browser.gecko && dragHandleMultiLineSelectionFixFirefox, editorExperiment('advanced_layouts', true) && isLayoutColumn && layoutColumnDragHandleStyles, dragHandleSelected && hasHadInteraction && selectedStyles],
856
856
  ref: buttonRef
857
857
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
858
858
  ,
@@ -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
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "3.19.3",
3
+ "version": "3.19.5",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@atlaskit/adf-schema": "^47.6.0",
36
- "@atlaskit/editor-common": "^106.9.0",
36
+ "@atlaskit/editor-common": "^107.0.0",
37
37
  "@atlaskit/editor-plugin-accessibility-utils": "^2.0.0",
38
38
  "@atlaskit/editor-plugin-analytics": "^2.3.0",
39
39
  "@atlaskit/editor-plugin-editor-disabled": "^2.1.0",
@@ -123,9 +123,6 @@
123
123
  "platform_editor_dnd_update_drag_start_target": {
124
124
  "type": "boolean"
125
125
  },
126
- "platform_editor_dnd_handle_highlight_fix_firefox": {
127
- "type": "boolean"
128
- },
129
126
  "platform_editor_track_node_types": {
130
127
  "type": "boolean"
131
128
  },