@atlaskit/editor-plugin-block-controls 8.9.1 → 8.10.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 8.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`cb0904030093f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cb0904030093f) -
8
+ [ux] Restricting blocks from showing remix button
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies
13
+
14
+ ## 8.9.2
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies
19
+
3
20
  ## 8.9.1
4
21
 
5
22
  ### Patch Changes
@@ -468,7 +468,7 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
468
468
  _iterator.f();
469
469
  }
470
470
  }
471
- if (rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true) && isViewMode) {
471
+ if (rightSideControlsEnabled && isViewMode && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
472
472
  var _iterator2 = _createForOfIteratorHelper(nodeDecorationRegistry),
473
473
  _step2;
474
474
  try {
@@ -493,7 +493,7 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
493
493
  }
494
494
  }
495
495
  } else if (api) {
496
- var _latestActiveNode5, _latestActiveNode14;
496
+ var _latestActiveNode5, _latestActiveNode1;
497
497
  if (shouldRecreateHandle && (!rightSideControlsEnabled || !isViewMode)) {
498
498
  var _activeNode11, _activeNode12, _latestActiveNode, _latestActiveNode2, _latestActiveNode3, _latestActiveNode4;
499
499
  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);
@@ -530,92 +530,133 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
530
530
  editorState: newState
531
531
  });
532
532
  decorations = decorations.add(newState.doc, [quickInsertButton]);
533
+
534
+ // both gates have overlapping logic to determine what controls to show
533
535
  if ((0, _platformFeatureFlags.fg)('platform_editor_expose_block_controls_deco_api')) {
534
- var _iterator3 = _createForOfIteratorHelper(nodeDecorationRegistry),
535
- _step3;
536
- try {
537
- var _loop3 = function _loop3() {
538
- var _latestActiveNode1, _latestActiveNode10, _latestActiveNode11, _latestActiveNode12, _latestActiveNode13, _activeNode15, _activeNode16;
539
- var factory = _step3.value;
540
- var params = {
541
- editorState: newState,
542
- nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
543
- anchorName: (_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.anchorName,
544
- nodeType: (_latestActiveNode10 = latestActiveNode) === null || _latestActiveNode10 === void 0 ? void 0 : _latestActiveNode10.nodeType,
545
- rootPos: (_latestActiveNode11 = latestActiveNode) === null || _latestActiveNode11 === void 0 ? void 0 : _latestActiveNode11.rootPos,
546
- rootAnchorName: (_latestActiveNode12 = latestActiveNode) === null || _latestActiveNode12 === void 0 ? void 0 : _latestActiveNode12.rootAnchorName,
547
- rootNodeType: (_latestActiveNode13 = latestActiveNode) === null || _latestActiveNode13 === void 0 ? void 0 : _latestActiveNode13.rootNodeType
536
+ if (rightSideControlsEnabled) {
537
+ var _iterator3 = _createForOfIteratorHelper(nodeDecorationRegistry),
538
+ _step3;
539
+ try {
540
+ var _loop3 = function _loop3() {
541
+ var _activeNode15, _activeNode16;
542
+ var factory = _step3.value;
543
+ if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
544
+ return 0; // continue
545
+ }
546
+ var params = {
547
+ editorState: newState,
548
+ nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
549
+ anchorName: latestActiveNode.anchorName,
550
+ nodeType: latestActiveNode.nodeType,
551
+ rootPos: latestActiveNode.rootPos,
552
+ rootAnchorName: latestActiveNode.rootAnchorName,
553
+ rootNodeType: latestActiveNode.rootNodeType
554
+ };
555
+ 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) {
556
+ return spec.type === factory.type;
557
+ });
558
+ decorations = decorations.remove(old);
559
+
560
+ // determines whether to show the decorations, see malleableUiPlugin.tsx
561
+ if (factory.shouldCreate && !factory.shouldCreate(params)) {
562
+ return 0; // continue
563
+ }
564
+ var dec = factory.create(params);
565
+ decorations = decorations.add(newState.doc, [dec]);
566
+ },
567
+ _ret;
568
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
569
+ _ret = _loop3();
570
+ if (_ret === 0) continue;
571
+ }
572
+ } catch (err) {
573
+ _iterator3.e(err);
574
+ } finally {
575
+ _iterator3.f();
576
+ }
577
+ } else {
578
+ var _iterator4 = _createForOfIteratorHelper(nodeDecorationRegistry),
579
+ _step4;
580
+ try {
581
+ var _loop4 = function _loop4() {
582
+ var factory = _step4.value;
583
+ var old = decorations.find(0, newState.doc.nodeSize, function (spec) {
584
+ return spec.type === factory.type;
585
+ });
586
+ decorations = decorations.remove(old);
548
587
  };
549
- 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) {
550
- return spec.type === factory.type;
551
- });
552
- decorations = decorations.remove(old);
553
- var dec = factory.create(params);
554
- decorations = decorations.add(newState.doc, [dec]);
555
- };
556
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
557
- _loop3();
588
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
589
+ _loop4();
590
+ }
591
+ } catch (err) {
592
+ _iterator4.e(err);
593
+ } finally {
594
+ _iterator4.f();
558
595
  }
559
- } catch (err) {
560
- _iterator3.e(err);
561
- } finally {
562
- _iterator3.f();
563
596
  }
564
597
  }
565
598
  }
566
599
 
567
600
  // In view mode (edit/live pages), show right-side controls on block hover (without drag handle or quick insert)
568
- var rootPos = (_latestActiveNode14 = latestActiveNode) === null || _latestActiveNode14 === void 0 ? void 0 : _latestActiveNode14.rootPos;
601
+ var rootPos = (_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.rootPos;
569
602
  // 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.
570
603
  var isDocLevel = rootPos !== undefined && !isNaN(rootPos);
571
604
  if (isViewMode && isDocLevel && flags.toolbarFlagsEnabled && rightSideControlsEnabled) {
572
- var _iterator4 = _createForOfIteratorHelper(nodeDecorationRegistry),
573
- _step4;
605
+ var _iterator5 = _createForOfIteratorHelper(nodeDecorationRegistry),
606
+ _step5;
574
607
  try {
575
- var _loop4 = function _loop4() {
576
- var factory = _step4.value;
577
- if (factory.showInViewMode) {
578
- var _latestActiveNode15, _latestActiveNode16, _latestActiveNode17, _latestActiveNode18, _latestActiveNode19;
579
- var existingAtPos = decorations.find(rootPos, rootPos, function (spec) {
580
- return spec.type === factory.type;
581
- });
582
- // Skip remove/re-add when decoration already exists at correct position - avoids
583
- // flickering from widget destroy/recreate on every transaction (e.g. on hover).
584
- if (existingAtPos.length > 0) {
585
- return 1; // continue
608
+ var _loop5 = function _loop5() {
609
+ var factory = _step5.value;
610
+ if (factory.showInViewMode) {
611
+ if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
612
+ return 0; // continue
613
+ }
614
+ var params = {
615
+ editorState: newState,
616
+ nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
617
+ anchorName: latestActiveNode.anchorName,
618
+ nodeType: latestActiveNode.nodeType,
619
+ rootPos: latestActiveNode.rootPos,
620
+ rootAnchorName: latestActiveNode.rootAnchorName,
621
+ rootNodeType: latestActiveNode.rootNodeType
622
+ };
623
+ if (factory.shouldCreate && !factory.shouldCreate(params)) {
624
+ return 0; // continue
625
+ }
626
+ var existingAtPos = decorations.find(rootPos, rootPos, function (spec) {
627
+ return spec.type === factory.type;
628
+ });
629
+ // Skip remove/re-add when decoration already exists at correct position - avoids
630
+ // flickering from widget destroy/recreate on every transaction (e.g. on hover).
631
+ if (existingAtPos.length > 0) {
632
+ return 0; // continue
633
+ }
634
+ // Remove any stale decoration at a different position (e.g. after moving to another block)
635
+ var stale = decorations.find(0, newState.doc.nodeSize, function (spec) {
636
+ return spec.type === factory.type;
637
+ });
638
+ decorations = decorations.remove(stale);
639
+ var dec = factory.create(params);
640
+ decorations = decorations.add(newState.doc, [dec]);
586
641
  }
587
- // Remove any stale decoration at a different position (e.g. after moving to another block)
588
- var stale = decorations.find(0, newState.doc.nodeSize, function (spec) {
589
- return spec.type === factory.type;
590
- });
591
- decorations = decorations.remove(stale);
592
- var dec = factory.create({
593
- editorState: newState,
594
- nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
595
- anchorName: (_latestActiveNode15 = latestActiveNode) === null || _latestActiveNode15 === void 0 ? void 0 : _latestActiveNode15.anchorName,
596
- nodeType: (_latestActiveNode16 = latestActiveNode) === null || _latestActiveNode16 === void 0 ? void 0 : _latestActiveNode16.nodeType,
597
- rootPos: (_latestActiveNode17 = latestActiveNode) === null || _latestActiveNode17 === void 0 ? void 0 : _latestActiveNode17.rootPos,
598
- rootAnchorName: (_latestActiveNode18 = latestActiveNode) === null || _latestActiveNode18 === void 0 ? void 0 : _latestActiveNode18.rootAnchorName,
599
- rootNodeType: (_latestActiveNode19 = latestActiveNode) === null || _latestActiveNode19 === void 0 ? void 0 : _latestActiveNode19.rootNodeType
600
- });
601
- decorations = decorations.add(newState.doc, [dec]);
602
- }
603
- };
604
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
605
- if (_loop4()) continue;
642
+ },
643
+ _ret2;
644
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
645
+ _ret2 = _loop5();
646
+ if (_ret2 === 0) continue;
606
647
  }
607
648
  } catch (err) {
608
- _iterator4.e(err);
649
+ _iterator5.e(err);
609
650
  } finally {
610
- _iterator4.f();
651
+ _iterator5.f();
611
652
  }
612
653
  } else if (isViewMode && rightSideControlsEnabled && (0, _expValEquals.expValEquals)('confluence_remix_icon_right_side', 'isEnabled', true)) {
613
654
  // Remove view-mode right-side decorations when no active node
614
- var _iterator5 = _createForOfIteratorHelper(nodeDecorationRegistry),
615
- _step5;
655
+ var _iterator6 = _createForOfIteratorHelper(nodeDecorationRegistry),
656
+ _step6;
616
657
  try {
617
- var _loop5 = function _loop5() {
618
- var factory = _step5.value;
658
+ var _loop6 = function _loop6() {
659
+ var factory = _step6.value;
619
660
  if (factory.showInViewMode) {
620
661
  var old = decorations.find(0, newState.doc.nodeSize, function (spec) {
621
662
  return spec.type === factory.type;
@@ -623,13 +664,13 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
623
664
  decorations = decorations.remove(old);
624
665
  }
625
666
  };
626
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
627
- _loop5();
667
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
668
+ _loop6();
628
669
  }
629
670
  } catch (err) {
630
- _iterator5.e(err);
671
+ _iterator6.e(err);
631
672
  } finally {
632
- _iterator5.f();
673
+ _iterator6.f();
633
674
  }
634
675
  }
635
676
  }
@@ -678,15 +719,15 @@ var _apply = exports.apply = function apply(api, formatMessage, tr, currentState
678
719
  var newActiveNode;
679
720
  // platform_editor_controls note: enables quick insert
680
721
  if (flags.toolbarFlagsEnabled) {
681
- var _latestActiveNode20, _latestActiveNode21;
722
+ var _latestActiveNode10, _latestActiveNode11;
682
723
  // remove isEmptyDoc check and let decorations render and determine their own visibility
683
724
  // In view mode with right-side controls we render node decorations (right-edge button), not the
684
725
  // handle - so findHandleDec is always empty. Don't clear activeNode in that case.
685
- var hasHandleOrViewModeControls = (0, _decorationsDragHandle.findHandleDec)(decorations, (_latestActiveNode20 = latestActiveNode) === null || _latestActiveNode20 === void 0 ? void 0 : _latestActiveNode20.pos, (_latestActiveNode21 = latestActiveNode) === null || _latestActiveNode21 === void 0 ? void 0 : _latestActiveNode21.pos).length > 0 || isViewMode && rightSideControlsEnabled;
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;
686
727
  newActiveNode = meta !== null && meta !== void 0 && meta.editorBlurred || !(meta !== null && meta !== void 0 && meta.activeNode) && !hasHandleOrViewModeControls ? null : latestActiveNode;
687
728
  } else {
688
- var _latestActiveNode22, _latestActiveNode23;
689
- newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && (0, _decorationsDragHandle.findHandleDec)(decorations, (_latestActiveNode22 = latestActiveNode) === null || _latestActiveNode22 === void 0 ? void 0 : _latestActiveNode22.pos, (_latestActiveNode23 = latestActiveNode) === null || _latestActiveNode23 === void 0 ? void 0 : _latestActiveNode23.pos).length === 0 ? null : latestActiveNode;
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;
690
731
  }
691
732
  var isMenuOpenNew = isMenuOpen;
692
733
  if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true)) {
@@ -444,7 +444,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
444
444
  decorations = decorations.remove(old);
445
445
  }
446
446
  }
447
- if (rightSideControlsEnabled && expValEquals('confluence_remix_icon_right_side', 'isEnabled', true) && isViewMode) {
447
+ if (rightSideControlsEnabled && isViewMode && expValEquals('confluence_remix_icon_right_side', 'isEnabled', true)) {
448
448
  for (const factory of nodeDecorationRegistry) {
449
449
  if (factory.showInViewMode) {
450
450
  var _activeNode1, _activeNode10;
@@ -455,7 +455,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
455
455
  }
456
456
  }
457
457
  } else if (api) {
458
- var _latestActiveNode5, _latestActiveNode14;
458
+ var _latestActiveNode5, _latestActiveNode1;
459
459
  if (shouldRecreateHandle && (!rightSideControlsEnabled || !isViewMode)) {
460
460
  var _activeNode11, _activeNode12, _latestActiveNode, _latestActiveNode2, _latestActiveNode3, _latestActiveNode4;
461
461
  const oldHandle = findHandleDec(decorations, (_activeNode11 = activeNode) === null || _activeNode11 === void 0 ? void 0 : _activeNode11.pos, (_activeNode12 = activeNode) === null || _activeNode12 === void 0 ? void 0 : _activeNode12.pos);
@@ -492,34 +492,65 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
492
492
  editorState: newState
493
493
  });
494
494
  decorations = decorations.add(newState.doc, [quickInsertButton]);
495
+
496
+ // both gates have overlapping logic to determine what controls to show
495
497
  if (fg('platform_editor_expose_block_controls_deco_api')) {
496
- for (const factory of nodeDecorationRegistry) {
497
- var _latestActiveNode1, _latestActiveNode10, _latestActiveNode11, _latestActiveNode12, _latestActiveNode13, _activeNode15, _activeNode16;
498
- const params = {
499
- editorState: newState,
500
- nodeViewPortalProviderAPI,
501
- anchorName: (_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.anchorName,
502
- nodeType: (_latestActiveNode10 = latestActiveNode) === null || _latestActiveNode10 === void 0 ? void 0 : _latestActiveNode10.nodeType,
503
- rootPos: (_latestActiveNode11 = latestActiveNode) === null || _latestActiveNode11 === void 0 ? void 0 : _latestActiveNode11.rootPos,
504
- rootAnchorName: (_latestActiveNode12 = latestActiveNode) === null || _latestActiveNode12 === void 0 ? void 0 : _latestActiveNode12.rootAnchorName,
505
- rootNodeType: (_latestActiveNode13 = latestActiveNode) === null || _latestActiveNode13 === void 0 ? void 0 : _latestActiveNode13.rootNodeType
506
- };
507
- const old = decorations.find((_activeNode15 = activeNode) === null || _activeNode15 === void 0 ? void 0 : _activeNode15.rootPos, (_activeNode16 = activeNode) === null || _activeNode16 === void 0 ? void 0 : _activeNode16.rootPos, spec => spec.type === factory.type);
508
- decorations = decorations.remove(old);
509
- const dec = factory.create(params);
510
- decorations = decorations.add(newState.doc, [dec]);
498
+ if (rightSideControlsEnabled) {
499
+ for (const factory of nodeDecorationRegistry) {
500
+ var _activeNode15, _activeNode16;
501
+ if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
502
+ continue;
503
+ }
504
+ const params = {
505
+ editorState: newState,
506
+ nodeViewPortalProviderAPI,
507
+ anchorName: latestActiveNode.anchorName,
508
+ nodeType: latestActiveNode.nodeType,
509
+ rootPos: latestActiveNode.rootPos,
510
+ rootAnchorName: latestActiveNode.rootAnchorName,
511
+ rootNodeType: latestActiveNode.rootNodeType
512
+ };
513
+ const old = decorations.find((_activeNode15 = activeNode) === null || _activeNode15 === void 0 ? void 0 : _activeNode15.rootPos, (_activeNode16 = activeNode) === null || _activeNode16 === void 0 ? void 0 : _activeNode16.rootPos, spec => spec.type === factory.type);
514
+ decorations = decorations.remove(old);
515
+
516
+ // determines whether to show the decorations, see malleableUiPlugin.tsx
517
+ if (factory.shouldCreate && !factory.shouldCreate(params)) {
518
+ continue;
519
+ }
520
+ const dec = factory.create(params);
521
+ decorations = decorations.add(newState.doc, [dec]);
522
+ }
523
+ } else {
524
+ for (const factory of nodeDecorationRegistry) {
525
+ const old = decorations.find(0, newState.doc.nodeSize, spec => spec.type === factory.type);
526
+ decorations = decorations.remove(old);
527
+ }
511
528
  }
512
529
  }
513
530
  }
514
531
 
515
532
  // In view mode (edit/live pages), show right-side controls on block hover (without drag handle or quick insert)
516
- const rootPos = (_latestActiveNode14 = latestActiveNode) === null || _latestActiveNode14 === void 0 ? void 0 : _latestActiveNode14.rootPos;
533
+ const rootPos = (_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.rootPos;
517
534
  // 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.
518
535
  const isDocLevel = rootPos !== undefined && !isNaN(rootPos);
519
536
  if (isViewMode && isDocLevel && flags.toolbarFlagsEnabled && rightSideControlsEnabled) {
520
537
  for (const factory of nodeDecorationRegistry) {
521
538
  if (factory.showInViewMode) {
522
- var _latestActiveNode15, _latestActiveNode16, _latestActiveNode17, _latestActiveNode18, _latestActiveNode19;
539
+ if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
540
+ continue;
541
+ }
542
+ const params = {
543
+ editorState: newState,
544
+ nodeViewPortalProviderAPI,
545
+ anchorName: latestActiveNode.anchorName,
546
+ nodeType: latestActiveNode.nodeType,
547
+ rootPos: latestActiveNode.rootPos,
548
+ rootAnchorName: latestActiveNode.rootAnchorName,
549
+ rootNodeType: latestActiveNode.rootNodeType
550
+ };
551
+ if (factory.shouldCreate && !factory.shouldCreate(params)) {
552
+ continue;
553
+ }
523
554
  const existingAtPos = decorations.find(rootPos, rootPos, spec => spec.type === factory.type);
524
555
  // Skip remove/re-add when decoration already exists at correct position - avoids
525
556
  // flickering from widget destroy/recreate on every transaction (e.g. on hover).
@@ -529,15 +560,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
529
560
  // Remove any stale decoration at a different position (e.g. after moving to another block)
530
561
  const stale = decorations.find(0, newState.doc.nodeSize, spec => spec.type === factory.type);
531
562
  decorations = decorations.remove(stale);
532
- const dec = factory.create({
533
- editorState: newState,
534
- nodeViewPortalProviderAPI,
535
- anchorName: (_latestActiveNode15 = latestActiveNode) === null || _latestActiveNode15 === void 0 ? void 0 : _latestActiveNode15.anchorName,
536
- nodeType: (_latestActiveNode16 = latestActiveNode) === null || _latestActiveNode16 === void 0 ? void 0 : _latestActiveNode16.nodeType,
537
- rootPos: (_latestActiveNode17 = latestActiveNode) === null || _latestActiveNode17 === void 0 ? void 0 : _latestActiveNode17.rootPos,
538
- rootAnchorName: (_latestActiveNode18 = latestActiveNode) === null || _latestActiveNode18 === void 0 ? void 0 : _latestActiveNode18.rootAnchorName,
539
- rootNodeType: (_latestActiveNode19 = latestActiveNode) === null || _latestActiveNode19 === void 0 ? void 0 : _latestActiveNode19.rootNodeType
540
- });
563
+ const dec = factory.create(params);
541
564
  decorations = decorations.add(newState.doc, [dec]);
542
565
  }
543
566
  }
@@ -597,15 +620,15 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
597
620
  let newActiveNode;
598
621
  // platform_editor_controls note: enables quick insert
599
622
  if (flags.toolbarFlagsEnabled) {
600
- var _latestActiveNode20, _latestActiveNode21;
623
+ var _latestActiveNode10, _latestActiveNode11;
601
624
  // remove isEmptyDoc check and let decorations render and determine their own visibility
602
625
  // In view mode with right-side controls we render node decorations (right-edge button), not the
603
626
  // handle - so findHandleDec is always empty. Don't clear activeNode in that case.
604
- const hasHandleOrViewModeControls = findHandleDec(decorations, (_latestActiveNode20 = latestActiveNode) === null || _latestActiveNode20 === void 0 ? void 0 : _latestActiveNode20.pos, (_latestActiveNode21 = latestActiveNode) === null || _latestActiveNode21 === void 0 ? void 0 : _latestActiveNode21.pos).length > 0 || isViewMode && rightSideControlsEnabled;
627
+ const hasHandleOrViewModeControls = 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;
605
628
  newActiveNode = meta !== null && meta !== void 0 && meta.editorBlurred || !(meta !== null && meta !== void 0 && meta.activeNode) && !hasHandleOrViewModeControls ? null : latestActiveNode;
606
629
  } else {
607
- var _latestActiveNode22, _latestActiveNode23;
608
- newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, (_latestActiveNode22 = latestActiveNode) === null || _latestActiveNode22 === void 0 ? void 0 : _latestActiveNode22.pos, (_latestActiveNode23 = latestActiveNode) === null || _latestActiveNode23 === void 0 ? void 0 : _latestActiveNode23.pos).length === 0 ? null : latestActiveNode;
630
+ var _latestActiveNode12, _latestActiveNode13;
631
+ newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && 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;
609
632
  }
610
633
  let isMenuOpenNew = isMenuOpen;
611
634
  if (expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true)) {
@@ -461,7 +461,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
461
461
  _iterator.f();
462
462
  }
463
463
  }
464
- if (rightSideControlsEnabled && expValEquals('confluence_remix_icon_right_side', 'isEnabled', true) && isViewMode) {
464
+ if (rightSideControlsEnabled && isViewMode && expValEquals('confluence_remix_icon_right_side', 'isEnabled', true)) {
465
465
  var _iterator2 = _createForOfIteratorHelper(nodeDecorationRegistry),
466
466
  _step2;
467
467
  try {
@@ -486,7 +486,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
486
486
  }
487
487
  }
488
488
  } else if (api) {
489
- var _latestActiveNode5, _latestActiveNode14;
489
+ var _latestActiveNode5, _latestActiveNode1;
490
490
  if (shouldRecreateHandle && (!rightSideControlsEnabled || !isViewMode)) {
491
491
  var _activeNode11, _activeNode12, _latestActiveNode, _latestActiveNode2, _latestActiveNode3, _latestActiveNode4;
492
492
  var _oldHandle = findHandleDec(decorations, (_activeNode11 = activeNode) === null || _activeNode11 === void 0 ? void 0 : _activeNode11.pos, (_activeNode12 = activeNode) === null || _activeNode12 === void 0 ? void 0 : _activeNode12.pos);
@@ -523,92 +523,133 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
523
523
  editorState: newState
524
524
  });
525
525
  decorations = decorations.add(newState.doc, [quickInsertButton]);
526
+
527
+ // both gates have overlapping logic to determine what controls to show
526
528
  if (fg('platform_editor_expose_block_controls_deco_api')) {
527
- var _iterator3 = _createForOfIteratorHelper(nodeDecorationRegistry),
528
- _step3;
529
- try {
530
- var _loop3 = function _loop3() {
531
- var _latestActiveNode1, _latestActiveNode10, _latestActiveNode11, _latestActiveNode12, _latestActiveNode13, _activeNode15, _activeNode16;
532
- var factory = _step3.value;
533
- var params = {
534
- editorState: newState,
535
- nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
536
- anchorName: (_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.anchorName,
537
- nodeType: (_latestActiveNode10 = latestActiveNode) === null || _latestActiveNode10 === void 0 ? void 0 : _latestActiveNode10.nodeType,
538
- rootPos: (_latestActiveNode11 = latestActiveNode) === null || _latestActiveNode11 === void 0 ? void 0 : _latestActiveNode11.rootPos,
539
- rootAnchorName: (_latestActiveNode12 = latestActiveNode) === null || _latestActiveNode12 === void 0 ? void 0 : _latestActiveNode12.rootAnchorName,
540
- rootNodeType: (_latestActiveNode13 = latestActiveNode) === null || _latestActiveNode13 === void 0 ? void 0 : _latestActiveNode13.rootNodeType
529
+ if (rightSideControlsEnabled) {
530
+ var _iterator3 = _createForOfIteratorHelper(nodeDecorationRegistry),
531
+ _step3;
532
+ try {
533
+ var _loop3 = function _loop3() {
534
+ var _activeNode15, _activeNode16;
535
+ var factory = _step3.value;
536
+ if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
537
+ return 0; // continue
538
+ }
539
+ var params = {
540
+ editorState: newState,
541
+ nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
542
+ anchorName: latestActiveNode.anchorName,
543
+ nodeType: latestActiveNode.nodeType,
544
+ rootPos: latestActiveNode.rootPos,
545
+ rootAnchorName: latestActiveNode.rootAnchorName,
546
+ rootNodeType: latestActiveNode.rootNodeType
547
+ };
548
+ 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) {
549
+ return spec.type === factory.type;
550
+ });
551
+ decorations = decorations.remove(old);
552
+
553
+ // determines whether to show the decorations, see malleableUiPlugin.tsx
554
+ if (factory.shouldCreate && !factory.shouldCreate(params)) {
555
+ return 0; // continue
556
+ }
557
+ var dec = factory.create(params);
558
+ decorations = decorations.add(newState.doc, [dec]);
559
+ },
560
+ _ret;
561
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
562
+ _ret = _loop3();
563
+ if (_ret === 0) continue;
564
+ }
565
+ } catch (err) {
566
+ _iterator3.e(err);
567
+ } finally {
568
+ _iterator3.f();
569
+ }
570
+ } else {
571
+ var _iterator4 = _createForOfIteratorHelper(nodeDecorationRegistry),
572
+ _step4;
573
+ try {
574
+ var _loop4 = function _loop4() {
575
+ var factory = _step4.value;
576
+ var old = decorations.find(0, newState.doc.nodeSize, function (spec) {
577
+ return spec.type === factory.type;
578
+ });
579
+ decorations = decorations.remove(old);
541
580
  };
542
- 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) {
543
- return spec.type === factory.type;
544
- });
545
- decorations = decorations.remove(old);
546
- var dec = factory.create(params);
547
- decorations = decorations.add(newState.doc, [dec]);
548
- };
549
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
550
- _loop3();
581
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
582
+ _loop4();
583
+ }
584
+ } catch (err) {
585
+ _iterator4.e(err);
586
+ } finally {
587
+ _iterator4.f();
551
588
  }
552
- } catch (err) {
553
- _iterator3.e(err);
554
- } finally {
555
- _iterator3.f();
556
589
  }
557
590
  }
558
591
  }
559
592
 
560
593
  // In view mode (edit/live pages), show right-side controls on block hover (without drag handle or quick insert)
561
- var rootPos = (_latestActiveNode14 = latestActiveNode) === null || _latestActiveNode14 === void 0 ? void 0 : _latestActiveNode14.rootPos;
594
+ var rootPos = (_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.rootPos;
562
595
  // 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.
563
596
  var isDocLevel = rootPos !== undefined && !isNaN(rootPos);
564
597
  if (isViewMode && isDocLevel && flags.toolbarFlagsEnabled && rightSideControlsEnabled) {
565
- var _iterator4 = _createForOfIteratorHelper(nodeDecorationRegistry),
566
- _step4;
598
+ var _iterator5 = _createForOfIteratorHelper(nodeDecorationRegistry),
599
+ _step5;
567
600
  try {
568
- var _loop4 = function _loop4() {
569
- var factory = _step4.value;
570
- if (factory.showInViewMode) {
571
- var _latestActiveNode15, _latestActiveNode16, _latestActiveNode17, _latestActiveNode18, _latestActiveNode19;
572
- var existingAtPos = decorations.find(rootPos, rootPos, function (spec) {
573
- return spec.type === factory.type;
574
- });
575
- // Skip remove/re-add when decoration already exists at correct position - avoids
576
- // flickering from widget destroy/recreate on every transaction (e.g. on hover).
577
- if (existingAtPos.length > 0) {
578
- return 1; // continue
601
+ var _loop5 = function _loop5() {
602
+ var factory = _step5.value;
603
+ if (factory.showInViewMode) {
604
+ if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
605
+ return 0; // continue
606
+ }
607
+ var params = {
608
+ editorState: newState,
609
+ nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
610
+ anchorName: latestActiveNode.anchorName,
611
+ nodeType: latestActiveNode.nodeType,
612
+ rootPos: latestActiveNode.rootPos,
613
+ rootAnchorName: latestActiveNode.rootAnchorName,
614
+ rootNodeType: latestActiveNode.rootNodeType
615
+ };
616
+ if (factory.shouldCreate && !factory.shouldCreate(params)) {
617
+ return 0; // continue
618
+ }
619
+ var existingAtPos = decorations.find(rootPos, rootPos, function (spec) {
620
+ return spec.type === factory.type;
621
+ });
622
+ // Skip remove/re-add when decoration already exists at correct position - avoids
623
+ // flickering from widget destroy/recreate on every transaction (e.g. on hover).
624
+ if (existingAtPos.length > 0) {
625
+ return 0; // continue
626
+ }
627
+ // Remove any stale decoration at a different position (e.g. after moving to another block)
628
+ var stale = decorations.find(0, newState.doc.nodeSize, function (spec) {
629
+ return spec.type === factory.type;
630
+ });
631
+ decorations = decorations.remove(stale);
632
+ var dec = factory.create(params);
633
+ decorations = decorations.add(newState.doc, [dec]);
579
634
  }
580
- // Remove any stale decoration at a different position (e.g. after moving to another block)
581
- var stale = decorations.find(0, newState.doc.nodeSize, function (spec) {
582
- return spec.type === factory.type;
583
- });
584
- decorations = decorations.remove(stale);
585
- var dec = factory.create({
586
- editorState: newState,
587
- nodeViewPortalProviderAPI: nodeViewPortalProviderAPI,
588
- anchorName: (_latestActiveNode15 = latestActiveNode) === null || _latestActiveNode15 === void 0 ? void 0 : _latestActiveNode15.anchorName,
589
- nodeType: (_latestActiveNode16 = latestActiveNode) === null || _latestActiveNode16 === void 0 ? void 0 : _latestActiveNode16.nodeType,
590
- rootPos: (_latestActiveNode17 = latestActiveNode) === null || _latestActiveNode17 === void 0 ? void 0 : _latestActiveNode17.rootPos,
591
- rootAnchorName: (_latestActiveNode18 = latestActiveNode) === null || _latestActiveNode18 === void 0 ? void 0 : _latestActiveNode18.rootAnchorName,
592
- rootNodeType: (_latestActiveNode19 = latestActiveNode) === null || _latestActiveNode19 === void 0 ? void 0 : _latestActiveNode19.rootNodeType
593
- });
594
- decorations = decorations.add(newState.doc, [dec]);
595
- }
596
- };
597
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
598
- if (_loop4()) continue;
635
+ },
636
+ _ret2;
637
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
638
+ _ret2 = _loop5();
639
+ if (_ret2 === 0) continue;
599
640
  }
600
641
  } catch (err) {
601
- _iterator4.e(err);
642
+ _iterator5.e(err);
602
643
  } finally {
603
- _iterator4.f();
644
+ _iterator5.f();
604
645
  }
605
646
  } else if (isViewMode && rightSideControlsEnabled && expValEquals('confluence_remix_icon_right_side', 'isEnabled', true)) {
606
647
  // Remove view-mode right-side decorations when no active node
607
- var _iterator5 = _createForOfIteratorHelper(nodeDecorationRegistry),
608
- _step5;
648
+ var _iterator6 = _createForOfIteratorHelper(nodeDecorationRegistry),
649
+ _step6;
609
650
  try {
610
- var _loop5 = function _loop5() {
611
- var factory = _step5.value;
651
+ var _loop6 = function _loop6() {
652
+ var factory = _step6.value;
612
653
  if (factory.showInViewMode) {
613
654
  var old = decorations.find(0, newState.doc.nodeSize, function (spec) {
614
655
  return spec.type === factory.type;
@@ -616,13 +657,13 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
616
657
  decorations = decorations.remove(old);
617
658
  }
618
659
  };
619
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
620
- _loop5();
660
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
661
+ _loop6();
621
662
  }
622
663
  } catch (err) {
623
- _iterator5.e(err);
664
+ _iterator6.e(err);
624
665
  } finally {
625
- _iterator5.f();
666
+ _iterator6.f();
626
667
  }
627
668
  }
628
669
  }
@@ -671,15 +712,15 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
671
712
  var newActiveNode;
672
713
  // platform_editor_controls note: enables quick insert
673
714
  if (flags.toolbarFlagsEnabled) {
674
- var _latestActiveNode20, _latestActiveNode21;
715
+ var _latestActiveNode10, _latestActiveNode11;
675
716
  // remove isEmptyDoc check and let decorations render and determine their own visibility
676
717
  // In view mode with right-side controls we render node decorations (right-edge button), not the
677
718
  // handle - so findHandleDec is always empty. Don't clear activeNode in that case.
678
- var hasHandleOrViewModeControls = findHandleDec(decorations, (_latestActiveNode20 = latestActiveNode) === null || _latestActiveNode20 === void 0 ? void 0 : _latestActiveNode20.pos, (_latestActiveNode21 = latestActiveNode) === null || _latestActiveNode21 === void 0 ? void 0 : _latestActiveNode21.pos).length > 0 || isViewMode && rightSideControlsEnabled;
719
+ var hasHandleOrViewModeControls = 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;
679
720
  newActiveNode = meta !== null && meta !== void 0 && meta.editorBlurred || !(meta !== null && meta !== void 0 && meta.activeNode) && !hasHandleOrViewModeControls ? null : latestActiveNode;
680
721
  } else {
681
- var _latestActiveNode22, _latestActiveNode23;
682
- newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, (_latestActiveNode22 = latestActiveNode) === null || _latestActiveNode22 === void 0 ? void 0 : _latestActiveNode22.pos, (_latestActiveNode23 = latestActiveNode) === null || _latestActiveNode23 === void 0 ? void 0 : _latestActiveNode23.pos).length === 0 ? null : latestActiveNode;
722
+ var _latestActiveNode12, _latestActiveNode13;
723
+ newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && 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;
683
724
  }
684
725
  var isMenuOpenNew = isMenuOpen;
685
726
  if (expValEqualsNoExposure('platform_editor_block_menu', 'isEnabled', true)) {
@@ -134,6 +134,11 @@ export type NodeDecorationFactory = {
134
134
  create: (params: NodeDecorationFactoryParams) => Decoration;
135
135
  /** Show this decoration in view mode when hovering over a block */
136
136
  showInViewMode?: boolean;
137
+ /**
138
+ * Optional filter: when false, the decoration is not created.
139
+ * Use for node-type-specific visibility (e.g. Remix button only on remixable blocks).
140
+ */
141
+ shouldCreate?: (params: NodeDecorationFactoryParams) => boolean;
137
142
  type: string;
138
143
  };
139
144
  export type MoveNode = (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
@@ -136,6 +136,11 @@ export type NodeDecorationFactory = {
136
136
  create: (params: NodeDecorationFactoryParams) => Decoration;
137
137
  /** Show this decoration in view mode when hovering over a block */
138
138
  showInViewMode?: boolean;
139
+ /**
140
+ * Optional filter: when false, the decoration is not created.
141
+ * Use for node-type-specific visibility (e.g. Remix button only on remixable blocks).
142
+ */
143
+ shouldCreate?: (params: NodeDecorationFactoryParams) => boolean;
139
144
  type: string;
140
145
  };
141
146
  export type MoveNode = (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "8.9.1",
3
+ "version": "8.10.0",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -28,7 +28,7 @@
28
28
  ],
29
29
  "atlaskit:src": "src/index.ts",
30
30
  "dependencies": {
31
- "@atlaskit/adf-schema": "^52.1.0",
31
+ "@atlaskit/adf-schema": "^52.2.0",
32
32
  "@atlaskit/browser-apis": "^0.0.1",
33
33
  "@atlaskit/button": "^23.10.0",
34
34
  "@atlaskit/editor-plugin-accessibility-utils": "^7.0.0",
@@ -57,7 +57,7 @@
57
57
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
58
58
  "@atlaskit/primitives": "^18.0.0",
59
59
  "@atlaskit/theme": "^22.0.0",
60
- "@atlaskit/tmp-editor-statsig": "^32.12.0",
60
+ "@atlaskit/tmp-editor-statsig": "^33.1.0",
61
61
  "@atlaskit/tokens": "^11.0.0",
62
62
  "@atlaskit/tooltip": "^20.14.0",
63
63
  "@babel/runtime": "^7.0.0",
@@ -68,7 +68,7 @@
68
68
  "uuid": "^3.1.0"
69
69
  },
70
70
  "peerDependencies": {
71
- "@atlaskit/editor-common": "^111.25.0",
71
+ "@atlaskit/editor-common": "^111.27.0",
72
72
  "react": "^18.2.0",
73
73
  "react-dom": "^18.2.0",
74
74
  "react-intl-next": "npm:react-intl@^5.18.1"