@atlaskit/editor-plugin-block-controls 1.12.4 → 1.12.5

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,16 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 1.12.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#134135](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/134135)
8
+ [`4aabe1f4ad731`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/4aabe1f4ad731) -
9
+ ED-24551 Fix drop target missing at end of bodied extension nodes.
10
+ - [#133748](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/133748)
11
+ [`3d90a431f7ed8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/3d90a431f7ed8) -
12
+ Optimise node decs to prevent re-renders on doc change
13
+
3
14
  ## 1.12.4
4
15
 
5
16
  ### Patch Changes
@@ -5,20 +5,24 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.nodeDecorations = exports.emptyParagraphNodeDecorations = exports.dropTargetDecorations = exports.dragHandleDecoration = void 0;
8
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
8
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
11
  var _react = require("react");
10
12
  var _bindEventListener = require("bind-event-listener");
11
13
  var _reactDom = _interopRequireDefault(require("react-dom"));
12
14
  var _reactIntlNext = require("react-intl-next");
15
+ var _uuid = _interopRequireDefault(require("uuid"));
13
16
  var _view = require("@atlaskit/editor-prosemirror/view");
14
17
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
18
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
15
19
  var _dragHandle = require("../ui/drag-handle");
16
20
  var _dropTarget = require("../ui/drop-target");
17
21
  var _dragTargetDebug = require("../utils/drag-target-debug");
18
22
  var _validation = require("../utils/validation");
19
23
  var IGNORE_NODES = ['tableCell', 'tableHeader', 'tableRow', 'layoutColumn', 'listItem', 'caption'];
20
24
  var IGNORE_NODE_DESCENDANTS = ['listItem', 'taskList', 'decisionList', 'mediaSingle'];
21
- var PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand'];
25
+ var PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand', 'bodiedExtension'];
22
26
  var getNestedDepth = function getNestedDepth() {
23
27
  return (0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_nested') ? 100 : 0;
24
28
  };
@@ -45,7 +49,8 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
45
49
  var activePMNode = typeof activeNodePos === 'number' && newState.doc.resolve(activeNodePos).nodeAfter;
46
50
  newState.doc.nodesBetween(0, newState.doc.nodeSize - 2, function (node, pos, parent, index) {
47
51
  var depth = 0;
48
- var endDec = null;
52
+ // drop target dco at the end position
53
+ var endPosDeco = null;
49
54
  if ((0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_nested')) {
50
55
  depth = newState.doc.resolve(pos).depth;
51
56
  if (node.isInline || !parent) {
@@ -69,7 +74,7 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
69
74
  });
70
75
  if (parent.lastChild === node && PARENT_WITH_END_DROP_TARGET.includes(parent.type.name)) {
71
76
  var endpos = pos + node.nodeSize;
72
- endDec = {
77
+ endPosDeco = {
73
78
  id: endpos,
74
79
  pos: endpos
75
80
  };
@@ -92,10 +97,10 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
92
97
  nextNode: node,
93
98
  parentNode: parent
94
99
  })));
95
- if (endDec) {
96
- decs.push(createDropTargetDecoration(endDec.pos, /*#__PURE__*/(0, _react.createElement)(_dropTarget.DropTarget, {
100
+ if (endPosDeco) {
101
+ decs.push(createDropTargetDecoration(endPosDeco.pos, /*#__PURE__*/(0, _react.createElement)(_dropTarget.DropTarget, {
97
102
  api: api,
98
- id: endDec.id,
103
+ id: endPosDeco.id,
99
104
  parentNode: parent,
100
105
  formatMessage: formatMessage
101
106
  })));
@@ -149,14 +154,39 @@ var emptyParagraphNodeDecorations = exports.emptyParagraphNodeDecorations = func
149
154
  type: 'node-decoration'
150
155
  });
151
156
  };
157
+ var ObjHash = /*#__PURE__*/function () {
158
+ function ObjHash() {
159
+ (0, _classCallCheck2.default)(this, ObjHash);
160
+ }
161
+ (0, _createClass2.default)(ObjHash, null, [{
162
+ key: "getForNode",
163
+ value: function getForNode(node) {
164
+ if (this.caching.has(node)) {
165
+ return this.caching.get(node);
166
+ }
167
+ var uniqueId = (0, _uuid.default)();
168
+ this.caching.set(node, uniqueId);
169
+ return uniqueId;
170
+ }
171
+ }]);
172
+ return ObjHash;
173
+ }();
174
+ (0, _defineProperty2.default)(ObjHash, "caching", new WeakMap());
152
175
  var nodeDecorations = exports.nodeDecorations = function nodeDecorations(newState) {
153
176
  var decs = [];
154
- newState.doc.descendants(function (node, pos, parent, index) {
177
+ newState.doc.descendants(function (node, pos, _parent, index) {
155
178
  var _Decoration$node2;
156
179
  var depth = 0;
157
180
  var anchorName;
158
181
  var shouldDescend = !IGNORE_NODE_DESCENDANTS.includes(node.type.name);
182
+ if ((0, _experiments.editorExperiment)('dnd-input-performance-optimisation', true, {
183
+ exposure: true
184
+ }) || (0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_nested')) {
185
+ var handleId = ObjHash.getForNode(node);
186
+ anchorName = "--node-anchor-".concat(node.type.name, "-").concat(handleId);
187
+ }
159
188
  if ((0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_nested')) {
189
+ var _anchorName;
160
190
  // Doesn't descend into a node
161
191
  if (node.isInline) {
162
192
  return false;
@@ -165,14 +195,17 @@ var nodeDecorations = exports.nodeDecorations = function nodeDecorations(newStat
165
195
  return shouldDescend; //skip over, don't consider it a valid depth
166
196
  }
167
197
  depth = newState.doc.resolve(pos).depth;
168
- anchorName = "--node-anchor-".concat(node.type.name, "-").concat(pos);
198
+ anchorName = (_anchorName = anchorName) !== null && _anchorName !== void 0 ? _anchorName : "--node-anchor-".concat(node.type.name, "-").concat(pos);
169
199
  } else {
170
- anchorName = "--node-anchor-".concat(node.type.name, "-").concat(index);
200
+ var _anchorName2;
201
+ anchorName = (_anchorName2 = anchorName) !== null && _anchorName2 !== void 0 ? _anchorName2 : "--node-anchor-".concat(node.type.name, "-").concat(index);
171
202
  }
172
203
  decs.push(_view.Decoration.node(pos, pos + node.nodeSize, (_Decoration$node2 = {
173
204
  style: "anchor-name: ".concat(anchorName, "; ").concat(pos === 0 ? 'margin-top: 0px;' : '', "; position: relative; z-index: 1;")
174
205
  }, (0, _defineProperty2.default)(_Decoration$node2, 'data-drag-handler-anchor-name', anchorName), (0, _defineProperty2.default)(_Decoration$node2, 'data-drag-handler-node-type', node.type.name), (0, _defineProperty2.default)(_Decoration$node2, 'data-drag-handler-anchor-depth', "".concat(depth)), _Decoration$node2), {
175
- type: 'node-decoration'
206
+ type: 'node-decoration',
207
+ anchorName: anchorName,
208
+ nodeType: node.type.name
176
209
  }));
177
210
  return shouldDescend && depth < getNestedDepth();
178
211
  });
@@ -16,6 +16,7 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
16
  var _element = require("@atlaskit/pragmatic-drag-and-drop-auto-scroll/element");
17
17
  var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
18
18
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
19
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
19
20
  var _dragTargetDebug = require("../utils/drag-target-debug");
20
21
  var _decorations = require("./decorations");
21
22
  var _handleMouseOver = require("./handle-mouse-over");
@@ -100,7 +101,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
100
101
  return initialState;
101
102
  },
102
103
  apply: function apply(tr, currentState, oldState, newState) {
103
- var _meta$activeNode, _meta$activeNode$hand, _activeNodeWithNewNod, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
104
+ var _meta$activeNode, _meta$activeNode$hand, _activeNodeWithNewNod, _meta$activeNode6, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
104
105
  var activeNode = currentState.activeNode,
105
106
  decorations = currentState.decorations,
106
107
  isMenuOpen = currentState.isMenuOpen,
@@ -112,6 +113,9 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
112
113
  isDragging = currentState.isDragging,
113
114
  isPMDragging = currentState.isPMDragging,
114
115
  childCount = currentState.childCount;
116
+ var isPerformanceFix = (0, _experiments.editorExperiment)('dnd-input-performance-optimisation', true, {
117
+ exposure: true
118
+ }) || (0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_nested');
115
119
  var activeNodeWithNewNodeType = null;
116
120
  var meta = tr.getMeta(key);
117
121
  var newChildCount = tr.docChanged && (0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_nested') ? getDocChildrenCount(newState) : childCount;
@@ -171,8 +175,8 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
171
175
  // The tr.meta.activeNode is triggered by the showDragHandleAt function during the mouse entry event
172
176
  // (when the table node rerenders)
173
177
  // The activeNode is from the previous rendering cycle, and verify if they share the same anchor.
174
- var maybeNodeWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 || (_meta$activeNode = meta.activeNode) === null || _meta$activeNode === void 0 ? void 0 : _meta$activeNode.nodeType) === 'table' && meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName);
175
- var redrawDecorations = decorations === _view.DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || nodeCountChanged || maybeNodeWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
178
+ var maybeTableWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 || (_meta$activeNode = meta.activeNode) === null || _meta$activeNode === void 0 ? void 0 : _meta$activeNode.nodeType) === 'table' && (isPerformanceFix || meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName));
179
+ var redrawDecorations = decorations === _view.DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || nodeCountChanged || maybeTableWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
176
180
 
177
181
  // Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
178
182
  if (redrawDecorations && !isResizerResizing && api) {
@@ -183,10 +187,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
183
187
  decorations = decorations.remove(oldNodeDecs);
184
188
  newNodeDecs = (_newNodeDecs = newNodeDecs) !== null && _newNodeDecs !== void 0 ? _newNodeDecs : (0, _decorations.nodeDecorations)(newState);
185
189
  decorations = decorations.add(newState.doc, (0, _toConsumableArray2.default)(newNodeDecs));
186
-
187
- // Note: Quite often the handle is not in the right position after a node is moved
188
- // it is safer for now to not show it when a node is moved
189
- if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
190
+ if (activeNode && !isDecsMissing) {
190
191
  var mappedPosisiton = tr.mapping.map(activeNode.pos);
191
192
  var prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
192
193
 
@@ -196,38 +197,53 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
196
197
  mappedPosisiton = prevMappedPos;
197
198
  }
198
199
  var newActiveNode = tr.doc.nodeAt(mappedPosisiton);
199
- var nodeType = activeNode.nodeType;
200
- var anchorName = activeNode.anchorName;
201
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
202
- nodeType = newActiveNode.type.name;
203
- anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
204
- activeNodeWithNewNodeType = {
205
- pos: prevMappedPos,
206
- nodeType: nodeType,
207
- anchorName: anchorName
208
- };
200
+ var draghandleDec;
201
+ if (isPerformanceFix) {
202
+ var _meta$activeNode$pos, _meta$activeNode2, _ref9, _meta$activeNode$anch, _meta$activeNode3, _decAtPos$spec, _ref10, _meta$activeNode$node, _meta$activeNode4, _decAtPos$spec2, _meta$activeNode5;
203
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
204
+ var _oldHandle = decorations.find(undefined, undefined, function (spec) {
205
+ return spec.id === 'drag-handle';
206
+ });
207
+ decorations = decorations.remove(_oldHandle);
208
+ }
209
+ var decAtPos = newNodeDecs.find(function (dec) {
210
+ return dec.from === mappedPosisiton;
211
+ });
212
+ draghandleDec = (0, _decorations.dragHandleDecoration)(api, getIntl, (_meta$activeNode$pos = meta === null || meta === void 0 || (_meta$activeNode2 = meta.activeNode) === null || _meta$activeNode2 === void 0 ? void 0 : _meta$activeNode2.pos) !== null && _meta$activeNode$pos !== void 0 ? _meta$activeNode$pos : mappedPosisiton, (_ref9 = (_meta$activeNode$anch = meta === null || meta === void 0 || (_meta$activeNode3 = meta.activeNode) === null || _meta$activeNode3 === void 0 ? void 0 : _meta$activeNode3.anchorName) !== null && _meta$activeNode$anch !== void 0 ? _meta$activeNode$anch : decAtPos === null || decAtPos === void 0 || (_decAtPos$spec = decAtPos.spec) === null || _decAtPos$spec === void 0 ? void 0 : _decAtPos$spec.anchorName) !== null && _ref9 !== void 0 ? _ref9 : activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName, (_ref10 = (_meta$activeNode$node = meta === null || meta === void 0 || (_meta$activeNode4 = meta.activeNode) === null || _meta$activeNode4 === void 0 ? void 0 : _meta$activeNode4.nodeType) !== null && _meta$activeNode$node !== void 0 ? _meta$activeNode$node : decAtPos === null || decAtPos === void 0 || (_decAtPos$spec2 = decAtPos.spec) === null || _decAtPos$spec2 === void 0 ? void 0 : _decAtPos$spec2.nodeType) !== null && _ref10 !== void 0 ? _ref10 : activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType, meta === null || meta === void 0 || (_meta$activeNode5 = meta.activeNode) === null || _meta$activeNode5 === void 0 ? void 0 : _meta$activeNode5.handleOptions);
213
+ } else {
214
+ var nodeType = activeNode.nodeType;
215
+ var anchorName = activeNode.anchorName;
216
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
217
+ nodeType = newActiveNode.type.name;
218
+ anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
219
+ activeNodeWithNewNodeType = {
220
+ pos: prevMappedPos,
221
+ nodeType: nodeType,
222
+ anchorName: anchorName
223
+ };
224
+ }
225
+ draghandleDec = (0, _decorations.dragHandleDecoration)(api, getIntl, activeNode.pos, anchorName, nodeType);
209
226
  }
210
- var draghandleDec = (0, _decorations.dragHandleDecoration)(api, getIntl, activeNode.pos, anchorName, nodeType);
211
227
  decorations = decorations.add(newState.doc, [draghandleDec]);
212
228
  }
213
229
  }
214
230
 
215
231
  // Remove previous drag handle widget and draw new drag handle widget when activeNode changes
216
232
  if (api && meta !== null && meta !== void 0 && meta.activeNode && ((meta === null || meta === void 0 ? void 0 : meta.activeNode.pos) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) && (meta === null || meta === void 0 ? void 0 : meta.activeNode.anchorName) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName) || meta !== null && meta !== void 0 && (_meta$activeNode$hand = meta.activeNode.handleOptions) !== null && _meta$activeNode$hand !== void 0 && _meta$activeNode$hand.isFocused)) {
217
- var _oldHandle = decorations.find(undefined, undefined, function (spec) {
233
+ var _oldHandle2 = decorations.find(undefined, undefined, function (spec) {
218
234
  return spec.id === 'drag-handle';
219
235
  });
220
- decorations = decorations.remove(_oldHandle);
236
+ decorations = decorations.remove(_oldHandle2);
221
237
  var decs = (0, _decorations.dragHandleDecoration)(api, getIntl, meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType, meta.activeNode.handleOptions);
222
238
  decorations = decorations.add(newState.doc, [decs]);
223
239
  }
224
240
 
225
241
  // Remove previous drag handle widget and draw new drag handle widget when node type changes
226
- if (activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
227
- var _oldHandle2 = decorations.find(undefined, undefined, function (spec) {
242
+ if (!isPerformanceFix && activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
243
+ var _oldHandle3 = decorations.find(undefined, undefined, function (spec) {
228
244
  return spec.id === 'drag-handle';
229
245
  });
230
- decorations = decorations.remove(_oldHandle2);
246
+ decorations = decorations.remove(_oldHandle3);
231
247
  var _decs = (0, _decorations.dragHandleDecoration)(api, getIntl, activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType);
232
248
  decorations = decorations.add(newState.doc, [_decs]);
233
249
  }
@@ -261,9 +277,9 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
261
277
 
262
278
  //Map drop target decoration positions when the document changes
263
279
  if (shouldMapDropTargets) {
264
- decorationState = decorationState.map(function (_ref9) {
265
- var id = _ref9.id,
266
- pos = _ref9.pos;
280
+ decorationState = decorationState.map(function (_ref11) {
281
+ var id = _ref11.id,
282
+ pos = _ref11.pos;
267
283
  return {
268
284
  id: id,
269
285
  pos: tr.mapping.map(pos)
@@ -276,8 +292,8 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
276
292
  decorations = decorations.map(tr.mapping, tr.doc);
277
293
  }
278
294
  var isEmptyDoc = (0, _platformFeatureFlags.fg)('platform_editor_elements_dnd_nested') ? newState.doc.childCount === 1 && newState.doc.nodeSize <= 4 && (newState.doc.firstChild === null || newState.doc.firstChild.nodeSize <= 2) : newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
279
- var hasNodeDecoration = decorations.find().some(function (_ref10) {
280
- var spec = _ref10.spec;
295
+ var hasNodeDecoration = decorations.find().some(function (_ref12) {
296
+ var spec = _ref12.spec;
281
297
  return spec.type === 'node-decoration';
282
298
  });
283
299
  if (!hasNodeDecoration && isEmptyDoc) {
@@ -285,7 +301,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
285
301
  }
286
302
 
287
303
  // Map active node position when the document changes
288
- var mappedActiveNodePos = tr.docChanged && activeNode ? activeNodeWithNewNodeType || {
304
+ var mappedActiveNodePos = tr.docChanged && activeNode ? !isPerformanceFix && activeNodeWithNewNodeType || {
289
305
  pos: tr.mapping.map(activeNode.pos),
290
306
  anchorName: activeNode.anchorName,
291
307
  nodeType: activeNode.nodeType
@@ -293,7 +309,7 @@ var createPlugin = exports.createPlugin = function createPlugin(api, getIntl) {
293
309
  return {
294
310
  decorations: decorations,
295
311
  decorationState: decorationState,
296
- activeNode: isEmptyDoc || isHandleMissing ? null : (_meta$activeNode2 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode2 !== void 0 ? _meta$activeNode2 : mappedActiveNodePos,
312
+ activeNode: isEmptyDoc || isHandleMissing ? null : (_meta$activeNode6 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode6 !== void 0 ? _meta$activeNode6 : mappedActiveNodePos,
297
313
  isDragging: (_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging,
298
314
  isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
299
315
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : currentState.editorHeight,
@@ -1,16 +1,19 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import { createElement } from 'react';
2
3
  import { bind } from 'bind-event-listener';
3
4
  import ReactDOM from 'react-dom';
4
5
  import { RawIntlProvider } from 'react-intl-next';
6
+ import uuid from 'uuid';
5
7
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
6
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
7
10
  import { DragHandle } from '../ui/drag-handle';
8
11
  import { DropTarget } from '../ui/drop-target';
9
12
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
10
13
  import { canMoveNodeToIndex } from '../utils/validation';
11
14
  const IGNORE_NODES = ['tableCell', 'tableHeader', 'tableRow', 'layoutColumn', 'listItem', 'caption'];
12
15
  const IGNORE_NODE_DESCENDANTS = ['listItem', 'taskList', 'decisionList', 'mediaSingle'];
13
- const PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand'];
16
+ const PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand', 'bodiedExtension'];
14
17
  const getNestedDepth = () => fg('platform_editor_elements_dnd_nested') ? 100 : 0;
15
18
  const createDropTargetDecoration = (pos, dropTargetDec) => {
16
19
  return Decoration.widget(pos, () => {
@@ -35,7 +38,8 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode)
35
38
  const activePMNode = typeof activeNodePos === 'number' && newState.doc.resolve(activeNodePos).nodeAfter;
36
39
  newState.doc.nodesBetween(0, newState.doc.nodeSize - 2, (node, pos, parent, index) => {
37
40
  let depth = 0;
38
- let endDec = null;
41
+ // drop target dco at the end position
42
+ let endPosDeco = null;
39
43
  if (fg('platform_editor_elements_dnd_nested')) {
40
44
  depth = newState.doc.resolve(pos).depth;
41
45
  if (node.isInline || !parent) {
@@ -59,7 +63,7 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode)
59
63
  });
60
64
  if (parent.lastChild === node && PARENT_WITH_END_DROP_TARGET.includes(parent.type.name)) {
61
65
  const endpos = pos + node.nodeSize;
62
- endDec = {
66
+ endPosDeco = {
63
67
  id: endpos,
64
68
  pos: endpos
65
69
  };
@@ -82,10 +86,10 @@ export const dropTargetDecorations = (newState, api, formatMessage, activeNode)
82
86
  nextNode: node,
83
87
  parentNode: parent
84
88
  })));
85
- if (endDec) {
86
- decs.push(createDropTargetDecoration(endDec.pos, /*#__PURE__*/createElement(DropTarget, {
89
+ if (endPosDeco) {
90
+ decs.push(createDropTargetDecoration(endPosDeco.pos, /*#__PURE__*/createElement(DropTarget, {
87
91
  api,
88
- id: endDec.id,
92
+ id: endPosDeco.id,
89
93
  parentNode: parent,
90
94
  formatMessage
91
95
  })));
@@ -140,13 +144,31 @@ export const emptyParagraphNodeDecorations = () => {
140
144
  type: 'node-decoration'
141
145
  });
142
146
  };
147
+ class ObjHash {
148
+ static getForNode(node) {
149
+ if (this.caching.has(node)) {
150
+ return this.caching.get(node);
151
+ }
152
+ const uniqueId = uuid();
153
+ this.caching.set(node, uniqueId);
154
+ return uniqueId;
155
+ }
156
+ }
157
+ _defineProperty(ObjHash, "caching", new WeakMap());
143
158
  export const nodeDecorations = newState => {
144
159
  const decs = [];
145
- newState.doc.descendants((node, pos, parent, index) => {
160
+ newState.doc.descendants((node, pos, _parent, index) => {
146
161
  let depth = 0;
147
162
  let anchorName;
148
163
  const shouldDescend = !IGNORE_NODE_DESCENDANTS.includes(node.type.name);
164
+ if (editorExperiment('dnd-input-performance-optimisation', true, {
165
+ exposure: true
166
+ }) || fg('platform_editor_elements_dnd_nested')) {
167
+ const handleId = ObjHash.getForNode(node);
168
+ anchorName = `--node-anchor-${node.type.name}-${handleId}`;
169
+ }
149
170
  if (fg('platform_editor_elements_dnd_nested')) {
171
+ var _anchorName;
150
172
  // Doesn't descend into a node
151
173
  if (node.isInline) {
152
174
  return false;
@@ -155,9 +177,10 @@ export const nodeDecorations = newState => {
155
177
  return shouldDescend; //skip over, don't consider it a valid depth
156
178
  }
157
179
  depth = newState.doc.resolve(pos).depth;
158
- anchorName = `--node-anchor-${node.type.name}-${pos}`;
180
+ anchorName = (_anchorName = anchorName) !== null && _anchorName !== void 0 ? _anchorName : `--node-anchor-${node.type.name}-${pos}`;
159
181
  } else {
160
- anchorName = `--node-anchor-${node.type.name}-${index}`;
182
+ var _anchorName2;
183
+ anchorName = (_anchorName2 = anchorName) !== null && _anchorName2 !== void 0 ? _anchorName2 : `--node-anchor-${node.type.name}-${index}`;
161
184
  }
162
185
  decs.push(Decoration.node(pos, pos + node.nodeSize, {
163
186
  style: `anchor-name: ${anchorName}; ${pos === 0 ? 'margin-top: 0px;' : ''}; position: relative; z-index: 1;`,
@@ -165,7 +188,9 @@ export const nodeDecorations = newState => {
165
188
  ['data-drag-handler-node-type']: node.type.name,
166
189
  ['data-drag-handler-anchor-depth']: `${depth}`
167
190
  }, {
168
- type: 'node-decoration'
191
+ type: 'node-decoration',
192
+ anchorName,
193
+ nodeType: node.type.name
169
194
  }));
170
195
  return shouldDescend && depth < getNestedDepth();
171
196
  });
@@ -8,6 +8,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
8
8
  import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
9
9
  import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
10
10
  import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
11
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
11
12
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
12
13
  import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, nodeDecorations } from './decorations';
13
14
  import { handleMouseOver } from './handle-mouse-over';
@@ -94,7 +95,7 @@ export const createPlugin = (api, getIntl) => {
94
95
  return initialState;
95
96
  },
96
97
  apply(tr, currentState, oldState, newState) {
97
- var _meta$activeNode, _meta$activeNode$hand, _activeNodeWithNewNod, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
98
+ var _meta$activeNode, _meta$activeNode$hand, _activeNodeWithNewNod, _meta$activeNode6, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
98
99
  let {
99
100
  activeNode,
100
101
  decorations,
@@ -108,6 +109,9 @@ export const createPlugin = (api, getIntl) => {
108
109
  isPMDragging,
109
110
  childCount
110
111
  } = currentState;
112
+ const isPerformanceFix = editorExperiment('dnd-input-performance-optimisation', true, {
113
+ exposure: true
114
+ }) || fg('platform_editor_elements_dnd_nested');
111
115
  let activeNodeWithNewNodeType = null;
112
116
  const meta = tr.getMeta(key);
113
117
  const newChildCount = tr.docChanged && fg('platform_editor_elements_dnd_nested') ? getDocChildrenCount(newState) : childCount;
@@ -162,8 +166,8 @@ export const createPlugin = (api, getIntl) => {
162
166
  // The tr.meta.activeNode is triggered by the showDragHandleAt function during the mouse entry event
163
167
  // (when the table node rerenders)
164
168
  // The activeNode is from the previous rendering cycle, and verify if they share the same anchor.
165
- const maybeNodeWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 ? void 0 : (_meta$activeNode = meta.activeNode) === null || _meta$activeNode === void 0 ? void 0 : _meta$activeNode.nodeType) === 'table' && meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName);
166
- const redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || nodeCountChanged || maybeNodeWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
169
+ const maybeTableWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 ? void 0 : (_meta$activeNode = meta.activeNode) === null || _meta$activeNode === void 0 ? void 0 : _meta$activeNode.nodeType) === 'table' && (isPerformanceFix || meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName));
170
+ const redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || nodeCountChanged || maybeTableWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
167
171
 
168
172
  // Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
169
173
  if (redrawDecorations && !isResizerResizing && api) {
@@ -172,10 +176,7 @@ export const createPlugin = (api, getIntl) => {
172
176
  decorations = decorations.remove(oldNodeDecs);
173
177
  newNodeDecs = (_newNodeDecs = newNodeDecs) !== null && _newNodeDecs !== void 0 ? _newNodeDecs : nodeDecorations(newState);
174
178
  decorations = decorations.add(newState.doc, [...newNodeDecs]);
175
-
176
- // Note: Quite often the handle is not in the right position after a node is moved
177
- // it is safer for now to not show it when a node is moved
178
- if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
179
+ if (activeNode && !isDecsMissing) {
179
180
  let mappedPosisiton = tr.mapping.map(activeNode.pos);
180
181
  const prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
181
182
 
@@ -185,18 +186,29 @@ export const createPlugin = (api, getIntl) => {
185
186
  mappedPosisiton = prevMappedPos;
186
187
  }
187
188
  const newActiveNode = tr.doc.nodeAt(mappedPosisiton);
188
- let nodeType = activeNode.nodeType;
189
- let anchorName = activeNode.anchorName;
190
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
191
- nodeType = newActiveNode.type.name;
192
- anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
193
- activeNodeWithNewNodeType = {
194
- pos: prevMappedPos,
195
- nodeType,
196
- anchorName
197
- };
189
+ let draghandleDec;
190
+ if (isPerformanceFix) {
191
+ var _meta$activeNode$pos, _meta$activeNode2, _ref, _meta$activeNode$anch, _meta$activeNode3, _decAtPos$spec, _ref2, _meta$activeNode$node, _meta$activeNode4, _decAtPos$spec2, _meta$activeNode5;
192
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
193
+ const oldHandle = decorations.find(undefined, undefined, spec => spec.id === 'drag-handle');
194
+ decorations = decorations.remove(oldHandle);
195
+ }
196
+ const decAtPos = newNodeDecs.find(dec => dec.from === mappedPosisiton);
197
+ draghandleDec = dragHandleDecoration(api, getIntl, (_meta$activeNode$pos = meta === null || meta === void 0 ? void 0 : (_meta$activeNode2 = meta.activeNode) === null || _meta$activeNode2 === void 0 ? void 0 : _meta$activeNode2.pos) !== null && _meta$activeNode$pos !== void 0 ? _meta$activeNode$pos : mappedPosisiton, (_ref = (_meta$activeNode$anch = meta === null || meta === void 0 ? void 0 : (_meta$activeNode3 = meta.activeNode) === null || _meta$activeNode3 === void 0 ? void 0 : _meta$activeNode3.anchorName) !== null && _meta$activeNode$anch !== void 0 ? _meta$activeNode$anch : decAtPos === null || decAtPos === void 0 ? void 0 : (_decAtPos$spec = decAtPos.spec) === null || _decAtPos$spec === void 0 ? void 0 : _decAtPos$spec.anchorName) !== null && _ref !== void 0 ? _ref : activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName, (_ref2 = (_meta$activeNode$node = meta === null || meta === void 0 ? void 0 : (_meta$activeNode4 = meta.activeNode) === null || _meta$activeNode4 === void 0 ? void 0 : _meta$activeNode4.nodeType) !== null && _meta$activeNode$node !== void 0 ? _meta$activeNode$node : decAtPos === null || decAtPos === void 0 ? void 0 : (_decAtPos$spec2 = decAtPos.spec) === null || _decAtPos$spec2 === void 0 ? void 0 : _decAtPos$spec2.nodeType) !== null && _ref2 !== void 0 ? _ref2 : activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType, meta === null || meta === void 0 ? void 0 : (_meta$activeNode5 = meta.activeNode) === null || _meta$activeNode5 === void 0 ? void 0 : _meta$activeNode5.handleOptions);
198
+ } else {
199
+ let nodeType = activeNode.nodeType;
200
+ let anchorName = activeNode.anchorName;
201
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
202
+ nodeType = newActiveNode.type.name;
203
+ anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
204
+ activeNodeWithNewNodeType = {
205
+ pos: prevMappedPos,
206
+ nodeType,
207
+ anchorName
208
+ };
209
+ }
210
+ draghandleDec = dragHandleDecoration(api, getIntl, activeNode.pos, anchorName, nodeType);
198
211
  }
199
- const draghandleDec = dragHandleDecoration(api, getIntl, activeNode.pos, anchorName, nodeType);
200
212
  decorations = decorations.add(newState.doc, [draghandleDec]);
201
213
  }
202
214
  }
@@ -210,7 +222,7 @@ export const createPlugin = (api, getIntl) => {
210
222
  }
211
223
 
212
224
  // Remove previous drag handle widget and draw new drag handle widget when node type changes
213
- if (activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
225
+ if (!isPerformanceFix && activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
214
226
  const oldHandle = decorations.find(undefined, undefined, spec => spec.id === 'drag-handle');
215
227
  decorations = decorations.remove(oldHandle);
216
228
  const decs = dragHandleDecoration(api, getIntl, activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType);
@@ -267,7 +279,7 @@ export const createPlugin = (api, getIntl) => {
267
279
  }
268
280
 
269
281
  // Map active node position when the document changes
270
- const mappedActiveNodePos = tr.docChanged && activeNode ? activeNodeWithNewNodeType || {
282
+ const mappedActiveNodePos = tr.docChanged && activeNode ? !isPerformanceFix && activeNodeWithNewNodeType || {
271
283
  pos: tr.mapping.map(activeNode.pos),
272
284
  anchorName: activeNode.anchorName,
273
285
  nodeType: activeNode.nodeType
@@ -275,7 +287,7 @@ export const createPlugin = (api, getIntl) => {
275
287
  return {
276
288
  decorations,
277
289
  decorationState,
278
- activeNode: isEmptyDoc || isHandleMissing ? null : (_meta$activeNode2 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode2 !== void 0 ? _meta$activeNode2 : mappedActiveNodePos,
290
+ activeNode: isEmptyDoc || isHandleMissing ? null : (_meta$activeNode6 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode6 !== void 0 ? _meta$activeNode6 : mappedActiveNodePos,
279
291
  isDragging: (_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging,
280
292
  isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
281
293
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : currentState.editorHeight,
@@ -1,17 +1,21 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
1
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
4
  import { createElement } from 'react';
3
5
  import { bind } from 'bind-event-listener';
4
6
  import ReactDOM from 'react-dom';
5
7
  import { RawIntlProvider } from 'react-intl-next';
8
+ import uuid from 'uuid';
6
9
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
10
  import { fg } from '@atlaskit/platform-feature-flags';
11
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
12
  import { DragHandle } from '../ui/drag-handle';
9
13
  import { DropTarget } from '../ui/drop-target';
10
14
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
11
15
  import { canMoveNodeToIndex } from '../utils/validation';
12
16
  var IGNORE_NODES = ['tableCell', 'tableHeader', 'tableRow', 'layoutColumn', 'listItem', 'caption'];
13
17
  var IGNORE_NODE_DESCENDANTS = ['listItem', 'taskList', 'decisionList', 'mediaSingle'];
14
- var PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand'];
18
+ var PARENT_WITH_END_DROP_TARGET = ['tableCell', 'tableHeader', 'panel', 'layoutColumn', 'expand', 'nestedExpand', 'bodiedExtension'];
15
19
  var getNestedDepth = function getNestedDepth() {
16
20
  return fg('platform_editor_elements_dnd_nested') ? 100 : 0;
17
21
  };
@@ -38,7 +42,8 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
38
42
  var activePMNode = typeof activeNodePos === 'number' && newState.doc.resolve(activeNodePos).nodeAfter;
39
43
  newState.doc.nodesBetween(0, newState.doc.nodeSize - 2, function (node, pos, parent, index) {
40
44
  var depth = 0;
41
- var endDec = null;
45
+ // drop target dco at the end position
46
+ var endPosDeco = null;
42
47
  if (fg('platform_editor_elements_dnd_nested')) {
43
48
  depth = newState.doc.resolve(pos).depth;
44
49
  if (node.isInline || !parent) {
@@ -62,7 +67,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
62
67
  });
63
68
  if (parent.lastChild === node && PARENT_WITH_END_DROP_TARGET.includes(parent.type.name)) {
64
69
  var endpos = pos + node.nodeSize;
65
- endDec = {
70
+ endPosDeco = {
66
71
  id: endpos,
67
72
  pos: endpos
68
73
  };
@@ -85,10 +90,10 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
85
90
  nextNode: node,
86
91
  parentNode: parent
87
92
  })));
88
- if (endDec) {
89
- decs.push(createDropTargetDecoration(endDec.pos, /*#__PURE__*/createElement(DropTarget, {
93
+ if (endPosDeco) {
94
+ decs.push(createDropTargetDecoration(endPosDeco.pos, /*#__PURE__*/createElement(DropTarget, {
90
95
  api: api,
91
- id: endDec.id,
96
+ id: endPosDeco.id,
92
97
  parentNode: parent,
93
98
  formatMessage: formatMessage
94
99
  })));
@@ -142,14 +147,39 @@ export var emptyParagraphNodeDecorations = function emptyParagraphNodeDecoration
142
147
  type: 'node-decoration'
143
148
  });
144
149
  };
150
+ var ObjHash = /*#__PURE__*/function () {
151
+ function ObjHash() {
152
+ _classCallCheck(this, ObjHash);
153
+ }
154
+ _createClass(ObjHash, null, [{
155
+ key: "getForNode",
156
+ value: function getForNode(node) {
157
+ if (this.caching.has(node)) {
158
+ return this.caching.get(node);
159
+ }
160
+ var uniqueId = uuid();
161
+ this.caching.set(node, uniqueId);
162
+ return uniqueId;
163
+ }
164
+ }]);
165
+ return ObjHash;
166
+ }();
167
+ _defineProperty(ObjHash, "caching", new WeakMap());
145
168
  export var nodeDecorations = function nodeDecorations(newState) {
146
169
  var decs = [];
147
- newState.doc.descendants(function (node, pos, parent, index) {
170
+ newState.doc.descendants(function (node, pos, _parent, index) {
148
171
  var _Decoration$node2;
149
172
  var depth = 0;
150
173
  var anchorName;
151
174
  var shouldDescend = !IGNORE_NODE_DESCENDANTS.includes(node.type.name);
175
+ if (editorExperiment('dnd-input-performance-optimisation', true, {
176
+ exposure: true
177
+ }) || fg('platform_editor_elements_dnd_nested')) {
178
+ var handleId = ObjHash.getForNode(node);
179
+ anchorName = "--node-anchor-".concat(node.type.name, "-").concat(handleId);
180
+ }
152
181
  if (fg('platform_editor_elements_dnd_nested')) {
182
+ var _anchorName;
153
183
  // Doesn't descend into a node
154
184
  if (node.isInline) {
155
185
  return false;
@@ -158,14 +188,17 @@ export var nodeDecorations = function nodeDecorations(newState) {
158
188
  return shouldDescend; //skip over, don't consider it a valid depth
159
189
  }
160
190
  depth = newState.doc.resolve(pos).depth;
161
- anchorName = "--node-anchor-".concat(node.type.name, "-").concat(pos);
191
+ anchorName = (_anchorName = anchorName) !== null && _anchorName !== void 0 ? _anchorName : "--node-anchor-".concat(node.type.name, "-").concat(pos);
162
192
  } else {
163
- anchorName = "--node-anchor-".concat(node.type.name, "-").concat(index);
193
+ var _anchorName2;
194
+ anchorName = (_anchorName2 = anchorName) !== null && _anchorName2 !== void 0 ? _anchorName2 : "--node-anchor-".concat(node.type.name, "-").concat(index);
164
195
  }
165
196
  decs.push(Decoration.node(pos, pos + node.nodeSize, (_Decoration$node2 = {
166
197
  style: "anchor-name: ".concat(anchorName, "; ").concat(pos === 0 ? 'margin-top: 0px;' : '', "; position: relative; z-index: 1;")
167
198
  }, _defineProperty(_Decoration$node2, 'data-drag-handler-anchor-name', anchorName), _defineProperty(_Decoration$node2, 'data-drag-handler-node-type', node.type.name), _defineProperty(_Decoration$node2, 'data-drag-handler-anchor-depth', "".concat(depth)), _Decoration$node2), {
168
- type: 'node-decoration'
199
+ type: 'node-decoration',
200
+ anchorName: anchorName,
201
+ nodeType: node.type.name
169
202
  }));
170
203
  return shouldDescend && depth < getNestedDepth();
171
204
  });
@@ -9,6 +9,7 @@ import { fg } 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 { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
12
13
  import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
13
14
  import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, nodeDecorations } from './decorations';
14
15
  import { handleMouseOver } from './handle-mouse-over';
@@ -93,7 +94,7 @@ export var createPlugin = function createPlugin(api, getIntl) {
93
94
  return initialState;
94
95
  },
95
96
  apply: function apply(tr, currentState, oldState, newState) {
96
- var _meta$activeNode, _meta$activeNode$hand, _activeNodeWithNewNod, _meta$activeNode2, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
97
+ var _meta$activeNode, _meta$activeNode$hand, _activeNodeWithNewNod, _meta$activeNode6, _meta$isDragging, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
97
98
  var activeNode = currentState.activeNode,
98
99
  decorations = currentState.decorations,
99
100
  isMenuOpen = currentState.isMenuOpen,
@@ -105,6 +106,9 @@ export var createPlugin = function createPlugin(api, getIntl) {
105
106
  isDragging = currentState.isDragging,
106
107
  isPMDragging = currentState.isPMDragging,
107
108
  childCount = currentState.childCount;
109
+ var isPerformanceFix = editorExperiment('dnd-input-performance-optimisation', true, {
110
+ exposure: true
111
+ }) || fg('platform_editor_elements_dnd_nested');
108
112
  var activeNodeWithNewNodeType = null;
109
113
  var meta = tr.getMeta(key);
110
114
  var newChildCount = tr.docChanged && fg('platform_editor_elements_dnd_nested') ? getDocChildrenCount(newState) : childCount;
@@ -164,8 +168,8 @@ export var createPlugin = function createPlugin(api, getIntl) {
164
168
  // The tr.meta.activeNode is triggered by the showDragHandleAt function during the mouse entry event
165
169
  // (when the table node rerenders)
166
170
  // The activeNode is from the previous rendering cycle, and verify if they share the same anchor.
167
- var maybeNodeWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 || (_meta$activeNode = meta.activeNode) === null || _meta$activeNode === void 0 ? void 0 : _meta$activeNode.nodeType) === 'table' && meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName);
168
- var redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || nodeCountChanged || maybeNodeWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
171
+ var maybeTableWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 || (_meta$activeNode = meta.activeNode) === null || _meta$activeNode === void 0 ? void 0 : _meta$activeNode.nodeType) === 'table' && (isPerformanceFix || meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName));
172
+ var redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || nodeCountChanged || maybeTableWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
169
173
 
170
174
  // Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
171
175
  if (redrawDecorations && !isResizerResizing && api) {
@@ -176,10 +180,7 @@ export var createPlugin = function createPlugin(api, getIntl) {
176
180
  decorations = decorations.remove(oldNodeDecs);
177
181
  newNodeDecs = (_newNodeDecs = newNodeDecs) !== null && _newNodeDecs !== void 0 ? _newNodeDecs : nodeDecorations(newState);
178
182
  decorations = decorations.add(newState.doc, _toConsumableArray(newNodeDecs));
179
-
180
- // Note: Quite often the handle is not in the right position after a node is moved
181
- // it is safer for now to not show it when a node is moved
182
- if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
183
+ if (activeNode && !isDecsMissing) {
183
184
  var mappedPosisiton = tr.mapping.map(activeNode.pos);
184
185
  var prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
185
186
 
@@ -189,38 +190,53 @@ export var createPlugin = function createPlugin(api, getIntl) {
189
190
  mappedPosisiton = prevMappedPos;
190
191
  }
191
192
  var newActiveNode = tr.doc.nodeAt(mappedPosisiton);
192
- var nodeType = activeNode.nodeType;
193
- var anchorName = activeNode.anchorName;
194
- if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
195
- nodeType = newActiveNode.type.name;
196
- anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
197
- activeNodeWithNewNodeType = {
198
- pos: prevMappedPos,
199
- nodeType: nodeType,
200
- anchorName: anchorName
201
- };
193
+ var draghandleDec;
194
+ if (isPerformanceFix) {
195
+ var _meta$activeNode$pos, _meta$activeNode2, _ref9, _meta$activeNode$anch, _meta$activeNode3, _decAtPos$spec, _ref10, _meta$activeNode$node, _meta$activeNode4, _decAtPos$spec2, _meta$activeNode5;
196
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
197
+ var _oldHandle = decorations.find(undefined, undefined, function (spec) {
198
+ return spec.id === 'drag-handle';
199
+ });
200
+ decorations = decorations.remove(_oldHandle);
201
+ }
202
+ var decAtPos = newNodeDecs.find(function (dec) {
203
+ return dec.from === mappedPosisiton;
204
+ });
205
+ draghandleDec = dragHandleDecoration(api, getIntl, (_meta$activeNode$pos = meta === null || meta === void 0 || (_meta$activeNode2 = meta.activeNode) === null || _meta$activeNode2 === void 0 ? void 0 : _meta$activeNode2.pos) !== null && _meta$activeNode$pos !== void 0 ? _meta$activeNode$pos : mappedPosisiton, (_ref9 = (_meta$activeNode$anch = meta === null || meta === void 0 || (_meta$activeNode3 = meta.activeNode) === null || _meta$activeNode3 === void 0 ? void 0 : _meta$activeNode3.anchorName) !== null && _meta$activeNode$anch !== void 0 ? _meta$activeNode$anch : decAtPos === null || decAtPos === void 0 || (_decAtPos$spec = decAtPos.spec) === null || _decAtPos$spec === void 0 ? void 0 : _decAtPos$spec.anchorName) !== null && _ref9 !== void 0 ? _ref9 : activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName, (_ref10 = (_meta$activeNode$node = meta === null || meta === void 0 || (_meta$activeNode4 = meta.activeNode) === null || _meta$activeNode4 === void 0 ? void 0 : _meta$activeNode4.nodeType) !== null && _meta$activeNode$node !== void 0 ? _meta$activeNode$node : decAtPos === null || decAtPos === void 0 || (_decAtPos$spec2 = decAtPos.spec) === null || _decAtPos$spec2 === void 0 ? void 0 : _decAtPos$spec2.nodeType) !== null && _ref10 !== void 0 ? _ref10 : activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType, meta === null || meta === void 0 || (_meta$activeNode5 = meta.activeNode) === null || _meta$activeNode5 === void 0 ? void 0 : _meta$activeNode5.handleOptions);
206
+ } else {
207
+ var nodeType = activeNode.nodeType;
208
+ var anchorName = activeNode.anchorName;
209
+ if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
210
+ nodeType = newActiveNode.type.name;
211
+ anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
212
+ activeNodeWithNewNodeType = {
213
+ pos: prevMappedPos,
214
+ nodeType: nodeType,
215
+ anchorName: anchorName
216
+ };
217
+ }
218
+ draghandleDec = dragHandleDecoration(api, getIntl, activeNode.pos, anchorName, nodeType);
202
219
  }
203
- var draghandleDec = dragHandleDecoration(api, getIntl, activeNode.pos, anchorName, nodeType);
204
220
  decorations = decorations.add(newState.doc, [draghandleDec]);
205
221
  }
206
222
  }
207
223
 
208
224
  // Remove previous drag handle widget and draw new drag handle widget when activeNode changes
209
225
  if (api && meta !== null && meta !== void 0 && meta.activeNode && ((meta === null || meta === void 0 ? void 0 : meta.activeNode.pos) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) && (meta === null || meta === void 0 ? void 0 : meta.activeNode.anchorName) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName) || meta !== null && meta !== void 0 && (_meta$activeNode$hand = meta.activeNode.handleOptions) !== null && _meta$activeNode$hand !== void 0 && _meta$activeNode$hand.isFocused)) {
210
- var _oldHandle = decorations.find(undefined, undefined, function (spec) {
226
+ var _oldHandle2 = decorations.find(undefined, undefined, function (spec) {
211
227
  return spec.id === 'drag-handle';
212
228
  });
213
- decorations = decorations.remove(_oldHandle);
229
+ decorations = decorations.remove(_oldHandle2);
214
230
  var decs = dragHandleDecoration(api, getIntl, meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType, meta.activeNode.handleOptions);
215
231
  decorations = decorations.add(newState.doc, [decs]);
216
232
  }
217
233
 
218
234
  // Remove previous drag handle widget and draw new drag handle widget when node type changes
219
- if (activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
220
- var _oldHandle2 = decorations.find(undefined, undefined, function (spec) {
235
+ if (!isPerformanceFix && activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
236
+ var _oldHandle3 = decorations.find(undefined, undefined, function (spec) {
221
237
  return spec.id === 'drag-handle';
222
238
  });
223
- decorations = decorations.remove(_oldHandle2);
239
+ decorations = decorations.remove(_oldHandle3);
224
240
  var _decs = dragHandleDecoration(api, getIntl, activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType);
225
241
  decorations = decorations.add(newState.doc, [_decs]);
226
242
  }
@@ -254,9 +270,9 @@ export var createPlugin = function createPlugin(api, getIntl) {
254
270
 
255
271
  //Map drop target decoration positions when the document changes
256
272
  if (shouldMapDropTargets) {
257
- decorationState = decorationState.map(function (_ref9) {
258
- var id = _ref9.id,
259
- pos = _ref9.pos;
273
+ decorationState = decorationState.map(function (_ref11) {
274
+ var id = _ref11.id,
275
+ pos = _ref11.pos;
260
276
  return {
261
277
  id: id,
262
278
  pos: tr.mapping.map(pos)
@@ -269,8 +285,8 @@ export var createPlugin = function createPlugin(api, getIntl) {
269
285
  decorations = decorations.map(tr.mapping, tr.doc);
270
286
  }
271
287
  var isEmptyDoc = fg('platform_editor_elements_dnd_nested') ? newState.doc.childCount === 1 && newState.doc.nodeSize <= 4 && (newState.doc.firstChild === null || newState.doc.firstChild.nodeSize <= 2) : newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
272
- var hasNodeDecoration = decorations.find().some(function (_ref10) {
273
- var spec = _ref10.spec;
288
+ var hasNodeDecoration = decorations.find().some(function (_ref12) {
289
+ var spec = _ref12.spec;
274
290
  return spec.type === 'node-decoration';
275
291
  });
276
292
  if (!hasNodeDecoration && isEmptyDoc) {
@@ -278,7 +294,7 @@ export var createPlugin = function createPlugin(api, getIntl) {
278
294
  }
279
295
 
280
296
  // Map active node position when the document changes
281
- var mappedActiveNodePos = tr.docChanged && activeNode ? activeNodeWithNewNodeType || {
297
+ var mappedActiveNodePos = tr.docChanged && activeNode ? !isPerformanceFix && activeNodeWithNewNodeType || {
282
298
  pos: tr.mapping.map(activeNode.pos),
283
299
  anchorName: activeNode.anchorName,
284
300
  nodeType: activeNode.nodeType
@@ -286,7 +302,7 @@ export var createPlugin = function createPlugin(api, getIntl) {
286
302
  return {
287
303
  decorations: decorations,
288
304
  decorationState: decorationState,
289
- activeNode: isEmptyDoc || isHandleMissing ? null : (_meta$activeNode2 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode2 !== void 0 ? _meta$activeNode2 : mappedActiveNodePos,
305
+ activeNode: isEmptyDoc || isHandleMissing ? null : (_meta$activeNode6 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode6 !== void 0 ? _meta$activeNode6 : mappedActiveNodePos,
290
306
  isDragging: (_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging,
291
307
  isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
292
308
  editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : currentState.editorHeight,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "1.12.4",
3
+ "version": "1.12.5",
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
  ".": "./src/index.ts"
32
32
  },
33
33
  "dependencies": {
34
- "@atlaskit/editor-common": "^88.0.0",
34
+ "@atlaskit/editor-common": "^88.2.0",
35
35
  "@atlaskit/editor-plugin-accessibility-utils": "^1.2.0",
36
36
  "@atlaskit/editor-plugin-analytics": "^1.8.0",
37
37
  "@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
@@ -40,19 +40,21 @@
40
40
  "@atlaskit/editor-prosemirror": "5.0.1",
41
41
  "@atlaskit/editor-shared-styles": "^2.13.0",
42
42
  "@atlaskit/editor-tables": "^2.8.0",
43
- "@atlaskit/icon": "^22.14.0",
43
+ "@atlaskit/icon": "^22.15.0",
44
44
  "@atlaskit/platform-feature-flags": "^0.3.0",
45
45
  "@atlaskit/pragmatic-drag-and-drop": "^1.3.0",
46
46
  "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^1.4.0",
47
47
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.0",
48
48
  "@atlaskit/theme": "^13.0.0",
49
+ "@atlaskit/tmp-editor-statsig": "^1.3.0",
49
50
  "@atlaskit/tokens": "^1.59.0",
50
51
  "@atlaskit/tooltip": "^18.7.0",
51
52
  "@babel/runtime": "^7.0.0",
52
53
  "@emotion/react": "^11.7.1",
53
54
  "bind-event-listener": "^3.0.0",
54
55
  "memoize-one": "^6.0.0",
55
- "raf-schd": "^4.0.3"
56
+ "raf-schd": "^4.0.3",
57
+ "uuid": "^3.1.0"
56
58
  },
57
59
  "peerDependencies": {
58
60
  "react": "^16.8.0",