@atlaskit/editor-plugin-block-controls 3.19.6 → 3.19.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 3.19.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [#174199](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/174199)
8
+ [`eee50ab6df3df`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/eee50ab6df3df) -
9
+ Only create and find node decorations within the range provided
10
+ - Updated dependencies
11
+
3
12
  ## 3.19.6
4
13
 
5
14
  ### Patch Changes
@@ -49,7 +49,7 @@ var findNextAnchorDecoration = function findNextAnchorDecoration(state) {
49
49
  return undefined;
50
50
  }
51
51
  var nextHandleNode = state.doc.nodeAt(nextHandleNodePos);
52
- var nodeDecorations = nextHandleNode && (0, _decorationsAnchor.findNodeDecs)(decorations, nextHandleNodePos, nextHandleNodePos + nextHandleNode.nodeSize);
52
+ var nodeDecorations = nextHandleNode && (0, _decorationsAnchor.findNodeDecs)(state, decorations, nextHandleNodePos, nextHandleNodePos + nextHandleNode.nodeSize);
53
53
  if (!nodeDecorations || nodeDecorations.length === 0) {
54
54
  return undefined;
55
55
  }
@@ -48,46 +48,79 @@ var shouldIgnoreNode = function shouldIgnoreNode(node, ignore_nodes, depth, pare
48
48
  }
49
49
  return (isEmbedCard || isMediaSingle) && ['wrap-right', 'wrap-left'].includes(node.attrs.layout) ? true : ignore_nodes.includes(node.type.name);
50
50
  };
51
+ var getPositionBeforeNodeAtPos = function getPositionBeforeNodeAtPos(state, pos) {
52
+ if (pos <= 0 || pos >= state.doc.nodeSize - 2) {
53
+ return pos;
54
+ }
55
+ var $pos = state.doc.resolve(pos);
56
+ if ($pos.depth > 0) {
57
+ return $pos.before();
58
+ }
59
+ return pos;
60
+ };
51
61
 
52
62
  /**
53
- * Find node decorations in the pos range between from and to (non-inclusive)
54
- * @param decorations
55
- * @param from
56
- * @param to
63
+ * Find node decorations corresponding to nodes with starting position between from and to (non-inclusive)
64
+ * @param from Position to start search from (inclusive)
65
+ * @param to Position to end search at (non-inclusive)
57
66
  * @returns
58
67
  */
59
- var findNodeDecs = exports.findNodeDecs = function findNodeDecs(decorations, from, to) {
60
- var newfrom = from;
61
- var newTo = to;
68
+ var findNodeDecs = exports.findNodeDecs = function findNodeDecs(state, decorations, from, to) {
69
+ var newFrom = from;
70
+ if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true)) {
71
+ // return empty array if range reversed
72
+ if (typeof to === 'number' && typeof newFrom === 'number' && newFrom > to) {
73
+ return [];
74
+ }
75
+ var decs = decorations.find(newFrom, to, function (spec) {
76
+ return spec.type === _decorationsCommon.TYPE_NODE_DEC;
77
+ });
62
78
 
63
- // make it non-inclusive
64
- if (newfrom !== undefined) {
65
- newfrom++;
66
- }
79
+ // Prosemirror finds any decorations that overlap with the provided position range, but we don't want to include decorations of nodes that start outside of the range
80
+ if (typeof to === 'number' && typeof newFrom === 'number') {
81
+ decs = decs.filter(function (dec) {
82
+ return dec.from >= (newFrom || 0) && dec.from < to;
83
+ });
84
+ }
85
+ return decs;
86
+ } else {
87
+ var newTo = to;
67
88
 
68
- // make it non-inclusive
69
- if (newTo !== undefined) {
70
- newTo--;
71
- }
89
+ // make it non-inclusive
90
+ if (newFrom !== undefined) {
91
+ newFrom++;
92
+ }
93
+
94
+ // make it non-inclusive
95
+ if (newTo !== undefined) {
96
+ newTo--;
97
+ }
72
98
 
73
- // return empty array if range reversed
74
- if (newfrom !== undefined && newTo !== undefined && newfrom > newTo) {
75
- return [];
99
+ // return empty array if range reversed
100
+ if (newFrom !== undefined && newTo !== undefined && newFrom > newTo) {
101
+ return [];
102
+ }
103
+ return decorations.find(newFrom, newTo, function (spec) {
104
+ return spec.type === _decorationsCommon.TYPE_NODE_DEC;
105
+ });
76
106
  }
77
- return decorations.find(newfrom, newTo, function (spec) {
78
- return spec.type === _decorationsCommon.TYPE_NODE_DEC;
79
- });
80
107
  };
81
108
  var nodeDecorations = exports.nodeDecorations = function nodeDecorations(newState, from, to) {
82
109
  var decs = [];
83
110
  var docFrom = from === undefined || from < 0 ? 0 : from;
84
111
  var docTo = to === undefined || to > newState.doc.nodeSize - 2 ? newState.doc.nodeSize - 2 : to;
85
112
  var ignore_nodes = (0, _experiments.editorExperiment)('advanced_layouts', true) ? IGNORE_NODES_NEXT : IGNORE_NODES;
86
- newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, index) {
113
+ newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, _) {
87
114
  var depth = 0;
88
115
  var shouldDescend = shouldDescendIntoNode(node);
89
116
  var anchorName = (0, _decorationsCommon.getNodeAnchor)(node);
90
117
  var nodeTypeWithLevel = (0, _decorationsCommon.getNodeTypeWithLevel)(node);
118
+ if ((0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true)) {
119
+ // We don't want to create decorations for nodes that start outside of the provided position range
120
+ if (pos < getPositionBeforeNodeAtPos(newState, docFrom)) {
121
+ return shouldDescend;
122
+ }
123
+ }
91
124
 
92
125
  // Doesn't descend into a node
93
126
  if (node.isInline) {
@@ -224,9 +224,9 @@ var getDecorations = exports.getDecorations = function getDecorations(state) {
224
224
  var _key$getState;
225
225
  return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
226
226
  };
227
- var getDecorationAtPos = function getDecorationAtPos(decorations, pos, to) {
227
+ var getDecorationAtPos = function getDecorationAtPos(state, decorations, pos, to) {
228
228
  // Find the newly minted node decs that touch the active node
229
- var findNewNodeDecs = (0, _decorationsAnchor.findNodeDecs)(decorations, pos - 1, to);
229
+ var findNewNodeDecs = (0, _decorationsAnchor.findNodeDecs)(state, decorations, (0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true) ? pos : pos - 1, to);
230
230
 
231
231
  // Find the specific dec that the active node corresponds to
232
232
  var nodeDecsAtActivePos = findNewNodeDecs.filter(function (dec) {
@@ -334,14 +334,14 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
334
334
  var shouldRedrawNodeDecs = !isResizerResizing && (isNodeDecsMissing || (meta === null || meta === void 0 ? void 0 : meta.isDragging));
335
335
  var isActiveNodeModified = false;
336
336
  if (api && shouldRedrawNodeDecs) {
337
- var oldNodeDecs = (0, _decorationsAnchor.findNodeDecs)(decorations, from, to);
337
+ var oldNodeDecs = (0, _decorationsAnchor.findNodeDecs)(newState, decorations, from, to);
338
338
  decorations = decorations.remove(oldNodeDecs);
339
339
  var newNodeDecs = (0, _decorationsAnchor.nodeDecorations)(newState, isDecSetEmpty ? undefined : from, isDecSetEmpty ? undefined : to);
340
340
  decorations = decorations.add(newState.doc, newNodeDecs);
341
341
  if ((0, _experiments.editorExperiment)('platform_editor_controls', 'control')) {
342
342
  if (latestActiveNode && !isActiveNodeDeleted) {
343
343
  // Find the newly minted node decs that touch the active node
344
- var findNewNodeDecs = (0, _decorationsAnchor.findNodeDecs)(decorations, latestActiveNode.pos - 1, to);
344
+ var findNewNodeDecs = (0, _decorationsAnchor.findNodeDecs)(newState, decorations, (0, _experiments.editorExperiment)('platform_editor_block_control_optimise_render', true) ? latestActiveNode.pos : latestActiveNode.pos - 1, to);
345
345
 
346
346
  // Find the specific dec that the active node corresponds to
347
347
  var nodeDecsAtActivePos = findNewNodeDecs.filter(function (dec) {
@@ -360,8 +360,8 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
360
360
  }
361
361
  } else {
362
362
  if (latestActiveNode && (!isActiveNodeDeleted || isReplacedWithSameSize)) {
363
- var _nodeDecAtActivePos = getDecorationAtPos(decorations, latestActiveNode.pos, to);
364
- var rootNodeDecAtActivePos = getDecorationAtPos(decorations, latestActiveNode.rootPos, to);
363
+ var _nodeDecAtActivePos = getDecorationAtPos(newState, decorations, latestActiveNode.pos, to);
364
+ var rootNodeDecAtActivePos = getDecorationAtPos(newState, decorations, latestActiveNode.rootPos, to);
365
365
  if (_nodeDecAtActivePos || rootNodeDecAtActivePos) {
366
366
  isActiveNodeModified = true;
367
367
  }
@@ -400,7 +400,7 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
400
400
  // Remove handle dec when explicitly hidden, a node is resizing, activeNode pos was deleted, or DnD moved a node
401
401
  shouldRemoveHandle = latestActiveNode && (isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
402
402
  }
403
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') && (0, _platformFeatureFlags.fg)('platform_editor_controls_patch_7')) {
403
+ if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
404
404
  // Remove handle dec when editor is blurred
405
405
  shouldRemoveHandle = shouldRemoveHandle || (meta === null || meta === void 0 ? void 0 : meta.editorBlurred);
406
406
  }
@@ -467,7 +467,7 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
467
467
  }
468
468
  var isEmptyDoc = (0, _utils.isEmptyDocument)(newState.doc);
469
469
  if (isEmptyDoc) {
470
- var hasNodeDecoration = !!(0, _decorationsAnchor.findNodeDecs)(decorations).length;
470
+ var hasNodeDecoration = !!(0, _decorationsAnchor.findNodeDecs)(newState, decorations).length;
471
471
  if (!hasNodeDecoration) {
472
472
  decorations = decorations.add(newState.doc, [(0, _decorationsDragHandle.emptyParagraphNodeDecorations)()]);
473
473
  }
@@ -740,7 +740,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl, no
740
740
  }
741
741
  },
742
742
  blur: function blur(view, event) {
743
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') && (0, _platformFeatureFlags.fg)('platform_editor_controls_patch_7')) {
743
+ if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
744
744
  var _api$core2;
745
745
  var isChildOfEditor = event.relatedTarget instanceof HTMLElement && event.relatedTarget.closest("#".concat(_ui.EDIT_AREA_ID)) !== null;
746
746
 
@@ -23,7 +23,7 @@ var refreshAnchorName = exports.refreshAnchorName = function refreshAnchorName(_
23
23
  var state = _main.key.getState(view.state);
24
24
  if (state !== null && state !== void 0 && state.decorations) {
25
25
  var _node$nodeSize;
26
- var nodeDecs = (0, _decorationsAnchor.findNodeDecs)(state.decorations, pos, pos + ((_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 0));
26
+ var nodeDecs = (0, _decorationsAnchor.findNodeDecs)(view.state, state.decorations, pos, pos + ((_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 0));
27
27
  var nodeDec = nodeDecs.at(0);
28
28
  if (!nodeDec) {
29
29
  return newAnchorName;
@@ -48,7 +48,7 @@ const findNextAnchorDecoration = state => {
48
48
  return undefined;
49
49
  }
50
50
  const nextHandleNode = state.doc.nodeAt(nextHandleNodePos);
51
- let nodeDecorations = nextHandleNode && findNodeDecs(decorations, nextHandleNodePos, nextHandleNodePos + nextHandleNode.nodeSize);
51
+ let nodeDecorations = nextHandleNode && findNodeDecs(state, decorations, nextHandleNodePos, nextHandleNodePos + nextHandleNode.nodeSize);
52
52
  if (!nodeDecorations || nodeDecorations.length === 0) {
53
53
  return undefined;
54
54
  }
@@ -40,44 +40,75 @@ const shouldIgnoreNode = (node, ignore_nodes, depth, parent) => {
40
40
  }
41
41
  return (isEmbedCard || isMediaSingle) && ['wrap-right', 'wrap-left'].includes(node.attrs.layout) ? true : ignore_nodes.includes(node.type.name);
42
42
  };
43
+ const getPositionBeforeNodeAtPos = (state, pos) => {
44
+ if (pos <= 0 || pos >= state.doc.nodeSize - 2) {
45
+ return pos;
46
+ }
47
+ const $pos = state.doc.resolve(pos);
48
+ if ($pos.depth > 0) {
49
+ return $pos.before();
50
+ }
51
+ return pos;
52
+ };
43
53
 
44
54
  /**
45
- * Find node decorations in the pos range between from and to (non-inclusive)
46
- * @param decorations
47
- * @param from
48
- * @param to
55
+ * Find node decorations corresponding to nodes with starting position between from and to (non-inclusive)
56
+ * @param from Position to start search from (inclusive)
57
+ * @param to Position to end search at (non-inclusive)
49
58
  * @returns
50
59
  */
51
- export const findNodeDecs = (decorations, from, to) => {
52
- let newfrom = from;
53
- let newTo = to;
60
+ export const findNodeDecs = (state, decorations, from, to) => {
61
+ let newFrom = from;
62
+ if (editorExperiment('platform_editor_block_control_optimise_render', true)) {
63
+ // return empty array if range reversed
64
+ if (typeof to === 'number' && typeof newFrom === 'number' && newFrom > to) {
65
+ return [];
66
+ }
67
+ let decs = decorations.find(newFrom, to, spec => spec.type === TYPE_NODE_DEC);
54
68
 
55
- // make it non-inclusive
56
- if (newfrom !== undefined) {
57
- newfrom++;
58
- }
69
+ // Prosemirror finds any decorations that overlap with the provided position range, but we don't want to include decorations of nodes that start outside of the range
70
+ if (typeof to === 'number' && typeof newFrom === 'number') {
71
+ decs = decs.filter(dec => {
72
+ return dec.from >= (newFrom || 0) && dec.from < to;
73
+ });
74
+ }
75
+ return decs;
76
+ } else {
77
+ let newTo = to;
59
78
 
60
- // make it non-inclusive
61
- if (newTo !== undefined) {
62
- newTo--;
63
- }
79
+ // make it non-inclusive
80
+ if (newFrom !== undefined) {
81
+ newFrom++;
82
+ }
83
+
84
+ // make it non-inclusive
85
+ if (newTo !== undefined) {
86
+ newTo--;
87
+ }
64
88
 
65
- // return empty array if range reversed
66
- if (newfrom !== undefined && newTo !== undefined && newfrom > newTo) {
67
- return [];
89
+ // return empty array if range reversed
90
+ if (newFrom !== undefined && newTo !== undefined && newFrom > newTo) {
91
+ return [];
92
+ }
93
+ return decorations.find(newFrom, newTo, spec => spec.type === TYPE_NODE_DEC);
68
94
  }
69
- return decorations.find(newfrom, newTo, spec => spec.type === TYPE_NODE_DEC);
70
95
  };
71
96
  export const nodeDecorations = (newState, from, to) => {
72
97
  const decs = [];
73
98
  const docFrom = from === undefined || from < 0 ? 0 : from;
74
99
  const docTo = to === undefined || to > newState.doc.nodeSize - 2 ? newState.doc.nodeSize - 2 : to;
75
100
  const ignore_nodes = editorExperiment('advanced_layouts', true) ? IGNORE_NODES_NEXT : IGNORE_NODES;
76
- newState.doc.nodesBetween(docFrom, docTo, (node, pos, parent, index) => {
101
+ newState.doc.nodesBetween(docFrom, docTo, (node, pos, parent, _) => {
77
102
  let depth = 0;
78
103
  const shouldDescend = shouldDescendIntoNode(node);
79
104
  const anchorName = getNodeAnchor(node);
80
105
  const nodeTypeWithLevel = getNodeTypeWithLevel(node);
106
+ if (editorExperiment('platform_editor_block_control_optimise_render', true)) {
107
+ // We don't want to create decorations for nodes that start outside of the provided position range
108
+ if (pos < getPositionBeforeNodeAtPos(newState, docFrom)) {
109
+ return shouldDescend;
110
+ }
111
+ }
81
112
 
82
113
  // Doesn't descend into a node
83
114
  if (node.isInline) {
@@ -222,9 +222,9 @@ export const getDecorations = state => {
222
222
  var _key$getState;
223
223
  return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
224
224
  };
225
- const getDecorationAtPos = (decorations, pos, to) => {
225
+ const getDecorationAtPos = (state, decorations, pos, to) => {
226
226
  // Find the newly minted node decs that touch the active node
227
- const findNewNodeDecs = findNodeDecs(decorations, pos - 1, to);
227
+ const findNewNodeDecs = findNodeDecs(state, decorations, editorExperiment('platform_editor_block_control_optimise_render', true) ? pos : pos - 1, to);
228
228
 
229
229
  // Find the specific dec that the active node corresponds to
230
230
  const nodeDecsAtActivePos = findNewNodeDecs.filter(dec => (dec === null || dec === void 0 ? void 0 : dec.from) === pos);
@@ -335,14 +335,14 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
335
335
  const shouldRedrawNodeDecs = !isResizerResizing && (isNodeDecsMissing || (meta === null || meta === void 0 ? void 0 : meta.isDragging));
336
336
  let isActiveNodeModified = false;
337
337
  if (api && shouldRedrawNodeDecs) {
338
- const oldNodeDecs = findNodeDecs(decorations, from, to);
338
+ const oldNodeDecs = findNodeDecs(newState, decorations, from, to);
339
339
  decorations = decorations.remove(oldNodeDecs);
340
340
  const newNodeDecs = nodeDecorations(newState, isDecSetEmpty ? undefined : from, isDecSetEmpty ? undefined : to);
341
341
  decorations = decorations.add(newState.doc, newNodeDecs);
342
342
  if (editorExperiment('platform_editor_controls', 'control')) {
343
343
  if (latestActiveNode && !isActiveNodeDeleted) {
344
344
  // Find the newly minted node decs that touch the active node
345
- const findNewNodeDecs = findNodeDecs(decorations, latestActiveNode.pos - 1, to);
345
+ const findNewNodeDecs = findNodeDecs(newState, decorations, editorExperiment('platform_editor_block_control_optimise_render', true) ? latestActiveNode.pos : latestActiveNode.pos - 1, to);
346
346
 
347
347
  // Find the specific dec that the active node corresponds to
348
348
  const nodeDecsAtActivePos = findNewNodeDecs.filter(dec => (dec === null || dec === void 0 ? void 0 : dec.from) === latestActiveNode.pos);
@@ -359,8 +359,8 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
359
359
  }
360
360
  } else {
361
361
  if (latestActiveNode && (!isActiveNodeDeleted || isReplacedWithSameSize)) {
362
- const nodeDecAtActivePos = getDecorationAtPos(decorations, latestActiveNode.pos, to);
363
- const rootNodeDecAtActivePos = getDecorationAtPos(decorations, latestActiveNode.rootPos, to);
362
+ const nodeDecAtActivePos = getDecorationAtPos(newState, decorations, latestActiveNode.pos, to);
363
+ const rootNodeDecAtActivePos = getDecorationAtPos(newState, decorations, latestActiveNode.rootPos, to);
364
364
  if (nodeDecAtActivePos || rootNodeDecAtActivePos) {
365
365
  isActiveNodeModified = true;
366
366
  }
@@ -399,7 +399,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
399
399
  // Remove handle dec when explicitly hidden, a node is resizing, activeNode pos was deleted, or DnD moved a node
400
400
  shouldRemoveHandle = latestActiveNode && (isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
401
401
  }
402
- if (editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_7')) {
402
+ if (editorExperiment('platform_editor_controls', 'variant1')) {
403
403
  // Remove handle dec when editor is blurred
404
404
  shouldRemoveHandle = shouldRemoveHandle || (meta === null || meta === void 0 ? void 0 : meta.editorBlurred);
405
405
  }
@@ -467,7 +467,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
467
467
  }
468
468
  const isEmptyDoc = isEmptyDocument(newState.doc);
469
469
  if (isEmptyDoc) {
470
- const hasNodeDecoration = !!findNodeDecs(decorations).length;
470
+ const hasNodeDecoration = !!findNodeDecs(newState, decorations).length;
471
471
  if (!hasNodeDecoration) {
472
472
  decorations = decorations.add(newState.doc, [emptyParagraphNodeDecorations()]);
473
473
  }
@@ -750,7 +750,7 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI) => {
750
750
  }
751
751
  },
752
752
  blur(view, event) {
753
- if (editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_7')) {
753
+ if (editorExperiment('platform_editor_controls', 'variant1')) {
754
754
  var _api$core2;
755
755
  const isChildOfEditor = event.relatedTarget instanceof HTMLElement && event.relatedTarget.closest(`#${EDIT_AREA_ID}`) !== null;
756
756
 
@@ -18,7 +18,7 @@ export const refreshAnchorName = ({
18
18
  const state = key.getState(view.state);
19
19
  if (state !== null && state !== void 0 && state.decorations) {
20
20
  var _node$nodeSize;
21
- const nodeDecs = findNodeDecs(state.decorations, pos, pos + ((_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 0));
21
+ const nodeDecs = findNodeDecs(view.state, state.decorations, pos, pos + ((_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 0));
22
22
  const nodeDec = nodeDecs.at(0);
23
23
  if (!nodeDec) {
24
24
  return newAnchorName;
@@ -43,7 +43,7 @@ var findNextAnchorDecoration = function findNextAnchorDecoration(state) {
43
43
  return undefined;
44
44
  }
45
45
  var nextHandleNode = state.doc.nodeAt(nextHandleNodePos);
46
- var nodeDecorations = nextHandleNode && findNodeDecs(decorations, nextHandleNodePos, nextHandleNodePos + nextHandleNode.nodeSize);
46
+ var nodeDecorations = nextHandleNode && findNodeDecs(state, decorations, nextHandleNodePos, nextHandleNodePos + nextHandleNode.nodeSize);
47
47
  if (!nodeDecorations || nodeDecorations.length === 0) {
48
48
  return undefined;
49
49
  }
@@ -41,46 +41,79 @@ var shouldIgnoreNode = function shouldIgnoreNode(node, ignore_nodes, depth, pare
41
41
  }
42
42
  return (isEmbedCard || isMediaSingle) && ['wrap-right', 'wrap-left'].includes(node.attrs.layout) ? true : ignore_nodes.includes(node.type.name);
43
43
  };
44
+ var getPositionBeforeNodeAtPos = function getPositionBeforeNodeAtPos(state, pos) {
45
+ if (pos <= 0 || pos >= state.doc.nodeSize - 2) {
46
+ return pos;
47
+ }
48
+ var $pos = state.doc.resolve(pos);
49
+ if ($pos.depth > 0) {
50
+ return $pos.before();
51
+ }
52
+ return pos;
53
+ };
44
54
 
45
55
  /**
46
- * Find node decorations in the pos range between from and to (non-inclusive)
47
- * @param decorations
48
- * @param from
49
- * @param to
56
+ * Find node decorations corresponding to nodes with starting position between from and to (non-inclusive)
57
+ * @param from Position to start search from (inclusive)
58
+ * @param to Position to end search at (non-inclusive)
50
59
  * @returns
51
60
  */
52
- export var findNodeDecs = function findNodeDecs(decorations, from, to) {
53
- var newfrom = from;
54
- var newTo = to;
61
+ export var findNodeDecs = function findNodeDecs(state, decorations, from, to) {
62
+ var newFrom = from;
63
+ if (editorExperiment('platform_editor_block_control_optimise_render', true)) {
64
+ // return empty array if range reversed
65
+ if (typeof to === 'number' && typeof newFrom === 'number' && newFrom > to) {
66
+ return [];
67
+ }
68
+ var decs = decorations.find(newFrom, to, function (spec) {
69
+ return spec.type === TYPE_NODE_DEC;
70
+ });
55
71
 
56
- // make it non-inclusive
57
- if (newfrom !== undefined) {
58
- newfrom++;
59
- }
72
+ // Prosemirror finds any decorations that overlap with the provided position range, but we don't want to include decorations of nodes that start outside of the range
73
+ if (typeof to === 'number' && typeof newFrom === 'number') {
74
+ decs = decs.filter(function (dec) {
75
+ return dec.from >= (newFrom || 0) && dec.from < to;
76
+ });
77
+ }
78
+ return decs;
79
+ } else {
80
+ var newTo = to;
60
81
 
61
- // make it non-inclusive
62
- if (newTo !== undefined) {
63
- newTo--;
64
- }
82
+ // make it non-inclusive
83
+ if (newFrom !== undefined) {
84
+ newFrom++;
85
+ }
86
+
87
+ // make it non-inclusive
88
+ if (newTo !== undefined) {
89
+ newTo--;
90
+ }
65
91
 
66
- // return empty array if range reversed
67
- if (newfrom !== undefined && newTo !== undefined && newfrom > newTo) {
68
- return [];
92
+ // return empty array if range reversed
93
+ if (newFrom !== undefined && newTo !== undefined && newFrom > newTo) {
94
+ return [];
95
+ }
96
+ return decorations.find(newFrom, newTo, function (spec) {
97
+ return spec.type === TYPE_NODE_DEC;
98
+ });
69
99
  }
70
- return decorations.find(newfrom, newTo, function (spec) {
71
- return spec.type === TYPE_NODE_DEC;
72
- });
73
100
  };
74
101
  export var nodeDecorations = function nodeDecorations(newState, from, to) {
75
102
  var decs = [];
76
103
  var docFrom = from === undefined || from < 0 ? 0 : from;
77
104
  var docTo = to === undefined || to > newState.doc.nodeSize - 2 ? newState.doc.nodeSize - 2 : to;
78
105
  var ignore_nodes = editorExperiment('advanced_layouts', true) ? IGNORE_NODES_NEXT : IGNORE_NODES;
79
- newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, index) {
106
+ newState.doc.nodesBetween(docFrom, docTo, function (node, pos, parent, _) {
80
107
  var depth = 0;
81
108
  var shouldDescend = shouldDescendIntoNode(node);
82
109
  var anchorName = getNodeAnchor(node);
83
110
  var nodeTypeWithLevel = getNodeTypeWithLevel(node);
111
+ if (editorExperiment('platform_editor_block_control_optimise_render', true)) {
112
+ // We don't want to create decorations for nodes that start outside of the provided position range
113
+ if (pos < getPositionBeforeNodeAtPos(newState, docFrom)) {
114
+ return shouldDescend;
115
+ }
116
+ }
84
117
 
85
118
  // Doesn't descend into a node
86
119
  if (node.isInline) {
@@ -217,9 +217,9 @@ export var getDecorations = function getDecorations(state) {
217
217
  var _key$getState;
218
218
  return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
219
219
  };
220
- var getDecorationAtPos = function getDecorationAtPos(decorations, pos, to) {
220
+ var getDecorationAtPos = function getDecorationAtPos(state, decorations, pos, to) {
221
221
  // Find the newly minted node decs that touch the active node
222
- var findNewNodeDecs = findNodeDecs(decorations, pos - 1, to);
222
+ var findNewNodeDecs = findNodeDecs(state, decorations, editorExperiment('platform_editor_block_control_optimise_render', true) ? pos : pos - 1, to);
223
223
 
224
224
  // Find the specific dec that the active node corresponds to
225
225
  var nodeDecsAtActivePos = findNewNodeDecs.filter(function (dec) {
@@ -327,14 +327,14 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
327
327
  var shouldRedrawNodeDecs = !isResizerResizing && (isNodeDecsMissing || (meta === null || meta === void 0 ? void 0 : meta.isDragging));
328
328
  var isActiveNodeModified = false;
329
329
  if (api && shouldRedrawNodeDecs) {
330
- var oldNodeDecs = findNodeDecs(decorations, from, to);
330
+ var oldNodeDecs = findNodeDecs(newState, decorations, from, to);
331
331
  decorations = decorations.remove(oldNodeDecs);
332
332
  var newNodeDecs = nodeDecorations(newState, isDecSetEmpty ? undefined : from, isDecSetEmpty ? undefined : to);
333
333
  decorations = decorations.add(newState.doc, newNodeDecs);
334
334
  if (editorExperiment('platform_editor_controls', 'control')) {
335
335
  if (latestActiveNode && !isActiveNodeDeleted) {
336
336
  // Find the newly minted node decs that touch the active node
337
- var findNewNodeDecs = findNodeDecs(decorations, latestActiveNode.pos - 1, to);
337
+ var findNewNodeDecs = findNodeDecs(newState, decorations, editorExperiment('platform_editor_block_control_optimise_render', true) ? latestActiveNode.pos : latestActiveNode.pos - 1, to);
338
338
 
339
339
  // Find the specific dec that the active node corresponds to
340
340
  var nodeDecsAtActivePos = findNewNodeDecs.filter(function (dec) {
@@ -353,8 +353,8 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
353
353
  }
354
354
  } else {
355
355
  if (latestActiveNode && (!isActiveNodeDeleted || isReplacedWithSameSize)) {
356
- var _nodeDecAtActivePos = getDecorationAtPos(decorations, latestActiveNode.pos, to);
357
- var rootNodeDecAtActivePos = getDecorationAtPos(decorations, latestActiveNode.rootPos, to);
356
+ var _nodeDecAtActivePos = getDecorationAtPos(newState, decorations, latestActiveNode.pos, to);
357
+ var rootNodeDecAtActivePos = getDecorationAtPos(newState, decorations, latestActiveNode.rootPos, to);
358
358
  if (_nodeDecAtActivePos || rootNodeDecAtActivePos) {
359
359
  isActiveNodeModified = true;
360
360
  }
@@ -393,7 +393,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
393
393
  // Remove handle dec when explicitly hidden, a node is resizing, activeNode pos was deleted, or DnD moved a node
394
394
  shouldRemoveHandle = latestActiveNode && (isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
395
395
  }
396
- if (editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_7')) {
396
+ if (editorExperiment('platform_editor_controls', 'variant1')) {
397
397
  // Remove handle dec when editor is blurred
398
398
  shouldRemoveHandle = shouldRemoveHandle || (meta === null || meta === void 0 ? void 0 : meta.editorBlurred);
399
399
  }
@@ -460,7 +460,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
460
460
  }
461
461
  var isEmptyDoc = isEmptyDocument(newState.doc);
462
462
  if (isEmptyDoc) {
463
- var hasNodeDecoration = !!findNodeDecs(decorations).length;
463
+ var hasNodeDecoration = !!findNodeDecs(newState, decorations).length;
464
464
  if (!hasNodeDecoration) {
465
465
  decorations = decorations.add(newState.doc, [emptyParagraphNodeDecorations()]);
466
466
  }
@@ -734,7 +734,7 @@ export var createPlugin = function createPlugin(api, getIntl, nodeViewPortalProv
734
734
  }
735
735
  },
736
736
  blur: function blur(view, event) {
737
- if (editorExperiment('platform_editor_controls', 'variant1') && fg('platform_editor_controls_patch_7')) {
737
+ if (editorExperiment('platform_editor_controls', 'variant1')) {
738
738
  var _api$core2;
739
739
  var isChildOfEditor = event.relatedTarget instanceof HTMLElement && event.relatedTarget.closest("#".concat(EDIT_AREA_ID)) !== null;
740
740
 
@@ -17,7 +17,7 @@ export var refreshAnchorName = function refreshAnchorName(_ref) {
17
17
  var state = key.getState(view.state);
18
18
  if (state !== null && state !== void 0 && state.decorations) {
19
19
  var _node$nodeSize;
20
- var nodeDecs = findNodeDecs(state.decorations, pos, pos + ((_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 0));
20
+ var nodeDecs = findNodeDecs(view.state, state.decorations, pos, pos + ((_node$nodeSize = node === null || node === void 0 ? void 0 : node.nodeSize) !== null && _node$nodeSize !== void 0 ? _node$nodeSize : 0));
21
21
  var nodeDec = nodeDecs.at(0);
22
22
  if (!nodeDec) {
23
23
  return newAnchorName;
@@ -3,11 +3,10 @@ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
3
3
  import { Decoration, type DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
4
  export declare const shouldDescendIntoNode: (node: PMNode) => boolean;
5
5
  /**
6
- * Find node decorations in the pos range between from and to (non-inclusive)
7
- * @param decorations
8
- * @param from
9
- * @param to
6
+ * Find node decorations corresponding to nodes with starting position between from and to (non-inclusive)
7
+ * @param from Position to start search from (inclusive)
8
+ * @param to Position to end search at (non-inclusive)
10
9
  * @returns
11
10
  */
12
- export declare const findNodeDecs: (decorations: DecorationSet, from?: number, to?: number) => Decoration[];
11
+ export declare const findNodeDecs: (state: EditorState, decorations: DecorationSet, from?: number, to?: number) => Decoration[];
13
12
  export declare const nodeDecorations: (newState: EditorState, from?: number, to?: number) => Decoration[];
@@ -3,11 +3,10 @@ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
3
3
  import { Decoration, type DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
4
  export declare const shouldDescendIntoNode: (node: PMNode) => boolean;
5
5
  /**
6
- * Find node decorations in the pos range between from and to (non-inclusive)
7
- * @param decorations
8
- * @param from
9
- * @param to
6
+ * Find node decorations corresponding to nodes with starting position between from and to (non-inclusive)
7
+ * @param from Position to start search from (inclusive)
8
+ * @param to Position to end search at (non-inclusive)
10
9
  * @returns
11
10
  */
12
- export declare const findNodeDecs: (decorations: DecorationSet, from?: number, to?: number) => Decoration[];
11
+ export declare const findNodeDecs: (state: EditorState, decorations: DecorationSet, from?: number, to?: number) => Decoration[];
13
12
  export declare const nodeDecorations: (newState: EditorState, from?: number, to?: number) => Decoration[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "3.19.6",
3
+ "version": "3.19.7",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -56,7 +56,7 @@
56
56
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
57
57
  "@atlaskit/primitives": "^14.9.0",
58
58
  "@atlaskit/theme": "^18.0.0",
59
- "@atlaskit/tmp-editor-statsig": "^7.2.0",
59
+ "@atlaskit/tmp-editor-statsig": "^8.0.0",
60
60
  "@atlaskit/tokens": "^5.3.0",
61
61
  "@atlaskit/tooltip": "^20.3.0",
62
62
  "@babel/runtime": "^7.0.0",
@@ -162,9 +162,6 @@
162
162
  "platform_editor_controls_patch_4": {
163
163
  "type": "boolean"
164
164
  },
165
- "platform_editor_controls_patch_7": {
166
- "type": "boolean"
167
- },
168
165
  "platform_editor_no_cursor_on_live_doc_init": {
169
166
  "type": "boolean"
170
167
  },