@atlaskit/editor-plugin-synced-block 5.3.13 → 5.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/editor-commands/index.js +7 -5
  3. package/dist/cjs/pm-plugins/main.js +87 -25
  4. package/dist/cjs/pm-plugins/utils/handle-bodied-sync-block-creation.js +141 -0
  5. package/dist/cjs/pm-plugins/utils/track-sync-blocks.js +1 -0
  6. package/dist/cjs/syncedBlockPlugin.js +4 -2
  7. package/dist/cjs/types/index.js +1 -0
  8. package/dist/cjs/ui/DeleteConfirmationModal.js +18 -1
  9. package/dist/cjs/ui/Flag.js +5 -1
  10. package/dist/cjs/ui/floating-toolbar.js +3 -0
  11. package/dist/es2019/editor-commands/index.js +7 -5
  12. package/dist/es2019/pm-plugins/main.js +67 -17
  13. package/dist/es2019/pm-plugins/utils/handle-bodied-sync-block-creation.js +134 -0
  14. package/dist/es2019/pm-plugins/utils/track-sync-blocks.js +1 -0
  15. package/dist/es2019/syncedBlockPlugin.js +4 -2
  16. package/dist/es2019/types/index.js +1 -0
  17. package/dist/es2019/ui/DeleteConfirmationModal.js +18 -1
  18. package/dist/es2019/ui/Flag.js +5 -0
  19. package/dist/es2019/ui/floating-toolbar.js +3 -0
  20. package/dist/esm/editor-commands/index.js +7 -5
  21. package/dist/esm/pm-plugins/main.js +87 -25
  22. package/dist/esm/pm-plugins/utils/handle-bodied-sync-block-creation.js +134 -0
  23. package/dist/esm/pm-plugins/utils/track-sync-blocks.js +1 -0
  24. package/dist/esm/syncedBlockPlugin.js +4 -2
  25. package/dist/esm/types/index.js +1 -0
  26. package/dist/esm/ui/DeleteConfirmationModal.js +18 -1
  27. package/dist/esm/ui/Flag.js +5 -1
  28. package/dist/esm/ui/floating-toolbar.js +3 -0
  29. package/dist/types/pm-plugins/main.d.ts +2 -1
  30. package/dist/types/pm-plugins/utils/handle-bodied-sync-block-creation.d.ts +9 -0
  31. package/dist/types/pm-plugins/utils/handle-bodied-sync-block-removal.d.ts +2 -2
  32. package/dist/types/types/index.d.ts +19 -1
  33. package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -1
  34. package/dist/types-ts4.5/pm-plugins/utils/handle-bodied-sync-block-creation.d.ts +9 -0
  35. package/dist/types-ts4.5/pm-plugins/utils/handle-bodied-sync-block-removal.d.ts +2 -2
  36. package/dist/types-ts4.5/types/index.d.ts +19 -1
  37. package/package.json +4 -1
@@ -1,9 +1,10 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2
5
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
3
6
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
7
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
8
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
8
9
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
9
10
  import { createSelectionClickHandler } from '@atlaskit/editor-common/selection';
@@ -13,15 +14,50 @@ import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
13
14
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
14
15
  import { DecorationSet, Decoration } from '@atlaskit/editor-prosemirror/view';
15
16
  import { convertPMNodesToSyncBlockNodes, rebaseTransaction } from '@atlaskit/editor-synced-block-provider';
17
+ import { fg } from '@atlaskit/platform-feature-flags';
16
18
  import { lazyBodiedSyncBlockView } from '../nodeviews/bodiedLazySyncedBlock';
17
19
  import { SyncBlock as SyncBlockView } from '../nodeviews/syncedBlock';
18
20
  import { FLAG_ID } from '../types';
21
+ import { handleBodiedSyncBlockCreation } from './utils/handle-bodied-sync-block-creation';
19
22
  import { handleBodiedSyncBlockRemoval } from './utils/handle-bodied-sync-block-removal';
20
23
  import { shouldIgnoreDomEvent } from './utils/ignore-dom-event';
21
24
  import { calculateDecorations } from './utils/selection-decorations';
22
25
  import { hasEditInSyncBlock, trackSyncBlocks } from './utils/track-sync-blocks';
23
26
  import { sliceFullyContainsNode } from './utils/utils';
24
27
  export var syncedBlockPluginKey = new PluginKey('syncedBlockPlugin');
28
+ var mapRetryCreationPosMap = function mapRetryCreationPosMap(oldMap, newRetryCreationPos, mapPos) {
29
+ var resourceId = newRetryCreationPos === null || newRetryCreationPos === void 0 ? void 0 : newRetryCreationPos.resourceId;
30
+ var newMap = new Map(oldMap);
31
+ if (resourceId) {
32
+ var pos = newRetryCreationPos.pos;
33
+ if (!pos) {
34
+ newMap.delete(resourceId);
35
+ } else {
36
+ newMap.set(resourceId, pos);
37
+ }
38
+ }
39
+ if (newMap.size === 0) {
40
+ return newMap;
41
+ }
42
+ var _iterator = _createForOfIteratorHelper(newMap.entries()),
43
+ _step;
44
+ try {
45
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
46
+ var _step$value = _slicedToArray(_step.value, 2),
47
+ id = _step$value[0],
48
+ _pos = _step$value[1];
49
+ newMap.set(id, {
50
+ from: mapPos(_pos.from),
51
+ to: mapPos(_pos.to)
52
+ });
53
+ }
54
+ } catch (err) {
55
+ _iterator.e(err);
56
+ } finally {
57
+ _iterator.f();
58
+ }
59
+ return newMap;
60
+ };
25
61
  var showCopiedFlag = function showCopiedFlag(api) {
26
62
  // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
27
63
  setTimeout(function () {
@@ -83,7 +119,8 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
83
119
  return {
84
120
  selectionDecorationSet: calculateDecorations(instance.doc, instance.selection, instance.schema),
85
121
  activeFlag: false,
86
- syncBlockStore: syncBlockStore
122
+ syncBlockStore: syncBlockStore,
123
+ retryCreationPosMap: new Map()
87
124
  };
88
125
  },
89
126
  apply: function apply(tr, currentPluginState, oldEditorState) {
@@ -91,15 +128,22 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
91
128
  var meta = tr.getMeta(syncedBlockPluginKey);
92
129
  var activeFlag = currentPluginState.activeFlag,
93
130
  selectionDecorationSet = currentPluginState.selectionDecorationSet,
94
- bodiedSyncBlockDeletionStatus = currentPluginState.bodiedSyncBlockDeletionStatus;
131
+ bodiedSyncBlockDeletionStatus = currentPluginState.bodiedSyncBlockDeletionStatus,
132
+ retryCreationPosMap = currentPluginState.retryCreationPosMap;
95
133
  var newDecorationSet = selectionDecorationSet.map(tr.mapping, tr.doc);
96
134
  if (!tr.selection.eq(oldEditorState.selection)) {
97
135
  newDecorationSet = calculateDecorations(tr.doc, tr.selection, tr.doc.type.schema);
98
136
  }
137
+ var newRetryCreationPosMap = retryCreationPosMap;
138
+ if (fg('platform_synced_block_patch_1')) {
139
+ var newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
140
+ newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
141
+ }
99
142
  return {
100
143
  activeFlag: (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag,
101
144
  selectionDecorationSet: newDecorationSet,
102
145
  syncBlockStore: syncBlockStore,
146
+ retryCreationPosMap: newRetryCreationPosMap,
103
147
  bodiedSyncBlockDeletionStatus: (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus
104
148
  };
105
149
  }
@@ -129,13 +173,16 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
129
173
  })
130
174
  },
131
175
  decorations: function decorations(state) {
132
- var _syncedBlockPluginKey, _syncedBlockPluginKey2, _api$connectivity, _api$editorViewMode;
133
- var selectionDecorationSet = (_syncedBlockPluginKey = (_syncedBlockPluginKey2 = syncedBlockPluginKey.getState(state)) === null || _syncedBlockPluginKey2 === void 0 ? void 0 : _syncedBlockPluginKey2.selectionDecorationSet) !== null && _syncedBlockPluginKey !== void 0 ? _syncedBlockPluginKey : DecorationSet.empty;
176
+ var _currentPluginState$s, _api$connectivity, _api$editorViewMode;
177
+ var currentPluginState = syncedBlockPluginKey.getState(state);
178
+ var selectionDecorationSet = (_currentPluginState$s = currentPluginState === null || currentPluginState === void 0 ? void 0 : currentPluginState.selectionDecorationSet) !== null && _currentPluginState$s !== void 0 ? _currentPluginState$s : DecorationSet.empty;
179
+ var syncBlockStore = currentPluginState === null || currentPluginState === void 0 ? void 0 : currentPluginState.syncBlockStore;
134
180
  var doc = state.doc;
135
181
  var isOffline = isOfflineMode(api === null || api === void 0 || (_api$connectivity = api.connectivity) === null || _api$connectivity === void 0 || (_api$connectivity = _api$connectivity.sharedState.currentState()) === null || _api$connectivity === void 0 ? void 0 : _api$connectivity.mode);
136
182
  var isViewMode = (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';
137
183
  var offlineDecorations = [];
138
184
  var viewModeDecorations = [];
185
+ var loadingDecorations = [];
139
186
  state.doc.descendants(function (node, pos) {
140
187
  if (node.type.name === 'bodiedSyncBlock' && isOffline) {
141
188
  offlineDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
@@ -147,8 +194,13 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
147
194
  class: SyncBlockStateCssClassName.viewModeClassName
148
195
  }));
149
196
  }
197
+ if (node.type.name === 'bodiedSyncBlock' && syncBlockStore.sourceManager.isPendingCreation(node.attrs.resourceId) && fg('platform_synced_block_patch_1')) {
198
+ loadingDecorations.push(Decoration.node(pos, pos + node.nodeSize, {
199
+ class: SyncBlockStateCssClassName.creationLoadingClassName
200
+ }));
201
+ }
150
202
  });
151
- return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations);
203
+ return selectionDecorationSet.add(doc, offlineDecorations).add(doc, viewModeDecorations).add(doc, loadingDecorations);
152
204
  },
153
205
  handleClickOn: createSelectionClickHandler(['bodiedSyncBlock'], function (target) {
154
206
  return !!target.closest(".".concat(BodiedSyncBlockSharedCssClassName.prefix));
@@ -209,6 +261,12 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
209
261
  var _api$connectivity2;
210
262
  var isOffline = 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);
211
263
  var isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
264
+ var hasNoPendingRequest = fg('platform_synced_block_patch_1') ? false :
265
+ // requireConfirmationBeforeDelete is always true, so this evaluates to false and hence redundant
266
+ !(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.sourceManager.requireConfirmationBeforeDelete()) && !syncBlockStore.sourceManager.hasPendingCreation();
267
+ var isCommitsCreation = fg('platform_synced_block_patch_1') ? false :
268
+ // For patch 1, we don't intercept the insert transaction, hence it's redundant
269
+ Boolean(tr.getMeta('isCommitSyncBlockCreation'));
212
270
 
213
271
  // Track newly added reference sync blocks before processing the transaction
214
272
  if (tr.docChanged && !tr.getMeta('isRemote')) {
@@ -229,7 +287,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
229
287
  // or are from remote (collab) or already confirmed sync block deletion
230
288
  // We only care about local changes that change the document
231
289
  // and are not yet confirmed for sync block deletion
232
- if (!tr.docChanged || !(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.sourceManager.requireConfirmationBeforeDelete()) && !syncBlockStore.sourceManager.hasPendingCreation() || Boolean(tr.getMeta('isRemote')) || Boolean(tr.getMeta('isCommitSyncBlockCreation')) || !isOffline && isConfirmedSyncBlockDeletion) {
290
+ if (!tr.docChanged || hasNoPendingRequest || Boolean(tr.getMeta('isRemote')) || isCommitsCreation || !isOffline && isConfirmedSyncBlockDeletion) {
233
291
  return true;
234
292
  }
235
293
  var _trackSyncBlocks2 = trackSyncBlocks(syncBlockStore.sourceManager.isSourceBlock, tr, state),
@@ -278,18 +336,22 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
278
336
  // After true is returned here and the node is created, we delete the node in the filterTransaction immediately, which cancels out the creation
279
337
  return true;
280
338
  }
281
-
282
- // If there is bodiedSyncBlock node addition and it's waiting for the result of saving the node to backend (syncBlockStore.hasPendingCreation()),
283
- // we need to intercept the transaction and save it in insert callback so that we only insert it to the document when backend call if backend call is successful
284
- // The callback will be evoked by in SourceSyncBlockStoreManager.commitPendingCreation
285
- syncBlockStore.sourceManager.registerCreationCallback(function () {
286
- var _api$core;
287
- api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function () {
288
- return tr.setMeta('isCommitSyncBlockCreation', true);
339
+ if (fg('platform_synced_block_patch_1')) {
340
+ handleBodiedSyncBlockCreation(bodiedSyncBlockAdded, state, api);
341
+ return true;
342
+ } else {
343
+ // If there is bodiedSyncBlock node addition and it's waiting for the result of saving the node to backend (syncBlockStore.hasPendingCreation()),
344
+ // we need to intercept the transaction and save it in insert callback so that we only insert it to the document when backend call if backend call is successful
345
+ // The callback will be evoked by in SourceSyncBlockStoreManager.commitPendingCreation
346
+ syncBlockStore.sourceManager.registerCreationCallback(function () {
347
+ var _api$core;
348
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function () {
349
+ return tr.setMeta('isCommitSyncBlockCreation', true);
350
+ });
351
+ api === null || api === void 0 || api.core.actions.focus();
289
352
  });
290
- api === null || api === void 0 || api.core.actions.focus();
291
- });
292
- return false;
353
+ return false;
354
+ }
293
355
  }
294
356
  } else {
295
357
  var _trackSyncBlocks4 = trackSyncBlocks(function (node) {
@@ -332,11 +394,11 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
332
394
  confirmationTransactionRef.current = rebaseTransaction(confirmationTransactionRef.current, tr, newState);
333
395
  }
334
396
  });
335
- var _iterator = _createForOfIteratorHelper(trs),
336
- _step;
397
+ var _iterator2 = _createForOfIteratorHelper(trs),
398
+ _step2;
337
399
  try {
338
400
  var _loop = function _loop() {
339
- var tr = _step.value;
401
+ var tr = _step2.value;
340
402
  if (!tr.getMeta(pmHistoryPluginKey)) {
341
403
  return 0; // continue
342
404
  }
@@ -357,15 +419,15 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
357
419
  }
358
420
  },
359
421
  _ret;
360
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
422
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
361
423
  _ret = _loop();
362
424
  if (_ret === 0) continue;
363
425
  if (_ret) return _ret.v;
364
426
  }
365
427
  } catch (err) {
366
- _iterator.e(err);
428
+ _iterator2.e(err);
367
429
  } finally {
368
- _iterator.f();
430
+ _iterator2.f();
369
431
  }
370
432
  return null;
371
433
  }
@@ -0,0 +1,134 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
5
+ import { FLAG_ID } from '../../types';
6
+ import { syncedBlockPluginKey } from '../main';
7
+ var onRetry = function onRetry(api, resourceId) {
8
+ return function () {
9
+ var _api$core, _api$core2;
10
+ api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.focus();
11
+ api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 || _api$core2.actions.execute(function (_ref) {
12
+ var _api$syncedBlock, _api$syncedBlock2;
13
+ var tr = _ref.tr;
14
+ var pos = api === null || api === void 0 || (_api$syncedBlock = api.syncedBlock) === null || _api$syncedBlock === void 0 || (_api$syncedBlock = _api$syncedBlock.sharedState.currentState()) === null || _api$syncedBlock === void 0 || (_api$syncedBlock = _api$syncedBlock.retryCreationPosMap) === null || _api$syncedBlock === void 0 ? void 0 : _api$syncedBlock.get(resourceId);
15
+ var from = pos === null || pos === void 0 ? void 0 : pos.from;
16
+ var to = pos === null || pos === void 0 ? void 0 : pos.to;
17
+ if (from === undefined || to === undefined) {
18
+ return tr;
19
+ }
20
+ tr.setSelection(TextSelection.create(tr.doc, from, to)).setMeta(syncedBlockPluginKey, {
21
+ activeFlag: false
22
+ });
23
+ api === null || api === void 0 || (_api$syncedBlock2 = api.syncedBlock) === null || _api$syncedBlock2 === void 0 || _api$syncedBlock2.commands.insertSyncedBlock()({
24
+ tr: tr
25
+ });
26
+ return tr;
27
+ });
28
+ };
29
+ };
30
+ var getRevertCreationPos = function getRevertCreationPos(api, doc, resourceId) {
31
+ var _api$syncedBlock3;
32
+ var retryCreationPos = api === null || api === void 0 || (_api$syncedBlock3 = api.syncedBlock) === null || _api$syncedBlock3 === void 0 || (_api$syncedBlock3 = _api$syncedBlock3.sharedState.currentState()) === null || _api$syncedBlock3 === void 0 || (_api$syncedBlock3 = _api$syncedBlock3.retryCreationPosMap) === null || _api$syncedBlock3 === void 0 ? void 0 : _api$syncedBlock3.get(resourceId);
33
+ if (retryCreationPos) {
34
+ return retryCreationPos;
35
+ }
36
+
37
+ // Fallback to find the positions in case BE call returns before plugin state becomes available
38
+ // which is highly unlikely
39
+ var currentPos;
40
+ doc.descendants(function (node, pos) {
41
+ if (currentPos) {
42
+ return false;
43
+ }
44
+ if (node.type.name === 'bodiedSyncBlock' && resourceId === node.attrs.resourceId) {
45
+ currentPos = {
46
+ from: pos,
47
+ to: pos + node.nodeSize
48
+ };
49
+ return false;
50
+ }
51
+ });
52
+ return currentPos;
53
+ };
54
+ var buildRevertCreationTr = function buildRevertCreationTr(tr, pos) {
55
+ var _tr$doc$nodeAt;
56
+ var content = (_tr$doc$nodeAt = tr.doc.nodeAt(pos.from)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.content;
57
+ if (content) {
58
+ tr.replaceWith(pos.from, pos.to, content);
59
+ var contentFrom = tr.mapping.map(pos.from);
60
+ tr.setSelection(TextSelection.create(tr.doc, contentFrom, contentFrom + content.size));
61
+ } else {
62
+ tr.delete(pos.from, pos.to);
63
+ }
64
+ return tr;
65
+ };
66
+
67
+ /**
68
+ *
69
+ * Save the new bodiedSyncBlock to backend with empty content and handles revert (if failed) and retry flow
70
+ */
71
+ export var handleBodiedSyncBlockCreation = function handleBodiedSyncBlockCreation(bodiedSyncBlockAdded, editorState, api) {
72
+ var syncBlockStore = syncedBlockPluginKey.getState(editorState).syncBlockStore;
73
+ bodiedSyncBlockAdded.forEach(function (node) {
74
+ if (node.from === undefined || node.to === undefined) {
75
+ return;
76
+ }
77
+ var retryCreationPos = {
78
+ from: node.from,
79
+ to: node.to
80
+ };
81
+ var resourceId = node.attrs.resourceId;
82
+ setTimeout(function () {
83
+ var _api$core3;
84
+ api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref2) {
85
+ var tr = _ref2.tr;
86
+ return tr.setMeta(syncedBlockPluginKey, {
87
+ retryCreationPos: {
88
+ resourceId: resourceId,
89
+ pos: retryCreationPos
90
+ }
91
+ });
92
+ });
93
+ });
94
+ syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, function (success) {
95
+ if (success) {
96
+ var _api$core4, _api$core5;
97
+ api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref3) {
98
+ var tr = _ref3.tr;
99
+ return tr.setMeta(syncedBlockPluginKey, {
100
+ retryCreationPos: {
101
+ resourceId: resourceId,
102
+ pos: undefined
103
+ }
104
+ });
105
+ });
106
+ api === null || api === void 0 || (_api$core5 = api.core) === null || _api$core5 === void 0 || _api$core5.actions.focus();
107
+ } else {
108
+ var _api$core6;
109
+ api === null || api === void 0 || (_api$core6 = api.core) === null || _api$core6 === void 0 || _api$core6.actions.execute(function (_ref4) {
110
+ var tr = _ref4.tr;
111
+ var revertCreationPos = getRevertCreationPos(api, tr.doc, resourceId);
112
+ if (!revertCreationPos) {
113
+ return tr;
114
+ }
115
+ var revertTr = buildRevertCreationTr(tr, revertCreationPos);
116
+ return revertTr.setMeta('isConfirmedSyncBlockDeletion', true).setMeta('addToHistory', false).setMeta(syncedBlockPluginKey, {
117
+ activeFlag: {
118
+ id: FLAG_ID.CANNOT_CREATE_SYNC_BLOCK,
119
+ onRetry: onRetry(api, resourceId),
120
+ onDismissed: function onDismissed(tr) {
121
+ return tr.setMeta(syncedBlockPluginKey, _objectSpread(_objectSpread({}, tr.getMeta(syncedBlockPluginKey)), {}, {
122
+ retryCreationPos: {
123
+ resourceId: resourceId,
124
+ pos: undefined
125
+ }
126
+ }));
127
+ }
128
+ }
129
+ });
130
+ });
131
+ }
132
+ }, node.node);
133
+ });
134
+ };
@@ -69,6 +69,7 @@ export var trackSyncBlocks = function trackSyncBlocks(predicate, tr, state) {
69
69
  var syncBlockAttr = node.attrs;
70
70
  syncBlockMapNew[syncBlockAttr.localId] = {
71
71
  attrs: syncBlockAttr,
72
+ node: node,
72
73
  from: offset,
73
74
  to: offset + node.nodeSize
74
75
  };
@@ -143,11 +143,13 @@ export var syncedBlockPlugin = function syncedBlockPlugin(_ref) {
143
143
  var _syncedBlockPluginKey = syncedBlockPluginKey.getState(editorState),
144
144
  activeFlag = _syncedBlockPluginKey.activeFlag,
145
145
  currentSyncBlockStore = _syncedBlockPluginKey.syncBlockStore,
146
- bodiedSyncBlockDeletionStatus = _syncedBlockPluginKey.bodiedSyncBlockDeletionStatus;
146
+ bodiedSyncBlockDeletionStatus = _syncedBlockPluginKey.bodiedSyncBlockDeletionStatus,
147
+ retryCreationPosMap = _syncedBlockPluginKey.retryCreationPosMap;
147
148
  return {
148
149
  activeFlag: activeFlag,
149
150
  syncBlockStore: currentSyncBlockStore,
150
- bodiedSyncBlockDeletionStatus: bodiedSyncBlockDeletionStatus
151
+ bodiedSyncBlockDeletionStatus: bodiedSyncBlockDeletionStatus,
152
+ retryCreationPosMap: retryCreationPosMap
151
153
  };
152
154
  }
153
155
  };
@@ -5,6 +5,7 @@ export var FLAG_ID = /*#__PURE__*/function (FLAG_ID) {
5
5
  FLAG_ID["FAIL_TO_DELETE"] = "fail-to-delete";
6
6
  FLAG_ID["SYNC_BLOCK_COPIED"] = "sync-block-copied";
7
7
  FLAG_ID["UNPUBLISHED_SYNC_BLOCK_PASTED"] = "unpublished-sync-block-pasted";
8
+ FLAG_ID["CANNOT_CREATE_SYNC_BLOCK"] = "cannot-create-sync-block";
8
9
  return FLAG_ID;
9
10
  }({});
10
11
  export var SYNCED_BLOCK_BUTTON_TEST_ID = {
@@ -11,6 +11,7 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
11
11
  import { syncBlockMessages as messages } from '@atlaskit/editor-common/messages';
12
12
  import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
13
13
  import ModalDialog, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
14
+ import { fg } from '@atlaskit/platform-feature-flags';
14
15
  import { Text, Box } from '@atlaskit/primitives/compiled';
15
16
  import Spinner from '@atlaskit/spinner';
16
17
  import { syncedBlockPluginKey } from '../pm-plugins/main';
@@ -30,6 +31,22 @@ var modalContentMap = {
30
31
  confirmButtonLabel: messages.deleteConfirmationModalUnsyncButton
31
32
  }
32
33
  };
34
+ var modalContentMapNew = {
35
+ 'source-block-deleted': {
36
+ titleMultiple: messages.deleteConfirmationModalTitleMultiple,
37
+ titleSingle: messages.deletionConfirmationModalTitleSingle,
38
+ descriptionSingle: messages.deletionConfirmationModalDescriptionNoRef,
39
+ descriptionMultiple: messages.deletionConfirmationModalDescription,
40
+ confirmButtonLabel: messages.deleteConfirmationModalDeleteButton
41
+ },
42
+ 'source-block-unsynced': {
43
+ titleMultiple: messages.unsyncConfirmationModalTitle,
44
+ titleSingle: messages.unsyncConfirmationModalTitle,
45
+ descriptionSingle: messages.unsyncConfirmModalDescriptionSingle,
46
+ descriptionMultiple: messages.unsyncConfirmModalDescriptionMultiple,
47
+ confirmButtonLabel: messages.deleteConfirmationModalUnsyncButton
48
+ }
49
+ };
33
50
  var styles = {
34
51
  spinner: "_1mou1wug _195g1wug"
35
52
  };
@@ -200,7 +217,7 @@ export var DeleteConfirmationModal = function DeleteConfirmationModal(_ref) {
200
217
  }, /*#__PURE__*/React.createElement(Spinner, {
201
218
  size: "large"
202
219
  })) : /*#__PURE__*/React.createElement(ModalContent, {
203
- content: modalContentMap[deleteReason],
220
+ content: fg('platform_synced_block_patch_2') ? modalContentMapNew[deleteReason] : modalContentMap[deleteReason],
204
221
  referenceCount: referenceCount,
205
222
  handleClick: handleClick,
206
223
  formatMessage: formatMessage,
@@ -11,7 +11,7 @@ import StatusSuccessIcon from '@atlaskit/icon/core/status-success';
11
11
  import StatusWarningIcon from '@atlaskit/icon/core/status-warning';
12
12
  import { syncedBlockPluginKey } from '../pm-plugins/main';
13
13
  import { FLAG_ID } from '../types';
14
- var flagMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE, {
14
+ var flagMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE, {
15
15
  title: messages.failToDeleteTitle,
16
16
  description: messages.failToDeleteWhenOfflineDescription,
17
17
  type: 'error'
@@ -34,6 +34,10 @@ var flagMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_d
34
34
  title: messages.unpublishedSyncBlockPastedTitle,
35
35
  description: messages.unpublishedSyncBlockPastedDescription,
36
36
  type: 'info'
37
+ }), FLAG_ID.CANNOT_CREATE_SYNC_BLOCK, {
38
+ title: messages.cannotCreateSyncBlockTitle,
39
+ description: messages.CannotCreateSyncBlockDescription,
40
+ type: 'error'
37
41
  });
38
42
  export var Flag = function Flag(_ref) {
39
43
  var api = _ref.api;
@@ -23,6 +23,9 @@ export var getToolbarConfig = function getToolbarConfig(state, intl, api, syncBl
23
23
  if (!syncBlockObject) {
24
24
  return;
25
25
  }
26
+ if (syncBlockStore.sourceManager.isPendingCreation(syncBlockObject.node.attrs.resourceId) && fg('platform_synced_block_patch_1')) {
27
+ return;
28
+ }
26
29
  var syncBlockInstance = syncBlockStore.referenceManager.getFromCache(syncBlockObject.node.attrs.resourceId);
27
30
  var isUnsyncedBlock = (syncBlockInstance === null || syncBlockInstance === void 0 || (_syncBlockInstance$er = syncBlockInstance.error) === null || _syncBlockInstance$er === void 0 ? void 0 : _syncBlockInstance$er.type) === SyncBlockError.NotFound;
28
31
  var isErroredBlock = syncBlockInstance === null || syncBlockInstance === void 0 ? void 0 : syncBlockInstance.error;
@@ -4,11 +4,12 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
4
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
5
5
  import { type SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
6
6
  import type { SyncedBlockPlugin, SyncedBlockPluginOptions } from '../syncedBlockPluginType';
7
- import { type ActiveFlag, type BodiedSyncBlockDeletionStatus } from '../types';
7
+ import { type ActiveFlag, type BodiedSyncBlockDeletionStatus, type RetryCreationPosMap } from '../types';
8
8
  export declare const syncedBlockPluginKey: PluginKey<any>;
9
9
  type SyncedBlockPluginState = {
10
10
  activeFlag: ActiveFlag;
11
11
  bodiedSyncBlockDeletionStatus?: BodiedSyncBlockDeletionStatus;
12
+ retryCreationPosMap: RetryCreationPosMap;
12
13
  selectionDecorationSet: DecorationSet;
13
14
  syncBlockStore: SyncBlockStoreManager;
14
15
  };
@@ -0,0 +1,9 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import { type EditorState } from '@atlaskit/editor-prosemirror/state';
3
+ import type { SyncedBlockPlugin } from '../../syncedBlockPluginType';
4
+ import { type SyncBlockInfo } from '../../types';
5
+ /**
6
+ *
7
+ * Save the new bodiedSyncBlock to backend with empty content and handles revert (if failed) and retry flow
8
+ */
9
+ export declare const handleBodiedSyncBlockCreation: (bodiedSyncBlockAdded: SyncBlockInfo[], editorState: EditorState, api: ExtractInjectionAPI<SyncedBlockPlugin> | undefined) => void;
@@ -3,7 +3,7 @@ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { DeletionReason, SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
4
4
  import type { SyncedBlockPlugin } from '../../syncedBlockPluginType';
5
5
  import { type SyncBlockInfo } from '../../types';
6
- export type ConfirmationTransactionRef = {
6
+ export type TransactionRef = {
7
7
  current: Transaction | undefined;
8
8
  };
9
- export declare const handleBodiedSyncBlockRemoval: (bodiedSyncBlockRemoved: SyncBlockInfo[], syncBlockStore: SyncBlockStoreManager, api: ExtractInjectionAPI<SyncedBlockPlugin> | undefined, confirmationTransactionRef: ConfirmationTransactionRef, deletionReason: DeletionReason) => boolean;
9
+ export declare const handleBodiedSyncBlockRemoval: (bodiedSyncBlockRemoved: SyncBlockInfo[], syncBlockStore: SyncBlockStoreManager, api: ExtractInjectionAPI<SyncedBlockPlugin> | undefined, confirmationTransactionRef: TransactionRef, deletionReason: DeletionReason) => boolean;
@@ -1,3 +1,4 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
1
2
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
2
3
  import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
3
4
  export declare enum FLAG_ID {
@@ -6,7 +7,8 @@ export declare enum FLAG_ID {
6
7
  CANNOT_CREATE_WHEN_OFFLINE = "cannot-create-when-offline",
7
8
  FAIL_TO_DELETE = "fail-to-delete",
8
9
  SYNC_BLOCK_COPIED = "sync-block-copied",
9
- UNPUBLISHED_SYNC_BLOCK_PASTED = "unpublished-sync-block-pasted"
10
+ UNPUBLISHED_SYNC_BLOCK_PASTED = "unpublished-sync-block-pasted",
11
+ CANNOT_CREATE_SYNC_BLOCK = "cannot-create-sync-block"
10
12
  }
11
13
  type FlagConfig = {
12
14
  id: FLAG_ID;
@@ -15,6 +17,15 @@ type FlagConfig = {
15
17
  };
16
18
  export type BodiedSyncBlockDeletionStatus = 'none' | 'processing' | 'completed';
17
19
  export type ActiveFlag = FlagConfig | false;
20
+ type RetryCreationPos = {
21
+ from: number;
22
+ to: number;
23
+ };
24
+ export type RetryCreationPosMap = Map<string, RetryCreationPos>;
25
+ export type RetryCreationPosEntry = {
26
+ pos?: RetryCreationPos;
27
+ resourceId: string;
28
+ };
18
29
  export type SyncedBlockSharedState = {
19
30
  /**
20
31
  * Whether to show a flag (usually for errors, e.g. fail to delete)
@@ -24,6 +35,12 @@ export type SyncedBlockSharedState = {
24
35
  * Whether the plugin is currently saving bodiedSyncBlock deletion to backend
25
36
  */
26
37
  bodiedSyncBlockDeletionStatus?: BodiedSyncBlockDeletionStatus;
38
+ /**
39
+ * Positions of pending creations keyed by resourceId, used for retry/revert flow.
40
+ * When a new bodiedSyncBlock is added, a new entry is added to map for mapping. The entry is removed when creation succeeds or retry option is dismissed.
41
+ *
42
+ */
43
+ retryCreationPosMap?: RetryCreationPosMap;
27
44
  /**
28
45
  * The current sync block store manager, used to manage fetching and updating sync block data
29
46
  */
@@ -36,6 +53,7 @@ export type SyncBlockAttrs = {
36
53
  export type SyncBlockInfo = {
37
54
  attrs: SyncBlockAttrs;
38
55
  from?: number;
56
+ node?: PMNode;
39
57
  to?: number;
40
58
  };
41
59
  export type SyncBlockMap = {
@@ -4,11 +4,12 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
4
4
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
5
5
  import { type SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
6
6
  import type { SyncedBlockPlugin, SyncedBlockPluginOptions } from '../syncedBlockPluginType';
7
- import { type ActiveFlag, type BodiedSyncBlockDeletionStatus } from '../types';
7
+ import { type ActiveFlag, type BodiedSyncBlockDeletionStatus, type RetryCreationPosMap } from '../types';
8
8
  export declare const syncedBlockPluginKey: PluginKey<any>;
9
9
  type SyncedBlockPluginState = {
10
10
  activeFlag: ActiveFlag;
11
11
  bodiedSyncBlockDeletionStatus?: BodiedSyncBlockDeletionStatus;
12
+ retryCreationPosMap: RetryCreationPosMap;
12
13
  selectionDecorationSet: DecorationSet;
13
14
  syncBlockStore: SyncBlockStoreManager;
14
15
  };
@@ -0,0 +1,9 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
+ import { type EditorState } from '@atlaskit/editor-prosemirror/state';
3
+ import type { SyncedBlockPlugin } from '../../syncedBlockPluginType';
4
+ import { type SyncBlockInfo } from '../../types';
5
+ /**
6
+ *
7
+ * Save the new bodiedSyncBlock to backend with empty content and handles revert (if failed) and retry flow
8
+ */
9
+ export declare const handleBodiedSyncBlockCreation: (bodiedSyncBlockAdded: SyncBlockInfo[], editorState: EditorState, api: ExtractInjectionAPI<SyncedBlockPlugin> | undefined) => void;
@@ -3,7 +3,7 @@ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { DeletionReason, SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
4
4
  import type { SyncedBlockPlugin } from '../../syncedBlockPluginType';
5
5
  import { type SyncBlockInfo } from '../../types';
6
- export type ConfirmationTransactionRef = {
6
+ export type TransactionRef = {
7
7
  current: Transaction | undefined;
8
8
  };
9
- export declare const handleBodiedSyncBlockRemoval: (bodiedSyncBlockRemoved: SyncBlockInfo[], syncBlockStore: SyncBlockStoreManager, api: ExtractInjectionAPI<SyncedBlockPlugin> | undefined, confirmationTransactionRef: ConfirmationTransactionRef, deletionReason: DeletionReason) => boolean;
9
+ export declare const handleBodiedSyncBlockRemoval: (bodiedSyncBlockRemoved: SyncBlockInfo[], syncBlockStore: SyncBlockStoreManager, api: ExtractInjectionAPI<SyncedBlockPlugin> | undefined, confirmationTransactionRef: TransactionRef, deletionReason: DeletionReason) => boolean;
@@ -1,3 +1,4 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
1
2
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
2
3
  import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
3
4
  export declare enum FLAG_ID {
@@ -6,7 +7,8 @@ export declare enum FLAG_ID {
6
7
  CANNOT_CREATE_WHEN_OFFLINE = "cannot-create-when-offline",
7
8
  FAIL_TO_DELETE = "fail-to-delete",
8
9
  SYNC_BLOCK_COPIED = "sync-block-copied",
9
- UNPUBLISHED_SYNC_BLOCK_PASTED = "unpublished-sync-block-pasted"
10
+ UNPUBLISHED_SYNC_BLOCK_PASTED = "unpublished-sync-block-pasted",
11
+ CANNOT_CREATE_SYNC_BLOCK = "cannot-create-sync-block"
10
12
  }
11
13
  type FlagConfig = {
12
14
  id: FLAG_ID;
@@ -15,6 +17,15 @@ type FlagConfig = {
15
17
  };
16
18
  export type BodiedSyncBlockDeletionStatus = 'none' | 'processing' | 'completed';
17
19
  export type ActiveFlag = FlagConfig | false;
20
+ type RetryCreationPos = {
21
+ from: number;
22
+ to: number;
23
+ };
24
+ export type RetryCreationPosMap = Map<string, RetryCreationPos>;
25
+ export type RetryCreationPosEntry = {
26
+ pos?: RetryCreationPos;
27
+ resourceId: string;
28
+ };
18
29
  export type SyncedBlockSharedState = {
19
30
  /**
20
31
  * Whether to show a flag (usually for errors, e.g. fail to delete)
@@ -24,6 +35,12 @@ export type SyncedBlockSharedState = {
24
35
  * Whether the plugin is currently saving bodiedSyncBlock deletion to backend
25
36
  */
26
37
  bodiedSyncBlockDeletionStatus?: BodiedSyncBlockDeletionStatus;
38
+ /**
39
+ * Positions of pending creations keyed by resourceId, used for retry/revert flow.
40
+ * When a new bodiedSyncBlock is added, a new entry is added to map for mapping. The entry is removed when creation succeeds or retry option is dismissed.
41
+ *
42
+ */
43
+ retryCreationPosMap?: RetryCreationPosMap;
27
44
  /**
28
45
  * The current sync block store manager, used to manage fetching and updating sync block data
29
46
  */
@@ -36,6 +53,7 @@ export type SyncBlockAttrs = {
36
53
  export type SyncBlockInfo = {
37
54
  attrs: SyncBlockAttrs;
38
55
  from?: number;
56
+ node?: PMNode;
39
57
  to?: number;
40
58
  };
41
59
  export type SyncBlockMap = {