@atlaskit/editor-plugin-synced-block 5.3.11 → 5.3.13
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 +16 -0
- package/afm-cc/tsconfig.json +0 -3
- package/afm-jira/tsconfig.json +0 -3
- package/afm-products/tsconfig.json +0 -3
- package/dist/cjs/editor-commands/index.js +99 -40
- package/dist/cjs/nodeviews/bodiedSyncedBlock.js +2 -7
- package/dist/cjs/nodeviews/syncedBlock.js +4 -18
- package/dist/cjs/pm-plugins/main.js +34 -43
- package/dist/cjs/pm-plugins/menu-and-toolbar-experiences.js +221 -81
- package/dist/cjs/pm-plugins/utils/track-sync-blocks.js +1 -2
- package/dist/cjs/pm-plugins/utils/utils.js +1 -46
- package/dist/cjs/syncedBlockPlugin.js +5 -7
- package/dist/cjs/types/index.js +5 -1
- package/dist/cjs/ui/CreateSyncedBlockDropdownItem.js +2 -1
- package/dist/cjs/ui/DeleteConfirmationModal.js +4 -20
- package/dist/cjs/ui/SyncBlockLabel.js +4 -10
- package/dist/cjs/ui/SyncBlockRefresher.js +7 -9
- package/dist/cjs/ui/SyncedLocationDropdown.js +32 -6
- package/dist/cjs/ui/floating-toolbar.js +11 -7
- package/dist/es2019/editor-commands/index.js +99 -40
- package/dist/es2019/nodeviews/bodiedSyncedBlock.js +2 -7
- package/dist/es2019/nodeviews/syncedBlock.js +4 -15
- package/dist/es2019/pm-plugins/main.js +33 -42
- package/dist/es2019/pm-plugins/menu-and-toolbar-experiences.js +206 -71
- package/dist/es2019/pm-plugins/utils/track-sync-blocks.js +1 -2
- package/dist/es2019/pm-plugins/utils/utils.js +0 -47
- package/dist/es2019/syncedBlockPlugin.js +4 -5
- package/dist/es2019/types/index.js +5 -1
- package/dist/es2019/ui/CreateSyncedBlockDropdownItem.js +2 -1
- package/dist/es2019/ui/DeleteConfirmationModal.js +4 -20
- package/dist/es2019/ui/SyncBlockLabel.js +4 -10
- package/dist/es2019/ui/SyncBlockRefresher.js +7 -9
- package/dist/es2019/ui/SyncedLocationDropdown.js +30 -6
- package/dist/es2019/ui/floating-toolbar.js +10 -6
- package/dist/esm/editor-commands/index.js +99 -40
- package/dist/esm/nodeviews/bodiedSyncedBlock.js +2 -7
- package/dist/esm/nodeviews/syncedBlock.js +4 -18
- package/dist/esm/pm-plugins/main.js +34 -43
- package/dist/esm/pm-plugins/menu-and-toolbar-experiences.js +221 -81
- package/dist/esm/pm-plugins/utils/track-sync-blocks.js +1 -2
- package/dist/esm/pm-plugins/utils/utils.js +0 -45
- package/dist/esm/syncedBlockPlugin.js +5 -7
- package/dist/esm/types/index.js +5 -1
- package/dist/esm/ui/CreateSyncedBlockDropdownItem.js +2 -1
- package/dist/esm/ui/DeleteConfirmationModal.js +4 -20
- package/dist/esm/ui/SyncBlockLabel.js +4 -10
- package/dist/esm/ui/SyncBlockRefresher.js +7 -9
- package/dist/esm/ui/SyncedLocationDropdown.js +32 -6
- package/dist/esm/ui/floating-toolbar.js +11 -7
- package/dist/types/editor-commands/index.d.ts +3 -2
- package/dist/types/pm-plugins/utils/handle-bodied-sync-block-removal.d.ts +1 -1
- package/dist/types/pm-plugins/utils/utils.d.ts +1 -3
- package/dist/types/syncedBlockPluginType.d.ts +2 -1
- package/dist/types/types/index.d.ts +4 -0
- package/dist/types/ui/SyncedLocationDropdown.d.ts +4 -1
- package/dist/types-ts4.5/editor-commands/index.d.ts +3 -2
- package/dist/types-ts4.5/pm-plugins/utils/handle-bodied-sync-block-removal.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/utils/utils.d.ts +1 -3
- package/dist/types-ts4.5/syncedBlockPluginType.d.ts +2 -1
- package/dist/types-ts4.5/types/index.d.ts +4 -0
- package/dist/types-ts4.5/ui/SyncedLocationDropdown.d.ts +4 -1
- package/package.json +5 -6
|
@@ -7,9 +7,7 @@ import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
|
7
7
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
8
8
|
import { DecorationSet, Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
9
9
|
import { convertPMNodesToSyncBlockNodes, rebaseTransaction } from '@atlaskit/editor-synced-block-provider';
|
|
10
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
11
10
|
import { lazyBodiedSyncBlockView } from '../nodeviews/bodiedLazySyncedBlock';
|
|
12
|
-
import { lazySyncBlockView } from '../nodeviews/lazySyncedBlock';
|
|
13
11
|
import { SyncBlock as SyncBlockView } from '../nodeviews/syncedBlock';
|
|
14
12
|
import { FLAG_ID } from '../types';
|
|
15
13
|
import { handleBodiedSyncBlockRemoval } from './utils/handle-bodied-sync-block-removal';
|
|
@@ -52,7 +50,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
52
50
|
const unpublishedFlagShown = new Set();
|
|
53
51
|
|
|
54
52
|
// Set up callback to detect unpublished sync blocks when they're fetched
|
|
55
|
-
|
|
53
|
+
syncBlockStore.referenceManager.setOnUnpublishedSyncBlockDetected(resourceId => {
|
|
56
54
|
// Only show the flag once per sync block
|
|
57
55
|
if (!unpublishedFlagShown.has(resourceId)) {
|
|
58
56
|
unpublishedFlagShown.add(resourceId);
|
|
@@ -104,7 +102,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
104
102
|
},
|
|
105
103
|
props: {
|
|
106
104
|
nodeViews: {
|
|
107
|
-
syncBlock:
|
|
105
|
+
syncBlock: (node, view, getPos, _decorations) => {
|
|
108
106
|
// To support SSR, pass `syncBlockStore` here
|
|
109
107
|
// and do not use lazy loading.
|
|
110
108
|
// We cannot start rendering and then load `syncBlockStore` asynchronously,
|
|
@@ -119,11 +117,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
119
117
|
eventDispatcher: pmPluginFactoryParams.eventDispatcher,
|
|
120
118
|
syncBlockStore: syncBlockStore
|
|
121
119
|
}).init();
|
|
122
|
-
}
|
|
123
|
-
options,
|
|
124
|
-
pmPluginFactoryParams,
|
|
125
|
-
api
|
|
126
|
-
}),
|
|
120
|
+
},
|
|
127
121
|
bodiedSyncBlock: lazyBodiedSyncBlockView({
|
|
128
122
|
pluginOptions: options,
|
|
129
123
|
pmPluginFactoryParams,
|
|
@@ -217,7 +211,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
217
211
|
const isConfirmedSyncBlockDeletion = Boolean(tr.getMeta('isConfirmedSyncBlockDeletion'));
|
|
218
212
|
|
|
219
213
|
// Track newly added reference sync blocks before processing the transaction
|
|
220
|
-
if (tr.docChanged && !tr.getMeta('isRemote')
|
|
214
|
+
if (tr.docChanged && !tr.getMeta('isRemote')) {
|
|
221
215
|
const {
|
|
222
216
|
added
|
|
223
217
|
} = trackSyncBlocks(node => node.type.name === 'syncBlock', tr, state);
|
|
@@ -242,42 +236,39 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
242
236
|
added: bodiedSyncBlockAdded
|
|
243
237
|
} = trackSyncBlocks(syncBlockStore.sourceManager.isSourceBlock, tr, state);
|
|
244
238
|
if (!isOffline) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
eventType: EVENT_TYPE.OPERATIONAL
|
|
261
|
-
});
|
|
239
|
+
const {
|
|
240
|
+
removed: syncBlockRemoved,
|
|
241
|
+
added: syncBlockAdded
|
|
242
|
+
} = trackSyncBlocks(node => node.type.name === 'syncBlock', tr, state);
|
|
243
|
+
syncBlockRemoved.forEach(syncBlock => {
|
|
244
|
+
var _api$analytics, _api$analytics$action;
|
|
245
|
+
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.fireAnalyticsEvent({
|
|
246
|
+
action: ACTION.DELETED,
|
|
247
|
+
actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
|
|
248
|
+
actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_DELETE,
|
|
249
|
+
attributes: {
|
|
250
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
251
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
252
|
+
},
|
|
253
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
262
254
|
});
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
255
|
+
});
|
|
256
|
+
syncBlockAdded.forEach(syncBlock => {
|
|
257
|
+
var _api$analytics2, _api$analytics2$actio;
|
|
258
|
+
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({
|
|
259
|
+
action: ACTION.INSERTED,
|
|
260
|
+
actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
|
|
261
|
+
actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_CREATE,
|
|
262
|
+
attributes: {
|
|
263
|
+
resourceId: syncBlock.attrs.resourceId,
|
|
264
|
+
blockInstanceId: syncBlock.attrs.localId
|
|
265
|
+
},
|
|
266
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
275
267
|
});
|
|
276
|
-
}
|
|
277
|
-
;
|
|
268
|
+
});
|
|
278
269
|
if (bodiedSyncBlockRemoved.length > 0) {
|
|
279
270
|
confirmationTransactionRef.current = tr;
|
|
280
|
-
return handleBodiedSyncBlockRemoval(bodiedSyncBlockRemoved, syncBlockStore, api, confirmationTransactionRef,
|
|
271
|
+
return handleBodiedSyncBlockRemoval(bodiedSyncBlockRemoved, syncBlockStore, api, confirmationTransactionRef, getDeleteReason(tr));
|
|
281
272
|
}
|
|
282
273
|
if (bodiedSyncBlockAdded.length > 0) {
|
|
283
274
|
if (Boolean(tr.getMeta(pmHistoryPluginKey))) {
|
|
@@ -3,6 +3,7 @@ import { ACTION, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
|
|
|
3
3
|
import { Experience, EXPERIENCE_ID, ExperienceCheckDomMutation, ExperienceCheckTimeout, getNodeQuery, getPopupContainerFromEditorView, popupWithNestedElement } from '@atlaskit/editor-common/experiences';
|
|
4
4
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
5
5
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
7
|
import { SYNCED_BLOCK_BUTTON_TEST_ID } from '../types';
|
|
7
8
|
const TIMEOUT_DURATION = 30000;
|
|
8
9
|
const pluginKey = new PluginKey('syncedBlockMenuAndToolbarExperience');
|
|
@@ -21,22 +22,76 @@ export const getMenuAndToolbarExperiencesPlugin = ({
|
|
|
21
22
|
}
|
|
22
23
|
return popupsTargetEl;
|
|
23
24
|
};
|
|
24
|
-
const createSourcePrimaryToolbarExperience =
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const createSourcePrimaryToolbarExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
26
|
+
action: ACTION.SYNCED_BLOCK_CREATE,
|
|
27
|
+
actionSubjectId: ACTION_SUBJECT_ID.PRIMARY_TOOLBAR,
|
|
28
|
+
dispatchAnalyticsEvent,
|
|
29
|
+
checks: [new ExperienceCheckTimeout({
|
|
30
|
+
durationMs: TIMEOUT_DURATION
|
|
31
|
+
}), syncedBlockAddedToDomCheck(refs)]
|
|
27
32
|
});
|
|
28
|
-
const createSourceBlockMenuExperience =
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
const createSourceBlockMenuExperience = new Experience(EXPERIENCE_ID.MENU_ACTION, {
|
|
34
|
+
action: ACTION.SYNCED_BLOCK_CREATE,
|
|
35
|
+
actionSubjectId: ACTION_SUBJECT_ID.BLOCK_MENU,
|
|
36
|
+
dispatchAnalyticsEvent,
|
|
37
|
+
checks: [new ExperienceCheckTimeout({
|
|
38
|
+
durationMs: TIMEOUT_DURATION
|
|
39
|
+
}), syncedBlockAddedToDomCheck(refs)]
|
|
31
40
|
});
|
|
32
|
-
const createSourceQuickInsertMenuExperience =
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
const createSourceQuickInsertMenuExperience = new Experience(EXPERIENCE_ID.MENU_ACTION, {
|
|
42
|
+
action: ACTION.SYNCED_BLOCK_CREATE,
|
|
43
|
+
actionSubjectId: ACTION_SUBJECT_ID.QUICK_INSERT,
|
|
44
|
+
dispatchAnalyticsEvent,
|
|
45
|
+
checks: [new ExperienceCheckTimeout({
|
|
46
|
+
durationMs: TIMEOUT_DURATION
|
|
47
|
+
}), syncedBlockAddedToDomCheck(refs)]
|
|
35
48
|
});
|
|
36
|
-
const deleteReferenceSyncedBlockExperience =
|
|
37
|
-
|
|
38
|
-
|
|
49
|
+
const deleteReferenceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
50
|
+
action: ACTION.REFERENCE_SYNCED_BLOCK_DELETE,
|
|
51
|
+
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
|
|
52
|
+
dispatchAnalyticsEvent,
|
|
53
|
+
checks: [new ExperienceCheckTimeout({
|
|
54
|
+
durationMs: TIMEOUT_DURATION
|
|
55
|
+
}), referenceSyncBlockRemovedFromDomCheck(refs)]
|
|
39
56
|
});
|
|
57
|
+
let unsyncReferenceSyncedBlockExperience;
|
|
58
|
+
let unsyncSourceSyncedBlockExperience;
|
|
59
|
+
let deleteSourceSyncedBlockExperience;
|
|
60
|
+
let syncedLocationsExperience;
|
|
61
|
+
if (fg('platform_synced_block_patch_1')) {
|
|
62
|
+
unsyncReferenceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
63
|
+
action: ACTION.REFERENCE_SYNCED_BLOCK_UNSYNC,
|
|
64
|
+
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
|
|
65
|
+
dispatchAnalyticsEvent,
|
|
66
|
+
checks: [new ExperienceCheckTimeout({
|
|
67
|
+
durationMs: TIMEOUT_DURATION
|
|
68
|
+
}), referenceSyncBlockRemovedFromDomCheck(refs)]
|
|
69
|
+
});
|
|
70
|
+
unsyncSourceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
71
|
+
action: ACTION.SYNCED_BLOCK_UNSYNC,
|
|
72
|
+
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
|
|
73
|
+
dispatchAnalyticsEvent,
|
|
74
|
+
checks: [new ExperienceCheckTimeout({
|
|
75
|
+
durationMs: TIMEOUT_DURATION
|
|
76
|
+
}), syncBlockDeleteConfirmationModalAddedCheck(refs)]
|
|
77
|
+
});
|
|
78
|
+
deleteSourceSyncedBlockExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
79
|
+
action: ACTION.SYNCED_BLOCK_DELETE,
|
|
80
|
+
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
|
|
81
|
+
dispatchAnalyticsEvent,
|
|
82
|
+
checks: [new ExperienceCheckTimeout({
|
|
83
|
+
durationMs: TIMEOUT_DURATION
|
|
84
|
+
}), syncBlockDeleteConfirmationModalAddedCheck(refs)]
|
|
85
|
+
});
|
|
86
|
+
syncedLocationsExperience = new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
87
|
+
action: ACTION.SYNCED_BLOCK_VIEW_SYNCED_LOCATIONS,
|
|
88
|
+
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
|
|
89
|
+
dispatchAnalyticsEvent,
|
|
90
|
+
checks: [new ExperienceCheckTimeout({
|
|
91
|
+
durationMs: TIMEOUT_DURATION
|
|
92
|
+
}), syncedLocationsDropdownOpenedCheck(refs)]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
40
95
|
const unbindClickListener = bind(document, {
|
|
41
96
|
type: 'click',
|
|
42
97
|
listener: event => {
|
|
@@ -52,13 +107,24 @@ export const getMenuAndToolbarExperiencesPlugin = ({
|
|
|
52
107
|
if (!isSyncedBlockButtonId(testId)) {
|
|
53
108
|
return;
|
|
54
109
|
}
|
|
110
|
+
if (button.disabled) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
55
113
|
handleButtonClick({
|
|
56
114
|
testId,
|
|
115
|
+
button,
|
|
57
116
|
createSourcePrimaryToolbarExperience,
|
|
58
117
|
createSourceBlockMenuExperience,
|
|
59
118
|
createSourceQuickInsertMenuExperience,
|
|
60
|
-
deleteReferenceSyncedBlockExperience
|
|
119
|
+
deleteReferenceSyncedBlockExperience,
|
|
120
|
+
unsyncReferenceSyncedBlockExperience,
|
|
121
|
+
unsyncSourceSyncedBlockExperience,
|
|
122
|
+
deleteSourceSyncedBlockExperience,
|
|
123
|
+
syncedLocationsExperience
|
|
61
124
|
});
|
|
125
|
+
},
|
|
126
|
+
options: {
|
|
127
|
+
capture: true
|
|
62
128
|
}
|
|
63
129
|
});
|
|
64
130
|
const unbindKeydownListener = bind(document, {
|
|
@@ -89,6 +155,7 @@ export const getMenuAndToolbarExperiencesPlugin = ({
|
|
|
89
155
|
editorViewEl = editorView.dom;
|
|
90
156
|
return {
|
|
91
157
|
destroy: () => {
|
|
158
|
+
var _deleteSourceSyncedBl, _unsyncReferenceSynce, _unsyncSourceSyncedBl, _syncedLocationsExper;
|
|
92
159
|
createSourcePrimaryToolbarExperience.abort({
|
|
93
160
|
reason: 'editorDestroyed'
|
|
94
161
|
});
|
|
@@ -101,6 +168,18 @@ export const getMenuAndToolbarExperiencesPlugin = ({
|
|
|
101
168
|
deleteReferenceSyncedBlockExperience.abort({
|
|
102
169
|
reason: 'editorDestroyed'
|
|
103
170
|
});
|
|
171
|
+
(_deleteSourceSyncedBl = deleteSourceSyncedBlockExperience) === null || _deleteSourceSyncedBl === void 0 ? void 0 : _deleteSourceSyncedBl.abort({
|
|
172
|
+
reason: 'editorDestroyed'
|
|
173
|
+
});
|
|
174
|
+
(_unsyncReferenceSynce = unsyncReferenceSyncedBlockExperience) === null || _unsyncReferenceSynce === void 0 ? void 0 : _unsyncReferenceSynce.abort({
|
|
175
|
+
reason: 'editorDestroyed'
|
|
176
|
+
});
|
|
177
|
+
(_unsyncSourceSyncedBl = unsyncSourceSyncedBlockExperience) === null || _unsyncSourceSyncedBl === void 0 ? void 0 : _unsyncSourceSyncedBl.abort({
|
|
178
|
+
reason: 'editorDestroyed'
|
|
179
|
+
});
|
|
180
|
+
(_syncedLocationsExper = syncedLocationsExperience) === null || _syncedLocationsExper === void 0 ? void 0 : _syncedLocationsExper.abort({
|
|
181
|
+
reason: 'editorDestroyed'
|
|
182
|
+
});
|
|
104
183
|
unbindClickListener();
|
|
105
184
|
unbindKeydownListener();
|
|
106
185
|
}
|
|
@@ -108,80 +187,64 @@ export const getMenuAndToolbarExperiencesPlugin = ({
|
|
|
108
187
|
}
|
|
109
188
|
});
|
|
110
189
|
};
|
|
111
|
-
const getCreateSourcePrimaryToolbarExperience = ({
|
|
112
|
-
refs,
|
|
113
|
-
dispatchAnalyticsEvent
|
|
114
|
-
}) => {
|
|
115
|
-
return new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
116
|
-
action: ACTION.SYNCED_BLOCK_CREATE,
|
|
117
|
-
actionSubjectId: ACTION_SUBJECT_ID.PRIMARY_TOOLBAR,
|
|
118
|
-
dispatchAnalyticsEvent,
|
|
119
|
-
checks: [new ExperienceCheckTimeout({
|
|
120
|
-
durationMs: TIMEOUT_DURATION
|
|
121
|
-
}), syncedBlockAddedToDomCheck(refs)]
|
|
122
|
-
});
|
|
123
|
-
};
|
|
124
|
-
const getCreateSourceBlockMenuExperience = ({
|
|
125
|
-
refs,
|
|
126
|
-
dispatchAnalyticsEvent
|
|
127
|
-
}) => {
|
|
128
|
-
return new Experience(EXPERIENCE_ID.MENU_ACTION, {
|
|
129
|
-
action: ACTION.SYNCED_BLOCK_CREATE,
|
|
130
|
-
actionSubjectId: ACTION_SUBJECT_ID.BLOCK_MENU,
|
|
131
|
-
dispatchAnalyticsEvent,
|
|
132
|
-
checks: [new ExperienceCheckTimeout({
|
|
133
|
-
durationMs: TIMEOUT_DURATION
|
|
134
|
-
}), syncedBlockAddedToDomCheck(refs)]
|
|
135
|
-
});
|
|
136
|
-
};
|
|
137
|
-
const getCreateSourceQuickInsertMenuExperience = ({
|
|
138
|
-
refs,
|
|
139
|
-
dispatchAnalyticsEvent
|
|
140
|
-
}) => {
|
|
141
|
-
return new Experience(EXPERIENCE_ID.MENU_ACTION, {
|
|
142
|
-
action: ACTION.SYNCED_BLOCK_CREATE,
|
|
143
|
-
actionSubjectId: ACTION_SUBJECT_ID.QUICK_INSERT,
|
|
144
|
-
dispatchAnalyticsEvent,
|
|
145
|
-
checks: [new ExperienceCheckTimeout({
|
|
146
|
-
durationMs: TIMEOUT_DURATION
|
|
147
|
-
}), syncedBlockAddedToDomCheck(refs)]
|
|
148
|
-
});
|
|
149
|
-
};
|
|
150
|
-
const getDeleteReferenceSyncedBlockToolbarExperience = ({
|
|
151
|
-
refs,
|
|
152
|
-
dispatchAnalyticsEvent
|
|
153
|
-
}) => {
|
|
154
|
-
return new Experience(EXPERIENCE_ID.TOOLBAR_ACTION, {
|
|
155
|
-
action: ACTION.REFERENCE_SYNCED_BLOCK_DELETE,
|
|
156
|
-
actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_TOOLBAR,
|
|
157
|
-
dispatchAnalyticsEvent,
|
|
158
|
-
checks: [new ExperienceCheckTimeout({
|
|
159
|
-
durationMs: TIMEOUT_DURATION
|
|
160
|
-
}), referenceSyncBlockRemovedFromDomCheck(refs)]
|
|
161
|
-
});
|
|
162
|
-
};
|
|
163
190
|
const isSyncedBlockButtonId = value => {
|
|
164
191
|
return !!value && syncedBlockButtonIds.has(value);
|
|
165
192
|
};
|
|
166
193
|
const handleButtonClick = ({
|
|
167
194
|
testId,
|
|
195
|
+
button,
|
|
168
196
|
createSourcePrimaryToolbarExperience,
|
|
169
197
|
createSourceBlockMenuExperience,
|
|
170
198
|
createSourceQuickInsertMenuExperience,
|
|
171
|
-
deleteReferenceSyncedBlockExperience
|
|
199
|
+
deleteReferenceSyncedBlockExperience,
|
|
200
|
+
unsyncReferenceSyncedBlockExperience,
|
|
201
|
+
unsyncSourceSyncedBlockExperience,
|
|
202
|
+
deleteSourceSyncedBlockExperience,
|
|
203
|
+
syncedLocationsExperience
|
|
172
204
|
}) => {
|
|
173
205
|
switch (testId) {
|
|
174
206
|
case SYNCED_BLOCK_BUTTON_TEST_ID.primaryToolbarCreate:
|
|
175
|
-
createSourcePrimaryToolbarExperience.start(
|
|
207
|
+
createSourcePrimaryToolbarExperience.start({
|
|
208
|
+
forceRestart: true
|
|
209
|
+
});
|
|
176
210
|
break;
|
|
177
211
|
case SYNCED_BLOCK_BUTTON_TEST_ID.blockMenuCreate:
|
|
178
|
-
createSourceBlockMenuExperience.start(
|
|
212
|
+
createSourceBlockMenuExperience.start({
|
|
213
|
+
forceRestart: true
|
|
214
|
+
});
|
|
179
215
|
break;
|
|
180
216
|
case SYNCED_BLOCK_BUTTON_TEST_ID.quickInsertCreate:
|
|
181
|
-
createSourceQuickInsertMenuExperience.start(
|
|
217
|
+
createSourceQuickInsertMenuExperience.start({
|
|
218
|
+
forceRestart: true
|
|
219
|
+
});
|
|
182
220
|
break;
|
|
183
221
|
case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceDelete:
|
|
184
|
-
deleteReferenceSyncedBlockExperience.start(
|
|
222
|
+
deleteReferenceSyncedBlockExperience.start({
|
|
223
|
+
forceRestart: true
|
|
224
|
+
});
|
|
225
|
+
break;
|
|
226
|
+
case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarReferenceUnsync:
|
|
227
|
+
unsyncReferenceSyncedBlockExperience === null || unsyncReferenceSyncedBlockExperience === void 0 ? void 0 : unsyncReferenceSyncedBlockExperience.start({
|
|
228
|
+
forceRestart: true
|
|
229
|
+
});
|
|
230
|
+
break;
|
|
231
|
+
case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceUnsync:
|
|
232
|
+
unsyncSourceSyncedBlockExperience === null || unsyncSourceSyncedBlockExperience === void 0 ? void 0 : unsyncSourceSyncedBlockExperience.start({
|
|
233
|
+
forceRestart: true
|
|
234
|
+
});
|
|
235
|
+
break;
|
|
236
|
+
case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSourceDelete:
|
|
237
|
+
deleteSourceSyncedBlockExperience === null || deleteSourceSyncedBlockExperience === void 0 ? void 0 : deleteSourceSyncedBlockExperience.start({
|
|
238
|
+
forceRestart: true
|
|
239
|
+
});
|
|
240
|
+
break;
|
|
241
|
+
case SYNCED_BLOCK_BUTTON_TEST_ID.syncedBlockToolbarSyncedLocationsTrigger:
|
|
242
|
+
// Only track when opening the dropdown
|
|
243
|
+
if (button.getAttribute('aria-pressed') === 'false') {
|
|
244
|
+
syncedLocationsExperience === null || syncedLocationsExperience === void 0 ? void 0 : syncedLocationsExperience.start({
|
|
245
|
+
forceRestart: true
|
|
246
|
+
});
|
|
247
|
+
}
|
|
185
248
|
break;
|
|
186
249
|
default:
|
|
187
250
|
{
|
|
@@ -258,4 +321,76 @@ const isSyncBlockRemovedInMutation = ({
|
|
|
258
321
|
}) => {
|
|
259
322
|
return type === 'childList' && [...removedNodes].some(isSyncBlockWithinNode);
|
|
260
323
|
};
|
|
261
|
-
const isSyncBlockWithinNode = node => getNodeQuery('[data-prosemirror-node-name="syncBlock"]')(node);
|
|
324
|
+
const isSyncBlockWithinNode = node => getNodeQuery('[data-prosemirror-node-name="syncBlock"]')(node);
|
|
325
|
+
const syncBlockDeleteConfirmationModalAddedCheck = refs => new ExperienceCheckDomMutation({
|
|
326
|
+
onDomMutation: ({
|
|
327
|
+
mutations
|
|
328
|
+
}) => {
|
|
329
|
+
if (mutations.some(isDeleteConfirmationModalAddedInMutation)) {
|
|
330
|
+
return {
|
|
331
|
+
status: 'success'
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
return undefined;
|
|
335
|
+
},
|
|
336
|
+
observeConfig: () => {
|
|
337
|
+
return {
|
|
338
|
+
target: document.body,
|
|
339
|
+
options: {
|
|
340
|
+
childList: true,
|
|
341
|
+
subtree: true
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
const isDeleteConfirmationModalAddedInMutation = ({
|
|
347
|
+
type,
|
|
348
|
+
addedNodes
|
|
349
|
+
}) => {
|
|
350
|
+
return type === 'childList' && [...addedNodes].some(isDeleteConfirmationModalWithinNode);
|
|
351
|
+
};
|
|
352
|
+
const isDeleteConfirmationModalWithinNode = node => getNodeQuery('[data-testid="sync-block-delete-confirmation"]')(node);
|
|
353
|
+
const syncedLocationsDropdownOpenedCheck = refs => new ExperienceCheckDomMutation({
|
|
354
|
+
onDomMutation: ({
|
|
355
|
+
mutations
|
|
356
|
+
}) => {
|
|
357
|
+
if (mutations.some(isSyncedLocationsDropdownErrorInMutation)) {
|
|
358
|
+
return {
|
|
359
|
+
status: 'failure'
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
if (mutations.some(isSyncedLocationsDropdownAddedInMutation)) {
|
|
363
|
+
return {
|
|
364
|
+
status: 'success'
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
return undefined;
|
|
368
|
+
},
|
|
369
|
+
observeConfig: () => {
|
|
370
|
+
return {
|
|
371
|
+
target: document.body,
|
|
372
|
+
options: {
|
|
373
|
+
childList: true,
|
|
374
|
+
subtree: true
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
const isSyncedLocationsDropdownAddedInMutation = ({
|
|
380
|
+
type,
|
|
381
|
+
addedNodes
|
|
382
|
+
}) => {
|
|
383
|
+
return type === 'childList' && [...addedNodes].some(isSyncedLocationsDropdownWithinNode);
|
|
384
|
+
};
|
|
385
|
+
const isSyncedLocationsDropdownErrorInMutation = ({
|
|
386
|
+
type,
|
|
387
|
+
addedNodes
|
|
388
|
+
}) => {
|
|
389
|
+
return type === 'childList' && [...addedNodes].some(isSyncedLocationsDropdownErrorWithinNode);
|
|
390
|
+
};
|
|
391
|
+
const isSyncedLocationsDropdownWithinNode = node => {
|
|
392
|
+
return !!(getNodeQuery('[data-testid="synced-locations-dropdown-content"]')(node) || getNodeQuery('[data-testid="synced-locations-dropdown-content-no-results"]')(node));
|
|
393
|
+
};
|
|
394
|
+
const isSyncedLocationsDropdownErrorWithinNode = node => {
|
|
395
|
+
return !!getNodeQuery('[data-testid="synced-locations-dropdown-content-error"]')(node);
|
|
396
|
+
};
|
|
@@ -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 = {};
|
|
@@ -20,7 +19,7 @@ export const trackSyncBlocks = (predicate, tr, state) => {
|
|
|
20
19
|
from,
|
|
21
20
|
to
|
|
22
21
|
} = step;
|
|
23
|
-
const docAtStep =
|
|
22
|
+
const docAtStep = tr.docs[idx];
|
|
24
23
|
let hasChange = false;
|
|
25
24
|
if (from !== to) {
|
|
26
25
|
step.getMap().forEach((oldStart, oldEnd) => {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
|
|
2
2
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
-
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
4
3
|
import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
5
|
-
import { CellSelection, findTable } from '@atlaskit/editor-tables';
|
|
6
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
4
|
export const findSyncBlock = (schema, selection) => {
|
|
8
5
|
const {
|
|
9
6
|
syncBlock
|
|
@@ -28,50 +25,6 @@ const UNSUPPORTED_NODE_TYPES = new Set(['inlineExtension', 'extension', 'bodiedE
|
|
|
28
25
|
* or false if conversion is not possible
|
|
29
26
|
*/
|
|
30
27
|
export const canBeConvertedToSyncBlock = selection => {
|
|
31
|
-
return fg('platform_synced_block_dogfooding') ? canBeConvertedToSyncBlockNew(selection) : canBeConvertedToSyncBlockOld(selection);
|
|
32
|
-
};
|
|
33
|
-
export const canBeConvertedToSyncBlockOld = selection => {
|
|
34
|
-
const schema = selection.$from.doc.type.schema;
|
|
35
|
-
const {
|
|
36
|
-
nodes
|
|
37
|
-
} = schema;
|
|
38
|
-
let from = selection.from;
|
|
39
|
-
let to = selection.to;
|
|
40
|
-
let contentToInclude = selection.content().content;
|
|
41
|
-
if (selection instanceof CellSelection) {
|
|
42
|
-
const table = findTable(selection);
|
|
43
|
-
if (!table) {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
contentToInclude = Fragment.from([table.node]);
|
|
47
|
-
from = table.pos;
|
|
48
|
-
to = table.pos + table.node.nodeSize;
|
|
49
|
-
} else if (selection instanceof TextSelection) {
|
|
50
|
-
const trueParent = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList, nodes.blockquote])(selection);
|
|
51
|
-
if (trueParent) {
|
|
52
|
-
contentToInclude = Fragment.from([trueParent.node]);
|
|
53
|
-
from = trueParent.pos;
|
|
54
|
-
to = trueParent.pos + trueParent.node.nodeSize;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
let canBeConverted = true;
|
|
58
|
-
selection.$from.doc.nodesBetween(from, to, node => {
|
|
59
|
-
if (UNSUPPORTED_NODE_TYPES.has(node.type.name)) {
|
|
60
|
-
canBeConverted = false;
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
if (!canBeConverted) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
contentToInclude = removeBreakoutMarks(contentToInclude);
|
|
68
|
-
return {
|
|
69
|
-
contentToInclude,
|
|
70
|
-
from,
|
|
71
|
-
to
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
export const canBeConvertedToSyncBlockNew = selection => {
|
|
75
28
|
const {
|
|
76
29
|
$from,
|
|
77
30
|
range
|
|
@@ -4,7 +4,6 @@ import { blockTypeMessages } from '@atlaskit/editor-common/messages';
|
|
|
4
4
|
import { IconSyncBlock } from '@atlaskit/editor-common/quick-insert';
|
|
5
5
|
import { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
6
6
|
import Lozenge from '@atlaskit/lozenge';
|
|
7
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
7
|
import { flushBodiedSyncBlocks, flushSyncBlocks } from './editor-actions';
|
|
9
8
|
import { copySyncedBlockReferenceToClipboardEditorCommand, createSyncedBlock } from './editor-commands';
|
|
10
9
|
import { createPlugin, syncedBlockPluginKey } from './pm-plugins/main';
|
|
@@ -41,7 +40,7 @@ export const syncedBlockPlugin = ({
|
|
|
41
40
|
return [{
|
|
42
41
|
name: 'syncedBlockPlugin',
|
|
43
42
|
plugin: params => createPlugin(config, params, syncBlockStore, api)
|
|
44
|
-
},
|
|
43
|
+
}, {
|
|
45
44
|
name: 'menuAndToolbarExperiencesPlugin',
|
|
46
45
|
plugin: () => getMenuAndToolbarExperiencesPlugin({
|
|
47
46
|
refs,
|
|
@@ -50,10 +49,10 @@ export const syncedBlockPlugin = ({
|
|
|
50
49
|
return 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(payload);
|
|
51
50
|
}
|
|
52
51
|
})
|
|
53
|
-
}]
|
|
52
|
+
}];
|
|
54
53
|
},
|
|
55
54
|
commands: {
|
|
56
|
-
copySyncedBlockReferenceToClipboard:
|
|
55
|
+
copySyncedBlockReferenceToClipboard: inputMethod => copySyncedBlockReferenceToClipboardEditorCommand(syncBlockStore, inputMethod, api),
|
|
57
56
|
insertSyncedBlock: () => ({
|
|
58
57
|
tr
|
|
59
58
|
}) => {
|
|
@@ -106,7 +105,7 @@ export const syncedBlockPlugin = ({
|
|
|
106
105
|
fireAnalyticsEvent: api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions.fireAnalyticsEvent
|
|
107
106
|
});
|
|
108
107
|
},
|
|
109
|
-
testId:
|
|
108
|
+
testId: SYNCED_BLOCK_BUTTON_TEST_ID.quickInsertCreate
|
|
110
109
|
}];
|
|
111
110
|
},
|
|
112
111
|
floatingToolbar: (state, intl) => getToolbarConfig(state, intl, api, syncBlockStore)
|
|
@@ -11,5 +11,9 @@ export const SYNCED_BLOCK_BUTTON_TEST_ID = {
|
|
|
11
11
|
primaryToolbarCreate: 'create-synced-block-toolbar-btn',
|
|
12
12
|
blockMenuCreate: 'create-synced-block-block-menu-btn',
|
|
13
13
|
quickInsertCreate: 'create-synced-block-quick-insert-btn',
|
|
14
|
-
syncedBlockToolbarReferenceDelete: 'reference-synced-block-delete-btn'
|
|
14
|
+
syncedBlockToolbarReferenceDelete: 'reference-synced-block-delete-btn',
|
|
15
|
+
syncedBlockToolbarSourceDelete: 'source-synced-block-delete-btn',
|
|
16
|
+
syncedBlockToolbarReferenceUnsync: 'reference-synced-block-unsync-btn',
|
|
17
|
+
syncedBlockToolbarSourceUnsync: 'source-synced-block-unsync-btn',
|
|
18
|
+
syncedBlockToolbarSyncedLocationsTrigger: 'synced-block-synced-locations-dropdown--trigger'
|
|
15
19
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { useIntl } from 'react-intl-next';
|
|
3
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
4
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
4
5
|
import { blockMenuMessages } from '@atlaskit/editor-common/messages';
|
|
5
6
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
@@ -66,7 +67,7 @@ const CopySyncedBlockDropdownItem = ({
|
|
|
66
67
|
});
|
|
67
68
|
const onClick = () => {
|
|
68
69
|
var _api$core3, _api$core4, _api$blockControls2, _api$blockControls2$c;
|
|
69
|
-
api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 ? void 0 : api.syncedBlock.commands.copySyncedBlockReferenceToClipboard());
|
|
70
|
+
api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 ? void 0 : api.syncedBlock.commands.copySyncedBlockReferenceToClipboard(INPUT_METHOD.BLOCK_MENU));
|
|
70
71
|
api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(api === null || api === void 0 ? void 0 : (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : (_api$blockControls2$c = _api$blockControls2.commands) === null || _api$blockControls2$c === void 0 ? void 0 : _api$blockControls2$c.toggleBlockMenu({
|
|
71
72
|
closeMenu: true
|
|
72
73
|
}));
|