@atlaskit/editor-plugin-annotation 2.8.2 → 2.9.0
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 +19 -0
- package/dist/cjs/editor-commands/index.js +50 -1
- package/dist/cjs/pm-plugins/annotation-manager-hooks.js +166 -4
- package/dist/cjs/pm-plugins/inline-comment.js +169 -30
- package/dist/cjs/pm-plugins/plugin-factory.js +51 -1
- package/dist/cjs/pm-plugins/reducer.js +18 -1
- package/dist/cjs/pm-plugins/toolbar.js +10 -7
- package/dist/cjs/pm-plugins/types.js +2 -0
- package/dist/cjs/ui/InlineCommentView.js +14 -1
- package/dist/es2019/editor-commands/index.js +42 -0
- package/dist/es2019/pm-plugins/annotation-manager-hooks.js +160 -5
- package/dist/es2019/pm-plugins/inline-comment.js +146 -9
- package/dist/es2019/pm-plugins/plugin-factory.js +51 -1
- package/dist/es2019/pm-plugins/reducer.js +22 -1
- package/dist/es2019/pm-plugins/toolbar.js +10 -8
- package/dist/es2019/pm-plugins/types.js +2 -0
- package/dist/es2019/ui/InlineCommentView.js +11 -1
- package/dist/esm/editor-commands/index.js +49 -0
- package/dist/esm/pm-plugins/annotation-manager-hooks.js +167 -5
- package/dist/esm/pm-plugins/inline-comment.js +159 -20
- package/dist/esm/pm-plugins/plugin-factory.js +51 -1
- package/dist/esm/pm-plugins/reducer.js +18 -1
- package/dist/esm/pm-plugins/toolbar.js +10 -7
- package/dist/esm/pm-plugins/types.js +2 -0
- package/dist/esm/ui/InlineCommentView.js +11 -1
- package/dist/types/editor-commands/index.d.ts +5 -0
- package/dist/types/pm-plugins/annotation-manager-hooks.d.ts +4 -1
- package/dist/types/pm-plugins/plugin-factory.d.ts +4 -0
- package/dist/types/pm-plugins/types.d.ts +26 -1
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types-ts4.5/editor-commands/index.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/annotation-manager-hooks.d.ts +4 -1
- package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/types.d.ts +26 -1
- package/dist/types-ts4.5/types/index.d.ts +1 -0
- package/package.json +7 -4
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { AnnotationTypes } from '@atlaskit/adf-schema';
|
|
2
|
-
import { getRangeInlineNodeNames } from '@atlaskit/editor-common/utils';
|
|
2
|
+
import { getAnnotationInlineNodeTypes, getRangeInlineNodeNames } from '@atlaskit/editor-common/utils';
|
|
3
3
|
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
4
|
-
import {
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
|
+
import { setInlineCommentDraftState, createAnnotation, setSelectedAnnotation, closeComponent, setHoveredAnnotation, removeInlineCommentFromDoc } from '../editor-commands';
|
|
5
6
|
import { AnnotationSelectionType } from '../types';
|
|
6
7
|
import { inlineCommentPluginKey, isSelectionValid } from './utils';
|
|
7
8
|
var ERROR_REASON_DRAFT_NOT_STARTED = 'draft-not-started';
|
|
8
9
|
var ERROR_REASON_DRAFT_IN_PROGRESS = 'draft-in-progress';
|
|
9
10
|
var ERROR_REASON_RANGE_MISSING = 'range-no-longer-exists';
|
|
10
11
|
var ERROR_REASON_RANGE_INVALID = 'invalid-range';
|
|
12
|
+
var ERROR_REASON_ID_INVALID = 'id-not-valid';
|
|
11
13
|
var domRefFromPos = function domRefFromPos(view, position) {
|
|
12
14
|
var dom;
|
|
13
15
|
try {
|
|
@@ -40,15 +42,34 @@ export var allowAnnotation = function allowAnnotation(editorView, options) {
|
|
|
40
42
|
};
|
|
41
43
|
export var startDraft = function startDraft(editorView, options) {
|
|
42
44
|
return function () {
|
|
43
|
-
var _getRangeInlineNodeNa, _options$
|
|
45
|
+
var _getRangeInlineNodeNa, _options$annotationMa2;
|
|
44
46
|
var _ref2 = inlineCommentPluginKey.getState(editorView.state) || {},
|
|
45
|
-
isDrafting = _ref2.isDrafting
|
|
47
|
+
isDrafting = _ref2.isDrafting,
|
|
48
|
+
selectedAnnotations = _ref2.selectedAnnotations;
|
|
46
49
|
if (isDrafting) {
|
|
47
50
|
return {
|
|
48
51
|
success: false,
|
|
49
52
|
reason: ERROR_REASON_DRAFT_IN_PROGRESS
|
|
50
53
|
};
|
|
51
54
|
}
|
|
55
|
+
if (!!(selectedAnnotations !== null && selectedAnnotations !== void 0 && selectedAnnotations.length) && fg('platform_editor_comments_api_manager_select')) {
|
|
56
|
+
// if there are selected annotations when starting a draft, we need to clear the selected annotations
|
|
57
|
+
// before we start the draft.
|
|
58
|
+
closeComponent()(editorView.state, editorView.dispatch);
|
|
59
|
+
|
|
60
|
+
// not only that but we need to also deselect any other annotations that are currently selected.
|
|
61
|
+
selectedAnnotations === null || selectedAnnotations === void 0 || selectedAnnotations.forEach(function (annotation) {
|
|
62
|
+
var _options$annotationMa, _getAnnotationInlineN;
|
|
63
|
+
(_options$annotationMa = options.annotationManager) === null || _options$annotationMa === void 0 || _options$annotationMa.emit({
|
|
64
|
+
name: 'annotationSelectionChanged',
|
|
65
|
+
data: {
|
|
66
|
+
annotationId: annotation.id,
|
|
67
|
+
isSelected: false,
|
|
68
|
+
inlineNodeTypes: (_getAnnotationInlineN = getAnnotationInlineNodeTypes(editorView.state, annotation.id)) !== null && _getAnnotationInlineN !== void 0 ? _getAnnotationInlineN : []
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
52
73
|
setInlineCommentDraftState(options.editorAnalyticsAPI)(true)(editorView.state, editorView.dispatch);
|
|
53
74
|
var _ref3 = inlineCommentPluginKey.getState(editorView.state) || {},
|
|
54
75
|
draftDecorationSet = _ref3.draftDecorationSet;
|
|
@@ -70,7 +91,7 @@ export var startDraft = function startDraft(editorView, options) {
|
|
|
70
91
|
to: decorations[decorations.length - 1].to
|
|
71
92
|
}
|
|
72
93
|
})) !== null && _getRangeInlineNodeNa !== void 0 ? _getRangeInlineNodeNa : [];
|
|
73
|
-
(_options$
|
|
94
|
+
(_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 || _options$annotationMa2.emit({
|
|
74
95
|
name: 'draftAnnotationStarted',
|
|
75
96
|
data: {
|
|
76
97
|
targetElement: targetElement,
|
|
@@ -114,6 +135,7 @@ export var clearDraft = function clearDraft(editorView, options) {
|
|
|
114
135
|
};
|
|
115
136
|
export var applyDraft = function applyDraft(editorView, options) {
|
|
116
137
|
return function (id) {
|
|
138
|
+
var _options$annotationMa3, _getAnnotationInlineN2;
|
|
117
139
|
var _ref5 = inlineCommentPluginKey.getState(editorView.state) || {},
|
|
118
140
|
isDrafting = _ref5.isDrafting,
|
|
119
141
|
draftDecorationSet = _ref5.draftDecorationSet,
|
|
@@ -138,6 +160,17 @@ export var applyDraft = function applyDraft(editorView, options) {
|
|
|
138
160
|
// Using the original decoration from position we should be able to locate the new target element.
|
|
139
161
|
// This is because the new annotation will be created at the same position as the draft decoration.
|
|
140
162
|
var targetElement = domRefFromPos(editorView, from);
|
|
163
|
+
|
|
164
|
+
// When a draft is applied it is automatically selected, so we need to set the selected annotation.
|
|
165
|
+
// emit the event for the selected annotation.
|
|
166
|
+
(_options$annotationMa3 = options.annotationManager) === null || _options$annotationMa3 === void 0 || _options$annotationMa3.emit({
|
|
167
|
+
name: 'annotationSelectionChanged',
|
|
168
|
+
data: {
|
|
169
|
+
annotationId: id,
|
|
170
|
+
isSelected: true,
|
|
171
|
+
inlineNodeTypes: (_getAnnotationInlineN2 = getAnnotationInlineNodeTypes(editorView.state, id)) !== null && _getAnnotationInlineN2 !== void 0 ? _getAnnotationInlineN2 : []
|
|
172
|
+
}
|
|
173
|
+
});
|
|
141
174
|
return {
|
|
142
175
|
success: true,
|
|
143
176
|
// Get the dom element from the newly created annotation and return it here.
|
|
@@ -182,4 +215,133 @@ export var getDraft = function getDraft(editorView, options) {
|
|
|
182
215
|
actionResult: undefined
|
|
183
216
|
};
|
|
184
217
|
};
|
|
218
|
+
};
|
|
219
|
+
export var setIsAnnotationSelected = function setIsAnnotationSelected(editorView, options) {
|
|
220
|
+
return function (id, isSelected) {
|
|
221
|
+
var _selectedAnnotations$;
|
|
222
|
+
var _ref7 = inlineCommentPluginKey.getState(editorView.state) || {},
|
|
223
|
+
annotations = _ref7.annotations,
|
|
224
|
+
isDrafting = _ref7.isDrafting,
|
|
225
|
+
selectedAnnotations = _ref7.selectedAnnotations;
|
|
226
|
+
if (isDrafting) {
|
|
227
|
+
return {
|
|
228
|
+
success: false,
|
|
229
|
+
reason: ERROR_REASON_DRAFT_IN_PROGRESS
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// If there is no annotation state with this id then we can assume the annotation is invalid.
|
|
234
|
+
if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {
|
|
235
|
+
return {
|
|
236
|
+
success: false,
|
|
237
|
+
reason: ERROR_REASON_ID_INVALID
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
var isCurrentlySelectedIndex = (_selectedAnnotations$ = selectedAnnotations === null || selectedAnnotations === void 0 ? void 0 : selectedAnnotations.findIndex(function (annotation) {
|
|
241
|
+
return annotation.id === id;
|
|
242
|
+
})) !== null && _selectedAnnotations$ !== void 0 ? _selectedAnnotations$ : -1;
|
|
243
|
+
var isCurrentlySelected = isCurrentlySelectedIndex !== -1;
|
|
244
|
+
if (isSelected !== isCurrentlySelected) {
|
|
245
|
+
// the annotation is selection is changing.
|
|
246
|
+
if (isCurrentlySelected && !isSelected) {
|
|
247
|
+
var _options$annotationMa4, _getAnnotationInlineN3;
|
|
248
|
+
// the selected annotaion is being unselected, so we need to close the view.
|
|
249
|
+
closeComponent()(editorView.state, editorView.dispatch);
|
|
250
|
+
(_options$annotationMa4 = options.annotationManager) === null || _options$annotationMa4 === void 0 || _options$annotationMa4.emit({
|
|
251
|
+
name: 'annotationSelectionChanged',
|
|
252
|
+
data: {
|
|
253
|
+
annotationId: id,
|
|
254
|
+
isSelected: false,
|
|
255
|
+
inlineNodeTypes: (_getAnnotationInlineN3 = getAnnotationInlineNodeTypes(editorView.state, id)) !== null && _getAnnotationInlineN3 !== void 0 ? _getAnnotationInlineN3 : []
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
} else if (!isCurrentlySelected && isSelected) {
|
|
259
|
+
var _options$annotationMa6, _getAnnotationInlineN5;
|
|
260
|
+
// the annotation is currently not selected and is being selected, so we need to open the view.
|
|
261
|
+
setSelectedAnnotation(id)(editorView.state, editorView.dispatch);
|
|
262
|
+
|
|
263
|
+
// the current annotations are going to be unselected. So we need to notify listeners of this change also.
|
|
264
|
+
selectedAnnotations === null || selectedAnnotations === void 0 || selectedAnnotations.forEach(function (annotation) {
|
|
265
|
+
if (annotation.id !== id) {
|
|
266
|
+
var _options$annotationMa5, _getAnnotationInlineN4;
|
|
267
|
+
(_options$annotationMa5 = options.annotationManager) === null || _options$annotationMa5 === void 0 || _options$annotationMa5.emit({
|
|
268
|
+
name: 'annotationSelectionChanged',
|
|
269
|
+
data: {
|
|
270
|
+
annotationId: annotation.id,
|
|
271
|
+
isSelected: false,
|
|
272
|
+
inlineNodeTypes: (_getAnnotationInlineN4 = getAnnotationInlineNodeTypes(editorView.state, annotation.id)) !== null && _getAnnotationInlineN4 !== void 0 ? _getAnnotationInlineN4 : []
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Lastly we need to emit the event for the selected annotation.
|
|
279
|
+
(_options$annotationMa6 = options.annotationManager) === null || _options$annotationMa6 === void 0 || _options$annotationMa6.emit({
|
|
280
|
+
name: 'annotationSelectionChanged',
|
|
281
|
+
data: {
|
|
282
|
+
annotationId: id,
|
|
283
|
+
isSelected: true,
|
|
284
|
+
inlineNodeTypes: (_getAnnotationInlineN5 = getAnnotationInlineNodeTypes(editorView.state, id)) !== null && _getAnnotationInlineN5 !== void 0 ? _getAnnotationInlineN5 : []
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
success: true,
|
|
291
|
+
isSelected: isSelected
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
export var setIsAnnotationHovered = function setIsAnnotationHovered(editorView, options) {
|
|
296
|
+
return function (id, isHovered) {
|
|
297
|
+
var _hoveredAnnotations$f;
|
|
298
|
+
var _ref8 = inlineCommentPluginKey.getState(editorView.state) || {},
|
|
299
|
+
annotations = _ref8.annotations,
|
|
300
|
+
hoveredAnnotations = _ref8.hoveredAnnotations;
|
|
301
|
+
|
|
302
|
+
// If there is no annotation state with this id then we can assume the annotation is invalid.
|
|
303
|
+
if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {
|
|
304
|
+
return {
|
|
305
|
+
success: false,
|
|
306
|
+
reason: ERROR_REASON_ID_INVALID
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
var isCurrentlyHoveredIndex = (_hoveredAnnotations$f = hoveredAnnotations === null || hoveredAnnotations === void 0 ? void 0 : hoveredAnnotations.findIndex(function (annotation) {
|
|
310
|
+
return annotation.id === id;
|
|
311
|
+
})) !== null && _hoveredAnnotations$f !== void 0 ? _hoveredAnnotations$f : -1;
|
|
312
|
+
var isCurrentlyHovered = isCurrentlyHoveredIndex !== -1;
|
|
313
|
+
if (isHovered !== isCurrentlyHovered) {
|
|
314
|
+
// the annotation in hovered is changing.
|
|
315
|
+
if (isCurrentlyHovered && !isHovered) {
|
|
316
|
+
// the hovered annotaion is being unhovered, so we should remove the hover state.
|
|
317
|
+
setHoveredAnnotation('')(editorView.state, editorView.dispatch);
|
|
318
|
+
} else if (!isCurrentlyHovered && isHovered) {
|
|
319
|
+
// the annotation is currently not hovered and is being hovered.
|
|
320
|
+
setHoveredAnnotation(id)(editorView.state, editorView.dispatch);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
success: true,
|
|
325
|
+
isHovered: isHovered
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
export var clearAnnotation = function clearAnnotation(editorView, options) {
|
|
330
|
+
return function (id) {
|
|
331
|
+
var _ref9 = inlineCommentPluginKey.getState(editorView.state) || {},
|
|
332
|
+
annotations = _ref9.annotations;
|
|
333
|
+
|
|
334
|
+
// If there is no annotation state with this id then we can assume the annotation is invalid.
|
|
335
|
+
if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {
|
|
336
|
+
return {
|
|
337
|
+
success: false,
|
|
338
|
+
reason: ERROR_REASON_ID_INVALID
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
removeInlineCommentFromDoc(id, options.provider.supportedBlockNodes)(editorView.state, editorView.dispatch);
|
|
342
|
+
return {
|
|
343
|
+
success: true,
|
|
344
|
+
actionResult: undefined
|
|
345
|
+
};
|
|
346
|
+
};
|
|
185
347
|
};
|
|
@@ -4,11 +4,12 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
4
4
|
import { AnnotationTypes } from '@atlaskit/adf-schema';
|
|
5
5
|
import { RESOLVE_METHOD } from '@atlaskit/editor-common/analytics';
|
|
6
6
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
7
|
+
import { getAnnotationInlineNodeTypes } from '@atlaskit/editor-common/utils';
|
|
7
8
|
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
9
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
9
|
-
import { clearDirtyMark, closeComponent, setHoveredAnnotation, setInlineCommentsVisibility, setSelectedAnnotation, updateInlineCommentResolvedState, updateMouseState } from '../editor-commands';
|
|
10
|
+
import { clearDirtyMark, closeComponent, setHoveredAnnotation, setInlineCommentsVisibility, setSelectedAnnotation, flushPendingSelections, updateInlineCommentResolvedState, updateMouseState, setPendingSelectedAnnotation, setInlineCommentDraftState } from '../editor-commands';
|
|
10
11
|
import { getAnnotationViewClassname, getBlockAnnotationViewClassname } from '../nodeviews';
|
|
11
|
-
import { allowAnnotation, applyDraft, clearDraft, getDraft, startDraft } from './annotation-manager-hooks';
|
|
12
|
+
import { allowAnnotation, applyDraft, clearDraft, clearAnnotation, getDraft, setIsAnnotationHovered, setIsAnnotationSelected, startDraft } from './annotation-manager-hooks';
|
|
12
13
|
import { createPluginState } from './plugin-factory';
|
|
13
14
|
import { decorationKey, getAllAnnotations, getPluginState, inlineCommentPluginKey } from './utils';
|
|
14
15
|
var fetchProviderStates = /*#__PURE__*/function () {
|
|
@@ -97,7 +98,9 @@ var initialState = function initialState() {
|
|
|
97
98
|
isVisible: true,
|
|
98
99
|
skipSelectionHandling: false,
|
|
99
100
|
featureFlagsPluginState: featureFlagsPluginState,
|
|
100
|
-
isDrafting: false
|
|
101
|
+
isDrafting: false,
|
|
102
|
+
pendingSelectedAnnotations: [],
|
|
103
|
+
pendingSelectedAnnotationsUpdateCount: 0
|
|
101
104
|
};
|
|
102
105
|
};
|
|
103
106
|
var hideToolbar = function hideToolbar(state, dispatch) {
|
|
@@ -156,12 +159,33 @@ export var inlineCommentPlugin = function inlineCommentPlugin(options) {
|
|
|
156
159
|
key: inlineCommentPluginKey,
|
|
157
160
|
state: createPluginState(options.dispatch, initialState(provider.disallowOnWhitespace, featureFlagsPluginState)),
|
|
158
161
|
view: function view(editorView) {
|
|
162
|
+
var allowAnnotationFn;
|
|
163
|
+
var startDraftFn;
|
|
164
|
+
var clearDraftFn;
|
|
165
|
+
var applyDraftFn;
|
|
166
|
+
var getDraftFn;
|
|
167
|
+
var setIsAnnotationSelectedFn;
|
|
168
|
+
var setIsAnnotationHoveredFn;
|
|
169
|
+
var clearAnnotationFn;
|
|
159
170
|
if (annotationManager && fg('platform_editor_comments_api_manager')) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
171
|
+
allowAnnotationFn = allowAnnotation(editorView, options);
|
|
172
|
+
startDraftFn = startDraft(editorView, options);
|
|
173
|
+
clearDraftFn = clearDraft(editorView, options);
|
|
174
|
+
applyDraftFn = applyDraft(editorView, options);
|
|
175
|
+
getDraftFn = getDraft(editorView, options);
|
|
176
|
+
annotationManager.hook('allowAnnotation', allowAnnotationFn);
|
|
177
|
+
annotationManager.hook('startDraft', startDraftFn);
|
|
178
|
+
annotationManager.hook('clearDraft', clearDraftFn);
|
|
179
|
+
annotationManager.hook('applyDraft', applyDraftFn);
|
|
180
|
+
annotationManager.hook('getDraft', getDraftFn);
|
|
181
|
+
if (fg('platform_editor_comments_api_manager_select')) {
|
|
182
|
+
setIsAnnotationSelectedFn = setIsAnnotationSelected(editorView, options);
|
|
183
|
+
setIsAnnotationHoveredFn = setIsAnnotationHovered(editorView, options);
|
|
184
|
+
clearAnnotationFn = clearAnnotation(editorView, options);
|
|
185
|
+
annotationManager.hook('setIsAnnotationSelected', setIsAnnotationSelectedFn);
|
|
186
|
+
annotationManager.hook('setIsAnnotationHovered', setIsAnnotationHoveredFn);
|
|
187
|
+
annotationManager.hook('clearAnnotation', clearAnnotationFn);
|
|
188
|
+
}
|
|
165
189
|
}
|
|
166
190
|
// Get initial state
|
|
167
191
|
// Need to pass `editorView` to mitigate editor state going stale
|
|
@@ -219,6 +243,13 @@ export var inlineCommentPlugin = function inlineCommentPlugin(options) {
|
|
|
219
243
|
|
|
220
244
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
221
245
|
editorView.root.addEventListener('mouseup', mouseUp);
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* This flag is used to prevent the preemptive gate from being called multiple times while a check is in-flight.
|
|
249
|
+
* If a check is still pending then it's most likely because the product is busy and trying to block the
|
|
250
|
+
* selection of an annotation.
|
|
251
|
+
*/
|
|
252
|
+
var isPreemptiveGateActive = false;
|
|
222
253
|
return {
|
|
223
254
|
update: function update(view, _prevState) {
|
|
224
255
|
var _prevSelectedAnnotati;
|
|
@@ -239,8 +270,85 @@ export var inlineCommentPlugin = function inlineCommentPlugin(options) {
|
|
|
239
270
|
// The selectComponentExperience is using a simplified object, which is why it's type asserted.
|
|
240
271
|
(_options$selectCommen = options.selectCommentExperience) === null || _options$selectCommen === void 0 || _options$selectCommen.selectAnnotation.complete(selectedAnnotationId);
|
|
241
272
|
}
|
|
242
|
-
|
|
243
|
-
|
|
273
|
+
if (fg('platform_editor_comments_api_manager_select')) {
|
|
274
|
+
// In the Editor, Annotations can be selected in three ways:
|
|
275
|
+
// 1. By clicking on the annotation in the editor
|
|
276
|
+
// 2. By using the annotation manager to select the annotation
|
|
277
|
+
// 3. By moving the cursor to the annotation and using the keyboard to select it
|
|
278
|
+
// Item 1 & 3 need to be protected by the preemptive gate. This is because these actions could be performed by a user
|
|
279
|
+
// at a time when changing the selection could cause data loss.
|
|
280
|
+
// The following preemptive check is designed to cover these items.
|
|
281
|
+
|
|
282
|
+
var _ref6 = getPluginState(view.state) || {},
|
|
283
|
+
pendingSelectedAnnotations = _ref6.pendingSelectedAnnotations,
|
|
284
|
+
pendingSelectedAnnotationsUpdateCount = _ref6.pendingSelectedAnnotationsUpdateCount;
|
|
285
|
+
var _ref7 = getPluginState(_prevState) || {},
|
|
286
|
+
prevPendingSelectedAnnotationsUpdateCount = _ref7.pendingSelectedAnnotationsUpdateCount;
|
|
287
|
+
if (!isPreemptiveGateActive && pendingSelectedAnnotationsUpdateCount !== prevPendingSelectedAnnotationsUpdateCount && !!(pendingSelectedAnnotations !== null && pendingSelectedAnnotations !== void 0 && pendingSelectedAnnotations.length)) {
|
|
288
|
+
// Need to set a lock to avoid calling gate multiple times. The lock will be released
|
|
289
|
+
// when the preemptive gate is complete.
|
|
290
|
+
isPreemptiveGateActive = true;
|
|
291
|
+
annotationManager === null || annotationManager === void 0 || annotationManager.checkPreemptiveGate().then(function (canSelectAnnotation) {
|
|
292
|
+
var _ref8 = getPluginState(view.state) || {},
|
|
293
|
+
isDrafting = _ref8.isDrafting,
|
|
294
|
+
latestPendingSelectedAnnotations = _ref8.pendingSelectedAnnotations,
|
|
295
|
+
latestSelectedAnnotations = _ref8.selectedAnnotations;
|
|
296
|
+
if (canSelectAnnotation) {
|
|
297
|
+
if (isDrafting) {
|
|
298
|
+
// The user must have chosen to discard there draft. So before we flush the pending selections
|
|
299
|
+
// we need to clear the draft if there is one.
|
|
300
|
+
setInlineCommentDraftState(options.editorAnalyticsAPI)(false)(view.state, view.dispatch);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Flush the pending selections into the selected annotations list.
|
|
304
|
+
flushPendingSelections(true)(view.state, view.dispatch);
|
|
305
|
+
latestSelectedAnnotations === null || latestSelectedAnnotations === void 0 || latestSelectedAnnotations.filter(function (annotation) {
|
|
306
|
+
return (latestPendingSelectedAnnotations === null || latestPendingSelectedAnnotations === void 0 ? void 0 : latestPendingSelectedAnnotations.findIndex(function (pendingAnnotation) {
|
|
307
|
+
return pendingAnnotation.id === annotation.id;
|
|
308
|
+
})) === -1;
|
|
309
|
+
}).forEach(function (annotation) {
|
|
310
|
+
var _options$annotationMa, _getAnnotationInlineN;
|
|
311
|
+
(_options$annotationMa = options.annotationManager) === null || _options$annotationMa === void 0 || _options$annotationMa.emit({
|
|
312
|
+
name: 'annotationSelectionChanged',
|
|
313
|
+
data: {
|
|
314
|
+
annotationId: annotation.id,
|
|
315
|
+
isSelected: false,
|
|
316
|
+
inlineNodeTypes: (_getAnnotationInlineN = getAnnotationInlineNodeTypes(editorView.state, annotation.id)) !== null && _getAnnotationInlineN !== void 0 ? _getAnnotationInlineN : []
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Notify the annotation manager that the pending selection has changed.
|
|
322
|
+
latestPendingSelectedAnnotations === null || latestPendingSelectedAnnotations === void 0 || latestPendingSelectedAnnotations.forEach(function (_ref9) {
|
|
323
|
+
var _options$annotationMa2, _getAnnotationInlineN2;
|
|
324
|
+
var id = _ref9.id;
|
|
325
|
+
(_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 || _options$annotationMa2.emit({
|
|
326
|
+
name: 'annotationSelectionChanged',
|
|
327
|
+
data: {
|
|
328
|
+
annotationId: id,
|
|
329
|
+
isSelected: true,
|
|
330
|
+
inlineNodeTypes: (_getAnnotationInlineN2 = getAnnotationInlineNodeTypes(view.state, id)) !== null && _getAnnotationInlineN2 !== void 0 ? _getAnnotationInlineN2 : []
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
} else {
|
|
335
|
+
// Clears the pending selections if the preemptive gate returns false.
|
|
336
|
+
// We should need to worry about dispatching change events here because the pending selections
|
|
337
|
+
// are being aborted and the selections will remain unchanged.
|
|
338
|
+
flushPendingSelections(false)(view.state, view.dispatch);
|
|
339
|
+
}
|
|
340
|
+
}).catch(function (error) {
|
|
341
|
+
// TODO: EDITOR-595 - Ensure and anlytic is fired to indicate which reports on the error.
|
|
342
|
+
|
|
343
|
+
// If an error has occured we will clear any pending selections to avoid accidentally setting the wrong thing.
|
|
344
|
+
flushPendingSelections(false)(view.state, view.dispatch);
|
|
345
|
+
}).finally(function () {
|
|
346
|
+
isPreemptiveGateActive = false;
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
var _ref10 = getPluginState(view.state) || {},
|
|
351
|
+
dirtyAnnotations = _ref10.dirtyAnnotations;
|
|
244
352
|
if (!dirtyAnnotations) {
|
|
245
353
|
return;
|
|
246
354
|
}
|
|
@@ -253,6 +361,16 @@ export var inlineCommentPlugin = function inlineCommentPlugin(options) {
|
|
|
253
361
|
if (updateSubscriber) {
|
|
254
362
|
updateSubscriber.off('resolve', resolve).off('delete', resolve).off('unresolve', unResolve).off('create', unResolve).off('setvisibility', setVisibility).off('setselectedannotation', setSelectedAnnotationFn).off('sethoveredannotation', setHoveredAnnotationFn).off('removehoveredannotation', removeHoveredannotationFn).off('closeinlinecomment', closeInlineCommentFn);
|
|
255
363
|
}
|
|
364
|
+
if (annotationManager && fg('platform_editor_comments_api_manager')) {
|
|
365
|
+
annotationManager.unhook('allowAnnotation', allowAnnotationFn);
|
|
366
|
+
annotationManager.unhook('startDraft', startDraftFn);
|
|
367
|
+
annotationManager.unhook('clearDraft', clearDraftFn);
|
|
368
|
+
annotationManager.unhook('applyDraft', applyDraftFn);
|
|
369
|
+
annotationManager.unhook('getDraft', getDraftFn);
|
|
370
|
+
annotationManager.unhook('setIsAnnotationSelected', setIsAnnotationSelectedFn);
|
|
371
|
+
annotationManager.unhook('setIsAnnotationHovered', setIsAnnotationHoveredFn);
|
|
372
|
+
annotationManager.unhook('clearAnnotation', clearAnnotationFn);
|
|
373
|
+
}
|
|
256
374
|
}
|
|
257
375
|
};
|
|
258
376
|
},
|
|
@@ -293,27 +411,48 @@ export var inlineCommentPlugin = function inlineCommentPlugin(options) {
|
|
|
293
411
|
if (isSelected && !(pluginState !== null && pluginState !== void 0 && pluginState.isInlineCommentViewClosed)) {
|
|
294
412
|
return false;
|
|
295
413
|
}
|
|
296
|
-
var
|
|
297
|
-
annotations =
|
|
414
|
+
var _ref11 = pluginState || {},
|
|
415
|
+
annotations = _ref11.annotations;
|
|
298
416
|
var isUnresolved = annotations && annotations[annotationId] === false;
|
|
299
417
|
if (!isUnresolved) {
|
|
300
418
|
return false;
|
|
301
419
|
}
|
|
302
|
-
|
|
420
|
+
if (fg('platform_editor_comments_api_manager_select')) {
|
|
421
|
+
var _pluginState$pendingS;
|
|
422
|
+
// The manager disable setting the selected annotation on click because in the editor this is already
|
|
423
|
+
// handled by the selection update handler. When the manager is enabled, and a selection changes it's pushed into
|
|
424
|
+
// the pendingSelectedAnnotations array. This is then used to update the selection when the preemptive gate
|
|
425
|
+
// is released.
|
|
426
|
+
var isPendingSelection = pluginState === null || pluginState === void 0 || (_pluginState$pendingS = pluginState.pendingSelectedAnnotations) === null || _pluginState$pendingS === void 0 ? void 0 : _pluginState$pendingS.some(function (selectedAnnotation) {
|
|
427
|
+
return selectedAnnotation.id === annotationId;
|
|
428
|
+
});
|
|
429
|
+
// If the annotation is selected and the inline comment view is open, do nothing
|
|
430
|
+
// as the user is already in the comment view.
|
|
431
|
+
if (isPendingSelection) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
setPendingSelectedAnnotation(annotationId)(view.state, view.dispatch);
|
|
435
|
+
} else {
|
|
436
|
+
setSelectedAnnotation(annotationId)(view.state, view.dispatch);
|
|
437
|
+
}
|
|
303
438
|
return true;
|
|
304
439
|
}
|
|
305
440
|
},
|
|
306
441
|
decorations: function decorations(state) {
|
|
307
442
|
// highlight comments, depending on state
|
|
308
|
-
var
|
|
309
|
-
draftDecorationSet =
|
|
310
|
-
annotations =
|
|
311
|
-
selectedAnnotations =
|
|
312
|
-
isVisible =
|
|
313
|
-
isInlineCommentViewClosed =
|
|
314
|
-
hoveredAnnotations =
|
|
443
|
+
var _ref12 = getPluginState(state) || {},
|
|
444
|
+
draftDecorationSet = _ref12.draftDecorationSet,
|
|
445
|
+
annotations = _ref12.annotations,
|
|
446
|
+
selectedAnnotations = _ref12.selectedAnnotations,
|
|
447
|
+
isVisible = _ref12.isVisible,
|
|
448
|
+
isInlineCommentViewClosed = _ref12.isInlineCommentViewClosed,
|
|
449
|
+
hoveredAnnotations = _ref12.hoveredAnnotations;
|
|
315
450
|
var decorations = draftDecorationSet !== null && draftDecorationSet !== void 0 ? draftDecorationSet : DecorationSet.empty;
|
|
316
451
|
var focusDecorations = [];
|
|
452
|
+
|
|
453
|
+
// TODO: EDITOR-760 - This needs to be optimised, it's not a good idea to scan the entire document
|
|
454
|
+
// everytime we need to update the decorations. This handler will be called alot. We should be caching
|
|
455
|
+
// the decorations in plugin state and only updating them when required.
|
|
317
456
|
state.doc.descendants(function (node, pos) {
|
|
318
457
|
var _provider$supportedBl;
|
|
319
458
|
// Inline comment on mediaInline is not supported as part of comments on media project
|
|
@@ -4,6 +4,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
import { pluginFactory } from '@atlaskit/editor-common/utils';
|
|
5
5
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
6
6
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
8
|
import reducer from './reducer';
|
|
8
9
|
import { decorationKey, findAnnotationsInSelection, inlineCommentPluginKey, isBlockNodeAnnotationsSelected, isSelectedAnnotationsChanged } from './utils';
|
|
9
10
|
var handleDocChanged = function handleDocChanged(tr, prevPluginState) {
|
|
@@ -19,6 +20,10 @@ var handleDocChanged = function handleDocChanged(tr, prevPluginState) {
|
|
|
19
20
|
* We clear bookmark on the following conditions:
|
|
20
21
|
* 1. if current selection is an empty selection, or
|
|
21
22
|
* 2. if the current selection and bookmark selection are different
|
|
23
|
+
* @param tr
|
|
24
|
+
* @param editorState
|
|
25
|
+
* @param bookmark
|
|
26
|
+
* @example
|
|
22
27
|
*/
|
|
23
28
|
export var shouldClearBookMarkCheck = function shouldClearBookMarkCheck(tr, editorState, bookmark) {
|
|
24
29
|
if (editorState.selection.empty || !bookmark) {
|
|
@@ -46,7 +51,7 @@ export var shouldClearBookMarkCheck = function shouldClearBookMarkCheck(tr, edit
|
|
|
46
51
|
// by default we discard bookmark
|
|
47
52
|
return true;
|
|
48
53
|
};
|
|
49
|
-
var
|
|
54
|
+
var getSelectionChangeHandlerOld = function getSelectionChangeHandlerOld(reopenCommentView) {
|
|
50
55
|
return function (tr, pluginState) {
|
|
51
56
|
if (pluginState.skipSelectionHandling) {
|
|
52
57
|
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
@@ -86,6 +91,51 @@ var getSelectionChangedHandler = function getSelectionChangedHandler(reopenComme
|
|
|
86
91
|
});
|
|
87
92
|
};
|
|
88
93
|
};
|
|
94
|
+
var getSelectionChangeHandlerNew = function getSelectionChangeHandlerNew(reopenCommentView) {
|
|
95
|
+
return function (tr, pluginState) {
|
|
96
|
+
if (pluginState.skipSelectionHandling) {
|
|
97
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
98
|
+
skipSelectionHandling: false
|
|
99
|
+
}, reopenCommentView && {
|
|
100
|
+
isInlineCommentViewClosed: false
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
var selectedAnnotations = findAnnotationsInSelection(tr.selection, tr.doc);
|
|
104
|
+
|
|
105
|
+
// NOTE: I've left this commented code here as a reference that the previous old code would reset the selected annotations
|
|
106
|
+
// if the selection is empty. If this is no longer needed, we can remove this code.
|
|
107
|
+
// clean up with platform_editor_comments_api_manager_select
|
|
108
|
+
// if (selectedAnnotations.length === 0) {
|
|
109
|
+
// return {
|
|
110
|
+
// ...pluginState,
|
|
111
|
+
// pendingSelectedAnnotations: selectedAnnotations,
|
|
112
|
+
// pendingSelectedAnnotationsUpdateCount:
|
|
113
|
+
// pluginState.pendingSelectedAnnotationsUpdateCount + 1,
|
|
114
|
+
// isInlineCommentViewClosed: true,
|
|
115
|
+
// selectAnnotationMethod: undefined,
|
|
116
|
+
// };
|
|
117
|
+
// }
|
|
118
|
+
|
|
119
|
+
if (isSelectedAnnotationsChanged(selectedAnnotations, pluginState.pendingSelectedAnnotations)) {
|
|
120
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
121
|
+
pendingSelectedAnnotations: selectedAnnotations,
|
|
122
|
+
pendingSelectedAnnotationsUpdateCount: pluginState.pendingSelectedAnnotationsUpdateCount + 1
|
|
123
|
+
}, reopenCommentView && {
|
|
124
|
+
isInlineCommentViewClosed: false
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return _objectSpread(_objectSpread(_objectSpread({}, pluginState), reopenCommentView && {
|
|
128
|
+
isInlineCommentViewClosed: false
|
|
129
|
+
}), {}, {
|
|
130
|
+
selectAnnotationMethod: undefined
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
var getSelectionChangedHandler = function getSelectionChangedHandler(reopenCommentView) {
|
|
135
|
+
return function (tr, pluginState) {
|
|
136
|
+
return fg('platform_editor_comments_api_manager_select') ? getSelectionChangeHandlerNew(reopenCommentView)(tr, pluginState) : getSelectionChangeHandlerOld(reopenCommentView)(tr, pluginState);
|
|
137
|
+
};
|
|
138
|
+
};
|
|
89
139
|
var _pluginFactory = pluginFactory(inlineCommentPluginKey, reducer, {
|
|
90
140
|
onSelectionChanged: getSelectionChangedHandler(true),
|
|
91
141
|
onDocChanged: handleDocChanged,
|
|
@@ -25,12 +25,14 @@ export default (function (pluginState, action) {
|
|
|
25
25
|
annotations: {}
|
|
26
26
|
});
|
|
27
27
|
case ACTIONS.CLOSE_COMPONENT:
|
|
28
|
-
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
28
|
+
return _objectSpread(_objectSpread(_objectSpread({}, pluginState), {}, {
|
|
29
29
|
isInlineCommentViewClosed: true,
|
|
30
30
|
isDrafting: false,
|
|
31
31
|
isOpeningMediaCommentFromToolbar: false
|
|
32
32
|
}, fg('platform_editor_annotation_selected_annotation') && {
|
|
33
33
|
selectedAnnotations: []
|
|
34
|
+
}), fg('platform_editor_comments_api_manager_select') && {
|
|
35
|
+
selectedAnnotations: []
|
|
34
36
|
});
|
|
35
37
|
case ACTIONS.ADD_INLINE_COMMENT:
|
|
36
38
|
var updatedPluginState = getNewDraftState(pluginState, action.data.drafting, action.data.editorState);
|
|
@@ -39,6 +41,8 @@ export default (function (pluginState, action) {
|
|
|
39
41
|
annotations: _objectSpread(_objectSpread({}, pluginState.annotations), action.data.inlineComments),
|
|
40
42
|
isInlineCommentViewClosed: false,
|
|
41
43
|
selectAnnotationMethod: undefined
|
|
44
|
+
}, fg('platform_editor_comments_api_manager_select') && {
|
|
45
|
+
skipSelectionHandling: true
|
|
42
46
|
});
|
|
43
47
|
case ACTIONS.INLINE_COMMENT_SET_VISIBLE:
|
|
44
48
|
var isVisible = action.data.isVisible;
|
|
@@ -62,6 +66,19 @@ export default (function (pluginState, action) {
|
|
|
62
66
|
skipSelectionHandling: true,
|
|
63
67
|
isInlineCommentViewClosed: false
|
|
64
68
|
});
|
|
69
|
+
case ACTIONS.FLUSH_PENDING_SELECTIONS:
|
|
70
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
71
|
+
selectedAnnotations: action.data.canSetAsSelectedAnnotations ? _toConsumableArray(pluginState.pendingSelectedAnnotations) : pluginState.selectedAnnotations,
|
|
72
|
+
pendingSelectedAnnotations: [],
|
|
73
|
+
isInlineCommentViewClosed: false
|
|
74
|
+
});
|
|
75
|
+
case ACTIONS.SET_PENDING_SELECTIONS:
|
|
76
|
+
return _objectSpread(_objectSpread({}, pluginState), {}, {
|
|
77
|
+
pendingSelectedAnnotations: _toConsumableArray(action.data.selectedAnnotations),
|
|
78
|
+
pendingSelectedAnnotationsUpdateCount: pluginState.pendingSelectedAnnotationsUpdateCount + 1,
|
|
79
|
+
skipSelectionHandling: true,
|
|
80
|
+
isInlineCommentViewClosed: false
|
|
81
|
+
});
|
|
65
82
|
default:
|
|
66
83
|
return pluginState;
|
|
67
84
|
}
|
|
@@ -130,7 +130,7 @@ export var buildToolbar = function buildToolbar(editorAnalyticsAPI) {
|
|
|
130
130
|
}
|
|
131
131
|
if (fg('platform_editor_comments_api_manager')) {
|
|
132
132
|
if (!annotationManager) {
|
|
133
|
-
// TODO: EDITOR-
|
|
133
|
+
// TODO: EDITOR-595 - If we've reached here and the manager is not initialized, we should
|
|
134
134
|
// dispatch an analytics event to indicate that the user has clicked the button but
|
|
135
135
|
// the action was not completed.
|
|
136
136
|
return false;
|
|
@@ -144,16 +144,19 @@ export var buildToolbar = function buildToolbar(editorAnalyticsAPI) {
|
|
|
144
144
|
}
|
|
145
145
|
});
|
|
146
146
|
createCommentExperience === null || createCommentExperience === void 0 || createCommentExperience.initExperience.start();
|
|
147
|
-
var
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
var result = annotationManager.startDraft();
|
|
148
|
+
if (result.success) {
|
|
149
|
+
// TODO: EDITOR-595 - Ensure and anlytic is fired to indicate that the user has started a draft.
|
|
150
|
+
} else {
|
|
151
|
+
// TODO: EDITOR-595 - Fire an analytics event to indicate that the user has clicked the button
|
|
152
|
+
// but the action was not completed, the result should contain a reason.
|
|
151
153
|
}
|
|
152
154
|
} else {
|
|
153
|
-
// TODO: EDITOR-
|
|
155
|
+
// TODO: EDITOR-595 - Track the toolbar comment button was clicked but the preemptive gate
|
|
156
|
+
// check returned false and the draft cannot be started.
|
|
154
157
|
}
|
|
155
158
|
}).catch(function () {
|
|
156
|
-
// TODO: EDITOR-
|
|
159
|
+
// TODO: EDITOR-595 - Handle preemptive gate check error. Something went very wrong in the gate.
|
|
157
160
|
});
|
|
158
161
|
return true;
|
|
159
162
|
} else {
|
|
@@ -8,5 +8,7 @@ export var ACTIONS = /*#__PURE__*/function (ACTIONS) {
|
|
|
8
8
|
ACTIONS[ACTIONS["CLOSE_COMPONENT"] = 6] = "CLOSE_COMPONENT";
|
|
9
9
|
ACTIONS[ACTIONS["SET_SELECTED_ANNOTATION"] = 7] = "SET_SELECTED_ANNOTATION";
|
|
10
10
|
ACTIONS[ACTIONS["SET_HOVERED_ANNOTATION"] = 8] = "SET_HOVERED_ANNOTATION";
|
|
11
|
+
ACTIONS[ACTIONS["FLUSH_PENDING_SELECTIONS"] = 9] = "FLUSH_PENDING_SELECTIONS";
|
|
12
|
+
ACTIONS[ACTIONS["SET_PENDING_SELECTIONS"] = 10] = "SET_PENDING_SELECTIONS";
|
|
11
13
|
return ACTIONS;
|
|
12
14
|
}({});
|