@atlaskit/editor-plugin-block-controls 13.2.17 → 13.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 13.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 13.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`fee74586b3125`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fee74586b3125) -
14
+ Improve block controls anchor reliability by adding control-specific fallback anchor names for
15
+ active drag-handle and quick-insert nodes.
16
+
17
+ When reliable-anchor mode is enabled, active nodes now expose fallback anchor names in addition to
18
+ `data-node-anchor`, so controls can resolve positioning even when primary anchor lookup is
19
+ temporarily out of sync.
20
+
21
+ Example of resulting CSS anchor usage:
22
+ - Drag handle:
23
+ `anchor(<data-node-anchor> start, anchor(--editor-block-controls-active-drag-handle-anchor start))`
24
+ - Quick insert:
25
+ `anchor(<data-node-anchor> start, anchor(--editor-block-controls-active-quick-insert-anchor start))`
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies
30
+
3
31
  ## 13.2.17
4
32
 
5
33
  ### Patch Changes
@@ -69,7 +69,14 @@ var getStickyNodes = (0, _memoizeOne.default)(function () {
69
69
  var shouldBeSticky = exports.shouldBeSticky = function shouldBeSticky(nodeType) {
70
70
  return (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') && getStickyNodes().includes(nodeType);
71
71
  };
72
- var getControlBottomCSSValue = exports.getControlBottomCSSValue = function getControlBottomCSSValue(anchor, isSticky, isTopLevelNode, isLayoutColumn) {
72
+ var getControlBottomCSSValue = exports.getControlBottomCSSValue = function getControlBottomCSSValue(anchor, isSticky, isTopLevelNode, isLayoutColumn, fallbackAnchor) {
73
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
74
+ return (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn || !isSticky || !isTopLevelNode ? {
75
+ bottom: 'unset'
76
+ } : {
77
+ bottom: fallbackAnchor ? "anchor(".concat(anchor, " end, anchor(").concat(fallbackAnchor, " end))") : "anchor(".concat(anchor, " end)")
78
+ };
79
+ }
73
80
  return (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn || !isSticky || !isTopLevelNode ? {
74
81
  bottom: 'unset'
75
82
  } : {
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.topPositionAdjustment = exports.spacingBetweenNodesForPreview = exports.spaceLookupMap = exports.rootElementGap = exports.nodeMargins = exports.getNestedNodeLeftPaddingMargin = exports.dropTargetMarginMap = exports.dragHandleGap = exports.STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER = exports.STICKY_CONTROLS_TOP_MARGIN = exports.QUICK_INSERT_WIDTH = exports.QUICK_INSERT_LEFT_OFFSET = exports.QUICK_INSERT_HEIGHT = exports.QUICK_INSERT_DIMENSIONS = exports.DRAG_HANDLE_ZINDEX = exports.DRAG_HANDLE_WRAPPED_MEDIA_EMBED_TOP_ADJUSTMENT = exports.DRAG_HANDLE_SYNCED_BLOCK_GAP = exports.DRAG_HANDLE_PARAGRAPH_TOP_ADJUSTMENT = exports.DRAG_HANDLE_PARAGRAPH_SMALL_TOP_ADJUSTMENT = exports.DRAG_HANDLE_NARROW_GAP = exports.DRAG_HANDLE_MAX_WIDTH_PLUS_GAP = exports.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH = exports.DRAG_HANDLE_MAX_GAP = exports.DRAG_HANDLE_LAYOUT_SECTION_TOP_ADJUSTMENT = exports.DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_H6_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H5_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H4_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H3_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H2_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H1_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DEFAULT_GAP = exports.DRAG_HANDLE_BORDER_RADIUS = exports.DEFAULT_COLUMN_DISTRIBUTIONS = exports.ACTIVE_QUICK_INSERT_ATTR = exports.ACTIVE_DRAG_HANDLE_ATTR = void 0;
7
+ exports.topPositionAdjustment = exports.spacingBetweenNodesForPreview = exports.spaceLookupMap = exports.rootElementGap = exports.nodeMargins = exports.getNestedNodeLeftPaddingMargin = exports.dropTargetMarginMap = exports.dragHandleGap = exports.STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER = exports.STICKY_CONTROLS_TOP_MARGIN = exports.QUICK_INSERT_WIDTH = exports.QUICK_INSERT_LEFT_OFFSET = exports.QUICK_INSERT_HEIGHT = exports.QUICK_INSERT_DIMENSIONS = exports.DRAG_HANDLE_ZINDEX = exports.DRAG_HANDLE_WRAPPED_MEDIA_EMBED_TOP_ADJUSTMENT = exports.DRAG_HANDLE_SYNCED_BLOCK_GAP = exports.DRAG_HANDLE_PARAGRAPH_TOP_ADJUSTMENT = exports.DRAG_HANDLE_PARAGRAPH_SMALL_TOP_ADJUSTMENT = exports.DRAG_HANDLE_NARROW_GAP = exports.DRAG_HANDLE_MAX_WIDTH_PLUS_GAP = exports.DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH = exports.DRAG_HANDLE_MAX_GAP = exports.DRAG_HANDLE_LAYOUT_SECTION_TOP_ADJUSTMENT = exports.DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_H6_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H5_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H4_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H3_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H2_TOP_ADJUSTMENT = exports.DRAG_HANDLE_H1_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DIVIDER_TOP_ADJUSTMENT = exports.DRAG_HANDLE_DEFAULT_GAP = exports.DRAG_HANDLE_BORDER_RADIUS = exports.DEFAULT_COLUMN_DISTRIBUTIONS = exports.ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME = exports.ACTIVE_QUICK_INSERT_ATTR = exports.ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME = exports.ACTIVE_DRAG_HANDLE_ATTR = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
10
  var _styles = require("@atlaskit/editor-common/styles");
@@ -16,6 +16,8 @@ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
16
16
  var _dropTargetMarginMap;
17
17
  var ACTIVE_DRAG_HANDLE_ATTR = exports.ACTIVE_DRAG_HANDLE_ATTR = 'data-active-drag-handle';
18
18
  var ACTIVE_QUICK_INSERT_ATTR = exports.ACTIVE_QUICK_INSERT_ATTR = 'data-active-quick-insert';
19
+ var ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME = exports.ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME = '--editor-block-controls-active-drag-handle-anchor';
20
+ var ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME = exports.ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME = '--editor-block-controls-active-quick-insert-anchor';
19
21
  var DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_HEIGHT = 24;
20
22
  var DRAG_HANDLE_BORDER_RADIUS = exports.DRAG_HANDLE_BORDER_RADIUS = 4;
21
23
  var DRAG_HANDLE_ZINDEX = exports.DRAG_HANDLE_ZINDEX = _editorSharedStyles.akRichMediaResizeZIndex + _editorSharedStyles.akEditorUnitZIndex; //place above legacy resizer
@@ -383,18 +383,26 @@ var buildToggleLayoutColumnMenuMeta = function buildToggleLayoutColumnMenuMeta(a
383
383
  openedViaKeyboard: openedViaKeyboard
384
384
  });
385
385
  };
386
- var DragHandle = exports.DragHandle = function DragHandle(_ref) {
386
+ var getDragHandleAnchorReference = function getDragHandleAnchorReference(_ref) {
387
+ var edge = _ref.edge,
388
+ safeAnchorName = _ref.safeAnchorName;
389
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
390
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ", anchor(").concat(_consts2.ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, " ").concat(edge, "))");
391
+ }
392
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ")");
393
+ };
394
+ var DragHandle = exports.DragHandle = function DragHandle(_ref2) {
387
395
  var _api$core4, _api$blockControls8;
388
- var view = _ref.view,
389
- api = _ref.api,
390
- formatMessage = _ref.formatMessage,
391
- getPos = _ref.getPos,
392
- anchorName = _ref.anchorName,
393
- nodeType = _ref.nodeType,
394
- handleOptions = _ref.handleOptions,
395
- _ref$isTopLevelNode = _ref.isTopLevelNode,
396
- isTopLevelNode = _ref$isTopLevelNode === void 0 ? true : _ref$isTopLevelNode,
397
- anchorRectCache = _ref.anchorRectCache;
396
+ var view = _ref2.view,
397
+ api = _ref2.api,
398
+ formatMessage = _ref2.formatMessage,
399
+ getPos = _ref2.getPos,
400
+ anchorName = _ref2.anchorName,
401
+ nodeType = _ref2.nodeType,
402
+ handleOptions = _ref2.handleOptions,
403
+ _ref2$isTopLevelNode = _ref2.isTopLevelNode,
404
+ isTopLevelNode = _ref2$isTopLevelNode === void 0 ? true : _ref2$isTopLevelNode,
405
+ anchorRectCache = _ref2.anchorRectCache;
398
406
  var buttonRef = (0, _react.useRef)(null);
399
407
  var mouseDownRef = (0, _react.useRef)(false);
400
408
  var _useState = (0, _react.useState)(false),
@@ -507,9 +515,9 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
507
515
  }, []);
508
516
  var handleOnClickNew = (0, _react.useCallback)(function (e) {
509
517
  var _api$core;
510
- api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
518
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref3) {
511
519
  var _selectionPreservatio, _api$analytics, _resolvedStartPos$nod, _api$blockControls, _api$blockControls2;
512
- var tr = _ref2.tr;
520
+ var tr = _ref3.tr;
513
521
  var startPos = getPos();
514
522
  if (startPos === undefined) {
515
523
  return tr;
@@ -558,9 +566,9 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
558
566
  }, [api, view, getPos, nodeType, anchorName]);
559
567
  var handleOnClick = (0, _react.useCallback)(function (e) {
560
568
  var _api$core2;
561
- api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref3) {
569
+ api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref4) {
562
570
  var _api$blockControls$sh, _api$analytics2;
563
- var tr = _ref3.tr;
571
+ var tr = _ref4.tr;
564
572
  var startPos = getPos();
565
573
  if (startPos === undefined) {
566
574
  return tr;
@@ -603,8 +611,8 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
603
611
  if (!e.repeat && e.key === ' ') {
604
612
  var _api$core3;
605
613
  var startPos = getPos();
606
- api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref4) {
607
- var tr = _ref4.tr;
614
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref5) {
615
+ var tr = _ref5.tr;
608
616
  if (startPos === undefined) {
609
617
  return tr;
610
618
  }
@@ -635,9 +643,9 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
635
643
  e.preventDefault();
636
644
  e.stopPropagation();
637
645
  var startPos = getPos();
638
- api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(function (_ref5) {
646
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(function (_ref6) {
639
647
  var _selectionPreservatio2, _api$blockControls4, _api$blockControls5, _api$userIntent;
640
- var tr = _ref5.tr;
648
+ var tr = _ref6.tr;
641
649
  if (startPos === undefined) {
642
650
  return tr;
643
651
  }
@@ -696,11 +704,11 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
696
704
  start: start
697
705
  };
698
706
  },
699
- onGenerateDragPreview: function onGenerateDragPreview(_ref6) {
707
+ onGenerateDragPreview: function onGenerateDragPreview(_ref7) {
700
708
  var _api$core6, _api$blockControls$sh2;
701
- var nativeSetDragImage = _ref6.nativeSetDragImage;
702
- api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(function (_ref7) {
703
- var tr = _ref7.tr;
709
+ var nativeSetDragImage = _ref7.nativeSetDragImage;
710
+ api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(function (_ref8) {
711
+ var tr = _ref8.tr;
704
712
  var handlePos = getPos();
705
713
  if (typeof handlePos !== 'number') {
706
714
  return tr;
@@ -777,8 +785,8 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
777
785
  };
778
786
  }
779
787
  },
780
- render: function render(_ref8) {
781
- var container = _ref8.container;
788
+ render: function render(_ref9) {
789
+ var container = _ref9.container;
782
790
  var dom = view.dom.querySelector("[".concat((0, _domAttrName.getAnchorAttrName)(), "=\"").concat(anchorName, "\"]"));
783
791
  if (!dom) {
784
792
  return;
@@ -814,9 +822,9 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
814
822
  if (start === undefined) {
815
823
  return;
816
824
  }
817
- api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref9) {
825
+ api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref0) {
818
826
  var _api$blockControls$sh3, _api$blockControls7, _api$analytics3;
819
- var tr = _ref9.tr;
827
+ var tr = _ref0.tr;
820
828
  var nodeTypes, hasSelectedMultipleNodes;
821
829
  var resolvedMovingNode = tr.doc.resolve(start);
822
830
  var maybeNode = resolvedMovingNode.nodeAfter;
@@ -893,10 +901,26 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
893
901
  var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
894
902
  var isSticky = (0, _dragHandlePositions.shouldBeSticky)(nodeType);
895
903
  if (supportsAnchor) {
896
- var bottom = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn) : {};
904
+ var anchorStart = getDragHandleAnchorReference({
905
+ edge: 'start',
906
+ safeAnchorName: safeAnchorName
907
+ });
908
+ var anchorTop = getDragHandleAnchorReference({
909
+ edge: 'top',
910
+ safeAnchorName: safeAnchorName
911
+ });
912
+ var anchorLeft = getDragHandleAnchorReference({
913
+ edge: 'left',
914
+ safeAnchorName: safeAnchorName
915
+ });
916
+ var anchorRight = getDragHandleAnchorReference({
917
+ edge: 'right',
918
+ safeAnchorName: safeAnchorName
919
+ });
920
+ var bottom = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn, _consts2.ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME) : {};
897
921
  return _objectSpread({
898
- left: isEdgeCase ? "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc((anchor(".concat(safeAnchorName, " right) + anchor(").concat(safeAnchorName, " left))/2 - ").concat(_consts2.DRAG_HANDLE_HEIGHT / 2, "px)") : "calc(anchor(".concat(safeAnchorName, " start) - ").concat(_styles.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts2.dragHandleGap)(nodeType, parentNodeType), "px)"),
899
- top: (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc(anchor(".concat(safeAnchorName, " top) - ").concat(_styles.DRAG_HANDLE_WIDTH, "px)") : "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _consts2.topPositionAdjustment)((0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? $pos && $pos.nodeAfter && (0, _decorationsCommon.getNodeTypeWithLevel)($pos.nodeAfter) || nodeType : nodeType, (dom === null || dom === void 0 ? void 0 : dom.getAttribute('layout')) || ''), "px)")
922
+ left: isEdgeCase ? "calc(".concat(anchorStart, " + ").concat((0, _dragHandlePositions.getLeftPosition)(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc((".concat(anchorRight, " + ").concat(anchorLeft, ")/2 - ").concat(_consts2.DRAG_HANDLE_HEIGHT / 2, "px)") : "calc(".concat(anchorStart, " - ").concat(_styles.DRAG_HANDLE_WIDTH, "px - ").concat((0, _consts2.dragHandleGap)(nodeType, parentNodeType), "px)"),
923
+ top: (0, _experiments.editorExperiment)('advanced_layouts', true) && isLayoutColumn ? "calc(".concat(anchorTop, " - ").concat(_styles.DRAG_HANDLE_WIDTH, "px)") : "calc(".concat(anchorStart, " + ").concat((0, _consts2.topPositionAdjustment)((0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? $pos && $pos.nodeAfter && (0, _decorationsCommon.getNodeTypeWithLevel)($pos.nodeAfter) || nodeType : nodeType, (dom === null || dom === void 0 ? void 0 : dom.getAttribute('layout')) || ''), "px)")
900
924
  }, bottom);
901
925
  }
902
926
  var height = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? (0, _dragHandlePositions.getControlHeightCSSValue)((0, _dragHandlePositions.getNodeHeight)(dom, safeAnchorName, anchorRectCache) || 0, isSticky, isTopLevelNodeValue, "".concat(_consts2.DRAG_HANDLE_HEIGHT), isLayoutColumn) : {};
@@ -1133,8 +1157,8 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
1133
1157
  var _pos = getPos();
1134
1158
  if (_pos !== undefined) {
1135
1159
  var _api$core8;
1136
- api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref0) {
1137
- var tr = _ref0.tr;
1160
+ api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref1) {
1161
+ var tr = _ref1.tr;
1138
1162
  tr.setMeta(_main.key, {
1139
1163
  activeNode: {
1140
1164
  pos: _pos,
@@ -1235,16 +1259,16 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
1235
1259
  var render = isTooltip ? buttonWithTooltip() : renderButton();
1236
1260
  return (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1') ? stickyRender : render;
1237
1261
  };
1238
- var DragHandleWithVisibility = exports.DragHandleWithVisibility = function DragHandleWithVisibility(_ref1) {
1239
- var view = _ref1.view,
1240
- api = _ref1.api,
1241
- formatMessage = _ref1.formatMessage,
1242
- getPos = _ref1.getPos,
1243
- anchorName = _ref1.anchorName,
1244
- nodeType = _ref1.nodeType,
1245
- handleOptions = _ref1.handleOptions,
1246
- isTopLevelNode = _ref1.isTopLevelNode,
1247
- anchorRectCache = _ref1.anchorRectCache;
1262
+ var DragHandleWithVisibility = exports.DragHandleWithVisibility = function DragHandleWithVisibility(_ref10) {
1263
+ var view = _ref10.view,
1264
+ api = _ref10.api,
1265
+ formatMessage = _ref10.formatMessage,
1266
+ getPos = _ref10.getPos,
1267
+ anchorName = _ref10.anchorName,
1268
+ nodeType = _ref10.nodeType,
1269
+ handleOptions = _ref10.handleOptions,
1270
+ isTopLevelNode = _ref10.isTopLevelNode,
1271
+ anchorRectCache = _ref10.anchorRectCache;
1248
1272
  var rightSideControlsEnabled = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls'], function (states) {
1249
1273
  var _states$blockControls2, _states$blockControls3;
1250
1274
  return {
@@ -348,6 +348,9 @@ var nextAnchorSelector = ['&[data-node-anchor]',
348
348
  // adjacent sibling with anchor (when next to a widget like gap cursor)
349
349
  '&.ProseMirror-widget + :not([data-node-anchor]) [data-node-anchor]:first-of-type' // first nested anchor inside adjacent sibling (when next to a widget like gap cursor)
350
350
  ].join(', ');
351
+
352
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
353
+ var combinedControlsFallbackAnchorNames = "".concat(_consts.ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, ", ").concat(_consts.ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME);
351
354
  var dragHandlerAnchorStyles = (0, _react.css)({
352
355
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
353
356
  '.ProseMirror': {
@@ -363,17 +366,31 @@ var dragHandlerAnchorStyles = (0, _react.css)({
363
366
  })
364
367
  }
365
368
  });
366
- var activeControlsSelector = "[".concat(_consts.ACTIVE_DRAG_HANDLE_ATTR, "], [").concat(_consts.ACTIVE_QUICK_INSERT_ATTR, "]");
367
369
 
368
370
  // Applies anchor-name via node decoration attributes rather than adjacency CSS selectors.
369
371
  // This is more reliable than dragHandlerAnchorStyles which depends on DOM structure.
370
372
  // Only nodes decorated with data-active-drag-handle / data-active-quick-insert get anchor-name.
371
373
  var staticControlsAnchorStyles = (0, _react.css)({
372
374
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
373
- '.ProseMirror': (0, _defineProperty2.default)({}, activeControlsSelector, {
374
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
375
- anchorName: "var(".concat(_styles.ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
376
- })
375
+ '.ProseMirror': {
376
+ // Active node can be both drag-handle and quick-insert target. Expose all three names:
377
+ // node anchor + both control-specific fallback anchors.
378
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
379
+ '[data-active-drag-handle][data-active-quick-insert][data-node-anchor]': {
380
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
381
+ anchorName: "".concat(combinedControlsFallbackAnchorNames, ", var(").concat(_styles.ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
382
+ },
383
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
384
+ '[data-active-drag-handle][data-node-anchor]': {
385
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
386
+ anchorName: "".concat(_consts.ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, ", var(").concat(_styles.ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
387
+ },
388
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
389
+ '[data-active-quick-insert][data-node-anchor]': {
390
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
391
+ anchorName: "".concat(_consts.ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, ", var(").concat(_styles.ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
392
+ }
393
+ }
377
394
  });
378
395
 
379
396
  // Styles applied to nodes with anchors when dragging
@@ -151,15 +151,23 @@ var tooltipContainerStylesImprovedStickyHeaderWithMarksFix = (0, _react2.css)({
151
151
 
152
152
  // TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
153
153
 
154
- var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref) {
155
- var view = _ref.view,
156
- api = _ref.api,
157
- formatMessage = _ref.formatMessage,
158
- getPos = _ref.getPos,
159
- anchorName = _ref.anchorName,
160
- rootAnchorName = _ref.rootAnchorName,
161
- rootNodeType = _ref.rootNodeType,
162
- anchorRectCache = _ref.anchorRectCache;
154
+ var getQuickInsertAnchorReference = function getQuickInsertAnchorReference(_ref) {
155
+ var edge = _ref.edge,
156
+ safeAnchorName = _ref.safeAnchorName;
157
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
158
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ", anchor(").concat(_consts.ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, " ").concat(edge, "))");
159
+ }
160
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ")");
161
+ };
162
+ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref2) {
163
+ var view = _ref2.view,
164
+ api = _ref2.api,
165
+ formatMessage = _ref2.formatMessage,
166
+ getPos = _ref2.getPos,
167
+ anchorName = _ref2.anchorName,
168
+ rootAnchorName = _ref2.rootAnchorName,
169
+ rootNodeType = _ref2.rootNodeType,
170
+ anchorRectCache = _ref2.anchorRectCache;
163
171
  var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['featureFlags'], function (states) {
164
172
  var _states$featureFlagsS;
165
173
  return {
@@ -217,12 +225,16 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
217
225
  }
218
226
  var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
219
227
  var isSticky = (0, _dragHandlePositions.shouldBeSticky)(rootNodeType);
220
- var bottom = (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName || anchorName, isSticky, true);
228
+ var anchorStart = getQuickInsertAnchorReference({
229
+ edge: 'start',
230
+ safeAnchorName: safeAnchorName
231
+ });
232
+ var bottom = (0, _dragHandlePositions.getControlBottomCSSValue)(safeAnchorName || anchorName, isSticky, true, false, _consts.ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME);
221
233
  if (supportsAnchor) {
222
234
  return _objectSpread({
223
- left: isEdgeCase ? "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _widgetPositions.getLeftPositionForRootElement)(dom, rootNodeType, _consts.QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)") : "calc(anchor(".concat(safeAnchorName, " start) - ").concat(_consts.QUICK_INSERT_DIMENSIONS.width, "px - ").concat((0, _consts.rootElementGap)(rootNodeType), "px + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)"),
235
+ left: isEdgeCase ? "calc(".concat(anchorStart, " + ").concat((0, _widgetPositions.getLeftPositionForRootElement)(dom, rootNodeType, _consts.QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)") : "calc(".concat(anchorStart, " - ").concat(_consts.QUICK_INSERT_DIMENSIONS.width, "px - ").concat((0, _consts.rootElementGap)(rootNodeType), "px + -").concat(_consts.QUICK_INSERT_LEFT_OFFSET, "px)"),
224
236
  // small text requires further tweaking to positioning, re-using existing methods to calculate to keep it unified with drag handle
225
- top: "calc(anchor(".concat(safeAnchorName, " start) + ").concat((0, _consts.topPositionAdjustment)(node && node.type.name === 'paragraph' && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _decorationsCommon.getNodeTypeWithLevel)(node) : rootNodeType), "px)")
237
+ top: "calc(".concat(anchorStart, " + ").concat((0, _consts.topPositionAdjustment)(node && node.type.name === 'paragraph' && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _decorationsCommon.getNodeTypeWithLevel)(node) : rootNodeType), "px)")
226
238
  }, bottom);
227
239
  }
228
240
 
@@ -287,8 +299,8 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
287
299
  var newPos =
288
300
  //if the current selection is selected from right to left, then set the selection to the start of the paragraph
289
301
  currentSelection.anchor === currentSelection.to ? currentParagraphNode.pos : currentParagraphNode.pos + currentParagraphNode.node.nodeSize - 1;
290
- api.core.actions.execute(function (_ref2) {
291
- var tr = _ref2.tr;
302
+ api.core.actions.execute(function (_ref3) {
303
+ var tr = _ref3.tr;
292
304
  tr.setSelection(_state.TextSelection.create(view.state.selection.$from.doc, newPos));
293
305
  return tr;
294
306
  });
@@ -302,8 +314,8 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
302
314
  // otherwise need to force the selection to be at the start of the node, because
303
315
  // prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
304
316
  // consistent NodeSelection for root level nodes.
305
- api.core.actions.execute(function (_ref3) {
306
- var tr = _ref3.tr;
317
+ api.core.actions.execute(function (_ref4) {
318
+ var tr = _ref4.tr;
307
319
  (0, _editorCommands.createNewLine)(view.state.selection.from)({
308
320
  tr: tr
309
321
  });
@@ -315,8 +327,8 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
315
327
  if (currentSelection instanceof _cellSelection.CellSelection) {
316
328
  // find the last inline position in the selection
317
329
  var lastInlinePosition = _state.TextSelection.near(view.state.selection.$to, -1);
318
- lastInlinePosition && api.core.actions.execute(function (_ref4) {
319
- var tr = _ref4.tr;
330
+ lastInlinePosition && api.core.actions.execute(function (_ref5) {
331
+ var tr = _ref5.tr;
320
332
  if (!(lastInlinePosition instanceof _state.TextSelection)) {
321
333
  // this will create a new line after the node
322
334
  (0, _editorCommands.createNewLine)(lastInlinePosition.from)({
@@ -375,16 +387,16 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
375
387
  css: [tooltipContainerStyles, (0, _expValEquals.expValEquals)('platform_editor_table_sticky_header_improvements', 'cohort', 'test_with_overflow') ? tooltipContainerImprovedStylesStickyHeader : tooltipContainerStylesStickyHeader, (0, _expValEquals.expValEquals)('platform_editor_table_sticky_header_improvements', 'cohort', 'test_with_overflow') ? tooltipContainerStylesImprovedStickyHeaderWithMarksFix : tooltipContainerStylesStickyHeaderWithMarksFix]
376
388
  }, tooltipPressable()));
377
389
  };
378
- var QuickInsertWithVisibility = exports.QuickInsertWithVisibility = function QuickInsertWithVisibility(_ref5) {
379
- var view = _ref5.view,
380
- api = _ref5.api,
381
- formatMessage = _ref5.formatMessage,
382
- getPos = _ref5.getPos,
383
- nodeType = _ref5.nodeType,
384
- anchorName = _ref5.anchorName,
385
- rootAnchorName = _ref5.rootAnchorName,
386
- rootNodeType = _ref5.rootNodeType,
387
- anchorRectCache = _ref5.anchorRectCache;
390
+ var QuickInsertWithVisibility = exports.QuickInsertWithVisibility = function QuickInsertWithVisibility(_ref6) {
391
+ var view = _ref6.view,
392
+ api = _ref6.api,
393
+ formatMessage = _ref6.formatMessage,
394
+ getPos = _ref6.getPos,
395
+ nodeType = _ref6.nodeType,
396
+ anchorName = _ref6.anchorName,
397
+ rootAnchorName = _ref6.rootAnchorName,
398
+ rootNodeType = _ref6.rootNodeType,
399
+ anchorRectCache = _ref6.anchorRectCache;
388
400
  var rightSideControlsEnabled = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls'], function (states) {
389
401
  var _states$blockControls, _states$blockControls2;
390
402
  return {
@@ -57,7 +57,14 @@ const getStickyNodes = memoizeOne(() => [...STICKY_NODES, ...(expValEquals('conf
57
57
  export const shouldBeSticky = nodeType => {
58
58
  return editorExperiment('platform_editor_controls', 'variant1') && getStickyNodes().includes(nodeType);
59
59
  };
60
- export const getControlBottomCSSValue = (anchor, isSticky, isTopLevelNode, isLayoutColumn) => {
60
+ export const getControlBottomCSSValue = (anchor, isSticky, isTopLevelNode, isLayoutColumn, fallbackAnchor) => {
61
+ if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
62
+ return editorExperiment('advanced_layouts', true) && isLayoutColumn || !isSticky || !isTopLevelNode ? {
63
+ bottom: 'unset'
64
+ } : {
65
+ bottom: fallbackAnchor ? `anchor(${anchor} end, anchor(${fallbackAnchor} end))` : `anchor(${anchor} end)`
66
+ };
67
+ }
61
68
  return editorExperiment('advanced_layouts', true) && isLayoutColumn || !isSticky || !isTopLevelNode ? {
62
69
  bottom: 'unset'
63
70
  } : {
@@ -6,6 +6,8 @@ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equ
6
6
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
7
7
  export const ACTIVE_DRAG_HANDLE_ATTR = 'data-active-drag-handle';
8
8
  export const ACTIVE_QUICK_INSERT_ATTR = 'data-active-quick-insert';
9
+ export const ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME = '--editor-block-controls-active-drag-handle-anchor';
10
+ export const ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME = '--editor-block-controls-active-quick-insert-anchor';
9
11
  export const DRAG_HANDLE_HEIGHT = 24;
10
12
  export const DRAG_HANDLE_BORDER_RADIUS = 4;
11
13
  export const DRAG_HANDLE_ZINDEX = akRichMediaResizeZIndex + akEditorUnitZIndex; //place above legacy resizer
@@ -35,7 +35,7 @@ import { getControlBottomCSSValue, getControlHeightCSSValue, getLeftPosition, ge
35
35
  import { expandAndUpdateSelection } from '../pm-plugins/utils/expand-and-update-selection';
36
36
  import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
37
37
  import { alignAnchorHeadInDirectionOfPos, expandSelectionHeadToNodeAtPos } from '../pm-plugins/utils/selection';
38
- import { ACTIVE_DRAG_HANDLE_ATTR, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
38
+ import { ACTIVE_DRAG_HANDLE_ATTR, ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
39
39
  import { DragHandleNestedIcon } from './drag-handle-nested-icon';
40
40
  import { dragPreview } from './drag-preview';
41
41
  import { shouldUseNestedDragHandleIcon } from './should-use-nested-drag-handle-icon';
@@ -375,6 +375,15 @@ const buildToggleLayoutColumnMenuMeta = (anchorPos, openedViaKeyboard) => ({
375
375
  } : {}),
376
376
  openedViaKeyboard
377
377
  });
378
+ const getDragHandleAnchorReference = ({
379
+ edge,
380
+ safeAnchorName
381
+ }) => {
382
+ if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
383
+ return `anchor(${safeAnchorName} ${edge}, anchor(${ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME} ${edge}))`;
384
+ }
385
+ return `anchor(${safeAnchorName} ${edge})`;
386
+ };
378
387
  export const DragHandle = ({
379
388
  view,
380
389
  api,
@@ -871,10 +880,26 @@ export const DragHandle = ({
871
880
  const isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
872
881
  const isSticky = shouldBeSticky(nodeType);
873
882
  if (supportsAnchor) {
874
- const bottom = editorExperiment('platform_editor_controls', 'variant1') ? getControlBottomCSSValue(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn) : {};
883
+ const anchorStart = getDragHandleAnchorReference({
884
+ edge: 'start',
885
+ safeAnchorName
886
+ });
887
+ const anchorTop = getDragHandleAnchorReference({
888
+ edge: 'top',
889
+ safeAnchorName
890
+ });
891
+ const anchorLeft = getDragHandleAnchorReference({
892
+ edge: 'left',
893
+ safeAnchorName
894
+ });
895
+ const anchorRight = getDragHandleAnchorReference({
896
+ edge: 'right',
897
+ safeAnchorName
898
+ });
899
+ const bottom = editorExperiment('platform_editor_controls', 'variant1') ? getControlBottomCSSValue(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn, ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME) : {};
875
900
  return {
876
- 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)`,
877
- 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)`,
901
+ left: isEdgeCase ? `calc(${anchorStart} + ${getLeftPosition(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType)})` : editorExperiment('advanced_layouts', true) && isLayoutColumn ? `calc((${anchorRight} + ${anchorLeft})/2 - ${DRAG_HANDLE_HEIGHT / 2}px)` : `calc(${anchorStart} - ${DRAG_HANDLE_WIDTH}px - ${dragHandleGap(nodeType, parentNodeType)}px)`,
902
+ top: editorExperiment('advanced_layouts', true) && isLayoutColumn ? `calc(${anchorTop} - ${DRAG_HANDLE_WIDTH}px)` : `calc(${anchorStart} + ${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)`,
878
903
  ...bottom
879
904
  };
880
905
  }
@@ -11,7 +11,7 @@ import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
11
11
  import { akEditorBreakoutPadding, akEditorCalculatedWideLayoutWidth, akEditorCalculatedWideLayoutWidthSmallViewport, akEditorFullPageNarrowBreakout, akEditorGutterPaddingDynamic, akEditorGutterPaddingReduced } from '@atlaskit/editor-shared-styles';
12
12
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
13
13
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
14
- import { ACTIVE_DRAG_HANDLE_ATTR, ACTIVE_QUICK_INSERT_ATTR, DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
14
+ import { ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
15
15
  import { NODE_ANCHOR_ATTR_NAME } from './utils/dom-attr-name';
16
16
 
17
17
  /**
@@ -428,6 +428,9 @@ const nextAnchorSelector = ['&[data-node-anchor]',
428
428
  // adjacent sibling with anchor (when next to a widget like gap cursor)
429
429
  '&.ProseMirror-widget + :not([data-node-anchor]) [data-node-anchor]:first-of-type' // first nested anchor inside adjacent sibling (when next to a widget like gap cursor)
430
430
  ].join(', ');
431
+
432
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
433
+ const combinedControlsFallbackAnchorNames = `${ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME}, ${ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME}`;
431
434
  const dragHandlerAnchorStyles = css({
432
435
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
433
436
  '.ProseMirror': {
@@ -449,7 +452,6 @@ const dragHandlerAnchorStyles = css({
449
452
  }
450
453
  }
451
454
  });
452
- const activeControlsSelector = `[${ACTIVE_DRAG_HANDLE_ATTR}], [${ACTIVE_QUICK_INSERT_ATTR}]`;
453
455
 
454
456
  // Applies anchor-name via node decoration attributes rather than adjacency CSS selectors.
455
457
  // This is more reliable than dragHandlerAnchorStyles which depends on DOM structure.
@@ -457,10 +459,22 @@ const activeControlsSelector = `[${ACTIVE_DRAG_HANDLE_ATTR}], [${ACTIVE_QUICK_IN
457
459
  const staticControlsAnchorStyles = css({
458
460
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
459
461
  '.ProseMirror': {
460
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
461
- [activeControlsSelector]: {
462
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
463
- anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
462
+ // Active node can be both drag-handle and quick-insert target. Expose all three names:
463
+ // node anchor + both control-specific fallback anchors.
464
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
465
+ '[data-active-drag-handle][data-active-quick-insert][data-node-anchor]': {
466
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
467
+ anchorName: `${combinedControlsFallbackAnchorNames}, var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
468
+ },
469
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
470
+ '[data-active-drag-handle][data-node-anchor]': {
471
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
472
+ anchorName: `${ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME}, var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
473
+ },
474
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
475
+ '[data-active-quick-insert][data-node-anchor]': {
476
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
477
+ anchorName: `${ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME}, var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
464
478
  }
465
479
  }
466
480
  });
@@ -23,7 +23,7 @@ import Tooltip from '@atlaskit/tooltip';
23
23
  import { getNodeTypeWithLevel } from '../pm-plugins/decorations-common';
24
24
  import { getControlBottomCSSValue, getControlHeightCSSValue, getNodeHeight, getTopPosition, shouldBeSticky } from '../pm-plugins/utils/drag-handle-positions';
25
25
  import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
26
- import { ACTIVE_QUICK_INSERT_ATTR, QUICK_INSERT_DIMENSIONS, QUICK_INSERT_HEIGHT, QUICK_INSERT_LEFT_OFFSET, QUICK_INSERT_WIDTH, rootElementGap, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
26
+ import { ACTIVE_QUICK_INSERT_ATTR, ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, QUICK_INSERT_DIMENSIONS, QUICK_INSERT_HEIGHT, QUICK_INSERT_LEFT_OFFSET, QUICK_INSERT_WIDTH, rootElementGap, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
27
27
  import { refreshAnchorName } from './utils/anchor-name';
28
28
  import { isInTextSelection, isNestedNodeSelected, isNonEditableBlock, isSelectionInNode } from './utils/document-checks';
29
29
  import { getAnchorAttrName } from './utils/dom-attr-name';
@@ -141,6 +141,15 @@ const tooltipContainerStylesImprovedStickyHeaderWithMarksFix = css({
141
141
 
142
142
  // TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
143
143
 
144
+ const getQuickInsertAnchorReference = ({
145
+ edge,
146
+ safeAnchorName
147
+ }) => {
148
+ if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
149
+ return `anchor(${safeAnchorName} ${edge}, anchor(${ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME} ${edge}))`;
150
+ }
151
+ return `anchor(${safeAnchorName} ${edge})`;
152
+ };
144
153
  export const TypeAheadControl = ({
145
154
  view,
146
155
  api,
@@ -206,12 +215,16 @@ export const TypeAheadControl = ({
206
215
  }
207
216
  const isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
208
217
  const isSticky = shouldBeSticky(rootNodeType);
209
- const bottom = getControlBottomCSSValue(safeAnchorName || anchorName, isSticky, true);
218
+ const anchorStart = getQuickInsertAnchorReference({
219
+ edge: 'start',
220
+ safeAnchorName
221
+ });
222
+ const bottom = getControlBottomCSSValue(safeAnchorName || anchorName, isSticky, true, false, ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME);
210
223
  if (supportsAnchor) {
211
224
  return {
212
- left: isEdgeCase ? `calc(anchor(${safeAnchorName} start) + ${getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates)} + -${QUICK_INSERT_LEFT_OFFSET}px)` : `calc(anchor(${safeAnchorName} start) - ${QUICK_INSERT_DIMENSIONS.width}px - ${rootElementGap(rootNodeType)}px + -${QUICK_INSERT_LEFT_OFFSET}px)`,
225
+ left: isEdgeCase ? `calc(${anchorStart} + ${getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates)} + -${QUICK_INSERT_LEFT_OFFSET}px)` : `calc(${anchorStart} - ${QUICK_INSERT_DIMENSIONS.width}px - ${rootElementGap(rootNodeType)}px + -${QUICK_INSERT_LEFT_OFFSET}px)`,
213
226
  // small text requires further tweaking to positioning, re-using existing methods to calculate to keep it unified with drag handle
214
- top: `calc(anchor(${safeAnchorName} start) + ${topPositionAdjustment(node && node.type.name === 'paragraph' && expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getNodeTypeWithLevel(node) : rootNodeType)}px)`,
227
+ top: `calc(${anchorStart} + ${topPositionAdjustment(node && node.type.name === 'paragraph' && expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getNodeTypeWithLevel(node) : rootNodeType)}px)`,
215
228
  ...bottom
216
229
  };
217
230
  }
@@ -62,7 +62,14 @@ var getStickyNodes = memoizeOne(function () {
62
62
  export var shouldBeSticky = function shouldBeSticky(nodeType) {
63
63
  return editorExperiment('platform_editor_controls', 'variant1') && getStickyNodes().includes(nodeType);
64
64
  };
65
- export var getControlBottomCSSValue = function getControlBottomCSSValue(anchor, isSticky, isTopLevelNode, isLayoutColumn) {
65
+ export var getControlBottomCSSValue = function getControlBottomCSSValue(anchor, isSticky, isTopLevelNode, isLayoutColumn, fallbackAnchor) {
66
+ if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
67
+ return editorExperiment('advanced_layouts', true) && isLayoutColumn || !isSticky || !isTopLevelNode ? {
68
+ bottom: 'unset'
69
+ } : {
70
+ bottom: fallbackAnchor ? "anchor(".concat(anchor, " end, anchor(").concat(fallbackAnchor, " end))") : "anchor(".concat(anchor, " end)")
71
+ };
72
+ }
66
73
  return editorExperiment('advanced_layouts', true) && isLayoutColumn || !isSticky || !isTopLevelNode ? {
67
74
  bottom: 'unset'
68
75
  } : {
@@ -9,6 +9,8 @@ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equ
9
9
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
10
10
  export var ACTIVE_DRAG_HANDLE_ATTR = 'data-active-drag-handle';
11
11
  export var ACTIVE_QUICK_INSERT_ATTR = 'data-active-quick-insert';
12
+ export var ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME = '--editor-block-controls-active-drag-handle-anchor';
13
+ export var ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME = '--editor-block-controls-active-quick-insert-anchor';
12
14
  export var DRAG_HANDLE_HEIGHT = 24;
13
15
  export var DRAG_HANDLE_BORDER_RADIUS = 4;
14
16
  export var DRAG_HANDLE_ZINDEX = akRichMediaResizeZIndex + akEditorUnitZIndex; //place above legacy resizer
@@ -40,7 +40,7 @@ import { getControlBottomCSSValue, getControlHeightCSSValue, getLeftPosition, ge
40
40
  import { expandAndUpdateSelection } from '../pm-plugins/utils/expand-and-update-selection';
41
41
  import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
42
42
  import { alignAnchorHeadInDirectionOfPos, expandSelectionHeadToNodeAtPos } from '../pm-plugins/utils/selection';
43
- import { ACTIVE_DRAG_HANDLE_ATTR, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
43
+ import { ACTIVE_DRAG_HANDLE_ATTR, ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
44
44
  import { DragHandleNestedIcon } from './drag-handle-nested-icon';
45
45
  import { dragPreview } from './drag-preview';
46
46
  import { shouldUseNestedDragHandleIcon } from './should-use-nested-drag-handle-icon';
@@ -379,18 +379,26 @@ var buildToggleLayoutColumnMenuMeta = function buildToggleLayoutColumnMenuMeta(a
379
379
  openedViaKeyboard: openedViaKeyboard
380
380
  });
381
381
  };
382
- export var DragHandle = function DragHandle(_ref) {
382
+ var getDragHandleAnchorReference = function getDragHandleAnchorReference(_ref) {
383
+ var edge = _ref.edge,
384
+ safeAnchorName = _ref.safeAnchorName;
385
+ if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
386
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ", anchor(").concat(ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, " ").concat(edge, "))");
387
+ }
388
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ")");
389
+ };
390
+ export var DragHandle = function DragHandle(_ref2) {
383
391
  var _api$core4, _api$blockControls8;
384
- var view = _ref.view,
385
- api = _ref.api,
386
- formatMessage = _ref.formatMessage,
387
- getPos = _ref.getPos,
388
- anchorName = _ref.anchorName,
389
- nodeType = _ref.nodeType,
390
- handleOptions = _ref.handleOptions,
391
- _ref$isTopLevelNode = _ref.isTopLevelNode,
392
- isTopLevelNode = _ref$isTopLevelNode === void 0 ? true : _ref$isTopLevelNode,
393
- anchorRectCache = _ref.anchorRectCache;
392
+ var view = _ref2.view,
393
+ api = _ref2.api,
394
+ formatMessage = _ref2.formatMessage,
395
+ getPos = _ref2.getPos,
396
+ anchorName = _ref2.anchorName,
397
+ nodeType = _ref2.nodeType,
398
+ handleOptions = _ref2.handleOptions,
399
+ _ref2$isTopLevelNode = _ref2.isTopLevelNode,
400
+ isTopLevelNode = _ref2$isTopLevelNode === void 0 ? true : _ref2$isTopLevelNode,
401
+ anchorRectCache = _ref2.anchorRectCache;
394
402
  var buttonRef = useRef(null);
395
403
  var mouseDownRef = useRef(false);
396
404
  var _useState = useState(false),
@@ -503,9 +511,9 @@ export var DragHandle = function DragHandle(_ref) {
503
511
  }, []);
504
512
  var handleOnClickNew = useCallback(function (e) {
505
513
  var _api$core;
506
- api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref2) {
514
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref3) {
507
515
  var _selectionPreservatio, _api$analytics, _resolvedStartPos$nod, _api$blockControls, _api$blockControls2;
508
- var tr = _ref2.tr;
516
+ var tr = _ref3.tr;
509
517
  var startPos = getPos();
510
518
  if (startPos === undefined) {
511
519
  return tr;
@@ -554,9 +562,9 @@ export var DragHandle = function DragHandle(_ref) {
554
562
  }, [api, view, getPos, nodeType, anchorName]);
555
563
  var handleOnClick = useCallback(function (e) {
556
564
  var _api$core2;
557
- api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref3) {
565
+ api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref4) {
558
566
  var _api$blockControls$sh, _api$analytics2;
559
- var tr = _ref3.tr;
567
+ var tr = _ref4.tr;
560
568
  var startPos = getPos();
561
569
  if (startPos === undefined) {
562
570
  return tr;
@@ -599,8 +607,8 @@ export var DragHandle = function DragHandle(_ref) {
599
607
  if (!e.repeat && e.key === ' ') {
600
608
  var _api$core3;
601
609
  var startPos = getPos();
602
- api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref4) {
603
- var tr = _ref4.tr;
610
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref5) {
611
+ var tr = _ref5.tr;
604
612
  if (startPos === undefined) {
605
613
  return tr;
606
614
  }
@@ -631,9 +639,9 @@ export var DragHandle = function DragHandle(_ref) {
631
639
  e.preventDefault();
632
640
  e.stopPropagation();
633
641
  var startPos = getPos();
634
- api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(function (_ref5) {
642
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.execute(function (_ref6) {
635
643
  var _selectionPreservatio2, _api$blockControls4, _api$blockControls5, _api$userIntent;
636
- var tr = _ref5.tr;
644
+ var tr = _ref6.tr;
637
645
  if (startPos === undefined) {
638
646
  return tr;
639
647
  }
@@ -692,11 +700,11 @@ export var DragHandle = function DragHandle(_ref) {
692
700
  start: start
693
701
  };
694
702
  },
695
- onGenerateDragPreview: function onGenerateDragPreview(_ref6) {
703
+ onGenerateDragPreview: function onGenerateDragPreview(_ref7) {
696
704
  var _api$core6, _api$blockControls$sh2;
697
- var nativeSetDragImage = _ref6.nativeSetDragImage;
698
- api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(function (_ref7) {
699
- var tr = _ref7.tr;
705
+ var nativeSetDragImage = _ref7.nativeSetDragImage;
706
+ api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(function (_ref8) {
707
+ var tr = _ref8.tr;
700
708
  var handlePos = getPos();
701
709
  if (typeof handlePos !== 'number') {
702
710
  return tr;
@@ -773,8 +781,8 @@ export var DragHandle = function DragHandle(_ref) {
773
781
  };
774
782
  }
775
783
  },
776
- render: function render(_ref8) {
777
- var container = _ref8.container;
784
+ render: function render(_ref9) {
785
+ var container = _ref9.container;
778
786
  var dom = view.dom.querySelector("[".concat(getAnchorAttrName(), "=\"").concat(anchorName, "\"]"));
779
787
  if (!dom) {
780
788
  return;
@@ -810,9 +818,9 @@ export var DragHandle = function DragHandle(_ref) {
810
818
  if (start === undefined) {
811
819
  return;
812
820
  }
813
- api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref9) {
821
+ api === null || api === void 0 || (_api$core7 = api.core) === null || _api$core7 === void 0 || _api$core7.actions.execute(function (_ref0) {
814
822
  var _api$blockControls$sh3, _api$blockControls7, _api$analytics3;
815
- var tr = _ref9.tr;
823
+ var tr = _ref0.tr;
816
824
  var nodeTypes, hasSelectedMultipleNodes;
817
825
  var resolvedMovingNode = tr.doc.resolve(start);
818
826
  var maybeNode = resolvedMovingNode.nodeAfter;
@@ -889,10 +897,26 @@ export var DragHandle = function DragHandle(_ref) {
889
897
  var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
890
898
  var isSticky = shouldBeSticky(nodeType);
891
899
  if (supportsAnchor) {
892
- var bottom = editorExperiment('platform_editor_controls', 'variant1') ? getControlBottomCSSValue(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn) : {};
900
+ var anchorStart = getDragHandleAnchorReference({
901
+ edge: 'start',
902
+ safeAnchorName: safeAnchorName
903
+ });
904
+ var anchorTop = getDragHandleAnchorReference({
905
+ edge: 'top',
906
+ safeAnchorName: safeAnchorName
907
+ });
908
+ var anchorLeft = getDragHandleAnchorReference({
909
+ edge: 'left',
910
+ safeAnchorName: safeAnchorName
911
+ });
912
+ var anchorRight = getDragHandleAnchorReference({
913
+ edge: 'right',
914
+ safeAnchorName: safeAnchorName
915
+ });
916
+ var bottom = editorExperiment('platform_editor_controls', 'variant1') ? getControlBottomCSSValue(safeAnchorName, isSticky, isTopLevelNodeValue, isLayoutColumn, ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME) : {};
893
917
  return _objectSpread({
894
- left: isEdgeCase ? "calc(anchor(".concat(safeAnchorName, " start) + ").concat(getLeftPosition(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : editorExperiment('advanced_layouts', true) && isLayoutColumn ? "calc((anchor(".concat(safeAnchorName, " right) + anchor(").concat(safeAnchorName, " left))/2 - ").concat(DRAG_HANDLE_HEIGHT / 2, "px)") : "calc(anchor(".concat(safeAnchorName, " start) - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType, parentNodeType), "px)"),
895
- top: editorExperiment('advanced_layouts', true) && isLayoutColumn ? "calc(anchor(".concat(safeAnchorName, " top) - ").concat(DRAG_HANDLE_WIDTH, "px)") : "calc(anchor(".concat(safeAnchorName, " start) + ").concat(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)")
918
+ left: isEdgeCase ? "calc(".concat(anchorStart, " + ").concat(getLeftPosition(dom, nodeType, innerContainer, isMacroInteractionUpdates, parentNodeType), ")") : editorExperiment('advanced_layouts', true) && isLayoutColumn ? "calc((".concat(anchorRight, " + ").concat(anchorLeft, ")/2 - ").concat(DRAG_HANDLE_HEIGHT / 2, "px)") : "calc(".concat(anchorStart, " - ").concat(DRAG_HANDLE_WIDTH, "px - ").concat(dragHandleGap(nodeType, parentNodeType), "px)"),
919
+ top: editorExperiment('advanced_layouts', true) && isLayoutColumn ? "calc(".concat(anchorTop, " - ").concat(DRAG_HANDLE_WIDTH, "px)") : "calc(".concat(anchorStart, " + ").concat(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)")
896
920
  }, bottom);
897
921
  }
898
922
  var height = editorExperiment('platform_editor_controls', 'variant1') ? getControlHeightCSSValue(getNodeHeight(dom, safeAnchorName, anchorRectCache) || 0, isSticky, isTopLevelNodeValue, "".concat(DRAG_HANDLE_HEIGHT), isLayoutColumn) : {};
@@ -1129,8 +1153,8 @@ export var DragHandle = function DragHandle(_ref) {
1129
1153
  var _pos = getPos();
1130
1154
  if (_pos !== undefined) {
1131
1155
  var _api$core8;
1132
- api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref0) {
1133
- var tr = _ref0.tr;
1156
+ api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 || _api$core8.actions.execute(function (_ref1) {
1157
+ var tr = _ref1.tr;
1134
1158
  tr.setMeta(key, {
1135
1159
  activeNode: {
1136
1160
  pos: _pos,
@@ -1231,16 +1255,16 @@ export var DragHandle = function DragHandle(_ref) {
1231
1255
  var render = isTooltip ? buttonWithTooltip() : renderButton();
1232
1256
  return editorExperiment('platform_editor_controls', 'variant1') ? stickyRender : render;
1233
1257
  };
1234
- export var DragHandleWithVisibility = function DragHandleWithVisibility(_ref1) {
1235
- var view = _ref1.view,
1236
- api = _ref1.api,
1237
- formatMessage = _ref1.formatMessage,
1238
- getPos = _ref1.getPos,
1239
- anchorName = _ref1.anchorName,
1240
- nodeType = _ref1.nodeType,
1241
- handleOptions = _ref1.handleOptions,
1242
- isTopLevelNode = _ref1.isTopLevelNode,
1243
- anchorRectCache = _ref1.anchorRectCache;
1258
+ export var DragHandleWithVisibility = function DragHandleWithVisibility(_ref10) {
1259
+ var view = _ref10.view,
1260
+ api = _ref10.api,
1261
+ formatMessage = _ref10.formatMessage,
1262
+ getPos = _ref10.getPos,
1263
+ anchorName = _ref10.anchorName,
1264
+ nodeType = _ref10.nodeType,
1265
+ handleOptions = _ref10.handleOptions,
1266
+ isTopLevelNode = _ref10.isTopLevelNode,
1267
+ anchorRectCache = _ref10.anchorRectCache;
1244
1268
  var rightSideControlsEnabled = useSharedPluginStateWithSelector(api, ['blockControls'], function (states) {
1245
1269
  var _states$blockControls2, _states$blockControls3;
1246
1270
  return {
@@ -12,7 +12,7 @@ import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
12
12
  import { akEditorBreakoutPadding, akEditorCalculatedWideLayoutWidth, akEditorCalculatedWideLayoutWidthSmallViewport, akEditorFullPageNarrowBreakout, akEditorGutterPaddingDynamic, akEditorGutterPaddingReduced } from '@atlaskit/editor-shared-styles';
13
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
14
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
15
- import { ACTIVE_DRAG_HANDLE_ATTR, ACTIVE_QUICK_INSERT_ATTR, DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
15
+ import { ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
16
16
  import { NODE_ANCHOR_ATTR_NAME } from './utils/dom-attr-name';
17
17
 
18
18
  /**
@@ -341,6 +341,9 @@ var nextAnchorSelector = ['&[data-node-anchor]',
341
341
  // adjacent sibling with anchor (when next to a widget like gap cursor)
342
342
  '&.ProseMirror-widget + :not([data-node-anchor]) [data-node-anchor]:first-of-type' // first nested anchor inside adjacent sibling (when next to a widget like gap cursor)
343
343
  ].join(', ');
344
+
345
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
346
+ var combinedControlsFallbackAnchorNames = "".concat(ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, ", ").concat(ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME);
344
347
  var dragHandlerAnchorStyles = css({
345
348
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
346
349
  '.ProseMirror': {
@@ -356,17 +359,31 @@ var dragHandlerAnchorStyles = css({
356
359
  })
357
360
  }
358
361
  });
359
- var activeControlsSelector = "[".concat(ACTIVE_DRAG_HANDLE_ATTR, "], [").concat(ACTIVE_QUICK_INSERT_ATTR, "]");
360
362
 
361
363
  // Applies anchor-name via node decoration attributes rather than adjacency CSS selectors.
362
364
  // This is more reliable than dragHandlerAnchorStyles which depends on DOM structure.
363
365
  // Only nodes decorated with data-active-drag-handle / data-active-quick-insert get anchor-name.
364
366
  var staticControlsAnchorStyles = css({
365
367
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
366
- '.ProseMirror': _defineProperty({}, activeControlsSelector, {
367
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
368
- anchorName: "var(".concat(ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
369
- })
368
+ '.ProseMirror': {
369
+ // Active node can be both drag-handle and quick-insert target. Expose all three names:
370
+ // node anchor + both control-specific fallback anchors.
371
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
372
+ '[data-active-drag-handle][data-active-quick-insert][data-node-anchor]': {
373
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
374
+ anchorName: "".concat(combinedControlsFallbackAnchorNames, ", var(").concat(ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
375
+ },
376
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
377
+ '[data-active-drag-handle][data-node-anchor]': {
378
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
379
+ anchorName: "".concat(ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, ", var(").concat(ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
380
+ },
381
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
382
+ '[data-active-quick-insert][data-node-anchor]': {
383
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
384
+ anchorName: "".concat(ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, ", var(").concat(ANCHOR_VARIABLE_NAME, ", attr(data-node-anchor type(<custom-ident>)))")
385
+ }
386
+ }
370
387
  });
371
388
 
372
389
  // Styles applied to nodes with anchors when dragging
@@ -27,7 +27,7 @@ import Tooltip from '@atlaskit/tooltip';
27
27
  import { getNodeTypeWithLevel } from '../pm-plugins/decorations-common';
28
28
  import { getControlBottomCSSValue, getControlHeightCSSValue, getNodeHeight, getTopPosition, shouldBeSticky } from '../pm-plugins/utils/drag-handle-positions';
29
29
  import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
30
- import { ACTIVE_QUICK_INSERT_ATTR, QUICK_INSERT_DIMENSIONS, QUICK_INSERT_HEIGHT, QUICK_INSERT_LEFT_OFFSET, QUICK_INSERT_WIDTH, rootElementGap, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
30
+ import { ACTIVE_QUICK_INSERT_ATTR, ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, QUICK_INSERT_DIMENSIONS, QUICK_INSERT_HEIGHT, QUICK_INSERT_LEFT_OFFSET, QUICK_INSERT_WIDTH, rootElementGap, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
31
31
  import { refreshAnchorName } from './utils/anchor-name';
32
32
  import { isInTextSelection, isNestedNodeSelected, isNonEditableBlock, isSelectionInNode } from './utils/document-checks';
33
33
  import { getAnchorAttrName } from './utils/dom-attr-name';
@@ -145,15 +145,23 @@ var tooltipContainerStylesImprovedStickyHeaderWithMarksFix = css({
145
145
 
146
146
  // TODO: ED-26959 - Share prop types between DragHandle - generic enough to create a type for block control decoration
147
147
 
148
- export var TypeAheadControl = function TypeAheadControl(_ref) {
149
- var view = _ref.view,
150
- api = _ref.api,
151
- formatMessage = _ref.formatMessage,
152
- getPos = _ref.getPos,
153
- anchorName = _ref.anchorName,
154
- rootAnchorName = _ref.rootAnchorName,
155
- rootNodeType = _ref.rootNodeType,
156
- anchorRectCache = _ref.anchorRectCache;
148
+ var getQuickInsertAnchorReference = function getQuickInsertAnchorReference(_ref) {
149
+ var edge = _ref.edge,
150
+ safeAnchorName = _ref.safeAnchorName;
151
+ if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
152
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ", anchor(").concat(ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, " ").concat(edge, "))");
153
+ }
154
+ return "anchor(".concat(safeAnchorName, " ").concat(edge, ")");
155
+ };
156
+ export var TypeAheadControl = function TypeAheadControl(_ref2) {
157
+ var view = _ref2.view,
158
+ api = _ref2.api,
159
+ formatMessage = _ref2.formatMessage,
160
+ getPos = _ref2.getPos,
161
+ anchorName = _ref2.anchorName,
162
+ rootAnchorName = _ref2.rootAnchorName,
163
+ rootNodeType = _ref2.rootNodeType,
164
+ anchorRectCache = _ref2.anchorRectCache;
157
165
  var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['featureFlags'], function (states) {
158
166
  var _states$featureFlagsS;
159
167
  return {
@@ -211,12 +219,16 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
211
219
  }
212
220
  var isEdgeCase = (hasResizer || isExtension || isEmbedCard || isBlockCard) && innerContainer;
213
221
  var isSticky = shouldBeSticky(rootNodeType);
214
- var bottom = getControlBottomCSSValue(safeAnchorName || anchorName, isSticky, true);
222
+ var anchorStart = getQuickInsertAnchorReference({
223
+ edge: 'start',
224
+ safeAnchorName: safeAnchorName
225
+ });
226
+ var bottom = getControlBottomCSSValue(safeAnchorName || anchorName, isSticky, true, false, ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME);
215
227
  if (supportsAnchor) {
216
228
  return _objectSpread({
217
- left: isEdgeCase ? "calc(anchor(".concat(safeAnchorName, " start) + ").concat(getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + -").concat(QUICK_INSERT_LEFT_OFFSET, "px)") : "calc(anchor(".concat(safeAnchorName, " start) - ").concat(QUICK_INSERT_DIMENSIONS.width, "px - ").concat(rootElementGap(rootNodeType), "px + -").concat(QUICK_INSERT_LEFT_OFFSET, "px)"),
229
+ left: isEdgeCase ? "calc(".concat(anchorStart, " + ").concat(getLeftPositionForRootElement(dom, rootNodeType, QUICK_INSERT_DIMENSIONS, innerContainer, isMacroInteractionUpdates), " + -").concat(QUICK_INSERT_LEFT_OFFSET, "px)") : "calc(".concat(anchorStart, " - ").concat(QUICK_INSERT_DIMENSIONS.width, "px - ").concat(rootElementGap(rootNodeType), "px + -").concat(QUICK_INSERT_LEFT_OFFSET, "px)"),
218
230
  // small text requires further tweaking to positioning, re-using existing methods to calculate to keep it unified with drag handle
219
- top: "calc(anchor(".concat(safeAnchorName, " start) + ").concat(topPositionAdjustment(node && node.type.name === 'paragraph' && expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getNodeTypeWithLevel(node) : rootNodeType), "px)")
231
+ top: "calc(".concat(anchorStart, " + ").concat(topPositionAdjustment(node && node.type.name === 'paragraph' && expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getNodeTypeWithLevel(node) : rootNodeType), "px)")
220
232
  }, bottom);
221
233
  }
222
234
 
@@ -281,8 +293,8 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
281
293
  var newPos =
282
294
  //if the current selection is selected from right to left, then set the selection to the start of the paragraph
283
295
  currentSelection.anchor === currentSelection.to ? currentParagraphNode.pos : currentParagraphNode.pos + currentParagraphNode.node.nodeSize - 1;
284
- api.core.actions.execute(function (_ref2) {
285
- var tr = _ref2.tr;
296
+ api.core.actions.execute(function (_ref3) {
297
+ var tr = _ref3.tr;
286
298
  tr.setSelection(TextSelection.create(view.state.selection.$from.doc, newPos));
287
299
  return tr;
288
300
  });
@@ -296,8 +308,8 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
296
308
  // otherwise need to force the selection to be at the start of the node, because
297
309
  // prosemirror is keeping it as NodeSelection for nested nodes. Do this to keep it
298
310
  // consistent NodeSelection for root level nodes.
299
- api.core.actions.execute(function (_ref3) {
300
- var tr = _ref3.tr;
311
+ api.core.actions.execute(function (_ref4) {
312
+ var tr = _ref4.tr;
301
313
  createNewLine(view.state.selection.from)({
302
314
  tr: tr
303
315
  });
@@ -309,8 +321,8 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
309
321
  if (currentSelection instanceof CellSelection) {
310
322
  // find the last inline position in the selection
311
323
  var lastInlinePosition = TextSelection.near(view.state.selection.$to, -1);
312
- lastInlinePosition && api.core.actions.execute(function (_ref4) {
313
- var tr = _ref4.tr;
324
+ lastInlinePosition && api.core.actions.execute(function (_ref5) {
325
+ var tr = _ref5.tr;
314
326
  if (!(lastInlinePosition instanceof TextSelection)) {
315
327
  // this will create a new line after the node
316
328
  createNewLine(lastInlinePosition.from)({
@@ -369,16 +381,16 @@ export var TypeAheadControl = function TypeAheadControl(_ref) {
369
381
  css: [tooltipContainerStyles, expValEquals('platform_editor_table_sticky_header_improvements', 'cohort', 'test_with_overflow') ? tooltipContainerImprovedStylesStickyHeader : tooltipContainerStylesStickyHeader, expValEquals('platform_editor_table_sticky_header_improvements', 'cohort', 'test_with_overflow') ? tooltipContainerStylesImprovedStickyHeaderWithMarksFix : tooltipContainerStylesStickyHeaderWithMarksFix]
370
382
  }, tooltipPressable()));
371
383
  };
372
- export var QuickInsertWithVisibility = function QuickInsertWithVisibility(_ref5) {
373
- var view = _ref5.view,
374
- api = _ref5.api,
375
- formatMessage = _ref5.formatMessage,
376
- getPos = _ref5.getPos,
377
- nodeType = _ref5.nodeType,
378
- anchorName = _ref5.anchorName,
379
- rootAnchorName = _ref5.rootAnchorName,
380
- rootNodeType = _ref5.rootNodeType,
381
- anchorRectCache = _ref5.anchorRectCache;
384
+ export var QuickInsertWithVisibility = function QuickInsertWithVisibility(_ref6) {
385
+ var view = _ref6.view,
386
+ api = _ref6.api,
387
+ formatMessage = _ref6.formatMessage,
388
+ getPos = _ref6.getPos,
389
+ nodeType = _ref6.nodeType,
390
+ anchorName = _ref6.anchorName,
391
+ rootAnchorName = _ref6.rootAnchorName,
392
+ rootNodeType = _ref6.rootNodeType,
393
+ anchorRectCache = _ref6.anchorRectCache;
382
394
  var rightSideControlsEnabled = useSharedPluginStateWithSelector(api, ['blockControls'], function (states) {
383
395
  var _states$blockControls, _states$blockControls2;
384
396
  return {
@@ -3,7 +3,7 @@ export declare const getTopPosition: (dom: HTMLElement | null, type?: string) =>
3
3
  export declare const getLeftPosition: (dom: HTMLElement | null, type: string, innerContainer?: HTMLElement | null, macroInteractionUpdates?: boolean, parentType?: string) => string;
4
4
  export declare const getNodeHeight: (dom: HTMLElement | null, anchor: string, anchorRectCache?: AnchorRectCache) => number | undefined;
5
5
  export declare const shouldBeSticky: (nodeType: string) => boolean;
6
- export declare const getControlBottomCSSValue: (anchor: string, isSticky: boolean, isTopLevelNode: boolean, isLayoutColumn?: boolean) => {
6
+ export declare const getControlBottomCSSValue: (anchor: string, isSticky: boolean, isTopLevelNode: boolean, isLayoutColumn?: boolean, fallbackAnchor?: string) => {
7
7
  bottom: String;
8
8
  };
9
9
  export declare const getControlHeightCSSValue: (nodeHeight: number, isSticky: boolean, isTopLevelNode: boolean, fallbackPxHeight: string, isLayoutColumn?: boolean) => {
@@ -1,5 +1,7 @@
1
1
  export declare const ACTIVE_DRAG_HANDLE_ATTR = "data-active-drag-handle";
2
2
  export declare const ACTIVE_QUICK_INSERT_ATTR = "data-active-quick-insert";
3
+ export declare const ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME = "--editor-block-controls-active-drag-handle-anchor";
4
+ export declare const ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME = "--editor-block-controls-active-quick-insert-anchor";
3
5
  export declare const DRAG_HANDLE_HEIGHT = 24;
4
6
  export declare const DRAG_HANDLE_BORDER_RADIUS = 4;
5
7
  export declare const DRAG_HANDLE_ZINDEX: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "13.2.17",
3
+ "version": "13.3.1",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -46,10 +46,10 @@
46
46
  "@atlaskit/pragmatic-drag-and-drop": "^2.0.0",
47
47
  "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^3.0.0",
48
48
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^4.1.0",
49
- "@atlaskit/primitives": "^22.1.0",
49
+ "@atlaskit/primitives": "^22.2.0",
50
50
  "@atlaskit/theme": "^26.1.0",
51
- "@atlaskit/tmp-editor-statsig": "^132.0.0",
52
- "@atlaskit/tokens": "^16.2.0",
51
+ "@atlaskit/tmp-editor-statsig": "^133.0.0",
52
+ "@atlaskit/tokens": "^16.3.0",
53
53
  "@atlaskit/tooltip": "^23.1.0",
54
54
  "@babel/runtime": "^7.0.0",
55
55
  "@emotion/react": "^11.7.1",
@@ -59,7 +59,7 @@
59
59
  "uuid": "^3.1.0"
60
60
  },
61
61
  "peerDependencies": {
62
- "@atlaskit/editor-common": "^116.35.0",
62
+ "@atlaskit/editor-common": "^116.39.0",
63
63
  "react": "^18.2.0",
64
64
  "react-dom": "^18.2.0",
65
65
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"