@atlaskit/editor-plugin-block-controls 3.2.1 → 3.3.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.
@@ -88,6 +88,7 @@ const getFocusedHandle = state => {
88
88
  };
89
89
  export const moveNodeViaShortcut = (api, direction, formatMessage) => {
90
90
  return state => {
91
+ var _hoistedPos;
91
92
  let isParentNodeOfTypeLayout;
92
93
  const shouldEnableNestedDndA11y = editorExperiment('nested-dnd', true);
93
94
  const {
@@ -100,19 +101,26 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
100
101
  const expandedSelection = expandSelectionBounds(selection.$anchor, selection.$head);
101
102
  const expandedAnchor = expandedSelection.$anchor.pos;
102
103
  const expandedHead = expandedSelection.$head.pos;
103
- const currentNodePos = isMultiSelectEnabled && !getFocusedHandle(state) ? Math.min(expandedAnchor, expandedHead) : getCurrentNodePos(state);
104
+ let hoistedPos;
105
+ const from = Math.min(expandedAnchor, expandedHead);
106
+ // Nodes like lists nest within themselves, we need to find the top most position
107
+ if (isParentNodeOfTypeLayout && fg('platform_editor_elements_dnd_multi_select_patch_1')) {
108
+ const LAYOUT_COL_DEPTH = 3;
109
+ hoistedPos = state.doc.resolve(from).before(LAYOUT_COL_DEPTH);
110
+ }
111
+ const currentNodePos = isMultiSelectEnabled && !getFocusedHandle(state) && !selection.empty ? (_hoistedPos = hoistedPos) !== null && _hoistedPos !== void 0 ? _hoistedPos : from : getCurrentNodePos(state);
104
112
  if (currentNodePos > -1) {
105
113
  var _state$doc$nodeAt;
106
- const $pos = state.doc.resolve(currentNodePos);
107
- const nodeAfterPos = isMultiSelectEnabled && !getFocusedHandle(state) ? Math.max(expandedAnchor, expandedHead) : $pos.posAtIndex($pos.index() + 1);
108
- const isTopLevelNode = $pos.depth === 0;
114
+ const $currentNodePos = state.doc.resolve(currentNodePos);
115
+ const nodeAfterPos = isMultiSelectEnabled && !getFocusedHandle(state) ? Math.max(expandedAnchor, expandedHead) : $currentNodePos.posAtIndex($currentNodePos.index() + 1);
116
+ const isTopLevelNode = $currentNodePos.depth === 0;
109
117
  let moveToPos = -1;
110
- const nodeIndex = $pos.index();
118
+ const nodeIndex = $currentNodePos.index();
111
119
  const isLayoutColumnSelected = selection instanceof NodeSelection && selection.node.type.name === 'layoutColumn';
112
120
  if (direction === DIRECTION.LEFT && shouldEnableNestedDndA11y) {
113
121
  if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
114
122
  var _api$core, _api$core2;
115
- const nodeBefore = $pos.nodeBefore;
123
+ const nodeBefore = $currentNodePos.nodeBefore;
116
124
  if (nodeBefore) {
117
125
  moveToPos = currentNodePos - nodeBefore.nodeSize;
118
126
  }
@@ -137,28 +145,28 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
137
145
  api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.focus();
138
146
  return true;
139
147
  } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
140
- var _$pos$nodeBefore, _api$core3, _api$blockControls2, _api$blockControls2$c;
141
- moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
148
+ var _$currentNodePos$node, _api$core3, _api$blockControls2, _api$blockControls2$c;
149
+ moveToPos = selection.from - (((_$currentNodePos$node = $currentNodePos.nodeBefore) === null || _$currentNodePos$node === void 0 ? void 0 : _$currentNodePos$node.nodeSize) || 1);
142
150
  api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.moveToLayout(currentNodePos, moveToPos, {
143
151
  selectMovedNode: true
144
152
  }));
145
153
  return true;
146
154
  } else {
147
- if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
155
+ if ($currentNodePos.depth < 2 || !isParentNodeOfTypeLayout) {
148
156
  return false;
149
157
  }
150
158
 
151
159
  // get the previous layoutSection node
152
- const index = $pos.index($pos.depth - 1);
153
- const grandParent = $pos.node($pos.depth - 1);
160
+ const index = $currentNodePos.index($currentNodePos.depth - 1);
161
+ const grandParent = $currentNodePos.node($currentNodePos.depth - 1);
154
162
  const previousNode = grandParent ? grandParent.maybeChild(index - 1) : null;
155
- moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
163
+ moveToPos = $currentNodePos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
156
164
  }
157
165
  } else if (direction === DIRECTION.RIGHT && shouldEnableNestedDndA11y) {
158
166
  if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
159
167
  var _api$core4, _api$core5;
160
- const endOfDoc = $pos.end();
161
- moveToPos = $pos.posAtIndex($pos.index() + 1);
168
+ const endOfDoc = $currentNodePos.end();
169
+ moveToPos = $currentNodePos.posAtIndex($currentNodePos.index() + 1);
162
170
  if (moveToPos >= endOfDoc) {
163
171
  return false;
164
172
  }
@@ -180,8 +188,8 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
180
188
  return true;
181
189
  } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
182
190
  var _api$core6, _api$blockControls4, _api$blockControls4$c;
183
- const index = $pos.index($pos.depth);
184
- const parent = $pos.node($pos.depth);
191
+ const index = $currentNodePos.index($currentNodePos.depth);
192
+ const parent = $currentNodePos.node($currentNodePos.depth);
185
193
  // get the next layoutColumn node
186
194
  const nextNode = parent ? parent.maybeChild(index + 1) : null;
187
195
 
@@ -191,29 +199,29 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
191
199
  return true;
192
200
  }
193
201
  const moveToEnd = index === parent.childCount - 2;
194
- moveToPos = moveToEnd ? $pos.before() : selection.to + ((nextNode === null || nextNode === void 0 ? void 0 : nextNode.nodeSize) || 1);
202
+ moveToPos = moveToEnd ? $currentNodePos.before() : selection.to + ((nextNode === null || nextNode === void 0 ? void 0 : nextNode.nodeSize) || 1);
195
203
  api === null || api === void 0 ? void 0 : (_api$core6 = api.core) === null || _api$core6 === void 0 ? void 0 : _api$core6.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 ? void 0 : (_api$blockControls4$c = _api$blockControls4.commands) === null || _api$blockControls4$c === void 0 ? void 0 : _api$blockControls4$c.moveToLayout(currentNodePos, moveToPos, {
196
204
  moveToEnd,
197
205
  selectMovedNode: true
198
206
  }));
199
207
  return true;
200
208
  } else {
201
- if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
209
+ if ($currentNodePos.depth < 2 || !isParentNodeOfTypeLayout) {
202
210
  return false;
203
211
  }
204
- moveToPos = $pos.after($pos.depth) + 1;
212
+ moveToPos = $currentNodePos.after($currentNodePos.depth) + 1;
205
213
  }
206
214
  } else if (direction === DIRECTION.UP) {
207
215
  if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
208
- moveToPos = $pos.start() - 1;
216
+ moveToPos = $currentNodePos.start() - 1;
209
217
  } else {
210
- const nodeBefore = $pos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $pos.node($pos.depth) : $pos.nodeBefore;
218
+ const nodeBefore = $currentNodePos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $currentNodePos.node($currentNodePos.depth) : $currentNodePos.nodeBefore;
211
219
  if (nodeBefore) {
212
220
  moveToPos = currentNodePos - nodeBefore.nodeSize;
213
221
  }
214
222
  }
215
223
  } else {
216
- const endOfDoc = $pos.end();
224
+ const endOfDoc = $currentNodePos.end();
217
225
  if (nodeAfterPos > endOfDoc) {
218
226
  return false;
219
227
  }
@@ -230,15 +238,25 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
230
238
  const nodeType = (_state$doc$nodeAt = state.doc.nodeAt(currentNodePos)) === null || _state$doc$nodeAt === void 0 ? void 0 : _state$doc$nodeAt.type.name;
231
239
 
232
240
  // only move the node if the destination is at the same depth, not support moving a nested node to a parent node
233
- const shouldMoveNode = (shouldEnableNestedDndA11y ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth || nodeType === 'layoutColumn' : moveToPos > -1) || nodeType === 'layoutColumn' && fg('platform_editor_advanced_layouts_accessibility');
241
+ const shouldMoveNode = (shouldEnableNestedDndA11y ? moveToPos > -1 && $currentNodePos.depth === state.doc.resolve(moveToPos).depth || nodeType === 'layoutColumn' : moveToPos > -1) || nodeType === 'layoutColumn' && fg('platform_editor_advanced_layouts_accessibility');
242
+ const {
243
+ $anchor: $newAnchor,
244
+ $head: $newHead
245
+ } = expandSelectionBounds($currentNodePos, selection.$to);
234
246
  if (shouldMoveNode) {
235
247
  var _api$core7;
236
248
  api === null || api === void 0 ? void 0 : (_api$core7 = api.core) === null || _api$core7 === void 0 ? void 0 : _api$core7.actions.execute(({
237
249
  tr
238
250
  }) => {
239
- api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
240
- tr
241
- });
251
+ if (fg('platform_editor_elements_dnd_multi_select_patch_1')) {
252
+ api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions($newAnchor.pos, $newHead.pos)({
253
+ tr
254
+ });
255
+ } else {
256
+ api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
257
+ tr
258
+ });
259
+ }
242
260
  moveNode(api)(currentNodePos, moveToPos, INPUT_METHOD.SHORTCUT, formatMessage)({
243
261
  tr
244
262
  });
@@ -262,9 +280,15 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
262
280
  api === null || api === void 0 ? void 0 : (_api$core9 = api.core) === null || _api$core9 === void 0 ? void 0 : _api$core9.actions.execute(({
263
281
  tr
264
282
  }) => {
265
- api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
266
- tr
267
- });
283
+ if (fg('platform_editor_elements_dnd_multi_select_patch_1')) {
284
+ api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions($newAnchor.pos, $newHead.pos)({
285
+ tr
286
+ });
287
+ } else {
288
+ api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
289
+ tr
290
+ });
291
+ }
268
292
  tr.scrollIntoView();
269
293
  return tr;
270
294
  });
@@ -292,6 +316,12 @@ export const moveNode = api => (start, to, inputMethod = INPUT_METHOD.DRAG_AND_D
292
316
  const isMultiSelect = editorExperiment('platform_editor_element_drag_and_drop_multiselect', true, {
293
317
  exposure: true
294
318
  });
319
+ if (fg('platform_editor_ease_of_use_metrics')) {
320
+ var _api$metrics;
321
+ api === null || api === void 0 ? void 0 : (_api$metrics = api.metrics) === null || _api$metrics === void 0 ? void 0 : _api$metrics.commands.setContentMoved()({
322
+ tr
323
+ });
324
+ }
295
325
  const slicePosition = getSelectedSlicePosition(start, tr, api);
296
326
  if (isMultiSelect) {
297
327
  sliceFrom = slicePosition.from;
@@ -313,6 +313,12 @@ export const moveToLayout = api => (from, to, options) => ({
313
313
  if (!fromContentWithoutBreakout) {
314
314
  return tr;
315
315
  }
316
+ if (fg('platform_editor_ease_of_use_metrics')) {
317
+ var _api$metrics;
318
+ api === null || api === void 0 ? void 0 : (_api$metrics = api.metrics) === null || _api$metrics === void 0 ? void 0 : _api$metrics.commands.setContentMoved()({
319
+ tr
320
+ });
321
+ }
316
322
  const isMultiSelect = editorExperiment('platform_editor_element_drag_and_drop_multiselect', true);
317
323
  if (toNode.type === layoutSection) {
318
324
  const toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize - 1 : to + 1;
@@ -133,6 +133,12 @@ const destroyFn = (api, editorView) => {
133
133
  }
134
134
  })(tr);
135
135
  }
136
+ if (fg('platform_editor_ease_of_use_metrics')) {
137
+ var _api$metrics;
138
+ api === null || api === void 0 ? void 0 : (_api$metrics = api.metrics) === null || _api$metrics === void 0 ? void 0 : _api$metrics.commands.startActiveSessionTimer()({
139
+ tr
140
+ });
141
+ }
136
142
  return tr.setMeta(key, {
137
143
  ...tr.getMeta(key),
138
144
  isDragging: false,
@@ -310,24 +316,23 @@ export const newApply = (api, formatMessage, tr, currentState, newState, flags,
310
316
  const oldHandle = findHandleDec(decorations, (_activeNode3 = activeNode) === null || _activeNode3 === void 0 ? void 0 : _activeNode3.pos, (_activeNode4 = activeNode) === null || _activeNode4 === void 0 ? void 0 : _activeNode4.pos);
311
317
  decorations = decorations.remove(oldHandle);
312
318
  if (editorExperiment('platform_editor_controls', 'variant1')) {
313
- var _activeNode5, _activeNode6;
314
- const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.rootPos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.rootPos);
319
+ const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations);
315
320
  decorations = decorations.remove(oldQuickInsertButton);
316
321
  }
317
322
  } else if (api && shouldRecreateHandle) {
318
- var _activeNode7, _activeNode8;
319
- const oldHandle = findHandleDec(decorations, (_activeNode7 = activeNode) === null || _activeNode7 === void 0 ? void 0 : _activeNode7.pos, (_activeNode8 = activeNode) === null || _activeNode8 === void 0 ? void 0 : _activeNode8.pos);
323
+ var _activeNode5, _activeNode6;
324
+ const oldHandle = findHandleDec(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.pos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.pos);
320
325
  decorations = decorations.remove(oldHandle);
321
326
  const handleDec = dragHandleDecoration(api, formatMessage, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.anchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.nodeType, nodeViewPortalProviderAPI, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.handleOptions);
322
327
  if (editorExperiment('platform_editor_controls', 'variant1')) {
323
- var _activeNode9, _activeNode10;
324
- const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode9 = activeNode) === null || _activeNode9 === void 0 ? void 0 : _activeNode9.rootPos, (_activeNode10 = activeNode) === null || _activeNode10 === void 0 ? void 0 : _activeNode10.rootPos);
325
- decorations = decorations.remove(oldQuickInsertButton);
326
- const quickInsertButton = quickInsertButtonDecoration(api, formatMessage, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootPos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.anchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.nodeType, nodeViewPortalProviderAPI, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootAnchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootNodeType);
327
- decorations = decorations.add(newState.doc, [handleDec, quickInsertButton]);
328
- } else {
329
- decorations = decorations.add(newState.doc, [handleDec]);
328
+ if ((latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootPos) !== undefined) {
329
+ const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations);
330
+ decorations = decorations.remove(oldQuickInsertButton);
331
+ const quickInsertButton = quickInsertButtonDecoration(api, formatMessage, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootPos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.anchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.nodeType, nodeViewPortalProviderAPI, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootAnchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.rootNodeType);
332
+ decorations = decorations.add(newState.doc, [quickInsertButton]);
333
+ }
330
334
  }
335
+ decorations = decorations.add(newState.doc, [handleDec]);
331
336
  }
332
337
 
333
338
  // Drop targets may be missing when the node count is being changed during a drag
@@ -570,7 +575,7 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
570
575
  },
571
576
  handleDOMEvents: {
572
577
  drop(view, event) {
573
- var _pluginState, _pluginState2, _pluginState3, _event$target;
578
+ var _pluginState, _pluginState2, _pluginState3, _event$target, _event$target$closest;
574
579
  // Prevent native DnD from triggering if we are in drag
575
580
  const {
576
581
  dispatch,
@@ -581,6 +586,12 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
581
586
  let pluginState = key.getState(state);
582
587
  const dndDragCancelled = (_pluginState = pluginState) === null || _pluginState === void 0 ? void 0 : _pluginState.lastDragCancelled;
583
588
  if ((_pluginState2 = pluginState) !== null && _pluginState2 !== void 0 && _pluginState2.isPMDragging || dndDragCancelled && isMultiSelectEnabled) {
589
+ if (fg('platform_editor_ease_of_use_metrics')) {
590
+ var _api$metrics2;
591
+ api === null || api === void 0 ? void 0 : (_api$metrics2 = api.metrics) === null || _api$metrics2 === void 0 ? void 0 : _api$metrics2.commands.startActiveSessionTimer()({
592
+ tr
593
+ });
594
+ }
584
595
  dispatch(tr.setMeta(key, {
585
596
  ...tr.getMeta(key),
586
597
  isPMDragging: false,
@@ -599,7 +610,7 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
599
610
  event.preventDefault();
600
611
  return false;
601
612
  }
602
- const nodeElement = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.closest('[data-drag-handler-anchor-name]');
613
+ const nodeElement = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : (_event$target$closest = _event$target.closest) === null || _event$target$closest === void 0 ? void 0 : _event$target$closest.call(_event$target, '[data-drag-handler-anchor-name]');
603
614
  if (!nodeElement) {
604
615
  return false;
605
616
  }
@@ -648,10 +659,18 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
648
659
  dispatch
649
660
  } = view;
650
661
  if ((_key$getState3 = key.getState(state)) !== null && _key$getState3 !== void 0 && _key$getState3.isPMDragging) {
651
- dispatch(state.tr.setMeta(key, {
662
+ const tr = state.tr;
663
+ tr.setMeta(key, {
652
664
  ...state.tr.getMeta(key),
653
665
  isPMDragging: false
654
- }));
666
+ });
667
+ if (fg('platform_editor_ease_of_use_metrics')) {
668
+ var _api$metrics3;
669
+ api === null || api === void 0 ? void 0 : (_api$metrics3 = api.metrics) === null || _api$metrics3 === void 0 ? void 0 : _api$metrics3.commands.startActiveSessionTimer()({
670
+ tr
671
+ });
672
+ }
673
+ dispatch(tr);
655
674
  }
656
675
  },
657
676
  mouseover: (view, event) => {
@@ -2,6 +2,7 @@ import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
2
2
  import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
4
4
  import { selectTableClosestToPos } from '@atlaskit/editor-tables/utils';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  export const getInlineNodePos = (tr, start, nodeSize) => {
6
7
  const $startPos = tr.doc.resolve(start);
7
8
  // To trigger the annotation floating toolbar for non-selectable node, we need to select inline nodes
@@ -53,6 +54,8 @@ export const getSelection = (tr, start) => {
53
54
  // we need a quick way to make all child media nodes appear as selected without the need for a custom selection
54
55
  nodeName === 'mediaGroup') {
55
56
  return new NodeSelection($startPos);
57
+ } else if (nodeName === 'taskList' && fg('platform_editor_elements_dnd_multi_select_patch_1')) {
58
+ return TextSelection.create(tr.doc, start, start + nodeSize);
56
59
  } else {
57
60
  const {
58
61
  inlineNodePos,
@@ -100,21 +103,42 @@ export const isHandleCorrelatedToSelection = (state, selection, handlePos) => {
100
103
  if (selection.empty) {
101
104
  return false;
102
105
  }
106
+ let nodeStart;
103
107
  const $selectionFrom = selection.$from;
104
- const selectionFrom = $selectionFrom.pos;
105
- let nodeStart = $selectionFrom.depth ? $selectionFrom.before() : selectionFrom;
106
- const $resolvedNodePos = state.doc.resolve(nodeStart);
107
- if (['tableRow', 'tableCell', 'tableHeader'].includes($resolvedNodePos.node().type.name)) {
108
- const parentNodeFindRes = findParentNodeOfType(state.schema.nodes['table'])(selection);
109
- const tablePos = parentNodeFindRes === null || parentNodeFindRes === void 0 ? void 0 : parentNodeFindRes.pos;
110
- nodeStart = typeof tablePos === 'undefined' ? nodeStart : tablePos;
111
- } else if (['listItem'].includes($resolvedNodePos.node().type.name)) {
112
- nodeStart = $resolvedNodePos.before(rootListDepth($resolvedNodePos));
113
- } else if (['taskList'].includes($resolvedNodePos.node().type.name)) {
114
- const listdepth = rootTaskListDepth($resolvedNodePos);
115
- nodeStart = $resolvedNodePos.before(listdepth);
116
- } else if (['blockquote'].includes($resolvedNodePos.node().type.name)) {
117
- nodeStart = $resolvedNodePos.before();
108
+ if (fg('platform_editor_elements_dnd_multi_select_patch_1')) {
109
+ nodeStart = $selectionFrom.before($selectionFrom.sharedDepth(selection.to) + 1);
110
+ if (nodeStart === $selectionFrom.pos) {
111
+ nodeStart = $selectionFrom.depth ? $selectionFrom.before() : $selectionFrom.pos;
112
+ }
113
+ const $resolvedNodePos = state.doc.resolve(nodeStart);
114
+ if (['tableRow', 'tableCell', 'tableHeader'].includes($resolvedNodePos.node().type.name)) {
115
+ const parentNodeFindRes = findParentNodeOfType(state.schema.nodes['table'])(selection);
116
+ const tablePos = parentNodeFindRes === null || parentNodeFindRes === void 0 ? void 0 : parentNodeFindRes.pos;
117
+ nodeStart = typeof tablePos === 'undefined' ? nodeStart : tablePos;
118
+ } else if (['listItem'].includes($resolvedNodePos.node().type.name)) {
119
+ nodeStart = $resolvedNodePos.before(rootListDepth($resolvedNodePos));
120
+ } else if (['taskList'].includes($resolvedNodePos.node().type.name)) {
121
+ const listdepth = rootTaskListDepth($resolvedNodePos);
122
+ nodeStart = $resolvedNodePos.before(listdepth);
123
+ } else if (['blockquote'].includes($resolvedNodePos.node().type.name)) {
124
+ nodeStart = $resolvedNodePos.before();
125
+ }
126
+ } else {
127
+ const selectionFrom = $selectionFrom.pos;
128
+ nodeStart = $selectionFrom.depth ? $selectionFrom.before() : selectionFrom;
129
+ const $resolvedNodePos = state.doc.resolve(nodeStart);
130
+ if (['tableRow', 'tableCell', 'tableHeader'].includes($resolvedNodePos.node().type.name)) {
131
+ const parentNodeFindRes = findParentNodeOfType(state.schema.nodes['table'])(selection);
132
+ const tablePos = parentNodeFindRes === null || parentNodeFindRes === void 0 ? void 0 : parentNodeFindRes.pos;
133
+ nodeStart = typeof tablePos === 'undefined' ? nodeStart : tablePos;
134
+ } else if (['listItem'].includes($resolvedNodePos.node().type.name)) {
135
+ nodeStart = $resolvedNodePos.before(rootListDepth($resolvedNodePos));
136
+ } else if (['taskList'].includes($resolvedNodePos.node().type.name)) {
137
+ const listdepth = rootTaskListDepth($resolvedNodePos);
138
+ nodeStart = $resolvedNodePos.before(listdepth);
139
+ } else if (['blockquote'].includes($resolvedNodePos.node().type.name)) {
140
+ nodeStart = $resolvedNodePos.before();
141
+ }
118
142
  }
119
143
  return Boolean(handlePos < selection.$to.pos && handlePos >= nodeStart);
120
144
  };
@@ -288,7 +288,7 @@ export const DragHandle = ({
288
288
  return tr;
289
289
  }
290
290
  const oldHandlePosCheck = handlePos >= tr.selection.$from.start() - 1 && handlePos <= tr.selection.to;
291
- const newHandlePosCheck = handlePos >= (tr.selection.$from.depth ? tr.selection.$from.before() : tr.selection.from) && handlePos < tr.selection.to;
291
+ const newHandlePosCheck = isHandleCorrelatedToSelection(view.state, tr.selection, handlePos);
292
292
  if (!tr.selection.empty && (fg('platform_editor_elements_dnd_multi_select_patch_1') ? newHandlePosCheck : oldHandlePosCheck)) {
293
293
  var _api$blockControls4;
294
294
  api === null || api === void 0 ? void 0 : (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 ? void 0 : _api$blockControls4.commands.setMultiSelectPositions()({
@@ -4,6 +4,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  import React from 'react';
5
5
  import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
6
6
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
7
+ import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
9
  import { moveNode } from './editor-commands/move-node';
9
10
  import { moveToLayout } from './editor-commands/move-to-layout';
@@ -82,6 +83,15 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
82
83
  nodeType: nodeType
83
84
  }
84
85
  }));
86
+ if (fg('platform_editor_ease_of_use_metrics')) {
87
+ var _api$metrics;
88
+ api === null || api === void 0 || (_api$metrics = api.metrics) === null || _api$metrics === void 0 || _api$metrics.commands.handleIntentToStartEdit({
89
+ shouldStartTimer: false,
90
+ shouldPersistActiveSession: true
91
+ })({
92
+ tr: tr
93
+ });
94
+ }
85
95
  return tr;
86
96
  };
87
97
  },
@@ -87,6 +87,7 @@ var getFocusedHandle = function getFocusedHandle(state) {
87
87
  };
88
88
  export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, formatMessage) {
89
89
  return function (state) {
90
+ var _hoistedPos;
90
91
  var isParentNodeOfTypeLayout;
91
92
  var shouldEnableNestedDndA11y = editorExperiment('nested-dnd', true);
92
93
  var selection = state.selection;
@@ -97,19 +98,26 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
97
98
  var expandedSelection = expandSelectionBounds(selection.$anchor, selection.$head);
98
99
  var expandedAnchor = expandedSelection.$anchor.pos;
99
100
  var expandedHead = expandedSelection.$head.pos;
100
- var currentNodePos = isMultiSelectEnabled && !getFocusedHandle(state) ? Math.min(expandedAnchor, expandedHead) : getCurrentNodePos(state);
101
+ var hoistedPos;
102
+ var from = Math.min(expandedAnchor, expandedHead);
103
+ // Nodes like lists nest within themselves, we need to find the top most position
104
+ if (isParentNodeOfTypeLayout && fg('platform_editor_elements_dnd_multi_select_patch_1')) {
105
+ var LAYOUT_COL_DEPTH = 3;
106
+ hoistedPos = state.doc.resolve(from).before(LAYOUT_COL_DEPTH);
107
+ }
108
+ var currentNodePos = isMultiSelectEnabled && !getFocusedHandle(state) && !selection.empty ? (_hoistedPos = hoistedPos) !== null && _hoistedPos !== void 0 ? _hoistedPos : from : getCurrentNodePos(state);
101
109
  if (currentNodePos > -1) {
102
110
  var _state$doc$nodeAt;
103
- var $pos = state.doc.resolve(currentNodePos);
104
- var nodeAfterPos = isMultiSelectEnabled && !getFocusedHandle(state) ? Math.max(expandedAnchor, expandedHead) : $pos.posAtIndex($pos.index() + 1);
105
- var isTopLevelNode = $pos.depth === 0;
111
+ var $currentNodePos = state.doc.resolve(currentNodePos);
112
+ var nodeAfterPos = isMultiSelectEnabled && !getFocusedHandle(state) ? Math.max(expandedAnchor, expandedHead) : $currentNodePos.posAtIndex($currentNodePos.index() + 1);
113
+ var isTopLevelNode = $currentNodePos.depth === 0;
106
114
  var moveToPos = -1;
107
- var nodeIndex = $pos.index();
115
+ var nodeIndex = $currentNodePos.index();
108
116
  var isLayoutColumnSelected = selection instanceof NodeSelection && selection.node.type.name === 'layoutColumn';
109
117
  if (direction === DIRECTION.LEFT && shouldEnableNestedDndA11y) {
110
118
  if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
111
119
  var _api$core, _api$core2;
112
- var nodeBefore = $pos.nodeBefore;
120
+ var nodeBefore = $currentNodePos.nodeBefore;
113
121
  if (nodeBefore) {
114
122
  moveToPos = currentNodePos - nodeBefore.nodeSize;
115
123
  }
@@ -133,28 +141,28 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
133
141
  api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.focus();
134
142
  return true;
135
143
  } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
136
- var _$pos$nodeBefore, _api$core3, _api$blockControls2;
137
- moveToPos = selection.from - (((_$pos$nodeBefore = $pos.nodeBefore) === null || _$pos$nodeBefore === void 0 ? void 0 : _$pos$nodeBefore.nodeSize) || 1);
144
+ var _$currentNodePos$node, _api$core3, _api$blockControls2;
145
+ moveToPos = selection.from - (((_$currentNodePos$node = $currentNodePos.nodeBefore) === null || _$currentNodePos$node === void 0 ? void 0 : _$currentNodePos$node.nodeSize) || 1);
138
146
  api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.commands) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.moveToLayout(currentNodePos, moveToPos, {
139
147
  selectMovedNode: true
140
148
  }));
141
149
  return true;
142
150
  } else {
143
- if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
151
+ if ($currentNodePos.depth < 2 || !isParentNodeOfTypeLayout) {
144
152
  return false;
145
153
  }
146
154
 
147
155
  // get the previous layoutSection node
148
- var index = $pos.index($pos.depth - 1);
149
- var grandParent = $pos.node($pos.depth - 1);
156
+ var index = $currentNodePos.index($currentNodePos.depth - 1);
157
+ var grandParent = $currentNodePos.node($currentNodePos.depth - 1);
150
158
  var previousNode = grandParent ? grandParent.maybeChild(index - 1) : null;
151
- moveToPos = $pos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
159
+ moveToPos = $currentNodePos.start() - ((previousNode === null || previousNode === void 0 ? void 0 : previousNode.nodeSize) || 1);
152
160
  }
153
161
  } else if (direction === DIRECTION.RIGHT && shouldEnableNestedDndA11y) {
154
162
  if (isTopLevelNode && editorExperiment('advanced_layouts', true) && fg('platform_editor_advanced_layouts_accessibility')) {
155
163
  var _api$core4, _api$core5;
156
- var endOfDoc = $pos.end();
157
- moveToPos = $pos.posAtIndex($pos.index() + 1);
164
+ var endOfDoc = $currentNodePos.end();
165
+ moveToPos = $currentNodePos.posAtIndex($currentNodePos.index() + 1);
158
166
  if (moveToPos >= endOfDoc) {
159
167
  return false;
160
168
  }
@@ -175,8 +183,8 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
175
183
  return true;
176
184
  } else if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
177
185
  var _api$core6, _api$blockControls4;
178
- var _index = $pos.index($pos.depth);
179
- var parent = $pos.node($pos.depth);
186
+ var _index = $currentNodePos.index($currentNodePos.depth);
187
+ var parent = $currentNodePos.node($currentNodePos.depth);
180
188
  // get the next layoutColumn node
181
189
  var nextNode = parent ? parent.maybeChild(_index + 1) : null;
182
190
 
@@ -186,29 +194,29 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
186
194
  return true;
187
195
  }
188
196
  var moveToEnd = _index === parent.childCount - 2;
189
- moveToPos = moveToEnd ? $pos.before() : selection.to + ((nextNode === null || nextNode === void 0 ? void 0 : nextNode.nodeSize) || 1);
197
+ moveToPos = moveToEnd ? $currentNodePos.before() : selection.to + ((nextNode === null || nextNode === void 0 ? void 0 : nextNode.nodeSize) || 1);
190
198
  api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(api === null || api === void 0 || (_api$blockControls4 = api.blockControls) === null || _api$blockControls4 === void 0 || (_api$blockControls4 = _api$blockControls4.commands) === null || _api$blockControls4 === void 0 ? void 0 : _api$blockControls4.moveToLayout(currentNodePos, moveToPos, {
191
199
  moveToEnd: moveToEnd,
192
200
  selectMovedNode: true
193
201
  }));
194
202
  return true;
195
203
  } else {
196
- if ($pos.depth < 2 || !isParentNodeOfTypeLayout) {
204
+ if ($currentNodePos.depth < 2 || !isParentNodeOfTypeLayout) {
197
205
  return false;
198
206
  }
199
- moveToPos = $pos.after($pos.depth) + 1;
207
+ moveToPos = $currentNodePos.after($currentNodePos.depth) + 1;
200
208
  }
201
209
  } else if (direction === DIRECTION.UP) {
202
210
  if (isLayoutColumnSelected && fg('platform_editor_advanced_layouts_accessibility')) {
203
- moveToPos = $pos.start() - 1;
211
+ moveToPos = $currentNodePos.start() - 1;
204
212
  } else {
205
- var _nodeBefore = $pos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $pos.node($pos.depth) : $pos.nodeBefore;
213
+ var _nodeBefore = $currentNodePos.depth > 1 && nodeIndex === 0 && shouldEnableNestedDndA11y ? $currentNodePos.node($currentNodePos.depth) : $currentNodePos.nodeBefore;
206
214
  if (_nodeBefore) {
207
215
  moveToPos = currentNodePos - _nodeBefore.nodeSize;
208
216
  }
209
217
  }
210
218
  } else {
211
- var _endOfDoc = $pos.end();
219
+ var _endOfDoc = $currentNodePos.end();
212
220
  if (nodeAfterPos > _endOfDoc) {
213
221
  return false;
214
222
  }
@@ -225,14 +233,23 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
225
233
  var nodeType = (_state$doc$nodeAt = state.doc.nodeAt(currentNodePos)) === null || _state$doc$nodeAt === void 0 ? void 0 : _state$doc$nodeAt.type.name;
226
234
 
227
235
  // only move the node if the destination is at the same depth, not support moving a nested node to a parent node
228
- var shouldMoveNode = (shouldEnableNestedDndA11y ? moveToPos > -1 && $pos.depth === state.doc.resolve(moveToPos).depth || nodeType === 'layoutColumn' : moveToPos > -1) || nodeType === 'layoutColumn' && fg('platform_editor_advanced_layouts_accessibility');
236
+ var shouldMoveNode = (shouldEnableNestedDndA11y ? moveToPos > -1 && $currentNodePos.depth === state.doc.resolve(moveToPos).depth || nodeType === 'layoutColumn' : moveToPos > -1) || nodeType === 'layoutColumn' && fg('platform_editor_advanced_layouts_accessibility');
237
+ var _expandSelectionBound = expandSelectionBounds($currentNodePos, selection.$to),
238
+ $newAnchor = _expandSelectionBound.$anchor,
239
+ $newHead = _expandSelectionBound.$head;
229
240
  if (shouldMoveNode) {
230
241
  var _api$core7;
231
242
  api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref4) {
232
243
  var tr = _ref4.tr;
233
- api === null || api === void 0 || api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
234
- tr: tr
235
- });
244
+ if (fg('platform_editor_elements_dnd_multi_select_patch_1')) {
245
+ api === null || api === void 0 || api.blockControls.commands.setMultiSelectPositions($newAnchor.pos, $newHead.pos)({
246
+ tr: tr
247
+ });
248
+ } else {
249
+ api === null || api === void 0 || api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
250
+ tr: tr
251
+ });
252
+ }
236
253
  moveNode(api)(currentNodePos, moveToPos, INPUT_METHOD.SHORTCUT, formatMessage)({
237
254
  tr: tr
238
255
  });
@@ -254,9 +271,15 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
254
271
  var _api$core9;
255
272
  api === null || api === void 0 || (_api$core9 = api.core) === null || _api$core9 === void 0 || _api$core9.actions.execute(function (_ref6) {
256
273
  var tr = _ref6.tr;
257
- api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
258
- tr: tr
259
- });
274
+ if (fg('platform_editor_elements_dnd_multi_select_patch_1')) {
275
+ api === null || api === void 0 || api.blockControls.commands.setMultiSelectPositions($newAnchor.pos, $newHead.pos)({
276
+ tr: tr
277
+ });
278
+ } else {
279
+ api === null || api === void 0 || api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
280
+ tr: tr
281
+ });
282
+ }
260
283
  tr.scrollIntoView();
261
284
  return tr;
262
285
  });
@@ -287,6 +310,12 @@ export var moveNode = function moveNode(api) {
287
310
  var isMultiSelect = editorExperiment('platform_editor_element_drag_and_drop_multiselect', true, {
288
311
  exposure: true
289
312
  });
313
+ if (fg('platform_editor_ease_of_use_metrics')) {
314
+ var _api$metrics;
315
+ api === null || api === void 0 || (_api$metrics = api.metrics) === null || _api$metrics === void 0 || _api$metrics.commands.setContentMoved()({
316
+ tr: tr
317
+ });
318
+ }
290
319
  var slicePosition = getSelectedSlicePosition(start, tr, api);
291
320
  if (isMultiSelect) {
292
321
  sliceFrom = slicePosition.from;
@@ -313,6 +313,12 @@ export var moveToLayout = function moveToLayout(api) {
313
313
  if (!fromContentWithoutBreakout) {
314
314
  return tr;
315
315
  }
316
+ if (fg('platform_editor_ease_of_use_metrics')) {
317
+ var _api$metrics;
318
+ api === null || api === void 0 || (_api$metrics = api.metrics) === null || _api$metrics === void 0 || _api$metrics.commands.setContentMoved()({
319
+ tr: tr
320
+ });
321
+ }
316
322
  var isMultiSelect = editorExperiment('platform_editor_element_drag_and_drop_multiselect', true);
317
323
  if (toNode.type === layoutSection) {
318
324
  var toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize - 1 : to + 1;