@atlaskit/editor-plugin-block-controls 2.21.5 → 2.21.7

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/blockControlsPlugin.js +0 -2
  3. package/dist/cjs/editor-commands/move-node.js +2 -5
  4. package/dist/cjs/editor-commands/move-to-layout.js +186 -60
  5. package/dist/cjs/pm-plugins/decorations-anchor.js +1 -6
  6. package/dist/cjs/pm-plugins/decorations-drag-handle.js +1 -4
  7. package/dist/cjs/pm-plugins/decorations-drop-target.js +35 -20
  8. package/dist/cjs/pm-plugins/main.js +2 -10
  9. package/dist/cjs/pm-plugins/utils/check-fragment.js +26 -0
  10. package/dist/cjs/pm-plugins/utils/drag-handle-positions.js +1 -4
  11. package/dist/cjs/pm-plugins/utils/fire-analytics.js +1 -4
  12. package/dist/cjs/pm-plugins/utils/inline-drop-target.js +1 -4
  13. package/dist/cjs/pm-plugins/utils/remove-from-source.js +15 -6
  14. package/dist/cjs/pm-plugins/utils/update-column-widths.js +1 -4
  15. package/dist/cjs/pm-plugins/utils/validation.js +28 -3
  16. package/dist/es2019/blockControlsPlugin.js +0 -2
  17. package/dist/es2019/editor-commands/move-node.js +2 -5
  18. package/dist/es2019/editor-commands/move-to-layout.js +171 -50
  19. package/dist/es2019/pm-plugins/decorations-anchor.js +1 -6
  20. package/dist/es2019/pm-plugins/decorations-drag-handle.js +1 -4
  21. package/dist/es2019/pm-plugins/decorations-drop-target.js +36 -21
  22. package/dist/es2019/pm-plugins/main.js +2 -10
  23. package/dist/es2019/pm-plugins/utils/check-fragment.js +20 -0
  24. package/dist/es2019/pm-plugins/utils/drag-handle-positions.js +1 -4
  25. package/dist/es2019/pm-plugins/utils/fire-analytics.js +1 -4
  26. package/dist/es2019/pm-plugins/utils/inline-drop-target.js +1 -4
  27. package/dist/es2019/pm-plugins/utils/remove-from-source.js +15 -6
  28. package/dist/es2019/pm-plugins/utils/update-column-widths.js +1 -4
  29. package/dist/es2019/pm-plugins/utils/validation.js +27 -3
  30. package/dist/esm/blockControlsPlugin.js +0 -2
  31. package/dist/esm/editor-commands/move-node.js +2 -5
  32. package/dist/esm/editor-commands/move-to-layout.js +187 -61
  33. package/dist/esm/pm-plugins/decorations-anchor.js +1 -6
  34. package/dist/esm/pm-plugins/decorations-drag-handle.js +1 -4
  35. package/dist/esm/pm-plugins/decorations-drop-target.js +36 -21
  36. package/dist/esm/pm-plugins/main.js +2 -10
  37. package/dist/esm/pm-plugins/utils/check-fragment.js +20 -0
  38. package/dist/esm/pm-plugins/utils/drag-handle-positions.js +1 -4
  39. package/dist/esm/pm-plugins/utils/fire-analytics.js +1 -4
  40. package/dist/esm/pm-plugins/utils/inline-drop-target.js +1 -4
  41. package/dist/esm/pm-plugins/utils/remove-from-source.js +15 -6
  42. package/dist/esm/pm-plugins/utils/update-column-widths.js +1 -4
  43. package/dist/esm/pm-plugins/utils/validation.js +27 -3
  44. package/dist/types/pm-plugins/utils/check-fragment.d.ts +9 -0
  45. package/dist/types/pm-plugins/utils/remove-from-source.d.ts +1 -1
  46. package/dist/types/pm-plugins/utils/validation.d.ts +1 -0
  47. package/dist/types-ts4.5/pm-plugins/utils/check-fragment.d.ts +9 -0
  48. package/dist/types-ts4.5/pm-plugins/utils/remove-from-source.d.ts +1 -1
  49. package/dist/types-ts4.5/pm-plugins/utils/validation.d.ts +1 -0
  50. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 2.21.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [#105486](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/105486)
8
+ [`ed00542ef3156`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/ed00542ef3156) -
9
+ Validate all the nodes in the selection instead of just the handle node
10
+
11
+ ## 2.21.6
12
+
13
+ ### Patch Changes
14
+
15
+ - [#105202](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/105202)
16
+ [`652b93ff9cff7`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/652b93ff9cff7) -
17
+ [ux] [ED-26290] Support drag and drop to create or update layout with multi select
18
+ - Updated dependencies
19
+
3
20
  ## 2.21.5
4
21
 
5
22
  ### Patch Changes
@@ -28,8 +28,6 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
28
28
  commands: {
29
29
  moveNode: (0, _moveNode.moveNode)(api),
30
30
  moveToLayout: (0, _moveToLayout.moveToLayout)(api),
31
- // Ignored via go/ees005
32
- // eslint-disable-next-line @typescript-eslint/max-params
33
31
  showDragHandleAt: function showDragHandleAt(pos, anchorName, nodeType, handleOptions) {
34
32
  return function (_ref3) {
35
33
  var tr = _ref3.tr;
@@ -160,10 +160,7 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
160
160
  var moveNode = exports.moveNode = function moveNode(api) {
161
161
  return function (start, to) {
162
162
  var inputMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _analytics.INPUT_METHOD.DRAG_AND_DROP;
163
- var formatMessage
164
- // Ignored via go/ees005
165
- // eslint-disable-next-line @typescript-eslint/max-params
166
- = arguments.length > 3 ? arguments[3] : undefined;
163
+ var formatMessage = arguments.length > 3 ? arguments[3] : undefined;
167
164
  return function (_ref4) {
168
165
  var tr = _ref4.tr;
169
166
  var isMultiSelect = (0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true, {
@@ -208,7 +205,7 @@ var moveNode = exports.moveNode = function moveNode(api) {
208
205
  if (sourceNode && isDragLayoutColumnToTopLevel($handlePos, $to)) {
209
206
  // need update after we support single column layout.
210
207
  var fragment = _model.Fragment.from(sourceNode.content);
211
- (0, _removeFromSource.removeFromSource)(tr, $handlePos);
208
+ (0, _removeFromSource.removeFromSource)(tr, $handlePos, $handlePos.pos + sourceNode.nodeSize);
212
209
  var _mappedTo = tr.mapping.map(to);
213
210
  tr.insert(_mappedTo, fragment).setSelection(_state.Selection.near(tr.doc.resolve(_mappedTo))).scrollIntoView();
214
211
  return tr;
@@ -8,6 +8,8 @@ var _analytics = require("@atlaskit/editor-common/analytics");
8
8
  var _model = require("@atlaskit/editor-prosemirror/model");
9
9
  var _state = require("@atlaskit/editor-prosemirror/state");
10
10
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
12
+ var _checkFragment = require("../pm-plugins/utils/check-fragment");
11
13
  var _consts = require("../pm-plugins/utils/consts");
12
14
  var _fireAnalytics = require("../pm-plugins/utils/fire-analytics");
13
15
  var _removeFromSource = require("../pm-plugins/utils/remove-from-source");
@@ -38,17 +40,27 @@ var createNewLayout = function createNewLayout(schema, layoutContents) {
38
40
  }
39
41
  return null;
40
42
  };
41
- var moveToExistingLayout = function moveToExistingLayout(toLayout, toLayoutPos, sourceNode, from, to, tr, $originalFrom, $originalTo, api
42
- // Ignored via go/ees005
43
- // eslint-disable-next-line @typescript-eslint/max-params
44
- ) {
43
+ var moveToExistingLayout = function moveToExistingLayout(toLayout, toLayoutPos, sourceContent, from, to, tr, $originalFrom, $originalTo, api) {
45
44
  var isSameLayout = (0, _validation.isInSameLayout)($originalFrom, $originalTo);
45
+ var sourceContentEndPos = -1;
46
+ if ((0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true)) {
47
+ if (sourceContent instanceof _model.Fragment) {
48
+ sourceContentEndPos = from + sourceContent.size;
49
+ }
50
+ } else {
51
+ if (sourceContent instanceof _model.Node) {
52
+ sourceContentEndPos = from + sourceContent.nodeSize;
53
+ }
54
+ }
55
+ if (sourceContentEndPos === -1) {
56
+ return tr;
57
+ }
46
58
  if (isSameLayout) {
47
59
  var _$originalFrom$nodeAf;
48
60
  // reorder columns
49
- tr.delete(from, from + sourceNode.nodeSize);
61
+ tr.delete(from, sourceContentEndPos);
50
62
  var mappedTo = tr.mapping.map(to);
51
- tr.insert(mappedTo, sourceNode);
63
+ tr.insert(mappedTo, sourceContent);
52
64
  if (!(0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_post_fix_patch_1')) {
53
65
  tr.setSelection(new _state.NodeSelection(tr.doc.resolve(mappedTo))).scrollIntoView();
54
66
  }
@@ -56,12 +68,12 @@ var moveToExistingLayout = function moveToExistingLayout(toLayout, toLayoutPos,
56
68
  } else if (toLayout.childCount < (0, _consts.maxLayoutColumnSupported)()) {
57
69
  var _$originalFrom$nodeAf2;
58
70
  if ((0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_post_fix_patch_1')) {
59
- (0, _removeFromSource.removeFromSource)(tr, tr.doc.resolve(from));
60
- insertToDestinationNoWidthUpdate(tr, tr.mapping.map(to), sourceNode);
71
+ (0, _removeFromSource.removeFromSource)(tr, tr.doc.resolve(from), sourceContentEndPos);
72
+ insertToDestinationNoWidthUpdate(tr, tr.mapping.map(to), sourceContent);
61
73
  } else {
62
- insertToDestination(tr, to, sourceNode, toLayout, toLayoutPos);
74
+ insertToDestination(tr, to, sourceContent, toLayout, toLayoutPos);
63
75
  var mappedFrom = tr.mapping.map(from);
64
- (0, _removeFromSource.removeFromSource)(tr, tr.doc.resolve(mappedFrom));
76
+ (0, _removeFromSource.removeFromSource)(tr, tr.doc.resolve(mappedFrom), tr.mapping.map(sourceContentEndPos));
65
77
  }
66
78
  (0, _fireAnalytics.attachMoveNodeAnalytics)(tr, _analytics.INPUT_METHOD.DRAG_AND_DROP, $originalFrom.depth, ((_$originalFrom$nodeAf2 = $originalFrom.nodeAfter) === null || _$originalFrom$nodeAf2 === void 0 ? void 0 : _$originalFrom$nodeAf2.type.name) || '', 1, 'layoutSection', false, api);
67
79
  }
@@ -76,27 +88,54 @@ var moveToExistingLayout = function moveToExistingLayout(toLayout, toLayoutPos,
76
88
  * @param sourceNode
77
89
  * @returns
78
90
  */
79
- var insertToDestinationNoWidthUpdate = function insertToDestinationNoWidthUpdate(tr, to, sourceNode) {
91
+ var insertToDestinationNoWidthUpdate = function insertToDestinationNoWidthUpdate(tr, to, sourceContent) {
80
92
  var _ref2 = tr.doc.type.schema.nodes || {},
81
93
  layoutColumn = _ref2.layoutColumn;
82
- var content = layoutColumn.createChecked({
83
- width: 0
84
- }, sourceNode.type.name === 'layoutColumn' ? sourceNode.content : sourceNode);
85
- tr.insert(to, content);
94
+ var content = null;
95
+ if ((0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true)) {
96
+ if (sourceContent instanceof _model.Fragment) {
97
+ var _sourceFragment$first;
98
+ var sourceFragment = sourceContent;
99
+ content = layoutColumn.createChecked({
100
+ width: 0
101
+ }, (0, _checkFragment.isFragmentOfType)(sourceFragment, 'layoutColumn') ? (_sourceFragment$first = sourceFragment.firstChild) === null || _sourceFragment$first === void 0 ? void 0 : _sourceFragment$first.content : sourceFragment);
102
+ }
103
+ } else {
104
+ if (sourceContent instanceof _model.Node) {
105
+ var sourceNode = sourceContent;
106
+ content = layoutColumn.createChecked({
107
+ width: 0
108
+ }, sourceNode.type.name === 'layoutColumn' ? sourceNode.content : sourceNode);
109
+ }
110
+ }
111
+ if (content) {
112
+ tr.insert(to, content);
113
+ }
86
114
  return tr;
87
115
  };
88
- var insertToDestination = function insertToDestination(tr, to, sourceNode, toLayout, toLayoutPos
89
- // Ignored via go/ees005
90
- // eslint-disable-next-line @typescript-eslint/max-params
91
- ) {
116
+ var insertToDestination = function insertToDestination(tr, to, sourceContent, toLayout, toLayoutPos) {
92
117
  var _ref3 = (0, _updateColumnWidths.updateColumnWidths)(tr, toLayout, toLayoutPos, toLayout.childCount + 1) || {},
93
118
  newColumnWidth = _ref3.newColumnWidth;
94
119
  var _ref4 = tr.doc.type.schema.nodes || {},
95
120
  layoutColumn = _ref4.layoutColumn;
96
- var content = layoutColumn.createChecked({
97
- width: newColumnWidth
98
- }, sourceNode.type.name === 'layoutColumn' ? sourceNode.content : sourceNode);
99
- tr.insert(to, content);
121
+ var content = null;
122
+ if ((0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true)) {
123
+ if (sourceContent instanceof _model.Fragment) {
124
+ var _sourceContent$firstC;
125
+ content = layoutColumn.createChecked({
126
+ width: newColumnWidth
127
+ }, (0, _checkFragment.isFragmentOfType)(sourceContent, 'layoutColumn') ? (_sourceContent$firstC = sourceContent.firstChild) === null || _sourceContent$firstC === void 0 ? void 0 : _sourceContent$firstC.content : sourceContent);
128
+ }
129
+ } else {
130
+ if (sourceContent instanceof _model.Node) {
131
+ content = layoutColumn.createChecked({
132
+ width: newColumnWidth
133
+ }, sourceContent.type.name === 'layoutColumn' ? sourceContent.content : sourceContent);
134
+ }
135
+ }
136
+ if (content) {
137
+ tr.insert(to, content);
138
+ }
100
139
  if (!(0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_post_fix_patch_1')) {
101
140
  tr.setSelection(new _state.NodeSelection(tr.doc.resolve(to))).scrollIntoView();
102
141
  }
@@ -127,67 +166,148 @@ var canMoveToLayout = function canMoveToLayout(from, to, tr) {
127
166
  return;
128
167
  }
129
168
  var $from = tr.doc.resolve(from);
169
+ var isMultiSelect = (0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true, {
170
+ exposure: true
171
+ });
130
172
 
131
173
  // invalid from position or dragging a layout
132
174
  if (!$from.nodeAfter || $from.nodeAfter.type === layoutSection) {
133
175
  return;
134
176
  }
177
+ var sourceContent = $from.nodeAfter;
178
+ var sourceFrom = from;
179
+ var sourceTo = from + sourceContent.nodeSize;
180
+ if (isMultiSelect) {
181
+ var _tr$selection$$from$n;
182
+ // Selection often starts from the content of the node (e.g. to show text selection properly),
183
+ // so we need to trace back to the start of the node instead
184
+ var contentStartPos = tr.selection.$from.nodeAfter && ((_tr$selection$$from$n = tr.selection.$from.nodeAfter) === null || _tr$selection$$from$n === void 0 ? void 0 : _tr$selection$$from$n.type.name) !== 'text' ? tr.selection.$from.pos : tr.selection.$from.before();
185
+
186
+ // If the handle position sits within the Editor selection, we will move all nodes that sit in that selection
187
+ // handle position is the same as `from` position
188
+ var useSelection = from >= contentStartPos && from <= tr.selection.to;
189
+ if (useSelection) {
190
+ sourceFrom = contentStartPos;
191
+ sourceTo = tr.selection.to;
192
+ sourceContent = tr.doc.slice(sourceFrom, sourceTo).content;
193
+
194
+ // TODO: this might become expensive for large content, consider removing it if check has been done beforehand
195
+ if ((0, _checkFragment.containsNodeOfType)(sourceContent, 'layoutSection')) {
196
+ return;
197
+ }
198
+ } else {
199
+ sourceContent = _model.Fragment.from($from.nodeAfter);
200
+ }
201
+ }
135
202
  var toNode = $to.nodeAfter;
136
- var fromNode = $from.nodeAfter;
137
203
  return {
138
204
  toNode: toNode,
139
- fromNode: fromNode,
140
- $from: $from,
141
- $to: $to
205
+ $to: $to,
206
+ sourceContent: sourceContent,
207
+ $sourceFrom: tr.doc.resolve(sourceFrom),
208
+ sourceTo: sourceTo
142
209
  };
143
210
  };
211
+ var removeBreakoutMarks = function removeBreakoutMarks(tr, $from, to) {
212
+ var fromContentWithoutBreakout = $from.nodeAfter;
213
+ var _ref6 = tr.doc.type.schema.marks || {},
214
+ breakout = _ref6.breakout;
215
+ if ((0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true)) {
216
+ tr.doc.nodesBetween($from.pos, to, function (node, pos, parent) {
217
+ // breakout doesn't exist on nested nodes
218
+ if ((parent === null || parent === void 0 ? void 0 : parent.type.name) === 'doc' && node.marks.some(function (m) {
219
+ return m.type === breakout;
220
+ })) {
221
+ tr.removeNodeMark(pos, breakout);
222
+ }
223
+
224
+ // descending is not needed as breakout doesn't exist on nested nodes
225
+ return false;
226
+ });
227
+ // resolve again the source content after node updated (remove breakout marks)
228
+ fromContentWithoutBreakout = tr.doc.slice($from.pos, to).content;
229
+ } else {
230
+ if (breakout && $from.nodeAfter && $from.nodeAfter.marks.some(function (m) {
231
+ return m.type === breakout;
232
+ })) {
233
+ tr.removeNodeMark($from.pos, breakout);
234
+ // resolve again the source node after node updated (remove breakout marks)
235
+ fromContentWithoutBreakout = tr.doc.resolve($from.pos).nodeAfter;
236
+ }
237
+ }
238
+ return fromContentWithoutBreakout;
239
+ };
240
+ var getBreakoutMode = function getBreakoutMode(content, breakout) {
241
+ if ((0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true)) {
242
+ if (content instanceof _model.Node) {
243
+ var _content$marks$find;
244
+ return (_content$marks$find = content.marks.find(function (m) {
245
+ return m.type === breakout;
246
+ })) === null || _content$marks$find === void 0 ? void 0 : _content$marks$find.attrs;
247
+ } else if (content instanceof _model.Fragment) {
248
+ // Find the first breakout mode in the fragment
249
+ var firstBreakoutMode;
250
+ for (var i = 0; i < content.childCount; i++) {
251
+ var child = content.child(i);
252
+ var breakoutMark = child.marks.find(function (m) {
253
+ return m.type === breakout;
254
+ });
255
+ if (breakoutMark) {
256
+ firstBreakoutMode = breakoutMark.attrs.mode;
257
+ break;
258
+ }
259
+ }
260
+ return firstBreakoutMode;
261
+ }
262
+ } else {
263
+ // Without multi-select support, we can assume source content is of type PMNode
264
+ if (content instanceof _model.Node) {
265
+ var _content$marks$find2;
266
+ return (_content$marks$find2 = content.marks.find(function (m) {
267
+ return m.type === breakout;
268
+ })) === null || _content$marks$find2 === void 0 ? void 0 : _content$marks$find2.attrs.mode;
269
+ }
270
+ }
271
+ };
272
+
273
+ // TODO: As part of platform_editor_element_drag_and_drop_multiselect clean up,
274
+ // source content variable that has type of `PMNode | Fragment` should be updated to `Fragment` only
144
275
  var moveToLayout = exports.moveToLayout = function moveToLayout(api) {
145
276
  return function (from, to, options) {
146
- return function (_ref6) {
147
- var tr = _ref6.tr;
277
+ return function (_ref7) {
278
+ var tr = _ref7.tr;
148
279
  var canMove = canMoveToLayout(from, to, tr);
149
280
  if (!canMove) {
150
281
  return tr;
151
282
  }
152
283
  var toNode = canMove.toNode,
153
- fromNode = canMove.fromNode,
154
- $from = canMove.$from,
155
- $to = canMove.$to;
156
- var _ref7 = tr.doc.type.schema.nodes || {},
157
- layoutSection = _ref7.layoutSection,
158
- layoutColumn = _ref7.layoutColumn;
159
- var _ref8 = tr.doc.type.schema.marks || {},
160
- breakout = _ref8.breakout;
161
- var fromNodeWithoutBreakout = fromNode;
162
- var getBreakoutMode = function getBreakoutMode(node) {
163
- var _node$marks$find;
164
- return (_node$marks$find = node.marks.find(function (m) {
165
- return m.type === breakout;
166
- })) === null || _node$marks$find === void 0 ? void 0 : _node$marks$find.attrs.mode;
167
- };
284
+ $to = canMove.$to,
285
+ sourceContent = canMove.sourceContent,
286
+ $sourceFrom = canMove.$sourceFrom,
287
+ sourceTo = canMove.sourceTo;
288
+ var _ref8 = tr.doc.type.schema.nodes || {},
289
+ layoutSection = _ref8.layoutSection,
290
+ layoutColumn = _ref8.layoutColumn;
291
+ var _ref9 = tr.doc.type.schema.marks || {},
292
+ breakout = _ref9.breakout;
293
+
168
294
  // get breakout mode from destination node,
169
295
  // if not found, get from source node,
170
- var breakoutMode = getBreakoutMode(toNode) || getBreakoutMode(fromNode);
296
+ var breakoutMode = getBreakoutMode(toNode, breakout) || getBreakoutMode(sourceContent, breakout);
171
297
 
172
- // remove breakout from node;
173
- if (breakout && $from.nodeAfter && $from.nodeAfter.marks.some(function (m) {
174
- return m.type === breakout;
175
- })) {
176
- tr.removeNodeMark(from, breakout);
177
- // resolve again the source node after node updated (remove breakout marks)
178
- fromNodeWithoutBreakout = tr.doc.resolve(from).nodeAfter;
179
- }
180
- if (!fromNodeWithoutBreakout) {
298
+ // remove breakout from source content
299
+ var fromContentWithoutBreakout = removeBreakoutMarks(tr, $sourceFrom, sourceTo);
300
+ if (!fromContentWithoutBreakout) {
181
301
  return tr;
182
302
  }
183
303
  if (toNode.type === layoutSection) {
184
304
  var toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize - 1 : to + 1;
185
- return moveToExistingLayout(toNode, to, fromNodeWithoutBreakout, from, toPos, tr, $from, $to, api);
305
+ return moveToExistingLayout(toNode, to, fromContentWithoutBreakout, $sourceFrom.pos, toPos, tr, $sourceFrom, $to, api);
186
306
  } else if (toNode.type === layoutColumn) {
187
307
  var toLayout = $to.parent;
188
308
  var toLayoutPos = to - $to.parentOffset - 1;
189
309
  var _toPos = options !== null && options !== void 0 && options.moveToEnd ? to + toNode.nodeSize : to;
190
- return moveToExistingLayout(toLayout, toLayoutPos, fromNodeWithoutBreakout, from, _toPos, tr, $from, $to, api);
310
+ return moveToExistingLayout(toLayout, toLayoutPos, fromContentWithoutBreakout, $sourceFrom.pos, _toPos, tr, $sourceFrom, $to, api);
191
311
  } else {
192
312
  var toNodeWithoutBreakout = toNode;
193
313
 
@@ -199,13 +319,19 @@ var moveToLayout = exports.moveToLayout = function moveToLayout(api) {
199
319
  // resolve again the source node after node updated (remove breakout marks)
200
320
  toNodeWithoutBreakout = tr.doc.resolve(to).nodeAfter || toNode;
201
321
  }
202
- if (fromNodeWithoutBreakout.type.name === 'layoutColumn') {
203
- fromNodeWithoutBreakout = fromNodeWithoutBreakout.content;
322
+ if ((0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true)) {
323
+ if ((0, _checkFragment.isFragmentOfType)(fromContentWithoutBreakout, 'layoutColumn') && fromContentWithoutBreakout.firstChild) {
324
+ fromContentWithoutBreakout = fromContentWithoutBreakout.firstChild.content;
325
+ }
326
+ } else {
327
+ if (fromContentWithoutBreakout instanceof _model.Node && fromContentWithoutBreakout.type.name === 'layoutColumn') {
328
+ fromContentWithoutBreakout = fromContentWithoutBreakout.content;
329
+ }
204
330
  }
205
- var layoutContents = options !== null && options !== void 0 && options.moveToEnd ? [toNodeWithoutBreakout, fromNodeWithoutBreakout] : [fromNodeWithoutBreakout, toNodeWithoutBreakout];
331
+ var layoutContents = options !== null && options !== void 0 && options.moveToEnd ? [toNodeWithoutBreakout, fromContentWithoutBreakout] : [fromContentWithoutBreakout, toNodeWithoutBreakout];
206
332
  var newLayout = createNewLayout(tr.doc.type.schema, layoutContents);
207
333
  if (newLayout) {
208
- tr = (0, _removeFromSource.removeFromSource)(tr, $from);
334
+ tr = (0, _removeFromSource.removeFromSource)(tr, $sourceFrom, sourceTo);
209
335
  var mappedTo = tr.mapping.map(to);
210
336
  tr.delete(mappedTo, mappedTo + toNodeWithoutBreakout.nodeSize).insert(mappedTo, newLayout);
211
337
  if (!(0, _platformFeatureFlags.fg)('platform_editor_advanced_layouts_post_fix_patch_1')) {
@@ -27,10 +27,7 @@ var shouldDescendIntoNode = exports.shouldDescendIntoNode = function shouldDesce
27
27
  }
28
28
  return !IGNORE_NODE_DESCENDANTS.includes(node.type.name);
29
29
  };
30
- var shouldIgnoreNode = function shouldIgnoreNode(node, ignore_nodes, depth, parent
31
- // Ignored via go/ees005
32
- // eslint-disable-next-line @typescript-eslint/max-params
33
- ) {
30
+ var shouldIgnoreNode = function shouldIgnoreNode(node, ignore_nodes, depth, parent) {
34
31
  var isEmbedCard = node.type.name === 'embedCard';
35
32
  var isMediaSingle = node.type.name === 'mediaSingle';
36
33
  var isFirstTableRow = (parent === null || parent === void 0 ? void 0 : parent.type.name) === 'table' && depth === 1 && node === parent.firstChild && 'tableRow' === node.type.name && (0, _experiments.editorExperiment)('advanced_layouts', true);
@@ -74,8 +71,6 @@ var nodeDecorations = exports.nodeDecorations = function nodeDecorations(newStat
74
71
  var docFrom = from === undefined || from < 0 ? 0 : from;
75
72
  var docTo = to === undefined || to > newState.doc.nodeSize - 2 ? newState.doc.nodeSize - 2 : to;
76
73
  var ignore_nodes = (0, _experiments.editorExperiment)('advanced_layouts', true) ? IGNORE_NODES_NEXT : IGNORE_NODES;
77
- // Ignored via go/ees005
78
- // eslint-disable-next-line @typescript-eslint/max-params
79
74
  newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, index) {
80
75
  var depth = 0;
81
76
  var anchorName;
@@ -29,10 +29,7 @@ var findHandleDec = exports.findHandleDec = function findHandleDec(decorations,
29
29
  return spec.type === _decorationsCommon.TYPE_HANDLE_DEC;
30
30
  });
31
31
  };
32
- var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDecoration(api, formatMessage, pos, anchorName, nodeType, nodeViewPortalProviderAPI, handleOptions
33
- // Ignored via go/ees005
34
- // eslint-disable-next-line @typescript-eslint/max-params
35
- ) {
32
+ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDecoration(api, formatMessage, pos, anchorName, nodeType, nodeViewPortalProviderAPI, handleOptions) {
36
33
  (0, _decorationsCommon.unmountDecorations)(nodeViewPortalProviderAPI, 'data-blocks-drag-handle-container', 'data-blocks-drag-handle-key');
37
34
  var unbind;
38
35
  var key = (0, _uuid.default)();
@@ -83,10 +83,7 @@ var findDropTargetDecs = exports.findDropTargetDecs = function findDropTargetDec
83
83
  return spec.type === _decorationsCommon.TYPE_DROP_TARGET_DEC;
84
84
  });
85
85
  };
86
- var createDropTargetDecoration = exports.createDropTargetDecoration = function createDropTargetDecoration(pos, props, nodeViewPortalProviderAPI, side, anchorRectCache, isSameLayout
87
- // Ignored via go/ees005
88
- // eslint-disable-next-line @typescript-eslint/max-params
89
- ) {
86
+ var createDropTargetDecoration = exports.createDropTargetDecoration = function createDropTargetDecoration(pos, props, nodeViewPortalProviderAPI, side, anchorRectCache, isSameLayout) {
90
87
  var key = (0, _uuid.default)();
91
88
  return _view.Decoration.widget(pos, function (_, getPosUnsafe) {
92
89
  var getPos = function getPos() {
@@ -127,10 +124,7 @@ var createDropTargetDecoration = exports.createDropTargetDecoration = function c
127
124
  side: side
128
125
  });
129
126
  };
130
- var createLayoutDropTargetDecoration = exports.createLayoutDropTargetDecoration = function createLayoutDropTargetDecoration(pos, props, nodeViewPortalProviderAPI, anchorRectCache
131
- // Ignored via go/ees005
132
- // eslint-disable-next-line @typescript-eslint/max-params
133
- ) {
127
+ var createLayoutDropTargetDecoration = exports.createLayoutDropTargetDecoration = function createLayoutDropTargetDecoration(pos, props, nodeViewPortalProviderAPI, anchorRectCache) {
134
128
  var key = (0, _uuid.default)();
135
129
  return _view.Decoration.widget(pos, function (_, getPosUnsafe) {
136
130
  var getPos = function getPos() {
@@ -162,10 +156,7 @@ var createLayoutDropTargetDecoration = exports.createLayoutDropTargetDecoration
162
156
  type: _decorationsCommon.TYPE_DROP_TARGET_DEC
163
157
  });
164
158
  };
165
- var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetDecorations(newState, api, formatMessage, nodeViewPortalProviderAPI, activeNode, anchorRectCache, from, to
166
- // Ignored via go/ees005
167
- // eslint-disable-next-line @typescript-eslint/max-params
168
- ) {
159
+ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetDecorations(newState, api, formatMessage, nodeViewPortalProviderAPI, activeNode, anchorRectCache, from, to) {
169
160
  (0, _decorationsCommon.unmountDecorations)(nodeViewPortalProviderAPI, 'data-blocks-drop-target-container', 'data-blocks-drop-target-key');
170
161
  var decs = [];
171
162
  var POS_END_OF_DOC = newState.doc.nodeSize - 2;
@@ -174,6 +165,9 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
174
165
  var activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
175
166
  var $activeNodePos = typeof activeNodePos === 'number' && newState.doc.resolve(activeNodePos);
176
167
  var activePMNode = $activeNodePos && $activeNodePos.nodeAfter;
168
+ var isMultiSelect = (0, _experiments.editorExperiment)('platform_editor_element_drag_and_drop_multiselect', true, {
169
+ exposure: true
170
+ });
177
171
  anchorRectCache === null || anchorRectCache === void 0 || anchorRectCache.clear();
178
172
  var prevNodeStack = [];
179
173
  var popNodeStack = function popNodeStack(depth) {
@@ -189,9 +183,6 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
189
183
  prevNodeStack.push(node);
190
184
  };
191
185
  var isAdvancedLayoutsPreRelease2 = (0, _experiments.editorExperiment)('advanced_layouts', true);
192
-
193
- // Ignored via go/ees005
194
- // eslint-disable-next-line @typescript-eslint/max-params
195
186
  newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, index) {
196
187
  var depth = 0;
197
188
  // drop target deco at the end position
@@ -223,12 +214,36 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
223
214
  pushNodeStack(node, depth);
224
215
  return shouldDescend(node); //skip over, don't consider it a valid depth
225
216
  }
226
- var canDrop = activePMNode && (0, _validation.canMoveNodeToIndex)(parent, index, activePMNode, $pos, node);
227
217
 
228
- //NOTE: This will block drop targets showing for nodes that are valid after transformation (i.e. expand -> nestedExpand)
229
- if (!canDrop) {
230
- pushNodeStack(node, depth);
231
- return false; //not valid pos, so nested not valid either
218
+ // When multi select is on, validate all the nodes in the selection instead of just the handle node
219
+ if (isMultiSelect) {
220
+ var selection = newState.selection;
221
+ var selectionFrom = selection.$from.pos;
222
+ var selectionTo = selection.$to.pos;
223
+ var handleInsideSelection = activeNodePos !== undefined && activeNodePos >= selectionFrom - 1 && activeNodePos <= selectionTo;
224
+ var selectionSlice = newState.doc.slice(selectionFrom, selectionTo, false);
225
+ var selectionSliceChildCount = selectionSlice.content.childCount;
226
+ var canDropSingleNode = true;
227
+ var canDropMultipleNodes = true;
228
+
229
+ // when there is only one node in the slice, use the same logic as when multi select is not on
230
+ if (selectionSliceChildCount > 1 && handleInsideSelection) {
231
+ canDropMultipleNodes = (0, _validation.canMoveSliceToIndex)(selectionSlice, selectionFrom, newState.doc, parent, index, $pos);
232
+ } else {
233
+ canDropSingleNode = !!(activePMNode && (0, _validation.canMoveNodeToIndex)(parent, index, activePMNode, $pos, node));
234
+ }
235
+ if (!canDropMultipleNodes || !canDropSingleNode) {
236
+ pushNodeStack(node, depth);
237
+ return false; //not valid pos, so nested not valid either
238
+ }
239
+ } else {
240
+ var canDrop = activePMNode && (0, _validation.canMoveNodeToIndex)(parent, index, activePMNode, $pos, node);
241
+
242
+ //NOTE: This will block drop targets showing for nodes that are valid after transformation (i.e. expand -> nestedExpand)
243
+ if (!canDrop) {
244
+ pushNodeStack(node, depth);
245
+ return false; //not valid pos, so nested not valid either
246
+ }
232
247
  }
233
248
  if (parent.lastChild === node && !(0, _utils.isEmptyParagraph)(node) && PARENT_WITH_END_DROP_TARGET.includes(parent.type.name)) {
234
249
  endPos = pos + node.nodeSize;
@@ -117,10 +117,7 @@ var initialState = {
117
117
  isDocSizeLimitEnabled: null,
118
118
  isPMDragging: false
119
119
  };
120
- var newApply = exports.newApply = function newApply(api, formatMessage, tr, currentState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache
121
- // Ignored via go/ees005
122
- // eslint-disable-next-line @typescript-eslint/max-params
123
- ) {
120
+ var newApply = exports.newApply = function newApply(api, formatMessage, tr, currentState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache) {
124
121
  var _meta$activeNode, _activeNode, _activeNode2, _meta$activeNode$hand, _meta$isDragging, _meta$isDragging2, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
125
122
  var activeNode = currentState.activeNode,
126
123
  decorations = currentState.decorations,
@@ -251,10 +248,7 @@ var newApply = exports.newApply = function newApply(api, formatMessage, tr, curr
251
248
  isPMDragging: (_meta$isPMDragging = meta === null || meta === void 0 ? void 0 : meta.isPMDragging) !== null && _meta$isPMDragging !== void 0 ? _meta$isPMDragging : isPMDragging
252
249
  };
253
250
  };
254
- var oldApply = exports.oldApply = function oldApply(api, formatMessage, tr, currentState, oldState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache
255
- // Ignored via go/ees005
256
- // eslint-disable-next-line @typescript-eslint/max-params
257
- ) {
251
+ var oldApply = exports.oldApply = function oldApply(api, formatMessage, tr, currentState, oldState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache) {
258
252
  var _meta$activeNode2, _meta$activeNode$hand2, _meta$activeNode8, _meta$isDragging4, _meta$editorHeight2, _meta$editorWidthLeft2, _meta$editorWidthRigh2, _meta$isPMDragging2;
259
253
  var isNestedEnabled = flags.isNestedEnabled;
260
254
  var activeNode = currentState.activeNode,
@@ -438,8 +432,6 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl, no
438
432
  init: function init() {
439
433
  return initialState;
440
434
  },
441
- // Ignored via go/ees005
442
- // eslint-disable-next-line @typescript-eslint/max-params
443
435
  apply: function apply(tr, currentState, oldState, newState) {
444
436
  if (isNestedEnabled) {
445
437
  return newApply(api, formatMessage, tr, currentState, newState, flags, nodeViewPortalProviderAPI, anchorRectCache);
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isFragmentOfType = exports.containsNodeOfType = void 0;
7
+ /**
8
+ * Check if the fragment has only one node of the specified type
9
+ */
10
+ var isFragmentOfType = exports.isFragmentOfType = function isFragmentOfType(fragment, type) {
11
+ var _fragment$firstChild;
12
+ return fragment.childCount === 1 && ((_fragment$firstChild = fragment.firstChild) === null || _fragment$firstChild === void 0 ? void 0 : _fragment$firstChild.type.name) === type;
13
+ };
14
+
15
+ /**
16
+ * Check if the fragment contains at least a node of the specified type
17
+ */
18
+ var containsNodeOfType = exports.containsNodeOfType = function containsNodeOfType(fragment, type) {
19
+ for (var i = 0; i < fragment.childCount; i++) {
20
+ var child = fragment.child(i);
21
+ if (child.type.name === type) {
22
+ return true;
23
+ }
24
+ }
25
+ return false;
26
+ };
@@ -40,10 +40,7 @@ var getTopPosition = exports.getTopPosition = function getTopPosition(dom, type)
40
40
  return "".concat(dom.offsetTop, "px");
41
41
  }
42
42
  };
43
- var getLeftPosition = exports.getLeftPosition = function getLeftPosition(dom, type, innerContainer, macroInteractionUpdates, parentType
44
- // Ignored via go/ees005
45
- // eslint-disable-next-line @typescript-eslint/max-params
46
- ) {
43
+ var getLeftPosition = exports.getLeftPosition = function getLeftPosition(dom, type, innerContainer, macroInteractionUpdates, parentType) {
47
44
  if (!dom) {
48
45
  return 'auto';
49
46
  }
@@ -5,10 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.fireInsertLayoutAnalytics = exports.attachMoveNodeAnalytics = void 0;
7
7
  var _analytics = require("@atlaskit/editor-common/analytics");
8
- var attachMoveNodeAnalytics = exports.attachMoveNodeAnalytics = function attachMoveNodeAnalytics(tr, inputMethod, fromDepth, fromNodeType, toDepth, toNodeType, isSameParent, api
9
- // Ignored via go/ees005
10
- // eslint-disable-next-line @typescript-eslint/max-params
11
- ) {
8
+ var attachMoveNodeAnalytics = exports.attachMoveNodeAnalytics = function attachMoveNodeAnalytics(tr, inputMethod, fromDepth, fromNodeType, toDepth, toNodeType, isSameParent, api) {
12
9
  var _api$analytics;
13
10
  return api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 ? void 0 : _api$analytics.attachAnalyticsEvent({
14
11
  eventType: _analytics.EVENT_TYPE.TRACK,
@@ -10,10 +10,7 @@ var _checkMediaLayout = require("./check-media-layout");
10
10
  var _consts = require("./consts");
11
11
  var shouldAllowInlineDropTarget = exports.shouldAllowInlineDropTarget = function shouldAllowInlineDropTarget(isNested, node) {
12
12
  var isSameLayout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
13
- var activeNode
14
- // Ignored via go/ees005
15
- // eslint-disable-next-line @typescript-eslint/max-params
16
- = arguments.length > 3 ? arguments[3] : undefined;
13
+ var activeNode = arguments.length > 3 ? arguments[3] : undefined;
17
14
  if ((0, _experiments.editorExperiment)('advanced_layouts', false) || isNested) {
18
15
  return false;
19
16
  }