@atlaskit/editor-plugin-synced-block 5.4.5 → 5.4.7

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 (32) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/nodeviews/syncedBlock.js +15 -0
  3. package/dist/cjs/pm-plugins/main.js +38 -67
  4. package/dist/cjs/pm-plugins/utils/track-sync-blocks.js +24 -66
  5. package/dist/cjs/pm-plugins/utils/utils.js +20 -10
  6. package/dist/cjs/syncedBlockPlugin.js +1 -3
  7. package/dist/cjs/types/index.js +1 -0
  8. package/dist/cjs/ui/Flag.js +5 -1
  9. package/dist/cjs/ui/SyncedLocationDropdown.js +11 -20
  10. package/dist/es2019/nodeviews/syncedBlock.js +11 -0
  11. package/dist/es2019/pm-plugins/main.js +39 -68
  12. package/dist/es2019/pm-plugins/utils/track-sync-blocks.js +25 -58
  13. package/dist/es2019/pm-plugins/utils/utils.js +18 -8
  14. package/dist/es2019/syncedBlockPlugin.js +2 -4
  15. package/dist/es2019/types/index.js +1 -0
  16. package/dist/es2019/ui/Flag.js +5 -0
  17. package/dist/es2019/ui/SyncedLocationDropdown.js +12 -21
  18. package/dist/esm/nodeviews/syncedBlock.js +15 -0
  19. package/dist/esm/pm-plugins/main.js +39 -68
  20. package/dist/esm/pm-plugins/utils/track-sync-blocks.js +24 -66
  21. package/dist/esm/pm-plugins/utils/utils.js +19 -9
  22. package/dist/esm/syncedBlockPlugin.js +2 -4
  23. package/dist/esm/types/index.js +1 -0
  24. package/dist/esm/ui/Flag.js +5 -1
  25. package/dist/esm/ui/SyncedLocationDropdown.js +11 -20
  26. package/dist/types/nodeviews/syncedBlock.d.ts +3 -1
  27. package/dist/types/pm-plugins/utils/utils.d.ts +1 -1
  28. package/dist/types/types/index.d.ts +6 -5
  29. package/dist/types-ts4.5/nodeviews/syncedBlock.d.ts +3 -1
  30. package/dist/types-ts4.5/pm-plugins/utils/utils.d.ts +1 -1
  31. package/dist/types-ts4.5/types/index.d.ts +6 -5
  32. package/package.json +3 -6
@@ -19,7 +19,7 @@ import { handleBodiedSyncBlockRemoval } from './utils/handle-bodied-sync-block-r
19
19
  import { shouldIgnoreDomEvent } from './utils/ignore-dom-event';
20
20
  import { calculateDecorations } from './utils/selection-decorations';
21
21
  import { hasEditInSyncBlock, trackSyncBlocks } from './utils/track-sync-blocks';
22
- import { deferDispatch, wasInlineExtensionInsertedInBodiedSyncBlock, sliceFullyContainsNode } from './utils/utils';
22
+ import { deferDispatch, wasExtensionInsertedInBodiedSyncBlock, sliceFullyContainsNode } from './utils/utils';
23
23
  export const syncedBlockPluginKey = new PluginKey('syncedBlockPlugin');
24
24
  const mapRetryCreationPosMap = (oldMap, newRetryCreationPos, mapPos) => {
25
25
  const resourceId = newRetryCreationPos === null || newRetryCreationPos === void 0 ? void 0 : newRetryCreationPos.resourceId;
@@ -56,24 +56,23 @@ const showCopiedFlag = api => {
56
56
  }));
57
57
  });
58
58
  };
59
- const showInlineExtensionInSyncBlockWarningIfNeeded = (tr, state, api, inlineExtensionFlagShown) => {
59
+ const showExtensionInSyncBlockWarningIfNeeded = (tr, state, api, extensionFlagShown) => {
60
60
  var _api$connectivity, _api$connectivity$sha;
61
- if (!fg('platform_synced_block_patch_3')) {
62
- return;
63
- }
64
61
  if (!tr.docChanged || tr.getMeta('isRemote') || Boolean(tr.getMeta(pmHistoryPluginKey)) || isOfflineMode(api === null || api === void 0 ? void 0 : (_api$connectivity = api.connectivity) === null || _api$connectivity === void 0 ? void 0 : (_api$connectivity$sha = _api$connectivity.sharedState.currentState()) === null || _api$connectivity$sha === void 0 ? void 0 : _api$connectivity$sha.mode)) {
65
62
  return;
66
63
  }
67
- const resourceId = wasInlineExtensionInsertedInBodiedSyncBlock(tr, state);
64
+ const resourceId = wasExtensionInsertedInBodiedSyncBlock(tr, state);
68
65
  // Only show the flag on the first instance per sync block (same as UNPUBLISHED_SYNC_BLOCK_PASTED)
69
- if (resourceId && !inlineExtensionFlagShown.has(resourceId)) {
70
- inlineExtensionFlagShown.add(resourceId);
66
+ if (resourceId && !extensionFlagShown.has(resourceId)) {
67
+ extensionFlagShown.add(resourceId);
71
68
  deferDispatch(() => {
72
69
  api === null || api === void 0 ? void 0 : api.core.actions.execute(({
73
70
  tr
74
71
  }) => tr.setMeta(syncedBlockPluginKey, {
75
72
  activeFlag: {
76
- id: FLAG_ID.INLINE_EXTENSION_IN_SYNC_BLOCK
73
+ id: editorExperiment('platform_synced_block_patch_6', true, {
74
+ exposure: true
75
+ }) ? FLAG_ID.EXTENSION_IN_SYNC_BLOCK : FLAG_ID.INLINE_EXTENSION_IN_SYNC_BLOCK
77
76
  }
78
77
  }));
79
78
  });
@@ -94,7 +93,7 @@ const filterTransactionOnline = ({
94
93
  confirmationTransactionRef,
95
94
  bodiedSyncBlockRemoved,
96
95
  bodiedSyncBlockAdded,
97
- inlineExtensionFlagShown
96
+ extensionFlagShown
98
97
  }) => {
99
98
  const {
100
99
  removed: syncBlockRemoved,
@@ -114,31 +113,17 @@ const filterTransactionOnline = ({
114
113
  });
115
114
  });
116
115
  syncBlockAdded.forEach(syncBlock => {
117
- if (fg('platform_synced_block_patch_3')) {
118
- var _api$analytics2, _api$analytics2$actio;
119
- api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : (_api$analytics2$actio = _api$analytics2.actions) === null || _api$analytics2$actio === void 0 ? void 0 : _api$analytics2$actio.fireAnalyticsEvent({
120
- action: ACTION.INSERTED,
121
- actionSubject: ACTION_SUBJECT.DOCUMENT,
122
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK,
123
- attributes: {
124
- resourceId: syncBlock.attrs.resourceId,
125
- blockInstanceId: syncBlock.attrs.localId
126
- },
127
- eventType: EVENT_TYPE.TRACK
128
- });
129
- } else {
130
- var _api$analytics3, _api$analytics3$actio;
131
- api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : (_api$analytics3$actio = _api$analytics3.actions) === null || _api$analytics3$actio === void 0 ? void 0 : _api$analytics3$actio.fireAnalyticsEvent({
132
- action: ACTION.INSERTED,
133
- actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
134
- actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
135
- attributes: {
136
- resourceId: syncBlock.attrs.resourceId,
137
- blockInstanceId: syncBlock.attrs.localId
138
- },
139
- eventType: EVENT_TYPE.OPERATIONAL
140
- });
141
- }
116
+ var _api$analytics2, _api$analytics2$actio;
117
+ api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : (_api$analytics2$actio = _api$analytics2.actions) === null || _api$analytics2$actio === void 0 ? void 0 : _api$analytics2$actio.fireAnalyticsEvent({
118
+ action: ACTION.INSERTED,
119
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
120
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK,
121
+ attributes: {
122
+ resourceId: syncBlock.attrs.resourceId,
123
+ blockInstanceId: syncBlock.attrs.localId
124
+ },
125
+ eventType: EVENT_TYPE.TRACK
126
+ });
142
127
  });
143
128
  if (bodiedSyncBlockRemoved.length > 0) {
144
129
  // eslint-disable-next-line no-param-reassign
@@ -155,7 +140,7 @@ const filterTransactionOnline = ({
155
140
  handleBodiedSyncBlockCreation(bodiedSyncBlockAdded, state, api);
156
141
  return true;
157
142
  }
158
- showInlineExtensionInSyncBlockWarningIfNeeded(tr, state, api, inlineExtensionFlagShown);
143
+ showExtensionInSyncBlockWarningIfNeeded(tr, state, api, extensionFlagShown);
159
144
  return true;
160
145
  };
161
146
  const filterTransactionOffline = ({
@@ -205,7 +190,7 @@ class SyncedBlockPluginContext {
205
190
  });
206
191
  _defineProperty(this, "_isCopyEvent", false);
207
192
  _defineProperty(this, "unpublishedFlagShown", new Set());
208
- _defineProperty(this, "inlineExtensionFlagShown", new Set());
193
+ _defineProperty(this, "extensionFlagShown", new Set());
209
194
  }
210
195
  get isCopyEvent() {
211
196
  return this._isCopyEvent;
@@ -220,7 +205,7 @@ class SyncedBlockPluginContext {
220
205
  }
221
206
  }
222
207
  export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api) => {
223
- var _ctx$confirmationTran, _ctx$unpublishedFlagS, _ctx$inlineExtensionF;
208
+ var _ctx$confirmationTran, _ctx$unpublishedFlagS, _ctx$extensionFlagSho;
224
209
  const {
225
210
  useLongPressSelection = false
226
211
  } = options || {};
@@ -230,7 +215,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
230
215
  };
231
216
  let isCopyEvent = false;
232
217
  const unpublishedFlagShown = (_ctx$unpublishedFlagS = ctx === null || ctx === void 0 ? void 0 : ctx.unpublishedFlagShown) !== null && _ctx$unpublishedFlagS !== void 0 ? _ctx$unpublishedFlagS : new Set();
233
- const inlineExtensionFlagShown = (_ctx$inlineExtensionF = ctx === null || ctx === void 0 ? void 0 : ctx.inlineExtensionFlagShown) !== null && _ctx$inlineExtensionF !== void 0 ? _ctx$inlineExtensionF : new Set();
218
+ const extensionFlagShown = (_ctx$extensionFlagSho = ctx === null || ctx === void 0 ? void 0 : ctx.extensionFlagShown) !== null && _ctx$extensionFlagSho !== void 0 ? _ctx$extensionFlagSho : new Set();
234
219
 
235
220
  // Set up callback to detect unpublished sync blocks when they're fetched
236
221
  syncBlockStore.referenceManager.setOnUnpublishedSyncBlockDetected(resourceId => {
@@ -484,7 +469,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
484
469
  confirmationTransactionRef,
485
470
  bodiedSyncBlockRemoved,
486
471
  bodiedSyncBlockAdded,
487
- inlineExtensionFlagShown
472
+ extensionFlagShown
488
473
  });
489
474
  }
490
475
  if (!isOffline) {
@@ -493,8 +478,8 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
493
478
  added: syncBlockAdded
494
479
  } = trackSyncBlocks(node => node.type.name === 'syncBlock', tr, state);
495
480
  syncBlockRemoved.forEach(syncBlock => {
496
- var _api$analytics4, _api$analytics4$actio;
497
- api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : (_api$analytics4$actio = _api$analytics4.actions) === null || _api$analytics4$actio === void 0 ? void 0 : _api$analytics4$actio.fireAnalyticsEvent({
481
+ var _api$analytics3, _api$analytics3$actio;
482
+ api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : (_api$analytics3$actio = _api$analytics3.actions) === null || _api$analytics3$actio === void 0 ? void 0 : _api$analytics3$actio.fireAnalyticsEvent({
498
483
  action: ACTION.DELETED,
499
484
  actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
500
485
  actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_DELETE,
@@ -506,31 +491,17 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
506
491
  });
507
492
  });
508
493
  syncBlockAdded.forEach(syncBlock => {
509
- if (fg('platform_synced_block_patch_3')) {
510
- var _api$analytics5, _api$analytics5$actio;
511
- api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : (_api$analytics5$actio = _api$analytics5.actions) === null || _api$analytics5$actio === void 0 ? void 0 : _api$analytics5$actio.fireAnalyticsEvent({
512
- action: ACTION.INSERTED,
513
- actionSubject: ACTION_SUBJECT.DOCUMENT,
514
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK,
515
- attributes: {
516
- resourceId: syncBlock.attrs.resourceId,
517
- blockInstanceId: syncBlock.attrs.localId
518
- },
519
- eventType: EVENT_TYPE.TRACK
520
- });
521
- } else {
522
- var _api$analytics6, _api$analytics6$actio;
523
- api === null || api === void 0 ? void 0 : (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : (_api$analytics6$actio = _api$analytics6.actions) === null || _api$analytics6$actio === void 0 ? void 0 : _api$analytics6$actio.fireAnalyticsEvent({
524
- action: ACTION.INSERTED,
525
- actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
526
- actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
527
- attributes: {
528
- resourceId: syncBlock.attrs.resourceId,
529
- blockInstanceId: syncBlock.attrs.localId
530
- },
531
- eventType: EVENT_TYPE.OPERATIONAL
532
- });
533
- }
494
+ var _api$analytics4, _api$analytics4$actio;
495
+ api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : (_api$analytics4$actio = _api$analytics4.actions) === null || _api$analytics4$actio === void 0 ? void 0 : _api$analytics4$actio.fireAnalyticsEvent({
496
+ action: ACTION.INSERTED,
497
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
498
+ actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK,
499
+ attributes: {
500
+ resourceId: syncBlock.attrs.resourceId,
501
+ blockInstanceId: syncBlock.attrs.localId
502
+ },
503
+ eventType: EVENT_TYPE.TRACK
504
+ });
534
505
  });
535
506
  if (bodiedSyncBlockRemoved.length > 0) {
536
507
  confirmationTransactionRef.current = tr;
@@ -546,7 +517,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
546
517
  handleBodiedSyncBlockCreation(bodiedSyncBlockAdded, state, api);
547
518
  return true;
548
519
  }
549
- showInlineExtensionInSyncBlockWarningIfNeeded(tr, state, api, inlineExtensionFlagShown);
520
+ showExtensionInSyncBlockWarningIfNeeded(tr, state, api, extensionFlagShown);
550
521
  return true;
551
522
  }
552
523
  const {
@@ -1,6 +1,5 @@
1
1
  import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
2
2
  import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
3
- import { fg } from '@atlaskit/platform-feature-flags';
4
3
  export const trackSyncBlocks = (predicate, tr, state) => {
5
4
  const removed = {};
6
5
  const added = {};
@@ -15,12 +14,12 @@ export const trackSyncBlocks = (predicate, tr, state) => {
15
14
  const replaceSteps = tr.steps.filter(step => step instanceof ReplaceStep || step instanceof ReplaceAroundStep);
16
15
 
17
16
  // this is a quick check to see if any insertion/deletion of bodiedSyncBlock happened
18
- const hasBodiedSyncBlockChanges = replaceSteps.some((step, idx) => {
17
+ const hasBodiedSyncBlockChanges = replaceSteps.some(step => {
19
18
  const {
20
19
  from,
21
20
  to
22
21
  } = step;
23
- const docAtStep = fg('platform_synced_block_patch_3') ? tr.docs[tr.steps.indexOf(step)] : tr.docs[idx];
22
+ const docAtStep = tr.docs[tr.steps.indexOf(step)];
24
23
  let hasChange = false;
25
24
  if (from !== to) {
26
25
  step.getMap().forEach((oldStart, oldEnd) => {
@@ -102,63 +101,31 @@ export const hasEditInSyncBlock = (tr, state) => {
102
101
  const {
103
102
  bodiedSyncBlock
104
103
  } = state.schema.nodes;
105
- if (fg('platform_synced_block_patch_3')) {
106
- for (let i = 0; i < tr.steps.length; i++) {
107
- var _tr$docs;
108
- const step = tr.steps[i];
109
- const map = step.getMap();
110
- const docAfterStep = (_tr$docs = tr.docs[i + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc;
111
- const positions = [];
104
+ for (let i = 0; i < tr.steps.length; i++) {
105
+ var _tr$docs;
106
+ const step = tr.steps[i];
107
+ const map = step.getMap();
108
+ const docAfterStep = (_tr$docs = tr.docs[i + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc;
109
+ const positions = [];
112
110
 
113
- // Extract positions from steps dynamically based on applicable properties
114
- if ('from' in step && typeof step.from === 'number' && 'to' in step && typeof step.to === 'number') {
115
- const {
116
- from,
117
- to
118
- } = step;
119
- positions.push(from, to);
120
- } else if ('pos' in step && typeof step.pos === 'number') {
121
- const {
122
- pos
123
- } = step;
124
- positions.push(pos);
125
- }
126
- for (const pos of positions) {
127
- const newPos = map.map(pos);
128
- if (newPos >= 0 && newPos <= docAfterStep.content.size) {
129
- if (findParentNodeOfTypeClosestToPos(docAfterStep.resolve(newPos), bodiedSyncBlock)) {
130
- return true;
131
- }
132
- }
133
- }
134
- }
135
- } else {
136
- for (const step of tr.steps) {
137
- const map = step.getMap();
111
+ // Extract positions from steps dynamically based on applicable properties
112
+ if ('from' in step && typeof step.from === 'number' && 'to' in step && typeof step.to === 'number') {
138
113
  const {
139
- doc
140
- } = tr;
141
- const positions = [];
142
-
143
- // Extract positions from steps dynamically based on applicable properties
144
- if ('from' in step && typeof step.from === 'number' && 'to' in step && typeof step.to === 'number') {
145
- const {
146
- from,
147
- to
148
- } = step;
149
- positions.push(from, to);
150
- } else if ('pos' in step && typeof step.pos === 'number') {
151
- const {
152
- pos
153
- } = step;
154
- positions.push(pos);
155
- }
156
- for (const pos of positions) {
157
- const newPos = map.map(pos);
158
- if (newPos >= 0 && newPos <= doc.content.size) {
159
- if (findParentNodeOfTypeClosestToPos(doc.resolve(newPos), bodiedSyncBlock)) {
160
- return true;
161
- }
114
+ from,
115
+ to
116
+ } = step;
117
+ positions.push(from, to);
118
+ } else if ('pos' in step && typeof step.pos === 'number') {
119
+ const {
120
+ pos
121
+ } = step;
122
+ positions.push(pos);
123
+ }
124
+ for (const pos of positions) {
125
+ const newPos = map.map(pos);
126
+ if (newPos >= 0 && newPos <= docAfterStep.content.size) {
127
+ if (findParentNodeOfTypeClosestToPos(docAfterStep.resolve(newPos), bodiedSyncBlock)) {
128
+ return true;
162
129
  }
163
130
  }
164
131
  }
@@ -3,6 +3,7 @@ import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
3
  import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
4
4
  import { findParentNodeOfType, findParentNodeOfTypeClosestToPos, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
5
5
  import { fg } from '@atlaskit/platform-feature-flags';
6
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
6
7
 
7
8
  /**
8
9
  * Defers a callback to the next microtask (when gated) or next macrotask via setTimeout(0).
@@ -91,29 +92,34 @@ export const sliceFullyContainsNode = (slice, node) => {
91
92
  }
92
93
  return true;
93
94
  };
94
- const fragmentContainsInlineExtension = fragment => {
95
+
96
+ // even though extension and bodiedExtension are explicitly not allowed by the schema, they can still be inserted nested inside other nodes e.g. layouts
97
+ const EXTENSION_NODES = new Set(['inlineExtension', 'extension', 'bodiedExtension']);
98
+ const fragmentContainsExtension = fragment => {
95
99
  let found = false;
96
100
  fragment.forEach(node => {
97
101
  if (found) {
98
102
  return;
99
103
  }
100
- if (node.type.name === 'inlineExtension') {
104
+ if (editorExperiment('platform_synced_block_patch_6', true, {
105
+ exposure: true
106
+ }) ? EXTENSION_NODES.has(node.type.name) : node.type.name === 'inlineExtension') {
101
107
  found = true;
102
108
  } else if (node.content.size) {
103
- if (fragmentContainsInlineExtension(node.content)) {
109
+ if (fragmentContainsExtension(node.content)) {
104
110
  found = true;
105
111
  }
106
112
  }
107
113
  });
108
114
  return found;
109
115
  };
110
- const sliceContainsInlineExtension = slice => fragmentContainsInlineExtension(slice.content);
116
+ const sliceContainsExtension = slice => fragmentContainsExtension(slice.content);
111
117
 
112
118
  /**
113
119
  * Returns the resourceId of the bodied sync block where an inline extension was inserted, or undefined.
114
120
  * Used to show a warning flag only on the first instance per sync block.
115
121
  */
116
- export const wasInlineExtensionInsertedInBodiedSyncBlock = (tr, state) => {
122
+ export const wasExtensionInsertedInBodiedSyncBlock = (tr, state) => {
117
123
  if (!tr.docChanged || tr.getMeta('isRemote')) {
118
124
  return undefined;
119
125
  }
@@ -135,7 +141,7 @@ export const wasInlineExtensionInsertedInBodiedSyncBlock = (tr, state) => {
135
141
  continue;
136
142
  }
137
143
  const replaceStep = step;
138
- if (!sliceContainsInlineExtension(replaceStep.slice)) {
144
+ if (!sliceContainsExtension(replaceStep.slice)) {
139
145
  continue;
140
146
  }
141
147
  const docAfterStep = (_docs = docs[i + 1]) !== null && _docs !== void 0 ? _docs : tr.doc;
@@ -158,13 +164,17 @@ export const wasInlineExtensionInsertedInBodiedSyncBlock = (tr, state) => {
158
164
  if (resourceId !== undefined) {
159
165
  return false;
160
166
  }
161
- if (node.type.name === 'inlineExtension') {
167
+ if (editorExperiment('platform_synced_block_patch_6', true, {
168
+ exposure: true
169
+ }) ? EXTENSION_NODES.has(node.type.name) : node.type.name === 'inlineExtension') {
162
170
  const $pos = tr.doc.resolve(pos);
163
171
  const parent = findParentNodeOfTypeClosestToPos($pos, bodiedSyncBlock);
164
172
  if (parent !== null && parent !== void 0 && parent.node.attrs.resourceId) {
165
173
  const mappedPos = tr.mapping.invert().map(pos);
166
174
  const nodeBefore = state.doc.nodeAt(mappedPos);
167
- if (!nodeBefore || nodeBefore.type.name !== 'inlineExtension') {
175
+ if (!nodeBefore || (editorExperiment('platform_synced_block_patch_6', true, {
176
+ exposure: true
177
+ }) ? EXTENSION_NODES.has(nodeBefore.type.name) : nodeBefore.type.name !== 'inlineExtension')) {
168
178
  resourceId = parent.node.attrs.resourceId;
169
179
  return false;
170
180
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { bodiedSyncBlock, syncBlock } from '@atlaskit/adf-schema';
2
+ import { syncBlock, bodiedSyncBlock } from '@atlaskit/adf-schema';
3
3
  import { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
4
4
  import { fg } from '@atlaskit/platform-feature-flags';
5
5
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
@@ -33,9 +33,7 @@ export const syncedBlockPlugin = ({
33
33
  node: syncBlock
34
34
  }, {
35
35
  name: 'bodiedSyncBlock',
36
- node:
37
- // eslint-disable-next-line @atlaskit/platform/no-preconditioning
38
- fg('platform_synced_block_patch_3') && !editorExperiment('platform_synced_block_patch_6', true, {
36
+ node: !editorExperiment('platform_synced_block_patch_6', true, {
39
37
  exposure: true
40
38
  }) ?
41
39
  // delete bodiedSyncBlockNodeWithToDOMFixed when cleaning up platform_synced_block_patch_6
@@ -7,6 +7,7 @@ export let FLAG_ID = /*#__PURE__*/function (FLAG_ID) {
7
7
  FLAG_ID["UNPUBLISHED_SYNC_BLOCK_PASTED"] = "unpublished-sync-block-pasted";
8
8
  FLAG_ID["CANNOT_CREATE_SYNC_BLOCK"] = "cannot-create-sync-block";
9
9
  FLAG_ID["INLINE_EXTENSION_IN_SYNC_BLOCK"] = "inline-extension-in-sync-block";
10
+ FLAG_ID["EXTENSION_IN_SYNC_BLOCK"] = "extension-in-sync-block";
10
11
  return FLAG_ID;
11
12
  }({});
12
13
  export const SYNCED_BLOCK_BUTTON_TEST_ID = {
@@ -44,6 +44,11 @@ const flagMap = {
44
44
  description: messages.CannotCreateSyncBlockDescription,
45
45
  type: 'error'
46
46
  },
47
+ [FLAG_ID.EXTENSION_IN_SYNC_BLOCK]: {
48
+ title: messages.extensionInSyncBlockTitle,
49
+ description: messages.extensionInSyncBlockDescription,
50
+ type: 'error'
51
+ },
47
52
  [FLAG_ID.INLINE_EXTENSION_IN_SYNC_BLOCK]: {
48
53
  title: messages.inlineExtensionInSyncBlockTitle,
49
54
  description: messages.inlineExtensionInSyncBlockDescription,
@@ -19,7 +19,6 @@ import QuotationMarkIcon from '@atlaskit/icon/core/quotation-mark';
19
19
  import StatusErrorIcon from '@atlaskit/icon/core/status-error';
20
20
  import { ConfluenceIcon, JiraIcon, AtlassianIcon } from '@atlaskit/logo';
21
21
  import Lozenge from '@atlaskit/lozenge';
22
- import { fg } from '@atlaskit/platform-feature-flags';
23
22
  import { Box, Text, Inline, Anchor, Stack } from '@atlaskit/primitives/compiled';
24
23
  import Spinner from '@atlaskit/spinner';
25
24
  import Tooltip from '@atlaskit/tooltip';
@@ -73,32 +72,24 @@ const productIconMap = {
73
72
  'jira-work-item': JiraIcon
74
73
  };
75
74
  const subTypeIconMap = {
76
- live: PageLiveDocIcon,
77
- page: PageIcon,
78
- blogpost: QuotationMarkIcon
79
- };
80
- const subTypeIconMapNew = {
81
75
  live: PageLiveDocIcon,
82
76
  page: PageIcon
83
77
  };
84
78
  const getConfluenceSubTypeIcon = (sourceAri, subType) => {
85
- if (fg('platform_synced_block_patch_3')) {
86
- try {
87
- const {
88
- type: pageType
89
- } = getPageIdAndTypeFromConfluencePageAri({
90
- ari: sourceAri
91
- });
92
- if (pageType === 'blogpost') {
93
- return QuotationMarkIcon;
94
- } else {
95
- return subType && subType in subTypeIconMapNew ? subTypeIconMapNew[subType] : PageIcon;
96
- }
97
- } catch {
98
- return PageIcon;
79
+ try {
80
+ const {
81
+ type: pageType
82
+ } = getPageIdAndTypeFromConfluencePageAri({
83
+ ari: sourceAri
84
+ });
85
+ if (pageType === 'blogpost') {
86
+ return QuotationMarkIcon;
87
+ } else {
88
+ return subType && subType in subTypeIconMap ? subTypeIconMap[subType] : PageIcon;
99
89
  }
90
+ } catch {
91
+ return PageIcon;
100
92
  }
101
- return subType && subType in subTypeIconMap ? subTypeIconMap[subType] : PageIcon;
102
93
  };
103
94
  const ProductIcon = ({
104
95
  product
@@ -13,6 +13,7 @@ import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
13
13
  import ReactNodeView from '@atlaskit/editor-common/react-node-view';
14
14
  import { SyncBlockSharedCssClassName, SyncBlockActionsProvider } from '@atlaskit/editor-common/sync-block';
15
15
  import { useFetchSyncBlockData as _useFetchSyncBlockData, useFetchSyncBlockTitle as _useFetchSyncBlockTitle } from '@atlaskit/editor-synced-block-provider';
16
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
16
17
  import { removeSyncedBlockAtPos } from '../editor-commands';
17
18
  import { SyncBlockRendererWrapper } from '../ui/SyncBlockRendererWrapper';
18
19
  export var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
@@ -33,6 +34,20 @@ export var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
33
34
  domRef.classList.add(SyncBlockSharedCssClassName.prefix);
34
35
  return domRef;
35
36
  }
37
+ }, {
38
+ key: "validUpdate",
39
+ value: function validUpdate(currentNode, newNode) {
40
+ // Only consider as the valid update if the localId and resourceId are the same
41
+ // This prevents PM reusing the same node view for different sync block node in live page transition
42
+ return currentNode.attrs.localId === newNode.attrs.localId && currentNode.attrs.resourceId === newNode.attrs.resourceId;
43
+ }
44
+ }, {
45
+ key: "update",
46
+ value: function update(node, decorations, innerDecorations) {
47
+ return _superPropGet(SyncBlock, "update", this, 3)([node, decorations, innerDecorations, editorExperiment('platform_synced_block_patch_6', true, {
48
+ exposure: true
49
+ }) ? this.validUpdate : undefined]);
50
+ }
36
51
  }, {
37
52
  key: "render",
38
53
  value: function render(_ref) {