@atlaskit/editor-plugin-block-controls 11.1.1 → 11.2.1

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.
@@ -42,16 +42,6 @@ const shouldIgnoreNode = (node, ignore_nodes, depth, parent) => {
42
42
  exposure: true
43
43
  }) ? true : ignore_nodes.includes(node.type.name);
44
44
  };
45
- const getPositionBeforeNodeAtPos = (state, pos) => {
46
- if (pos <= 0 || pos >= state.doc.nodeSize - 2) {
47
- return pos;
48
- }
49
- const $pos = state.doc.resolve(pos);
50
- if ($pos.depth > 0) {
51
- return $pos.before();
52
- }
53
- return pos;
54
- };
55
45
 
56
46
  /**
57
47
  * Find node decorations corresponding to nodes with starting position between from and to (non-inclusive)
@@ -61,39 +51,23 @@ const getPositionBeforeNodeAtPos = (state, pos) => {
61
51
  */
62
52
  export const findNodeDecs = (state, decorations, from, to) => {
63
53
  let newFrom = from;
64
- if (editorExperiment('platform_editor_block_control_optimise_render', true)) {
65
- // return empty array if range reversed
66
- if (typeof to === 'number' && typeof newFrom === 'number' && newFrom > to) {
67
- return [];
68
- }
69
- let decs = decorations.find(newFrom, to, spec => spec.type === TYPE_NODE_DEC);
54
+ let newTo = to;
70
55
 
71
- // 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
72
- if (typeof to === 'number' && typeof newFrom === 'number') {
73
- decs = decs.filter(dec => {
74
- return dec.from >= (newFrom || 0) && dec.from < to;
75
- });
76
- }
77
- return decs;
78
- } else {
79
- let newTo = to;
80
-
81
- // make it non-inclusive
82
- if (newFrom !== undefined) {
83
- newFrom++;
84
- }
56
+ // make it non-inclusive
57
+ if (newFrom !== undefined) {
58
+ newFrom++;
59
+ }
85
60
 
86
- // make it non-inclusive
87
- if (newTo !== undefined) {
88
- newTo--;
89
- }
61
+ // make it non-inclusive
62
+ if (newTo !== undefined) {
63
+ newTo--;
64
+ }
90
65
 
91
- // return empty array if range reversed
92
- if (newFrom !== undefined && newTo !== undefined && newFrom > newTo) {
93
- return [];
94
- }
95
- return decorations.find(newFrom, newTo, spec => spec.type === TYPE_NODE_DEC);
66
+ // return empty array if range reversed
67
+ if (newFrom !== undefined && newTo !== undefined && newFrom > newTo) {
68
+ return [];
96
69
  }
70
+ return decorations.find(newFrom, newTo, spec => spec.type === TYPE_NODE_DEC);
97
71
  };
98
72
  export const nodeDecorations = (newState, from, to) => {
99
73
  const decs = [];
@@ -108,12 +82,6 @@ export const nodeDecorations = (newState, from, to) => {
108
82
  const shouldDescend = shouldDescendIntoNode(node);
109
83
  const anchorName = getNodeAnchor(node);
110
84
  const 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
- }
117
85
 
118
86
  // Doesn't descend into a node
119
87
  if (node.isInline) {
@@ -34,11 +34,7 @@ export const dragHandleDecoration = ({
34
34
  anchorRectCache,
35
35
  editorState
36
36
  }) => {
37
- if (!editorExperiment('platform_editor_block_control_optimise_render', true, {
38
- exposure: true
39
- })) {
40
- unmountDecorations(nodeViewPortalProviderAPI, 'data-blocks-drag-handle-container', 'data-blocks-drag-handle-key');
41
- }
37
+ unmountDecorations(nodeViewPortalProviderAPI, 'data-blocks-drag-handle-container', 'data-blocks-drag-handle-key');
42
38
  let unbind;
43
39
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
44
40
  const key = uuid();
@@ -55,9 +51,6 @@ export const dragHandleDecoration = ({
55
51
  marks: expValEquals('platform_editor_clean_up_widget_mark_logic', 'isEnabled', true) ? [] : getActiveBlockMarks(editorState, pos),
56
52
  destroy: node => {
57
53
  unbind && unbind();
58
- if (editorExperiment('platform_editor_block_control_optimise_render', true) && node instanceof HTMLElement) {
59
- ReactDOM.unmountComponentAtNode(node);
60
- }
61
54
  }
62
55
  } : {
63
56
  side: -1,
@@ -67,9 +60,6 @@ export const dragHandleDecoration = ({
67
60
  marks: expValEquals('platform_editor_clean_up_widget_mark_logic', 'isEnabled', true) ? [] : expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? getActiveBlockMarks(editorState, pos) : undefined,
68
61
  destroy: node => {
69
62
  unbind && unbind();
70
- if (editorExperiment('platform_editor_block_control_optimise_render', true) && node instanceof HTMLElement) {
71
- ReactDOM.unmountComponentAtNode(node);
72
- }
73
63
  }
74
64
  };
75
65
  return Decoration.widget(pos, (view, getPosUnsafe) => {
@@ -7,7 +7,6 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
7
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
8
  import { QuickInsertWithVisibility } from '../ui/quick-insert-button';
9
9
  import { getActiveBlockMarks } from './utils/marks';
10
- import { createVanillaButton } from './vanilla-quick-insert';
11
10
  const TYPE_QUICK_INSERT = 'INSERT_BUTTON';
12
11
  export const findQuickInsertInsertButtonDecoration = (decorations, from, to) => {
13
12
  return decorations.find(from, to, spec => spec.type === TYPE_QUICK_INSERT);
@@ -70,23 +69,6 @@ export const quickInsertButtonDecoration = ({
70
69
  element.setAttribute('data-blocks-quick-insert-button', 'true');
71
70
  }
72
71
  element.setAttribute('data-testid', 'block-ctrl-quick-insert-button');
73
- if (editorExperiment('platform_editor_block_control_optimise_render', true, {
74
- exposure: true
75
- })) {
76
- const vanillaElement = createVanillaButton({
77
- formatMessage,
78
- api,
79
- view,
80
- getPos,
81
- cleanupCallbacks,
82
- rootAnchorName: rootAnchorName !== null && rootAnchorName !== void 0 ? rootAnchorName : nodeType,
83
- anchorName,
84
- rootNodeType: rootNodeType !== null && rootNodeType !== void 0 ? rootNodeType : nodeType,
85
- anchorRectCache
86
- });
87
- element.appendChild(vanillaElement);
88
- return element;
89
- }
90
72
  nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(QuickInsertWithVisibility, {
91
73
  api,
92
74
  getPos,
@@ -91,6 +91,19 @@ export const handleMouseOver = (view, event, api) => {
91
91
  }
92
92
  let rootElement = target === null || target === void 0 ? void 0 : target.closest(isNativeAnchorSupported ? getDefaultNodeSelector() : `[data-drag-handler-anchor-name]`);
93
93
 
94
+ // Fallback for table nodes in view mode: the table-anchor-names plugin sets data-node-anchor on
95
+ // the first <tr> element.
96
+ // - When platform_editor_native_anchor_with_dnd is disabled, the primary closest() uses
97
+ // [data-drag-handler-anchor-name] and misses table rows. Try data-node-anchor via closest().
98
+ // - For wide/max breakout tables, hovering in the left/right margin area of the full-viewport-
99
+ // width breakout wrapper (ak-editor-breakout-mark) sets event.target to the wrapper div, which
100
+ // has no anchor attribute. Use querySelector to find the [data-node-anchor] descendant inside.
101
+ // Both cases apply only in view mode with right-side remix controls.
102
+ if (!rootElement && isViewMode && rightSideControlsEnabled) {
103
+ var _ref, _target$closest;
104
+ rootElement = (_ref = (_target$closest = target === null || target === void 0 ? void 0 : target.closest(`[${NODE_ANCHOR_ATTR_NAME}]`)) !== null && _target$closest !== void 0 ? _target$closest : target instanceof HTMLElement ? target.querySelector(`[${NODE_ANCHOR_ATTR_NAME}]`) : null) !== null && _ref !== void 0 ? _ref : null;
105
+ }
106
+
94
107
  // When hovering over the right-edge button (rendered in a portal outside the block), resolve the
95
108
  // block from the container's anchor so activeNode stays set and the button remains visible.
96
109
  if (!rootElement && rightSideControlsEnabled && fg('confluence_remix_button_right_side_block_fg')) {
@@ -103,7 +116,7 @@ export const handleMouseOver = (view, event, api) => {
103
116
  }
104
117
  }
105
118
  if (rootElement) {
106
- var _rootElement$parentEl;
119
+ var _rootElement$parentEl, _rootElement$getAttri2;
107
120
  // We want to exlude handles from showing for empty paragraph and heading nodes
108
121
  if (isEmptyNestedParagraphOrHeading(rootElement)) {
109
122
  return false;
@@ -176,6 +189,11 @@ export const handleMouseOver = (view, event, api) => {
176
189
  // Ignored via go/ees005
177
190
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
178
191
  anchorName = rootElement.getAttribute(getAnchorAttrName());
192
+ // Fallback for table nodes that only have data-node-anchor (not data-drag-handler-anchor-name).
193
+ if (!anchorName) {
194
+ var _rootElement$getAttri;
195
+ anchorName = (_rootElement$getAttri = rootElement.getAttribute(NODE_ANCHOR_ATTR_NAME)) !== null && _rootElement$getAttri !== void 0 ? _rootElement$getAttri : anchorName;
196
+ }
179
197
  }
180
198
 
181
199
  // No need to update handle position if its already there
@@ -223,13 +241,16 @@ export const handleMouseOver = (view, event, api) => {
223
241
  if (targetPos !== rootPos) {
224
242
  const rootDOM = view.nodeDOM(rootPos);
225
243
  if (rootDOM instanceof HTMLElement) {
226
- var _rootDOM$getAttribute;
227
- rootAnchorName = (_rootDOM$getAttribute = rootDOM.getAttribute(getAnchorAttrName())) !== null && _rootDOM$getAttribute !== void 0 ? _rootDOM$getAttribute : undefined;
228
- rootNodeType = isNativeAnchorSupported ? getTypeNameFromDom(rootDOM) : rootDOM.getAttribute('data-drag-handler-node-type');
244
+ var _ref2, _rootDOM$getAttribute, _rootDOM$getAttribute2;
245
+ rootAnchorName = (_ref2 = (_rootDOM$getAttribute = rootDOM.getAttribute(getAnchorAttrName())) !== null && _rootDOM$getAttribute !== void 0 ? _rootDOM$getAttribute : rootDOM.getAttribute(NODE_ANCHOR_ATTR_NAME)) !== null && _ref2 !== void 0 ? _ref2 : undefined;
246
+ rootNodeType = isNativeAnchorSupported ? getTypeNameFromDom(rootDOM) : // Fallback: breakout mark wrappers have no data-drag-handler-node-type;
247
+ // use data-prosemirror-node-name instead.
248
+ (_rootDOM$getAttribute2 = rootDOM.getAttribute('data-drag-handler-node-type')) !== null && _rootDOM$getAttribute2 !== void 0 ? _rootDOM$getAttribute2 : getTypeNameFromDom(rootDOM);
229
249
  }
230
250
  }
231
251
  }
232
- const nodeType = isNativeAnchorSupported ? getTypeNameFromDom(rootElement) : rootElement.getAttribute('data-drag-handler-node-type');
252
+ const nodeType = isNativeAnchorSupported ? getTypeNameFromDom(rootElement) : // Fallback for table nodes: tr has data-prosemirror-node-name but not data-drag-handler-node-type.
253
+ (_rootElement$getAttri2 = rootElement.getAttribute('data-drag-handler-node-type')) !== null && _rootElement$getAttri2 !== void 0 ? _rootElement$getAttri2 : getTypeNameFromDom(rootElement);
233
254
  if (nodeType) {
234
255
  // platform_editor_controls note: enables quick insert
235
256
  if (toolbarFlagsEnabled) {
@@ -1,4 +1,5 @@
1
1
  import rafSchedule from 'raf-schd';
2
+ import { getDocument } from '@atlaskit/browser-apis';
2
3
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
3
4
  import { getBrowserInfo } from '@atlaskit/editor-common/browser';
4
5
  import { getNodeIdProvider } from '@atlaskit/editor-common/node-anchor';
@@ -44,7 +45,8 @@ const isHTMLElement = element => {
44
45
  return element instanceof HTMLElement;
45
46
  };
46
47
  const destroyFn = (api, editorView) => {
47
- const scrollable = document.querySelector('.fabric-editor-popup-scroll-parent');
48
+ var _getDocument$querySel, _getDocument;
49
+ const scrollable = (_getDocument$querySel = (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.querySelector('.fabric-editor-popup-scroll-parent')) !== null && _getDocument$querySel !== void 0 ? _getDocument$querySel : null;
48
50
  const cleanupFn = [];
49
51
  if (scrollable) {
50
52
  cleanupFn.push(autoScrollForElements({
@@ -224,7 +226,7 @@ export const getDecorations = state => {
224
226
  };
225
227
  const getDecorationAtPos = (state, decorations, pos, to) => {
226
228
  // Find the newly minted node decs that touch the active node
227
- const findNewNodeDecs = findNodeDecs(state, decorations, editorExperiment('platform_editor_block_control_optimise_render', true) ? pos : pos - 1, to);
229
+ const findNewNodeDecs = findNodeDecs(state, decorations, pos - 1, to);
228
230
 
229
231
  // Find the specific dec that the active node corresponds to
230
232
  const nodeDecsAtActivePos = findNewNodeDecs.filter(dec => (dec === null || dec === void 0 ? void 0 : dec.from) === pos);
@@ -266,10 +268,11 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
266
268
  const meta = tr.getMeta(key);
267
269
  const hasDocumentSizeBreachedThreshold = api === null || api === void 0 ? void 0 : (_api$limitedMode = api.limitedMode) === null || _api$limitedMode === void 0 ? void 0 : (_api$limitedMode$shar = _api$limitedMode.sharedState.currentState()) === null || _api$limitedMode$shar === void 0 ? void 0 : (_api$limitedMode$shar2 = _api$limitedMode$shar.limitedModePluginKey.getState(newState)) === null || _api$limitedMode$shar2 === void 0 ? void 0 : _api$limitedMode$shar2.documentSizeBreachesThreshold;
268
270
  if (hasDocumentSizeBreachedThreshold) {
271
+ var _getDocument$querySel2, _getDocument2;
269
272
  /**
270
273
  * INFO: This if statement is a duplicate of the logic in destroy(). When the threshold is breached and we enter limited mode, we want to trigger the cleanup logic in destroy().
271
274
  */
272
- const editorContentArea = document.querySelector('.fabric-editor-popup-scroll-parent');
275
+ const editorContentArea = (_getDocument$querySel2 = (_getDocument2 = getDocument()) === null || _getDocument2 === void 0 ? void 0 : _getDocument2.querySelector('.fabric-editor-popup-scroll-parent')) !== null && _getDocument$querySel2 !== void 0 ? _getDocument$querySel2 : null;
273
276
  if (editorContentArea && resizeObserverWidth) {
274
277
  resizeObserverWidth.unobserve(editorContentArea);
275
278
  }
@@ -369,7 +372,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
369
372
  if (!flags.toolbarFlagsEnabled) {
370
373
  if (latestActiveNode && !isActiveNodeDeleted) {
371
374
  // Find the newly minted node decs that touch the active node
372
- const findNewNodeDecs = findNodeDecs(newState, decorations, editorExperiment('platform_editor_block_control_optimise_render', true) ? latestActiveNode.pos : latestActiveNode.pos - 1, to);
375
+ const findNewNodeDecs = findNodeDecs(newState, decorations, latestActiveNode.pos - 1, to);
373
376
 
374
377
  // Find the specific dec that the active node corresponds to
375
378
  const nodeDecsAtActivePos = findNewNodeDecs.filter(dec => (dec === null || dec === void 0 ? void 0 : dec.from) === latestActiveNode.pos);
@@ -430,6 +433,16 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
430
433
  // Remove handle dec when editor is blurred
431
434
  shouldRemoveHandle = shouldRemoveHandle || (meta === null || meta === void 0 ? void 0 : meta.editorBlurred);
432
435
  }
436
+
437
+ // In view mode with right-side controls, remove any lingering drag handle decorations
438
+ // (they may carry over from edit mode). Only remove drag handles specifically, not
439
+ // the remix button decorations (those are managed separately via showInViewMode).
440
+ if (isViewMode && rightSideControlsEnabled) {
441
+ const allHandleDecs = findHandleDec(decorations, 0, newState.doc.content.size);
442
+ if (allHandleDecs.length > 0) {
443
+ decorations = decorations.remove(allHandleDecs);
444
+ }
445
+ }
433
446
  if (shouldRemoveHandle) {
434
447
  var _activeNode5, _activeNode6;
435
448
  const oldHandle = findHandleDec(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.pos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.pos);
@@ -705,7 +718,7 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI, nodeDecora
705
718
  },
706
719
  props: {
707
720
  decorations: state => {
708
- var _api$limitedMode2, _api$limitedMode2$sha, _api$editorDisabled, _api$editorDisabled$s, _key$getState2;
721
+ var _api$limitedMode2, _api$limitedMode2$sha, _api$editorDisabled, _api$editorDisabled$s, _key$getState2, _api$editorViewMode3, _api$editorViewMode3$;
709
722
  if (api !== null && api !== void 0 && (_api$limitedMode2 = api.limitedMode) !== null && _api$limitedMode2 !== void 0 && (_api$limitedMode2$sha = _api$limitedMode2.sharedState.currentState()) !== null && _api$limitedMode2$sha !== void 0 && _api$limitedMode2$sha.enabled) {
710
723
  return;
711
724
  }
@@ -718,7 +731,16 @@ export const createPlugin = (api, getIntl, nodeViewPortalProviderAPI, nodeDecora
718
731
  return;
719
732
  }
720
733
  }
721
- return (_key$getState2 = key.getState(state)) === null || _key$getState2 === void 0 ? void 0 : _key$getState2.decorations;
734
+ let decorationSet = (_key$getState2 = key.getState(state)) === null || _key$getState2 === void 0 ? void 0 : _key$getState2.decorations;
735
+ // In view mode with right-side controls, remove any lingering drag-handle decorations
736
+ // (created in edit mode) that may not have been cleaned up on mode switch.
737
+ if (decorationSet && rightSideControlsEnabled && (api === null || api === void 0 ? void 0 : (_api$editorViewMode3 = api.editorViewMode) === null || _api$editorViewMode3 === void 0 ? void 0 : (_api$editorViewMode3$ = _api$editorViewMode3.sharedState.currentState()) === null || _api$editorViewMode3$ === void 0 ? void 0 : _api$editorViewMode3$.mode) === 'view') {
738
+ const handleDecs = findHandleDec(decorationSet, 0, state.doc.content.size);
739
+ if (handleDecs.length > 0) {
740
+ decorationSet = decorationSet.remove(handleDecs);
741
+ }
742
+ }
743
+ return decorationSet;
722
744
  },
723
745
  handleDOMEvents: {
724
746
  drop(view, event) {
@@ -350,7 +350,6 @@ export const DragHandle = ({
350
350
  const [dragHandleSelected, setDragHandleSelected] = useState(false);
351
351
  const [dragHandleDisabled, setDragHandleDisabled] = useState(false);
352
352
  const [blockCardWidth, setBlockCardWidth] = useState(768);
353
- const [recalculatePosition, setRecalculatePosition] = useState(false);
354
353
  const [positionStylesOld, setPositionStylesOld] = useState({
355
354
  display: 'none'
356
355
  });
@@ -391,9 +390,6 @@ export const DragHandle = ({
391
390
  // just rely on the dynamic value (rename it to isTopLevelNode for simplicitiy)
392
391
  const isTopLevelNodeValue = expValEquals('platform_editor_nested_drag_handle_icon', 'isEnabled', true) ? isTopLevelNodeDynamic : isTopLevelNode;
393
392
  useEffect(() => {
394
- if (editorExperiment('platform_editor_block_control_optimise_render', true)) {
395
- return;
396
- }
397
393
  // blockCard/datasource width is rendered correctly after this decoraton does. We need to observe for changes.
398
394
  if (nodeType === 'blockCard') {
399
395
  const dom = view.dom.querySelector(`[${getAnchorAttrName()}="${anchorName}"]`);
@@ -788,62 +784,6 @@ export const DragHandle = ({
788
784
  }
789
785
  });
790
786
  }, [anchorName, api, getPos, isMultiSelect, nodeType, start, view]);
791
- const positionStyles = useMemo(() => {
792
- if (!editorExperiment('platform_editor_block_control_optimise_render', true)) {
793
- return {};
794
- }
795
-
796
- // This is a no-op to allow recalculatePosition to be used as a dependency
797
- if (recalculatePosition) {
798
- setRecalculatePosition(recalculatePosition);
799
- }
800
- const pos = getPos();
801
- const $pos = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? typeof pos === 'number' && view.state.doc.resolve(pos) : pos && view.state.doc.resolve(pos);
802
- const parentPos = $pos && $pos.depth ? $pos.before() : undefined;
803
- const node = parentPos !== undefined ? view.state.doc.nodeAt(parentPos) : undefined;
804
- const parentNodeType = node === null || node === void 0 ? void 0 : node.type.name;
805
- const supportsAnchor = CSS.supports('top', `anchor(${anchorName} start)`) && CSS.supports('left', `anchor(${anchorName} start)`);
806
- const safeAnchorName = editorExperiment('platform_editor_controls', 'variant1') ? refreshAnchorName({
807
- getPos,
808
- view,
809
- anchorName
810
- }) : anchorName;
811
- const dom = view.dom.querySelector(`[${getAnchorAttrName()}="${safeAnchorName}"]`);
812
- const hasResizer = nodeType === 'table' || nodeType === 'mediaSingle';
813
- const isExtension = nodeType === 'extension' || nodeType === 'bodiedExtension' || nodeType === 'multiBodiedExtension';
814
- const isBlockCard = nodeType === 'blockCard';
815
- const isEmbedCard = nodeType === 'embedCard';
816
- const isMacroInteractionUpdates = macroInteractionUpdates && isExtension;
817
- let innerContainer = null;
818
- if (dom) {
819
- if (isEmbedCard) {
820
- innerContainer = dom.querySelector('.rich-media-item');
821
- } else if (hasResizer) {
822
- innerContainer = dom.querySelector('.resizer-item');
823
- } else if (isExtension) {
824
- innerContainer = dom.querySelector('.extension-container[data-layout]');
825
- } else if (isBlockCard) {
826
- //specific to datasource blockCard
827
- innerContainer = dom.querySelector('.datasourceView-content-inner-wrap');
828
- }
829
- }
830
- const isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
831
- const isSticky = shouldBeSticky(nodeType);
832
- if (supportsAnchor) {
833
- const bottom = editorExperiment('platform_editor_controls', 'variant1') ? getControlBottomCSSValue(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn) : {};
834
- return {
835
- left: isEdgeCase ? `calc(anchor(${safeAnchorName} start) + ${getLeftPosition(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType)})` : editorExperiment('advanced_layouts', true) && isLayoutColumn ? `calc((anchor(${safeAnchorName} right) + anchor(${safeAnchorName} left))/2 - ${DRAG_HANDLE_HEIGHT / 2}px)` : `calc(anchor(${safeAnchorName} start) - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType, parentNodeType)}px)`,
836
- top: editorExperiment('advanced_layouts', true) && isLayoutColumn ? `calc(anchor(${safeAnchorName} top) - ${DRAG_HANDLE_WIDTH}px)` : `calc(anchor(${safeAnchorName} start) + ${topPositionAdjustment(expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? $pos && $pos.nodeAfter && getNodeTypeWithLevel($pos.nodeAfter) || nodeType : nodeType, (dom === null || dom === void 0 ? void 0 : dom.getAttribute('layout')) || '')}px)`,
837
- ...bottom
838
- };
839
- }
840
- const height = editorExperiment('platform_editor_controls', 'variant1') ? getControlHeightCSSValue(getNodeHeight(dom, safeAnchorName, anchorRectCache) || 0, isSticky, isTopLevelNodeValue, `${DRAG_HANDLE_HEIGHT}`, isLayoutColumn) : {};
841
- return {
842
- left: isEdgeCase ? `calc(${(dom === null || dom === void 0 ? void 0 : dom.offsetLeft) || 0}px + ${getLeftPosition(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType)})` : getLeftPosition(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType),
843
- top: getTopPosition(dom, nodeType),
844
- ...height
845
- };
846
- }, [anchorName, getPos, view, nodeType, macroInteractionUpdates, anchorRectCache, isTopLevelNodeValue, isLayoutColumn, recalculatePosition]);
847
787
  const calculatePositionOld = useCallback(() => {
848
788
  const pos = getPos();
849
789
  const $pos = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? typeof pos === 'number' && view.state.doc.resolve(pos) : pos && view.state.doc.resolve(pos);
@@ -893,9 +833,6 @@ export const DragHandle = ({
893
833
  };
894
834
  }, [anchorName, getPos, view, nodeType, blockCardWidth, macroInteractionUpdates, anchorRectCache, isTopLevelNodeValue, isLayoutColumn]);
895
835
  useEffect(() => {
896
- if (editorExperiment('platform_editor_block_control_optimise_render', true)) {
897
- return;
898
- }
899
836
  let cleanUpTransitionListener;
900
837
  if (nodeType === 'extension' || nodeType === 'embedCard') {
901
838
  const dom = view.dom.querySelector(`[${getAnchorAttrName()}="${anchorName}"]`);
@@ -918,28 +855,6 @@ export const DragHandle = ({
918
855
  (_cleanUpTransitionLis = cleanUpTransitionListener) === null || _cleanUpTransitionLis === void 0 ? void 0 : _cleanUpTransitionLis();
919
856
  };
920
857
  }, [calculatePositionOld, view.dom, anchorName, nodeType]);
921
- useEffect(() => {
922
- if (!editorExperiment('platform_editor_block_control_optimise_render', true)) {
923
- return;
924
- }
925
- let cleanUpTransitionListener;
926
- if (nodeType === 'extension' || nodeType === 'embedCard') {
927
- const dom = view.dom.querySelector(`[${getAnchorAttrName()}="${anchorName}"]`);
928
- if (!dom) {
929
- return;
930
- }
931
- cleanUpTransitionListener = bind(dom, {
932
- type: 'transitionend',
933
- listener: () => {
934
- setRecalculatePosition(!recalculatePosition);
935
- }
936
- });
937
- }
938
- return () => {
939
- var _cleanUpTransitionLis2;
940
- (_cleanUpTransitionLis2 = cleanUpTransitionListener) === null || _cleanUpTransitionLis2 === void 0 ? void 0 : _cleanUpTransitionLis2();
941
- };
942
- }, [view, anchorName, nodeType, recalculatePosition]);
943
858
  useEffect(() => {
944
859
  if (handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && buttonRef.current) {
945
860
  const id = requestAnimationFrame(() => {
@@ -948,9 +863,7 @@ export const DragHandle = ({
948
863
  });
949
864
  return () => {
950
865
  cancelAnimationFrame(id);
951
- if (!editorExperiment('platform_editor_block_control_optimise_render', true)) {
952
- view.focus();
953
- }
866
+ view.focus();
954
867
  };
955
868
  }
956
869
  }, [buttonRef, handleOptions === null || handleOptions === void 0 ? void 0 : handleOptions.isFocused, view]);
@@ -1065,7 +978,7 @@ export const DragHandle = ({
1065
978
  ref: buttonRef
1066
979
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
1067
980
  ,
1068
- style: !editorExperiment('platform_editor_controls', 'variant1') ? editorExperiment('platform_editor_block_control_optimise_render', true) ? positionStyles : positionStylesOld : {},
981
+ style: !editorExperiment('platform_editor_controls', 'variant1') ? positionStylesOld : {},
1069
982
  onMouseDown: expValEqualsNoExposure('platform_editor_selection_toolbar_block_handle', 'isEnabled', true) ? handleMouseDown : undefined,
1070
983
  onMouseUp: editorExperiment('platform_editor_block_menu', true) ? handleMouseUp : undefined,
1071
984
  onClick: editorExperiment('platform_editor_block_menu', true) ? handleOnClickNew : handleOnClick,
@@ -1117,7 +1030,7 @@ export const DragHandle = ({
1117
1030
  const stickyWithTooltip = () => jsx(Box
1118
1031
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
1119
1032
  , {
1120
- style: editorExperiment('platform_editor_block_control_optimise_render', true) ? positionStyles : positionStylesOld
1033
+ style: positionStylesOld
1121
1034
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
1122
1035
  ,
1123
1036
  xcss: [dragHandleContainerStyles],
@@ -1145,7 +1058,7 @@ export const DragHandle = ({
1145
1058
  const stickyWithoutTooltip = () => jsx(Box
1146
1059
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
1147
1060
  , {
1148
- style: editorExperiment('platform_editor_block_control_optimise_render', true) ? positionStyles : positionStylesOld
1061
+ style: positionStylesOld
1149
1062
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
1150
1063
  ,
1151
1064
  xcss: [dragHandleContainerStyles],
@@ -5,11 +5,10 @@
5
5
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
6
6
  import { css, Global, jsx } from '@emotion/react';
7
7
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
8
- import { ANCHOR_VARIABLE_NAME, DRAG_HANDLE_WIDTH, isCSSAnchorSupported, tableControlsSpacing } from '@atlaskit/editor-common/styles';
8
+ import { ANCHOR_VARIABLE_NAME, DRAG_HANDLE_WIDTH, isCSSAnchorSupported } from '@atlaskit/editor-common/styles';
9
9
  import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
10
10
  import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
11
11
  import { akEditorBreakoutPadding, akEditorCalculatedWideLayoutWidth, akEditorCalculatedWideLayoutWidthSmallViewport, akEditorFullPageNarrowBreakout, akEditorGutterPaddingDynamic, akEditorGutterPaddingReduced } from '@atlaskit/editor-shared-styles';
12
- import { layers } from '@atlaskit/theme/constants';
13
12
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
13
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
15
14
  import { DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
@@ -301,87 +300,6 @@ const globalStyles = () => css({
301
300
  marginTop: '0 !important'
302
301
  }
303
302
  });
304
- const quickInsertStyles = () => css({
305
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
306
- '.blocks-quick-insert-button': {
307
- backgroundColor: 'transparent',
308
- top: `var(--top-override,8px)`,
309
- position: 'sticky',
310
- boxSizing: 'border-box',
311
- display: 'flex',
312
- flexDirection: 'column',
313
- justifyContent: 'center',
314
- alignItems: 'center',
315
- height: "var(--ds-space-300, 24px)",
316
- width: "var(--ds-space-300, 24px)",
317
- border: 'none',
318
- borderRadius: "var(--ds-radius-full, 9999px)",
319
- zIndex: layers.card(),
320
- outline: 'none',
321
- cursor: 'pointer',
322
- color: "var(--ds-icon-subtle, #505258)"
323
- },
324
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
325
- '[data-blocks-quick-insert-container]:has(~ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
326
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
327
- '--top-override': `${tableControlsSpacing}px`
328
- },
329
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
330
- '[data-prosemirror-mark-name="breakout"]:has([data-blocks-quick-insert-container]):has(~ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
331
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
332
- '--top-override': `${tableControlsSpacing}px`
333
- },
334
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
335
- '.blocks-quick-insert-button:hover': {
336
- backgroundColor: "var(--ds-background-neutral-subtle-hovered, #0515240F)"
337
- },
338
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
339
- '.blocks-quick-insert-button:active': {
340
- backgroundColor: "var(--ds-background-neutral-subtle-pressed, #0B120E24)"
341
- },
342
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
343
- '.blocks-quick-insert-button:focus': {
344
- outline: `${"var(--ds-border-width-focused, 2px)"} solid ${"var(--ds-border-focused, #4688EC)"}`
345
- },
346
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
347
- '.blocks-quick-insert-visible-container': {
348
- transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out',
349
- opacity: 1,
350
- visibility: 'visible'
351
- },
352
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
353
- '.blocks-quick-insert-invisible-container': {
354
- transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out',
355
- opacity: 0,
356
- visibility: 'hidden'
357
- },
358
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
359
- '.blocks-quick-insert-tooltip': {
360
- zIndex: layers.tooltip(),
361
- borderRadius: "var(--ds-radius-small, 4px)",
362
- padding: `${"var(--ds-space-050, 4px)"} 0`,
363
- boxSizing: 'border-box',
364
- maxWidth: '240px',
365
- backgroundColor: "var(--ds-background-neutral-bold, #292A2E)",
366
- color: "var(--ds-text-inverse, #FFFFFF)",
367
- font: "var(--ds-font-body-small, normal 400 12px/16px \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
368
- insetBlockStart: "var(--ds-space-0, 0px)",
369
- insetInlineStart: "var(--ds-space-0, 0px)",
370
- overflowWrap: 'break-word',
371
- paddingBlockEnd: "var(--ds-space-025, 2px)",
372
- paddingBlockStart: "var(--ds-space-025, 2px)",
373
- paddingInlineEnd: "var(--ds-space-075, 6px)",
374
- paddingInlineStart: "var(--ds-space-075, 6px)",
375
- wordWrap: 'break-word',
376
- pointerEvents: 'none',
377
- userSelect: 'none',
378
- // Based on: platform/packages/design-system/motion/src/entering/keyframes-motion.tsx
379
- transition: 'opacity .1s ease-in-out, transform .1s ease-in-out, visibility .1s ease-in-out',
380
- '@media (prefers-reduced-motion: reduce)': {
381
- transition: 'none'
382
- }
383
- }
384
- });
385
303
  const topLevelNodeMarginStyles = css({
386
304
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
387
305
  '.ProseMirror': {
@@ -581,6 +499,6 @@ export const GlobalStylesWrapper = ({
581
499
  exposure: true
582
500
  }) ? expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendHoverZoneReducedNext : extendHoverZoneReduced : undefined,
583
501
  // platform_editor_controls note: this allows drag handles to render on empty lines
584
- toolbarFlagsEnabled ? undefined : withInlineNodeStyle, editorExperiment('platform_editor_block_control_optimise_render', true) ? quickInsertStyles : undefined, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, editorExperiment('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, topLevelNodeMarginStyles, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && expValEquals('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles)]
502
+ toolbarFlagsEnabled ? undefined : withInlineNodeStyle, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, editorExperiment('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, topLevelNodeMarginStyles, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && expValEquals('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles)]
585
503
  });
586
504
  };