@atlaskit/editor-plugin-synced-block 8.2.7 → 8.2.9
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/afm-cc/tsconfig.json +0 -1
- package/afm-products/tsconfig.json +0 -1
- package/dist/cjs/pm-plugins/main.js +179 -56
- package/dist/es2019/pm-plugins/main.js +182 -57
- package/dist/esm/pm-plugins/main.js +179 -56
- package/dist/types/pm-plugins/main.d.ts +17 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +17 -0
- package/package.json +4 -4
- package/afm-jira/tsconfig.json +0 -120
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 8.2.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 8.2.8
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`27f53bba7e425`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/27f53bba7e425) -
|
|
14
|
+
EDITOR-6930: Refactor decorations prop to map status decorations in apply() instead of rebuilding
|
|
15
|
+
via doc.descendants() every transaction. Behind editor_synced_block_perf experiment.
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
|
|
3
18
|
## 8.2.7
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/afm-cc/tsconfig.json
CHANGED
|
@@ -99,9 +99,7 @@ var showExtensionInSyncBlockWarningIfNeeded = function showExtensionInSyncBlockW
|
|
|
99
99
|
var tr = _ref2.tr;
|
|
100
100
|
return tr.setMeta(syncedBlockPluginKey, {
|
|
101
101
|
activeFlag: {
|
|
102
|
-
id:
|
|
103
|
-
exposure: true
|
|
104
|
-
}) ? _types.FLAG_ID.EXTENSION_IN_SYNC_BLOCK : _types.FLAG_ID.INLINE_EXTENSION_IN_SYNC_BLOCK
|
|
102
|
+
id: _types.FLAG_ID.EXTENSION_IN_SYNC_BLOCK
|
|
105
103
|
}
|
|
106
104
|
});
|
|
107
105
|
});
|
|
@@ -206,6 +204,48 @@ var filterTransactionOffline = function filterTransactionOffline(_ref4) {
|
|
|
206
204
|
return true;
|
|
207
205
|
};
|
|
208
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Build the status decoration set for sync-block nodes. This performs a full
|
|
209
|
+
* `doc.descendants()` walk so it must only be called when a status signal
|
|
210
|
+
* actually changes (offline, view-mode, dragging, pending-creation). Between
|
|
211
|
+
* status changes the caller should use `decorationSet.map(tr.mapping, tr.doc)`
|
|
212
|
+
* instead (see EDITOR-6930).
|
|
213
|
+
*/
|
|
214
|
+
var buildStatusDecorations = function buildStatusDecorations(doc, syncBlockStore, isOffline, isViewMode, isDragging) {
|
|
215
|
+
// Fast path: when all status flags are off and no creations are in flight,
|
|
216
|
+
// no node can produce a decoration — skip the full doc traversal.
|
|
217
|
+
if (!isOffline && !isViewMode && !isDragging && !syncBlockStore.sourceManager.hasPendingCreations()) {
|
|
218
|
+
return _view.DecorationSet.empty;
|
|
219
|
+
}
|
|
220
|
+
var offlineDecorations = [];
|
|
221
|
+
var viewModeDecorations = [];
|
|
222
|
+
var loadingDecorations = [];
|
|
223
|
+
var dragDecorations = [];
|
|
224
|
+
doc.descendants(function (node, pos) {
|
|
225
|
+
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
226
|
+
offlineDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
227
|
+
class: _syncBlock.SyncBlockStateCssClassName.disabledClassName
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
if (syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
231
|
+
viewModeDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
232
|
+
class: _syncBlock.SyncBlockStateCssClassName.viewModeClassName
|
|
233
|
+
}));
|
|
234
|
+
}
|
|
235
|
+
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
236
|
+
loadingDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
237
|
+
class: _syncBlock.SyncBlockStateCssClassName.creationLoadingClassName
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
if (isDragging && syncBlockStore.isSyncBlock(node)) {
|
|
241
|
+
dragDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
242
|
+
class: _syncBlock.SyncBlockStateCssClassName.draggingClassName
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
return _view.DecorationSet.create(doc, [].concat(offlineDecorations, viewModeDecorations, loadingDecorations, dragDecorations));
|
|
247
|
+
};
|
|
248
|
+
|
|
209
249
|
/**
|
|
210
250
|
* Encapsulates mutable state that persists across transactions in the
|
|
211
251
|
* synced block plugin. Replaces module-level closure variables so state
|
|
@@ -282,6 +322,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
282
322
|
key: syncedBlockPluginKey,
|
|
283
323
|
state: {
|
|
284
324
|
init: function init(_, instance) {
|
|
325
|
+
var _api$connectivity2, _api$editorViewMode, _api$userIntent;
|
|
285
326
|
// When `editor_synced_block_perf` is ON and the document has no
|
|
286
327
|
// synced blocks, we skip the eager fetch + cache walks. They will be
|
|
287
328
|
// re-run lazily by `apply` the first time a synced block enters the
|
|
@@ -306,13 +347,28 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
306
347
|
}
|
|
307
348
|
}
|
|
308
349
|
}
|
|
350
|
+
|
|
351
|
+
// Read initial shared-state signals for status decorations
|
|
352
|
+
var initIsOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity2 = api.connectivity) === null || _api$connectivity2 === void 0 || (_api$connectivity2 = _api$connectivity2.sharedState.currentState()) === null || _api$connectivity2 === void 0 ? void 0 : _api$connectivity2.mode);
|
|
353
|
+
var initIsViewMode = (api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode) === 'view';
|
|
354
|
+
var initIsDragging = (api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || (_api$userIntent = _api$userIntent.sharedState.currentState()) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.currentUserIntent) === 'dragging';
|
|
355
|
+
|
|
356
|
+
// Build initial status decoration set (EDITOR-6930).
|
|
357
|
+
// When the perf gate is ON and the doc has synced blocks we do a
|
|
358
|
+
// single traversal here; afterwards `apply()` will map or rebuild
|
|
359
|
+
// only when a status signal changes.
|
|
360
|
+
var initStatusDecorationSet = (0, _expValEquals.expValEquals)('editor_synced_block_perf', 'isEnabled', true) && docHasSyncedBlocks ? buildStatusDecorations(instance.doc, syncBlockStore, initIsOffline, initIsViewMode, initIsDragging) : _view.DecorationSet.empty;
|
|
309
361
|
return {
|
|
310
362
|
selectionDecorationSet: (0, _selectionDecorations.calculateDecorations)(instance.doc, instance.selection, instance.schema),
|
|
311
363
|
activeFlag: false,
|
|
312
364
|
syncBlockStore: syncBlockStore,
|
|
313
365
|
retryCreationPosMap: new Map(),
|
|
314
366
|
hasSyncedBlocks: docHasSyncedBlocks,
|
|
315
|
-
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges()
|
|
367
|
+
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges(),
|
|
368
|
+
statusDecorationSet: initStatusDecorationSet,
|
|
369
|
+
prevIsOffline: initIsOffline,
|
|
370
|
+
prevIsViewMode: initIsViewMode,
|
|
371
|
+
prevIsDragging: initIsDragging
|
|
316
372
|
};
|
|
317
373
|
},
|
|
318
374
|
apply: function apply(tr, currentPluginState, oldEditorState) {
|
|
@@ -322,7 +378,11 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
322
378
|
selectionDecorationSet = currentPluginState.selectionDecorationSet,
|
|
323
379
|
bodiedSyncBlockDeletionStatus = currentPluginState.bodiedSyncBlockDeletionStatus,
|
|
324
380
|
retryCreationPosMap = currentPluginState.retryCreationPosMap,
|
|
325
|
-
prevHasSyncedBlocks = currentPluginState.hasSyncedBlocks
|
|
381
|
+
prevHasSyncedBlocks = currentPluginState.hasSyncedBlocks,
|
|
382
|
+
prevStatusDecorationSet = currentPluginState.statusDecorationSet,
|
|
383
|
+
prevOffline = currentPluginState.prevIsOffline,
|
|
384
|
+
prevViewMode = currentPluginState.prevIsViewMode,
|
|
385
|
+
prevDragging = currentPluginState.prevIsDragging;
|
|
326
386
|
|
|
327
387
|
// Lazy-init bookkeeping: once a synced block enters the document we
|
|
328
388
|
// flip `hasSyncedBlocks` to `true` for the lifetime of this editor
|
|
@@ -347,6 +407,41 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
347
407
|
newDecorationSet = (0, _selectionDecorations.calculateDecorations)(tr.doc, tr.selection, tr.doc.type.schema);
|
|
348
408
|
}
|
|
349
409
|
}
|
|
410
|
+
|
|
411
|
+
// --- Status decoration set (EDITOR-6930) ---
|
|
412
|
+
// When the perf gate is ON we maintain `statusDecorationSet` in
|
|
413
|
+
// plugin state so the `decorations` prop becomes an O(1) lookup.
|
|
414
|
+
var nextStatusDecorationSet = prevStatusDecorationSet;
|
|
415
|
+
var nextIsOffline = prevOffline;
|
|
416
|
+
var nextIsViewMode = prevViewMode;
|
|
417
|
+
var nextIsDragging = prevDragging;
|
|
418
|
+
if ((0, _expValEquals.expValEquals)('editor_synced_block_perf', 'isEnabled', true)) {
|
|
419
|
+
if (!nextHasSyncedBlocks) {
|
|
420
|
+
// No synced blocks → keep empty status decorations
|
|
421
|
+
nextStatusDecorationSet = _view.DecorationSet.empty;
|
|
422
|
+
} else {
|
|
423
|
+
var _api$connectivity3, _api$editorViewMode2, _api$userIntent2;
|
|
424
|
+
// Read current shared-state signals
|
|
425
|
+
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);
|
|
426
|
+
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';
|
|
427
|
+
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';
|
|
428
|
+
|
|
429
|
+
// Determine whether we need a full rebuild or a cheap map
|
|
430
|
+
var hasSyncedBlocksJustFlipped = nextHasSyncedBlocks && !prevHasSyncedBlocks;
|
|
431
|
+
var statusSignalChanged = nextIsOffline !== prevOffline || nextIsViewMode !== prevViewMode || nextIsDragging !== prevDragging;
|
|
432
|
+
// Meta-driven status changes (e.g. pending creation
|
|
433
|
+
// completed, retry creation pos updated)
|
|
434
|
+
var hasMetaStatusChange = !!(meta !== null && meta !== void 0 && meta.retryCreationPos) || !!(meta !== null && meta !== void 0 && meta.activeFlag);
|
|
435
|
+
if (hasSyncedBlocksJustFlipped || statusSignalChanged || hasMetaStatusChange) {
|
|
436
|
+
// Full rebuild — a status signal changed
|
|
437
|
+
nextStatusDecorationSet = buildStatusDecorations(tr.doc, syncBlockStore, nextIsOffline, nextIsViewMode, nextIsDragging);
|
|
438
|
+
} else if (tr.docChanged) {
|
|
439
|
+
// Cheap map — positions shifted but status unchanged
|
|
440
|
+
nextStatusDecorationSet = prevStatusDecorationSet.map(tr.mapping, tr.doc);
|
|
441
|
+
}
|
|
442
|
+
// else: nothing changed, keep same reference
|
|
443
|
+
}
|
|
444
|
+
}
|
|
350
445
|
var newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
|
|
351
446
|
var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
|
|
352
447
|
return {
|
|
@@ -356,7 +451,11 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
356
451
|
retryCreationPosMap: newRetryCreationPosMap,
|
|
357
452
|
hasSyncedBlocks: nextHasSyncedBlocks,
|
|
358
453
|
bodiedSyncBlockDeletionStatus: (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus,
|
|
359
|
-
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges()
|
|
454
|
+
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges(),
|
|
455
|
+
statusDecorationSet: nextStatusDecorationSet,
|
|
456
|
+
prevIsOffline: nextIsOffline,
|
|
457
|
+
prevIsViewMode: nextIsViewMode,
|
|
458
|
+
prevIsDragging: nextIsDragging
|
|
360
459
|
};
|
|
361
460
|
}
|
|
362
461
|
},
|
|
@@ -395,57 +494,81 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
395
494
|
})
|
|
396
495
|
},
|
|
397
496
|
decorations: function decorations(state) {
|
|
398
|
-
var _currentPluginState$s, _api$connectivity2, _api$editorViewMode, _api$userIntent, _api$focus;
|
|
399
497
|
var currentPluginState = syncedBlockPluginKey.getState(state);
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
var doc = state.doc;
|
|
403
|
-
|
|
404
|
-
// Lazy-init: when no synced block exists in the doc, skip the
|
|
405
|
-
// `descendants` walk and the 4 shared-state reads below. The
|
|
406
|
-
// selection decoration set is the only thing that can be
|
|
407
|
-
// non-empty in this state.
|
|
408
|
-
if (currentPluginState && !currentPluginState.hasSyncedBlocks && (0, _expValEquals.expValEquals)('editor_synced_block_perf', 'isEnabled', true)) {
|
|
409
|
-
return selectionDecorationSet;
|
|
498
|
+
if (!currentPluginState) {
|
|
499
|
+
return _view.DecorationSet.empty;
|
|
410
500
|
}
|
|
411
|
-
var
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
if (syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
425
|
-
viewModeDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
426
|
-
class: _syncBlock.SyncBlockStateCssClassName.viewModeClassName
|
|
427
|
-
}));
|
|
428
|
-
}
|
|
429
|
-
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
430
|
-
loadingDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
431
|
-
class: _syncBlock.SyncBlockStateCssClassName.creationLoadingClassName
|
|
432
|
-
}));
|
|
501
|
+
var selectionDecorationSet = currentPluginState.selectionDecorationSet,
|
|
502
|
+
statusDecorationSet = currentPluginState.statusDecorationSet,
|
|
503
|
+
docHasSyncedBlocks = currentPluginState.hasSyncedBlocks;
|
|
504
|
+
|
|
505
|
+
// When the perf gate is ON, both `selectionDecorationSet` and
|
|
506
|
+
// `statusDecorationSet` are maintained in plugin state by
|
|
507
|
+
// `apply()`. The `decorations` prop is now an O(1) merge of
|
|
508
|
+
// the two cached sets — no `doc.descendants()` walk, no
|
|
509
|
+
// shared-state reads.
|
|
510
|
+
if ((0, _expValEquals.expValEquals)('editor_synced_block_perf', 'isEnabled', true)) {
|
|
511
|
+
var _api$focus$sharedStat, _api$focus;
|
|
512
|
+
if (!docHasSyncedBlocks) {
|
|
513
|
+
return selectionDecorationSet;
|
|
433
514
|
}
|
|
434
515
|
|
|
435
|
-
//
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
516
|
+
// Focus state is read live here (single cheap read) because
|
|
517
|
+
// it only gates whether selection decorations are included —
|
|
518
|
+
// it does not affect the status decoration set and can change
|
|
519
|
+
// within the same transaction cycle.
|
|
520
|
+
var hasFocus = (_api$focus$sharedStat = api === null || api === void 0 || (_api$focus = api.focus) === null || _api$focus === void 0 || (_api$focus = _api$focus.sharedState) === null || _api$focus === void 0 || (_api$focus = _api$focus.currentState()) === null || _api$focus === void 0 ? void 0 : _api$focus.hasFocus) !== null && _api$focus$sharedStat !== void 0 ? _api$focus$sharedStat : true;
|
|
521
|
+
|
|
522
|
+
// Merge selection + status decorations.
|
|
523
|
+
// When the editor is unfocused,
|
|
524
|
+
// omit selection decorations (matches old behaviour).
|
|
525
|
+
var statusDecorations = statusDecorationSet.find();
|
|
526
|
+
if (statusDecorations.length === 0) {
|
|
527
|
+
return hasFocus ? selectionDecorationSet : _view.DecorationSet.empty;
|
|
528
|
+
} else {
|
|
529
|
+
return hasFocus ? selectionDecorationSet.add(state.doc, statusDecorations) : statusDecorationSet;
|
|
440
530
|
}
|
|
441
|
-
});
|
|
442
|
-
if (api !== null && api !== void 0 && (_api$focus = api.focus) !== null && _api$focus !== void 0 && (_api$focus = _api$focus.sharedState) !== null && _api$focus !== void 0 && (_api$focus = _api$focus.currentState()) !== null && _api$focus !== void 0 && _api$focus.hasFocus || !(0, _experiments.editorExperiment)('platform_synced_block_patch_6', true, {
|
|
443
|
-
exposure: true
|
|
444
|
-
})) {
|
|
445
|
-
// Don't show decorations if the editor is not focused
|
|
446
|
-
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
447
531
|
} else {
|
|
448
|
-
|
|
532
|
+
var _api$connectivity4, _api$editorViewMode3, _api$userIntent3, _api$focus2;
|
|
533
|
+
// --- Legacy path (perf gate OFF) ---
|
|
534
|
+
// Full `doc.descendants()` walk every transaction. Preserved
|
|
535
|
+
// for safe rollback.
|
|
536
|
+
var _syncBlockStore = currentPluginState.syncBlockStore;
|
|
537
|
+
var doc = state.doc;
|
|
538
|
+
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);
|
|
539
|
+
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';
|
|
540
|
+
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';
|
|
541
|
+
var offlineDecorations = [];
|
|
542
|
+
var viewModeDecorations = [];
|
|
543
|
+
var loadingDecorations = [];
|
|
544
|
+
var dragDecorations = [];
|
|
545
|
+
state.doc.descendants(function (node, pos) {
|
|
546
|
+
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
547
|
+
offlineDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
548
|
+
class: _syncBlock.SyncBlockStateCssClassName.disabledClassName
|
|
549
|
+
}));
|
|
550
|
+
}
|
|
551
|
+
if (_syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
552
|
+
viewModeDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
553
|
+
class: _syncBlock.SyncBlockStateCssClassName.viewModeClassName
|
|
554
|
+
}));
|
|
555
|
+
}
|
|
556
|
+
if (node.type.name === 'bodiedSyncBlock' && _syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
557
|
+
loadingDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
558
|
+
class: _syncBlock.SyncBlockStateCssClassName.creationLoadingClassName
|
|
559
|
+
}));
|
|
560
|
+
}
|
|
561
|
+
if (isDragging && _syncBlockStore.isSyncBlock(node)) {
|
|
562
|
+
dragDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
|
|
563
|
+
class: _syncBlock.SyncBlockStateCssClassName.draggingClassName
|
|
564
|
+
}));
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
if (api !== null && api !== void 0 && (_api$focus2 = api.focus) !== null && _api$focus2 !== void 0 && (_api$focus2 = _api$focus2.sharedState) !== null && _api$focus2 !== void 0 && (_api$focus2 = _api$focus2.currentState()) !== null && _api$focus2 !== void 0 && _api$focus2.hasFocus) {
|
|
568
|
+
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
569
|
+
} else {
|
|
570
|
+
return _view.DecorationSet.empty.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
571
|
+
}
|
|
449
572
|
}
|
|
450
573
|
},
|
|
451
574
|
handleClickOn: (0, _selection.createSelectionClickHandler)(['bodiedSyncBlock'], function (target) {
|
|
@@ -503,7 +626,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
503
626
|
}
|
|
504
627
|
},
|
|
505
628
|
filterTransaction: function filterTransaction(tr, state) {
|
|
506
|
-
var _api$
|
|
629
|
+
var _api$editorViewMode4, _api$connectivity5;
|
|
507
630
|
// Lazy-init: when no synced block currently exists in the doc and the
|
|
508
631
|
// transaction does not insert one, all downstream filter logic is a
|
|
509
632
|
// no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
|
|
@@ -514,11 +637,11 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
514
637
|
return true;
|
|
515
638
|
}
|
|
516
639
|
}
|
|
517
|
-
var viewMode = api === null || api === void 0 || (_api$
|
|
640
|
+
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;
|
|
518
641
|
if (viewMode === 'view' && (0, _platformFeatureFlags.fg)('platform_synced_block_patch_8')) {
|
|
519
642
|
return true;
|
|
520
643
|
}
|
|
521
|
-
var isOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$
|
|
644
|
+
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);
|
|
522
645
|
var isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
|
|
523
646
|
|
|
524
647
|
// Track newly added reference sync blocks before processing the transaction
|
|
@@ -593,7 +716,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
593
716
|
});
|
|
594
717
|
},
|
|
595
718
|
appendTransaction: function appendTransaction(trs, oldState, newState) {
|
|
596
|
-
var _api$
|
|
719
|
+
var _api$editorViewMode5;
|
|
597
720
|
// Lazy-init: when neither the previous nor the new state contains a
|
|
598
721
|
// synced block (and none of the dispatched transactions inserts one),
|
|
599
722
|
// skip all downstream work. This is the hot path on the ~99.97% of
|
|
@@ -606,7 +729,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
606
729
|
return null;
|
|
607
730
|
}
|
|
608
731
|
}
|
|
609
|
-
var viewMode = api === null || api === void 0 || (_api$
|
|
732
|
+
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;
|
|
610
733
|
if (viewMode === 'view' && (0, _platformFeatureFlags.fg)('platform_synced_block_patch_8')) {
|
|
611
734
|
return null;
|
|
612
735
|
}
|
|
@@ -74,9 +74,7 @@ const showExtensionInSyncBlockWarningIfNeeded = (tr, state, api, extensionFlagSh
|
|
|
74
74
|
tr
|
|
75
75
|
}) => tr.setMeta(syncedBlockPluginKey, {
|
|
76
76
|
activeFlag: {
|
|
77
|
-
id:
|
|
78
|
-
exposure: true
|
|
79
|
-
}) ? FLAG_ID.EXTENSION_IN_SYNC_BLOCK : FLAG_ID.INLINE_EXTENSION_IN_SYNC_BLOCK
|
|
77
|
+
id: FLAG_ID.EXTENSION_IN_SYNC_BLOCK
|
|
80
78
|
}
|
|
81
79
|
}));
|
|
82
80
|
});
|
|
@@ -183,6 +181,48 @@ const filterTransactionOffline = ({
|
|
|
183
181
|
return true;
|
|
184
182
|
};
|
|
185
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Build the status decoration set for sync-block nodes. This performs a full
|
|
186
|
+
* `doc.descendants()` walk so it must only be called when a status signal
|
|
187
|
+
* actually changes (offline, view-mode, dragging, pending-creation). Between
|
|
188
|
+
* status changes the caller should use `decorationSet.map(tr.mapping, tr.doc)`
|
|
189
|
+
* instead (see EDITOR-6930).
|
|
190
|
+
*/
|
|
191
|
+
const buildStatusDecorations = (doc, syncBlockStore, isOffline, isViewMode, isDragging) => {
|
|
192
|
+
// Fast path: when all status flags are off and no creations are in flight,
|
|
193
|
+
// no node can produce a decoration — skip the full doc traversal.
|
|
194
|
+
if (!isOffline && !isViewMode && !isDragging && !syncBlockStore.sourceManager.hasPendingCreations()) {
|
|
195
|
+
return DecorationSet.empty;
|
|
196
|
+
}
|
|
197
|
+
const offlineDecorations = [];
|
|
198
|
+
const viewModeDecorations = [];
|
|
199
|
+
const loadingDecorations = [];
|
|
200
|
+
const dragDecorations = [];
|
|
201
|
+
doc.descendants((node, pos) => {
|
|
202
|
+
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
203
|
+
offlineDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
204
|
+
class: SyncBlockStateCssClassName.disabledClassName
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
if (syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
208
|
+
viewModeDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
209
|
+
class: SyncBlockStateCssClassName.viewModeClassName
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
213
|
+
loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
214
|
+
class: SyncBlockStateCssClassName.creationLoadingClassName
|
|
215
|
+
}));
|
|
216
|
+
}
|
|
217
|
+
if (isDragging && syncBlockStore.isSyncBlock(node)) {
|
|
218
|
+
dragDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
219
|
+
class: SyncBlockStateCssClassName.draggingClassName
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
return DecorationSet.create(doc, [...offlineDecorations, ...viewModeDecorations, ...loadingDecorations, ...dragDecorations]);
|
|
224
|
+
};
|
|
225
|
+
|
|
186
226
|
/**
|
|
187
227
|
* Encapsulates mutable state that persists across transactions in the
|
|
188
228
|
* synced block plugin. Replaces module-level closure variables so state
|
|
@@ -249,6 +289,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
249
289
|
key: syncedBlockPluginKey,
|
|
250
290
|
state: {
|
|
251
291
|
init(_, instance) {
|
|
292
|
+
var _api$connectivity2, _api$connectivity2$sh, _api$editorViewMode, _api$editorViewMode$s, _api$userIntent, _api$userIntent$share;
|
|
252
293
|
// When `editor_synced_block_perf` is ON and the document has no
|
|
253
294
|
// synced blocks, we skip the eager fetch + cache walks. They will be
|
|
254
295
|
// re-run lazily by `apply` the first time a synced block enters the
|
|
@@ -273,13 +314,28 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
273
314
|
}
|
|
274
315
|
}
|
|
275
316
|
}
|
|
317
|
+
|
|
318
|
+
// Read initial shared-state signals for status decorations
|
|
319
|
+
const initIsOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity2 = api.connectivity) === null || _api$connectivity2 === void 0 ? void 0 : (_api$connectivity2$sh = _api$connectivity2.sharedState.currentState()) === null || _api$connectivity2$sh === void 0 ? void 0 : _api$connectivity2$sh.mode);
|
|
320
|
+
const initIsViewMode = (api === null || api === void 0 ? void 0 : (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : (_api$editorViewMode$s = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode$s === void 0 ? void 0 : _api$editorViewMode$s.mode) === 'view';
|
|
321
|
+
const initIsDragging = (api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : (_api$userIntent$share = _api$userIntent.sharedState.currentState()) === null || _api$userIntent$share === void 0 ? void 0 : _api$userIntent$share.currentUserIntent) === 'dragging';
|
|
322
|
+
|
|
323
|
+
// Build initial status decoration set (EDITOR-6930).
|
|
324
|
+
// When the perf gate is ON and the doc has synced blocks we do a
|
|
325
|
+
// single traversal here; afterwards `apply()` will map or rebuild
|
|
326
|
+
// only when a status signal changes.
|
|
327
|
+
const initStatusDecorationSet = expValEquals('editor_synced_block_perf', 'isEnabled', true) && docHasSyncedBlocks ? buildStatusDecorations(instance.doc, syncBlockStore, initIsOffline, initIsViewMode, initIsDragging) : DecorationSet.empty;
|
|
276
328
|
return {
|
|
277
329
|
selectionDecorationSet: calculateDecorations(instance.doc, instance.selection, instance.schema),
|
|
278
330
|
activeFlag: false,
|
|
279
331
|
syncBlockStore: syncBlockStore,
|
|
280
332
|
retryCreationPosMap: new Map(),
|
|
281
333
|
hasSyncedBlocks: docHasSyncedBlocks,
|
|
282
|
-
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges()
|
|
334
|
+
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges(),
|
|
335
|
+
statusDecorationSet: initStatusDecorationSet,
|
|
336
|
+
prevIsOffline: initIsOffline,
|
|
337
|
+
prevIsViewMode: initIsViewMode,
|
|
338
|
+
prevIsDragging: initIsDragging
|
|
283
339
|
};
|
|
284
340
|
},
|
|
285
341
|
apply: (tr, currentPluginState, oldEditorState) => {
|
|
@@ -290,7 +346,11 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
290
346
|
selectionDecorationSet,
|
|
291
347
|
bodiedSyncBlockDeletionStatus,
|
|
292
348
|
retryCreationPosMap,
|
|
293
|
-
hasSyncedBlocks: prevHasSyncedBlocks
|
|
349
|
+
hasSyncedBlocks: prevHasSyncedBlocks,
|
|
350
|
+
statusDecorationSet: prevStatusDecorationSet,
|
|
351
|
+
prevIsOffline: prevOffline,
|
|
352
|
+
prevIsViewMode: prevViewMode,
|
|
353
|
+
prevIsDragging: prevDragging
|
|
294
354
|
} = currentPluginState;
|
|
295
355
|
|
|
296
356
|
// Lazy-init bookkeeping: once a synced block enters the document we
|
|
@@ -316,6 +376,41 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
316
376
|
newDecorationSet = calculateDecorations(tr.doc, tr.selection, tr.doc.type.schema);
|
|
317
377
|
}
|
|
318
378
|
}
|
|
379
|
+
|
|
380
|
+
// --- Status decoration set (EDITOR-6930) ---
|
|
381
|
+
// When the perf gate is ON we maintain `statusDecorationSet` in
|
|
382
|
+
// plugin state so the `decorations` prop becomes an O(1) lookup.
|
|
383
|
+
let nextStatusDecorationSet = prevStatusDecorationSet;
|
|
384
|
+
let nextIsOffline = prevOffline;
|
|
385
|
+
let nextIsViewMode = prevViewMode;
|
|
386
|
+
let nextIsDragging = prevDragging;
|
|
387
|
+
if (expValEquals('editor_synced_block_perf', 'isEnabled', true)) {
|
|
388
|
+
if (!nextHasSyncedBlocks) {
|
|
389
|
+
// No synced blocks → keep empty status decorations
|
|
390
|
+
nextStatusDecorationSet = DecorationSet.empty;
|
|
391
|
+
} else {
|
|
392
|
+
var _api$connectivity3, _api$connectivity3$sh, _api$editorViewMode2, _api$editorViewMode2$, _api$userIntent2, _api$userIntent2$shar;
|
|
393
|
+
// Read current shared-state signals
|
|
394
|
+
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);
|
|
395
|
+
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';
|
|
396
|
+
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';
|
|
397
|
+
|
|
398
|
+
// Determine whether we need a full rebuild or a cheap map
|
|
399
|
+
const hasSyncedBlocksJustFlipped = nextHasSyncedBlocks && !prevHasSyncedBlocks;
|
|
400
|
+
const statusSignalChanged = nextIsOffline !== prevOffline || nextIsViewMode !== prevViewMode || nextIsDragging !== prevDragging;
|
|
401
|
+
// Meta-driven status changes (e.g. pending creation
|
|
402
|
+
// completed, retry creation pos updated)
|
|
403
|
+
const hasMetaStatusChange = !!(meta !== null && meta !== void 0 && meta.retryCreationPos) || !!(meta !== null && meta !== void 0 && meta.activeFlag);
|
|
404
|
+
if (hasSyncedBlocksJustFlipped || statusSignalChanged || hasMetaStatusChange) {
|
|
405
|
+
// Full rebuild — a status signal changed
|
|
406
|
+
nextStatusDecorationSet = buildStatusDecorations(tr.doc, syncBlockStore, nextIsOffline, nextIsViewMode, nextIsDragging);
|
|
407
|
+
} else if (tr.docChanged) {
|
|
408
|
+
// Cheap map — positions shifted but status unchanged
|
|
409
|
+
nextStatusDecorationSet = prevStatusDecorationSet.map(tr.mapping, tr.doc);
|
|
410
|
+
}
|
|
411
|
+
// else: nothing changed, keep same reference
|
|
412
|
+
}
|
|
413
|
+
}
|
|
319
414
|
const newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
|
|
320
415
|
const newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
|
|
321
416
|
return {
|
|
@@ -325,7 +420,11 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
325
420
|
retryCreationPosMap: newRetryCreationPosMap,
|
|
326
421
|
hasSyncedBlocks: nextHasSyncedBlocks,
|
|
327
422
|
bodiedSyncBlockDeletionStatus: (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus,
|
|
328
|
-
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges()
|
|
423
|
+
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges(),
|
|
424
|
+
statusDecorationSet: nextStatusDecorationSet,
|
|
425
|
+
prevIsOffline: nextIsOffline,
|
|
426
|
+
prevIsViewMode: nextIsViewMode,
|
|
427
|
+
prevIsDragging: nextIsDragging
|
|
329
428
|
};
|
|
330
429
|
}
|
|
331
430
|
},
|
|
@@ -361,59 +460,85 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
361
460
|
})
|
|
362
461
|
},
|
|
363
462
|
decorations: state => {
|
|
364
|
-
var _currentPluginState$s, _api$connectivity2, _api$connectivity2$sh, _api$editorViewMode, _api$editorViewMode$s, _api$userIntent, _api$userIntent$share, _api$focus, _api$focus$sharedStat, _api$focus$sharedStat2;
|
|
365
463
|
const currentPluginState = syncedBlockPluginKey.getState(state);
|
|
366
|
-
|
|
367
|
-
|
|
464
|
+
if (!currentPluginState) {
|
|
465
|
+
return DecorationSet.empty;
|
|
466
|
+
}
|
|
368
467
|
const {
|
|
369
|
-
|
|
370
|
-
|
|
468
|
+
selectionDecorationSet,
|
|
469
|
+
statusDecorationSet,
|
|
470
|
+
hasSyncedBlocks: docHasSyncedBlocks
|
|
471
|
+
} = currentPluginState;
|
|
371
472
|
|
|
372
|
-
//
|
|
373
|
-
// `
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
const isDragging = (api === null || api === void 0 ? void 0 : (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 ? void 0 : (_api$userIntent$share = _api$userIntent.sharedState.currentState()) === null || _api$userIntent$share === void 0 ? void 0 : _api$userIntent$share.currentUserIntent) === 'dragging';
|
|
382
|
-
const offlineDecorations = [];
|
|
383
|
-
const viewModeDecorations = [];
|
|
384
|
-
const loadingDecorations = [];
|
|
385
|
-
const dragDecorations = [];
|
|
386
|
-
state.doc.descendants((node, pos) => {
|
|
387
|
-
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
388
|
-
offlineDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
389
|
-
class: SyncBlockStateCssClassName.disabledClassName
|
|
390
|
-
}));
|
|
391
|
-
}
|
|
392
|
-
if (syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
393
|
-
viewModeDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
394
|
-
class: SyncBlockStateCssClassName.viewModeClassName
|
|
395
|
-
}));
|
|
396
|
-
}
|
|
397
|
-
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
398
|
-
loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
399
|
-
class: SyncBlockStateCssClassName.creationLoadingClassName
|
|
400
|
-
}));
|
|
473
|
+
// When the perf gate is ON, both `selectionDecorationSet` and
|
|
474
|
+
// `statusDecorationSet` are maintained in plugin state by
|
|
475
|
+
// `apply()`. The `decorations` prop is now an O(1) merge of
|
|
476
|
+
// the two cached sets — no `doc.descendants()` walk, no
|
|
477
|
+
// shared-state reads.
|
|
478
|
+
if (expValEquals('editor_synced_block_perf', 'isEnabled', true)) {
|
|
479
|
+
var _api$focus$sharedStat, _api$focus, _api$focus$sharedStat2, _api$focus$sharedStat3;
|
|
480
|
+
if (!docHasSyncedBlocks) {
|
|
481
|
+
return selectionDecorationSet;
|
|
401
482
|
}
|
|
402
483
|
|
|
403
|
-
//
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
484
|
+
// Focus state is read live here (single cheap read) because
|
|
485
|
+
// it only gates whether selection decorations are included —
|
|
486
|
+
// it does not affect the status decoration set and can change
|
|
487
|
+
// within the same transaction cycle.
|
|
488
|
+
const hasFocus = (_api$focus$sharedStat = api === null || api === void 0 ? void 0 : (_api$focus = api.focus) === null || _api$focus === void 0 ? void 0 : (_api$focus$sharedStat2 = _api$focus.sharedState) === null || _api$focus$sharedStat2 === void 0 ? void 0 : (_api$focus$sharedStat3 = _api$focus$sharedStat2.currentState()) === null || _api$focus$sharedStat3 === void 0 ? void 0 : _api$focus$sharedStat3.hasFocus) !== null && _api$focus$sharedStat !== void 0 ? _api$focus$sharedStat : true;
|
|
489
|
+
|
|
490
|
+
// Merge selection + status decorations.
|
|
491
|
+
// When the editor is unfocused,
|
|
492
|
+
// omit selection decorations (matches old behaviour).
|
|
493
|
+
const statusDecorations = statusDecorationSet.find();
|
|
494
|
+
if (statusDecorations.length === 0) {
|
|
495
|
+
return hasFocus ? selectionDecorationSet : DecorationSet.empty;
|
|
496
|
+
} else {
|
|
497
|
+
return hasFocus ? selectionDecorationSet.add(state.doc, statusDecorations) : statusDecorationSet;
|
|
408
498
|
}
|
|
409
|
-
});
|
|
410
|
-
if (api !== null && api !== void 0 && (_api$focus = api.focus) !== null && _api$focus !== void 0 && (_api$focus$sharedStat = _api$focus.sharedState) !== null && _api$focus$sharedStat !== void 0 && (_api$focus$sharedStat2 = _api$focus$sharedStat.currentState()) !== null && _api$focus$sharedStat2 !== void 0 && _api$focus$sharedStat2.hasFocus || !editorExperiment('platform_synced_block_patch_6', true, {
|
|
411
|
-
exposure: true
|
|
412
|
-
})) {
|
|
413
|
-
// Don't show decorations if the editor is not focused
|
|
414
|
-
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
415
499
|
} else {
|
|
416
|
-
|
|
500
|
+
var _api$connectivity4, _api$connectivity4$sh, _api$editorViewMode3, _api$editorViewMode3$, _api$userIntent3, _api$userIntent3$shar, _api$focus2, _api$focus2$sharedSta, _api$focus2$sharedSta2;
|
|
501
|
+
// --- Legacy path (perf gate OFF) ---
|
|
502
|
+
// Full `doc.descendants()` walk every transaction. Preserved
|
|
503
|
+
// for safe rollback.
|
|
504
|
+
const syncBlockStore = currentPluginState.syncBlockStore;
|
|
505
|
+
const {
|
|
506
|
+
doc
|
|
507
|
+
} = state;
|
|
508
|
+
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);
|
|
509
|
+
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';
|
|
510
|
+
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';
|
|
511
|
+
const offlineDecorations = [];
|
|
512
|
+
const viewModeDecorations = [];
|
|
513
|
+
const loadingDecorations = [];
|
|
514
|
+
const dragDecorations = [];
|
|
515
|
+
state.doc.descendants((node, pos) => {
|
|
516
|
+
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
517
|
+
offlineDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
518
|
+
class: SyncBlockStateCssClassName.disabledClassName
|
|
519
|
+
}));
|
|
520
|
+
}
|
|
521
|
+
if (syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
522
|
+
viewModeDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
523
|
+
class: SyncBlockStateCssClassName.viewModeClassName
|
|
524
|
+
}));
|
|
525
|
+
}
|
|
526
|
+
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
527
|
+
loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
528
|
+
class: SyncBlockStateCssClassName.creationLoadingClassName
|
|
529
|
+
}));
|
|
530
|
+
}
|
|
531
|
+
if (isDragging && syncBlockStore.isSyncBlock(node)) {
|
|
532
|
+
dragDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
533
|
+
class: SyncBlockStateCssClassName.draggingClassName
|
|
534
|
+
}));
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
if (api !== null && api !== void 0 && (_api$focus2 = api.focus) !== null && _api$focus2 !== void 0 && (_api$focus2$sharedSta = _api$focus2.sharedState) !== null && _api$focus2$sharedSta !== void 0 && (_api$focus2$sharedSta2 = _api$focus2$sharedSta.currentState()) !== null && _api$focus2$sharedSta2 !== void 0 && _api$focus2$sharedSta2.hasFocus) {
|
|
538
|
+
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
539
|
+
} else {
|
|
540
|
+
return DecorationSet.empty.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
541
|
+
}
|
|
417
542
|
}
|
|
418
543
|
},
|
|
419
544
|
handleClickOn: createSelectionClickHandler(['bodiedSyncBlock'], target => !!target.closest(`.${BodiedSyncBlockSharedCssClassName.prefix}`), {
|
|
@@ -473,7 +598,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
473
598
|
}
|
|
474
599
|
},
|
|
475
600
|
filterTransaction: (tr, state) => {
|
|
476
|
-
var _api$
|
|
601
|
+
var _api$editorViewMode4, _api$editorViewMode4$, _api$connectivity5, _api$connectivity5$sh;
|
|
477
602
|
// Lazy-init: when no synced block currently exists in the doc and the
|
|
478
603
|
// transaction does not insert one, all downstream filter logic is a
|
|
479
604
|
// no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
|
|
@@ -484,11 +609,11 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
484
609
|
return true;
|
|
485
610
|
}
|
|
486
611
|
}
|
|
487
|
-
const viewMode = api === null || api === void 0 ? void 0 : (_api$
|
|
612
|
+
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;
|
|
488
613
|
if (viewMode === 'view' && fg('platform_synced_block_patch_8')) {
|
|
489
614
|
return true;
|
|
490
615
|
}
|
|
491
|
-
const isOffline = isOfflineMode(api === null || api === void 0 ? void 0 : (_api$
|
|
616
|
+
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);
|
|
492
617
|
const isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
|
|
493
618
|
|
|
494
619
|
// Track newly added reference sync blocks before processing the transaction
|
|
@@ -556,7 +681,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
556
681
|
});
|
|
557
682
|
},
|
|
558
683
|
appendTransaction: (trs, oldState, newState) => {
|
|
559
|
-
var _api$
|
|
684
|
+
var _api$editorViewMode5, _api$editorViewMode5$;
|
|
560
685
|
// Lazy-init: when neither the previous nor the new state contains a
|
|
561
686
|
// synced block (and none of the dispatched transactions inserts one),
|
|
562
687
|
// skip all downstream work. This is the hot path on the ~99.97% of
|
|
@@ -569,7 +694,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
569
694
|
return null;
|
|
570
695
|
}
|
|
571
696
|
}
|
|
572
|
-
const viewMode = api === null || api === void 0 ? void 0 : (_api$
|
|
697
|
+
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;
|
|
573
698
|
if (viewMode === 'view' && fg('platform_synced_block_patch_8')) {
|
|
574
699
|
return null;
|
|
575
700
|
}
|
|
@@ -92,9 +92,7 @@ var showExtensionInSyncBlockWarningIfNeeded = function showExtensionInSyncBlockW
|
|
|
92
92
|
var tr = _ref2.tr;
|
|
93
93
|
return tr.setMeta(syncedBlockPluginKey, {
|
|
94
94
|
activeFlag: {
|
|
95
|
-
id:
|
|
96
|
-
exposure: true
|
|
97
|
-
}) ? FLAG_ID.EXTENSION_IN_SYNC_BLOCK : FLAG_ID.INLINE_EXTENSION_IN_SYNC_BLOCK
|
|
95
|
+
id: FLAG_ID.EXTENSION_IN_SYNC_BLOCK
|
|
98
96
|
}
|
|
99
97
|
});
|
|
100
98
|
});
|
|
@@ -199,6 +197,48 @@ var filterTransactionOffline = function filterTransactionOffline(_ref4) {
|
|
|
199
197
|
return true;
|
|
200
198
|
};
|
|
201
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Build the status decoration set for sync-block nodes. This performs a full
|
|
202
|
+
* `doc.descendants()` walk so it must only be called when a status signal
|
|
203
|
+
* actually changes (offline, view-mode, dragging, pending-creation). Between
|
|
204
|
+
* status changes the caller should use `decorationSet.map(tr.mapping, tr.doc)`
|
|
205
|
+
* instead (see EDITOR-6930).
|
|
206
|
+
*/
|
|
207
|
+
var buildStatusDecorations = function buildStatusDecorations(doc, syncBlockStore, isOffline, isViewMode, isDragging) {
|
|
208
|
+
// Fast path: when all status flags are off and no creations are in flight,
|
|
209
|
+
// no node can produce a decoration — skip the full doc traversal.
|
|
210
|
+
if (!isOffline && !isViewMode && !isDragging && !syncBlockStore.sourceManager.hasPendingCreations()) {
|
|
211
|
+
return DecorationSet.empty;
|
|
212
|
+
}
|
|
213
|
+
var offlineDecorations = [];
|
|
214
|
+
var viewModeDecorations = [];
|
|
215
|
+
var loadingDecorations = [];
|
|
216
|
+
var dragDecorations = [];
|
|
217
|
+
doc.descendants(function (node, pos) {
|
|
218
|
+
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
219
|
+
offlineDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
220
|
+
class: SyncBlockStateCssClassName.disabledClassName
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
if (syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
224
|
+
viewModeDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
225
|
+
class: SyncBlockStateCssClassName.viewModeClassName
|
|
226
|
+
}));
|
|
227
|
+
}
|
|
228
|
+
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
229
|
+
loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
230
|
+
class: SyncBlockStateCssClassName.creationLoadingClassName
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
if (isDragging && syncBlockStore.isSyncBlock(node)) {
|
|
234
|
+
dragDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
235
|
+
class: SyncBlockStateCssClassName.draggingClassName
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
return DecorationSet.create(doc, [].concat(offlineDecorations, viewModeDecorations, loadingDecorations, dragDecorations));
|
|
240
|
+
};
|
|
241
|
+
|
|
202
242
|
/**
|
|
203
243
|
* Encapsulates mutable state that persists across transactions in the
|
|
204
244
|
* synced block plugin. Replaces module-level closure variables so state
|
|
@@ -275,6 +315,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
275
315
|
key: syncedBlockPluginKey,
|
|
276
316
|
state: {
|
|
277
317
|
init: function init(_, instance) {
|
|
318
|
+
var _api$connectivity2, _api$editorViewMode, _api$userIntent;
|
|
278
319
|
// When `editor_synced_block_perf` is ON and the document has no
|
|
279
320
|
// synced blocks, we skip the eager fetch + cache walks. They will be
|
|
280
321
|
// re-run lazily by `apply` the first time a synced block enters the
|
|
@@ -299,13 +340,28 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
299
340
|
}
|
|
300
341
|
}
|
|
301
342
|
}
|
|
343
|
+
|
|
344
|
+
// Read initial shared-state signals for status decorations
|
|
345
|
+
var initIsOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity2 = api.connectivity) === null || _api$connectivity2 === void 0 || (_api$connectivity2 = _api$connectivity2.sharedState.currentState()) === null || _api$connectivity2 === void 0 ? void 0 : _api$connectivity2.mode);
|
|
346
|
+
var initIsViewMode = (api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 || (_api$editorViewMode = _api$editorViewMode.sharedState.currentState()) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.mode) === 'view';
|
|
347
|
+
var initIsDragging = (api === null || api === void 0 || (_api$userIntent = api.userIntent) === null || _api$userIntent === void 0 || (_api$userIntent = _api$userIntent.sharedState.currentState()) === null || _api$userIntent === void 0 ? void 0 : _api$userIntent.currentUserIntent) === 'dragging';
|
|
348
|
+
|
|
349
|
+
// Build initial status decoration set (EDITOR-6930).
|
|
350
|
+
// When the perf gate is ON and the doc has synced blocks we do a
|
|
351
|
+
// single traversal here; afterwards `apply()` will map or rebuild
|
|
352
|
+
// only when a status signal changes.
|
|
353
|
+
var initStatusDecorationSet = expValEquals('editor_synced_block_perf', 'isEnabled', true) && docHasSyncedBlocks ? buildStatusDecorations(instance.doc, syncBlockStore, initIsOffline, initIsViewMode, initIsDragging) : DecorationSet.empty;
|
|
302
354
|
return {
|
|
303
355
|
selectionDecorationSet: calculateDecorations(instance.doc, instance.selection, instance.schema),
|
|
304
356
|
activeFlag: false,
|
|
305
357
|
syncBlockStore: syncBlockStore,
|
|
306
358
|
retryCreationPosMap: new Map(),
|
|
307
359
|
hasSyncedBlocks: docHasSyncedBlocks,
|
|
308
|
-
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges()
|
|
360
|
+
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges(),
|
|
361
|
+
statusDecorationSet: initStatusDecorationSet,
|
|
362
|
+
prevIsOffline: initIsOffline,
|
|
363
|
+
prevIsViewMode: initIsViewMode,
|
|
364
|
+
prevIsDragging: initIsDragging
|
|
309
365
|
};
|
|
310
366
|
},
|
|
311
367
|
apply: function apply(tr, currentPluginState, oldEditorState) {
|
|
@@ -315,7 +371,11 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
315
371
|
selectionDecorationSet = currentPluginState.selectionDecorationSet,
|
|
316
372
|
bodiedSyncBlockDeletionStatus = currentPluginState.bodiedSyncBlockDeletionStatus,
|
|
317
373
|
retryCreationPosMap = currentPluginState.retryCreationPosMap,
|
|
318
|
-
prevHasSyncedBlocks = currentPluginState.hasSyncedBlocks
|
|
374
|
+
prevHasSyncedBlocks = currentPluginState.hasSyncedBlocks,
|
|
375
|
+
prevStatusDecorationSet = currentPluginState.statusDecorationSet,
|
|
376
|
+
prevOffline = currentPluginState.prevIsOffline,
|
|
377
|
+
prevViewMode = currentPluginState.prevIsViewMode,
|
|
378
|
+
prevDragging = currentPluginState.prevIsDragging;
|
|
319
379
|
|
|
320
380
|
// Lazy-init bookkeeping: once a synced block enters the document we
|
|
321
381
|
// flip `hasSyncedBlocks` to `true` for the lifetime of this editor
|
|
@@ -340,6 +400,41 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
340
400
|
newDecorationSet = calculateDecorations(tr.doc, tr.selection, tr.doc.type.schema);
|
|
341
401
|
}
|
|
342
402
|
}
|
|
403
|
+
|
|
404
|
+
// --- Status decoration set (EDITOR-6930) ---
|
|
405
|
+
// When the perf gate is ON we maintain `statusDecorationSet` in
|
|
406
|
+
// plugin state so the `decorations` prop becomes an O(1) lookup.
|
|
407
|
+
var nextStatusDecorationSet = prevStatusDecorationSet;
|
|
408
|
+
var nextIsOffline = prevOffline;
|
|
409
|
+
var nextIsViewMode = prevViewMode;
|
|
410
|
+
var nextIsDragging = prevDragging;
|
|
411
|
+
if (expValEquals('editor_synced_block_perf', 'isEnabled', true)) {
|
|
412
|
+
if (!nextHasSyncedBlocks) {
|
|
413
|
+
// No synced blocks → keep empty status decorations
|
|
414
|
+
nextStatusDecorationSet = DecorationSet.empty;
|
|
415
|
+
} else {
|
|
416
|
+
var _api$connectivity3, _api$editorViewMode2, _api$userIntent2;
|
|
417
|
+
// Read current shared-state signals
|
|
418
|
+
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);
|
|
419
|
+
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';
|
|
420
|
+
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';
|
|
421
|
+
|
|
422
|
+
// Determine whether we need a full rebuild or a cheap map
|
|
423
|
+
var hasSyncedBlocksJustFlipped = nextHasSyncedBlocks && !prevHasSyncedBlocks;
|
|
424
|
+
var statusSignalChanged = nextIsOffline !== prevOffline || nextIsViewMode !== prevViewMode || nextIsDragging !== prevDragging;
|
|
425
|
+
// Meta-driven status changes (e.g. pending creation
|
|
426
|
+
// completed, retry creation pos updated)
|
|
427
|
+
var hasMetaStatusChange = !!(meta !== null && meta !== void 0 && meta.retryCreationPos) || !!(meta !== null && meta !== void 0 && meta.activeFlag);
|
|
428
|
+
if (hasSyncedBlocksJustFlipped || statusSignalChanged || hasMetaStatusChange) {
|
|
429
|
+
// Full rebuild — a status signal changed
|
|
430
|
+
nextStatusDecorationSet = buildStatusDecorations(tr.doc, syncBlockStore, nextIsOffline, nextIsViewMode, nextIsDragging);
|
|
431
|
+
} else if (tr.docChanged) {
|
|
432
|
+
// Cheap map — positions shifted but status unchanged
|
|
433
|
+
nextStatusDecorationSet = prevStatusDecorationSet.map(tr.mapping, tr.doc);
|
|
434
|
+
}
|
|
435
|
+
// else: nothing changed, keep same reference
|
|
436
|
+
}
|
|
437
|
+
}
|
|
343
438
|
var newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
|
|
344
439
|
var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
|
|
345
440
|
return {
|
|
@@ -349,7 +444,11 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
349
444
|
retryCreationPosMap: newRetryCreationPosMap,
|
|
350
445
|
hasSyncedBlocks: nextHasSyncedBlocks,
|
|
351
446
|
bodiedSyncBlockDeletionStatus: (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus,
|
|
352
|
-
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges()
|
|
447
|
+
hasUnsavedBodiedSyncBlockChanges: syncBlockStore.sourceManager.hasUnsavedChanges(),
|
|
448
|
+
statusDecorationSet: nextStatusDecorationSet,
|
|
449
|
+
prevIsOffline: nextIsOffline,
|
|
450
|
+
prevIsViewMode: nextIsViewMode,
|
|
451
|
+
prevIsDragging: nextIsDragging
|
|
353
452
|
};
|
|
354
453
|
}
|
|
355
454
|
},
|
|
@@ -388,57 +487,81 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
388
487
|
})
|
|
389
488
|
},
|
|
390
489
|
decorations: function decorations(state) {
|
|
391
|
-
var _currentPluginState$s, _api$connectivity2, _api$editorViewMode, _api$userIntent, _api$focus;
|
|
392
490
|
var currentPluginState = syncedBlockPluginKey.getState(state);
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
var doc = state.doc;
|
|
396
|
-
|
|
397
|
-
// Lazy-init: when no synced block exists in the doc, skip the
|
|
398
|
-
// `descendants` walk and the 4 shared-state reads below. The
|
|
399
|
-
// selection decoration set is the only thing that can be
|
|
400
|
-
// non-empty in this state.
|
|
401
|
-
if (currentPluginState && !currentPluginState.hasSyncedBlocks && expValEquals('editor_synced_block_perf', 'isEnabled', true)) {
|
|
402
|
-
return selectionDecorationSet;
|
|
491
|
+
if (!currentPluginState) {
|
|
492
|
+
return DecorationSet.empty;
|
|
403
493
|
}
|
|
404
|
-
var
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if (syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
418
|
-
viewModeDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
419
|
-
class: SyncBlockStateCssClassName.viewModeClassName
|
|
420
|
-
}));
|
|
421
|
-
}
|
|
422
|
-
if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
423
|
-
loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
424
|
-
class: SyncBlockStateCssClassName.creationLoadingClassName
|
|
425
|
-
}));
|
|
494
|
+
var selectionDecorationSet = currentPluginState.selectionDecorationSet,
|
|
495
|
+
statusDecorationSet = currentPluginState.statusDecorationSet,
|
|
496
|
+
docHasSyncedBlocks = currentPluginState.hasSyncedBlocks;
|
|
497
|
+
|
|
498
|
+
// When the perf gate is ON, both `selectionDecorationSet` and
|
|
499
|
+
// `statusDecorationSet` are maintained in plugin state by
|
|
500
|
+
// `apply()`. The `decorations` prop is now an O(1) merge of
|
|
501
|
+
// the two cached sets — no `doc.descendants()` walk, no
|
|
502
|
+
// shared-state reads.
|
|
503
|
+
if (expValEquals('editor_synced_block_perf', 'isEnabled', true)) {
|
|
504
|
+
var _api$focus$sharedStat, _api$focus;
|
|
505
|
+
if (!docHasSyncedBlocks) {
|
|
506
|
+
return selectionDecorationSet;
|
|
426
507
|
}
|
|
427
508
|
|
|
428
|
-
//
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
509
|
+
// Focus state is read live here (single cheap read) because
|
|
510
|
+
// it only gates whether selection decorations are included —
|
|
511
|
+
// it does not affect the status decoration set and can change
|
|
512
|
+
// within the same transaction cycle.
|
|
513
|
+
var hasFocus = (_api$focus$sharedStat = api === null || api === void 0 || (_api$focus = api.focus) === null || _api$focus === void 0 || (_api$focus = _api$focus.sharedState) === null || _api$focus === void 0 || (_api$focus = _api$focus.currentState()) === null || _api$focus === void 0 ? void 0 : _api$focus.hasFocus) !== null && _api$focus$sharedStat !== void 0 ? _api$focus$sharedStat : true;
|
|
514
|
+
|
|
515
|
+
// Merge selection + status decorations.
|
|
516
|
+
// When the editor is unfocused,
|
|
517
|
+
// omit selection decorations (matches old behaviour).
|
|
518
|
+
var statusDecorations = statusDecorationSet.find();
|
|
519
|
+
if (statusDecorations.length === 0) {
|
|
520
|
+
return hasFocus ? selectionDecorationSet : DecorationSet.empty;
|
|
521
|
+
} else {
|
|
522
|
+
return hasFocus ? selectionDecorationSet.add(state.doc, statusDecorations) : statusDecorationSet;
|
|
433
523
|
}
|
|
434
|
-
});
|
|
435
|
-
if (api !== null && api !== void 0 && (_api$focus = api.focus) !== null && _api$focus !== void 0 && (_api$focus = _api$focus.sharedState) !== null && _api$focus !== void 0 && (_api$focus = _api$focus.currentState()) !== null && _api$focus !== void 0 && _api$focus.hasFocus || !editorExperiment('platform_synced_block_patch_6', true, {
|
|
436
|
-
exposure: true
|
|
437
|
-
})) {
|
|
438
|
-
// Don't show decorations if the editor is not focused
|
|
439
|
-
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
440
524
|
} else {
|
|
441
|
-
|
|
525
|
+
var _api$connectivity4, _api$editorViewMode3, _api$userIntent3, _api$focus2;
|
|
526
|
+
// --- Legacy path (perf gate OFF) ---
|
|
527
|
+
// Full `doc.descendants()` walk every transaction. Preserved
|
|
528
|
+
// for safe rollback.
|
|
529
|
+
var _syncBlockStore = currentPluginState.syncBlockStore;
|
|
530
|
+
var doc = state.doc;
|
|
531
|
+
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);
|
|
532
|
+
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';
|
|
533
|
+
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';
|
|
534
|
+
var offlineDecorations = [];
|
|
535
|
+
var viewModeDecorations = [];
|
|
536
|
+
var loadingDecorations = [];
|
|
537
|
+
var dragDecorations = [];
|
|
538
|
+
state.doc.descendants(function (node, pos) {
|
|
539
|
+
if (node.type.name === 'bodiedSyncBlock' && isOffline) {
|
|
540
|
+
offlineDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
541
|
+
class: SyncBlockStateCssClassName.disabledClassName
|
|
542
|
+
}));
|
|
543
|
+
}
|
|
544
|
+
if (_syncBlockStore.isSyncBlock(node) && isViewMode) {
|
|
545
|
+
viewModeDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
546
|
+
class: SyncBlockStateCssClassName.viewModeClassName
|
|
547
|
+
}));
|
|
548
|
+
}
|
|
549
|
+
if (node.type.name === 'bodiedSyncBlock' && _syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId)) {
|
|
550
|
+
loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
551
|
+
class: SyncBlockStateCssClassName.creationLoadingClassName
|
|
552
|
+
}));
|
|
553
|
+
}
|
|
554
|
+
if (isDragging && _syncBlockStore.isSyncBlock(node)) {
|
|
555
|
+
dragDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
556
|
+
class: SyncBlockStateCssClassName.draggingClassName
|
|
557
|
+
}));
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
if (api !== null && api !== void 0 && (_api$focus2 = api.focus) !== null && _api$focus2 !== void 0 && (_api$focus2 = _api$focus2.sharedState) !== null && _api$focus2 !== void 0 && (_api$focus2 = _api$focus2.currentState()) !== null && _api$focus2 !== void 0 && _api$focus2.hasFocus) {
|
|
561
|
+
return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
562
|
+
} else {
|
|
563
|
+
return DecorationSet.empty.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations).add(doc, dragDecorations);
|
|
564
|
+
}
|
|
442
565
|
}
|
|
443
566
|
},
|
|
444
567
|
handleClickOn: createSelectionClickHandler(['bodiedSyncBlock'], function (target) {
|
|
@@ -496,7 +619,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
496
619
|
}
|
|
497
620
|
},
|
|
498
621
|
filterTransaction: function filterTransaction(tr, state) {
|
|
499
|
-
var _api$
|
|
622
|
+
var _api$editorViewMode4, _api$connectivity5;
|
|
500
623
|
// Lazy-init: when no synced block currently exists in the doc and the
|
|
501
624
|
// transaction does not insert one, all downstream filter logic is a
|
|
502
625
|
// no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
|
|
@@ -507,11 +630,11 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
507
630
|
return true;
|
|
508
631
|
}
|
|
509
632
|
}
|
|
510
|
-
var viewMode = api === null || api === void 0 || (_api$
|
|
633
|
+
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;
|
|
511
634
|
if (viewMode === 'view' && fg('platform_synced_block_patch_8')) {
|
|
512
635
|
return true;
|
|
513
636
|
}
|
|
514
|
-
var isOffline = isOfflineMode(api === null || api === void 0 || (_api$
|
|
637
|
+
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);
|
|
515
638
|
var isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
|
|
516
639
|
|
|
517
640
|
// Track newly added reference sync blocks before processing the transaction
|
|
@@ -586,7 +709,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
586
709
|
});
|
|
587
710
|
},
|
|
588
711
|
appendTransaction: function appendTransaction(trs, oldState, newState) {
|
|
589
|
-
var _api$
|
|
712
|
+
var _api$editorViewMode5;
|
|
590
713
|
// Lazy-init: when neither the previous nor the new state contains a
|
|
591
714
|
// synced block (and none of the dispatched transactions inserts one),
|
|
592
715
|
// skip all downstream work. This is the hot path on the ~99.97% of
|
|
@@ -599,7 +722,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
599
722
|
return null;
|
|
600
723
|
}
|
|
601
724
|
}
|
|
602
|
-
var viewMode = api === null || api === void 0 || (_api$
|
|
725
|
+
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;
|
|
603
726
|
if (viewMode === 'view' && fg('platform_synced_block_patch_8')) {
|
|
604
727
|
return null;
|
|
605
728
|
}
|
|
@@ -21,8 +21,25 @@ type SyncedBlockPluginState = {
|
|
|
21
21
|
*/
|
|
22
22
|
hasSyncedBlocks: boolean;
|
|
23
23
|
hasUnsavedBodiedSyncBlockChanges?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Cached previous values for shared-state signals. Used inside `apply()` to
|
|
26
|
+
* detect when a status change requires a full rebuild of `statusDecorationSet`
|
|
27
|
+
* instead of a cheap `map()` call. Only meaningful when
|
|
28
|
+
* `editor_synced_block_perf` is ON.
|
|
29
|
+
*/
|
|
30
|
+
prevIsDragging: boolean;
|
|
31
|
+
prevIsOffline: boolean;
|
|
32
|
+
prevIsViewMode: boolean;
|
|
24
33
|
retryCreationPosMap: RetryCreationPosMap;
|
|
25
34
|
selectionDecorationSet: DecorationSet;
|
|
35
|
+
/**
|
|
36
|
+
* Cached decoration set for sync-block status decorations (offline overlay,
|
|
37
|
+
* view-mode class, creation-loading spinner, drag border). When the perf
|
|
38
|
+
* gate is ON this is computed in `apply()` and mapped through edits so the
|
|
39
|
+
* `decorations` prop becomes an O(1) lookup instead of a full
|
|
40
|
+
* `doc.descendants()` walk every transaction (see EDITOR-6930).
|
|
41
|
+
*/
|
|
42
|
+
statusDecorationSet: DecorationSet;
|
|
26
43
|
syncBlockStore: SyncBlockStoreManager;
|
|
27
44
|
};
|
|
28
45
|
export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams, syncBlockStore: SyncBlockStoreManager, api?: ExtractInjectionAPI<SyncedBlockPlugin>) => SafePlugin<SyncedBlockPluginState>;
|
|
@@ -21,8 +21,25 @@ type SyncedBlockPluginState = {
|
|
|
21
21
|
*/
|
|
22
22
|
hasSyncedBlocks: boolean;
|
|
23
23
|
hasUnsavedBodiedSyncBlockChanges?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Cached previous values for shared-state signals. Used inside `apply()` to
|
|
26
|
+
* detect when a status change requires a full rebuild of `statusDecorationSet`
|
|
27
|
+
* instead of a cheap `map()` call. Only meaningful when
|
|
28
|
+
* `editor_synced_block_perf` is ON.
|
|
29
|
+
*/
|
|
30
|
+
prevIsDragging: boolean;
|
|
31
|
+
prevIsOffline: boolean;
|
|
32
|
+
prevIsViewMode: boolean;
|
|
24
33
|
retryCreationPosMap: RetryCreationPosMap;
|
|
25
34
|
selectionDecorationSet: DecorationSet;
|
|
35
|
+
/**
|
|
36
|
+
* Cached decoration set for sync-block status decorations (offline overlay,
|
|
37
|
+
* view-mode class, creation-loading spinner, drag border). When the perf
|
|
38
|
+
* gate is ON this is computed in `apply()` and mapped through edits so the
|
|
39
|
+
* `decorations` prop becomes an O(1) lookup instead of a full
|
|
40
|
+
* `doc.descendants()` walk every transaction (see EDITOR-6930).
|
|
41
|
+
*/
|
|
42
|
+
statusDecorationSet: DecorationSet;
|
|
26
43
|
syncBlockStore: SyncBlockStoreManager;
|
|
27
44
|
};
|
|
28
45
|
export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams, syncBlockStore: SyncBlockStoreManager, api?: ExtractInjectionAPI<SyncedBlockPlugin>) => SafePlugin<SyncedBlockPluginState>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-synced-block",
|
|
3
|
-
"version": "8.2.
|
|
3
|
+
"version": "8.2.9",
|
|
4
4
|
"description": "SyncedBlock plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
"@atlaskit/icon-lab": "^6.7.0",
|
|
51
51
|
"@atlaskit/logo": "^20.1.0",
|
|
52
52
|
"@atlaskit/lozenge": "^13.8.0",
|
|
53
|
-
"@atlaskit/modal-dialog": "^
|
|
53
|
+
"@atlaskit/modal-dialog": "^15.0.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": "^77.
|
|
57
|
+
"@atlaskit/tmp-editor-statsig": "^77.1.0",
|
|
58
58
|
"@atlaskit/tokens": "13.0.3",
|
|
59
59
|
"@atlaskit/tooltip": "^22.0.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.21.0",
|
|
68
68
|
"react": "^18.2.0",
|
|
69
69
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
70
70
|
},
|
package/afm-jira/tsconfig.json
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../../../tsconfig.local-consumption.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"target": "es5",
|
|
5
|
-
"outDir": "../../../../../jira/tsDist/@atlaskit__editor-plugin-synced-block/app",
|
|
6
|
-
"rootDir": "../",
|
|
7
|
-
"composite": true,
|
|
8
|
-
"noCheck": true
|
|
9
|
-
},
|
|
10
|
-
"include": [
|
|
11
|
-
"../src/**/*.ts",
|
|
12
|
-
"../src/**/*.tsx"
|
|
13
|
-
],
|
|
14
|
-
"exclude": [
|
|
15
|
-
"../src/**/__tests__/*",
|
|
16
|
-
"../src/**/*.test.*",
|
|
17
|
-
"../src/**/test.*",
|
|
18
|
-
"../src/**/examples.*",
|
|
19
|
-
"../src/**/examples/*",
|
|
20
|
-
"../src/**/examples/**/*",
|
|
21
|
-
"../src/**/*.stories.*",
|
|
22
|
-
"../src/**/stories/*",
|
|
23
|
-
"../src/**/stories/**/*"
|
|
24
|
-
],
|
|
25
|
-
"references": [
|
|
26
|
-
{
|
|
27
|
-
"path": "../../adf-schema/afm-jira/tsconfig.json"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"path": "../../../design-system/button/afm-jira/tsconfig.json"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"path": "../../../design-system/dropdown-menu/afm-jira/tsconfig.json"
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"path": "../../editor-json-transformer/afm-jira/tsconfig.json"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"path": "../../editor-plugin-analytics/afm-jira/tsconfig.json"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"path": "../../editor-plugin-block-menu/afm-jira/tsconfig.json"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"path": "../../editor-plugin-connectivity/afm-jira/tsconfig.json"
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"path": "../../editor-plugin-content-format/afm-jira/tsconfig.json"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
"path": "../../editor-plugin-decorations/afm-jira/tsconfig.json"
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"path": "../../editor-plugin-floating-toolbar/afm-jira/tsconfig.json"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"path": "../../editor-plugin-focus/afm-jira/tsconfig.json"
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"path": "../../editor-plugin-selection/afm-jira/tsconfig.json"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"path": "../../editor-plugin-user-intent/afm-jira/tsconfig.json"
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"path": "../../editor-prosemirror/afm-jira/tsconfig.json"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"path": "../../editor-shared-styles/afm-jira/tsconfig.json"
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"path": "../../editor-synced-block-provider/afm-jira/tsconfig.json"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"path": "../../editor-toolbar/afm-jira/tsconfig.json"
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"path": "../../../design-system/flag/afm-jira/tsconfig.json"
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"path": "../../../design-system/icon/afm-jira/tsconfig.json"
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"path": "../../../design-system/icon-lab/afm-jira/tsconfig.json"
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
"path": "../../../design-system/logo/afm-jira/tsconfig.json"
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
"path": "../../../design-system/lozenge/afm-jira/tsconfig.json"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"path": "../../../design-system/modal-dialog/afm-jira/tsconfig.json"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"path": "../../../platform/feature-flags/afm-jira/tsconfig.json"
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
"path": "../../../design-system/primitives/afm-jira/tsconfig.json"
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
"path": "../../../design-system/spinner/afm-jira/tsconfig.json"
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
"path": "../../tmp-editor-statsig/afm-jira/tsconfig.json"
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
"path": "../../../design-system/tokens/afm-jira/tsconfig.json"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"path": "../../../design-system/tooltip/afm-jira/tsconfig.json"
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
"path": "../../../design-system/visually-hidden/afm-jira/tsconfig.json"
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"path": "../../editor-common/afm-jira/tsconfig.json"
|
|
118
|
-
}
|
|
119
|
-
]
|
|
120
|
-
}
|