@atlaskit/editor-plugin-block-controls 1.4.33 → 1.4.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 1.4.35
4
+
5
+ ### Patch Changes
6
+
7
+ - [#115170](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/115170)
8
+ [`d3d39a486f0d9`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/d3d39a486f0d9) -
9
+ Fix drag handle position when deleting a paragraph
10
+ - [#115170](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/115170)
11
+ [`108a85e557e41`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/108a85e557e41) -
12
+ Hide drag handle on empty paragraph
13
+
14
+ ## 1.4.34
15
+
16
+ ### Patch Changes
17
+
18
+ - [#115110](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/115110)
19
+ [`cc8cc2bbe88f8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/cc8cc2bbe88f8) -
20
+ Fix a regression where drag and drop a node at itself duplicates the node
21
+ - [#114841](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/114841)
22
+ [`2ea1a74c41971`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2ea1a74c41971) -
23
+ Fix drag handle position when change from paragraph to blockQuote
24
+ - [#115110](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/115110)
25
+ [`bfa2f902f0cb3`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/bfa2f902f0cb3) -
26
+ change doc size limit to child count
27
+
3
28
  ## 1.4.33
4
29
 
5
30
  ### Patch Changes
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.nodeDecorations = exports.mouseMoveWrapperDecorations = exports.dropTargetDecorations = exports.dragHandleDecoration = void 0;
7
+ exports.nodeDecorations = exports.mouseMoveWrapperDecorations = exports.emptyParagraphNodeDecorations = exports.dropTargetDecorations = exports.dragHandleDecoration = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = require("react");
10
10
  var _reactDom = _interopRequireDefault(require("react-dom"));
@@ -69,10 +69,19 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
69
69
  decorationState: decorationState
70
70
  };
71
71
  };
72
+ var emptyParagraphNodeDecorations = exports.emptyParagraphNodeDecorations = function emptyParagraphNodeDecorations() {
73
+ var anchorName = "--node-anchor-paragraph-0";
74
+ var style = "anchor-name: ".concat(anchorName, "; margin-top: 0px;");
75
+ return _view.Decoration.node(0, 2, (0, _defineProperty2.default)({
76
+ style: style
77
+ }, 'data-drag-handler-anchor-name', anchorName), {
78
+ type: 'node-decoration'
79
+ });
80
+ };
72
81
  var nodeDecorations = exports.nodeDecorations = function nodeDecorations(newState) {
73
82
  var decs = [];
74
83
  newState.doc.descendants(function (node, pos, _parent, index) {
75
- var _Decoration$node;
84
+ var _Decoration$node2;
76
85
  var anchorName = "--node-anchor-".concat(node.type.name, "-").concat(index);
77
86
  var style;
78
87
  if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2')) {
@@ -80,9 +89,11 @@ var nodeDecorations = exports.nodeDecorations = function nodeDecorations(newStat
80
89
  } else {
81
90
  style = "anchor-name: ".concat(anchorName, "; ").concat(pos === 0 ? 'margin-top: 0px;' : '');
82
91
  }
83
- decs.push(_view.Decoration.node(pos, pos + node.nodeSize, (_Decoration$node = {
92
+ decs.push(_view.Decoration.node(pos, pos + node.nodeSize, (_Decoration$node2 = {
84
93
  style: style
85
- }, (0, _defineProperty2.default)(_Decoration$node, 'data-drag-handler-anchor-name', anchorName), (0, _defineProperty2.default)(_Decoration$node, 'data-drag-handler-node-type', node.type.name), _Decoration$node)));
94
+ }, (0, _defineProperty2.default)(_Decoration$node2, 'data-drag-handler-anchor-name', anchorName), (0, _defineProperty2.default)(_Decoration$node2, 'data-drag-handler-node-type', node.type.name), _Decoration$node2), {
95
+ type: 'node-decoration'
96
+ }));
86
97
  return false;
87
98
  });
88
99
  return decs;
@@ -78,13 +78,10 @@ var initialState = {
78
78
  isMenuOpen: false,
79
79
  editorHeight: 0,
80
80
  isResizerResizing: false,
81
- isDocSizeLimitEnabled: false,
81
+ isDocSizeLimitEnabled: null,
82
82
  isPMDragging: false
83
83
  };
84
- if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
85
- initialState.isDocSizeLimitEnabled = true;
86
- }
87
- var DRAG_AND_DROP_DOC_SIZE_LIMIT = 20000;
84
+ var DRAG_AND_DROP_DOC_SIZE_LIMIT = 50;
88
85
  var createPlugin = exports.createPlugin = function createPlugin(api) {
89
86
  return new _safePlugin.SafePlugin({
90
87
  key: key,
@@ -94,7 +91,14 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
94
91
  },
95
92
  apply: function apply(tr, currentState, oldState, newState) {
96
93
  var _meta$activeNode, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$isPMDragging;
97
- if (initialState.isDocSizeLimitEnabled && newState.doc.nodeSize > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
94
+ if (initialState.isDocSizeLimitEnabled === null) {
95
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
96
+ initialState.isDocSizeLimitEnabled = true;
97
+ } else {
98
+ initialState.isDocSizeLimitEnabled = false;
99
+ }
100
+ }
101
+ if (initialState.isDocSizeLimitEnabled && newState.doc.childCount > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
98
102
  return initialState;
99
103
  }
100
104
  var activeNode = currentState.activeNode,
@@ -166,10 +170,18 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
166
170
  // Note: Quite often the handle is not in the right position after a node is moved
167
171
  // it is safer for now to not show it when a node is moved
168
172
  if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
169
- var newActiveNode = activeNode && tr.doc.nodeAt(tr.mapping.map(activeNode.pos));
173
+ var mappedPosisiton = tr.mapping.map(activeNode.pos);
174
+ var prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
175
+
176
+ // When a node type changed to be nested inside another node, the position of the active node is off by 1
177
+ // This is a workaround to fix the position of the active node when it is nested
178
+ if (mappedPosisiton === prevMappedPos + 1) {
179
+ mappedPosisiton = prevMappedPos;
180
+ }
181
+ var newActiveNode = tr.doc.nodeAt(mappedPosisiton);
170
182
  var nodeType = activeNode.nodeType;
171
183
  var anchorName = activeNode.anchorName;
172
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
184
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
173
185
  nodeType = newActiveNode.type.name;
174
186
  anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
175
187
  }
@@ -224,6 +236,14 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
224
236
  if (tr.docChanged && !redrawDecorations) {
225
237
  decorations = decorations.map(tr.mapping, tr.doc);
226
238
  }
239
+ var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
240
+ var hasNodeDecoration = decorations.find().some(function (_ref11) {
241
+ var spec = _ref11.spec;
242
+ return spec.type === 'node-decoration';
243
+ });
244
+ if (!hasNodeDecoration && isEmptyDoc) {
245
+ decorations = decorations.add(newState.doc, [(0, _decorations.emptyParagraphNodeDecorations)()]);
246
+ }
227
247
 
228
248
  // Map active node position when the document changes
229
249
  var mappedActiveNodePos = tr.docChanged && activeNode ? {
@@ -231,7 +251,6 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
231
251
  anchorName: activeNode.anchorName,
232
252
  nodeType: activeNode.nodeType
233
253
  } : activeNode;
234
- var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
235
254
  return {
236
255
  decorations: decorations,
237
256
  decorationState: decorationState,
@@ -256,12 +275,12 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
256
275
  },
257
276
  handleDOMEvents: {
258
277
  drop: function drop(view, event) {
259
- var _pluginState$activeNo;
260
278
  // prosemirror has sends a default transaction on drop (meta where uiEvent is 'drop'),
261
279
  // this duplicates the an empty version of the node it was dropping,
262
280
  // Adding some check here to prevent that if drop position is within activeNode
263
281
  var state = view.state,
264
- dispatch = view.dispatch;
282
+ dispatch = view.dispatch,
283
+ dragging = view.dragging;
265
284
  var pluginState = key.getState(state);
266
285
  if (pluginState !== null && pluginState !== void 0 && pluginState.isPMDragging) {
267
286
  dispatch(state.tr.setMeta(key, {
@@ -271,9 +290,11 @@ var createPlugin = exports.createPlugin = function createPlugin(api) {
271
290
  if (!(event.target instanceof HTMLElement) || !(pluginState !== null && pluginState !== void 0 && pluginState.activeNode)) {
272
291
  return false;
273
292
  }
274
- var node = view.nodeDOM(pluginState === null || pluginState === void 0 || (_pluginState$activeNo = pluginState.activeNode) === null || _pluginState$activeNo === void 0 ? void 0 : _pluginState$activeNo.pos);
275
- var isActiveNode = event.target === node;
276
- if (isActiveNode) {
293
+ // Currently we can only drag one node at a time
294
+ // so we only need to check first child
295
+ var draggable = dragging === null || dragging === void 0 ? void 0 : dragging.slice.content.firstChild;
296
+ var activeNode = state.tr.doc.nodeAt(pluginState.activeNode.pos);
297
+ if (draggable === activeNode) {
277
298
  // Prevent the default drop behavior if the position is within the activeNode
278
299
  event.preventDefault();
279
300
  return true;
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.GlobalStylesWrapper = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
7
9
  var _react = require("@emotion/react");
8
10
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
9
11
  /** @jsx jsx */
@@ -32,13 +34,18 @@ var extendedHoverZone = (0, _react.css)({
32
34
  display: 'none'
33
35
  }
34
36
  });
35
- var globalStyles = (0, _react.css)({
37
+ var paragraphWithTrailingBreak = '+ p > .ProseMirror-trailingBreak';
38
+ var paragraphWithCursorTarget = '+ p > .cursor-target';
39
+ var globalStyles = (0, _react.css)((0, _defineProperty2.default)({
36
40
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
37
41
  '.ProseMirror-widget:first-child + *': {
38
42
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
39
43
  marginTop: '0 !important'
40
44
  }
41
- });
45
+ }, ".ProseMirror-widget[data-blocks-drag-handle-container=\"true\"]:has(".concat(paragraphWithTrailingBreak, "):not(:has(").concat(paragraphWithCursorTarget, "))"), {
46
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
47
+ display: 'none !important'
48
+ }));
42
49
  var GlobalStylesWrapper = exports.GlobalStylesWrapper = function GlobalStylesWrapper() {
43
50
  return (0, _react.jsx)(_react.Global, {
44
51
  styles: [globalStyles, (0, _platformFeatureFlags.getBooleanFF)('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2') && extendedHoverZone]
@@ -61,6 +61,16 @@ export const dropTargetDecorations = (oldState, newState, api) => {
61
61
  decorationState
62
62
  };
63
63
  };
64
+ export const emptyParagraphNodeDecorations = () => {
65
+ const anchorName = `--node-anchor-paragraph-0`;
66
+ const style = `anchor-name: ${anchorName}; margin-top: 0px;`;
67
+ return Decoration.node(0, 2, {
68
+ style,
69
+ ['data-drag-handler-anchor-name']: anchorName
70
+ }, {
71
+ type: 'node-decoration'
72
+ });
73
+ };
64
74
  export const nodeDecorations = newState => {
65
75
  const decs = [];
66
76
  newState.doc.descendants((node, pos, _parent, index) => {
@@ -75,6 +85,8 @@ export const nodeDecorations = newState => {
75
85
  style,
76
86
  ['data-drag-handler-anchor-name']: anchorName,
77
87
  ['data-drag-handler-node-type']: node.type.name
88
+ }, {
89
+ type: 'node-decoration'
78
90
  }));
79
91
  return false;
80
92
  });
@@ -9,7 +9,7 @@ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
9
9
  import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
10
10
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
11
11
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
12
- import { dragHandleDecoration, dropTargetDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
12
+ import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
13
13
  import { handleMouseOver } from './handle-mouse-over';
14
14
  export const key = new PluginKey('blockControls');
15
15
  const destroyFn = api => {
@@ -72,13 +72,10 @@ const initialState = {
72
72
  isMenuOpen: false,
73
73
  editorHeight: 0,
74
74
  isResizerResizing: false,
75
- isDocSizeLimitEnabled: false,
75
+ isDocSizeLimitEnabled: null,
76
76
  isPMDragging: false
77
77
  };
78
- if (getBooleanFF('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
79
- initialState.isDocSizeLimitEnabled = true;
80
- }
81
- const DRAG_AND_DROP_DOC_SIZE_LIMIT = 20000;
78
+ const DRAG_AND_DROP_DOC_SIZE_LIMIT = 50;
82
79
  export const createPlugin = api => {
83
80
  return new SafePlugin({
84
81
  key,
@@ -88,7 +85,14 @@ export const createPlugin = api => {
88
85
  },
89
86
  apply(tr, currentState, oldState, newState) {
90
87
  var _meta$activeNode, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$isPMDragging;
91
- if (initialState.isDocSizeLimitEnabled && newState.doc.nodeSize > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
88
+ if (initialState.isDocSizeLimitEnabled === null) {
89
+ if (getBooleanFF('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
90
+ initialState.isDocSizeLimitEnabled = true;
91
+ } else {
92
+ initialState.isDocSizeLimitEnabled = false;
93
+ }
94
+ }
95
+ if (initialState.isDocSizeLimitEnabled && newState.doc.childCount > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
92
96
  return initialState;
93
97
  }
94
98
  let {
@@ -157,10 +161,18 @@ export const createPlugin = api => {
157
161
  // Note: Quite often the handle is not in the right position after a node is moved
158
162
  // it is safer for now to not show it when a node is moved
159
163
  if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
160
- const newActiveNode = activeNode && tr.doc.nodeAt(tr.mapping.map(activeNode.pos));
164
+ let mappedPosisiton = tr.mapping.map(activeNode.pos);
165
+ const prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
166
+
167
+ // When a node type changed to be nested inside another node, the position of the active node is off by 1
168
+ // This is a workaround to fix the position of the active node when it is nested
169
+ if (mappedPosisiton === prevMappedPos + 1) {
170
+ mappedPosisiton = prevMappedPos;
171
+ }
172
+ const newActiveNode = tr.doc.nodeAt(mappedPosisiton);
161
173
  let nodeType = activeNode.nodeType;
162
174
  let anchorName = activeNode.anchorName;
163
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
175
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
164
176
  nodeType = newActiveNode.type.name;
165
177
  anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
166
178
  }
@@ -215,6 +227,13 @@ export const createPlugin = api => {
215
227
  if (tr.docChanged && !redrawDecorations) {
216
228
  decorations = decorations.map(tr.mapping, tr.doc);
217
229
  }
230
+ const isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
231
+ const hasNodeDecoration = decorations.find().some(({
232
+ spec
233
+ }) => spec.type === 'node-decoration');
234
+ if (!hasNodeDecoration && isEmptyDoc) {
235
+ decorations = decorations.add(newState.doc, [emptyParagraphNodeDecorations()]);
236
+ }
218
237
 
219
238
  // Map active node position when the document changes
220
239
  const mappedActiveNodePos = tr.docChanged && activeNode ? {
@@ -222,7 +241,6 @@ export const createPlugin = api => {
222
241
  anchorName: activeNode.anchorName,
223
242
  nodeType: activeNode.nodeType
224
243
  } : activeNode;
225
- const isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
226
244
  return {
227
245
  decorations,
228
246
  decorationState,
@@ -247,13 +265,13 @@ export const createPlugin = api => {
247
265
  },
248
266
  handleDOMEvents: {
249
267
  drop(view, event) {
250
- var _pluginState$activeNo;
251
268
  // prosemirror has sends a default transaction on drop (meta where uiEvent is 'drop'),
252
269
  // this duplicates the an empty version of the node it was dropping,
253
270
  // Adding some check here to prevent that if drop position is within activeNode
254
271
  const {
255
272
  state,
256
- dispatch
273
+ dispatch,
274
+ dragging
257
275
  } = view;
258
276
  const pluginState = key.getState(state);
259
277
  if (pluginState !== null && pluginState !== void 0 && pluginState.isPMDragging) {
@@ -264,9 +282,11 @@ export const createPlugin = api => {
264
282
  if (!(event.target instanceof HTMLElement) || !(pluginState !== null && pluginState !== void 0 && pluginState.activeNode)) {
265
283
  return false;
266
284
  }
267
- const node = view.nodeDOM(pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$activeNo = pluginState.activeNode) === null || _pluginState$activeNo === void 0 ? void 0 : _pluginState$activeNo.pos);
268
- const isActiveNode = event.target === node;
269
- if (isActiveNode) {
285
+ // Currently we can only drag one node at a time
286
+ // so we only need to check first child
287
+ const draggable = dragging === null || dragging === void 0 ? void 0 : dragging.slice.content.firstChild;
288
+ const activeNode = state.tr.doc.nodeAt(pluginState.activeNode.pos);
289
+ if (draggable === activeNode) {
270
290
  // Prevent the default drop behavior if the position is within the activeNode
271
291
  event.preventDefault();
272
292
  return true;
@@ -25,11 +25,20 @@ const extendedHoverZone = css({
25
25
  display: 'none'
26
26
  }
27
27
  });
28
+ const paragraphWithTrailingBreak = '+ p > .ProseMirror-trailingBreak';
29
+ const paragraphWithCursorTarget = '+ p > .cursor-target';
28
30
  const globalStyles = css({
29
31
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
30
32
  '.ProseMirror-widget:first-child + *': {
31
33
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
32
34
  marginTop: '0 !important'
35
+ },
36
+ // Currently, we are hiding the drag handle container by checking if the paragraph has a trailing break and no cursor target
37
+ // TODO ED-23827 add a classname to empty paragraphs for easier targeting
38
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
39
+ [`.ProseMirror-widget[data-blocks-drag-handle-container="true"]:has(${paragraphWithTrailingBreak}):not(:has(${paragraphWithCursorTarget}))`]: {
40
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
41
+ display: 'none !important'
33
42
  }
34
43
  });
35
44
  export const GlobalStylesWrapper = () => {
@@ -62,10 +62,19 @@ export var dropTargetDecorations = function dropTargetDecorations(oldState, newS
62
62
  decorationState: decorationState
63
63
  };
64
64
  };
65
+ export var emptyParagraphNodeDecorations = function emptyParagraphNodeDecorations() {
66
+ var anchorName = "--node-anchor-paragraph-0";
67
+ var style = "anchor-name: ".concat(anchorName, "; margin-top: 0px;");
68
+ return Decoration.node(0, 2, _defineProperty({
69
+ style: style
70
+ }, 'data-drag-handler-anchor-name', anchorName), {
71
+ type: 'node-decoration'
72
+ });
73
+ };
65
74
  export var nodeDecorations = function nodeDecorations(newState) {
66
75
  var decs = [];
67
76
  newState.doc.descendants(function (node, pos, _parent, index) {
68
- var _Decoration$node;
77
+ var _Decoration$node2;
69
78
  var anchorName = "--node-anchor-".concat(node.type.name, "-").concat(index);
70
79
  var style;
71
80
  if (getBooleanFF('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2')) {
@@ -73,9 +82,11 @@ export var nodeDecorations = function nodeDecorations(newState) {
73
82
  } else {
74
83
  style = "anchor-name: ".concat(anchorName, "; ").concat(pos === 0 ? 'margin-top: 0px;' : '');
75
84
  }
76
- decs.push(Decoration.node(pos, pos + node.nodeSize, (_Decoration$node = {
85
+ decs.push(Decoration.node(pos, pos + node.nodeSize, (_Decoration$node2 = {
77
86
  style: style
78
- }, _defineProperty(_Decoration$node, 'data-drag-handler-anchor-name', anchorName), _defineProperty(_Decoration$node, 'data-drag-handler-node-type', node.type.name), _Decoration$node)));
87
+ }, _defineProperty(_Decoration$node2, 'data-drag-handler-anchor-name', anchorName), _defineProperty(_Decoration$node2, 'data-drag-handler-node-type', node.type.name), _Decoration$node2), {
88
+ type: 'node-decoration'
89
+ }));
79
90
  return false;
80
91
  });
81
92
  return decs;
@@ -10,7 +10,7 @@ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
10
10
  import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
11
11
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
12
12
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
13
- import { dragHandleDecoration, dropTargetDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
13
+ import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, mouseMoveWrapperDecorations, nodeDecorations } from './decorations';
14
14
  import { handleMouseOver } from './handle-mouse-over';
15
15
  export var key = new PluginKey('blockControls');
16
16
  var destroyFn = function destroyFn(api) {
@@ -71,13 +71,10 @@ var initialState = {
71
71
  isMenuOpen: false,
72
72
  editorHeight: 0,
73
73
  isResizerResizing: false,
74
- isDocSizeLimitEnabled: false,
74
+ isDocSizeLimitEnabled: null,
75
75
  isPMDragging: false
76
76
  };
77
- if (getBooleanFF('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
78
- initialState.isDocSizeLimitEnabled = true;
79
- }
80
- var DRAG_AND_DROP_DOC_SIZE_LIMIT = 20000;
77
+ var DRAG_AND_DROP_DOC_SIZE_LIMIT = 50;
81
78
  export var createPlugin = function createPlugin(api) {
82
79
  return new SafePlugin({
83
80
  key: key,
@@ -87,7 +84,14 @@ export var createPlugin = function createPlugin(api) {
87
84
  },
88
85
  apply: function apply(tr, currentState, oldState, newState) {
89
86
  var _meta$activeNode, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$isPMDragging;
90
- if (initialState.isDocSizeLimitEnabled && newState.doc.nodeSize > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
87
+ if (initialState.isDocSizeLimitEnabled === null) {
88
+ if (getBooleanFF('platform.editor.elements.drag-and-drop-doc-size-limit_7k4vq')) {
89
+ initialState.isDocSizeLimitEnabled = true;
90
+ } else {
91
+ initialState.isDocSizeLimitEnabled = false;
92
+ }
93
+ }
94
+ if (initialState.isDocSizeLimitEnabled && newState.doc.childCount > DRAG_AND_DROP_DOC_SIZE_LIMIT) {
91
95
  return initialState;
92
96
  }
93
97
  var activeNode = currentState.activeNode,
@@ -159,10 +163,18 @@ export var createPlugin = function createPlugin(api) {
159
163
  // Note: Quite often the handle is not in the right position after a node is moved
160
164
  // it is safer for now to not show it when a node is moved
161
165
  if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
162
- var newActiveNode = activeNode && tr.doc.nodeAt(tr.mapping.map(activeNode.pos));
166
+ var mappedPosisiton = tr.mapping.map(activeNode.pos);
167
+ var prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
168
+
169
+ // When a node type changed to be nested inside another node, the position of the active node is off by 1
170
+ // This is a workaround to fix the position of the active node when it is nested
171
+ if (mappedPosisiton === prevMappedPos + 1) {
172
+ mappedPosisiton = prevMappedPos;
173
+ }
174
+ var newActiveNode = tr.doc.nodeAt(mappedPosisiton);
163
175
  var nodeType = activeNode.nodeType;
164
176
  var anchorName = activeNode.anchorName;
165
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType && !(meta !== null && meta !== void 0 && meta.nodeMoved)) {
177
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
166
178
  nodeType = newActiveNode.type.name;
167
179
  anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
168
180
  }
@@ -217,6 +229,14 @@ export var createPlugin = function createPlugin(api) {
217
229
  if (tr.docChanged && !redrawDecorations) {
218
230
  decorations = decorations.map(tr.mapping, tr.doc);
219
231
  }
232
+ var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
233
+ var hasNodeDecoration = decorations.find().some(function (_ref11) {
234
+ var spec = _ref11.spec;
235
+ return spec.type === 'node-decoration';
236
+ });
237
+ if (!hasNodeDecoration && isEmptyDoc) {
238
+ decorations = decorations.add(newState.doc, [emptyParagraphNodeDecorations()]);
239
+ }
220
240
 
221
241
  // Map active node position when the document changes
222
242
  var mappedActiveNodePos = tr.docChanged && activeNode ? {
@@ -224,7 +244,6 @@ export var createPlugin = function createPlugin(api) {
224
244
  anchorName: activeNode.anchorName,
225
245
  nodeType: activeNode.nodeType
226
246
  } : activeNode;
227
- var isEmptyDoc = newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
228
247
  return {
229
248
  decorations: decorations,
230
249
  decorationState: decorationState,
@@ -249,12 +268,12 @@ export var createPlugin = function createPlugin(api) {
249
268
  },
250
269
  handleDOMEvents: {
251
270
  drop: function drop(view, event) {
252
- var _pluginState$activeNo;
253
271
  // prosemirror has sends a default transaction on drop (meta where uiEvent is 'drop'),
254
272
  // this duplicates the an empty version of the node it was dropping,
255
273
  // Adding some check here to prevent that if drop position is within activeNode
256
274
  var state = view.state,
257
- dispatch = view.dispatch;
275
+ dispatch = view.dispatch,
276
+ dragging = view.dragging;
258
277
  var pluginState = key.getState(state);
259
278
  if (pluginState !== null && pluginState !== void 0 && pluginState.isPMDragging) {
260
279
  dispatch(state.tr.setMeta(key, {
@@ -264,9 +283,11 @@ export var createPlugin = function createPlugin(api) {
264
283
  if (!(event.target instanceof HTMLElement) || !(pluginState !== null && pluginState !== void 0 && pluginState.activeNode)) {
265
284
  return false;
266
285
  }
267
- var node = view.nodeDOM(pluginState === null || pluginState === void 0 || (_pluginState$activeNo = pluginState.activeNode) === null || _pluginState$activeNo === void 0 ? void 0 : _pluginState$activeNo.pos);
268
- var isActiveNode = event.target === node;
269
- if (isActiveNode) {
286
+ // Currently we can only drag one node at a time
287
+ // so we only need to check first child
288
+ var draggable = dragging === null || dragging === void 0 ? void 0 : dragging.slice.content.firstChild;
289
+ var activeNode = state.tr.doc.nodeAt(pluginState.activeNode.pos);
290
+ if (draggable === activeNode) {
270
291
  // Prevent the default drop behavior if the position is within the activeNode
271
292
  event.preventDefault();
272
293
  return true;
@@ -1,3 +1,4 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  /** @jsx jsx */
2
3
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
3
4
  import { css, Global, jsx } from '@emotion/react';
@@ -25,13 +26,18 @@ var extendedHoverZone = css({
25
26
  display: 'none'
26
27
  }
27
28
  });
28
- var globalStyles = css({
29
+ var paragraphWithTrailingBreak = '+ p > .ProseMirror-trailingBreak';
30
+ var paragraphWithCursorTarget = '+ p > .cursor-target';
31
+ var globalStyles = css(_defineProperty({
29
32
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
30
33
  '.ProseMirror-widget:first-child + *': {
31
34
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
32
35
  marginTop: '0 !important'
33
36
  }
34
- });
37
+ }, ".ProseMirror-widget[data-blocks-drag-handle-container=\"true\"]:has(".concat(paragraphWithTrailingBreak, "):not(:has(").concat(paragraphWithCursorTarget, "))"), {
38
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
39
+ display: 'none !important'
40
+ }));
35
41
  export var GlobalStylesWrapper = function GlobalStylesWrapper() {
36
42
  return jsx(Global, {
37
43
  styles: [globalStyles, getBooleanFF('platform.editor.elements.drag-and-drop-remove-wrapper_fyqr2') && extendedHoverZone]
@@ -9,6 +9,7 @@ export declare const dropTargetDecorations: (oldState: EditorState, newState: Ed
9
9
  pos: number;
10
10
  }[];
11
11
  };
12
+ export declare const emptyParagraphNodeDecorations: () => Decoration;
12
13
  export declare const nodeDecorations: (newState: EditorState) => Decoration[];
13
14
  /**
14
15
  * Setting up decorations around each node to track mousemove events into each node
@@ -16,7 +16,7 @@ export interface PluginState {
16
16
  nodeType: string;
17
17
  } | null;
18
18
  isResizerResizing: boolean;
19
- isDocSizeLimitEnabled: boolean;
19
+ isDocSizeLimitEnabled: boolean | null;
20
20
  /**
21
21
  * is dragging the node without using drag handle, i,e, native prosemirror DnD
22
22
  */
@@ -9,6 +9,7 @@ export declare const dropTargetDecorations: (oldState: EditorState, newState: Ed
9
9
  pos: number;
10
10
  }[];
11
11
  };
12
+ export declare const emptyParagraphNodeDecorations: () => Decoration;
12
13
  export declare const nodeDecorations: (newState: EditorState) => Decoration[];
13
14
  /**
14
15
  * Setting up decorations around each node to track mousemove events into each node
@@ -16,7 +16,7 @@ export interface PluginState {
16
16
  nodeType: string;
17
17
  } | null;
18
18
  isResizerResizing: boolean;
19
- isDocSizeLimitEnabled: boolean;
19
+ isDocSizeLimitEnabled: boolean | null;
20
20
  /**
21
21
  * is dragging the node without using drag handle, i,e, native prosemirror DnD
22
22
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "1.4.33",
3
+ "version": "1.4.35",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",