@atlaskit/editor-plugin-synced-block 5.3.32 → 5.3.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-synced-block
2
2
 
3
+ ## 5.3.34
4
+
5
+ ### Patch Changes
6
+
7
+ - [`6424f86f6390a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6424f86f6390a) -
8
+ Improve Synced Blocks robustness
9
+ - Updated dependencies
10
+
11
+ ## 5.3.33
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
3
17
  ## 5.3.32
4
18
 
5
19
  ### Patch Changes
@@ -153,9 +153,7 @@ var copySyncedBlockReferenceToClipboardInternal = function copySyncedBlockRefere
153
153
  }
154
154
  var domNode = (0, _copyButton.toDOM)(referenceSyncBlockNode, schema);
155
155
  (0, _copyButton.copyDomNode)(domNode, referenceSyncBlockNode.type, selection);
156
-
157
- // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
158
- setTimeout(function () {
156
+ (0, _utils2.deferDispatch)(function () {
159
157
  api === null || api === void 0 || api.core.actions.execute(function (_ref3) {
160
158
  var _api$analytics4;
161
159
  var tr = _ref3.tr;
@@ -175,7 +173,7 @@ var copySyncedBlockReferenceToClipboardInternal = function copySyncedBlockRefere
175
173
  }
176
174
  });
177
175
  });
178
- }, 0);
176
+ });
179
177
  return true;
180
178
  };
181
179
  var editSyncedBlockSource = exports.editSyncedBlockSource = function editSyncedBlockSource(syncBlockStore, api) {
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.syncedBlockPluginKey = exports.createPlugin = void 0;
8
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
8
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
12
  var _analytics = require("@atlaskit/editor-common/analytics");
@@ -24,7 +26,7 @@ var _handleBodiedSyncBlockCreation = require("./utils/handle-bodied-sync-block-c
24
26
  var _handleBodiedSyncBlockRemoval = require("./utils/handle-bodied-sync-block-removal");
25
27
  var _ignoreDomEvent = require("./utils/ignore-dom-event");
26
28
  var _selectionDecorations = require("./utils/selection-decorations");
27
- var _trackSyncBlocks6 = require("./utils/track-sync-blocks");
29
+ var _trackSyncBlocks8 = require("./utils/track-sync-blocks");
28
30
  var _utils2 = require("./utils/utils");
29
31
  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; }
30
32
  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) { (0, _defineProperty2.default)(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; }
@@ -66,8 +68,7 @@ var mapRetryCreationPosMap = function mapRetryCreationPosMap(oldMap, newRetryCre
66
68
  return newMap;
67
69
  };
68
70
  var showCopiedFlag = function showCopiedFlag(api) {
69
- // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
70
- setTimeout(function () {
71
+ (0, _utils2.deferDispatch)(function () {
71
72
  api === null || api === void 0 || api.core.actions.execute(function (_ref) {
72
73
  var tr = _ref.tr;
73
74
  return tr.setMeta(syncedBlockPluginKey, {
@@ -76,7 +77,7 @@ var showCopiedFlag = function showCopiedFlag(api) {
76
77
  }
77
78
  });
78
79
  });
79
- }, 0);
80
+ });
80
81
  };
81
82
  var showInlineExtensionInSyncBlockWarningIfNeeded = function showInlineExtensionInSyncBlockWarningIfNeeded(tr, state, api, inlineExtensionFlagShown) {
82
83
  var _api$connectivity;
@@ -90,8 +91,7 @@ var showInlineExtensionInSyncBlockWarningIfNeeded = function showInlineExtension
90
91
  // Only show the flag on the first instance per sync block (same as UNPUBLISHED_SYNC_BLOCK_PASTED)
91
92
  if (resourceId && !inlineExtensionFlagShown.has(resourceId)) {
92
93
  inlineExtensionFlagShown.add(resourceId);
93
- // Use setTimeout to dispatch in next tick and avoid re-entrant dispatch from filterTransaction
94
- setTimeout(function () {
94
+ (0, _utils2.deferDispatch)(function () {
95
95
  api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
96
96
  var tr = _ref2.tr;
97
97
  return tr.setMeta(syncedBlockPluginKey, {
@@ -100,7 +100,7 @@ var showInlineExtensionInSyncBlockWarningIfNeeded = function showInlineExtension
100
100
  }
101
101
  });
102
102
  });
103
- }, 0);
103
+ });
104
104
  }
105
105
  };
106
106
  var getDeleteReason = function getDeleteReason(tr) {
@@ -110,36 +110,176 @@ var getDeleteReason = function getDeleteReason(tr) {
110
110
  }
111
111
  return reason;
112
112
  };
113
+ var filterTransactionOnline = function filterTransactionOnline(_ref3) {
114
+ var tr = _ref3.tr,
115
+ state = _ref3.state,
116
+ syncBlockStore = _ref3.syncBlockStore,
117
+ api = _ref3.api,
118
+ confirmationTransactionRef = _ref3.confirmationTransactionRef,
119
+ bodiedSyncBlockRemoved = _ref3.bodiedSyncBlockRemoved,
120
+ bodiedSyncBlockAdded = _ref3.bodiedSyncBlockAdded,
121
+ inlineExtensionFlagShown = _ref3.inlineExtensionFlagShown;
122
+ var _trackSyncBlocks = (0, _trackSyncBlocks8.trackSyncBlocks)(function (node) {
123
+ return node.type.name === 'syncBlock';
124
+ }, tr, state),
125
+ syncBlockRemoved = _trackSyncBlocks.removed,
126
+ syncBlockAdded = _trackSyncBlocks.added;
127
+ syncBlockRemoved.forEach(function (syncBlock) {
128
+ var _api$analytics;
129
+ api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.fireAnalyticsEvent({
130
+ action: _analytics.ACTION.DELETED,
131
+ actionSubject: _analytics.ACTION_SUBJECT.SYNCED_BLOCK,
132
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_DELETE,
133
+ attributes: {
134
+ resourceId: syncBlock.attrs.resourceId,
135
+ blockInstanceId: syncBlock.attrs.localId
136
+ },
137
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL
138
+ });
139
+ });
140
+ syncBlockAdded.forEach(function (syncBlock) {
141
+ if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_3')) {
142
+ var _api$analytics2;
143
+ api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.fireAnalyticsEvent({
144
+ action: _analytics.ACTION.INSERTED,
145
+ actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
146
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK,
147
+ attributes: {
148
+ resourceId: syncBlock.attrs.resourceId,
149
+ blockInstanceId: syncBlock.attrs.localId
150
+ },
151
+ eventType: _analytics.EVENT_TYPE.TRACK
152
+ });
153
+ } else {
154
+ var _api$analytics3;
155
+ api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || (_api$analytics3 = _api$analytics3.actions) === null || _api$analytics3 === void 0 || _api$analytics3.fireAnalyticsEvent({
156
+ action: _analytics.ACTION.INSERTED,
157
+ actionSubject: _analytics.ACTION_SUBJECT.SYNCED_BLOCK,
158
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
159
+ attributes: {
160
+ resourceId: syncBlock.attrs.resourceId,
161
+ blockInstanceId: syncBlock.attrs.localId
162
+ },
163
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL
164
+ });
165
+ }
166
+ });
167
+ if (bodiedSyncBlockRemoved.length > 0) {
168
+ // eslint-disable-next-line no-param-reassign
169
+ confirmationTransactionRef.current = tr;
170
+ return (0, _handleBodiedSyncBlockRemoval.handleBodiedSyncBlockRemoval)(bodiedSyncBlockRemoved, syncBlockStore, api, confirmationTransactionRef, getDeleteReason(tr));
171
+ }
172
+ if (bodiedSyncBlockAdded.length > 0) {
173
+ if (tr.getMeta(_utils.pmHistoryPluginKey)) {
174
+ // We don't allow bodiedSyncBlock creation via redo, however, we need to return true here to let transaction through so history can be updated properly.
175
+ // If we simply returns false, creation from redo is blocked as desired, but this results in editor showing redo as possible even though it's not.
176
+ // After true is returned here and the node is created, we delete the node in the filterTransaction immediately, which cancels out the creation
177
+ return true;
178
+ }
179
+ (0, _handleBodiedSyncBlockCreation.handleBodiedSyncBlockCreation)(bodiedSyncBlockAdded, state, api);
180
+ return true;
181
+ }
182
+ showInlineExtensionInSyncBlockWarningIfNeeded(tr, state, api, inlineExtensionFlagShown);
183
+ return true;
184
+ };
185
+ var filterTransactionOffline = function filterTransactionOffline(_ref4) {
186
+ var tr = _ref4.tr,
187
+ state = _ref4.state,
188
+ api = _ref4.api,
189
+ isConfirmedSyncBlockDeletion = _ref4.isConfirmedSyncBlockDeletion,
190
+ bodiedSyncBlockRemoved = _ref4.bodiedSyncBlockRemoved,
191
+ bodiedSyncBlockAdded = _ref4.bodiedSyncBlockAdded;
192
+ var _trackSyncBlocks2 = (0, _trackSyncBlocks8.trackSyncBlocks)(function (node) {
193
+ return node.type.name === 'syncBlock';
194
+ }, tr, state),
195
+ syncBlockRemoved = _trackSyncBlocks2.removed,
196
+ syncBlockAdded = _trackSyncBlocks2.added;
197
+ var errorFlag = false;
198
+ if (isConfirmedSyncBlockDeletion || bodiedSyncBlockRemoved.length > 0 || syncBlockRemoved.length > 0) {
199
+ errorFlag = _types.FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE;
200
+ } else if (bodiedSyncBlockAdded.length > 0 || syncBlockAdded.length > 0) {
201
+ errorFlag = _types.FLAG_ID.CANNOT_CREATE_WHEN_OFFLINE;
202
+ } else if ((0, _trackSyncBlocks8.hasEditInSyncBlock)(tr, state)) {
203
+ errorFlag = _types.FLAG_ID.CANNOT_EDIT_WHEN_OFFLINE;
204
+ }
205
+ if (errorFlag) {
206
+ (0, _utils2.deferDispatch)(function () {
207
+ api === null || api === void 0 || api.core.actions.execute(function (_ref5) {
208
+ var tr = _ref5.tr;
209
+ return tr.setMeta(syncedBlockPluginKey, {
210
+ activeFlag: {
211
+ id: errorFlag
212
+ }
213
+ });
214
+ });
215
+ });
216
+ return false;
217
+ }
218
+ return true;
219
+ };
220
+
221
+ /**
222
+ * Encapsulates mutable state that persists across transactions in the
223
+ * synced block plugin. Replaces module-level closure variables so state
224
+ * is explicitly scoped to a single plugin instance.
225
+ */
226
+ var SyncedBlockPluginContext = /*#__PURE__*/function () {
227
+ function SyncedBlockPluginContext() {
228
+ (0, _classCallCheck2.default)(this, SyncedBlockPluginContext);
229
+ (0, _defineProperty2.default)(this, "confirmationTransactionRef", {
230
+ current: undefined
231
+ });
232
+ (0, _defineProperty2.default)(this, "_isCopyEvent", false);
233
+ (0, _defineProperty2.default)(this, "unpublishedFlagShown", new Set());
234
+ (0, _defineProperty2.default)(this, "inlineExtensionFlagShown", new Set());
235
+ }
236
+ return (0, _createClass2.default)(SyncedBlockPluginContext, [{
237
+ key: "isCopyEvent",
238
+ get: function get() {
239
+ return this._isCopyEvent;
240
+ }
241
+ }, {
242
+ key: "markCopyEvent",
243
+ value: function markCopyEvent() {
244
+ this._isCopyEvent = true;
245
+ }
246
+ }, {
247
+ key: "consumeCopyEvent",
248
+ value: function consumeCopyEvent() {
249
+ var was = this._isCopyEvent;
250
+ this._isCopyEvent = false;
251
+ return was;
252
+ }
253
+ }]);
254
+ }();
113
255
  var createPlugin = exports.createPlugin = function createPlugin(options, pmPluginFactoryParams, syncBlockStore, api) {
114
- var _ref3 = options || {},
115
- _ref3$useLongPressSel = _ref3.useLongPressSelection,
116
- useLongPressSelection = _ref3$useLongPressSel === void 0 ? false : _ref3$useLongPressSel;
117
- var confirmationTransactionRef = {
256
+ var _ctx$confirmationTran, _ctx$unpublishedFlagS, _ctx$inlineExtensionF;
257
+ var _ref6 = options || {},
258
+ _ref6$useLongPressSel = _ref6.useLongPressSelection,
259
+ useLongPressSelection = _ref6$useLongPressSel === void 0 ? false : _ref6$useLongPressSel;
260
+ var ctx = (0, _platformFeatureFlags.fg)('platform_synced_block_patch_5') ? new SyncedBlockPluginContext() : undefined;
261
+ var confirmationTransactionRef = (_ctx$confirmationTran = ctx === null || ctx === void 0 ? void 0 : ctx.confirmationTransactionRef) !== null && _ctx$confirmationTran !== void 0 ? _ctx$confirmationTran : {
118
262
  current: undefined
119
263
  };
120
- // Track if a copy event occurred to distinguish copy from drag and drop
121
264
  var isCopyEvent = false;
122
- // Track which sync blocks have already triggered the unpublished flag
123
- var unpublishedFlagShown = new Set();
124
- // Track which sync blocks have already triggered the inline extension in sync block flag
125
- var inlineExtensionFlagShown = new Set();
265
+ var unpublishedFlagShown = (_ctx$unpublishedFlagS = ctx === null || ctx === void 0 ? void 0 : ctx.unpublishedFlagShown) !== null && _ctx$unpublishedFlagS !== void 0 ? _ctx$unpublishedFlagS : new Set();
266
+ var inlineExtensionFlagShown = (_ctx$inlineExtensionF = ctx === null || ctx === void 0 ? void 0 : ctx.inlineExtensionFlagShown) !== null && _ctx$inlineExtensionF !== void 0 ? _ctx$inlineExtensionF : new Set();
126
267
 
127
268
  // Set up callback to detect unpublished sync blocks when they're fetched
128
269
  syncBlockStore.referenceManager.setOnUnpublishedSyncBlockDetected(function (resourceId) {
129
270
  // Only show the flag once per sync block
130
271
  if (!unpublishedFlagShown.has(resourceId)) {
131
272
  unpublishedFlagShown.add(resourceId);
132
- // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
133
- setTimeout(function () {
134
- api === null || api === void 0 || api.core.actions.execute(function (_ref4) {
135
- var tr = _ref4.tr;
273
+ (0, _utils2.deferDispatch)(function () {
274
+ api === null || api === void 0 || api.core.actions.execute(function (_ref7) {
275
+ var tr = _ref7.tr;
136
276
  return tr.setMeta(syncedBlockPluginKey, {
137
277
  activeFlag: {
138
278
  id: _types.FLAG_ID.UNPUBLISHED_SYNC_BLOCK_PASTED
139
279
  }
140
280
  });
141
281
  });
142
- }, 0);
282
+ });
143
283
  }
144
284
  });
145
285
  return new _safePlugin.SafePlugin({
@@ -182,20 +322,22 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
182
322
  props: {
183
323
  nodeViews: {
184
324
  syncBlock: function syncBlock(node, view, getPos, _decorations) {
185
- // To support SSR, pass `syncBlockStore` here
186
- // and do not use lazy loading.
187
- // We cannot start rendering and then load `syncBlockStore` asynchronously,
188
- // because obtaining it is asynchronous (sharedPluginState.currentState() is delayed).
189
- return new _syncedBlock.SyncBlock({
190
- api: api,
191
- options: options,
192
- node: node,
193
- view: view,
194
- getPos: getPos,
195
- portalProviderAPI: pmPluginFactoryParams.portalProviderAPI,
196
- eventDispatcher: pmPluginFactoryParams.eventDispatcher,
197
- syncBlockStore: syncBlockStore
198
- }).init();
325
+ return (
326
+ // To support SSR, pass `syncBlockStore` here
327
+ // and do not use lazy loading.
328
+ // We cannot start rendering and then load `syncBlockStore` asynchronously,
329
+ // because obtaining it is asynchronous (sharedPluginState.currentState() is delayed).
330
+ new _syncedBlock.SyncBlock({
331
+ api: api,
332
+ options: options,
333
+ node: node,
334
+ view: view,
335
+ getPos: getPos,
336
+ portalProviderAPI: pmPluginFactoryParams.portalProviderAPI,
337
+ eventDispatcher: pmPluginFactoryParams.eventDispatcher,
338
+ syncBlockStore: syncBlockStore
339
+ }).init()
340
+ );
199
341
  },
200
342
  bodiedSyncBlock: (0, _bodiedLazySyncedBlock.lazyBodiedSyncBlockView)({
201
343
  pluginOptions: options,
@@ -246,17 +388,23 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
246
388
  return (0, _ignoreDomEvent.shouldIgnoreDomEvent)(view, event, api);
247
389
  },
248
390
  copy: function copy() {
249
- isCopyEvent = true;
391
+ if (ctx) {
392
+ ctx.markCopyEvent();
393
+ } else {
394
+ isCopyEvent = true;
395
+ }
250
396
  return false;
251
397
  }
252
398
  },
253
- transformCopied: function transformCopied(slice, _ref5) {
254
- var state = _ref5.state;
399
+ transformCopied: function transformCopied(slice, _ref8) {
400
+ var state = _ref8.state;
255
401
  var pluginState = syncedBlockPluginKey.getState(state);
256
402
  var syncBlockStore = pluginState === null || pluginState === void 0 ? void 0 : pluginState.syncBlockStore;
257
403
  var schema = state.schema;
258
- var isCopy = isCopyEvent;
259
- isCopyEvent = false;
404
+ var isCopy = ctx ? ctx.consumeCopyEvent() : isCopyEvent;
405
+ if (!ctx) {
406
+ isCopyEvent = false;
407
+ }
260
408
  if (!syncBlockStore || !isCopy) {
261
409
  return slice;
262
410
  }
@@ -295,11 +443,10 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
295
443
 
296
444
  // Track newly added reference sync blocks before processing the transaction
297
445
  if (tr.docChanged && !tr.getMeta('isRemote')) {
298
- var _trackSyncBlocks = (0, _trackSyncBlocks6.trackSyncBlocks)(function (node) {
446
+ var _trackSyncBlocks3 = (0, _trackSyncBlocks8.trackSyncBlocks)(function (node) {
299
447
  return node.type.name === 'syncBlock';
300
448
  }, tr, state),
301
- added = _trackSyncBlocks.added;
302
- // Mark newly added sync blocks so we can detect unpublished status when data is fetched
449
+ added = _trackSyncBlocks3.added;
303
450
  added.forEach(function (nodeInfo) {
304
451
  var _nodeInfo$attrs;
305
452
  if ((_nodeInfo$attrs = nodeInfo.attrs) !== null && _nodeInfo$attrs !== void 0 && _nodeInfo$attrs.resourceId) {
@@ -307,26 +454,40 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
307
454
  }
308
455
  });
309
456
  }
310
-
311
- // Ignore transactions that don't change the document
312
- // or are from remote (collab) or already confirmed sync block deletion
313
- // We only care about local changes that change the document
314
- // and are not yet confirmed for sync block deletion
315
457
  if (!tr.docChanged || Boolean(tr.getMeta('isRemote')) || !isOffline && isConfirmedSyncBlockDeletion) {
316
458
  return true;
317
459
  }
318
- var _trackSyncBlocks2 = (0, _trackSyncBlocks6.trackSyncBlocks)(syncBlockStore.sourceManager.isSourceBlock, tr, state),
319
- bodiedSyncBlockRemoved = _trackSyncBlocks2.removed,
320
- bodiedSyncBlockAdded = _trackSyncBlocks2.added;
460
+ var _trackSyncBlocks4 = (0, _trackSyncBlocks8.trackSyncBlocks)(syncBlockStore.sourceManager.isSourceBlock, tr, state),
461
+ bodiedSyncBlockRemoved = _trackSyncBlocks4.removed,
462
+ bodiedSyncBlockAdded = _trackSyncBlocks4.added;
463
+ if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_5')) {
464
+ return isOffline ? filterTransactionOffline({
465
+ tr: tr,
466
+ state: state,
467
+ api: api,
468
+ isConfirmedSyncBlockDeletion: isConfirmedSyncBlockDeletion,
469
+ bodiedSyncBlockRemoved: bodiedSyncBlockRemoved,
470
+ bodiedSyncBlockAdded: bodiedSyncBlockAdded
471
+ }) : filterTransactionOnline({
472
+ tr: tr,
473
+ state: state,
474
+ syncBlockStore: syncBlockStore,
475
+ api: api,
476
+ confirmationTransactionRef: confirmationTransactionRef,
477
+ bodiedSyncBlockRemoved: bodiedSyncBlockRemoved,
478
+ bodiedSyncBlockAdded: bodiedSyncBlockAdded,
479
+ inlineExtensionFlagShown: inlineExtensionFlagShown
480
+ });
481
+ }
321
482
  if (!isOffline) {
322
- var _trackSyncBlocks3 = (0, _trackSyncBlocks6.trackSyncBlocks)(function (node) {
483
+ var _trackSyncBlocks5 = (0, _trackSyncBlocks8.trackSyncBlocks)(function (node) {
323
484
  return node.type.name === 'syncBlock';
324
485
  }, tr, state),
325
- syncBlockRemoved = _trackSyncBlocks3.removed,
326
- syncBlockAdded = _trackSyncBlocks3.added;
327
- syncBlockRemoved.forEach(function (syncBlock) {
328
- var _api$analytics;
329
- api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.fireAnalyticsEvent({
486
+ _syncBlockRemoved = _trackSyncBlocks5.removed,
487
+ _syncBlockAdded = _trackSyncBlocks5.added;
488
+ _syncBlockRemoved.forEach(function (syncBlock) {
489
+ var _api$analytics4;
490
+ api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 || (_api$analytics4 = _api$analytics4.actions) === null || _api$analytics4 === void 0 || _api$analytics4.fireAnalyticsEvent({
330
491
  action: _analytics.ACTION.DELETED,
331
492
  actionSubject: _analytics.ACTION_SUBJECT.SYNCED_BLOCK,
332
493
  actionSubjectId: _analytics.ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_DELETE,
@@ -337,10 +498,10 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
337
498
  eventType: _analytics.EVENT_TYPE.OPERATIONAL
338
499
  });
339
500
  });
340
- syncBlockAdded.forEach(function (syncBlock) {
501
+ _syncBlockAdded.forEach(function (syncBlock) {
341
502
  if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_3')) {
342
- var _api$analytics2;
343
- api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || (_api$analytics2 = _api$analytics2.actions) === null || _api$analytics2 === void 0 || _api$analytics2.fireAnalyticsEvent({
503
+ var _api$analytics5;
504
+ api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 || (_api$analytics5 = _api$analytics5.actions) === null || _api$analytics5 === void 0 || _api$analytics5.fireAnalyticsEvent({
344
505
  action: _analytics.ACTION.INSERTED,
345
506
  actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
346
507
  actionSubjectId: _analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK,
@@ -351,8 +512,8 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
351
512
  eventType: _analytics.EVENT_TYPE.TRACK
352
513
  });
353
514
  } else {
354
- var _api$analytics3;
355
- api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || (_api$analytics3 = _api$analytics3.actions) === null || _api$analytics3 === void 0 || _api$analytics3.fireAnalyticsEvent({
515
+ var _api$analytics6;
516
+ api === null || api === void 0 || (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 || (_api$analytics6 = _api$analytics6.actions) === null || _api$analytics6 === void 0 || _api$analytics6.fireAnalyticsEvent({
356
517
  action: _analytics.ACTION.INSERTED,
357
518
  actionSubject: _analytics.ACTION_SUBJECT.SYNCED_BLOCK,
358
519
  actionSubjectId: _analytics.ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
@@ -369,7 +530,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
369
530
  return (0, _handleBodiedSyncBlockRemoval.handleBodiedSyncBlockRemoval)(bodiedSyncBlockRemoved, syncBlockStore, api, confirmationTransactionRef, getDeleteReason(tr));
370
531
  }
371
532
  if (bodiedSyncBlockAdded.length > 0) {
372
- if (Boolean(tr.getMeta(_utils.pmHistoryPluginKey))) {
533
+ if (tr.getMeta(_utils.pmHistoryPluginKey)) {
373
534
  // We don't allow bodiedSyncBlock creation via redo, however, we need to return true here to let transaction through so history can be updated properly.
374
535
  // If we simply returns false, creation from redo is blocked as desired, but this results in editor showing redo as possible even though it's not.
375
536
  // After true is returned here and the node is created, we delete the node in the filterTransaction immediately, which cancels out the creation
@@ -380,36 +541,34 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
380
541
  }
381
542
  showInlineExtensionInSyncBlockWarningIfNeeded(tr, state, api, inlineExtensionFlagShown);
382
543
  return true;
383
- } else {
384
- var _trackSyncBlocks4 = (0, _trackSyncBlocks6.trackSyncBlocks)(function (node) {
385
- return node.type.name === 'syncBlock';
386
- }, tr, state),
387
- _syncBlockRemoved = _trackSyncBlocks4.removed,
388
- _syncBlockAdded = _trackSyncBlocks4.added;
389
- var errorFlag = false;
544
+ }
545
+ var _trackSyncBlocks6 = (0, _trackSyncBlocks8.trackSyncBlocks)(function (node) {
546
+ return node.type.name === 'syncBlock';
547
+ }, tr, state),
548
+ syncBlockRemoved = _trackSyncBlocks6.removed,
549
+ syncBlockAdded = _trackSyncBlocks6.added;
550
+ var errorFlag = false;
390
551
 
391
- // Disable (bodied)syncBlock node deletion/creation/edition in offline mode and trigger an error flag instead
392
- if (isConfirmedSyncBlockDeletion || bodiedSyncBlockRemoved.length > 0 || _syncBlockRemoved.length > 0) {
393
- errorFlag = _types.FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE;
394
- } else if (bodiedSyncBlockAdded.length > 0 || _syncBlockAdded.length > 0) {
395
- errorFlag = _types.FLAG_ID.CANNOT_CREATE_WHEN_OFFLINE;
396
- } else if ((0, _trackSyncBlocks6.hasEditInSyncBlock)(tr, state)) {
397
- errorFlag = _types.FLAG_ID.CANNOT_EDIT_WHEN_OFFLINE;
398
- }
399
- if (errorFlag) {
400
- // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
401
- setTimeout(function () {
402
- api === null || api === void 0 || api.core.actions.execute(function (_ref6) {
403
- var tr = _ref6.tr;
404
- return tr.setMeta(syncedBlockPluginKey, {
405
- activeFlag: {
406
- id: errorFlag
407
- }
408
- });
552
+ // Disable (bodied)syncBlock node deletion/creation/edition in offline mode and trigger an error flag instead
553
+ if (isConfirmedSyncBlockDeletion || bodiedSyncBlockRemoved.length > 0 || syncBlockRemoved.length > 0) {
554
+ errorFlag = _types.FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE;
555
+ } else if (bodiedSyncBlockAdded.length > 0 || syncBlockAdded.length > 0) {
556
+ errorFlag = _types.FLAG_ID.CANNOT_CREATE_WHEN_OFFLINE;
557
+ } else if ((0, _trackSyncBlocks8.hasEditInSyncBlock)(tr, state)) {
558
+ errorFlag = _types.FLAG_ID.CANNOT_EDIT_WHEN_OFFLINE;
559
+ }
560
+ if (errorFlag) {
561
+ (0, _utils2.deferDispatch)(function () {
562
+ api === null || api === void 0 || api.core.actions.execute(function (_ref9) {
563
+ var tr = _ref9.tr;
564
+ return tr.setMeta(syncedBlockPluginKey, {
565
+ activeFlag: {
566
+ id: errorFlag
567
+ }
409
568
  });
410
- }, 0);
411
- return false;
412
- }
569
+ });
570
+ });
571
+ return false;
413
572
  }
414
573
  return true;
415
574
  },
@@ -426,29 +585,27 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
426
585
  try {
427
586
  var _loop = function _loop() {
428
587
  var tr = _step2.value;
429
- if (!tr.getMeta(_utils.pmHistoryPluginKey)) {
430
- return 0; // continue
431
- }
432
- var _trackSyncBlocks5 = (0, _trackSyncBlocks6.trackSyncBlocks)(syncBlockStore.sourceManager.isSourceBlock, tr, oldState),
433
- added = _trackSyncBlocks5.added;
434
- if (added.length > 0) {
435
- // Delete bodiedSyncBlock if it's originated from history, i.e. redo creation
436
- // See filterTransaction above for more details
437
- var _tr = newState.tr;
438
- added.forEach(function (node) {
439
- if (node.from !== undefined && node.to !== undefined) {
440
- _tr.delete(node.from, node.to);
441
- }
442
- });
443
- return {
444
- v: _tr
445
- };
588
+ if (tr.getMeta(_utils.pmHistoryPluginKey)) {
589
+ var _trackSyncBlocks7 = (0, _trackSyncBlocks8.trackSyncBlocks)(syncBlockStore.sourceManager.isSourceBlock, tr, oldState),
590
+ added = _trackSyncBlocks7.added;
591
+ if (added.length > 0) {
592
+ // Delete bodiedSyncBlock if it's originated from history, i.e. redo creation
593
+ // See filterTransaction above for more details
594
+ var _tr = newState.tr;
595
+ added.forEach(function (node) {
596
+ if (node.from !== undefined && node.to !== undefined) {
597
+ _tr.delete(node.from, node.to);
598
+ }
599
+ });
600
+ return {
601
+ v: _tr
602
+ };
603
+ }
446
604
  }
447
605
  },
448
606
  _ret;
449
607
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
450
608
  _ret = _loop();
451
- if (_ret === 0) continue;
452
609
  if (_ret) return _ret.v;
453
610
  }
454
611
  } catch (err) {
@@ -9,6 +9,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
9
9
  var _state = require("@atlaskit/editor-prosemirror/state");
10
10
  var _types = require("../../types");
11
11
  var _main = require("../main");
12
+ var _utils = require("./utils");
12
13
  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; }
13
14
  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) { (0, _defineProperty2.default)(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; }
14
15
  var onRetry = function onRetry(api, resourceId) {
@@ -86,7 +87,7 @@ var handleBodiedSyncBlockCreation = exports.handleBodiedSyncBlockCreation = func
86
87
  to: node.to
87
88
  };
88
89
  var resourceId = node.attrs.resourceId;
89
- setTimeout(function () {
90
+ (0, _utils.deferDispatch)(function () {
90
91
  var _api$core3;
91
92
  api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(function (_ref2) {
92
93
  var tr = _ref2.tr;
@@ -3,11 +3,23 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.wasInlineExtensionInsertedInBodiedSyncBlock = exports.sliceFullyContainsNode = exports.isBodiedSyncBlockNode = exports.findSyncBlockOrBodiedSyncBlock = exports.findSyncBlock = exports.findBodiedSyncBlock = exports.canBeConvertedToSyncBlock = void 0;
6
+ exports.wasInlineExtensionInsertedInBodiedSyncBlock = exports.sliceFullyContainsNode = exports.isBodiedSyncBlockNode = exports.findSyncBlockOrBodiedSyncBlock = exports.findSyncBlock = exports.findBodiedSyncBlock = exports.deferDispatch = exports.canBeConvertedToSyncBlock = void 0;
7
7
  var _selection = require("@atlaskit/editor-common/selection");
8
8
  var _model = require("@atlaskit/editor-prosemirror/model");
9
9
  var _transform = require("@atlaskit/editor-prosemirror/transform");
10
10
  var _utils = require("@atlaskit/editor-prosemirror/utils");
11
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
+ /**
13
+ * Defers a callback to the next microtask (when gated) or next macrotask via setTimeout(0).
14
+ * Used to avoid re-entrant ProseMirror dispatch cycles.
15
+ */
16
+ var deferDispatch = exports.deferDispatch = function deferDispatch(fn) {
17
+ if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_5')) {
18
+ queueMicrotask(fn);
19
+ } else {
20
+ setTimeout(fn, 0);
21
+ }
22
+ };
11
23
  var findSyncBlock = exports.findSyncBlock = function findSyncBlock(schema, selection) {
12
24
  var syncBlock = schema.nodes.syncBlock;
13
25
  return (0, _utils.findSelectedNodeOfType)(syncBlock)(selection);