@atlaskit/editor-plugin-synced-block 8.3.9 → 8.3.11
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 +15 -0
- package/dist/cjs/pm-plugins/main.js +37 -23
- package/dist/es2019/pm-plugins/main.js +37 -23
- package/dist/esm/pm-plugins/main.js +37 -23
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 8.3.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`2cef675d24c75`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2cef675d24c75) -
|
|
8
|
+
Performance: short-circuit synced block plugin state updates for no-op editor transactions when
|
|
9
|
+
the perf experiment is enabled.
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 8.3.10
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
|
|
3
18
|
## 8.3.9
|
|
4
19
|
|
|
5
20
|
### 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$
|
|
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$
|
|
475
|
-
nextIsViewMode = (api === null || api === void 0 || (_api$
|
|
476
|
-
nextIsDragging = (api === null || api === void 0 || (_api$
|
|
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$
|
|
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$
|
|
598
|
-
var isViewMode = (api === null || api === void 0 || (_api$
|
|
599
|
-
var isDragging = (api === null || api === void 0 || (_api$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
}
|
|
@@ -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$
|
|
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$
|
|
444
|
-
nextIsViewMode = (api === null || api === void 0 ? void 0 : (_api$
|
|
445
|
-
nextIsDragging = (api === null || api === void 0 ? void 0 : (_api$
|
|
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$
|
|
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$
|
|
568
|
-
const isViewMode = (api === null || api === void 0 ? void 0 : (_api$
|
|
569
|
-
const isDragging = (api === null || api === void 0 ? void 0 : (_api$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
}
|
|
@@ -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$
|
|
480
|
+
var _api$connectivity4, _api$editorViewMode3, _api$userIntent3;
|
|
466
481
|
// Read current shared-state signals
|
|
467
|
-
nextIsOffline = isOfflineMode(api === null || api === void 0 || (_api$
|
|
468
|
-
nextIsViewMode = (api === null || api === void 0 || (_api$
|
|
469
|
-
nextIsDragging = (api === null || api === void 0 || (_api$
|
|
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$
|
|
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$
|
|
591
|
-
var isViewMode = (api === null || api === void 0 || (_api$
|
|
592
|
-
var isDragging = (api === null || api === void 0 || (_api$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-synced-block",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.11",
|
|
4
4
|
"description": "SyncedBlock plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"atlaskit:src": "src/index.ts",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@atlaskit/adf-schema": "^52.
|
|
31
|
+
"@atlaskit/adf-schema": "^52.12.0",
|
|
32
32
|
"@atlaskit/button": "23.11.6",
|
|
33
|
-
"@atlaskit/dropdown-menu": "16.
|
|
33
|
+
"@atlaskit/dropdown-menu": "16.9.0",
|
|
34
34
|
"@atlaskit/editor-json-transformer": "^8.32.0",
|
|
35
35
|
"@atlaskit/editor-plugin-analytics": "^10.1.0",
|
|
36
36
|
"@atlaskit/editor-plugin-block-menu": "^9.2.0",
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"@atlaskit/editor-prosemirror": "^7.3.0",
|
|
45
45
|
"@atlaskit/editor-shared-styles": "^3.11.0",
|
|
46
46
|
"@atlaskit/editor-synced-block-provider": "^6.6.0",
|
|
47
|
-
"@atlaskit/editor-toolbar": "^1.
|
|
47
|
+
"@atlaskit/editor-toolbar": "^1.6.0",
|
|
48
48
|
"@atlaskit/flag": "^17.11.0",
|
|
49
49
|
"@atlaskit/icon": "35.0.0",
|
|
50
50
|
"@atlaskit/icon-lab": "^6.9.0",
|
|
51
51
|
"@atlaskit/logo": "^20.1.0",
|
|
52
52
|
"@atlaskit/lozenge": "^13.8.0",
|
|
53
|
-
"@atlaskit/modal-dialog": "^15.
|
|
53
|
+
"@atlaskit/modal-dialog": "^15.1.0",
|
|
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.
|
|
57
|
+
"@atlaskit/tmp-editor-statsig": "^81.2.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.
|
|
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
|
},
|