@atlaskit/editor-plugin-block-controls 12.1.1 → 12.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/editor-commands/move-node.js +2 -1
  3. package/dist/cjs/pm-plugins/decorations-drag-handle.js +19 -1
  4. package/dist/cjs/pm-plugins/decorations-drop-target.js +2 -1
  5. package/dist/cjs/pm-plugins/decorations-quick-insert-button.js +19 -1
  6. package/dist/cjs/pm-plugins/main.js +77 -19
  7. package/dist/cjs/ui/consts.js +3 -1
  8. package/dist/cjs/ui/drag-handle.js +9 -0
  9. package/dist/cjs/ui/global-styles.js +13 -1
  10. package/dist/cjs/ui/quick-insert-button.js +8 -0
  11. package/dist/es2019/editor-commands/move-node.js +2 -1
  12. package/dist/es2019/pm-plugins/decorations-drag-handle.js +14 -0
  13. package/dist/es2019/pm-plugins/decorations-drop-target.js +2 -1
  14. package/dist/es2019/pm-plugins/decorations-quick-insert-button.js +13 -0
  15. package/dist/es2019/pm-plugins/main.js +79 -21
  16. package/dist/es2019/ui/consts.js +2 -0
  17. package/dist/es2019/ui/drag-handle.js +10 -1
  18. package/dist/es2019/ui/global-styles.js +17 -2
  19. package/dist/es2019/ui/quick-insert-button.js +9 -1
  20. package/dist/esm/editor-commands/move-node.js +2 -1
  21. package/dist/esm/pm-plugins/decorations-drag-handle.js +18 -0
  22. package/dist/esm/pm-plugins/decorations-drop-target.js +2 -1
  23. package/dist/esm/pm-plugins/decorations-quick-insert-button.js +18 -0
  24. package/dist/esm/pm-plugins/main.js +79 -21
  25. package/dist/esm/ui/consts.js +2 -0
  26. package/dist/esm/ui/drag-handle.js +10 -1
  27. package/dist/esm/ui/global-styles.js +14 -2
  28. package/dist/esm/ui/quick-insert-button.js +9 -1
  29. package/dist/types/pm-plugins/decorations-drag-handle.d.ts +7 -0
  30. package/dist/types/pm-plugins/decorations-quick-insert-button.d.ts +7 -0
  31. package/dist/types/ui/consts.d.ts +2 -0
  32. package/dist/types-ts4.5/pm-plugins/decorations-drag-handle.d.ts +7 -0
  33. package/dist/types-ts4.5/pm-plugins/decorations-quick-insert-button.d.ts +7 -0
  34. package/dist/types-ts4.5/ui/consts.d.ts +2 -0
  35. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 12.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`4c2645b77929d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4c2645b77929d) -
8
+ [ux] EDITOR-7346 add ai and diff plugin support for panel_c1
9
+ - Updated dependencies
10
+
11
+ ## 12.2.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`1f87c5cc71aa3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1f87c5cc71aa3) -
16
+ Improve reliability of editor controls positioning by using ProseMirror node decorations to apply
17
+ CSS anchor-name, replacing fragile CSS adjacency selectors. Gated behind
18
+ platform_editor_controls_reliable_anchor experiment.
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
3
24
  ## 12.1.1
4
25
 
5
26
  ### Patch Changes
@@ -13,6 +13,7 @@ var _selection = require("@atlaskit/editor-common/selection");
13
13
  var _transforms = require("@atlaskit/editor-common/transforms");
14
14
  var _types = require("@atlaskit/editor-common/types");
15
15
  var _utils = require("@atlaskit/editor-common/utils");
16
+ var _nodeTypeUtils = require("@atlaskit/editor-common/utils/node-type-utils");
16
17
  var _model = require("@atlaskit/editor-prosemirror/model");
17
18
  var _state = require("@atlaskit/editor-prosemirror/state");
18
19
  var _transform = require("@atlaskit/editor-prosemirror/transform");
@@ -78,7 +79,7 @@ var nodesSupportDragLayoutColumnInto = ['tableCell', 'tableHeader', 'panel', 'ex
78
79
  var isDragLayoutColumnIntoSupportedNodes = function isDragLayoutColumnIntoSupportedNodes($from, $to) {
79
80
  var _$from$nodeAfter;
80
81
  var isTopLevel = $to.depth === 0;
81
- var toParentTypeName = (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (0, _utils.getBaseNodeTypeName)($to.parent.type) : $to.parent.type.name;
82
+ var toParentTypeName = (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (0, _nodeTypeUtils.getBaseNodeTypeName)($to.parent.type) : $to.parent.type.name;
82
83
  var isDragIntoNodes = nodesSupportDragLayoutColumnInto.includes(toParentTypeName);
83
84
  var supportedCondition = isDragIntoNodes || isTopLevel;
84
85
  return ((_$from$nodeAfter = $from.nodeAfter) === null || _$from$nodeAfter === void 0 ? void 0 : _$from$nodeAfter.type.name) === 'layoutColumn' && $from.parent.type.name === 'layoutSection' && supportedCondition;
@@ -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.findHandleDec = exports.emptyParagraphNodeDecorations = exports.dragHandleDecoration = void 0;
7
+ exports.findHandleDec = exports.findActiveDragHandleNodeDec = exports.emptyParagraphNodeDecorations = exports.dragHandleDecoration = exports.createActiveDragHandleNodeDecoration = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = require("react");
10
10
  var _bindEventListener = require("bind-event-listener");
@@ -14,11 +14,29 @@ var _view = require("@atlaskit/editor-prosemirror/view");
14
14
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
15
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
16
16
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
17
+ var _consts = require("../ui/consts");
17
18
  var _dragHandle = require("../ui/drag-handle");
18
19
  var _decorationsCommon = require("./decorations-common");
19
20
  var _marks = require("./utils/marks");
20
21
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
21
22
 
23
+ var TYPE_ACTIVE_HANDLE_DEC = 'active-drag-handle-node';
24
+
25
+ /**
26
+ * Creates a Decoration.node that marks the active node with `data-active-drag-handle="true"`.
27
+ * The CSS in staticControlsAnchorStyles then applies `anchor-name` to this attribute,
28
+ * which is more reliable than the adjacency-selector approach in dragHandlerAnchorStyles.
29
+ */
30
+ var createActiveDragHandleNodeDecoration = exports.createActiveDragHandleNodeDecoration = function createActiveDragHandleNodeDecoration(pos, nodeSize) {
31
+ return _view.Decoration.node(pos, pos + nodeSize, (0, _defineProperty2.default)({}, _consts.ACTIVE_DRAG_HANDLE_ATTR, 'true'), {
32
+ type: TYPE_ACTIVE_HANDLE_DEC
33
+ });
34
+ };
35
+ var findActiveDragHandleNodeDec = exports.findActiveDragHandleNodeDec = function findActiveDragHandleNodeDec(decorations, from, to) {
36
+ return decorations.find(from, to, function (spec) {
37
+ return spec.type === TYPE_ACTIVE_HANDLE_DEC;
38
+ });
39
+ };
22
40
  var emptyParagraphNodeDecorations = exports.emptyParagraphNodeDecorations = function emptyParagraphNodeDecorations() {
23
41
  var anchorName = "--node-anchor-paragraph-0";
24
42
  var style = "anchor-name: ".concat(anchorName, "; margin-top: 0px;");
@@ -12,6 +12,7 @@ var _memoizeOne = _interopRequireDefault(require("memoize-one"));
12
12
  var _uuid = _interopRequireDefault(require("uuid"));
13
13
  var _selection = require("@atlaskit/editor-common/selection");
14
14
  var _utils = require("@atlaskit/editor-common/utils");
15
+ var _nodeTypeUtils = require("@atlaskit/editor-common/utils/node-type-utils");
15
16
  var _view = require("@atlaskit/editor-prosemirror/view");
16
17
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
17
18
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
@@ -250,7 +251,7 @@ var dropTargetDecorations = exports.dropTargetDecorations = function dropTargetD
250
251
  pushNodeStack(node, depth);
251
252
  return false; //not valid pos, so nested not valid either
252
253
  }
253
- var parentTypeName = (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (0, _utils.getBaseNodeTypeName)(parent.type) : parent.type.name;
254
+ var parentTypeName = (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (0, _nodeTypeUtils.getBaseNodeTypeName)(parent.type) : parent.type.name;
254
255
  if (parent.lastChild === node && !(0, _utils.isEmptyParagraph)(node) && parentTypesWithEndDropTarget.includes(parentTypeName)) {
255
256
  endPos = pos + node.nodeSize;
256
257
  }
@@ -4,23 +4,41 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.quickInsertButtonDecoration = exports.findQuickInsertInsertButtonDecoration = void 0;
7
+ exports.quickInsertButtonDecoration = exports.findQuickInsertInsertButtonDecoration = exports.findActiveQuickInsertNodeDec = exports.createActiveQuickInsertNodeDecoration = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
8
9
  var _react = require("react");
9
10
  var _uuid = _interopRequireDefault(require("uuid"));
10
11
  var _view = require("@atlaskit/editor-prosemirror/view");
11
12
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
13
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
13
14
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
15
+ var _consts = require("../ui/consts");
14
16
  var _quickInsertButton = require("../ui/quick-insert-button");
15
17
  var _marks = require("./utils/marks");
16
18
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
17
19
 
18
20
  var TYPE_QUICK_INSERT = 'INSERT_BUTTON';
21
+ var TYPE_ACTIVE_QUICK_INSERT_NODE = 'active-quick-insert-node';
19
22
  var findQuickInsertInsertButtonDecoration = exports.findQuickInsertInsertButtonDecoration = function findQuickInsertInsertButtonDecoration(decorations, from, to) {
20
23
  return decorations.find(from, to, function (spec) {
21
24
  return spec.type === TYPE_QUICK_INSERT;
22
25
  });
23
26
  };
27
+ /**
28
+ * Creates a Decoration.node that marks the active node with `data-active-quick-insert="true"`.
29
+ * The CSS in staticControlsAnchorStyles applies `anchor-name` to this attribute directly,
30
+ * replacing the unreliable adjacency selector `[block-ctrl-quick-insert-button] + *`.
31
+ */
32
+ var createActiveQuickInsertNodeDecoration = exports.createActiveQuickInsertNodeDecoration = function createActiveQuickInsertNodeDecoration(pos, nodeSize) {
33
+ return _view.Decoration.node(pos, pos + nodeSize, (0, _defineProperty2.default)({}, _consts.ACTIVE_QUICK_INSERT_ATTR, 'true'), {
34
+ type: TYPE_ACTIVE_QUICK_INSERT_NODE
35
+ });
36
+ };
37
+ var findActiveQuickInsertNodeDec = exports.findActiveQuickInsertNodeDec = function findActiveQuickInsertNodeDec(decorations, from, to) {
38
+ return decorations.find(from, to, function (spec) {
39
+ return spec.type === TYPE_ACTIVE_QUICK_INSERT_NODE;
40
+ });
41
+ };
24
42
  var quickInsertButtonDecoration = exports.quickInsertButtonDecoration = function quickInsertButtonDecoration(_ref) {
25
43
  var api = _ref.api,
26
44
  formatMessage = _ref.formatMessage,
@@ -445,21 +445,32 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
445
445
  }
446
446
  }
447
447
  if (shouldRemoveHandle) {
448
- var _activeNode5, _activeNode6;
448
+ var _activeNode5, _activeNode6, _activeNode7;
449
449
  var oldHandle = (0, _decorationsDragHandle.findHandleDec)(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.pos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.pos);
450
450
  decorations = decorations.remove(oldHandle);
451
+ // When removing the handle, also remove the anchor-marker node decorations
452
+ // (data-active-drag-handle / data-active-quick-insert) so the DOM attributes
453
+ // don't linger on nodes that are no longer active.
454
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true) && ((_activeNode7 = activeNode) === null || _activeNode7 === void 0 ? void 0 : _activeNode7.pos) !== undefined) {
455
+ var oldActiveNodeDec = (0, _decorationsDragHandle.findActiveDragHandleNodeDec)(decorations, activeNode.pos, activeNode.pos);
456
+ decorations = decorations.remove(oldActiveNodeDec);
457
+ if (activeNode.rootPos !== undefined) {
458
+ var oldActiveQuickInsertDec = (0, _decorationsQuickInsertButton.findActiveQuickInsertNodeDec)(decorations, activeNode.rootPos, activeNode.rootPos);
459
+ decorations = decorations.remove(oldActiveQuickInsertDec);
460
+ }
461
+ }
451
462
  // platform_editor_controls note: enables quick insert
452
463
  if (flags.toolbarFlagsEnabled && quickInsertButtonEnabled) {
453
- var _activeNode7, _activeNode8;
454
- var oldQuickInsertButton = (0, _decorationsQuickInsertButton.findQuickInsertInsertButtonDecoration)(decorations, (_activeNode7 = activeNode) === null || _activeNode7 === void 0 ? void 0 : _activeNode7.rootPos, (_activeNode8 = activeNode) === null || _activeNode8 === void 0 ? void 0 : _activeNode8.rootPos);
464
+ var _activeNode8, _activeNode9;
465
+ var oldQuickInsertButton = (0, _decorationsQuickInsertButton.findQuickInsertInsertButtonDecoration)(decorations, (_activeNode8 = activeNode) === null || _activeNode8 === void 0 ? void 0 : _activeNode8.rootPos, (_activeNode9 = activeNode) === null || _activeNode9 === void 0 ? void 0 : _activeNode9.rootPos);
455
466
  decorations = decorations.remove(oldQuickInsertButton);
456
467
  var _iterator = _createForOfIteratorHelper(nodeDecorationRegistry),
457
468
  _step;
458
469
  try {
459
470
  var _loop2 = function _loop2() {
460
- var _activeNode1, _activeNode10;
471
+ var _activeNode10, _activeNode11;
461
472
  var factory = _step.value;
462
- var old = decorations.find((_activeNode1 = activeNode) === null || _activeNode1 === void 0 ? void 0 : _activeNode1.rootPos, (_activeNode10 = activeNode) === null || _activeNode10 === void 0 ? void 0 : _activeNode10.rootPos, function (spec) {
473
+ var old = decorations.find((_activeNode10 = activeNode) === null || _activeNode10 === void 0 ? void 0 : _activeNode10.rootPos, (_activeNode11 = activeNode) === null || _activeNode11 === void 0 ? void 0 : _activeNode11.rootPos, function (spec) {
463
474
  return spec.type === factory.type;
464
475
  });
465
476
  decorations = decorations.remove(old);
@@ -479,8 +490,8 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
479
490
  var _loop = function _loop() {
480
491
  var factory = _step2.value;
481
492
  if (factory.showInViewMode) {
482
- var _activeNode9, _activeNode0;
483
- var old = decorations.find((_activeNode9 = activeNode) === null || _activeNode9 === void 0 ? void 0 : _activeNode9.rootPos, (_activeNode0 = activeNode) === null || _activeNode0 === void 0 ? void 0 : _activeNode0.rootPos, function (spec) {
493
+ var _activeNode0, _activeNode1;
494
+ var old = decorations.find((_activeNode0 = activeNode) === null || _activeNode0 === void 0 ? void 0 : _activeNode0.rootPos, (_activeNode1 = activeNode) === null || _activeNode1 === void 0 ? void 0 : _activeNode1.rootPos, function (spec) {
484
495
  return spec.type === factory.type;
485
496
  });
486
497
  decorations = decorations.remove(old);
@@ -497,10 +508,10 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
497
508
  }
498
509
  }
499
510
  } else if (api) {
500
- var _latestActiveNode5, _latestActiveNode1;
511
+ var _latestActiveNode5, _latestActiveNode10;
501
512
  if (shouldRecreateHandle && (!rightSideControlsEnabled || !isViewMode)) {
502
- var _activeNode11, _activeNode12, _latestActiveNode, _latestActiveNode2, _latestActiveNode3, _latestActiveNode4;
503
- var _oldHandle = (0, _decorationsDragHandle.findHandleDec)(decorations, (_activeNode11 = activeNode) === null || _activeNode11 === void 0 ? void 0 : _activeNode11.pos, (_activeNode12 = activeNode) === null || _activeNode12 === void 0 ? void 0 : _activeNode12.pos);
513
+ var _activeNode12, _activeNode13, _latestActiveNode, _latestActiveNode2, _latestActiveNode3, _latestActiveNode4;
514
+ var _oldHandle = (0, _decorationsDragHandle.findHandleDec)(decorations, (_activeNode12 = activeNode) === null || _activeNode12 === void 0 ? void 0 : _activeNode12.pos, (_activeNode13 = activeNode) === null || _activeNode13 === void 0 ? void 0 : _activeNode13.pos);
504
515
  decorations = decorations.remove(_oldHandle);
505
516
  var handleDec = (0, _decorationsDragHandle.dragHandleDecoration)({
506
517
  api: api,
@@ -514,12 +525,44 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
514
525
  editorState: newState
515
526
  });
516
527
  decorations = decorations.add(newState.doc, [handleDec]);
528
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
529
+ // Recreate the drag handle node decoration when the edit-mode node itself changed
530
+ // or its content was modified. Other triggers (editorSizeChanged, handleNeedsRedraw)
531
+ // don't move the decoration — DecorationSet.map() already remaps it correctly.
532
+ var needsNodeDecUpdate = activeNodeChanged || isActiveNodeModified;
533
+ if (needsNodeDecUpdate) {
534
+ var _newState$doc$nodeAt;
535
+ var nodeSize = (_newState$doc$nodeAt = newState.doc.nodeAt(latestActiveNode.pos)) === null || _newState$doc$nodeAt === void 0 ? void 0 : _newState$doc$nodeAt.nodeSize;
536
+ if (nodeSize !== undefined) {
537
+ var _activeNode14, _activeNode15;
538
+ var _oldActiveNodeDec = (0, _decorationsDragHandle.findActiveDragHandleNodeDec)(decorations, (_activeNode14 = activeNode) === null || _activeNode14 === void 0 ? void 0 : _activeNode14.pos, (_activeNode15 = activeNode) === null || _activeNode15 === void 0 ? void 0 : _activeNode15.pos);
539
+ decorations = decorations.remove(_oldActiveNodeDec);
540
+ decorations = decorations.add(newState.doc, [(0, _decorationsDragHandle.createActiveDragHandleNodeDecoration)(latestActiveNode.pos, nodeSize)]);
541
+ }
542
+ }
543
+
544
+ // The quick-insert decoration lives on the root node (rootPos), which can change
545
+ // independently of the edit-mode node — e.g. when only editorSizeChanged fires but
546
+ // rootActiveNodeChanged is also true. So we use a separate, broader guard that
547
+ // includes rootActiveNodeChanged to avoid leaving the attribute on a stale root node.
548
+ var needsQuickInsertDecUpdate = activeNodeChanged || isActiveNodeModified || rootActiveNodeChanged;
549
+ if (needsQuickInsertDecUpdate && latestActiveNode.rootPos !== undefined) {
550
+ var _newState$doc$nodeAt2;
551
+ var rootNodeSize = (_newState$doc$nodeAt2 = newState.doc.nodeAt(latestActiveNode.rootPos)) === null || _newState$doc$nodeAt2 === void 0 ? void 0 : _newState$doc$nodeAt2.nodeSize;
552
+ if (rootNodeSize !== undefined) {
553
+ var _activeNode16, _activeNode17;
554
+ var _oldActiveQuickInsertDec = (0, _decorationsQuickInsertButton.findActiveQuickInsertNodeDec)(decorations, (_activeNode16 = activeNode) === null || _activeNode16 === void 0 ? void 0 : _activeNode16.rootPos, (_activeNode17 = activeNode) === null || _activeNode17 === void 0 ? void 0 : _activeNode17.rootPos);
555
+ decorations = decorations.remove(_oldActiveQuickInsertDec);
556
+ decorations = decorations.add(newState.doc, [(0, _decorationsQuickInsertButton.createActiveQuickInsertNodeDecoration)(latestActiveNode.rootPos, rootNodeSize)]);
557
+ }
558
+ }
559
+ }
517
560
  }
518
561
  if (shouldRecreateQuickInsertButton && ((_latestActiveNode5 = latestActiveNode) === null || _latestActiveNode5 === void 0 ? void 0 : _latestActiveNode5.rootPos) !== undefined &&
519
562
  // platform_editor_controls note: enables quick insert
520
563
  flags.toolbarFlagsEnabled && quickInsertButtonEnabled && (!rightSideControlsEnabled || !isViewMode)) {
521
- var _activeNode13, _activeNode14, _latestActiveNode6, _latestActiveNode7, _latestActiveNode8, _latestActiveNode9, _latestActiveNode0;
522
- var _oldQuickInsertButton = (0, _decorationsQuickInsertButton.findQuickInsertInsertButtonDecoration)(decorations, (_activeNode13 = activeNode) === null || _activeNode13 === void 0 ? void 0 : _activeNode13.rootPos, (_activeNode14 = activeNode) === null || _activeNode14 === void 0 ? void 0 : _activeNode14.rootPos);
564
+ var _activeNode18, _activeNode19, _latestActiveNode6, _latestActiveNode7, _latestActiveNode8, _latestActiveNode9, _latestActiveNode0, _latestActiveNode1;
565
+ var _oldQuickInsertButton = (0, _decorationsQuickInsertButton.findQuickInsertInsertButtonDecoration)(decorations, (_activeNode18 = activeNode) === null || _activeNode18 === void 0 ? void 0 : _activeNode18.rootPos, (_activeNode19 = activeNode) === null || _activeNode19 === void 0 ? void 0 : _activeNode19.rootPos);
523
566
  decorations = decorations.remove(_oldQuickInsertButton);
524
567
  var quickInsertButton = (0, _decorationsQuickInsertButton.quickInsertButtonDecoration)({
525
568
  api: api,
@@ -534,12 +577,27 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
534
577
  editorState: newState
535
578
  });
536
579
  decorations = decorations.add(newState.doc, [quickInsertButton]);
580
+
581
+ // Update quick insert node decoration when the quick insert button is recreated but
582
+ // the drag handle was NOT recreated (shouldRecreateHandle was false). When
583
+ // shouldRecreateHandle is true, the block above already handles this.
584
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !shouldRecreateHandle && ((_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.rootPos) !== undefined) {
585
+ var _activeNode20, _newState$doc$nodeAt3;
586
+ if (((_activeNode20 = activeNode) === null || _activeNode20 === void 0 ? void 0 : _activeNode20.rootPos) !== undefined) {
587
+ var _oldActiveQuickInsertDec2 = (0, _decorationsQuickInsertButton.findActiveQuickInsertNodeDec)(decorations, activeNode.rootPos, activeNode.rootPos);
588
+ decorations = decorations.remove(_oldActiveQuickInsertDec2);
589
+ }
590
+ var _rootNodeSize = (_newState$doc$nodeAt3 = newState.doc.nodeAt(latestActiveNode.rootPos)) === null || _newState$doc$nodeAt3 === void 0 ? void 0 : _newState$doc$nodeAt3.nodeSize;
591
+ if (_rootNodeSize !== undefined) {
592
+ decorations = decorations.add(newState.doc, [(0, _decorationsQuickInsertButton.createActiveQuickInsertNodeDecoration)(latestActiveNode.rootPos, _rootNodeSize)]);
593
+ }
594
+ }
537
595
  if (rightSideControlsEnabled) {
538
596
  var _iterator3 = _createForOfIteratorHelper(nodeDecorationRegistry),
539
597
  _step3;
540
598
  try {
541
599
  var _loop3 = function _loop3() {
542
- var _activeNode15, _activeNode16;
600
+ var _activeNode21, _activeNode22;
543
601
  var factory = _step3.value;
544
602
  if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
545
603
  return 0; // continue
@@ -553,7 +611,7 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
553
611
  rootAnchorName: latestActiveNode.rootAnchorName,
554
612
  rootNodeType: latestActiveNode.rootNodeType
555
613
  };
556
- var old = decorations.find((_activeNode15 = activeNode) === null || _activeNode15 === void 0 ? void 0 : _activeNode15.rootPos, (_activeNode16 = activeNode) === null || _activeNode16 === void 0 ? void 0 : _activeNode16.rootPos, function (spec) {
614
+ var old = decorations.find((_activeNode21 = activeNode) === null || _activeNode21 === void 0 ? void 0 : _activeNode21.rootPos, (_activeNode22 = activeNode) === null || _activeNode22 === void 0 ? void 0 : _activeNode22.rootPos, function (spec) {
557
615
  return spec.type === factory.type;
558
616
  });
559
617
  decorations = decorations.remove(old);
@@ -598,7 +656,7 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
598
656
  }
599
657
 
600
658
  // In view mode (edit/live pages), show right-side controls on block hover (without drag handle or quick insert)
601
- var rootPos = (_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.rootPos;
659
+ var rootPos = (_latestActiveNode10 = latestActiveNode) === null || _latestActiveNode10 === void 0 ? void 0 : _latestActiveNode10.rootPos;
602
660
  // rootPos is computed using the same logic as the floating insert menu, so it always points to a top-level (doc child) block when defined.
603
661
  var isDocLevel = rootPos !== undefined && !isNaN(rootPos);
604
662
  if (isViewMode && isDocLevel && flags.toolbarFlagsEnabled && rightSideControlsEnabled) {
@@ -719,15 +777,15 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
719
777
  var newActiveNode;
720
778
  // platform_editor_controls note: enables quick insert
721
779
  if (flags.toolbarFlagsEnabled) {
722
- var _latestActiveNode10, _latestActiveNode11;
780
+ var _latestActiveNode11, _latestActiveNode12;
723
781
  // remove isEmptyDoc check and let decorations render and determine their own visibility
724
782
  // In view mode with right-side controls we render node decorations (right-edge button), not the
725
783
  // handle - so findHandleDec is always empty. Don't clear activeNode in that case.
726
- var hasHandleOrViewModeControls = (0, _decorationsDragHandle.findHandleDec)(decorations, (_latestActiveNode10 = latestActiveNode) === null || _latestActiveNode10 === void 0 ? void 0 : _latestActiveNode10.pos, (_latestActiveNode11 = latestActiveNode) === null || _latestActiveNode11 === void 0 ? void 0 : _latestActiveNode11.pos).length > 0 || isViewMode && rightSideControlsEnabled;
784
+ var hasHandleOrViewModeControls = (0, _decorationsDragHandle.findHandleDec)(decorations, (_latestActiveNode11 = latestActiveNode) === null || _latestActiveNode11 === void 0 ? void 0 : _latestActiveNode11.pos, (_latestActiveNode12 = latestActiveNode) === null || _latestActiveNode12 === void 0 ? void 0 : _latestActiveNode12.pos).length > 0 || isViewMode && rightSideControlsEnabled;
727
785
  newActiveNode = meta !== null && meta !== void 0 && meta.editorBlurred || !(meta !== null && meta !== void 0 && meta.activeNode) && !hasHandleOrViewModeControls ? null : latestActiveNode;
728
786
  } else {
729
- var _latestActiveNode12, _latestActiveNode13;
730
- newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && (0, _decorationsDragHandle.findHandleDec)(decorations, (_latestActiveNode12 = latestActiveNode) === null || _latestActiveNode12 === void 0 ? void 0 : _latestActiveNode12.pos, (_latestActiveNode13 = latestActiveNode) === null || _latestActiveNode13 === void 0 ? void 0 : _latestActiveNode13.pos).length === 0 ? null : latestActiveNode;
787
+ var _latestActiveNode13, _latestActiveNode14;
788
+ newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && (0, _decorationsDragHandle.findHandleDec)(decorations, (_latestActiveNode13 = latestActiveNode) === null || _latestActiveNode13 === void 0 ? void 0 : _latestActiveNode13.pos, (_latestActiveNode14 = latestActiveNode) === null || _latestActiveNode14 === void 0 ? void 0 : _latestActiveNode14.pos).length === 0 ? null : latestActiveNode;
731
789
  }
732
790
  var isMenuOpenNew = isMenuOpen;
733
791
  if ((0, _experiments.editorExperiment)('platform_editor_block_menu', true)) {
@@ -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 = 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_ATTR = exports.ACTIVE_DRAG_HANDLE_ATTR = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _styles = require("@atlaskit/editor-common/styles");
10
10
  var _utils = require("@atlaskit/editor-common/utils");
@@ -12,6 +12,8 @@ var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
12
12
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
13
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
14
14
  var _dropTargetMarginMap;
15
+ var ACTIVE_DRAG_HANDLE_ATTR = exports.ACTIVE_DRAG_HANDLE_ATTR = 'data-active-drag-handle';
16
+ var ACTIVE_QUICK_INSERT_ATTR = exports.ACTIVE_QUICK_INSERT_ATTR = 'data-active-quick-insert';
15
17
  var DRAG_HANDLE_HEIGHT = exports.DRAG_HANDLE_HEIGHT = 24;
16
18
  var DRAG_HANDLE_BORDER_RADIUS = exports.DRAG_HANDLE_BORDER_RADIUS = 4;
17
19
  var DRAG_HANDLE_ZINDEX = exports.DRAG_HANDLE_ZINDEX = _editorSharedStyles.akRichMediaResizeZIndex + _editorSharedStyles.akEditorUnitZIndex; //place above legacy resizer
@@ -827,6 +827,15 @@ var DragHandle = exports.DragHandle = function DragHandle(_ref) {
827
827
  anchorName: anchorName
828
828
  }) : anchorName;
829
829
  var dom = view.dom.querySelector("[".concat((0, _domAttrName.getAnchorAttrName)(), "=\"").concat(safeAnchorName, "\"]"));
830
+
831
+ // Defence-in-depth guard: since the node decoration sets data-active-drag-handle on the
832
+ // active node, we check for it directly. This is a cheap DOM attribute read (no reflow,
833
+ // no style recalculation) and hides the control if the decoration hasn't been applied yet.
834
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !(dom !== null && dom !== void 0 && dom.hasAttribute(_consts2.ACTIVE_DRAG_HANDLE_ATTR))) {
835
+ return {
836
+ display: 'none'
837
+ };
838
+ }
830
839
  var hasResizer = nodeType === 'table' || nodeType === 'mediaSingle';
831
840
  var isExtension = nodeType === 'extension' || nodeType === 'bodiedExtension' || nodeType === 'multiBodiedExtension' && (0, _platformFeatureFlags.fg)('confluence_frontend_native_tabs_extension');
832
841
  var isBlockCard = nodeType === 'blockCard' && !!blockCardWidth;
@@ -363,6 +363,18 @@ var dragHandlerAnchorStyles = (0, _react.css)({
363
363
  })
364
364
  }
365
365
  });
366
+ var activeControlsSelector = "[".concat(_consts.ACTIVE_DRAG_HANDLE_ATTR, "], [").concat(_consts.ACTIVE_QUICK_INSERT_ATTR, "]");
367
+
368
+ // Applies anchor-name via node decoration attributes rather than adjacency CSS selectors.
369
+ // This is more reliable than dragHandlerAnchorStyles which depends on DOM structure.
370
+ // Only nodes decorated with data-active-drag-handle / data-active-quick-insert get anchor-name.
371
+ var staticControlsAnchorStyles = (0, _react.css)({
372
+ // 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
+ })
377
+ });
366
378
 
367
379
  // Styles applied to nodes with anchors when dragging
368
380
  var dragAnchorStyles = (0, _react.css)({
@@ -411,6 +423,6 @@ var GlobalStylesWrapper = exports.GlobalStylesWrapper = function GlobalStylesWra
411
423
  exposure: true
412
424
  }) ? (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendHoverZoneReducedNext : extendHoverZoneReduced : undefined,
413
425
  // platform_editor_controls note: this allows drag handles to render on empty lines
414
- toolbarFlagsEnabled ? undefined : withInlineNodeStyle, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, (0, _experiments.editorExperiment)('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, topLevelNodeMarginStyles, (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && (0, _expValEquals.expValEquals)('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles)]
426
+ toolbarFlagsEnabled ? undefined : withInlineNodeStyle, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, (0, _experiments.editorExperiment)('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, topLevelNodeMarginStyles, (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && (0, _expValEquals.expValEquals)('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles), (0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true) ? staticControlsAnchorStyles : undefined]
415
427
  });
416
428
  };
@@ -190,6 +190,14 @@ var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref
190
190
  anchorName: rootAnchorName
191
191
  });
192
192
  var dom = view.dom.querySelector("[".concat((0, _domAttrName.getAnchorAttrName)(), "=\"").concat(safeAnchorName, "\"]"));
193
+
194
+ // Defence-in-depth guard: the node decoration sets data-active-quick-insert on the
195
+ // active root node. Check for it directly — cheap DOM attribute read, no reflow.
196
+ if ((0, _expValEquals.expValEquals)('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !(dom !== null && dom !== void 0 && dom.hasAttribute(_consts.ACTIVE_QUICK_INSERT_ATTR))) {
197
+ return {
198
+ display: 'none'
199
+ };
200
+ }
193
201
  var hasResizer = rootNodeType === 'table' || rootNodeType === 'mediaSingle';
194
202
  var isExtension = rootNodeType === 'extension' || rootNodeType === 'bodiedExtension' || rootNodeType === 'multiBodiedExtension' && (0, _platformFeatureFlags.fg)('confluence_frontend_native_tabs_extension');
195
203
  var isBlockCard = rootNodeType === 'blockCard';
@@ -4,7 +4,8 @@ import { blockControlsMessages } from '@atlaskit/editor-common/messages';
4
4
  import { expandSelectionBounds, GapCursorSelection } from '@atlaskit/editor-common/selection';
5
5
  import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
6
6
  import { DIRECTION } from '@atlaskit/editor-common/types';
7
- import { getBaseNodeTypeName, isEmptyParagraph } from '@atlaskit/editor-common/utils';
7
+ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
8
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
8
9
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
9
10
  import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
10
11
  import { Mapping, StepMap } from '@atlaskit/editor-prosemirror/transform';
@@ -7,9 +7,23 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
7
7
  import { fg } from '@atlaskit/platform-feature-flags';
8
8
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
9
9
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
10
+ import { ACTIVE_DRAG_HANDLE_ATTR } from '../ui/consts';
10
11
  import { DragHandle, DragHandleWithVisibility } from '../ui/drag-handle';
11
12
  import { TYPE_HANDLE_DEC, TYPE_NODE_DEC, unmountDecorations } from './decorations-common';
12
13
  import { getActiveBlockMarks, getMatchingBlockMarks } from './utils/marks';
14
+ const TYPE_ACTIVE_HANDLE_DEC = 'active-drag-handle-node';
15
+
16
+ /**
17
+ * Creates a Decoration.node that marks the active node with `data-active-drag-handle="true"`.
18
+ * The CSS in staticControlsAnchorStyles then applies `anchor-name` to this attribute,
19
+ * which is more reliable than the adjacency-selector approach in dragHandlerAnchorStyles.
20
+ */
21
+ export const createActiveDragHandleNodeDecoration = (pos, nodeSize) => Decoration.node(pos, pos + nodeSize, {
22
+ [ACTIVE_DRAG_HANDLE_ATTR]: 'true'
23
+ }, {
24
+ type: TYPE_ACTIVE_HANDLE_DEC
25
+ });
26
+ export const findActiveDragHandleNodeDec = (decorations, from, to) => decorations.find(from, to, spec => spec.type === TYPE_ACTIVE_HANDLE_DEC);
13
27
  export const emptyParagraphNodeDecorations = () => {
14
28
  const anchorName = `--node-anchor-paragraph-0`;
15
29
  const style = `anchor-name: ${anchorName}; margin-top: 0px;`;
@@ -3,7 +3,8 @@ import memoizeOne from 'memoize-one';
3
3
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
4
4
  import uuid from 'uuid';
5
5
  import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
6
- import { getBaseNodeTypeName, isEmptyParagraph } from '@atlaskit/editor-common/utils';
6
+ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
7
+ import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
7
8
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
8
9
  import { fg } from '@atlaskit/platform-feature-flags';
9
10
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -5,12 +5,25 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
5
5
  import { fg } from '@atlaskit/platform-feature-flags';
6
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
7
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
8
+ import { ACTIVE_QUICK_INSERT_ATTR } from '../ui/consts';
8
9
  import { QuickInsertWithVisibility } from '../ui/quick-insert-button';
9
10
  import { getActiveBlockMarks, getMatchingBlockMarks } from './utils/marks';
10
11
  const TYPE_QUICK_INSERT = 'INSERT_BUTTON';
12
+ const TYPE_ACTIVE_QUICK_INSERT_NODE = 'active-quick-insert-node';
11
13
  export const findQuickInsertInsertButtonDecoration = (decorations, from, to) => {
12
14
  return decorations.find(from, to, spec => spec.type === TYPE_QUICK_INSERT);
13
15
  };
16
+ /**
17
+ * Creates a Decoration.node that marks the active node with `data-active-quick-insert="true"`.
18
+ * The CSS in staticControlsAnchorStyles applies `anchor-name` to this attribute directly,
19
+ * replacing the unreliable adjacency selector `[block-ctrl-quick-insert-button] + *`.
20
+ */
21
+ export const createActiveQuickInsertNodeDecoration = (pos, nodeSize) => Decoration.node(pos, pos + nodeSize, {
22
+ [ACTIVE_QUICK_INSERT_ATTR]: 'true'
23
+ }, {
24
+ type: TYPE_ACTIVE_QUICK_INSERT_NODE
25
+ });
26
+ export const findActiveQuickInsertNodeDec = (decorations, from, to) => decorations.find(from, to, spec => spec.type === TYPE_ACTIVE_QUICK_INSERT_NODE);
14
27
  export const quickInsertButtonDecoration = ({
15
28
  api,
16
29
  formatMessage,