@atlaskit/editor-plugin-synced-block 8.3.10 → 8.3.12

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-synced-block
2
2
 
3
+ ## 8.3.12
4
+
5
+ ### Patch Changes
6
+
7
+ - [`6ce6728b2191c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6ce6728b2191c) -
8
+ Adds separate testId for overflow menu to differenciate between reference and source sync block
9
+ button.
10
+
11
+ ## 8.3.11
12
+
13
+ ### Patch Changes
14
+
15
+ - [`2cef675d24c75`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2cef675d24c75) -
16
+ Performance: short-circuit synced block plugin state updates for no-op editor transactions when
17
+ the perf experiment is enabled.
18
+ - Updated dependencies
19
+
3
20
  ## 8.3.10
4
21
 
5
22
  ### Patch Changes
@@ -411,7 +411,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
411
411
  };
412
412
  },
413
413
  apply: function apply(tr, currentPluginState, oldEditorState) {
414
- var _meta$activeFlag, _meta$bodiedSyncBlock;
414
+ var _api$userIntent2, _api$connectivity3, _api$editorViewMode2, _meta$activeFlag, _meta$bodiedSyncBlock;
415
415
  var meta = tr.getMeta(syncedBlockPluginKey);
416
416
  // isPerfExperimentOn is cached at createPlugin() level — see above
417
417
 
@@ -425,6 +425,29 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
425
425
  prevViewMode = currentPluginState.prevIsViewMode,
426
426
  prevDragging = currentPluginState.prevIsDragging;
427
427
 
428
+ // Pre-compute once so the fast-path probe and the bottom ref-equality
429
+ // short-circuit share the same source-manager snapshot. Track C will make this O(1).
430
+ var nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
431
+
432
+ // --- Fast path (EDITOR-6934 follow-up, see Confluence 7050540723 §9.3 / §9.9):
433
+ // when no plugin meta is set, and neither the document nor selection changed,
434
+ // most synced-block plugin state cannot change. The source manager is mutable
435
+ // outside ProseMirror transactions, though, so preserve existing empty-transaction
436
+ // sync semantics by checking that snapshot first.
437
+ //
438
+ // Note: selection-only transactions intentionally fall through to the normal
439
+ // apply path because calculateDecorations depends on drag/view-mode state
440
+ // that is not captured here.
441
+ //
442
+ // We also need to ensure shared-state signals (drag, offline, view-mode)
443
+ // haven't changed — these are propagated via empty transactions and drive
444
+ // status decoration rebuilds (e.g. drag border). Without this check the
445
+ // fast path would swallow drag-start transactions and the synced block
446
+ // border would never appear (see VR test: synced-block-drag-selection).
447
+ if (isPerfExperimentOn && !meta && !tr.docChanged && tr.selection.eq(oldEditorState.selection) && nextHasUnsavedBodiedSyncBlockChanges === currentPluginState.hasUnsavedBodiedSyncBlockChanges && (api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || (_api$userIntent2 = _api$userIntent2.sharedState.currentState()) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.currentUserIntent) === 'dragging' === prevDragging && (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity3 = api.connectivity) === null || _api$connectivity3 === void 0 || (_api$connectivity3 = _api$connectivity3.sharedState.currentState()) === null || _api$connectivity3 === void 0 ? void 0 : _api$connectivity3.mode) === prevOffline && (api === null || api === void 0 || (_api$editorViewMode2 = api.editorViewMode) === null || _api$editorViewMode2 === void 0 || (_api$editorViewMode2 = _api$editorViewMode2.sharedState.currentState()) === null || _api$editorViewMode2 === void 0 ? void 0 : _api$editorViewMode2.mode) === 'view' === prevViewMode) {
448
+ return currentPluginState;
449
+ }
450
+
428
451
  // Lazy-init bookkeeping: once a synced block enters the document we
429
452
  // flip `hasSyncedBlocks` to `true` for the lifetime of this editor
430
453
  var nextHasSyncedBlocks = prevHasSyncedBlocks;
@@ -433,14 +456,6 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
433
456
  nextHasSyncedBlocks = true;
434
457
  }
435
458
  }
436
-
437
- // --- Fast path (EDITOR-6929): when `hasSyncedBlocks` is false,
438
- // no meta is set, and the selection/doc haven't changed in a way
439
- // that affects our state, return the SAME object reference so
440
- // SharedStateAPI skips notifying subscribers. ---
441
- if (!nextHasSyncedBlocks && !meta && !tr.docChanged && tr.selection.eq(oldEditorState.selection) && isPerfExperimentOn) {
442
- return currentPluginState;
443
- }
444
459
  var newDecorationSet = tr.docChanged ? selectionDecorationSet.map(tr.mapping, tr.doc) // only map if document changed
445
460
  : selectionDecorationSet;
446
461
  if (!tr.selection.eq(oldEditorState.selection)) {
@@ -469,11 +484,11 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
469
484
  // No synced blocks → keep empty status decorations
470
485
  nextStatusDecorationSet = _view.DecorationSet.empty;
471
486
  } else {
472
- var _api$connectivity3, _api$editorViewMode2, _api$userIntent2;
487
+ var _api$connectivity4, _api$editorViewMode3, _api$userIntent3;
473
488
  // Read current shared-state signals
474
- nextIsOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity3 = api.connectivity) === null || _api$connectivity3 === void 0 || (_api$connectivity3 = _api$connectivity3.sharedState.currentState()) === null || _api$connectivity3 === void 0 ? void 0 : _api$connectivity3.mode);
475
- nextIsViewMode = (api === null || api === void 0 || (_api$editorViewMode2 = api.editorViewMode) === null || _api$editorViewMode2 === void 0 || (_api$editorViewMode2 = _api$editorViewMode2.sharedState.currentState()) === null || _api$editorViewMode2 === void 0 ? void 0 : _api$editorViewMode2.mode) === 'view';
476
- nextIsDragging = (api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || (_api$userIntent2 = _api$userIntent2.sharedState.currentState()) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.currentUserIntent) === 'dragging';
489
+ nextIsOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity4 = api.connectivity) === null || _api$connectivity4 === void 0 || (_api$connectivity4 = _api$connectivity4.sharedState.currentState()) === null || _api$connectivity4 === void 0 ? void 0 : _api$connectivity4.mode);
490
+ nextIsViewMode = (api === null || api === void 0 || (_api$editorViewMode3 = api.editorViewMode) === null || _api$editorViewMode3 === void 0 || (_api$editorViewMode3 = _api$editorViewMode3.sharedState.currentState()) === null || _api$editorViewMode3 === void 0 ? void 0 : _api$editorViewMode3.mode) === 'view';
491
+ nextIsDragging = (api === null || api === void 0 || (_api$userIntent3 = api.userIntent) === null || _api$userIntent3 === void 0 || (_api$userIntent3 = _api$userIntent3.sharedState.currentState()) === null || _api$userIntent3 === void 0 ? void 0 : _api$userIntent3.currentUserIntent) === 'dragging';
477
492
 
478
493
  // Determine whether we need a full rebuild or a cheap map
479
494
  var hasSyncedBlocksJustFlipped = nextHasSyncedBlocks && !prevHasSyncedBlocks;
@@ -495,7 +510,6 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
495
510
  var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping), isPerfExperimentOn);
496
511
  var nextActiveFlag = (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag;
497
512
  var nextBodiedSyncBlockDeletionStatus = (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus;
498
- var nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
499
513
 
500
514
  // --- Reference equality (EDITOR-6929): return the same object
501
515
  // when ALL fields are reference-equal to avoid SharedStateAPI
@@ -588,15 +602,15 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
588
602
  return hasFocus ? selectionDecorationSet.add(state.doc, statusDecorations) : statusDecorationSet;
589
603
  }
590
604
  } else {
591
- var _api$connectivity4, _api$editorViewMode3, _api$userIntent3, _api$focus2;
605
+ var _api$connectivity5, _api$editorViewMode4, _api$userIntent4, _api$focus2;
592
606
  // --- Legacy path (perf gate OFF) ---
593
607
  // Full `doc.descendants()` walk every transaction. Preserved
594
608
  // for safe rollback.
595
609
  var _syncBlockStore = currentPluginState.syncBlockStore;
596
610
  var doc = state.doc;
597
- var isOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity4 = api.connectivity) === null || _api$connectivity4 === void 0 || (_api$connectivity4 = _api$connectivity4.sharedState.currentState()) === null || _api$connectivity4 === void 0 ? void 0 : _api$connectivity4.mode);
598
- var isViewMode = (api === null || api === void 0 || (_api$editorViewMode3 = api.editorViewMode) === null || _api$editorViewMode3 === void 0 || (_api$editorViewMode3 = _api$editorViewMode3.sharedState.currentState()) === null || _api$editorViewMode3 === void 0 ? void 0 : _api$editorViewMode3.mode) === 'view';
599
- var isDragging = (api === null || api === void 0 || (_api$userIntent3 = api.userIntent) === null || _api$userIntent3 === void 0 || (_api$userIntent3 = _api$userIntent3.sharedState.currentState()) === null || _api$userIntent3 === void 0 ? void 0 : _api$userIntent3.currentUserIntent) === 'dragging';
611
+ var isOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 || (_api$connectivity5 = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5 === void 0 ? void 0 : _api$connectivity5.mode);
612
+ var isViewMode = (api === null || api === void 0 || (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 || (_api$editorViewMode4 = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4 === void 0 ? void 0 : _api$editorViewMode4.mode) === 'view';
613
+ var isDragging = (api === null || api === void 0 || (_api$userIntent4 = api.userIntent) === null || _api$userIntent4 === void 0 || (_api$userIntent4 = _api$userIntent4.sharedState.currentState()) === null || _api$userIntent4 === void 0 ? void 0 : _api$userIntent4.currentUserIntent) === 'dragging';
600
614
  var offlineDecorations = [];
601
615
  var viewModeDecorations = [];
602
616
  var loadingDecorations = [];
@@ -685,7 +699,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
685
699
  }
686
700
  },
687
701
  filterTransaction: function filterTransaction(tr, state) {
688
- var _api$editorViewMode4, _api$connectivity5;
702
+ var _api$editorViewMode5, _api$connectivity6;
689
703
  // Lazy-init: when no synced block currently exists in the doc and the
690
704
  // transaction does not insert one, all downstream filter logic is a
691
705
  // no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
@@ -696,11 +710,11 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
696
710
  return true;
697
711
  }
698
712
  }
699
- var viewMode = api === null || api === void 0 || (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 || (_api$editorViewMode4 = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4 === void 0 ? void 0 : _api$editorViewMode4.mode;
713
+ var viewMode = api === null || api === void 0 || (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 || (_api$editorViewMode5 = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5 === void 0 ? void 0 : _api$editorViewMode5.mode;
700
714
  if (viewMode === 'view') {
701
715
  return true;
702
716
  }
703
- var isOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 || (_api$connectivity5 = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5 === void 0 ? void 0 : _api$connectivity5.mode);
717
+ var isOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity6 = api.connectivity) === null || _api$connectivity6 === void 0 || (_api$connectivity6 = _api$connectivity6.sharedState.currentState()) === null || _api$connectivity6 === void 0 ? void 0 : _api$connectivity6.mode);
704
718
  var isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
705
719
 
706
720
  // Track newly added reference sync blocks before processing the transaction
@@ -774,7 +788,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
774
788
  });
775
789
  },
776
790
  appendTransaction: function appendTransaction(trs, oldState, newState) {
777
- var _api$editorViewMode5;
791
+ var _api$editorViewMode6;
778
792
  // Lazy-init: when neither the previous nor the new state contains a
779
793
  // synced block (and none of the dispatched transactions inserts one),
780
794
  // skip all downstream work. This is the hot path on the ~99.97% of
@@ -787,7 +801,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
787
801
  return null;
788
802
  }
789
803
  }
790
- var viewMode = api === null || api === void 0 || (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 || (_api$editorViewMode5 = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5 === void 0 ? void 0 : _api$editorViewMode5.mode;
804
+ var viewMode = api === null || api === void 0 || (_api$editorViewMode6 = api.editorViewMode) === null || _api$editorViewMode6 === void 0 || (_api$editorViewMode6 = _api$editorViewMode6.sharedState.currentState()) === null || _api$editorViewMode6 === void 0 ? void 0 : _api$editorViewMode6.mode;
791
805
  if (viewMode === 'view') {
792
806
  return null;
793
807
  }
@@ -289,6 +289,9 @@ var handleButtonClick = function handleButtonClick(_ref2) {
289
289
  });
290
290
  }
291
291
  break;
292
+ case _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceOverflowTrigger:
293
+ case _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceOverflowTrigger:
294
+ break;
292
295
  default:
293
296
  {
294
297
  // Exhaustiveness check: if a new SyncedBlockToolbarButtonId is added
@@ -25,5 +25,7 @@ var SYNCED_BLOCK_BUTTON_TEST_ID = exports.SYNCED_BLOCK_BUTTON_TEST_ID = {
25
25
  syncedBlockToolbarSourceDelete: 'source-synced-block-delete-btn',
26
26
  syncedBlockToolbarReferenceUnsync: 'reference-synced-block-unsync-btn',
27
27
  syncedBlockToolbarSourceUnsync: 'source-synced-block-unsync-btn',
28
- syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger'
28
+ syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger',
29
+ syncedBlockToolbarReferenceOverflowTrigger: 'reference-synced-block-overflow-dropdown--trigger',
30
+ syncedBlockToolbarSourceOverflowTrigger: 'source-synced-block-overflow-dropdown--trigger'
29
31
  };
@@ -18,6 +18,7 @@ var _copy = _interopRequireDefault(require("@atlaskit/icon/core/copy"));
18
18
  var _delete = _interopRequireDefault(require("@atlaskit/icon/core/delete"));
19
19
  var _edit = _interopRequireDefault(require("@atlaskit/icon/core/edit"));
20
20
  var _linkBroken = _interopRequireDefault(require("@atlaskit/icon/core/link-broken"));
21
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
21
22
  var _editorCommands = require("../editor-commands");
22
23
  var _utils2 = require("../pm-plugins/utils/utils");
23
24
  var _types = require("../types");
@@ -132,6 +133,9 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(stat
132
133
  // testId is required to show focus on trigger button on ESC key press
133
134
  // see hideOnEsc in platform/packages/editor/editor-plugin-floating-toolbar/src/ui/Dropdown.tsx
134
135
  var testId = 'synced-block-overflow-dropdown-trigger';
136
+ if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_12')) {
137
+ testId = isBodiedSyncBlock ? _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceOverflowTrigger : _types.SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceOverflowTrigger;
138
+ }
135
139
  var overflowMenuConfig = [{
136
140
  type: 'overflow-dropdown',
137
141
  testId: testId,
@@ -378,7 +378,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
378
378
  };
379
379
  },
380
380
  apply: (tr, currentPluginState, oldEditorState) => {
381
- var _meta$activeFlag, _meta$bodiedSyncBlock;
381
+ var _api$userIntent2, _api$userIntent2$shar, _api$connectivity3, _api$connectivity3$sh, _api$editorViewMode2, _api$editorViewMode2$, _meta$activeFlag, _meta$bodiedSyncBlock;
382
382
  const meta = tr.getMeta(syncedBlockPluginKey);
383
383
  // isPerfExperimentOn is cached at createPlugin() level — see above
384
384
 
@@ -394,6 +394,29 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
394
394
  prevIsDragging: prevDragging
395
395
  } = currentPluginState;
396
396
 
397
+ // Pre-compute once so the fast-path probe and the bottom ref-equality
398
+ // short-circuit share the same source-manager snapshot. Track C will make this O(1).
399
+ const nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
400
+
401
+ // --- Fast path (EDITOR-6934 follow-up, see Confluence 7050540723 §9.3 / §9.9):
402
+ // when no plugin meta is set, and neither the document nor selection changed,
403
+ // most synced-block plugin state cannot change. The source manager is mutable
404
+ // outside ProseMirror transactions, though, so preserve existing empty-transaction
405
+ // sync semantics by checking that snapshot first.
406
+ //
407
+ // Note: selection-only transactions intentionally fall through to the normal
408
+ // apply path because calculateDecorations depends on drag/view-mode state
409
+ // that is not captured here.
410
+ //
411
+ // We also need to ensure shared-state signals (drag, offline, view-mode)
412
+ // haven't changed — these are propagated via empty transactions and drive
413
+ // status decoration rebuilds (e.g. drag border). Without this check the
414
+ // fast path would swallow drag-start transactions and the synced block
415
+ // border would never appear (see VR test: synced-block-drag-selection).
416
+ if (isPerfExperimentOn && !meta && !tr.docChanged && tr.selection.eq(oldEditorState.selection) && nextHasUnsavedBodiedSyncBlockChanges === currentPluginState.hasUnsavedBodiedSyncBlockChanges && (api === null || api === void 0 ? void 0 : (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : (_api$userIntent2$shar = _api$userIntent2.sharedState.currentState()) === null || _api$userIntent2$shar === void 0 ? void 0 : _api$userIntent2$shar.currentUserIntent) === 'dragging' === prevDragging && isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity3 = api.connectivity) === null || _api$connectivity3 === void 0 ? void 0 : (_api$connectivity3$sh = _api$connectivity3.sharedState.currentState()) === null || _api$connectivity3$sh === void 0 ? void 0 : _api$connectivity3$sh.mode) === prevOffline && (api === null || api === void 0 ? void 0 : (_api$editorViewMode2 = api.editorViewMode) === null || _api$editorViewMode2 === void 0 ? void 0 : (_api$editorViewMode2$ = _api$editorViewMode2.sharedState.currentState()) === null || _api$editorViewMode2$ === void 0 ? void 0 : _api$editorViewMode2$.mode) === 'view' === prevViewMode) {
417
+ return currentPluginState;
418
+ }
419
+
397
420
  // Lazy-init bookkeeping: once a synced block enters the document we
398
421
  // flip `hasSyncedBlocks` to `true` for the lifetime of this editor
399
422
  let nextHasSyncedBlocks = prevHasSyncedBlocks;
@@ -402,14 +425,6 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
402
425
  nextHasSyncedBlocks = true;
403
426
  }
404
427
  }
405
-
406
- // --- Fast path (EDITOR-6929): when `hasSyncedBlocks` is false,
407
- // no meta is set, and the selection/doc haven't changed in a way
408
- // that affects our state, return the SAME object reference so
409
- // SharedStateAPI skips notifying subscribers. ---
410
- if (!nextHasSyncedBlocks && !meta && !tr.docChanged && tr.selection.eq(oldEditorState.selection) && isPerfExperimentOn) {
411
- return currentPluginState;
412
- }
413
428
  let newDecorationSet = tr.docChanged ? selectionDecorationSet.map(tr.mapping, tr.doc) // only map if document changed
414
429
  : selectionDecorationSet;
415
430
  if (!tr.selection.eq(oldEditorState.selection)) {
@@ -438,11 +453,11 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
438
453
  // No synced blocks → keep empty status decorations
439
454
  nextStatusDecorationSet = DecorationSet.empty;
440
455
  } else {
441
- var _api$connectivity3, _api$connectivity3$sh, _api$editorViewMode2, _api$editorViewMode2$, _api$userIntent2, _api$userIntent2$shar;
456
+ var _api$connectivity4, _api$connectivity4$sh, _api$editorViewMode3, _api$editorViewMode3$, _api$userIntent3, _api$userIntent3$shar;
442
457
  // Read current shared-state signals
443
- nextIsOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity3 = api.connectivity) === null || _api$connectivity3 === void 0 ? void 0 : (_api$connectivity3$sh = _api$connectivity3.sharedState.currentState()) === null || _api$connectivity3$sh === void 0 ? void 0 : _api$connectivity3$sh.mode);
444
- nextIsViewMode = (api === null || api === void 0 ? void 0 : (_api$editorViewMode2 = api.editorViewMode) === null || _api$editorViewMode2 === void 0 ? void 0 : (_api$editorViewMode2$ = _api$editorViewMode2.sharedState.currentState()) === null || _api$editorViewMode2$ === void 0 ? void 0 : _api$editorViewMode2$.mode) === 'view';
445
- nextIsDragging = (api === null || api === void 0 ? void 0 : (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 ? void 0 : (_api$userIntent2$shar = _api$userIntent2.sharedState.currentState()) === null || _api$userIntent2$shar === void 0 ? void 0 : _api$userIntent2$shar.currentUserIntent) === 'dragging';
458
+ nextIsOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity4 = api.connectivity) === null || _api$connectivity4 === void 0 ? void 0 : (_api$connectivity4$sh = _api$connectivity4.sharedState.currentState()) === null || _api$connectivity4$sh === void 0 ? void 0 : _api$connectivity4$sh.mode);
459
+ nextIsViewMode = (api === null || api === void 0 ? void 0 : (_api$editorViewMode3 = api.editorViewMode) === null || _api$editorViewMode3 === void 0 ? void 0 : (_api$editorViewMode3$ = _api$editorViewMode3.sharedState.currentState()) === null || _api$editorViewMode3$ === void 0 ? void 0 : _api$editorViewMode3$.mode) === 'view';
460
+ nextIsDragging = (api === null || api === void 0 ? void 0 : (_api$userIntent3 = api.userIntent) === null || _api$userIntent3 === void 0 ? void 0 : (_api$userIntent3$shar = _api$userIntent3.sharedState.currentState()) === null || _api$userIntent3$shar === void 0 ? void 0 : _api$userIntent3$shar.currentUserIntent) === 'dragging';
446
461
 
447
462
  // Determine whether we need a full rebuild or a cheap map
448
463
  const hasSyncedBlocksJustFlipped = nextHasSyncedBlocks && !prevHasSyncedBlocks;
@@ -464,7 +479,6 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
464
479
  const newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping), isPerfExperimentOn);
465
480
  const nextActiveFlag = (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag;
466
481
  const nextBodiedSyncBlockDeletionStatus = (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus;
467
- const nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
468
482
 
469
483
  // --- Reference equality (EDITOR-6929): return the same object
470
484
  // when ALL fields are reference-equal to avoid SharedStateAPI
@@ -556,7 +570,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
556
570
  return hasFocus ? selectionDecorationSet.add(state.doc, statusDecorations) : statusDecorationSet;
557
571
  }
558
572
  } else {
559
- var _api$connectivity4, _api$connectivity4$sh, _api$editorViewMode3, _api$editorViewMode3$, _api$userIntent3, _api$userIntent3$shar, _api$focus2, _api$focus2$sharedSta, _api$focus2$sharedSta2;
573
+ var _api$connectivity5, _api$connectivity5$sh, _api$editorViewMode4, _api$editorViewMode4$, _api$userIntent4, _api$userIntent4$shar, _api$focus2, _api$focus2$sharedSta, _api$focus2$sharedSta2;
560
574
  // --- Legacy path (perf gate OFF) ---
561
575
  // Full `doc.descendants()` walk every transaction. Preserved
562
576
  // for safe rollback.
@@ -564,9 +578,9 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
564
578
  const {
565
579
  doc
566
580
  } = state;
567
- const isOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity4 = api.connectivity) === null || _api$connectivity4 === void 0 ? void 0 : (_api$connectivity4$sh = _api$connectivity4.sharedState.currentState()) === null || _api$connectivity4$sh === void 0 ? void 0 : _api$connectivity4$sh.mode);
568
- const isViewMode = (api === null || api === void 0 ? void 0 : (_api$editorViewMode3 = api.editorViewMode) === null || _api$editorViewMode3 === void 0 ? void 0 : (_api$editorViewMode3$ = _api$editorViewMode3.sharedState.currentState()) === null || _api$editorViewMode3$ === void 0 ? void 0 : _api$editorViewMode3$.mode) === 'view';
569
- const isDragging = (api === null || api === void 0 ? void 0 : (_api$userIntent3 = api.userIntent) === null || _api$userIntent3 === void 0 ? void 0 : (_api$userIntent3$shar = _api$userIntent3.sharedState.currentState()) === null || _api$userIntent3$shar === void 0 ? void 0 : _api$userIntent3$shar.currentUserIntent) === 'dragging';
581
+ const isOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 ? void 0 : (_api$connectivity5$sh = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5$sh === void 0 ? void 0 : _api$connectivity5$sh.mode);
582
+ const isViewMode = (api === null || api === void 0 ? void 0 : (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 ? void 0 : (_api$editorViewMode4$ = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4$ === void 0 ? void 0 : _api$editorViewMode4$.mode) === 'view';
583
+ const isDragging = (api === null || api === void 0 ? void 0 : (_api$userIntent4 = api.userIntent) === null || _api$userIntent4 === void 0 ? void 0 : (_api$userIntent4$shar = _api$userIntent4.sharedState.currentState()) === null || _api$userIntent4$shar === void 0 ? void 0 : _api$userIntent4$shar.currentUserIntent) === 'dragging';
570
584
  const offlineDecorations = [];
571
585
  const viewModeDecorations = [];
572
586
  const loadingDecorations = [];
@@ -657,7 +671,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
657
671
  }
658
672
  },
659
673
  filterTransaction: (tr, state) => {
660
- var _api$editorViewMode4, _api$editorViewMode4$, _api$connectivity5, _api$connectivity5$sh;
674
+ var _api$editorViewMode5, _api$editorViewMode5$, _api$connectivity6, _api$connectivity6$sh;
661
675
  // Lazy-init: when no synced block currently exists in the doc and the
662
676
  // transaction does not insert one, all downstream filter logic is a
663
677
  // no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
@@ -668,11 +682,11 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
668
682
  return true;
669
683
  }
670
684
  }
671
- const viewMode = api === null || api === void 0 ? void 0 : (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 ? void 0 : (_api$editorViewMode4$ = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4$ === void 0 ? void 0 : _api$editorViewMode4$.mode;
685
+ const viewMode = api === null || api === void 0 ? void 0 : (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 ? void 0 : (_api$editorViewMode5$ = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5$ === void 0 ? void 0 : _api$editorViewMode5$.mode;
672
686
  if (viewMode === 'view') {
673
687
  return true;
674
688
  }
675
- const isOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 ? void 0 : (_api$connectivity5$sh = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5$sh === void 0 ? void 0 : _api$connectivity5$sh.mode);
689
+ const isOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity6 = api.connectivity) === null || _api$connectivity6 === void 0 ? void 0 : (_api$connectivity6$sh = _api$connectivity6.sharedState.currentState()) === null || _api$connectivity6$sh === void 0 ? void 0 : _api$connectivity6$sh.mode);
676
690
  const isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
677
691
 
678
692
  // Track newly added reference sync blocks before processing the transaction
@@ -739,7 +753,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
739
753
  });
740
754
  },
741
755
  appendTransaction: (trs, oldState, newState) => {
742
- var _api$editorViewMode5, _api$editorViewMode5$;
756
+ var _api$editorViewMode6, _api$editorViewMode6$;
743
757
  // Lazy-init: when neither the previous nor the new state contains a
744
758
  // synced block (and none of the dispatched transactions inserts one),
745
759
  // skip all downstream work. This is the hot path on the ~99.97% of
@@ -752,7 +766,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
752
766
  return null;
753
767
  }
754
768
  }
755
- const viewMode = api === null || api === void 0 ? void 0 : (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 ? void 0 : (_api$editorViewMode5$ = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5$ === void 0 ? void 0 : _api$editorViewMode5$.mode;
769
+ const viewMode = api === null || api === void 0 ? void 0 : (_api$editorViewMode6 = api.editorViewMode) === null || _api$editorViewMode6 === void 0 ? void 0 : (_api$editorViewMode6$ = _api$editorViewMode6.sharedState.currentState()) === null || _api$editorViewMode6$ === void 0 ? void 0 : _api$editorViewMode6$.mode;
756
770
  if (viewMode === 'view') {
757
771
  return null;
758
772
  }
@@ -283,6 +283,9 @@ const handleButtonClick = ({
283
283
  });
284
284
  }
285
285
  break;
286
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceOverflowTrigger:
287
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceOverflowTrigger:
288
+ break;
286
289
  default:
287
290
  {
288
291
  // Exhaustiveness check: if a new SyncedBlockToolbarButtonId is added
@@ -19,5 +19,7 @@ export const SYNCED_BLOCK_BUTTON_TEST_ID = {
19
19
  syncedBlockToolbarSourceDelete: 'source-synced-block-delete-btn',
20
20
  syncedBlockToolbarReferenceUnsync: 'reference-synced-block-unsync-btn',
21
21
  syncedBlockToolbarSourceUnsync: 'source-synced-block-unsync-btn',
22
- syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger'
22
+ syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger',
23
+ syncedBlockToolbarReferenceOverflowTrigger: 'reference-synced-block-overflow-dropdown--trigger',
24
+ syncedBlockToolbarSourceOverflowTrigger: 'source-synced-block-overflow-dropdown--trigger'
23
25
  };
@@ -9,6 +9,7 @@ import CopyIcon from '@atlaskit/icon/core/copy';
9
9
  import DeleteIcon from '@atlaskit/icon/core/delete';
10
10
  import EditIcon from '@atlaskit/icon/core/edit';
11
11
  import LinkBrokenIcon from '@atlaskit/icon/core/link-broken';
12
+ import { fg } from '@atlaskit/platform-feature-flags';
12
13
  import { copySyncedBlockReferenceToClipboard, editSyncedBlockSource, removeSyncedBlock, unsync } from '../editor-commands';
13
14
  import { findSyncBlockOrBodiedSyncBlock, isBodiedSyncBlockNode } from '../pm-plugins/utils/utils';
14
15
  import { SYNCED_BLOCK_BUTTON_TEST_ID } from '../types';
@@ -127,7 +128,10 @@ export const getToolbarConfig = (state, intl, api, syncBlockStore) => {
127
128
 
128
129
  // testId is required to show focus on trigger button on ESC key press
129
130
  // see hideOnEsc in platform/packages/editor/editor-plugin-floating-toolbar/src/ui/Dropdown.tsx
130
- const testId = 'synced-block-overflow-dropdown-trigger';
131
+ let testId = 'synced-block-overflow-dropdown-trigger';
132
+ if (fg('platform_synced_block_patch_12')) {
133
+ testId = isBodiedSyncBlock ? SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceOverflowTrigger : SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceOverflowTrigger;
134
+ }
131
135
  const overflowMenuConfig = [{
132
136
  type: 'overflow-dropdown',
133
137
  testId,
@@ -404,7 +404,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
404
404
  };
405
405
  },
406
406
  apply: function apply(tr, currentPluginState, oldEditorState) {
407
- var _meta$activeFlag, _meta$bodiedSyncBlock;
407
+ var _api$userIntent2, _api$connectivity3, _api$editorViewMode2, _meta$activeFlag, _meta$bodiedSyncBlock;
408
408
  var meta = tr.getMeta(syncedBlockPluginKey);
409
409
  // isPerfExperimentOn is cached at createPlugin() level — see above
410
410
 
@@ -418,6 +418,29 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
418
418
  prevViewMode = currentPluginState.prevIsViewMode,
419
419
  prevDragging = currentPluginState.prevIsDragging;
420
420
 
421
+ // Pre-compute once so the fast-path probe and the bottom ref-equality
422
+ // short-circuit share the same source-manager snapshot. Track C will make this O(1).
423
+ var nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
424
+
425
+ // --- Fast path (EDITOR-6934 follow-up, see Confluence 7050540723 §9.3 / §9.9):
426
+ // when no plugin meta is set, and neither the document nor selection changed,
427
+ // most synced-block plugin state cannot change. The source manager is mutable
428
+ // outside ProseMirror transactions, though, so preserve existing empty-transaction
429
+ // sync semantics by checking that snapshot first.
430
+ //
431
+ // Note: selection-only transactions intentionally fall through to the normal
432
+ // apply path because calculateDecorations depends on drag/view-mode state
433
+ // that is not captured here.
434
+ //
435
+ // We also need to ensure shared-state signals (drag, offline, view-mode)
436
+ // haven't changed — these are propagated via empty transactions and drive
437
+ // status decoration rebuilds (e.g. drag border). Without this check the
438
+ // fast path would swallow drag-start transactions and the synced block
439
+ // border would never appear (see VR test: synced-block-drag-selection).
440
+ if (isPerfExperimentOn && !meta && !tr.docChanged && tr.selection.eq(oldEditorState.selection) && nextHasUnsavedBodiedSyncBlockChanges === currentPluginState.hasUnsavedBodiedSyncBlockChanges && (api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || (_api$userIntent2 = _api$userIntent2.sharedState.currentState()) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.currentUserIntent) === 'dragging' === prevDragging && isOfflineMode(api === null || api === void 0 || (_api$connectivity3 = api.connectivity) === null || _api$connectivity3 === void 0 || (_api$connectivity3 = _api$connectivity3.sharedState.currentState()) === null || _api$connectivity3 === void 0 ? void 0 : _api$connectivity3.mode) === prevOffline && (api === null || api === void 0 || (_api$editorViewMode2 = api.editorViewMode) === null || _api$editorViewMode2 === void 0 || (_api$editorViewMode2 = _api$editorViewMode2.sharedState.currentState()) === null || _api$editorViewMode2 === void 0 ? void 0 : _api$editorViewMode2.mode) === 'view' === prevViewMode) {
441
+ return currentPluginState;
442
+ }
443
+
421
444
  // Lazy-init bookkeeping: once a synced block enters the document we
422
445
  // flip `hasSyncedBlocks` to `true` for the lifetime of this editor
423
446
  var nextHasSyncedBlocks = prevHasSyncedBlocks;
@@ -426,14 +449,6 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
426
449
  nextHasSyncedBlocks = true;
427
450
  }
428
451
  }
429
-
430
- // --- Fast path (EDITOR-6929): when `hasSyncedBlocks` is false,
431
- // no meta is set, and the selection/doc haven't changed in a way
432
- // that affects our state, return the SAME object reference so
433
- // SharedStateAPI skips notifying subscribers. ---
434
- if (!nextHasSyncedBlocks && !meta && !tr.docChanged && tr.selection.eq(oldEditorState.selection) && isPerfExperimentOn) {
435
- return currentPluginState;
436
- }
437
452
  var newDecorationSet = tr.docChanged ? selectionDecorationSet.map(tr.mapping, tr.doc) // only map if document changed
438
453
  : selectionDecorationSet;
439
454
  if (!tr.selection.eq(oldEditorState.selection)) {
@@ -462,11 +477,11 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
462
477
  // No synced blocks → keep empty status decorations
463
478
  nextStatusDecorationSet = DecorationSet.empty;
464
479
  } else {
465
- var _api$connectivity3, _api$editorViewMode2, _api$userIntent2;
480
+ var _api$connectivity4, _api$editorViewMode3, _api$userIntent3;
466
481
  // Read current shared-state signals
467
- nextIsOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity3 = api.connectivity) === null || _api$connectivity3 === void 0 || (_api$connectivity3 = _api$connectivity3.sharedState.currentState()) === null || _api$connectivity3 === void 0 ? void 0 : _api$connectivity3.mode);
468
- nextIsViewMode = (api === null || api === void 0 || (_api$editorViewMode2 = api.editorViewMode) === null || _api$editorViewMode2 === void 0 || (_api$editorViewMode2 = _api$editorViewMode2.sharedState.currentState()) === null || _api$editorViewMode2 === void 0 ? void 0 : _api$editorViewMode2.mode) === 'view';
469
- nextIsDragging = (api === null || api === void 0 || (_api$userIntent2 = api.userIntent) === null || _api$userIntent2 === void 0 || (_api$userIntent2 = _api$userIntent2.sharedState.currentState()) === null || _api$userIntent2 === void 0 ? void 0 : _api$userIntent2.currentUserIntent) === 'dragging';
482
+ nextIsOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity4 = api.connectivity) === null || _api$connectivity4 === void 0 || (_api$connectivity4 = _api$connectivity4.sharedState.currentState()) === null || _api$connectivity4 === void 0 ? void 0 : _api$connectivity4.mode);
483
+ nextIsViewMode = (api === null || api === void 0 || (_api$editorViewMode3 = api.editorViewMode) === null || _api$editorViewMode3 === void 0 || (_api$editorViewMode3 = _api$editorViewMode3.sharedState.currentState()) === null || _api$editorViewMode3 === void 0 ? void 0 : _api$editorViewMode3.mode) === 'view';
484
+ nextIsDragging = (api === null || api === void 0 || (_api$userIntent3 = api.userIntent) === null || _api$userIntent3 === void 0 || (_api$userIntent3 = _api$userIntent3.sharedState.currentState()) === null || _api$userIntent3 === void 0 ? void 0 : _api$userIntent3.currentUserIntent) === 'dragging';
470
485
 
471
486
  // Determine whether we need a full rebuild or a cheap map
472
487
  var hasSyncedBlocksJustFlipped = nextHasSyncedBlocks && !prevHasSyncedBlocks;
@@ -488,7 +503,6 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
488
503
  var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping), isPerfExperimentOn);
489
504
  var nextActiveFlag = (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag;
490
505
  var nextBodiedSyncBlockDeletionStatus = (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus;
491
- var nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
492
506
 
493
507
  // --- Reference equality (EDITOR-6929): return the same object
494
508
  // when ALL fields are reference-equal to avoid SharedStateAPI
@@ -581,15 +595,15 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
581
595
  return hasFocus ? selectionDecorationSet.add(state.doc, statusDecorations) : statusDecorationSet;
582
596
  }
583
597
  } else {
584
- var _api$connectivity4, _api$editorViewMode3, _api$userIntent3, _api$focus2;
598
+ var _api$connectivity5, _api$editorViewMode4, _api$userIntent4, _api$focus2;
585
599
  // --- Legacy path (perf gate OFF) ---
586
600
  // Full `doc.descendants()` walk every transaction. Preserved
587
601
  // for safe rollback.
588
602
  var _syncBlockStore = currentPluginState.syncBlockStore;
589
603
  var doc = state.doc;
590
- var isOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity4 = api.connectivity) === null || _api$connectivity4 === void 0 || (_api$connectivity4 = _api$connectivity4.sharedState.currentState()) === null || _api$connectivity4 === void 0 ? void 0 : _api$connectivity4.mode);
591
- var isViewMode = (api === null || api === void 0 || (_api$editorViewMode3 = api.editorViewMode) === null || _api$editorViewMode3 === void 0 || (_api$editorViewMode3 = _api$editorViewMode3.sharedState.currentState()) === null || _api$editorViewMode3 === void 0 ? void 0 : _api$editorViewMode3.mode) === 'view';
592
- var isDragging = (api === null || api === void 0 || (_api$userIntent3 = api.userIntent) === null || _api$userIntent3 === void 0 || (_api$userIntent3 = _api$userIntent3.sharedState.currentState()) === null || _api$userIntent3 === void 0 ? void 0 : _api$userIntent3.currentUserIntent) === 'dragging';
604
+ var isOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 || (_api$connectivity5 = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5 === void 0 ? void 0 : _api$connectivity5.mode);
605
+ var isViewMode = (api === null || api === void 0 || (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 || (_api$editorViewMode4 = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4 === void 0 ? void 0 : _api$editorViewMode4.mode) === 'view';
606
+ var isDragging = (api === null || api === void 0 || (_api$userIntent4 = api.userIntent) === null || _api$userIntent4 === void 0 || (_api$userIntent4 = _api$userIntent4.sharedState.currentState()) === null || _api$userIntent4 === void 0 ? void 0 : _api$userIntent4.currentUserIntent) === 'dragging';
593
607
  var offlineDecorations = [];
594
608
  var viewModeDecorations = [];
595
609
  var loadingDecorations = [];
@@ -678,7 +692,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
678
692
  }
679
693
  },
680
694
  filterTransaction: function filterTransaction(tr, state) {
681
- var _api$editorViewMode4, _api$connectivity5;
695
+ var _api$editorViewMode5, _api$connectivity6;
682
696
  // Lazy-init: when no synced block currently exists in the doc and the
683
697
  // transaction does not insert one, all downstream filter logic is a
684
698
  // no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
@@ -689,11 +703,11 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
689
703
  return true;
690
704
  }
691
705
  }
692
- var viewMode = api === null || api === void 0 || (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 || (_api$editorViewMode4 = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4 === void 0 ? void 0 : _api$editorViewMode4.mode;
706
+ var viewMode = api === null || api === void 0 || (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 || (_api$editorViewMode5 = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5 === void 0 ? void 0 : _api$editorViewMode5.mode;
693
707
  if (viewMode === 'view') {
694
708
  return true;
695
709
  }
696
- var isOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 || (_api$connectivity5 = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5 === void 0 ? void 0 : _api$connectivity5.mode);
710
+ var isOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity6 = api.connectivity) === null || _api$connectivity6 === void 0 || (_api$connectivity6 = _api$connectivity6.sharedState.currentState()) === null || _api$connectivity6 === void 0 ? void 0 : _api$connectivity6.mode);
697
711
  var isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
698
712
 
699
713
  // Track newly added reference sync blocks before processing the transaction
@@ -767,7 +781,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
767
781
  });
768
782
  },
769
783
  appendTransaction: function appendTransaction(trs, oldState, newState) {
770
- var _api$editorViewMode5;
784
+ var _api$editorViewMode6;
771
785
  // Lazy-init: when neither the previous nor the new state contains a
772
786
  // synced block (and none of the dispatched transactions inserts one),
773
787
  // skip all downstream work. This is the hot path on the ~99.97% of
@@ -780,7 +794,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
780
794
  return null;
781
795
  }
782
796
  }
783
- var viewMode = api === null || api === void 0 || (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 || (_api$editorViewMode5 = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5 === void 0 ? void 0 : _api$editorViewMode5.mode;
797
+ var viewMode = api === null || api === void 0 || (_api$editorViewMode6 = api.editorViewMode) === null || _api$editorViewMode6 === void 0 || (_api$editorViewMode6 = _api$editorViewMode6.sharedState.currentState()) === null || _api$editorViewMode6 === void 0 ? void 0 : _api$editorViewMode6.mode;
784
798
  if (viewMode === 'view') {
785
799
  return null;
786
800
  }
@@ -282,6 +282,9 @@ var handleButtonClick = function handleButtonClick(_ref2) {
282
282
  });
283
283
  }
284
284
  break;
285
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceOverflowTrigger:
286
+ case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceOverflowTrigger:
287
+ break;
285
288
  default:
286
289
  {
287
290
  // Exhaustiveness check: if a new SyncedBlockToolbarButtonId is added
@@ -19,5 +19,7 @@ export var SYNCED_BLOCK_BUTTON_TEST_ID = {
19
19
  syncedBlockToolbarSourceDelete: 'source-synced-block-delete-btn',
20
20
  syncedBlockToolbarReferenceUnsync: 'reference-synced-block-unsync-btn',
21
21
  syncedBlockToolbarSourceUnsync: 'source-synced-block-unsync-btn',
22
- syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger'
22
+ syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger',
23
+ syncedBlockToolbarReferenceOverflowTrigger: 'reference-synced-block-overflow-dropdown--trigger',
24
+ syncedBlockToolbarSourceOverflowTrigger: 'source-synced-block-overflow-dropdown--trigger'
23
25
  };
@@ -12,6 +12,7 @@ import CopyIcon from '@atlaskit/icon/core/copy';
12
12
  import DeleteIcon from '@atlaskit/icon/core/delete';
13
13
  import EditIcon from '@atlaskit/icon/core/edit';
14
14
  import LinkBrokenIcon from '@atlaskit/icon/core/link-broken';
15
+ import { fg } from '@atlaskit/platform-feature-flags';
15
16
  import { copySyncedBlockReferenceToClipboard, editSyncedBlockSource, removeSyncedBlock, unsync } from '../editor-commands';
16
17
  import { findSyncBlockOrBodiedSyncBlock, isBodiedSyncBlockNode } from '../pm-plugins/utils/utils';
17
18
  import { SYNCED_BLOCK_BUTTON_TEST_ID } from '../types';
@@ -123,6 +124,9 @@ export var getToolbarConfig = function getToolbarConfig(state, intl, api, syncBl
123
124
  // testId is required to show focus on trigger button on ESC key press
124
125
  // see hideOnEsc in platform/packages/editor/editor-plugin-floating-toolbar/src/ui/Dropdown.tsx
125
126
  var testId = 'synced-block-overflow-dropdown-trigger';
127
+ if (fg('platform_synced_block_patch_12')) {
128
+ testId = isBodiedSyncBlock ? SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceOverflowTrigger : SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceOverflowTrigger;
129
+ }
126
130
  var overflowMenuConfig = [{
127
131
  type: 'overflow-dropdown',
128
132
  testId: testId,
@@ -88,5 +88,7 @@ export declare const SYNCED_BLOCK_BUTTON_TEST_ID: {
88
88
  readonly syncedBlockToolbarReferenceUnsync: "reference-synced-block-unsync-btn";
89
89
  readonly syncedBlockToolbarSourceUnsync: "source-synced-block-unsync-btn";
90
90
  readonly syncedBlockToolbarSyncedLocationsTrigger: "synced-block-synced-locations-dropdown--trigger";
91
+ readonly syncedBlockToolbarReferenceOverflowTrigger: "reference-synced-block-overflow-dropdown--trigger";
92
+ readonly syncedBlockToolbarSourceOverflowTrigger: "source-synced-block-overflow-dropdown--trigger";
91
93
  };
92
94
  export {};
@@ -88,5 +88,7 @@ export declare const SYNCED_BLOCK_BUTTON_TEST_ID: {
88
88
  readonly syncedBlockToolbarReferenceUnsync: "reference-synced-block-unsync-btn";
89
89
  readonly syncedBlockToolbarSourceUnsync: "source-synced-block-unsync-btn";
90
90
  readonly syncedBlockToolbarSyncedLocationsTrigger: "synced-block-synced-locations-dropdown--trigger";
91
+ readonly syncedBlockToolbarReferenceOverflowTrigger: "reference-synced-block-overflow-dropdown--trigger";
92
+ readonly syncedBlockToolbarSourceOverflowTrigger: "source-synced-block-overflow-dropdown--trigger";
91
93
  };
92
94
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-synced-block",
3
- "version": "8.3.10",
3
+ "version": "8.3.12",
4
4
  "description": "SyncedBlock plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -54,7 +54,7 @@
54
54
  "@atlaskit/platform-feature-flags": "^1.1.0",
55
55
  "@atlaskit/primitives": "^19.0.0",
56
56
  "@atlaskit/spinner": "19.1.2",
57
- "@atlaskit/tmp-editor-statsig": "^81.1.0",
57
+ "@atlaskit/tmp-editor-statsig": "^81.3.0",
58
58
  "@atlaskit/tokens": "13.0.4",
59
59
  "@atlaskit/tooltip": "^22.2.0",
60
60
  "@atlaskit/visually-hidden": "^3.1.0",
@@ -64,7 +64,7 @@
64
64
  "date-fns": "^2.17.0"
65
65
  },
66
66
  "peerDependencies": {
67
- "@atlaskit/editor-common": "^114.35.0",
67
+ "@atlaskit/editor-common": "^114.36.0",
68
68
  "react": "^18.2.0",
69
69
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
70
70
  },