@atlaskit/editor-plugin-block-controls 2.26.4 → 2.27.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.
- package/CHANGELOG.md +21 -0
- package/dist/cjs/blockControlsPlugin.js +10 -4
- package/dist/cjs/editor-commands/move-node.js +38 -8
- package/dist/cjs/pm-plugins/decorations-drop-target.js +11 -5
- package/dist/cjs/pm-plugins/main.js +3 -1
- package/dist/cjs/pm-plugins/utils/getSelection.js +2 -2
- package/dist/cjs/pm-plugins/utils/selection.js +8 -5
- package/dist/cjs/pm-plugins/utils/validation.js +2 -1
- package/dist/cjs/ui/drag-handle.js +1 -1
- package/dist/es2019/blockControlsPlugin.js +10 -5
- package/dist/es2019/editor-commands/move-node.js +37 -5
- package/dist/es2019/pm-plugins/decorations-drop-target.js +12 -5
- package/dist/es2019/pm-plugins/main.js +3 -1
- package/dist/es2019/pm-plugins/utils/getSelection.js +1 -1
- package/dist/es2019/pm-plugins/utils/selection.js +8 -6
- package/dist/es2019/pm-plugins/utils/validation.js +2 -1
- package/dist/es2019/ui/drag-handle.js +2 -2
- package/dist/esm/blockControlsPlugin.js +10 -4
- package/dist/esm/editor-commands/move-node.js +39 -9
- package/dist/esm/pm-plugins/decorations-drop-target.js +11 -5
- package/dist/esm/pm-plugins/main.js +3 -1
- package/dist/esm/pm-plugins/utils/getSelection.js +1 -1
- package/dist/esm/pm-plugins/utils/selection.js +8 -5
- package/dist/esm/pm-plugins/utils/validation.js +2 -1
- package/dist/esm/ui/drag-handle.js +2 -2
- package/dist/types/blockControlsPluginType.d.ts +1 -1
- package/dist/types/pm-plugins/utils/getSelection.d.ts +1 -1
- package/dist/types/pm-plugins/utils/selection.d.ts +2 -2
- package/dist/types/pm-plugins/utils/validation.d.ts +1 -1
- package/dist/types-ts4.5/blockControlsPluginType.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/utils/getSelection.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/utils/selection.d.ts +2 -2
- package/dist/types-ts4.5/pm-plugins/utils/validation.d.ts +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 2.27.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#112996](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/112996)
|
|
8
|
+
[`e76ab95452657`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e76ab95452657) -
|
|
9
|
+
ED-26395: Added tests for canMoveSliceToIndex, and fix drop target showing when first node is p,
|
|
10
|
+
second node table, drop into panel
|
|
11
|
+
|
|
12
|
+
## 2.27.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- [#114097](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/114097)
|
|
17
|
+
[`c767c26ecbc7c`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/c767c26ecbc7c) -
|
|
18
|
+
[ux] [ED-26269] Support moving multiple nodes with shortcuts
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
|
|
3
24
|
## 2.26.4
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -67,16 +67,22 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
|
|
|
67
67
|
return tr;
|
|
68
68
|
};
|
|
69
69
|
},
|
|
70
|
-
setMultiSelectPositions: function setMultiSelectPositions() {
|
|
70
|
+
setMultiSelectPositions: function setMultiSelectPositions(anchor, head) {
|
|
71
71
|
return function (_ref5) {
|
|
72
72
|
var _api$selection;
|
|
73
73
|
var tr = _ref5.tr;
|
|
74
74
|
var _tr$selection = tr.selection,
|
|
75
75
|
userAnchor = _tr$selection.anchor,
|
|
76
76
|
userHead = _tr$selection.head;
|
|
77
|
-
var
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
var expandedAnchor, expandedHead;
|
|
78
|
+
if (anchor !== undefined && head !== undefined) {
|
|
79
|
+
expandedAnchor = tr.doc.resolve(anchor);
|
|
80
|
+
expandedHead = tr.doc.resolve(head);
|
|
81
|
+
} else {
|
|
82
|
+
var expandedSelection = (0, _selection.expandSelectionBounds)(tr.selection.$anchor, tr.selection.$head);
|
|
83
|
+
expandedAnchor = expandedSelection.$anchor;
|
|
84
|
+
expandedHead = expandedSelection.$head;
|
|
85
|
+
}
|
|
80
86
|
api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || _api$selection.commands.setManualSelection(expandedAnchor.pos, expandedHead.pos)({
|
|
81
87
|
tr: tr
|
|
82
88
|
});
|
|
@@ -95,7 +95,18 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
|
|
|
95
95
|
if (shouldEnableNestedDndA11y) {
|
|
96
96
|
isParentNodeOfTypeLayout = !!(0, _utils2.findParentNodeOfType)([state.schema.nodes.layoutSection])(state.selection);
|
|
97
97
|
}
|
|
98
|
-
var
|
|
98
|
+
var isMultiSelectEnabled = (0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true);
|
|
99
|
+
var expandedAnchor, expandedHead;
|
|
100
|
+
var pluginState = api === null || api === void 0 ? void 0 : api.blockControls.sharedState.currentState();
|
|
101
|
+
if (pluginState !== null && pluginState !== void 0 && pluginState.multiSelectDnD) {
|
|
102
|
+
expandedAnchor = pluginState.multiSelectDnD.anchor;
|
|
103
|
+
expandedHead = pluginState.multiSelectDnD.head;
|
|
104
|
+
} else {
|
|
105
|
+
var expandedSelection = (0, _selection.expandSelectionBounds)(selection.$anchor, selection.$head);
|
|
106
|
+
expandedAnchor = expandedSelection.$anchor.pos;
|
|
107
|
+
expandedHead = expandedSelection.$head.pos;
|
|
108
|
+
}
|
|
109
|
+
var currentNodePos = isMultiSelectEnabled ? Math.min(expandedAnchor, expandedHead) : getCurrentNodePos(state);
|
|
99
110
|
if (currentNodePos > -1) {
|
|
100
111
|
var _state$doc$nodeAt;
|
|
101
112
|
var $pos = state.doc.resolve(currentNodePos);
|
|
@@ -206,7 +217,7 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
|
|
|
206
217
|
}
|
|
207
218
|
} else {
|
|
208
219
|
var _endOfDoc = $pos.end();
|
|
209
|
-
var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
|
|
220
|
+
var nodeAfterPos = isMultiSelectEnabled ? Math.max(expandedAnchor, expandedHead) : $pos.posAtIndex($pos.index() + 1);
|
|
210
221
|
if (nodeAfterPos > _endOfDoc) {
|
|
211
222
|
return false;
|
|
212
223
|
}
|
|
@@ -228,6 +239,9 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
|
|
|
228
239
|
var _api$core7;
|
|
229
240
|
api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref4) {
|
|
230
241
|
var tr = _ref4.tr;
|
|
242
|
+
api === null || api === void 0 || api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
|
|
243
|
+
tr: tr
|
|
244
|
+
});
|
|
231
245
|
moveNode(api)(currentNodePos, moveToPos, _analytics.INPUT_METHOD.SHORTCUT, formatMessage)({
|
|
232
246
|
tr: tr
|
|
233
247
|
});
|
|
@@ -235,7 +249,7 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
|
|
|
235
249
|
return tr;
|
|
236
250
|
});
|
|
237
251
|
return true;
|
|
238
|
-
} else if (nodeType) {
|
|
252
|
+
} else if (nodeType && !isMultiSelectEnabled) {
|
|
239
253
|
var _api$core8;
|
|
240
254
|
// If the node is first/last one, only select the node
|
|
241
255
|
api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref5) {
|
|
@@ -245,6 +259,17 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
|
|
|
245
259
|
return tr;
|
|
246
260
|
});
|
|
247
261
|
return true;
|
|
262
|
+
} else if (isMultiSelectEnabled) {
|
|
263
|
+
var _api$core9;
|
|
264
|
+
api === null || api === void 0 || (_api$core9 = api.core) === null || _api$core9 === void 0 || _api$core9.actions.execute(function (_ref6) {
|
|
265
|
+
var tr = _ref6.tr;
|
|
266
|
+
api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
|
|
267
|
+
tr: tr
|
|
268
|
+
});
|
|
269
|
+
tr.scrollIntoView();
|
|
270
|
+
return tr;
|
|
271
|
+
});
|
|
272
|
+
return true;
|
|
248
273
|
}
|
|
249
274
|
}
|
|
250
275
|
return false;
|
|
@@ -254,8 +279,9 @@ var moveNode = exports.moveNode = function moveNode(api) {
|
|
|
254
279
|
return function (start, to) {
|
|
255
280
|
var inputMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _analytics.INPUT_METHOD.DRAG_AND_DROP;
|
|
256
281
|
var formatMessage = arguments.length > 3 ? arguments[3] : undefined;
|
|
257
|
-
return function (
|
|
258
|
-
var
|
|
282
|
+
return function (_ref7) {
|
|
283
|
+
var _api$blockControls$co;
|
|
284
|
+
var tr = _ref7.tr;
|
|
259
285
|
if (!api) {
|
|
260
286
|
return tr;
|
|
261
287
|
}
|
|
@@ -327,10 +353,14 @@ var moveNode = exports.moveNode = function moveNode(api) {
|
|
|
327
353
|
mappedTo = tr.mapping.map(to);
|
|
328
354
|
tr.insert(mappedTo, _nodeCopy); // insert the content at the new position
|
|
329
355
|
}
|
|
330
|
-
|
|
331
|
-
tr.
|
|
356
|
+
var sliceSize = sliceTo - sliceFrom;
|
|
357
|
+
tr = inputMethod === _analytics.INPUT_METHOD.DRAG_AND_DROP ? (0, _getSelection.setCursorPositionAtMovedNode)(tr, mappedTo) : isMultiSelect ? (_api$blockControls$co = api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions(mappedTo, mappedTo + sliceSize)({
|
|
358
|
+
tr: tr
|
|
359
|
+
})) !== null && _api$blockControls$co !== void 0 ? _api$blockControls$co : tr : (0, _getSelection.selectNode)(tr, mappedTo, handleNode.type.name);
|
|
360
|
+
var currMeta = tr.getMeta(_main.key);
|
|
361
|
+
tr.setMeta(_main.key, _objectSpread(_objectSpread({}, currMeta), {}, {
|
|
332
362
|
nodeMoved: true
|
|
333
|
-
});
|
|
363
|
+
}));
|
|
334
364
|
api === null || api === void 0 || api.core.actions.focus();
|
|
335
365
|
var $mappedTo = tr.doc.resolve(mappedTo);
|
|
336
366
|
var expandAncestor = (0, _utils2.findParentNodeOfTypeClosestToPos)($to, [expand, nestedExpand]);
|
|
@@ -8,6 +8,7 @@ exports.findDropTargetDecs = exports.dropTargetDecorations = exports.createLayou
|
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _react = require("react");
|
|
10
10
|
var _uuid = _interopRequireDefault(require("uuid"));
|
|
11
|
+
var _selection = require("@atlaskit/editor-common/selection");
|
|
11
12
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
12
13
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
13
14
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
@@ -166,6 +167,15 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
|
|
|
166
167
|
prevNodeStack.push(node);
|
|
167
168
|
};
|
|
168
169
|
var isAdvancedLayoutsPreRelease2 = (0, _experiments.editorExperiment)('advanced_layouts', true);
|
|
170
|
+
|
|
171
|
+
// For deciding to show drop targets or not when multiple nodes are selected
|
|
172
|
+
var selection = newState.selection;
|
|
173
|
+
var _expandSelectionBound = (0, _selection.expandSelectionBounds)(selection.$anchor, selection.$head),
|
|
174
|
+
expandedAnchor = _expandSelectionBound.$anchor,
|
|
175
|
+
expandedHead = _expandSelectionBound.$head;
|
|
176
|
+
var selectionFrom = Math.min(expandedAnchor.pos, expandedHead.pos);
|
|
177
|
+
var selectionTo = Math.max(expandedAnchor.pos, expandedHead.pos);
|
|
178
|
+
var handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom && activeNodePos <= selectionTo;
|
|
169
179
|
newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, index) {
|
|
170
180
|
var depth = 0;
|
|
171
181
|
// drop target deco at the end position
|
|
@@ -200,10 +210,6 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
|
|
|
200
210
|
|
|
201
211
|
// When multi select is on, validate all the nodes in the selection instead of just the handle node
|
|
202
212
|
if (isMultiSelect) {
|
|
203
|
-
var selection = newState.selection;
|
|
204
|
-
var selectionFrom = selection.$from.pos;
|
|
205
|
-
var selectionTo = selection.$to.pos;
|
|
206
|
-
var handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom - 1 && activeNodePos <= selectionTo;
|
|
207
213
|
var selectionSlice = newState.doc.slice(selectionFrom, selectionTo, false);
|
|
208
214
|
var selectionSliceChildCount = selectionSlice.content.childCount;
|
|
209
215
|
var canDropSingleNode = true;
|
|
@@ -211,7 +217,7 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
|
|
|
211
217
|
|
|
212
218
|
// when there is only one node in the slice, use the same logic as when multi select is not on
|
|
213
219
|
if (selectionSliceChildCount > 1 && handleInsideSelection) {
|
|
214
|
-
canDropMultipleNodes = (0, _validation.canMoveSliceToIndex)(selectionSlice, selectionFrom,
|
|
220
|
+
canDropMultipleNodes = (0, _validation.canMoveSliceToIndex)(selectionSlice, selectionFrom, parent, index, $pos);
|
|
215
221
|
} else {
|
|
216
222
|
canDropSingleNode = !!(activePMNode && (0, _validation.canMoveNodeToIndex)(parent, index, activePMNode, $pos, node));
|
|
217
223
|
}
|
|
@@ -189,7 +189,9 @@ var newApply = exports.newApply = function newApply(api, formatMessage, tr, curr
|
|
|
189
189
|
var resizerMeta = tr.getMeta('is-resizer-resizing');
|
|
190
190
|
isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
|
|
191
191
|
if (multiSelectDnD && flags.isMultiSelectEnabled) {
|
|
192
|
-
multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false
|
|
192
|
+
multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false ||
|
|
193
|
+
// For move node with shortcut, only reset when the selection changes
|
|
194
|
+
tr.selection.anchor !== multiSelectDnD.textAnchor || tr.selection.head !== multiSelectDnD.textHead ? undefined : multiSelectDnD;
|
|
193
195
|
}
|
|
194
196
|
var _getTrMetadata = (0, _transactions.getTrMetadata)(tr),
|
|
195
197
|
from = _getTrMetadata.from,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.setCursorPositionAtMovedNode = exports.selectNode = exports.rootTaskListDepth = exports.rootListDepth = exports.
|
|
6
|
+
exports.setCursorPositionAtMovedNode = exports.selectNode = exports.rootTaskListDepth = exports.rootListDepth = exports.isHandleCorrelatedToSelection = exports.getSelection = exports.getInlineNodePos = void 0;
|
|
7
7
|
var _selection = require("@atlaskit/editor-common/selection");
|
|
8
8
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
9
9
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
@@ -100,7 +100,7 @@ var setCursorPositionAtMovedNode = exports.setCursorPositionAtMovedNode = functi
|
|
|
100
100
|
* @param handlePos
|
|
101
101
|
* @returns
|
|
102
102
|
*/
|
|
103
|
-
var
|
|
103
|
+
var isHandleCorrelatedToSelection = exports.isHandleCorrelatedToSelection = function isHandleCorrelatedToSelection(state, selection, handlePos) {
|
|
104
104
|
if (selection.empty) {
|
|
105
105
|
return false;
|
|
106
106
|
}
|
|
@@ -4,10 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getSelectedSlicePosition = exports.getMultiSelectionIfPosInside = void 0;
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
var
|
|
10
|
-
|
|
7
|
+
var _main = require("../main");
|
|
8
|
+
var getMultiSelectionIfPosInside = exports.getMultiSelectionIfPosInside = function getMultiSelectionIfPosInside(api, pos, tr) {
|
|
9
|
+
var _api$blockControls, _pluginState$multiSel, _tr$getMeta;
|
|
10
|
+
var pluginState = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState();
|
|
11
|
+
// With move nodes shortcut, we expand selection and move node within one transaction,
|
|
12
|
+
// Hence we also look for `multiSelectDnD` in transaction meta
|
|
13
|
+
var multiSelectDnD = (_pluginState$multiSel = pluginState === null || pluginState === void 0 ? void 0 : pluginState.multiSelectDnD) !== null && _pluginState$multiSel !== void 0 ? _pluginState$multiSel : tr === null || tr === void 0 || (_tr$getMeta = tr.getMeta(_main.key)) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.multiSelectDnD;
|
|
11
14
|
if (multiSelectDnD && multiSelectDnD.anchor >= 0 && multiSelectDnD.head >= 0) {
|
|
12
15
|
var multiFrom = Math.min(multiSelectDnD.anchor, multiSelectDnD.head);
|
|
13
16
|
var multiTo = Math.max(multiSelectDnD.anchor, multiSelectDnD.head);
|
|
@@ -27,7 +30,7 @@ var getMultiSelectionIfPosInside = exports.getMultiSelectionIfPosInside = functi
|
|
|
27
30
|
*/
|
|
28
31
|
var getSelectedSlicePosition = exports.getSelectedSlicePosition = function getSelectedSlicePosition(handlePos, tr, api) {
|
|
29
32
|
var _activeNode$nodeSize;
|
|
30
|
-
var _getMultiSelectionIfP = getMultiSelectionIfPosInside(api, handlePos),
|
|
33
|
+
var _getMultiSelectionIfP = getMultiSelectionIfPosInside(api, handlePos, tr),
|
|
31
34
|
anchor = _getMultiSelectionIfP.anchor,
|
|
32
35
|
head = _getMultiSelectionIfP.head;
|
|
33
36
|
var inSelection = anchor !== undefined && head !== undefined;
|
|
@@ -121,8 +121,9 @@ function canMoveNodeToIndex(destParent, indexIntoParent, srcNode, $destNodePos,
|
|
|
121
121
|
}
|
|
122
122
|
return destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType);
|
|
123
123
|
}
|
|
124
|
-
function canMoveSliceToIndex(slice, sliceFromPos,
|
|
124
|
+
function canMoveSliceToIndex(slice, sliceFromPos, destParent, indexIntoParent, $destNodePos, destNode) {
|
|
125
125
|
var canMoveNodes = true;
|
|
126
|
+
var doc = $destNodePos.doc;
|
|
126
127
|
var nodesPos = [];
|
|
127
128
|
for (var i = 0; i < slice.content.childCount; i++) {
|
|
128
129
|
var node = slice.content.maybeChild(i);
|
|
@@ -401,7 +401,7 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
|
|
|
401
401
|
if (!isMultiSelect || typeof start !== 'number' || !selection) {
|
|
402
402
|
return;
|
|
403
403
|
}
|
|
404
|
-
setDragHandleSelected((0, _getSelection.
|
|
404
|
+
setDragHandleSelected((0, _getSelection.isHandleCorrelatedToSelection)(view.state, selection, start));
|
|
405
405
|
}, [start, selection, view.state]);
|
|
406
406
|
var helpDescriptors = isTopLevelNode && (0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_accessibility') ? [{
|
|
407
407
|
description: formatMessage(_messages.blockControlsMessages.dragToMove)
|
|
@@ -56,7 +56,7 @@ export const blockControlsPlugin = ({
|
|
|
56
56
|
});
|
|
57
57
|
return tr;
|
|
58
58
|
},
|
|
59
|
-
setMultiSelectPositions: () => ({
|
|
59
|
+
setMultiSelectPositions: (anchor, head) => ({
|
|
60
60
|
tr
|
|
61
61
|
}) => {
|
|
62
62
|
var _api$selection;
|
|
@@ -64,10 +64,15 @@ export const blockControlsPlugin = ({
|
|
|
64
64
|
anchor: userAnchor,
|
|
65
65
|
head: userHead
|
|
66
66
|
} = tr.selection;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
let expandedAnchor, expandedHead;
|
|
68
|
+
if (anchor !== undefined && head !== undefined) {
|
|
69
|
+
expandedAnchor = tr.doc.resolve(anchor);
|
|
70
|
+
expandedHead = tr.doc.resolve(head);
|
|
71
|
+
} else {
|
|
72
|
+
const expandedSelection = expandSelectionBounds(tr.selection.$anchor, tr.selection.$head);
|
|
73
|
+
expandedAnchor = expandedSelection.$anchor;
|
|
74
|
+
expandedHead = expandedSelection.$head;
|
|
75
|
+
}
|
|
71
76
|
api === null || api === void 0 ? void 0 : (_api$selection = api.selection) === null || _api$selection === void 0 ? void 0 : _api$selection.commands.setManualSelection(expandedAnchor.pos, expandedHead.pos)({
|
|
72
77
|
tr
|
|
73
78
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import { expandedState } from '@atlaskit/editor-common/expand';
|
|
3
3
|
import { blockControlsMessages } from '@atlaskit/editor-common/messages';
|
|
4
|
-
import { GapCursorSelection } from '@atlaskit/editor-common/selection';
|
|
4
|
+
import { GapCursorSelection, expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
5
5
|
import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
|
|
6
6
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
7
7
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
@@ -92,7 +92,18 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
92
92
|
if (shouldEnableNestedDndA11y) {
|
|
93
93
|
isParentNodeOfTypeLayout = !!findParentNodeOfType([state.schema.nodes.layoutSection])(state.selection);
|
|
94
94
|
}
|
|
95
|
-
const
|
|
95
|
+
const isMultiSelectEnabled = editorExperiment('platform_editor_element_drag_and_drop_multiselect', true);
|
|
96
|
+
let expandedAnchor, expandedHead;
|
|
97
|
+
const pluginState = api === null || api === void 0 ? void 0 : api.blockControls.sharedState.currentState();
|
|
98
|
+
if (pluginState !== null && pluginState !== void 0 && pluginState.multiSelectDnD) {
|
|
99
|
+
expandedAnchor = pluginState.multiSelectDnD.anchor;
|
|
100
|
+
expandedHead = pluginState.multiSelectDnD.head;
|
|
101
|
+
} else {
|
|
102
|
+
const expandedSelection = expandSelectionBounds(selection.$anchor, selection.$head);
|
|
103
|
+
expandedAnchor = expandedSelection.$anchor.pos;
|
|
104
|
+
expandedHead = expandedSelection.$head.pos;
|
|
105
|
+
}
|
|
106
|
+
const currentNodePos = isMultiSelectEnabled ? Math.min(expandedAnchor, expandedHead) : getCurrentNodePos(state);
|
|
96
107
|
if (currentNodePos > -1) {
|
|
97
108
|
var _state$doc$nodeAt;
|
|
98
109
|
const $pos = state.doc.resolve(currentNodePos);
|
|
@@ -205,7 +216,7 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
205
216
|
}
|
|
206
217
|
} else {
|
|
207
218
|
const endOfDoc = $pos.end();
|
|
208
|
-
const nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
|
|
219
|
+
const nodeAfterPos = isMultiSelectEnabled ? Math.max(expandedAnchor, expandedHead) : $pos.posAtIndex($pos.index() + 1);
|
|
209
220
|
if (nodeAfterPos > endOfDoc) {
|
|
210
221
|
return false;
|
|
211
222
|
}
|
|
@@ -228,6 +239,9 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
228
239
|
api === null || api === void 0 ? void 0 : (_api$core7 = api.core) === null || _api$core7 === void 0 ? void 0 : _api$core7.actions.execute(({
|
|
229
240
|
tr
|
|
230
241
|
}) => {
|
|
242
|
+
api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
|
|
243
|
+
tr
|
|
244
|
+
});
|
|
231
245
|
moveNode(api)(currentNodePos, moveToPos, INPUT_METHOD.SHORTCUT, formatMessage)({
|
|
232
246
|
tr
|
|
233
247
|
});
|
|
@@ -235,7 +249,7 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
235
249
|
return tr;
|
|
236
250
|
});
|
|
237
251
|
return true;
|
|
238
|
-
} else if (nodeType) {
|
|
252
|
+
} else if (nodeType && !isMultiSelectEnabled) {
|
|
239
253
|
var _api$core8;
|
|
240
254
|
// If the node is first/last one, only select the node
|
|
241
255
|
api === null || api === void 0 ? void 0 : (_api$core8 = api.core) === null || _api$core8 === void 0 ? void 0 : _api$core8.actions.execute(({
|
|
@@ -246,6 +260,18 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
246
260
|
return tr;
|
|
247
261
|
});
|
|
248
262
|
return true;
|
|
263
|
+
} else if (isMultiSelectEnabled) {
|
|
264
|
+
var _api$core9;
|
|
265
|
+
api === null || api === void 0 ? void 0 : (_api$core9 = api.core) === null || _api$core9 === void 0 ? void 0 : _api$core9.actions.execute(({
|
|
266
|
+
tr
|
|
267
|
+
}) => {
|
|
268
|
+
api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
|
|
269
|
+
tr
|
|
270
|
+
});
|
|
271
|
+
tr.scrollIntoView();
|
|
272
|
+
return tr;
|
|
273
|
+
});
|
|
274
|
+
return true;
|
|
249
275
|
}
|
|
250
276
|
}
|
|
251
277
|
return false;
|
|
@@ -254,6 +280,7 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
|
|
|
254
280
|
export const moveNode = api => (start, to, inputMethod = INPUT_METHOD.DRAG_AND_DROP, formatMessage) => ({
|
|
255
281
|
tr
|
|
256
282
|
}) => {
|
|
283
|
+
var _api$blockControls$co2;
|
|
257
284
|
if (!api) {
|
|
258
285
|
return tr;
|
|
259
286
|
}
|
|
@@ -326,8 +353,13 @@ export const moveNode = api => (start, to, inputMethod = INPUT_METHOD.DRAG_AND_D
|
|
|
326
353
|
mappedTo = tr.mapping.map(to);
|
|
327
354
|
tr.insert(mappedTo, nodeCopy); // insert the content at the new position
|
|
328
355
|
}
|
|
329
|
-
|
|
356
|
+
const sliceSize = sliceTo - sliceFrom;
|
|
357
|
+
tr = inputMethod === INPUT_METHOD.DRAG_AND_DROP ? setCursorPositionAtMovedNode(tr, mappedTo) : isMultiSelect ? (_api$blockControls$co2 = api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions(mappedTo, mappedTo + sliceSize)({
|
|
358
|
+
tr
|
|
359
|
+
})) !== null && _api$blockControls$co2 !== void 0 ? _api$blockControls$co2 : tr : selectNode(tr, mappedTo, handleNode.type.name);
|
|
360
|
+
const currMeta = tr.getMeta(key);
|
|
330
361
|
tr.setMeta(key, {
|
|
362
|
+
...currMeta,
|
|
331
363
|
nodeMoved: true
|
|
332
364
|
});
|
|
333
365
|
api === null || api === void 0 ? void 0 : api.core.actions.focus();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createElement } from 'react';
|
|
2
2
|
import uuid from 'uuid';
|
|
3
|
+
import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
3
4
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
4
5
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
6
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
@@ -153,6 +154,16 @@ export const dropTargetDecorations = (newState, api, formatMessage, nodeViewPort
|
|
|
153
154
|
prevNodeStack.push(node);
|
|
154
155
|
};
|
|
155
156
|
const isAdvancedLayoutsPreRelease2 = editorExperiment('advanced_layouts', true);
|
|
157
|
+
|
|
158
|
+
// For deciding to show drop targets or not when multiple nodes are selected
|
|
159
|
+
const selection = newState.selection;
|
|
160
|
+
const {
|
|
161
|
+
$anchor: expandedAnchor,
|
|
162
|
+
$head: expandedHead
|
|
163
|
+
} = expandSelectionBounds(selection.$anchor, selection.$head);
|
|
164
|
+
const selectionFrom = Math.min(expandedAnchor.pos, expandedHead.pos);
|
|
165
|
+
const selectionTo = Math.max(expandedAnchor.pos, expandedHead.pos);
|
|
166
|
+
const handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom && activeNodePos <= selectionTo;
|
|
156
167
|
newState.doc.nodesBetween(docFrom, docTo, (node, pos, parent, index) => {
|
|
157
168
|
let depth = 0;
|
|
158
169
|
// drop target deco at the end position
|
|
@@ -187,10 +198,6 @@ export const dropTargetDecorations = (newState, api, formatMessage, nodeViewPort
|
|
|
187
198
|
|
|
188
199
|
// When multi select is on, validate all the nodes in the selection instead of just the handle node
|
|
189
200
|
if (isMultiSelect) {
|
|
190
|
-
const selection = newState.selection;
|
|
191
|
-
const selectionFrom = selection.$from.pos;
|
|
192
|
-
const selectionTo = selection.$to.pos;
|
|
193
|
-
const handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom - 1 && activeNodePos <= selectionTo;
|
|
194
201
|
const selectionSlice = newState.doc.slice(selectionFrom, selectionTo, false);
|
|
195
202
|
const selectionSliceChildCount = selectionSlice.content.childCount;
|
|
196
203
|
let canDropSingleNode = true;
|
|
@@ -198,7 +205,7 @@ export const dropTargetDecorations = (newState, api, formatMessage, nodeViewPort
|
|
|
198
205
|
|
|
199
206
|
// when there is only one node in the slice, use the same logic as when multi select is not on
|
|
200
207
|
if (selectionSliceChildCount > 1 && handleInsideSelection) {
|
|
201
|
-
canDropMultipleNodes = canMoveSliceToIndex(selectionSlice, selectionFrom,
|
|
208
|
+
canDropMultipleNodes = canMoveSliceToIndex(selectionSlice, selectionFrom, parent, index, $pos);
|
|
202
209
|
} else {
|
|
203
210
|
canDropSingleNode = !!(activePMNode && canMoveNodeToIndex(parent, index, activePMNode, $pos, node));
|
|
204
211
|
}
|
|
@@ -189,7 +189,9 @@ export const newApply = (api, formatMessage, tr, currentState, newState, flags,
|
|
|
189
189
|
const resizerMeta = tr.getMeta('is-resizer-resizing');
|
|
190
190
|
isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
|
|
191
191
|
if (multiSelectDnD && flags.isMultiSelectEnabled) {
|
|
192
|
-
multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false
|
|
192
|
+
multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false ||
|
|
193
|
+
// For move node with shortcut, only reset when the selection changes
|
|
194
|
+
tr.selection.anchor !== multiSelectDnD.textAnchor || tr.selection.head !== multiSelectDnD.textHead ? undefined : multiSelectDnD;
|
|
193
195
|
}
|
|
194
196
|
const {
|
|
195
197
|
from,
|
|
@@ -96,7 +96,7 @@ export const setCursorPositionAtMovedNode = (tr, start) => {
|
|
|
96
96
|
* @param handlePos
|
|
97
97
|
* @returns
|
|
98
98
|
*/
|
|
99
|
-
export const
|
|
99
|
+
export const isHandleCorrelatedToSelection = (state, selection, handlePos) => {
|
|
100
100
|
if (selection.empty) {
|
|
101
101
|
return false;
|
|
102
102
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { key } from '../main';
|
|
2
|
+
export const getMultiSelectionIfPosInside = (api, pos, tr) => {
|
|
3
|
+
var _api$blockControls, _pluginState$multiSel, _tr$getMeta;
|
|
4
|
+
const pluginState = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState();
|
|
5
|
+
// With move nodes shortcut, we expand selection and move node within one transaction,
|
|
6
|
+
// Hence we also look for `multiSelectDnD` in transaction meta
|
|
7
|
+
const multiSelectDnD = (_pluginState$multiSel = pluginState === null || pluginState === void 0 ? void 0 : pluginState.multiSelectDnD) !== null && _pluginState$multiSel !== void 0 ? _pluginState$multiSel : tr === null || tr === void 0 ? void 0 : (_tr$getMeta = tr.getMeta(key)) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.multiSelectDnD;
|
|
6
8
|
if (multiSelectDnD && multiSelectDnD.anchor >= 0 && multiSelectDnD.head >= 0) {
|
|
7
9
|
const multiFrom = Math.min(multiSelectDnD.anchor, multiSelectDnD.head);
|
|
8
10
|
const multiTo = Math.max(multiSelectDnD.anchor, multiSelectDnD.head);
|
|
@@ -25,7 +27,7 @@ export const getSelectedSlicePosition = (handlePos, tr, api) => {
|
|
|
25
27
|
const {
|
|
26
28
|
anchor,
|
|
27
29
|
head
|
|
28
|
-
} = getMultiSelectionIfPosInside(api, handlePos);
|
|
30
|
+
} = getMultiSelectionIfPosInside(api, handlePos, tr);
|
|
29
31
|
const inSelection = anchor !== undefined && head !== undefined;
|
|
30
32
|
const from = inSelection ? Math.min(anchor, head) : handlePos;
|
|
31
33
|
const activeNode = tr.doc.nodeAt(handlePos);
|
|
@@ -114,8 +114,9 @@ export function canMoveNodeToIndex(destParent, indexIntoParent, srcNode, $destNo
|
|
|
114
114
|
}
|
|
115
115
|
return destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType);
|
|
116
116
|
}
|
|
117
|
-
export function canMoveSliceToIndex(slice, sliceFromPos,
|
|
117
|
+
export function canMoveSliceToIndex(slice, sliceFromPos, destParent, indexIntoParent, $destNodePos, destNode) {
|
|
118
118
|
let canMoveNodes = true;
|
|
119
|
+
const doc = $destNodePos.doc;
|
|
119
120
|
const nodesPos = [];
|
|
120
121
|
for (let i = 0; i < slice.content.childCount; i++) {
|
|
121
122
|
const node = slice.content.maybeChild(i);
|
|
@@ -24,7 +24,7 @@ import { key } from '../pm-plugins/main';
|
|
|
24
24
|
import { getMultiSelectAnalyticsAttributes } from '../pm-plugins/utils/analytics';
|
|
25
25
|
import { getLeftPosition, getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
|
|
26
26
|
import { getNestedNodePosition } from '../pm-plugins/utils/getNestedNodePosition';
|
|
27
|
-
import {
|
|
27
|
+
import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
|
|
28
28
|
import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, topPositionAdjustment } from './consts';
|
|
29
29
|
import { dragPreview } from './drag-preview';
|
|
30
30
|
const iconWrapperStyles = xcss({
|
|
@@ -383,7 +383,7 @@ export const DragHandle = ({
|
|
|
383
383
|
if (!isMultiSelect || typeof start !== 'number' || !selection) {
|
|
384
384
|
return;
|
|
385
385
|
}
|
|
386
|
-
setDragHandleSelected(
|
|
386
|
+
setDragHandleSelected(isHandleCorrelatedToSelection(view.state, selection, start));
|
|
387
387
|
}, [start, selection, view.state]);
|
|
388
388
|
let helpDescriptors = isTopLevelNode && fg('platform_editor_advanced_layouts_accessibility') ? [{
|
|
389
389
|
description: formatMessage(blockControlsMessages.dragToMove)
|
|
@@ -60,16 +60,22 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
|
|
|
60
60
|
return tr;
|
|
61
61
|
};
|
|
62
62
|
},
|
|
63
|
-
setMultiSelectPositions: function setMultiSelectPositions() {
|
|
63
|
+
setMultiSelectPositions: function setMultiSelectPositions(anchor, head) {
|
|
64
64
|
return function (_ref5) {
|
|
65
65
|
var _api$selection;
|
|
66
66
|
var tr = _ref5.tr;
|
|
67
67
|
var _tr$selection = tr.selection,
|
|
68
68
|
userAnchor = _tr$selection.anchor,
|
|
69
69
|
userHead = _tr$selection.head;
|
|
70
|
-
var
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
var expandedAnchor, expandedHead;
|
|
71
|
+
if (anchor !== undefined && head !== undefined) {
|
|
72
|
+
expandedAnchor = tr.doc.resolve(anchor);
|
|
73
|
+
expandedHead = tr.doc.resolve(head);
|
|
74
|
+
} else {
|
|
75
|
+
var expandedSelection = expandSelectionBounds(tr.selection.$anchor, tr.selection.$head);
|
|
76
|
+
expandedAnchor = expandedSelection.$anchor;
|
|
77
|
+
expandedHead = expandedSelection.$head;
|
|
78
|
+
}
|
|
73
79
|
api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || _api$selection.commands.setManualSelection(expandedAnchor.pos, expandedHead.pos)({
|
|
74
80
|
tr: tr
|
|
75
81
|
});
|
|
@@ -4,7 +4,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
5
|
import { expandedState } from '@atlaskit/editor-common/expand';
|
|
6
6
|
import { blockControlsMessages } from '@atlaskit/editor-common/messages';
|
|
7
|
-
import { GapCursorSelection } from '@atlaskit/editor-common/selection';
|
|
7
|
+
import { GapCursorSelection, expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
8
8
|
import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
|
|
9
9
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
10
10
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
@@ -89,7 +89,18 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
|
|
|
89
89
|
if (shouldEnableNestedDndA11y) {
|
|
90
90
|
isParentNodeOfTypeLayout = !!findParentNodeOfType([state.schema.nodes.layoutSection])(state.selection);
|
|
91
91
|
}
|
|
92
|
-
var
|
|
92
|
+
var isMultiSelectEnabled = editorExperiment('platform_editor_element_drag_and_drop_multiselect', true);
|
|
93
|
+
var expandedAnchor, expandedHead;
|
|
94
|
+
var pluginState = api === null || api === void 0 ? void 0 : api.blockControls.sharedState.currentState();
|
|
95
|
+
if (pluginState !== null && pluginState !== void 0 && pluginState.multiSelectDnD) {
|
|
96
|
+
expandedAnchor = pluginState.multiSelectDnD.anchor;
|
|
97
|
+
expandedHead = pluginState.multiSelectDnD.head;
|
|
98
|
+
} else {
|
|
99
|
+
var expandedSelection = expandSelectionBounds(selection.$anchor, selection.$head);
|
|
100
|
+
expandedAnchor = expandedSelection.$anchor.pos;
|
|
101
|
+
expandedHead = expandedSelection.$head.pos;
|
|
102
|
+
}
|
|
103
|
+
var currentNodePos = isMultiSelectEnabled ? Math.min(expandedAnchor, expandedHead) : getCurrentNodePos(state);
|
|
93
104
|
if (currentNodePos > -1) {
|
|
94
105
|
var _state$doc$nodeAt;
|
|
95
106
|
var $pos = state.doc.resolve(currentNodePos);
|
|
@@ -200,7 +211,7 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
|
|
|
200
211
|
}
|
|
201
212
|
} else {
|
|
202
213
|
var _endOfDoc = $pos.end();
|
|
203
|
-
var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
|
|
214
|
+
var nodeAfterPos = isMultiSelectEnabled ? Math.max(expandedAnchor, expandedHead) : $pos.posAtIndex($pos.index() + 1);
|
|
204
215
|
if (nodeAfterPos > _endOfDoc) {
|
|
205
216
|
return false;
|
|
206
217
|
}
|
|
@@ -222,6 +233,9 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
|
|
|
222
233
|
var _api$core7;
|
|
223
234
|
api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref4) {
|
|
224
235
|
var tr = _ref4.tr;
|
|
236
|
+
api === null || api === void 0 || api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
|
|
237
|
+
tr: tr
|
|
238
|
+
});
|
|
225
239
|
moveNode(api)(currentNodePos, moveToPos, INPUT_METHOD.SHORTCUT, formatMessage)({
|
|
226
240
|
tr: tr
|
|
227
241
|
});
|
|
@@ -229,7 +243,7 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
|
|
|
229
243
|
return tr;
|
|
230
244
|
});
|
|
231
245
|
return true;
|
|
232
|
-
} else if (nodeType) {
|
|
246
|
+
} else if (nodeType && !isMultiSelectEnabled) {
|
|
233
247
|
var _api$core8;
|
|
234
248
|
// If the node is first/last one, only select the node
|
|
235
249
|
api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref5) {
|
|
@@ -239,6 +253,17 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
|
|
|
239
253
|
return tr;
|
|
240
254
|
});
|
|
241
255
|
return true;
|
|
256
|
+
} else if (isMultiSelectEnabled) {
|
|
257
|
+
var _api$core9;
|
|
258
|
+
api === null || api === void 0 || (_api$core9 = api.core) === null || _api$core9 === void 0 || _api$core9.actions.execute(function (_ref6) {
|
|
259
|
+
var tr = _ref6.tr;
|
|
260
|
+
api.blockControls.commands.setMultiSelectPositions(expandedAnchor, expandedHead)({
|
|
261
|
+
tr: tr
|
|
262
|
+
});
|
|
263
|
+
tr.scrollIntoView();
|
|
264
|
+
return tr;
|
|
265
|
+
});
|
|
266
|
+
return true;
|
|
242
267
|
}
|
|
243
268
|
}
|
|
244
269
|
return false;
|
|
@@ -248,8 +273,9 @@ export var moveNode = function moveNode(api) {
|
|
|
248
273
|
return function (start, to) {
|
|
249
274
|
var inputMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : INPUT_METHOD.DRAG_AND_DROP;
|
|
250
275
|
var formatMessage = arguments.length > 3 ? arguments[3] : undefined;
|
|
251
|
-
return function (
|
|
252
|
-
var
|
|
276
|
+
return function (_ref7) {
|
|
277
|
+
var _api$blockControls$co;
|
|
278
|
+
var tr = _ref7.tr;
|
|
253
279
|
if (!api) {
|
|
254
280
|
return tr;
|
|
255
281
|
}
|
|
@@ -321,10 +347,14 @@ export var moveNode = function moveNode(api) {
|
|
|
321
347
|
mappedTo = tr.mapping.map(to);
|
|
322
348
|
tr.insert(mappedTo, _nodeCopy); // insert the content at the new position
|
|
323
349
|
}
|
|
324
|
-
|
|
325
|
-
tr.
|
|
350
|
+
var sliceSize = sliceTo - sliceFrom;
|
|
351
|
+
tr = inputMethod === INPUT_METHOD.DRAG_AND_DROP ? setCursorPositionAtMovedNode(tr, mappedTo) : isMultiSelect ? (_api$blockControls$co = api === null || api === void 0 ? void 0 : api.blockControls.commands.setMultiSelectPositions(mappedTo, mappedTo + sliceSize)({
|
|
352
|
+
tr: tr
|
|
353
|
+
})) !== null && _api$blockControls$co !== void 0 ? _api$blockControls$co : tr : selectNode(tr, mappedTo, handleNode.type.name);
|
|
354
|
+
var currMeta = tr.getMeta(key);
|
|
355
|
+
tr.setMeta(key, _objectSpread(_objectSpread({}, currMeta), {}, {
|
|
326
356
|
nodeMoved: true
|
|
327
|
-
});
|
|
357
|
+
}));
|
|
328
358
|
api === null || api === void 0 || api.core.actions.focus();
|
|
329
359
|
var $mappedTo = tr.doc.resolve(mappedTo);
|
|
330
360
|
var expandAncestor = findParentNodeOfTypeClosestToPos($to, [expand, nestedExpand]);
|
|
@@ -3,6 +3,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
|
|
|
3
3
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
4
|
import { createElement } from 'react';
|
|
5
5
|
import uuid from 'uuid';
|
|
6
|
+
import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
6
7
|
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
7
8
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
8
9
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
@@ -159,6 +160,15 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
|
|
|
159
160
|
prevNodeStack.push(node);
|
|
160
161
|
};
|
|
161
162
|
var isAdvancedLayoutsPreRelease2 = editorExperiment('advanced_layouts', true);
|
|
163
|
+
|
|
164
|
+
// For deciding to show drop targets or not when multiple nodes are selected
|
|
165
|
+
var selection = newState.selection;
|
|
166
|
+
var _expandSelectionBound = expandSelectionBounds(selection.$anchor, selection.$head),
|
|
167
|
+
expandedAnchor = _expandSelectionBound.$anchor,
|
|
168
|
+
expandedHead = _expandSelectionBound.$head;
|
|
169
|
+
var selectionFrom = Math.min(expandedAnchor.pos, expandedHead.pos);
|
|
170
|
+
var selectionTo = Math.max(expandedAnchor.pos, expandedHead.pos);
|
|
171
|
+
var handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom && activeNodePos <= selectionTo;
|
|
162
172
|
newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, index) {
|
|
163
173
|
var depth = 0;
|
|
164
174
|
// drop target deco at the end position
|
|
@@ -193,10 +203,6 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
|
|
|
193
203
|
|
|
194
204
|
// When multi select is on, validate all the nodes in the selection instead of just the handle node
|
|
195
205
|
if (isMultiSelect) {
|
|
196
|
-
var selection = newState.selection;
|
|
197
|
-
var selectionFrom = selection.$from.pos;
|
|
198
|
-
var selectionTo = selection.$to.pos;
|
|
199
|
-
var handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom - 1 && activeNodePos <= selectionTo;
|
|
200
206
|
var selectionSlice = newState.doc.slice(selectionFrom, selectionTo, false);
|
|
201
207
|
var selectionSliceChildCount = selectionSlice.content.childCount;
|
|
202
208
|
var canDropSingleNode = true;
|
|
@@ -204,7 +210,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
|
|
|
204
210
|
|
|
205
211
|
// when there is only one node in the slice, use the same logic as when multi select is not on
|
|
206
212
|
if (selectionSliceChildCount > 1 && handleInsideSelection) {
|
|
207
|
-
canDropMultipleNodes = canMoveSliceToIndex(selectionSlice, selectionFrom,
|
|
213
|
+
canDropMultipleNodes = canMoveSliceToIndex(selectionSlice, selectionFrom, parent, index, $pos);
|
|
208
214
|
} else {
|
|
209
215
|
canDropSingleNode = !!(activePMNode && canMoveNodeToIndex(parent, index, activePMNode, $pos, node));
|
|
210
216
|
}
|
|
@@ -182,7 +182,9 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
|
|
|
182
182
|
var resizerMeta = tr.getMeta('is-resizer-resizing');
|
|
183
183
|
isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
|
|
184
184
|
if (multiSelectDnD && flags.isMultiSelectEnabled) {
|
|
185
|
-
multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false
|
|
185
|
+
multiSelectDnD = (meta === null || meta === void 0 ? void 0 : meta.isDragging) === false ||
|
|
186
|
+
// For move node with shortcut, only reset when the selection changes
|
|
187
|
+
tr.selection.anchor !== multiSelectDnD.textAnchor || tr.selection.head !== multiSelectDnD.textHead ? undefined : multiSelectDnD;
|
|
186
188
|
}
|
|
187
189
|
var _getTrMetadata = getTrMetadata(tr),
|
|
188
190
|
from = _getTrMetadata.from,
|
|
@@ -94,7 +94,7 @@ export var setCursorPositionAtMovedNode = function setCursorPositionAtMovedNode(
|
|
|
94
94
|
* @param handlePos
|
|
95
95
|
* @returns
|
|
96
96
|
*/
|
|
97
|
-
export var
|
|
97
|
+
export var isHandleCorrelatedToSelection = function isHandleCorrelatedToSelection(state, selection, handlePos) {
|
|
98
98
|
if (selection.empty) {
|
|
99
99
|
return false;
|
|
100
100
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
|
|
1
|
+
import { key } from '../main';
|
|
2
|
+
export var getMultiSelectionIfPosInside = function getMultiSelectionIfPosInside(api, pos, tr) {
|
|
3
|
+
var _api$blockControls, _pluginState$multiSel, _tr$getMeta;
|
|
4
|
+
var pluginState = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState();
|
|
5
|
+
// With move nodes shortcut, we expand selection and move node within one transaction,
|
|
6
|
+
// Hence we also look for `multiSelectDnD` in transaction meta
|
|
7
|
+
var multiSelectDnD = (_pluginState$multiSel = pluginState === null || pluginState === void 0 ? void 0 : pluginState.multiSelectDnD) !== null && _pluginState$multiSel !== void 0 ? _pluginState$multiSel : tr === null || tr === void 0 || (_tr$getMeta = tr.getMeta(key)) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.multiSelectDnD;
|
|
5
8
|
if (multiSelectDnD && multiSelectDnD.anchor >= 0 && multiSelectDnD.head >= 0) {
|
|
6
9
|
var multiFrom = Math.min(multiSelectDnD.anchor, multiSelectDnD.head);
|
|
7
10
|
var multiTo = Math.max(multiSelectDnD.anchor, multiSelectDnD.head);
|
|
@@ -21,7 +24,7 @@ export var getMultiSelectionIfPosInside = function getMultiSelectionIfPosInside(
|
|
|
21
24
|
*/
|
|
22
25
|
export var getSelectedSlicePosition = function getSelectedSlicePosition(handlePos, tr, api) {
|
|
23
26
|
var _activeNode$nodeSize;
|
|
24
|
-
var _getMultiSelectionIfP = getMultiSelectionIfPosInside(api, handlePos),
|
|
27
|
+
var _getMultiSelectionIfP = getMultiSelectionIfPosInside(api, handlePos, tr),
|
|
25
28
|
anchor = _getMultiSelectionIfP.anchor,
|
|
26
29
|
head = _getMultiSelectionIfP.head;
|
|
27
30
|
var inSelection = anchor !== undefined && head !== undefined;
|
|
@@ -112,8 +112,9 @@ export function canMoveNodeToIndex(destParent, indexIntoParent, srcNode, $destNo
|
|
|
112
112
|
}
|
|
113
113
|
return destParent.canReplaceWith(indexIntoParent, indexIntoParent, srcNodeType);
|
|
114
114
|
}
|
|
115
|
-
export function canMoveSliceToIndex(slice, sliceFromPos,
|
|
115
|
+
export function canMoveSliceToIndex(slice, sliceFromPos, destParent, indexIntoParent, $destNodePos, destNode) {
|
|
116
116
|
var canMoveNodes = true;
|
|
117
|
+
var doc = $destNodePos.doc;
|
|
117
118
|
var nodesPos = [];
|
|
118
119
|
for (var i = 0; i < slice.content.childCount; i++) {
|
|
119
120
|
var node = slice.content.maybeChild(i);
|
|
@@ -29,7 +29,7 @@ import { key } from '../pm-plugins/main';
|
|
|
29
29
|
import { getMultiSelectAnalyticsAttributes } from '../pm-plugins/utils/analytics';
|
|
30
30
|
import { getLeftPosition, getTopPosition } from '../pm-plugins/utils/drag-handle-positions';
|
|
31
31
|
import { getNestedNodePosition } from '../pm-plugins/utils/getNestedNodePosition';
|
|
32
|
-
import {
|
|
32
|
+
import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
|
|
33
33
|
import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_WIDTH, DRAG_HANDLE_ZINDEX, dragHandleGap, topPositionAdjustment } from './consts';
|
|
34
34
|
import { dragPreview } from './drag-preview';
|
|
35
35
|
var iconWrapperStyles = xcss({
|
|
@@ -396,7 +396,7 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
396
396
|
if (!isMultiSelect || typeof start !== 'number' || !selection) {
|
|
397
397
|
return;
|
|
398
398
|
}
|
|
399
|
-
setDragHandleSelected(
|
|
399
|
+
setDragHandleSelected(isHandleCorrelatedToSelection(view.state, selection, start));
|
|
400
400
|
}, [start, selection, view.state]);
|
|
401
401
|
var helpDescriptors = isTopLevelNode && fg('platform_editor_advanced_layouts_accessibility') ? [{
|
|
402
402
|
description: formatMessage(blockControlsMessages.dragToMove)
|
|
@@ -87,7 +87,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
|
87
87
|
moveNode: MoveNode;
|
|
88
88
|
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
|
|
89
89
|
setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
|
|
90
|
-
setMultiSelectPositions: () => EditorCommand;
|
|
90
|
+
setMultiSelectPositions: (anchor?: number, head?: number) => EditorCommand;
|
|
91
91
|
};
|
|
92
92
|
}>;
|
|
93
93
|
export type BlockControlsMeta = {
|
|
@@ -14,6 +14,6 @@ export declare const setCursorPositionAtMovedNode: (tr: Transaction, start: numb
|
|
|
14
14
|
* @param handlePos
|
|
15
15
|
* @returns
|
|
16
16
|
*/
|
|
17
|
-
export declare const
|
|
17
|
+
export declare const isHandleCorrelatedToSelection: (state: EditorState, selection: Selection, handlePos: number) => boolean;
|
|
18
18
|
export declare const rootListDepth: (itemPos: ResolvedPos) => number | undefined;
|
|
19
19
|
export declare const rootTaskListDepth: (taskListPos: ResolvedPos) => number | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
|
-
import { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { type Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
3
|
import type { BlockControlsPlugin } from '../../blockControlsPluginType';
|
|
4
|
-
export declare const getMultiSelectionIfPosInside: (api: ExtractInjectionAPI<BlockControlsPlugin>, pos: number) => {
|
|
4
|
+
export declare const getMultiSelectionIfPosInside: (api: ExtractInjectionAPI<BlockControlsPlugin>, pos: number, tr?: Transaction) => {
|
|
5
5
|
anchor?: number;
|
|
6
6
|
head?: number;
|
|
7
7
|
};
|
|
@@ -17,4 +17,4 @@ export declare const transformExpandToNestedExpand: (expandNode: PMNode) => PMNo
|
|
|
17
17
|
export declare const transformSliceExpandToNestedExpand: (slice: Slice) => Slice | null;
|
|
18
18
|
export declare const memoizedTransformExpandToNestedExpand: import("memoize-one").MemoizedFn<(node: PMNode) => PMNode | null>;
|
|
19
19
|
export declare function canMoveNodeToIndex(destParent: PMNode, indexIntoParent: number, srcNode: PMNode, $destNodePos: ResolvedPos, destNode?: PMNode): boolean;
|
|
20
|
-
export declare function canMoveSliceToIndex(slice: Slice, sliceFromPos: number,
|
|
20
|
+
export declare function canMoveSliceToIndex(slice: Slice, sliceFromPos: number, destParent: PMNode, indexIntoParent: number, $destNodePos: ResolvedPos, destNode?: PMNode): boolean;
|
|
@@ -87,7 +87,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
|
|
|
87
87
|
moveNode: MoveNode;
|
|
88
88
|
showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
|
|
89
89
|
setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
|
|
90
|
-
setMultiSelectPositions: () => EditorCommand;
|
|
90
|
+
setMultiSelectPositions: (anchor?: number, head?: number) => EditorCommand;
|
|
91
91
|
};
|
|
92
92
|
}>;
|
|
93
93
|
export type BlockControlsMeta = {
|
|
@@ -14,6 +14,6 @@ export declare const setCursorPositionAtMovedNode: (tr: Transaction, start: numb
|
|
|
14
14
|
* @param handlePos
|
|
15
15
|
* @returns
|
|
16
16
|
*/
|
|
17
|
-
export declare const
|
|
17
|
+
export declare const isHandleCorrelatedToSelection: (state: EditorState, selection: Selection, handlePos: number) => boolean;
|
|
18
18
|
export declare const rootListDepth: (itemPos: ResolvedPos) => number | undefined;
|
|
19
19
|
export declare const rootTaskListDepth: (taskListPos: ResolvedPos) => number | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
|
-
import { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { type Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
3
|
import type { BlockControlsPlugin } from '../../blockControlsPluginType';
|
|
4
|
-
export declare const getMultiSelectionIfPosInside: (api: ExtractInjectionAPI<BlockControlsPlugin>, pos: number) => {
|
|
4
|
+
export declare const getMultiSelectionIfPosInside: (api: ExtractInjectionAPI<BlockControlsPlugin>, pos: number, tr?: Transaction) => {
|
|
5
5
|
anchor?: number;
|
|
6
6
|
head?: number;
|
|
7
7
|
};
|
|
@@ -17,4 +17,4 @@ export declare const transformExpandToNestedExpand: (expandNode: PMNode) => PMNo
|
|
|
17
17
|
export declare const transformSliceExpandToNestedExpand: (slice: Slice) => Slice | null;
|
|
18
18
|
export declare const memoizedTransformExpandToNestedExpand: import("memoize-one").MemoizedFn<(node: PMNode) => PMNode | null>;
|
|
19
19
|
export declare function canMoveNodeToIndex(destParent: PMNode, indexIntoParent: number, srcNode: PMNode, $destNodePos: ResolvedPos, destNode?: PMNode): boolean;
|
|
20
|
-
export declare function canMoveSliceToIndex(slice: Slice, sliceFromPos: number,
|
|
20
|
+
export declare function canMoveSliceToIndex(slice: Slice, sliceFromPos: number, destParent: PMNode, indexIntoParent: number, $destNodePos: ResolvedPos, destNode?: PMNode): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-controls",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.27.1",
|
|
4
4
|
"description": "Block controls plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@atlaskit/adf-schema": "^47.2.1",
|
|
34
|
-
"@atlaskit/editor-common": "^99.
|
|
34
|
+
"@atlaskit/editor-common": "^99.16.0",
|
|
35
35
|
"@atlaskit/editor-plugin-accessibility-utils": "^1.4.0",
|
|
36
36
|
"@atlaskit/editor-plugin-analytics": "^1.12.0",
|
|
37
37
|
"@atlaskit/editor-plugin-editor-disabled": "^1.5.0",
|