@atlaskit/editor-plugin-block-controls 20.0.2 → 20.1.0

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 (148) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cjs/blockControlsPlugin.js +53 -17
  3. package/dist/cjs/editor-commands/move-node.js +1 -1
  4. package/dist/cjs/editor-commands/show-drag-handle.js +17 -5
  5. package/dist/cjs/pm-plugins/decorations-anchor.js +3 -2
  6. package/dist/cjs/pm-plugins/decorations-drop-target-active.js +3 -2
  7. package/dist/cjs/pm-plugins/decorations-drop-target.js +3 -2
  8. package/dist/cjs/pm-plugins/decorations-surface-anchor.js +72 -0
  9. package/dist/cjs/pm-plugins/handle-mouse-down.js +2 -1
  10. package/dist/cjs/pm-plugins/handle-mouse-over.js +4 -3
  11. package/dist/cjs/pm-plugins/handle-sparse-mouse-over.js +125 -0
  12. package/dist/cjs/pm-plugins/interaction-tracking/pm-plugin.js +1 -1
  13. package/dist/cjs/pm-plugins/main.js +68 -56
  14. package/dist/cjs/pm-plugins/sparse-surfaces.js +49 -0
  15. package/dist/cjs/pm-plugins/utils/drag-handle-positions.js +1 -1
  16. package/dist/cjs/pm-plugins/utils/sparse-surface-candidates.js +419 -0
  17. package/dist/cjs/pm-plugins/utils/sparse-surfaces-mapping.js +108 -0
  18. package/dist/cjs/pm-plugins/utils/sparse-surfaces-state.js +53 -0
  19. package/dist/cjs/pm-plugins/utils/sparse-surfaces-view.js +134 -0
  20. package/dist/cjs/pm-plugins/utils/surface-viewport.js +223 -0
  21. package/dist/cjs/pm-plugins/utils/transactions.js +5 -0
  22. package/dist/cjs/pm-plugins/utils/validation.js +1 -1
  23. package/dist/cjs/ui/block-controls-left-surfaces.js +31 -25
  24. package/dist/cjs/ui/block-controls-right-surfaces.js +31 -25
  25. package/dist/cjs/ui/block-controls-surface-context.js +1 -0
  26. package/dist/cjs/ui/block-controls-surface-drag-handle-registration.js +6 -7
  27. package/dist/cjs/ui/block-controls-surface-drag-handle.js +6 -2
  28. package/dist/cjs/ui/consts.js +1 -1
  29. package/dist/cjs/ui/drag-handle.js +6 -4
  30. package/dist/cjs/ui/drop-target-layout.js +3 -2
  31. package/dist/cjs/ui/drop-target.js +4 -3
  32. package/dist/cjs/ui/global-styles.js +70 -28
  33. package/dist/cjs/ui/inline-drop-target.js +6 -5
  34. package/dist/cjs/ui/use-block-controls-surface-drag-source.js +1 -1
  35. package/dist/cjs/ui/utils/anchor-name.js +2 -1
  36. package/dist/cjs/ui/utils/dom-attr-name.js +3 -2
  37. package/dist/cjs/ui/utils/get-surface-placement.js +2 -1
  38. package/dist/cjs/ui/utils/partition-components-by-persistence.js +1 -1
  39. package/dist/cjs/ui/visibility-container.js +1 -1
  40. package/dist/es2019/blockControlsPlugin.js +42 -8
  41. package/dist/es2019/editor-commands/move-node.js +1 -1
  42. package/dist/es2019/editor-commands/show-drag-handle.js +14 -2
  43. package/dist/es2019/entry-points/block-decoration-utils-anchor-name.js +1 -0
  44. package/dist/es2019/entry-points/block-decoration-utils-consts.js +1 -0
  45. package/dist/es2019/entry-points/block-decoration-utils-dom-attr-name.js +1 -0
  46. package/dist/es2019/entry-points/block-decoration-utils-drag-handle-positions.js +1 -0
  47. package/dist/es2019/entry-points/block-decoration-utils-visibility-container.js +1 -0
  48. package/dist/es2019/entry-points/block-decoration-utils-widget-positions.js +1 -0
  49. package/dist/es2019/entry-points/blockControlsPlugin.js +1 -0
  50. package/dist/es2019/pm-plugins/decorations-anchor.js +3 -2
  51. package/dist/es2019/pm-plugins/decorations-drop-target-active.js +3 -2
  52. package/dist/es2019/pm-plugins/decorations-drop-target.js +3 -2
  53. package/dist/es2019/pm-plugins/decorations-surface-anchor.js +56 -0
  54. package/dist/es2019/pm-plugins/handle-mouse-down.js +2 -1
  55. package/dist/es2019/pm-plugins/handle-mouse-over.js +4 -3
  56. package/dist/es2019/pm-plugins/handle-sparse-mouse-over.js +116 -0
  57. package/dist/es2019/pm-plugins/interaction-tracking/pm-plugin.js +1 -1
  58. package/dist/es2019/pm-plugins/main.js +72 -56
  59. package/dist/es2019/pm-plugins/sparse-surfaces.js +37 -0
  60. package/dist/es2019/pm-plugins/utils/drag-handle-positions.js +1 -1
  61. package/dist/es2019/pm-plugins/utils/sparse-surface-candidates.js +305 -0
  62. package/dist/es2019/pm-plugins/utils/sparse-surfaces-mapping.js +78 -0
  63. package/dist/es2019/pm-plugins/utils/sparse-surfaces-state.js +39 -0
  64. package/dist/es2019/pm-plugins/utils/sparse-surfaces-view.js +121 -0
  65. package/dist/es2019/pm-plugins/utils/surface-viewport.js +192 -0
  66. package/dist/es2019/pm-plugins/utils/transactions.js +5 -0
  67. package/dist/es2019/pm-plugins/utils/update-selection.js +1 -2
  68. package/dist/es2019/pm-plugins/utils/validation.js +1 -1
  69. package/dist/es2019/ui/block-controls-left-surfaces.js +21 -14
  70. package/dist/es2019/ui/block-controls-right-surfaces.js +21 -14
  71. package/dist/es2019/ui/block-controls-surface-context.js +1 -0
  72. package/dist/es2019/ui/block-controls-surface-drag-handle-registration.js +4 -5
  73. package/dist/es2019/ui/block-controls-surface-drag-handle.js +6 -2
  74. package/dist/es2019/ui/consts.js +1 -1
  75. package/dist/es2019/ui/drag-handle.js +6 -4
  76. package/dist/es2019/ui/drop-target-layout.js +3 -2
  77. package/dist/es2019/ui/drop-target.js +4 -3
  78. package/dist/es2019/ui/global-styles.js +68 -29
  79. package/dist/es2019/ui/inline-drop-target.js +7 -5
  80. package/dist/es2019/ui/use-block-controls-surface-drag-source.js +1 -1
  81. package/dist/es2019/ui/utils/anchor-name.js +2 -1
  82. package/dist/es2019/ui/utils/dom-attr-name.js +3 -2
  83. package/dist/es2019/ui/utils/get-surface-placement.js +2 -1
  84. package/dist/es2019/ui/utils/partition-components-by-persistence.js +1 -1
  85. package/dist/es2019/ui/visibility-container.js +1 -1
  86. package/dist/esm/blockControlsPlugin.js +53 -17
  87. package/dist/esm/editor-commands/move-node.js +1 -1
  88. package/dist/esm/editor-commands/show-drag-handle.js +17 -5
  89. package/dist/esm/entry-points/block-decoration-utils-anchor-name.js +1 -0
  90. package/dist/esm/entry-points/block-decoration-utils-consts.js +1 -0
  91. package/dist/esm/entry-points/block-decoration-utils-dom-attr-name.js +1 -0
  92. package/dist/esm/entry-points/block-decoration-utils-drag-handle-positions.js +1 -0
  93. package/dist/esm/entry-points/block-decoration-utils-visibility-container.js +1 -0
  94. package/dist/esm/entry-points/block-decoration-utils-widget-positions.js +1 -0
  95. package/dist/esm/entry-points/blockControlsPlugin.js +1 -0
  96. package/dist/esm/pm-plugins/decorations-anchor.js +3 -2
  97. package/dist/esm/pm-plugins/decorations-drop-target-active.js +3 -2
  98. package/dist/esm/pm-plugins/decorations-drop-target.js +3 -2
  99. package/dist/esm/pm-plugins/decorations-surface-anchor.js +65 -0
  100. package/dist/esm/pm-plugins/handle-mouse-down.js +2 -1
  101. package/dist/esm/pm-plugins/handle-mouse-over.js +4 -3
  102. package/dist/esm/pm-plugins/handle-sparse-mouse-over.js +119 -0
  103. package/dist/esm/pm-plugins/interaction-tracking/pm-plugin.js +1 -1
  104. package/dist/esm/pm-plugins/main.js +68 -56
  105. package/dist/esm/pm-plugins/sparse-surfaces.js +43 -0
  106. package/dist/esm/pm-plugins/utils/drag-handle-positions.js +1 -1
  107. package/dist/esm/pm-plugins/utils/sparse-surface-candidates.js +413 -0
  108. package/dist/esm/pm-plugins/utils/sparse-surfaces-mapping.js +101 -0
  109. package/dist/esm/pm-plugins/utils/sparse-surfaces-state.js +46 -0
  110. package/dist/esm/pm-plugins/utils/sparse-surfaces-view.js +127 -0
  111. package/dist/esm/pm-plugins/utils/surface-viewport.js +217 -0
  112. package/dist/esm/pm-plugins/utils/transactions.js +5 -0
  113. package/dist/esm/pm-plugins/utils/update-selection.js +1 -2
  114. package/dist/esm/pm-plugins/utils/validation.js +1 -1
  115. package/dist/esm/ui/block-controls-left-surfaces.js +33 -27
  116. package/dist/esm/ui/block-controls-right-surfaces.js +33 -27
  117. package/dist/esm/ui/block-controls-surface-context.js +1 -0
  118. package/dist/esm/ui/block-controls-surface-drag-handle-registration.js +7 -8
  119. package/dist/esm/ui/block-controls-surface-drag-handle.js +6 -2
  120. package/dist/esm/ui/consts.js +1 -1
  121. package/dist/esm/ui/drag-handle.js +6 -4
  122. package/dist/esm/ui/drop-target-layout.js +3 -2
  123. package/dist/esm/ui/drop-target.js +4 -3
  124. package/dist/esm/ui/global-styles.js +71 -29
  125. package/dist/esm/ui/inline-drop-target.js +7 -5
  126. package/dist/esm/ui/use-block-controls-surface-drag-source.js +1 -1
  127. package/dist/esm/ui/utils/anchor-name.js +2 -1
  128. package/dist/esm/ui/utils/dom-attr-name.js +3 -2
  129. package/dist/esm/ui/utils/get-surface-placement.js +2 -1
  130. package/dist/esm/ui/utils/partition-components-by-persistence.js +1 -1
  131. package/dist/esm/ui/visibility-container.js +1 -1
  132. package/dist/types/blockControlsPluginType.d.ts +11 -4
  133. package/dist/types/pm-plugins/decorations-surface-anchor.d.ts +22 -0
  134. package/dist/types/pm-plugins/handle-sparse-mouse-over.d.ts +5 -0
  135. package/dist/types/pm-plugins/main.d.ts +2 -9
  136. package/dist/types/pm-plugins/sparse-surfaces.d.ts +8 -0
  137. package/dist/types/pm-plugins/utils/sparse-surface-candidates.d.ts +89 -0
  138. package/dist/types/pm-plugins/utils/sparse-surfaces-mapping.d.ts +20 -0
  139. package/dist/types/pm-plugins/utils/sparse-surfaces-state.d.ts +27 -0
  140. package/dist/types/pm-plugins/utils/sparse-surfaces-view.d.ts +15 -0
  141. package/dist/types/pm-plugins/utils/surface-viewport.d.ts +10 -0
  142. package/dist/types/ui/inline-drop-target.d.ts +4 -0
  143. package/dist/types/ui/utils/get-surface-placement.d.ts +3 -2
  144. package/package.json +7 -7
  145. package/dist/cjs/pm-plugins/utils/surface-node-positions.js +0 -100
  146. package/dist/es2019/pm-plugins/utils/surface-node-positions.js +0 -78
  147. package/dist/esm/pm-plugins/utils/surface-node-positions.js +0 -93
  148. package/dist/types/pm-plugins/utils/surface-node-positions.d.ts +0 -14
@@ -10,9 +10,9 @@ import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-che
10
10
  import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
11
11
  import { akEditorBreakoutPadding, akEditorCalculatedWideLayoutWidth, akEditorCalculatedWideLayoutWidthSmallViewport, akEditorFullPageNarrowBreakout, akEditorGutterPaddingDynamic, akEditorGutterPaddingReduced } from '@atlaskit/editor-shared-styles';
12
12
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
13
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
13
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
15
- import { ACTIVE_DRAG_HANDLE_ATTR, ACTIVE_DRAG_HANDLE_FALLBACK_ANCHOR_NAME, ACTIVE_QUICK_INSERT_ATTR, ACTIVE_QUICK_INSERT_FALLBACK_ANCHOR_NAME, DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
14
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
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
  /**
@@ -462,18 +462,68 @@ const staticControlsAnchorStyles = css({
462
462
  }
463
463
  }
464
464
  });
465
+ const sparseSurfaceAnchorName = 'var(--block-controls-surface-anchor-name)';
465
466
 
466
- /**
467
- * Names the CSS anchor on top-level nodes, so the block controls surfaces can anchor to the blocks
468
- * they render against. Only top-level at the moment as we don't have use cases yet for persistent controls that are nested.
469
- */
470
- const surfaceAnchorStyles = css({
467
+ // Inner node-view boxes own the visible geometry for these nodes. The root arm keeps a sparse
468
+ // marker useful when a node view has not mounted its inner box yet.
469
+ const sparseSurfaceAnchorStyles = css({
471
470
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
472
471
  '.ProseMirror': {
473
- // 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, @atlaskit/ui-styling-standard/no-imported-style-values
474
- [`[${NODE_ANCHOR_ATTR_NAME}]:not([${NODE_ANCHOR_ATTR_NAME}] [${NODE_ANCHOR_ATTR_NAME}]):not([${ACTIVE_DRAG_HANDLE_ATTR}], [${ACTIVE_QUICK_INSERT_ATTR}])`]: {
475
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
476
- anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
472
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
473
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="blockCard"]:has(.datasourceView-content-inner-wrap) .datasourceView-content-inner-wrap': {
474
+ anchorName: sparseSurfaceAnchorName
475
+ },
476
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
477
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="blockCard"]:not(:has(.datasourceView-content-inner-wrap))': {
478
+ anchorName: sparseSurfaceAnchorName
479
+ },
480
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
481
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="bodiedExtension"]:has(.extension-container[data-layout]) .extension-container[data-layout]': {
482
+ anchorName: sparseSurfaceAnchorName
483
+ },
484
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
485
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="bodiedExtension"]:not(:has(.extension-container[data-layout]))': {
486
+ anchorName: sparseSurfaceAnchorName
487
+ },
488
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
489
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="embedCard"]:has(.rich-media-item) .rich-media-item': {
490
+ anchorName: sparseSurfaceAnchorName
491
+ },
492
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
493
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="embedCard"]:not(:has(.rich-media-item))': {
494
+ anchorName: sparseSurfaceAnchorName
495
+ },
496
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
497
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="extension"]:has(.extension-container[data-layout]) .extension-container[data-layout]': {
498
+ anchorName: sparseSurfaceAnchorName
499
+ },
500
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
501
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="extension"]:not(:has(.extension-container[data-layout]))': {
502
+ anchorName: sparseSurfaceAnchorName
503
+ },
504
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
505
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="mediaSingle"]:has(.resizer-item) .resizer-item': {
506
+ anchorName: sparseSurfaceAnchorName
507
+ },
508
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
509
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="mediaSingle"]:not(:has(.resizer-item))': {
510
+ anchorName: sparseSurfaceAnchorName
511
+ },
512
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
513
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="multiBodiedExtension"]:has(.extension-container[data-layout]) .extension-container[data-layout]': {
514
+ anchorName: sparseSurfaceAnchorName
515
+ },
516
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
517
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="multiBodiedExtension"]:not(:has(.extension-container[data-layout]))': {
518
+ anchorName: sparseSurfaceAnchorName
519
+ },
520
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
521
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="table"]:has(.resizer-item) .resizer-item': {
522
+ anchorName: sparseSurfaceAnchorName
523
+ },
524
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
525
+ '[data-block-controls-surface-anchor][data-block-controls-surface-node-type="table"]:not(:has(.resizer-item))': {
526
+ anchorName: sparseSurfaceAnchorName
477
527
  }
478
528
  }
479
529
  });
@@ -517,33 +567,22 @@ export const GlobalStylesWrapper = ({
517
567
  isDragging: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.isDragging
518
568
  };
519
569
  });
520
- const isDragging = expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true) ? isDraggingFromState : false;
570
+ const sparseSurfacesEnabled = isExperimentEnabled('platform_editor_block_control_migration');
571
+ const isDragging = sparseSurfacesEnabled || expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true) ? isDraggingFromState : false;
521
572
  const shouldRenderAnchors = isCSSAnchorSupported() && expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true);
522
-
523
- // The surfaces anchor to blocks they render against rather than only to the hovered one, so they
524
- // need a name on every node. Added alongside whichever conditional rule applies rather than
525
- // replacing it: this one matches only non-active nodes, so the two sets are disjoint.
526
- //
527
- // The migration check is what scopes this. Unlike the surfaces, this component renders for every
528
- // editor, so without it the rule would name anchors on documents that have no surface to anchor.
529
- const shouldRenderSurfaceAnchors =
530
- // eslint-disable-next-line @atlaskit/platform/no-preconditioning -- browser capability, not a flag: an anchor name is meaningless where `anchor()` cannot resolve
531
- Boolean(isCSSAnchorSupported()) && isExperimentEnabled('platform_editor_block_control_migration');
573
+ const sparseSurfaceAnchorsEnabled = Boolean(isCSSAnchorSupported()) && sparseSurfacesEnabled;
532
574
  const toolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar));
533
575
  return jsx(Global
534
576
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
535
577
  , {
536
- styles: [globalStyles(), globalDnDStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendedHoverZoneNext() : extendedHoverZone(), isDragging && (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendedDragZoneNext : extendedDragZone), editorExperiment('platform_editor_preview_panel_responsiveness', true, {
578
+ styles: [globalStyles(), globalDnDStyle, (!sparseSurfacesEnabled || isDragging) && (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? extendedHoverZoneNext() : extendedHoverZone()), isDragging && (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? extendedDragZoneNext : extendedDragZone), (!sparseSurfacesEnabled || isDragging) && editorExperiment('platform_editor_preview_panel_responsiveness', true, {
537
579
  exposure: true
538
- }) ? expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendHoverZoneReducedNext : extendHoverZoneReduced : undefined,
580
+ }) ? expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? extendHoverZoneReducedNext : extendHoverZoneReduced : undefined,
539
581
  // platform_editor_controls note: this allows drag handles to render on empty lines
540
- toolbarFlagsEnabled ? undefined : withInlineNodeStyle, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, editorExperiment('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && expValEquals('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) ?
582
+ toolbarFlagsEnabled ? undefined : withInlineNodeStyle, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, editorExperiment('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, (!sparseSurfacesEnabled || isDragging) && (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? withRelativePosStyleNext : withRelativePosStyle), (!sparseSurfacesEnabled || isDragging) && (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle), (!sparseSurfacesEnabled || isDragging) && ((expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) && expValEquals('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone), sparseSurfaceAnchorsEnabled ? isDragging ? dragAnchorStyles : false : expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) ?
541
583
  // dragAnchorStyles sets anchor-name on ALL nodes during drag (needed for drop target positioning).
542
584
  // staticControlsAnchorStyles handles anchor-name via node decorations for non-drag state.
543
585
  // shouldRenderAnchors guards both: only apply anchor styles on browsers that support CSS anchor positioning.
544
- shouldRenderAnchors ? isDragging ? dragAnchorStyles : staticControlsAnchorStyles : false : shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles),
545
- // Last so that, at equal specificity, the surfaces' own anchor names are the ones that
546
- // stand. It cannot overlap the active-node rules above, which this selector excludes.
547
- shouldRenderSurfaceAnchors && surfaceAnchorStyles]
586
+ shouldRenderAnchors ? isDragging ? dragAnchorStyles : staticControlsAnchorStyles : false : shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles), sparseSurfaceAnchorsEnabled && sparseSurfaceAnchorStyles]
548
587
  });
549
588
  };
@@ -4,10 +4,12 @@
4
4
  * @jsxRuntime classic
5
5
  * @jsx jsx
6
6
  */
7
+
7
8
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
9
10
  import { css, jsx } from '@emotion/react';
10
11
  import { akEditorBreakoutPadding } from '@atlaskit/editor-shared-styles';
12
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
11
13
  import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
12
14
  import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element-adapter';
13
15
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -87,7 +89,7 @@ export const InlineDropTarget = ({
87
89
  const ref = useRef(null);
88
90
  const [isDraggedOver, setIsDraggedOver] = useState(false);
89
91
  const anchorName = useMemo(() => {
90
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
92
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
91
93
  var _getPos;
92
94
  return nextNode ? (api === null || api === void 0 ? void 0 : api.core.actions.getAnchorIdForNode(nextNode, (_getPos = getPos()) !== null && _getPos !== void 0 ? _getPos : -1)) || '' : '';
93
95
  }
@@ -118,7 +120,7 @@ export const InlineDropTarget = ({
118
120
  innerContainerWidth = `calc(var(--ak-editor--line-length) * ${percentageWidth})`;
119
121
  }
120
122
  } else if (nextNode.type.name === 'table' && nextNode.firstChild) {
121
- const tableWidthAnchor = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? typeof nextNodePos === 'number' ? (api === null || api === void 0 ? void 0 : api.core.actions.getAnchorIdForNode(nextNode.firstChild, nextNodePos + 1)) || '' : '' : getNodeAnchor(nextNode.firstChild);
123
+ const tableWidthAnchor = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? typeof nextNodePos === 'number' ? (api === null || api === void 0 ? void 0 : api.core.actions.getAnchorIdForNode(nextNode.firstChild, nextNodePos + 1)) || '' : '' : getNodeAnchor(nextNode.firstChild);
122
124
  const isNumberColumnEnabled = Boolean(nextNode.attrs.isNumberColumnEnabled);
123
125
  if (isAnchorSupported()) {
124
126
  innerContainerWidth = isNumberColumnEnabled ? `calc(anchor-size(${tableWidthAnchor} width) + ${TABLE_NUMBERED_COLUMN_WIDTH}px)` : `anchor-size(${tableWidthAnchor} width)`;
@@ -131,7 +133,7 @@ export const InlineDropTarget = ({
131
133
  innerContainerWidth = `min(${nextNode.attrs.width}px, ${innerContainerWidth})`;
132
134
  }
133
135
  } else if (nextNode.type.name === 'mediaSingle' && nextNode.firstChild) {
134
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
136
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
135
137
  var _nextNode$firstChild;
136
138
  // check pos is a number
137
139
  if (typeof nextNodePos === 'number' && ((_nextNode$firstChild = nextNode.firstChild) === null || _nextNode$firstChild === void 0 ? void 0 : _nextNode$firstChild.type.name) === 'media') {
@@ -146,7 +148,7 @@ export const InlineDropTarget = ({
146
148
  let heightTargetAnchorName = targetAnchorName;
147
149
  if (nextNode.type.name === 'layoutSection' && nextNode.firstChild && nextNode.lastChild) {
148
150
  if (isLeftPosition) {
149
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
151
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
150
152
  if (typeof nextNodePos === 'number') {
151
153
  heightTargetAnchorName = (api === null || api === void 0 ? void 0 : api.core.actions.getAnchorIdForNode(nextNode.firstChild, nextNodePos + 1)) || '';
152
154
  } else {
@@ -156,7 +158,7 @@ export const InlineDropTarget = ({
156
158
  heightTargetAnchorName = getNodeAnchor(nextNode.firstChild);
157
159
  }
158
160
  } else {
159
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
161
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
160
162
  if (typeof nextNodePos === 'number') {
161
163
  const lastNodeStartPos = nextNode.content.size - nextNode.lastChild.nodeSize;
162
164
  heightTargetAnchorName = (api === null || api === void 0 ? void 0 : api.core.actions.getAnchorIdForNode(nextNode.lastChild, lastNodeStartPos + 1)) || '';
@@ -9,8 +9,8 @@ import { defaultActiveAnchorTracker } from '../pm-plugins/utils/active-anchor-tr
9
9
  import { getMultiSelectAnalyticsAttributes } from '../pm-plugins/utils/analytics';
10
10
  import { isCollapsedHeading, prepareCollapsedHeadingSelection } from '../pm-plugins/utils/collapsed-heading';
11
11
  import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
12
- import { dragPreview } from './drag-preview';
13
12
  import { getNodeMarginsForDragPreview, getNodeSpacingForDragPreview } from './block-controls-surface-drag-handle-utils';
13
+ import { dragPreview } from './drag-preview';
14
14
  const EDITOR_BLOCKS_DRAG_INIT = 'Editor Blocks Drag Initialization Time';
15
15
  /**
16
16
  * Registry surface drag source. This intentionally duplicates the stable widget handle's drag
@@ -1,3 +1,4 @@
1
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
1
2
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
2
3
  import { findNodeDecs } from '../../pm-plugins/decorations-anchor';
3
4
  import { key } from '../../pm-plugins/main';
@@ -11,7 +12,7 @@ export const refreshAnchorName = ({
11
12
  anchorName
12
13
  }) => {
13
14
  let newAnchorName = anchorName || '';
14
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
15
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
15
16
  return newAnchorName;
16
17
  }
17
18
  const pos = getPos();
@@ -1,14 +1,15 @@
1
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
1
2
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
2
3
  export const NODE_ANCHOR_ATTR_NAME = 'data-node-anchor';
3
4
  export const NODE_NODE_TYPE_ATTR_NAME = 'data-prosemirror-node-name';
4
5
  export const getAnchorAttrName = () => {
5
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
6
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
6
7
  return NODE_ANCHOR_ATTR_NAME;
7
8
  }
8
9
  return 'data-drag-handler-anchor-name';
9
10
  };
10
11
  export const getTypeNameAttrName = () => {
11
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
12
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
12
13
  return NODE_NODE_TYPE_ATTR_NAME;
13
14
  }
14
15
  return 'data-drag-handler-node-type';
@@ -96,6 +96,7 @@ const INVALID_ANCHOR_FALLBACK_TOP = `-${INVALID_ANCHOR_OFFSCREEN_PX}px`;
96
96
  const INVALID_ANCHOR_FALLBACK_BOTTOM = `${INVALID_ANCHOR_OFFSCREEN_PX}px`;
97
97
  export const getAnchoredSurfacePlacement = ({
98
98
  anchorName,
99
+ layout,
99
100
  nodeType,
100
101
  nodeTypeWithLevel,
101
102
  parentNodeType,
@@ -127,7 +128,7 @@ export const getAnchoredSurfacePlacement = ({
127
128
  } : {}),
128
129
  left: side === 'right' ? `calc(anchor(${anchorName} right) + ${gap}px)` : `anchor(${anchorName} left)`,
129
130
  positionAnchor: anchorName,
130
- top: `calc(anchor(${anchorName} top, ${INVALID_ANCHOR_FALLBACK_TOP}) + ${topPositionAdjustment(nodeTypeWithLevel)}px)`,
131
+ top: `calc(anchor(${anchorName} top, ${INVALID_ANCHOR_FALLBACK_TOP}) + ${topPositionAdjustment(nodeTypeWithLevel, layout)}px)`,
131
132
  // The left side grows away from the node without knowing its own width, so it pulls itself
132
133
  // back past its own box and the gap. The right side grows into the margin, so the gap is
133
134
  // already folded into `left` above.
@@ -1,6 +1,6 @@
1
1
  import { BLOCK_CONTROL_UI_CONTEXT } from '@atlaskit/editor-common/block-controls/block-control-ui-context';
2
- import { getComponentIdentity, resolveSurface, willComponentRender } from '@atlaskit/editor-ui-control-model/surface-renderer';
3
2
  import { createSurfaceContext } from '@atlaskit/editor-ui-control-model/create-surface-context';
3
+ import { getComponentIdentity, resolveSurface, willComponentRender } from '@atlaskit/editor-ui-control-model/surface-renderer';
4
4
  /**
5
5
  * Split registered components into two groups:
6
6
  * those that should be rendered persistently and those that should only be rendered on hover.
@@ -10,8 +10,8 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
10
10
  import { akEditorFullPageNarrowBreakout } from '@atlaskit/editor-shared-styles';
11
11
  // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
12
12
  import { Box, xcss } from '@atlaskit/primitives';
13
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
13
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
14
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
15
  const RIGHT_CONTROL_HIDE_DELAY_MS = 150;
16
16
  const baseStyles = xcss({
17
17
  transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out'
@@ -18,12 +18,14 @@ import { moveNode } from './editor-commands/move-node';
18
18
  import { moveNodeWithBlockMenu as _moveNodeWithBlockMenu } from './editor-commands/move-node-with-block-menu';
19
19
  import { moveToLayout } from './editor-commands/move-to-layout';
20
20
  import { canMoveNodeUpOrDown } from './editor-commands/utils/move-node-utils';
21
+ import { getNodeTypeWithLevel } from './pm-plugins/decorations-common';
21
22
  import { firstNodeDecPlugin } from './pm-plugins/first-node-dec-plugin';
22
23
  import { createInteractionTrackingPlugin, interactionTrackingPluginKey } from './pm-plugins/interaction-tracking/pm-plugin';
23
24
  import { createPlugin, key } from './pm-plugins/main';
24
25
  import { startPreservingSelection as _startPreservingSelection, stopPreservingSelection as _stopPreservingSelection } from './pm-plugins/selection-preservation/editor-commands';
25
26
  import { selectionPreservationPluginKey } from './pm-plugins/selection-preservation/plugin-key';
26
27
  import { createSelectionPreservationPlugin } from './pm-plugins/selection-preservation/pm-plugin';
28
+ import { createSparseSurfacesPlugin, sparseSurfacesKey } from './pm-plugins/sparse-surfaces';
27
29
  import { expandAndUpdateSelection as _expandAndUpdateSelection } from './pm-plugins/utils/expand-and-update-selection';
28
30
  import { selectNode } from './pm-plugins/utils/getSelection';
29
31
  import { BlockControlsLeftSurfaces } from './ui/block-controls-left-surfaces';
@@ -39,7 +41,6 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
39
41
  var rightSideControlsEnabled = (_config$rightSideCont = config === null || config === void 0 ? void 0 : config.rightSideControlsEnabled) !== null && _config$rightSideCont !== void 0 ? _config$rightSideCont : false;
40
42
  var quickInsertButtonEnabled = (_config$quickInsertBu = config === null || config === void 0 ? void 0 : config.quickInsertButtonEnabled) !== null && _config$quickInsertBu !== void 0 ? _config$quickInsertBu : true;
41
43
  var registryBlockControlsEnabled = isExperimentEnabled('platform_editor_block_control_migration');
42
- var legacyBlockControlsEnabled = !registryBlockControlsEnabled;
43
44
  if (registryBlockControlsEnabled) {
44
45
  var _api$uiControlRegistr, _api$uiControlRegistr2;
45
46
  api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 || _api$uiControlRegistr.actions.register([BLOCK_CONTROLS_LEFT_SURFACE, _objectSpread(_objectSpread({}, BLOCK_CONTROLS_LEFT_SECTION), {}, {
@@ -135,9 +136,17 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
135
136
  plugin: function plugin(_ref2) {
136
137
  var getIntl = _ref2.getIntl,
137
138
  nodeViewPortalProviderAPI = _ref2.nodeViewPortalProviderAPI;
138
- return createPlugin(api, getIntl, nodeViewPortalProviderAPI, nodeDecorationRegistry, rightSideControlsEnabled, quickInsertButtonEnabled && legacyBlockControlsEnabled, legacyBlockControlsEnabled);
139
+ return createPlugin(api, getIntl, nodeViewPortalProviderAPI, registryBlockControlsEnabled ? [] : nodeDecorationRegistry, rightSideControlsEnabled, quickInsertButtonEnabled && !registryBlockControlsEnabled);
139
140
  }
140
141
  }];
142
+ if (registryBlockControlsEnabled) {
143
+ pmPlugins.push({
144
+ name: 'blockControlsSparseSurfaces',
145
+ plugin: function plugin() {
146
+ return createSparseSurfacesPlugin(api);
147
+ }
148
+ });
149
+ }
141
150
  if (editorExperiment('platform_editor_controls', 'variant1')) {
142
151
  pmPlugins.push({
143
152
  name: 'blockControlsInteractionTrackingPlugin',
@@ -156,7 +165,7 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
156
165
  // Not registered under the registry migration: the decoration puts an inline
157
166
  // `margin-top: 0` on the first document node, which fights features that render their own
158
167
  // content above it — a leading show-diff widget is left flush against the node below.
159
- if (areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar)) && legacyBlockControlsEnabled) {
168
+ if (areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar)) && !registryBlockControlsEnabled) {
160
169
  pmPlugins.push({
161
170
  name: 'firstNodeDec',
162
171
  plugin: firstNodeDecPlugin
@@ -203,10 +212,34 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
203
212
  return tr;
204
213
  };
205
214
  },
206
- toggleBlockMenu: function toggleBlockMenu(options) {
215
+ showControlAtPosition: function showControlAtPosition(pos, control, options) {
207
216
  return function (_ref6) {
208
- var _api$userIntent, _api$blockControls2, _options$anchorName, _api$blockControls3;
209
217
  var tr = _ref6.tr;
218
+ var node = tr.doc.nodeAt(pos);
219
+ if (!node) {
220
+ return tr;
221
+ }
222
+ var anchorName = api === null || api === void 0 ? void 0 : api.core.actions.getAnchorIdForNode(node, pos);
223
+ if (!anchorName) {
224
+ return tr;
225
+ }
226
+ var currMeta = tr.getMeta(key);
227
+ tr.setMeta(key, _objectSpread(_objectSpread({}, currMeta), {}, {
228
+ activeNode: {
229
+ pos: pos,
230
+ anchorName: anchorName,
231
+ controlKey: control.key,
232
+ nodeType: getNodeTypeWithLevel(node),
233
+ handleOptions: options
234
+ }
235
+ }));
236
+ return tr;
237
+ };
238
+ },
239
+ toggleBlockMenu: function toggleBlockMenu(options) {
240
+ return function (_ref7) {
241
+ var _api$userIntent, _api$blockControls2, _options$triggerByNod, _options$anchorName, _api$blockControls3;
242
+ var tr = _ref7.tr;
210
243
  var currMeta = tr.getMeta(key);
211
244
  var currentUserIntent = api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || (_api$userIntent = _api$userIntent.sharedState.currentState()) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.currentUserIntent;
212
245
  var isMenuCurrentlyOpen = api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 || (_api$blockControls2 = _api$blockControls2.sharedState.currentState()) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.isMenuOpen;
@@ -231,8 +264,9 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
231
264
  return tr;
232
265
  }
233
266
 
234
- // Do not open menu on layoutColumn and close opened menu when layoutColumn drag handle is clicked
235
- if (options !== null && options !== void 0 && (_options$anchorName = options.anchorName) !== null && _options$anchorName !== void 0 && _options$anchorName.includes('layoutColumn')) {
267
+ // Do not open the block menu for layout columns. Anchor resolution can lag behind
268
+ // a migrated surface click, so prefer the explicit node metadata when available.
269
+ if ((options === null || options === void 0 || (_options$triggerByNod = options.triggerByNode) === null || _options$triggerByNod === void 0 ? void 0 : _options$triggerByNod.nodeType) === 'layoutColumn' || options !== null && options !== void 0 && (_options$anchorName = options.anchorName) !== null && _options$anchorName !== void 0 && _options$anchorName.includes('layoutColumn')) {
236
270
  if (currentUserIntent === 'blockMenuOpen') {
237
271
  var _api$userIntent3;
238
272
  api === null || api === void 0 || (_api$userIntent3 = api.userIntent) === null || _api$userIntent3 === void 0 || _api$userIntent3.commands.setCurrentUserIntent('default')({
@@ -308,9 +342,9 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
308
342
  };
309
343
  },
310
344
  setNodeDragged: function setNodeDragged(getPos, anchorName, nodeType) {
311
- return function (_ref7) {
345
+ return function (_ref8) {
312
346
  var _api$userIntent6;
313
- var tr = _ref7.tr;
347
+ var tr = _ref8.tr;
314
348
  var pos = getPos();
315
349
  if (pos === undefined) {
316
350
  return tr;
@@ -340,9 +374,9 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
340
374
  };
341
375
  },
342
376
  setMultiSelectPositions: function setMultiSelectPositions(anchor, head) {
343
- return function (_ref8) {
377
+ return function (_ref9) {
344
378
  var _api$selection, _$to$nodeBefore, _$from$nodeAfter;
345
- var tr = _ref8.tr;
379
+ var tr = _ref9.tr;
346
380
  var _tr$selection = tr.selection,
347
381
  userAnchor = _tr$selection.anchor,
348
382
  userHead = _tr$selection.head;
@@ -394,8 +428,8 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
394
428
  };
395
429
  },
396
430
  setSelectedViaDragHandle: function setSelectedViaDragHandle(isSelectedViaDragHandle) {
397
- return function (_ref9) {
398
- var tr = _ref9.tr;
431
+ return function (_ref0) {
432
+ var tr = _ref0.tr;
399
433
  var currMeta = tr.getMeta(key);
400
434
  return tr.setMeta(key, _objectSpread(_objectSpread({}, currMeta), {}, {
401
435
  isSelectedViaDragHandle: isSelectedViaDragHandle
@@ -437,8 +471,10 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
437
471
  isSelectedViaDragHandle: (_key$getState$isSelec = (_key$getState10 = key.getState(editorState)) === null || _key$getState10 === void 0 ? void 0 : _key$getState10.isSelectedViaDragHandle) !== null && _key$getState$isSelec !== void 0 ? _key$getState$isSelec : false
438
472
  };
439
473
  if (registryBlockControlsEnabled) {
440
- var _key$getState$surface, _key$getState11;
441
- sharedState.surfaceNodePositions = (_key$getState$surface = (_key$getState11 = key.getState(editorState)) === null || _key$getState11 === void 0 ? void 0 : _key$getState11.surfaceNodePositions) !== null && _key$getState$surface !== void 0 ? _key$getState$surface : [];
474
+ var surfaces = sparseSurfacesKey.getState(editorState);
475
+ sharedState.surfaceNodePositions = surfaces === null || surfaces === void 0 ? void 0 : surfaces.candidates.positions;
476
+ sharedState.surfaceAnchors = surfaces === null || surfaces === void 0 ? void 0 : surfaces.anchors;
477
+ sharedState.surfaceActiveNodes = surfaces === null || surfaces === void 0 ? void 0 : surfaces.activeNodesByPosition;
442
478
  }
443
479
  if (editorExperiment('platform_editor_controls', 'variant1')) {
444
480
  var _interactionTrackingP2, _interactionTrackingP3, _interactionTrackingP4;
@@ -450,8 +486,8 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
450
486
  sharedState.preservedSelection = (_selectionPreservatio = selectionPreservationPluginKey.getState(editorState)) === null || _selectionPreservatio === void 0 ? void 0 : _selectionPreservatio.preservedSelection;
451
487
  return sharedState;
452
488
  },
453
- contentComponent: function contentComponent(_ref0) {
454
- var editorView = _ref0.editorView;
489
+ contentComponent: function contentComponent(_ref1) {
490
+ var editorView = _ref1.editorView;
455
491
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(GlobalStylesWrapper, {
456
492
  api: api
457
493
  }), registryBlockControlsEnabled && editorView && api ? /*#__PURE__*/React.createElement(SurfaceEditorViewContext.Provider, {
@@ -16,8 +16,8 @@ import { findChildrenByType, findParentNodeOfType, findParentNodeOfTypeClosestTo
16
16
  import { findTable, isInTable, isTableSelected } from '@atlaskit/editor-tables/utils';
17
17
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
18
18
  import { fg } from '@atlaskit/platform-feature-flags/fg';
19
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
20
19
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
20
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
21
21
  import { key } from '../pm-plugins/main';
22
22
  import { attachMoveNodeAnalytics, getMultiSelectAnalyticsAttributes } from '../pm-plugins/utils/analytics';
23
23
  import { isCollapsedHeading, updateCollapsedHeadingAfterMove } from '../pm-plugins/utils/collapsed-heading';
@@ -1,6 +1,8 @@
1
1
  import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
2
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
2
3
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
4
  import { findNodeDecs } from '../pm-plugins/decorations-anchor';
5
+ import { getNodeTypeWithLevel } from '../pm-plugins/decorations-common';
4
6
  import { getDecorations, key } from '../pm-plugins/main';
5
7
  import { getNestedNodePosition, getNestedNodeStartingPosition } from '../pm-plugins/utils/getNestedNodePosition';
6
8
  import { NODE_ANCHOR_ATTR_NAME, NODE_NODE_TYPE_ATTR_NAME } from '../ui/utils/dom-attr-name';
@@ -9,7 +11,6 @@ var findParentPosForHandle = function findParentPosForHandle(state) {
9
11
  var $from = state.selection.$from;
10
12
  var _ref = key.getState(state) || {},
11
13
  activeNode = _ref.activeNode;
12
-
13
14
  // if a node handle is already focused, return the parent pos of that node (with focused handle)
14
15
  if (activeNode && (_activeNode$handleOpt = activeNode.handleOptions) !== null && _activeNode$handleOpt !== void 0 && _activeNode$handleOpt.isFocused) {
15
16
  var $activeNodePos = state.doc.resolve(activeNode.pos);
@@ -33,7 +34,7 @@ var findParentPosForHandle = function findParentPosForHandle(state) {
33
34
  }
34
35
 
35
36
  // else find closest parent node
36
- return expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ?
37
+ return expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ?
37
38
  // With native anchor enabled, all nodes have anchor name attribute despite no drag handle support, e.g. listItem, caption,
38
39
  // as opposed to old approach, node decoration is only added to the node that have drag handle,
39
40
  // hence, we need to return the exact position of the node that can have drag handle
@@ -107,13 +108,24 @@ var findNextAnchorNode = function findNextAnchorNode(view) {
107
108
  };
108
109
  export var showDragHandleAtSelection = function showDragHandleAtSelection(api) {
109
110
  return function (state, _, view) {
111
+ if (api && isExperimentEnabled('platform_editor_block_control_migration')) {
112
+ var pos = findParentPosForHandle(state);
113
+ var node = pos === undefined ? undefined : state.doc.nodeAt(pos);
114
+ var anchorName = node && pos !== undefined ? api.core.actions.getAnchorIdForNode(node, pos) : undefined;
115
+ if (!node || pos === undefined || !anchorName) {
116
+ return false;
117
+ }
118
+ return api.core.actions.execute(api.blockControls.commands.showDragHandleAt(pos, anchorName, getNodeTypeWithLevel(node), {
119
+ isFocused: true
120
+ }));
121
+ }
110
122
  if (view && expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
111
123
  var anchorNode = findNextAnchorNode(view);
112
124
  if (api && anchorNode) {
113
- var pos = anchorNode.pos,
114
- anchorName = anchorNode.anchorName,
125
+ var _pos = anchorNode.pos,
126
+ _anchorName = anchorNode.anchorName,
115
127
  nodeType = anchorNode.nodeType;
116
- api.core.actions.execute(api.blockControls.commands.showDragHandleAt(pos, anchorName, nodeType, {
128
+ api.core.actions.execute(api.blockControls.commands.showDragHandleAt(_pos, _anchorName, nodeType, {
117
129
  isFocused: true
118
130
  }));
119
131
  return true;
@@ -1,2 +1,3 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
+
2
3
  export { refreshAnchorName } from '../ui/utils/anchor-name';
@@ -1,2 +1,3 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
+
2
3
  export { rootElementGap, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from '../ui/consts';
@@ -1,2 +1,3 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
+
2
3
  export { getAnchorAttrName } from '../ui/utils/dom-attr-name';
@@ -1,2 +1,3 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
+
2
3
  export { getControlBottomCSSValue, getControlHeightCSSValue, getNodeHeight, getTopPosition, shouldBeSticky } from '../pm-plugins/utils/drag-handle-positions';
@@ -1,2 +1,3 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
+
2
3
  export { VisibilityContainer } from '../ui/visibility-container';
@@ -1,2 +1,3 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
+
2
3
  export { getRightPositionForRootElement } from '../pm-plugins/utils/widget-positions';
@@ -1,2 +1,3 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
+
2
3
  export { blockControlsPlugin } from '../blockControlsPlugin';
@@ -1,7 +1,8 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
4
4
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
5
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
6
  import { getNodeAnchor, getNodeTypeWithLevel, NESTED_DEPTH, TYPE_NODE_DEC } from './decorations-common';
6
7
  var IGNORE_NODES = ['tableCell', 'tableHeader', 'tableRow', 'listItem', 'caption', 'layoutColumn'];
7
8
  export var IGNORE_NODES_NEXT = ['tableCell', 'tableHeader', 'tableRow', 'listItem', 'caption'];
@@ -70,7 +71,7 @@ export var findNodeDecs = function findNodeDecs(state, decorations, from, to) {
70
71
  };
71
72
  export var nodeDecorations = function nodeDecorations(newState, from, to) {
72
73
  var decs = [];
73
- if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
74
+ if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration')) {
74
75
  return [];
75
76
  }
76
77
  var docFrom = from === undefined || from < 0 ? 0 : from;
@@ -4,8 +4,9 @@ import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
4
4
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
5
5
  import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
6
6
  import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
7
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
8
8
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
9
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
9
10
  import { getNodeAnchor } from './decorations-common';
10
11
  import { createDropTargetDecoration, createLayoutDropTargetDecoration } from './decorations-drop-target';
11
12
  import { findSurroundingNodes } from './decorations-find-surrounding-nodes';
@@ -251,7 +252,7 @@ export var getActiveDropTargetDecorations = function getActiveDropTargetDecorati
251
252
  }
252
253
  }
253
254
  }
254
- defaultActiveAnchorTracker.emit(expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? api.core.actions.getAnchorIdForNode(anchorEmitNodeWithPos.node, anchorEmitNodeWithPos.pos) || '' : getNodeAnchor(anchorEmitNodeWithPos.node));
255
+ defaultActiveAnchorTracker.emit(expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? api.core.actions.getAnchorIdForNode(anchorEmitNodeWithPos.node, anchorEmitNodeWithPos.pos) || '' : getNodeAnchor(anchorEmitNodeWithPos.node));
255
256
  return {
256
257
  decsToAdd: decsToAdd,
257
258
  decsToRemove: decsToRemove
@@ -10,8 +10,9 @@ import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
10
10
  import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
11
11
  import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
12
12
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
13
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
13
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
14
14
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
15
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
16
  import { nodeMargins } from '../ui/consts';
16
17
  import { DropTarget, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_GAP, EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET } from '../ui/drop-target';
17
18
  import { DropTargetLayout, DropTargetLayoutNativeAnchorSupport } from '../ui/drop-target-layout';
@@ -146,7 +147,7 @@ export var createLayoutDropTargetDecoration = function createLayoutDropTargetDec
146
147
  element.setAttribute('data-blocks-drop-target-container', 'true');
147
148
  element.setAttribute('data-blocks-drop-target-key', key);
148
149
  element.style.clear = 'unset';
149
- var DropTargetLayoutComponent = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? DropTargetLayoutNativeAnchorSupport : DropTargetLayout;
150
+ var DropTargetLayoutComponent = expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) || isExperimentEnabled('platform_editor_block_control_migration') ? DropTargetLayoutNativeAnchorSupport : DropTargetLayout;
150
151
  nodeViewPortalProviderAPI.render(function () {
151
152
  return /*#__PURE__*/createElement(DropTargetLayoutComponent, _objectSpread(_objectSpread({}, props), {}, {
152
153
  getPos: getPos,