@atlaskit/editor-plugin-block-controls 2.6.1 → 2.6.3

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,25 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 2.6.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#153087](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/153087)
8
+ [`a29ea6551ed67`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a29ea6551ed67) -
9
+ ED-24902: Change display from inline to block to fix focus issues with drag handle
10
+ - [#152414](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/152414)
11
+ [`893c9f74cb700`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/893c9f74cb700) -
12
+ Use getPos instead of pos when rendering drag handle
13
+ - Updated dependencies
14
+
15
+ ## 2.6.2
16
+
17
+ ### Patch Changes
18
+
19
+ - [#152656](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/152656)
20
+ [`07cd0baf1bb6f`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/07cd0baf1bb6f) -
21
+ Fix corner case where getTrMetadata does not give full pos range
22
+
3
23
  ## 2.6.1
4
24
 
5
25
  ### Patch Changes
@@ -52,20 +52,9 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
52
52
  return tr;
53
53
  };
54
54
  },
55
- hideDragHandle: function hideDragHandle() {
55
+ setNodeDragged: function setNodeDragged(getPos, anchorName, nodeType) {
56
56
  return function (_ref5) {
57
57
  var tr = _ref5.tr;
58
- if ((0, _platformFeatureFlags.fg)('confluence_frontend_page_title_enter_improvements')) {
59
- tr.setMeta(_main.key, {
60
- hideDragHandle: true
61
- });
62
- }
63
- return tr;
64
- };
65
- },
66
- setNodeDragged: function setNodeDragged(getPos, anchorName, nodeType) {
67
- return function (_ref6) {
68
- var tr = _ref6.tr;
69
58
  var pos = getPos();
70
59
  if (pos === undefined) {
71
60
  return tr;
@@ -336,18 +336,22 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
336
336
  return _view.Decoration.widget(pos, function (view, getPos) {
337
337
  var element = document.createElement('span');
338
338
  // Need to set it to inline to avoid text being split when merging two paragraphs
339
- element.style.display = 'inline';
339
+ // platform_editor_element_dnd_nested_fix_patch_2 -> inline decoration causes focus issues when refocusing Editor into first line
340
+ element.style.display = (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_fix_patch_2') ? 'block' : 'inline';
340
341
  element.setAttribute('data-testid', 'block-ctrl-decorator-widget');
341
342
  element.setAttribute('data-blocks-drag-handle-container', 'true');
342
343
  var isTopLevelNode = true;
343
344
  if ((0, _experiments.editorExperiment)('nested-dnd', true)) {
344
- var $pos = view.state.doc.resolve(pos);
345
- isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
345
+ var newPos = (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_fix_patch_3') ? getPos() : pos;
346
+ if (typeof newPos === 'number') {
347
+ var $pos = view.state.doc.resolve(newPos);
348
+ isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
349
+ }
346
350
  /*
347
351
  * We disable mouseover event to fix flickering issue on hover
348
352
  * However, the tooltip for nested drag handle is no long working.
349
353
  */
350
- if (!isTopLevelNode) {
354
+ if (newPos === undefined || !isTopLevelNode) {
351
355
  // This will also hide the tooltip.
352
356
  unbind = (0, _bindEventListener.bind)(element, {
353
357
  type: 'mouseover',
@@ -13,11 +13,6 @@ var isEmptyNestedParagraphOrHeading = function isEmptyNestedParagraphOrHeading(t
13
13
  }
14
14
  return false;
15
15
  };
16
- var isDocFirstChildEmptyLine = function isDocFirstChildEmptyLine(elem) {
17
- var _elem$firstElementChi;
18
- var parentElement = elem.parentElement;
19
- return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
20
- };
21
16
  var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, event, api) {
22
17
  var _api$blockControls, _target$classList;
23
18
  var _ref = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
@@ -36,11 +31,6 @@ var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, e
36
31
  var rootElement = target === null || target === void 0 ? void 0 : target.closest('[data-drag-handler-anchor-name]');
37
32
  if (rootElement) {
38
33
  var _rootElement$parentEl;
39
- if (isDocFirstChildEmptyLine(rootElement) && (0, _platformFeatureFlags.fg)('confluence_frontend_page_title_enter_improvements')) {
40
- var _api$core, _api$blockControls2;
41
- api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.hideDragHandle());
42
- return;
43
- }
44
34
  // We want to exlude handles from showing for empty paragraph and heading nodes
45
35
  if ((0, _experiments.editorExperiment)('nested-dnd', true) && isEmptyNestedParagraphOrHeading(rootElement)) {
46
36
  return false;
@@ -89,8 +79,8 @@ var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, e
89
79
  }
90
80
  var nodeType = rootElement.getAttribute('data-drag-handler-node-type');
91
81
  if (nodeType) {
92
- var _api$core2, _api$blockControls3;
93
- api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.commands.showDragHandleAt(rootPos, anchorName, nodeType));
82
+ var _api$core, _api$blockControls2;
83
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.showDragHandleAt(rootPos, anchorName, nodeType));
94
84
  }
95
85
  }
96
86
  };
@@ -97,7 +97,6 @@ var initialState = {
97
97
  };
98
98
  var newApply = exports.newApply = function newApply(api, formatMessage, tr, currentState, newState, flags, anchorHeightsCache) {
99
99
  var _meta$activeNode, _activeNode, _activeNode2, _meta$activeNode$hand, _meta$isDragging, _meta$isDragging2, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
100
- var isTitleEnterImprovementEnabled = flags.isTitleEnterImprovementEnabled;
101
100
  var activeNode = currentState.activeNode,
102
101
  decorations = currentState.decorations,
103
102
  editorHeight = currentState.editorHeight,
@@ -177,7 +176,7 @@ var newApply = exports.newApply = function newApply(api, formatMessage, tr, curr
177
176
  var shouldRecreateHandle = latestActiveNode && (activeNodeChanged || isActiveNodeModified || editorSizeChanged || handleNeedsRedraw);
178
177
 
179
178
  // Remove handle dec when explicitly hidden, a node is resizing, activeNode pos was deleted, or DnD moved a node
180
- var shouldRemoveHandle = latestActiveNode && ((meta === null || meta === void 0 ? void 0 : meta.hideDragHandle) && isTitleEnterImprovementEnabled || isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
179
+ var shouldRemoveHandle = latestActiveNode && (isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
181
180
  if (shouldRemoveHandle) {
182
181
  var _activeNode3, _activeNode4;
183
182
  var oldHandle = (0, _decorations.findHandleDec)(decorations, (_activeNode3 = activeNode) === null || _activeNode3 === void 0 ? void 0 : _activeNode3.pos, (_activeNode4 = activeNode) === null || _activeNode4 === void 0 ? void 0 : _activeNode4.pos);
@@ -229,8 +228,7 @@ var newApply = exports.newApply = function newApply(api, formatMessage, tr, curr
229
228
  };
230
229
  var oldApply = exports.oldApply = function oldApply(api, formatMessage, tr, currentState, oldState, newState, flags, anchorHeightsCache) {
231
230
  var _meta$activeNode2, _meta$activeNode$hand2, _activeNodeWithNewNod, _meta$activeNode8, _meta$isDragging4, _meta$editorHeight2, _meta$editorWidthLeft2, _meta$editorWidthRigh2, _meta$isPMDragging2;
232
- var isNestedEnabled = flags.isNestedEnabled,
233
- isTitleEnterImprovementEnabled = flags.isTitleEnterImprovementEnabled;
231
+ var isNestedEnabled = flags.isNestedEnabled;
234
232
  var activeNode = currentState.activeNode,
235
233
  decorations = currentState.decorations,
236
234
  isMenuOpen = currentState.isMenuOpen,
@@ -265,7 +263,7 @@ var oldApply = exports.oldApply = function oldApply(api, formatMessage, tr, curr
265
263
  // During resize, remove the drag handle widget so its dom positioning doesn't need to be maintained
266
264
  // Also remove the handle when the node is moved or the node count changes. This helps prevent incorrect positioning
267
265
  // Don't remove the handle if remote changes are changing the node count, its prosemirror position can be mapped instead
268
- if (meta !== null && meta !== void 0 && meta.hideDragHandle && isTitleEnterImprovementEnabled || isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
266
+ if (isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
269
267
  var oldHandle = decorations.find(undefined, undefined, function (spec) {
270
268
  return spec.type === 'drag-handle';
271
269
  });
@@ -429,11 +427,9 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
429
427
  var isOptimisedApply = isNestedEnabled && (0, _experiments.editorExperiment)('optimised-apply-dnd', true, {
430
428
  exposure: true
431
429
  });
432
- var isTitleEnterImprovementEnabled = (0, _platformFeatureFlags.fg)('confluence_frontend_page_title_enter_improvements');
433
430
  var flags = {
434
431
  isNestedEnabled: isNestedEnabled,
435
- isOptimisedApply: isOptimisedApply,
436
- isTitleEnterImprovementEnabled: isTitleEnterImprovementEnabled
432
+ isOptimisedApply: isOptimisedApply
437
433
  };
438
434
  if ((0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_fix_patch_2')) {
439
435
  // TODO: Remove this once FG is used in code
@@ -28,7 +28,7 @@ var isStepDelete = exports.isStepDelete = function isStepDelete(s) {
28
28
  /**
29
29
  * Get metadata from the transaction.
30
30
  * @param tr
31
- * @returns Min 'from', max 'to' (from + slice size). If no steps, returns pos range of entire doc.
31
+ * @returns Min 'from', max 'to' (from + slice size, or mapped 'to', whichever is larger). If no steps, returns pos range of entire doc.
32
32
  * Number of ReplaceStep and ReplaceAroundStep steps 'numReplaceSteps'.
33
33
  * 'isAllText' if all steps are represent adding inline text or a backspace/delete or no-op
34
34
  */
@@ -42,7 +42,9 @@ var getTrMetadata = exports.getTrMetadata = function getTrMetadata(tr) {
42
42
  if (s instanceof _transform.ReplaceAroundStep || s instanceof _transform.ReplaceStep && !isStepText(s) && !isStepDelete(s)) {
43
43
  isAllText = false;
44
44
  }
45
+ var mappedTo = tr.mapping.map(s.to);
45
46
  var $to = s.from + s.slice.size;
47
+ $to = $to > mappedTo ? $to : mappedTo;
46
48
  from = from === undefined || from > s.from ? s.from : from;
47
49
  to = to === undefined || to < $to ? $to : to;
48
50
  numReplaceSteps++;
@@ -41,16 +41,6 @@ export const blockControlsPlugin = ({
41
41
  });
42
42
  return tr;
43
43
  },
44
- hideDragHandle: () => ({
45
- tr
46
- }) => {
47
- if (fg('confluence_frontend_page_title_enter_improvements')) {
48
- tr.setMeta(key, {
49
- hideDragHandle: true
50
- });
51
- }
52
- return tr;
53
- },
54
44
  setNodeDragged: (getPos, anchorName, nodeType) => ({
55
45
  tr
56
46
  }) => {
@@ -316,18 +316,22 @@ export const dragHandleDecoration = (api, formatMessage, pos, anchorName, nodeTy
316
316
  return Decoration.widget(pos, (view, getPos) => {
317
317
  const element = document.createElement('span');
318
318
  // Need to set it to inline to avoid text being split when merging two paragraphs
319
- element.style.display = 'inline';
319
+ // platform_editor_element_dnd_nested_fix_patch_2 -> inline decoration causes focus issues when refocusing Editor into first line
320
+ element.style.display = fg('platform_editor_element_dnd_nested_fix_patch_2') ? 'block' : 'inline';
320
321
  element.setAttribute('data-testid', 'block-ctrl-decorator-widget');
321
322
  element.setAttribute('data-blocks-drag-handle-container', 'true');
322
323
  let isTopLevelNode = true;
323
324
  if (editorExperiment('nested-dnd', true)) {
324
- const $pos = view.state.doc.resolve(pos);
325
- isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
325
+ const newPos = fg('platform_editor_element_dnd_nested_fix_patch_3') ? getPos() : pos;
326
+ if (typeof newPos === 'number') {
327
+ const $pos = view.state.doc.resolve(newPos);
328
+ isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
329
+ }
326
330
  /*
327
331
  * We disable mouseover event to fix flickering issue on hover
328
332
  * However, the tooltip for nested drag handle is no long working.
329
333
  */
330
- if (!isTopLevelNode) {
334
+ if (newPos === undefined || !isTopLevelNode) {
331
335
  // This will also hide the tooltip.
332
336
  unbind = bind(element, {
333
337
  type: 'mouseover',
@@ -7,11 +7,6 @@ const isEmptyNestedParagraphOrHeading = target => {
7
7
  }
8
8
  return false;
9
9
  };
10
- const isDocFirstChildEmptyLine = elem => {
11
- var _elem$firstElementChi;
12
- const parentElement = elem.parentElement;
13
- return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
14
- };
15
10
  export const handleMouseOver = (view, event, api) => {
16
11
  var _api$blockControls, _target$classList;
17
12
  const {
@@ -31,11 +26,6 @@ export const handleMouseOver = (view, event, api) => {
31
26
  let rootElement = target === null || target === void 0 ? void 0 : target.closest('[data-drag-handler-anchor-name]');
32
27
  if (rootElement) {
33
28
  var _rootElement$parentEl;
34
- if (isDocFirstChildEmptyLine(rootElement) && fg('confluence_frontend_page_title_enter_improvements')) {
35
- var _api$core, _api$blockControls2;
36
- api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.hideDragHandle());
37
- return;
38
- }
39
29
  // We want to exlude handles from showing for empty paragraph and heading nodes
40
30
  if (editorExperiment('nested-dnd', true) && isEmptyNestedParagraphOrHeading(rootElement)) {
41
31
  return false;
@@ -84,8 +74,8 @@ export const handleMouseOver = (view, event, api) => {
84
74
  }
85
75
  const nodeType = rootElement.getAttribute('data-drag-handler-node-type');
86
76
  if (nodeType) {
87
- var _api$core2, _api$blockControls3;
88
- api === null || api === void 0 ? void 0 : (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.commands.showDragHandleAt(rootPos, anchorName, nodeType));
77
+ var _api$core, _api$blockControls2;
78
+ api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.showDragHandleAt(rootPos, anchorName, nodeType));
89
79
  }
90
80
  }
91
81
  };
@@ -91,9 +91,6 @@ const initialState = {
91
91
  };
92
92
  export const newApply = (api, formatMessage, tr, currentState, newState, flags, anchorHeightsCache) => {
93
93
  var _meta$activeNode, _activeNode, _activeNode2, _meta$activeNode$hand, _meta$isDragging, _meta$isDragging2, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
94
- const {
95
- isTitleEnterImprovementEnabled
96
- } = flags;
97
94
  let {
98
95
  activeNode,
99
96
  decorations,
@@ -176,7 +173,7 @@ export const newApply = (api, formatMessage, tr, currentState, newState, flags,
176
173
  const shouldRecreateHandle = latestActiveNode && (activeNodeChanged || isActiveNodeModified || editorSizeChanged || handleNeedsRedraw);
177
174
 
178
175
  // Remove handle dec when explicitly hidden, a node is resizing, activeNode pos was deleted, or DnD moved a node
179
- const shouldRemoveHandle = latestActiveNode && ((meta === null || meta === void 0 ? void 0 : meta.hideDragHandle) && isTitleEnterImprovementEnabled || isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
176
+ const shouldRemoveHandle = latestActiveNode && (isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
180
177
  if (shouldRemoveHandle) {
181
178
  var _activeNode3, _activeNode4;
182
179
  const oldHandle = findHandleDec(decorations, (_activeNode3 = activeNode) === null || _activeNode3 === void 0 ? void 0 : _activeNode3.pos, (_activeNode4 = activeNode) === null || _activeNode4 === void 0 ? void 0 : _activeNode4.pos);
@@ -229,8 +226,7 @@ export const newApply = (api, formatMessage, tr, currentState, newState, flags,
229
226
  export const oldApply = (api, formatMessage, tr, currentState, oldState, newState, flags, anchorHeightsCache) => {
230
227
  var _meta$activeNode2, _meta$activeNode$hand2, _activeNodeWithNewNod, _meta$activeNode8, _meta$isDragging4, _meta$editorHeight2, _meta$editorWidthLeft2, _meta$editorWidthRigh2, _meta$isPMDragging2;
231
228
  const {
232
- isNestedEnabled,
233
- isTitleEnterImprovementEnabled
229
+ isNestedEnabled
234
230
  } = flags;
235
231
  let {
236
232
  activeNode,
@@ -264,7 +260,7 @@ export const oldApply = (api, formatMessage, tr, currentState, oldState, newStat
264
260
  // During resize, remove the drag handle widget so its dom positioning doesn't need to be maintained
265
261
  // Also remove the handle when the node is moved or the node count changes. This helps prevent incorrect positioning
266
262
  // Don't remove the handle if remote changes are changing the node count, its prosemirror position can be mapped instead
267
- if (meta !== null && meta !== void 0 && meta.hideDragHandle && isTitleEnterImprovementEnabled || isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
263
+ if (isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
268
264
  const oldHandle = decorations.find(undefined, undefined, spec => spec.type === 'drag-handle');
269
265
  decorations = decorations.remove(oldHandle);
270
266
  }
@@ -406,11 +402,9 @@ export const createPlugin = (api, getIntl) => {
406
402
  const isOptimisedApply = isNestedEnabled && editorExperiment('optimised-apply-dnd', true, {
407
403
  exposure: true
408
404
  });
409
- const isTitleEnterImprovementEnabled = fg('confluence_frontend_page_title_enter_improvements');
410
405
  const flags = {
411
406
  isNestedEnabled,
412
- isOptimisedApply,
413
- isTitleEnterImprovementEnabled
407
+ isOptimisedApply
414
408
  };
415
409
  if (fg('platform_editor_element_dnd_nested_fix_patch_2')) {
416
410
  // TODO: Remove this once FG is used in code
@@ -22,7 +22,7 @@ export const isStepDelete = s => {
22
22
  /**
23
23
  * Get metadata from the transaction.
24
24
  * @param tr
25
- * @returns Min 'from', max 'to' (from + slice size). If no steps, returns pos range of entire doc.
25
+ * @returns Min 'from', max 'to' (from + slice size, or mapped 'to', whichever is larger). If no steps, returns pos range of entire doc.
26
26
  * Number of ReplaceStep and ReplaceAroundStep steps 'numReplaceSteps'.
27
27
  * 'isAllText' if all steps are represent adding inline text or a backspace/delete or no-op
28
28
  */
@@ -36,7 +36,9 @@ export const getTrMetadata = tr => {
36
36
  if (s instanceof ReplaceAroundStep || s instanceof ReplaceStep && !isStepText(s) && !isStepDelete(s)) {
37
37
  isAllText = false;
38
38
  }
39
- const $to = s.from + s.slice.size;
39
+ const mappedTo = tr.mapping.map(s.to);
40
+ let $to = s.from + s.slice.size;
41
+ $to = $to > mappedTo ? $to : mappedTo;
40
42
  from = from === undefined || from > s.from ? s.from : from;
41
43
  to = to === undefined || to < $to ? $to : to;
42
44
  numReplaceSteps++;
@@ -45,20 +45,9 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
45
45
  return tr;
46
46
  };
47
47
  },
48
- hideDragHandle: function hideDragHandle() {
48
+ setNodeDragged: function setNodeDragged(getPos, anchorName, nodeType) {
49
49
  return function (_ref5) {
50
50
  var tr = _ref5.tr;
51
- if (fg('confluence_frontend_page_title_enter_improvements')) {
52
- tr.setMeta(key, {
53
- hideDragHandle: true
54
- });
55
- }
56
- return tr;
57
- };
58
- },
59
- setNodeDragged: function setNodeDragged(getPos, anchorName, nodeType) {
60
- return function (_ref6) {
61
- var tr = _ref6.tr;
62
51
  var pos = getPos();
63
52
  if (pos === undefined) {
64
53
  return tr;
@@ -329,18 +329,22 @@ export var dragHandleDecoration = function dragHandleDecoration(api, formatMessa
329
329
  return Decoration.widget(pos, function (view, getPos) {
330
330
  var element = document.createElement('span');
331
331
  // Need to set it to inline to avoid text being split when merging two paragraphs
332
- element.style.display = 'inline';
332
+ // platform_editor_element_dnd_nested_fix_patch_2 -> inline decoration causes focus issues when refocusing Editor into first line
333
+ element.style.display = fg('platform_editor_element_dnd_nested_fix_patch_2') ? 'block' : 'inline';
333
334
  element.setAttribute('data-testid', 'block-ctrl-decorator-widget');
334
335
  element.setAttribute('data-blocks-drag-handle-container', 'true');
335
336
  var isTopLevelNode = true;
336
337
  if (editorExperiment('nested-dnd', true)) {
337
- var $pos = view.state.doc.resolve(pos);
338
- isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
338
+ var newPos = fg('platform_editor_element_dnd_nested_fix_patch_3') ? getPos() : pos;
339
+ if (typeof newPos === 'number') {
340
+ var $pos = view.state.doc.resolve(newPos);
341
+ isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
342
+ }
339
343
  /*
340
344
  * We disable mouseover event to fix flickering issue on hover
341
345
  * However, the tooltip for nested drag handle is no long working.
342
346
  */
343
- if (!isTopLevelNode) {
347
+ if (newPos === undefined || !isTopLevelNode) {
344
348
  // This will also hide the tooltip.
345
349
  unbind = bind(element, {
346
350
  type: 'mouseover',
@@ -7,11 +7,6 @@ var isEmptyNestedParagraphOrHeading = function isEmptyNestedParagraphOrHeading(t
7
7
  }
8
8
  return false;
9
9
  };
10
- var isDocFirstChildEmptyLine = function isDocFirstChildEmptyLine(elem) {
11
- var _elem$firstElementChi;
12
- var parentElement = elem.parentElement;
13
- return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
14
- };
15
10
  export var handleMouseOver = function handleMouseOver(view, event, api) {
16
11
  var _api$blockControls, _target$classList;
17
12
  var _ref = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
@@ -30,11 +25,6 @@ export var handleMouseOver = function handleMouseOver(view, event, api) {
30
25
  var rootElement = target === null || target === void 0 ? void 0 : target.closest('[data-drag-handler-anchor-name]');
31
26
  if (rootElement) {
32
27
  var _rootElement$parentEl;
33
- if (isDocFirstChildEmptyLine(rootElement) && fg('confluence_frontend_page_title_enter_improvements')) {
34
- var _api$core, _api$blockControls2;
35
- api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.hideDragHandle());
36
- return;
37
- }
38
28
  // We want to exlude handles from showing for empty paragraph and heading nodes
39
29
  if (editorExperiment('nested-dnd', true) && isEmptyNestedParagraphOrHeading(rootElement)) {
40
30
  return false;
@@ -83,8 +73,8 @@ export var handleMouseOver = function handleMouseOver(view, event, api) {
83
73
  }
84
74
  var nodeType = rootElement.getAttribute('data-drag-handler-node-type');
85
75
  if (nodeType) {
86
- var _api$core2, _api$blockControls3;
87
- api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(api === null || api === void 0 || (_api$blockControls3 = api.blockControls) === null || _api$blockControls3 === void 0 ? void 0 : _api$blockControls3.commands.showDragHandleAt(rootPos, anchorName, nodeType));
76
+ var _api$core, _api$blockControls2;
77
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.showDragHandleAt(rootPos, anchorName, nodeType));
88
78
  }
89
79
  }
90
80
  };
@@ -90,7 +90,6 @@ var initialState = {
90
90
  };
91
91
  export var newApply = function newApply(api, formatMessage, tr, currentState, newState, flags, anchorHeightsCache) {
92
92
  var _meta$activeNode, _activeNode, _activeNode2, _meta$activeNode$hand, _meta$isDragging, _meta$isDragging2, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
93
- var isTitleEnterImprovementEnabled = flags.isTitleEnterImprovementEnabled;
94
93
  var activeNode = currentState.activeNode,
95
94
  decorations = currentState.decorations,
96
95
  editorHeight = currentState.editorHeight,
@@ -170,7 +169,7 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
170
169
  var shouldRecreateHandle = latestActiveNode && (activeNodeChanged || isActiveNodeModified || editorSizeChanged || handleNeedsRedraw);
171
170
 
172
171
  // Remove handle dec when explicitly hidden, a node is resizing, activeNode pos was deleted, or DnD moved a node
173
- var shouldRemoveHandle = latestActiveNode && ((meta === null || meta === void 0 ? void 0 : meta.hideDragHandle) && isTitleEnterImprovementEnabled || isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
172
+ var shouldRemoveHandle = latestActiveNode && (isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
174
173
  if (shouldRemoveHandle) {
175
174
  var _activeNode3, _activeNode4;
176
175
  var oldHandle = findHandleDec(decorations, (_activeNode3 = activeNode) === null || _activeNode3 === void 0 ? void 0 : _activeNode3.pos, (_activeNode4 = activeNode) === null || _activeNode4 === void 0 ? void 0 : _activeNode4.pos);
@@ -222,8 +221,7 @@ export var newApply = function newApply(api, formatMessage, tr, currentState, ne
222
221
  };
223
222
  export var oldApply = function oldApply(api, formatMessage, tr, currentState, oldState, newState, flags, anchorHeightsCache) {
224
223
  var _meta$activeNode2, _meta$activeNode$hand2, _activeNodeWithNewNod, _meta$activeNode8, _meta$isDragging4, _meta$editorHeight2, _meta$editorWidthLeft2, _meta$editorWidthRigh2, _meta$isPMDragging2;
225
- var isNestedEnabled = flags.isNestedEnabled,
226
- isTitleEnterImprovementEnabled = flags.isTitleEnterImprovementEnabled;
224
+ var isNestedEnabled = flags.isNestedEnabled;
227
225
  var activeNode = currentState.activeNode,
228
226
  decorations = currentState.decorations,
229
227
  isMenuOpen = currentState.isMenuOpen,
@@ -258,7 +256,7 @@ export var oldApply = function oldApply(api, formatMessage, tr, currentState, ol
258
256
  // During resize, remove the drag handle widget so its dom positioning doesn't need to be maintained
259
257
  // Also remove the handle when the node is moved or the node count changes. This helps prevent incorrect positioning
260
258
  // Don't remove the handle if remote changes are changing the node count, its prosemirror position can be mapped instead
261
- if (meta !== null && meta !== void 0 && meta.hideDragHandle && isTitleEnterImprovementEnabled || isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
259
+ if (isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
262
260
  var oldHandle = decorations.find(undefined, undefined, function (spec) {
263
261
  return spec.type === 'drag-handle';
264
262
  });
@@ -422,11 +420,9 @@ export var createPlugin = function createPlugin(api, getIntl) {
422
420
  var isOptimisedApply = isNestedEnabled && editorExperiment('optimised-apply-dnd', true, {
423
421
  exposure: true
424
422
  });
425
- var isTitleEnterImprovementEnabled = fg('confluence_frontend_page_title_enter_improvements');
426
423
  var flags = {
427
424
  isNestedEnabled: isNestedEnabled,
428
- isOptimisedApply: isOptimisedApply,
429
- isTitleEnterImprovementEnabled: isTitleEnterImprovementEnabled
425
+ isOptimisedApply: isOptimisedApply
430
426
  };
431
427
  if (fg('platform_editor_element_dnd_nested_fix_patch_2')) {
432
428
  // TODO: Remove this once FG is used in code
@@ -22,7 +22,7 @@ export var isStepDelete = function isStepDelete(s) {
22
22
  /**
23
23
  * Get metadata from the transaction.
24
24
  * @param tr
25
- * @returns Min 'from', max 'to' (from + slice size). If no steps, returns pos range of entire doc.
25
+ * @returns Min 'from', max 'to' (from + slice size, or mapped 'to', whichever is larger). If no steps, returns pos range of entire doc.
26
26
  * Number of ReplaceStep and ReplaceAroundStep steps 'numReplaceSteps'.
27
27
  * 'isAllText' if all steps are represent adding inline text or a backspace/delete or no-op
28
28
  */
@@ -36,7 +36,9 @@ export var getTrMetadata = function getTrMetadata(tr) {
36
36
  if (s instanceof ReplaceAroundStep || s instanceof ReplaceStep && !isStepText(s) && !isStepDelete(s)) {
37
37
  isAllText = false;
38
38
  }
39
+ var mappedTo = tr.mapping.map(s.to);
39
40
  var $to = s.from + s.slice.size;
41
+ $to = $to > mappedTo ? $to : mappedTo;
40
42
  from = from === undefined || from > s.from ? s.from : from;
41
43
  to = to === undefined || to < $to ? $to : to;
42
44
  numReplaceSteps++;
@@ -10,7 +10,6 @@ export declare const key: PluginKey<PluginState>;
10
10
  export interface FlagType {
11
11
  isNestedEnabled: boolean;
12
12
  isOptimisedApply: boolean;
13
- isTitleEnterImprovementEnabled: boolean;
14
13
  }
15
14
  export declare const newApply: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, formatMessage: IntlShape['formatMessage'], tr: ReadonlyTransaction, currentState: PluginState, newState: EditorState, flags: FlagType, anchorHeightsCache?: AnchorHeightsCache) => {
16
15
  decorations: DecorationSet;
@@ -60,7 +60,6 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
60
60
  commands: {
61
61
  moveNode: (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
62
62
  showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
63
- hideDragHandle: () => EditorCommand;
64
63
  setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
65
64
  };
66
65
  }>;
@@ -21,7 +21,7 @@ export declare const isStepDelete: (s: ReplaceStep) => boolean;
21
21
  /**
22
22
  * Get metadata from the transaction.
23
23
  * @param tr
24
- * @returns Min 'from', max 'to' (from + slice size). If no steps, returns pos range of entire doc.
24
+ * @returns Min 'from', max 'to' (from + slice size, or mapped 'to', whichever is larger). If no steps, returns pos range of entire doc.
25
25
  * Number of ReplaceStep and ReplaceAroundStep steps 'numReplaceSteps'.
26
26
  * 'isAllText' if all steps are represent adding inline text or a backspace/delete or no-op
27
27
  */
@@ -10,7 +10,6 @@ export declare const key: PluginKey<PluginState>;
10
10
  export interface FlagType {
11
11
  isNestedEnabled: boolean;
12
12
  isOptimisedApply: boolean;
13
- isTitleEnterImprovementEnabled: boolean;
14
13
  }
15
14
  export declare const newApply: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, formatMessage: IntlShape['formatMessage'], tr: ReadonlyTransaction, currentState: PluginState, newState: EditorState, flags: FlagType, anchorHeightsCache?: AnchorHeightsCache) => {
16
15
  decorations: DecorationSet;
@@ -60,7 +60,6 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
60
60
  commands: {
61
61
  moveNode: (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
62
62
  showDragHandleAt: (pos: number, anchorName: string, nodeType: string, handleOptions?: HandleOptions) => EditorCommand;
63
- hideDragHandle: () => EditorCommand;
64
63
  setNodeDragged: (getPos: () => number | undefined, anchorName: string, nodeType: string) => EditorCommand;
65
64
  };
66
65
  }>;
@@ -21,7 +21,7 @@ export declare const isStepDelete: (s: ReplaceStep) => boolean;
21
21
  /**
22
22
  * Get metadata from the transaction.
23
23
  * @param tr
24
- * @returns Min 'from', max 'to' (from + slice size). If no steps, returns pos range of entire doc.
24
+ * @returns Min 'from', max 'to' (from + slice size, or mapped 'to', whichever is larger). If no steps, returns pos range of entire doc.
25
25
  * Number of ReplaceStep and ReplaceAroundStep steps 'numReplaceSteps'.
26
26
  * 'isAllText' if all steps are represent adding inline text or a backspace/delete or no-op
27
27
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "2.6.1",
3
+ "version": "2.6.3",
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": "^42.0.2",
34
- "@atlaskit/editor-common": "^93.5.0",
34
+ "@atlaskit/editor-common": "^93.6.0",
35
35
  "@atlaskit/editor-plugin-accessibility-utils": "^1.2.0",
36
36
  "@atlaskit/editor-plugin-analytics": "^1.10.0",
37
37
  "@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
@@ -48,7 +48,7 @@
48
48
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.0",
49
49
  "@atlaskit/primitives": "^12.2.0",
50
50
  "@atlaskit/theme": "^13.1.0",
51
- "@atlaskit/tmp-editor-statsig": "^2.5.0",
51
+ "@atlaskit/tmp-editor-statsig": "^2.6.0",
52
52
  "@atlaskit/tokens": "^2.0.0",
53
53
  "@atlaskit/tooltip": "^18.8.0",
54
54
  "@babel/runtime": "^7.0.0",
@@ -139,10 +139,10 @@
139
139
  "platform_editor_element_dnd_nested_fix_patch_2": {
140
140
  "type": "boolean"
141
141
  },
142
- "platform_editor_element_dnd_nested_type_error_fix": {
142
+ "platform_editor_element_dnd_nested_fix_patch_3": {
143
143
  "type": "boolean"
144
144
  },
145
- "confluence_frontend_page_title_enter_improvements": {
145
+ "platform_editor_element_dnd_nested_type_error_fix": {
146
146
  "type": "boolean"
147
147
  },
148
148
  "platform_editor_element_dnd_nested_a11y": {