@atlaskit/editor-plugin-synced-block 5.2.1 → 5.2.2

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 (65) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/afm-jira/tsconfig.json +1 -1
  3. package/dist/cjs/editor-commands/index.js +10 -4
  4. package/dist/cjs/pm-plugins/menu-and-toolbar-experiences.js +267 -0
  5. package/dist/cjs/syncedBlockPlugin.js +21 -12
  6. package/dist/cjs/types/index.js +6 -3
  7. package/dist/cjs/ui/CreateSyncedBlockButton.js +2 -1
  8. package/dist/cjs/ui/CreateSyncedBlockDropdownItem.js +2 -1
  9. package/dist/cjs/ui/floating-toolbar.js +2 -1
  10. package/dist/es2019/editor-commands/index.js +10 -4
  11. package/dist/es2019/pm-plugins/menu-and-toolbar-experiences.js +261 -0
  12. package/dist/es2019/syncedBlockPlugin.js +19 -12
  13. package/dist/es2019/types/index.js +5 -2
  14. package/dist/es2019/ui/CreateSyncedBlockButton.js +2 -1
  15. package/dist/es2019/ui/CreateSyncedBlockDropdownItem.js +2 -1
  16. package/dist/es2019/ui/floating-toolbar.js +2 -1
  17. package/dist/esm/editor-commands/index.js +10 -4
  18. package/dist/esm/pm-plugins/menu-and-toolbar-experiences.js +260 -0
  19. package/dist/esm/syncedBlockPlugin.js +21 -12
  20. package/dist/esm/types/index.js +5 -2
  21. package/dist/esm/ui/CreateSyncedBlockButton.js +2 -1
  22. package/dist/esm/ui/CreateSyncedBlockDropdownItem.js +2 -1
  23. package/dist/esm/ui/floating-toolbar.js +2 -1
  24. package/dist/types/editor-commands/index.d.ts +3 -1
  25. package/dist/types/pm-plugins/menu-and-toolbar-experiences.d.ts +12 -0
  26. package/dist/types/types/index.d.ts +5 -14
  27. package/dist/types-ts4.5/editor-commands/index.d.ts +3 -1
  28. package/dist/types-ts4.5/pm-plugins/menu-and-toolbar-experiences.d.ts +12 -0
  29. package/dist/types-ts4.5/types/index.d.ts +5 -14
  30. package/package.json +3 -3
  31. package/dist/cjs/pm-plugins/experience-tracking/create-reference-experience.js +0 -113
  32. package/dist/cjs/pm-plugins/experience-tracking/create-source-experience.js +0 -169
  33. package/dist/cjs/pm-plugins/experience-tracking/delete-reference-experience.js +0 -175
  34. package/dist/cjs/pm-plugins/experience-tracking/delete-source-experience.js +0 -103
  35. package/dist/cjs/pm-plugins/experience-tracking/get-experience-tracking-plugins.js +0 -61
  36. package/dist/cjs/pm-plugins/experience-tracking/provider-only-experiences.js +0 -128
  37. package/dist/cjs/pm-plugins/utils/experience-tracking-utils.js +0 -85
  38. package/dist/es2019/pm-plugins/experience-tracking/create-reference-experience.js +0 -109
  39. package/dist/es2019/pm-plugins/experience-tracking/create-source-experience.js +0 -166
  40. package/dist/es2019/pm-plugins/experience-tracking/delete-reference-experience.js +0 -181
  41. package/dist/es2019/pm-plugins/experience-tracking/delete-source-experience.js +0 -98
  42. package/dist/es2019/pm-plugins/experience-tracking/get-experience-tracking-plugins.js +0 -46
  43. package/dist/es2019/pm-plugins/experience-tracking/provider-only-experiences.js +0 -127
  44. package/dist/es2019/pm-plugins/utils/experience-tracking-utils.js +0 -65
  45. package/dist/esm/pm-plugins/experience-tracking/create-reference-experience.js +0 -107
  46. package/dist/esm/pm-plugins/experience-tracking/create-source-experience.js +0 -163
  47. package/dist/esm/pm-plugins/experience-tracking/delete-reference-experience.js +0 -169
  48. package/dist/esm/pm-plugins/experience-tracking/delete-source-experience.js +0 -97
  49. package/dist/esm/pm-plugins/experience-tracking/get-experience-tracking-plugins.js +0 -55
  50. package/dist/esm/pm-plugins/experience-tracking/provider-only-experiences.js +0 -122
  51. package/dist/esm/pm-plugins/utils/experience-tracking-utils.js +0 -79
  52. package/dist/types/pm-plugins/experience-tracking/create-reference-experience.d.ts +0 -10
  53. package/dist/types/pm-plugins/experience-tracking/create-source-experience.d.ts +0 -10
  54. package/dist/types/pm-plugins/experience-tracking/delete-reference-experience.d.ts +0 -13
  55. package/dist/types/pm-plugins/experience-tracking/delete-source-experience.d.ts +0 -12
  56. package/dist/types/pm-plugins/experience-tracking/get-experience-tracking-plugins.d.ts +0 -5
  57. package/dist/types/pm-plugins/experience-tracking/provider-only-experiences.d.ts +0 -3
  58. package/dist/types/pm-plugins/utils/experience-tracking-utils.d.ts +0 -9
  59. package/dist/types-ts4.5/pm-plugins/experience-tracking/create-reference-experience.d.ts +0 -10
  60. package/dist/types-ts4.5/pm-plugins/experience-tracking/create-source-experience.d.ts +0 -10
  61. package/dist/types-ts4.5/pm-plugins/experience-tracking/delete-reference-experience.d.ts +0 -13
  62. package/dist/types-ts4.5/pm-plugins/experience-tracking/delete-source-experience.d.ts +0 -12
  63. package/dist/types-ts4.5/pm-plugins/experience-tracking/get-experience-tracking-plugins.d.ts +0 -5
  64. package/dist/types-ts4.5/pm-plugins/experience-tracking/provider-only-experiences.d.ts +0 -3
  65. package/dist/types-ts4.5/pm-plugins/utils/experience-tracking-utils.d.ts +0 -9
@@ -1,166 +0,0 @@
1
- import { bind } from 'bind-event-listener';
2
- import { ACTION_SUBJECT, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
3
- import { Experience, ExperienceCheckDomMutation, ExperienceCheckTimeout, getPopupContainerFromEditorView, popupWithNestedElement } from '@atlaskit/editor-common/experiences';
4
- import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
- import { EXPERIENCE_ABORT_REASON } from '../../types';
7
- import { getAddedResourceIds, getTarget } from '../utils/experience-tracking-utils';
8
- const pluginKey = new PluginKey('createSourceSyncBlockExperience');
9
- const START_METHOD = {
10
- BLOCK_MENU: 'block-menu',
11
- PINNED_TOOLBAR: 'pinned-toolbar',
12
- QUICK_INSERT: 'quick-insert'
13
- };
14
- const SYNCED_BLOCK_CREATE_BUTTON_IDS = ['create-synced-block-toolbar-btn', 'create-synced-block-block-menu-btn', 'create-synced-block-quick-insert-btn'];
15
- const syncedBlockCreateButtonIds = new Set(SYNCED_BLOCK_CREATE_BUTTON_IDS);
16
-
17
- /**
18
- * This experience tracks when a source sync block is inserted.
19
- *
20
- * Start: When user inserts a sync block via block menu, quick insert or pinned toolbar
21
- * Success: When the sync block is added to the DOM within 3000ms of start
22
- * Failure: When 3000ms passes without the source sync block being added to the DOM
23
- */
24
- export const getCreateSourceExperiencePlugin = ({
25
- refs,
26
- dispatchAnalyticsEvent,
27
- syncBlockStore
28
- }) => {
29
- let popupsTargetEl;
30
- let editorViewEl;
31
- const getPopupsTarget = () => {
32
- if (!popupsTargetEl) {
33
- popupsTargetEl = refs.popupsMountPoint || refs.wrapperElement || getPopupContainerFromEditorView(editorViewEl);
34
- }
35
- return popupsTargetEl;
36
- };
37
- const experience = getCreateSourceExperience({
38
- refs,
39
- dispatchAnalyticsEvent
40
- });
41
- syncBlockStore.sourceManager.setCreateExperience(experience);
42
- const unbindClickListener = bind(document, {
43
- type: 'click',
44
- listener: event => {
45
- const target = event.target;
46
- if (!target) {
47
- return;
48
- }
49
- const button = target.closest('button[data-testid]');
50
- if (!button || !(button instanceof HTMLButtonElement)) {
51
- return;
52
- }
53
- const testId = button.dataset.testid;
54
- if (!isSyncedBlockCreateButtonId(testId)) {
55
- return;
56
- }
57
- handleButtonClick(testId, experience);
58
- }
59
- });
60
- const unbindKeydownListener = bind(document, {
61
- type: 'keydown',
62
- listener: event => {
63
- if (isEnterKey(event.key)) {
64
- const typeaheadPopup = popupWithNestedElement(getPopupsTarget(), '.fabric-editor-typeahead');
65
- if (!typeaheadPopup || !(typeaheadPopup instanceof HTMLElement)) {
66
- return;
67
- }
68
- const firstItem = typeaheadPopup.querySelector('[role="option"]');
69
- if (!firstItem || !(firstItem instanceof HTMLElement)) {
70
- return;
71
- }
72
- const testId = firstItem.dataset.testid;
73
- if (testId === 'create-synced-block-quick-insert-btn') {
74
- experience.start({
75
- method: START_METHOD.QUICK_INSERT
76
- });
77
- }
78
- }
79
- },
80
- options: {
81
- capture: true
82
- }
83
- });
84
- return new SafePlugin({
85
- key: pluginKey,
86
- view: editorView => {
87
- editorViewEl = editorView.dom;
88
- return {
89
- destroy: () => {
90
- experience.abort({
91
- reason: EXPERIENCE_ABORT_REASON.EDITOR_DESTROYED
92
- });
93
- unbindClickListener();
94
- unbindKeydownListener();
95
- }
96
- };
97
- }
98
- });
99
- };
100
- const getCreateSourceExperience = ({
101
- refs,
102
- dispatchAnalyticsEvent
103
- }) => {
104
- return new Experience(ACTION_SUBJECT.SYNCED_BLOCK, {
105
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE,
106
- dispatchAnalyticsEvent,
107
- checks: [new ExperienceCheckTimeout({
108
- durationMs: 3000
109
- }), new ExperienceCheckDomMutation({
110
- onDomMutation: ({
111
- mutations
112
- }) => {
113
- const createdResourceIds = getAddedResourceIds(mutations, '[data-prosemirror-node-name="bodiedSyncBlock"]');
114
- if (createdResourceIds.length > 0) {
115
- return {
116
- status: 'success',
117
- metadata: {
118
- createdResourceIds
119
- }
120
- };
121
- }
122
- return undefined;
123
- },
124
- observeConfig: () => {
125
- return {
126
- target: getTarget(refs.containerElement),
127
- options: {
128
- childList: true
129
- }
130
- };
131
- }
132
- })]
133
- });
134
- };
135
- const isSyncedBlockCreateButtonId = value => {
136
- return !!value && syncedBlockCreateButtonIds.has(value);
137
- };
138
- const handleButtonClick = (testId, experience) => {
139
- switch (testId) {
140
- case 'create-synced-block-toolbar-btn':
141
- experience.start({
142
- method: START_METHOD.PINNED_TOOLBAR
143
- });
144
- break;
145
- case 'create-synced-block-block-menu-btn':
146
- experience.start({
147
- method: START_METHOD.BLOCK_MENU
148
- });
149
- break;
150
- case 'create-synced-block-quick-insert-btn':
151
- experience.start({
152
- method: START_METHOD.QUICK_INSERT
153
- });
154
- break;
155
- default:
156
- {
157
- // Exhaustiveness check: if a new SyncedBlockToolbarButtonId is added
158
- // but not handled above, TypeScript will error here.
159
- const _exhaustiveCheck = testId;
160
- return _exhaustiveCheck;
161
- }
162
- }
163
- };
164
- const isEnterKey = key => {
165
- return key === 'Enter';
166
- };
@@ -1,181 +0,0 @@
1
- import { bind } from 'bind-event-listener';
2
- import { ACTION_SUBJECT, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
3
- import { Experience, ExperienceCheckDomMutation, ExperienceCheckTimeout } from '@atlaskit/editor-common/experiences';
4
- import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
- import { EXPERIENCE_ABORT_REASON } from '../../types';
7
- import { getRemovedResourceIds, getTarget, wasSyncBlockDeletedOrAddedByHistory } from '../utils/experience-tracking-utils';
8
- const pluginKey = new PluginKey('deleteReferenceSyncBlockExperience');
9
- const START_METHOD = {
10
- ELEMENT_TOOLBAR: 'element-toolbar',
11
- DELETE: 'delete',
12
- TYPED_OVER: 'typed-over',
13
- CUT: 'cut',
14
- UNDO: 'undo',
15
- REDO: 'redo'
16
- };
17
-
18
- /**
19
- * This experience tracks when a reference sync block is deleted.
20
- *
21
- * Start: When user deletes ref sync block from toolbar, presses delete when cursor is in front of ref sync block,
22
- * presses any key with a ref sync block selected, cuts with a ref sync block selected, triggers undo/redo that deletes a ref sync block
23
- * Success: When the sync block is removed from the DOM within 2000ms of start
24
- * Failure: When 2000ms passes without the reference sync block being removed from the DOM
25
- */
26
- export const getDeleteReferenceExperiencePlugin = ({
27
- refs,
28
- dispatchAnalyticsEvent,
29
- syncBlockStore
30
- }) => {
31
- const experience = getDeleteReferenceExperience({
32
- refs,
33
- dispatchAnalyticsEvent
34
- });
35
- syncBlockStore.sourceManager.setDeleteExperience(experience);
36
- const unbindClickListener = bind(document, {
37
- type: 'click',
38
- listener: event => {
39
- const target = event.target;
40
- if (!target) {
41
- return;
42
- }
43
- const button = target.closest('button[data-testid]');
44
- if (!button || !(button instanceof HTMLButtonElement)) {
45
- return;
46
- }
47
- const testId = button.dataset.testid;
48
- if (isReferenceSyncedBlockDeleteButtonId(testId)) {
49
- experience.start({
50
- method: START_METHOD.ELEMENT_TOOLBAR
51
- });
52
- }
53
- }
54
- });
55
- return new SafePlugin({
56
- key: pluginKey,
57
- props: {
58
- handleDOMEvents: {
59
- cut: view => {
60
- const {
61
- state
62
- } = view;
63
- if (hasSyncBlockInSelection(state.selection)) {
64
- experience.start({
65
- method: START_METHOD.CUT
66
- });
67
- }
68
- return false;
69
- },
70
- keydown: (view, event) => {
71
- const {
72
- state
73
- } = view;
74
- const hasSelection = hasSyncBlockInSelection(state.selection);
75
- const hasAdjacent = hasSyncBlockBeforeCursor(state.selection);
76
- if (hasSelection) {
77
- experience.start({
78
- method: START_METHOD.TYPED_OVER
79
- });
80
- }
81
- if (isDeleteKey(event.key) && hasAdjacent) {
82
- experience.start({
83
- method: START_METHOD.DELETE
84
- });
85
- }
86
- return false;
87
- }
88
- }
89
- },
90
- appendTransaction: (transactions, oldState, newState) => {
91
- transactions.forEach(tr => {
92
- const {
93
- hasDeletedSyncBlock,
94
- isUndo
95
- } = wasSyncBlockDeletedOrAddedByHistory(tr, oldState, newState);
96
- if (hasDeletedSyncBlock) {
97
- experience.start({
98
- method: isUndo ? START_METHOD.UNDO : START_METHOD.REDO
99
- });
100
- }
101
- });
102
- return null;
103
- },
104
- view: () => {
105
- return {
106
- destroy: () => {
107
- experience.abort({
108
- reason: EXPERIENCE_ABORT_REASON.EDITOR_DESTROYED
109
- });
110
- unbindClickListener();
111
- }
112
- };
113
- }
114
- });
115
- };
116
- export const getDeleteReferenceExperience = ({
117
- refs,
118
- dispatchAnalyticsEvent
119
- }) => {
120
- return new Experience(ACTION_SUBJECT.SYNCED_BLOCK, {
121
- actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_DELETE,
122
- dispatchAnalyticsEvent,
123
- checks: [new ExperienceCheckTimeout({
124
- durationMs: 2000
125
- }), new ExperienceCheckDomMutation({
126
- onDomMutation: ({
127
- mutations
128
- }) => {
129
- const deletedResourceIds = getRemovedResourceIds(mutations, '[data-prosemirror-node-name="syncBlock"]');
130
- if (deletedResourceIds.length > 0) {
131
- return {
132
- status: 'success',
133
- metadata: {
134
- deletedResourceIds
135
- }
136
- };
137
- }
138
- return undefined;
139
- },
140
- observeConfig: () => {
141
- return {
142
- target: getTarget(refs.containerElement),
143
- options: {
144
- childList: true
145
- }
146
- };
147
- }
148
- })]
149
- });
150
- };
151
- const isReferenceSyncedBlockDeleteButtonId = testId => testId === 'reference-synced-block-delete-button';
152
- const isDeleteKey = key => {
153
- return key === 'Delete' || key === 'Backspace';
154
- };
155
- const hasSyncBlockInSelection = selection => {
156
- const {
157
- syncBlock
158
- } = selection.$from.doc.type.schema.nodes;
159
- let found = false;
160
- selection.$from.doc.nodesBetween(selection.from, selection.to, node => {
161
- if (node.type === syncBlock) {
162
- found = true;
163
- return false;
164
- }
165
- // sync block nodes can only be found at the top level
166
- return false;
167
- });
168
- return found;
169
- };
170
- const hasSyncBlockBeforeCursor = selection => {
171
- if (!selection.empty) {
172
- return false;
173
- }
174
- const {
175
- syncBlock
176
- } = selection.$from.doc.type.schema.nodes;
177
- const {
178
- nodeBefore
179
- } = selection.$from;
180
- return (nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.type) === syncBlock;
181
- };
@@ -1,98 +0,0 @@
1
- import { bind } from 'bind-event-listener';
2
- import { ACTION_SUBJECT, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
3
- import { Experience, ExperienceCheckDomMutation, ExperienceCheckTimeout } from '@atlaskit/editor-common/experiences';
4
- import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
5
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
- import { EXPERIENCE_ABORT_REASON } from '../../types';
7
- import { getRemovedResourceIds, getTarget } from '../utils/experience-tracking-utils';
8
- const pluginKey = new PluginKey('deleteSourceSyncBlockExperience');
9
- const START_METHOD = {
10
- DELETE_CONFIRM_BUTTON: 'delete-confirm-button'
11
- };
12
-
13
- /**
14
- * This experience tracks when a source sync block is deleted.
15
- *
16
- * Start: When user clicks the delete button in the delete modal
17
- * Success: When the sync block is removed from the DOM within 2000ms of start
18
- * Failure: When 2000ms passes without the source sync block being removed from the DOM
19
- */
20
- export const getDeleteSourceExperiencePlugin = ({
21
- refs,
22
- dispatchAnalyticsEvent,
23
- syncBlockStore
24
- }) => {
25
- const experience = getDeleteSourceExperience({
26
- refs,
27
- dispatchAnalyticsEvent
28
- });
29
- syncBlockStore.sourceManager.setDeleteExperience(experience);
30
- const unbindClickListener = bind(document, {
31
- type: 'click',
32
- listener: event => {
33
- const target = event.target;
34
- if (!target) {
35
- return;
36
- }
37
- const button = target.closest('button[data-testid]');
38
- if (!button || !(button instanceof HTMLButtonElement)) {
39
- return;
40
- }
41
- const testId = button.dataset.testid;
42
- if (isSyncedBlockDeleteButtonId(testId)) {
43
- experience.start({
44
- method: START_METHOD.DELETE_CONFIRM_BUTTON
45
- });
46
- }
47
- }
48
- });
49
- return new SafePlugin({
50
- key: pluginKey,
51
- view: () => {
52
- return {
53
- destroy: () => {
54
- experience.abort({
55
- reason: EXPERIENCE_ABORT_REASON.EDITOR_DESTROYED
56
- });
57
- unbindClickListener();
58
- }
59
- };
60
- }
61
- });
62
- };
63
- export const getDeleteSourceExperience = ({
64
- refs,
65
- dispatchAnalyticsEvent
66
- }) => {
67
- return new Experience(ACTION_SUBJECT.SYNCED_BLOCK, {
68
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_DELETE,
69
- dispatchAnalyticsEvent,
70
- checks: [new ExperienceCheckTimeout({
71
- durationMs: 2000
72
- }), new ExperienceCheckDomMutation({
73
- onDomMutation: ({
74
- mutations
75
- }) => {
76
- const deletedResourceIds = getRemovedResourceIds(mutations, '[data-prosemirror-node-name="bodiedSyncBlock"]');
77
- if (deletedResourceIds.length > 0) {
78
- return {
79
- status: 'success',
80
- metadata: {
81
- deletedResourceIds
82
- }
83
- };
84
- }
85
- return undefined;
86
- },
87
- observeConfig: () => {
88
- return {
89
- target: getTarget(refs.containerElement),
90
- options: {
91
- childList: true
92
- }
93
- };
94
- }
95
- })]
96
- });
97
- };
98
- const isSyncedBlockDeleteButtonId = testId => testId === 'synced-block-delete-confirmation-modal-delete-button';
@@ -1,46 +0,0 @@
1
- import { getCreateReferenceExperiencePlugin } from "./create-reference-experience";
2
- import { getCreateSourceExperiencePlugin } from "./create-source-experience";
3
- import { getDeleteReferenceExperiencePlugin } from "./delete-reference-experience";
4
- import { getDeleteSourceExperiencePlugin } from "./delete-source-experience";
5
- import { getProviderOnlyExperiencesPlugin } from "./provider-only-experiences";
6
- export const getExperienceTrackingPlugins = ({
7
- refs,
8
- dispatchAnalyticsEvent,
9
- syncBlockStore
10
- }) => {
11
- return [{
12
- name: 'createReferenceSyncedBlockExperiencePlugin',
13
- plugin: () => getCreateReferenceExperiencePlugin({
14
- refs,
15
- dispatchAnalyticsEvent
16
- })
17
- }, {
18
- name: 'createSourceSyncedBlockExperiencePlugin',
19
- plugin: () => getCreateSourceExperiencePlugin({
20
- refs,
21
- dispatchAnalyticsEvent,
22
- syncBlockStore
23
- })
24
- }, {
25
- name: 'deleteSourceExperiencePlugin',
26
- plugin: () => getDeleteSourceExperiencePlugin({
27
- refs,
28
- dispatchAnalyticsEvent,
29
- syncBlockStore
30
- })
31
- }, {
32
- name: 'deleteReferenceExperiencePlugin',
33
- plugin: () => getDeleteReferenceExperiencePlugin({
34
- refs,
35
- dispatchAnalyticsEvent,
36
- syncBlockStore
37
- })
38
- }, {
39
- name: 'providerOnlySyncedBlockExperiencesPlugin',
40
- plugin: () => getProviderOnlyExperiencesPlugin({
41
- refs,
42
- dispatchAnalyticsEvent,
43
- syncBlockStore
44
- })
45
- }];
46
- };
@@ -1,127 +0,0 @@
1
- import { ACTION_SUBJECT, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
2
- import { Experience, ExperienceCheckTimeout } from '@atlaskit/editor-common/experiences';
3
- import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
4
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
5
- import { EXPERIENCE_ABORT_REASON } from '../../types';
6
- const pluginKey = new PluginKey('providerOnlySyncBlockExperiences');
7
- export const getProviderOnlyExperiencesPlugin = ({
8
- refs,
9
- dispatchAnalyticsEvent,
10
- syncBlockStore
11
- }) => {
12
- const saveSourceExperience = getSaveSourceExperience({
13
- refs,
14
- dispatchAnalyticsEvent
15
- });
16
- syncBlockStore.sourceManager.setSaveExperience(saveSourceExperience);
17
- const saveReferenceExperience = getSaveReferenceExperience({
18
- refs,
19
- dispatchAnalyticsEvent
20
- });
21
- const fetchExperience = getFetchExperience({
22
- refs,
23
- dispatchAnalyticsEvent
24
- });
25
- const fetchSourceInfoExperience = getFetchSourceInfoExperience({
26
- refs,
27
- dispatchAnalyticsEvent
28
- });
29
- syncBlockStore.referenceManager.setExperiences(fetchExperience, fetchSourceInfoExperience, saveReferenceExperience);
30
- return new SafePlugin({
31
- key: pluginKey,
32
- view: () => {
33
- return {
34
- destroy: () => {
35
- saveSourceExperience.abort({
36
- reason: EXPERIENCE_ABORT_REASON.EDITOR_DESTROYED
37
- });
38
- saveReferenceExperience.abort({
39
- reason: EXPERIENCE_ABORT_REASON.EDITOR_DESTROYED
40
- });
41
- fetchExperience.abort({
42
- reason: EXPERIENCE_ABORT_REASON.EDITOR_DESTROYED
43
- });
44
- fetchSourceInfoExperience.abort({
45
- reason: EXPERIENCE_ABORT_REASON.EDITOR_DESTROYED
46
- });
47
- }
48
- };
49
- }
50
- });
51
- };
52
-
53
- /**
54
- * This experience tracks when a source sync block is saved to the BE.
55
- *
56
- * Start: When the flush source sync block function is called.
57
- * Success: When the sync block save is successful within 1500ms of start.
58
- * Failure: When 1500ms passes without the sync block being successfully saved
59
- */
60
- const getSaveSourceExperience = ({
61
- dispatchAnalyticsEvent
62
- }) => {
63
- return new Experience(ACTION_SUBJECT.SYNCED_BLOCK, {
64
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE,
65
- dispatchAnalyticsEvent,
66
- checks: [new ExperienceCheckTimeout({
67
- durationMs: 1500
68
- })]
69
- });
70
- };
71
-
72
- /**
73
- * This experience tracks when a reference sync block is saved to the BE.
74
- *
75
- * Start: When the flush sync block function is called.
76
- * Success: When the sync block save is successful within 1500ms of start.
77
- * Failure: When 1500ms passes without the sync block being successfully saved
78
- */
79
- const getSaveReferenceExperience = ({
80
- dispatchAnalyticsEvent
81
- }) => {
82
- return new Experience(ACTION_SUBJECT.SYNCED_BLOCK, {
83
- actionSubjectId: ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_UPDATE,
84
- dispatchAnalyticsEvent,
85
- checks: [new ExperienceCheckTimeout({
86
- durationMs: 1500
87
- })]
88
- });
89
- };
90
-
91
- /**
92
- * This experience tracks when a reference sync block data is fetched from the BE.
93
- *
94
- * Start: When the fetchNodesData function is called.
95
- * Success: When the fetching the data is successful within 1500ms of start.
96
- * Failure: When 1500ms passes without the data being successfully fetched, or the fetch fails
97
- */
98
- const getFetchExperience = ({
99
- dispatchAnalyticsEvent
100
- }) => {
101
- return new Experience(ACTION_SUBJECT.SYNCED_BLOCK, {
102
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH,
103
- dispatchAnalyticsEvent,
104
- checks: [new ExperienceCheckTimeout({
105
- durationMs: 1500
106
- })]
107
- });
108
- };
109
-
110
- /**
111
- * This experience tracks when a reference sync block source info data (title, url) is fetched from the BE.
112
- *
113
- * Start: When the fetchSourceInfo function is called.
114
- * Success: When the fetching the data is successful within 2500ms of start.
115
- * Failure: When 2500ms passes without the data being successfully fetched, or the fetch fails
116
- */
117
- const getFetchSourceInfoExperience = ({
118
- dispatchAnalyticsEvent
119
- }) => {
120
- return new Experience(ACTION_SUBJECT.SYNCED_BLOCK, {
121
- actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_GET_SOURCE_INFO,
122
- dispatchAnalyticsEvent,
123
- checks: [new ExperienceCheckTimeout({
124
- durationMs: 2500
125
- })]
126
- });
127
- };
@@ -1,65 +0,0 @@
1
- import { pmHistoryPluginKey } from '@atlaskit/editor-common/utils';
2
- import { findChildren } from '@atlaskit/editor-prosemirror/utils';
3
- let targetEl;
4
- export const getTarget = containerElement => {
5
- if (!targetEl) {
6
- const element = containerElement === null || containerElement === void 0 ? void 0 : containerElement.querySelector('.ProseMirror');
7
- if (!element || !(element instanceof HTMLElement)) {
8
- return null;
9
- }
10
- targetEl = element;
11
- }
12
- return targetEl;
13
- };
14
- export const wasSyncBlockDeletedOrAddedByHistory = (tr, oldState, newState) => {
15
- const historyMeta = tr.getMeta(pmHistoryPluginKey);
16
- if (!Boolean(historyMeta)) {
17
- return {};
18
- }
19
- const {
20
- syncBlock
21
- } = newState.schema.nodes;
22
- const oldSyncBlockNodes = findChildren(oldState.doc, node => node.type === syncBlock);
23
- const newSyncBlockNodes = findChildren(newState.doc, node => node.type === syncBlock);
24
- const oldSyncBlockIds = new Set(oldSyncBlockNodes.map(nodeWithPos => nodeWithPos.node.attrs.localId).filter(localId => Boolean(localId)));
25
- const newSyncBlockIds = new Set(newSyncBlockNodes.map(nodeWithPos => nodeWithPos.node.attrs.localId).filter(localId => Boolean(localId)));
26
- const hasDeletedSyncBlock = Array.from(oldSyncBlockIds).some(localId => !newSyncBlockIds.has(localId));
27
- const hasAddedSyncBlock = Array.from(newSyncBlockIds).some(localId => !oldSyncBlockIds.has(localId));
28
- return {
29
- hasDeletedSyncBlock,
30
- hasAddedSyncBlock,
31
- isUndo: historyMeta.redo === false
32
- };
33
- };
34
- const getResourceIds = (nodes, resourceIds, query) => {
35
- nodes.forEach(node => {
36
- if (!(node instanceof HTMLElement)) {
37
- return;
38
- }
39
- const syncBlockElements = node.querySelectorAll(query);
40
- syncBlockElements.forEach(element => {
41
- const resourceId = element.getAttribute('resourceid');
42
- if (resourceId) {
43
- resourceIds.push(resourceId);
44
- }
45
- });
46
- });
47
- };
48
- export const getAddedResourceIds = (mutations, query) => {
49
- const resourceIds = [];
50
- mutations.forEach(mutation => {
51
- if (mutation.type === 'childList') {
52
- getResourceIds(mutation.addedNodes, resourceIds, query);
53
- }
54
- });
55
- return resourceIds;
56
- };
57
- export const getRemovedResourceIds = (mutations, query) => {
58
- const resourceIds = [];
59
- mutations.forEach(mutation => {
60
- if (mutation.type === 'childList') {
61
- getResourceIds(mutation.removedNodes, resourceIds, query);
62
- }
63
- });
64
- return resourceIds;
65
- };