@atlaskit/editor-plugin-annotation 2.8.3 → 2.9.1

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 (31) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/editor-commands/index.js +50 -1
  3. package/dist/cjs/pm-plugins/annotation-manager-hooks.js +166 -4
  4. package/dist/cjs/pm-plugins/inline-comment.js +169 -30
  5. package/dist/cjs/pm-plugins/plugin-factory.js +51 -1
  6. package/dist/cjs/pm-plugins/reducer.js +18 -1
  7. package/dist/cjs/pm-plugins/toolbar.js +10 -7
  8. package/dist/cjs/pm-plugins/types.js +2 -0
  9. package/dist/es2019/editor-commands/index.js +42 -0
  10. package/dist/es2019/pm-plugins/annotation-manager-hooks.js +160 -5
  11. package/dist/es2019/pm-plugins/inline-comment.js +146 -9
  12. package/dist/es2019/pm-plugins/plugin-factory.js +51 -1
  13. package/dist/es2019/pm-plugins/reducer.js +22 -1
  14. package/dist/es2019/pm-plugins/toolbar.js +10 -8
  15. package/dist/es2019/pm-plugins/types.js +2 -0
  16. package/dist/esm/editor-commands/index.js +49 -0
  17. package/dist/esm/pm-plugins/annotation-manager-hooks.js +167 -5
  18. package/dist/esm/pm-plugins/inline-comment.js +159 -20
  19. package/dist/esm/pm-plugins/plugin-factory.js +51 -1
  20. package/dist/esm/pm-plugins/reducer.js +18 -1
  21. package/dist/esm/pm-plugins/toolbar.js +10 -7
  22. package/dist/esm/pm-plugins/types.js +2 -0
  23. package/dist/types/editor-commands/index.d.ts +5 -0
  24. package/dist/types/pm-plugins/annotation-manager-hooks.d.ts +4 -1
  25. package/dist/types/pm-plugins/plugin-factory.d.ts +4 -0
  26. package/dist/types/pm-plugins/types.d.ts +26 -1
  27. package/dist/types-ts4.5/editor-commands/index.d.ts +5 -0
  28. package/dist/types-ts4.5/pm-plugins/annotation-manager-hooks.d.ts +4 -1
  29. package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +4 -0
  30. package/dist/types-ts4.5/pm-plugins/types.d.ts +26 -1
  31. package/package.json +8 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-plugin-annotation
2
2
 
3
+ ## 2.9.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 2.9.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#157348](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/157348)
14
+ [`2745ba38d05fd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2745ba38d05fd) -
15
+ Implemented the new manager set selection and hover APIs. This will allow anyone with access to
16
+ the annotations manager the ability to control when/what annotation is selected/hovered.
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+
3
22
  ## 2.8.3
4
23
 
5
24
  ### Patch Changes
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.updateMouseState = exports.updateInlineCommentResolvedState = exports.showInlineCommentForBlockNode = exports.setSelectedAnnotation = exports.setInlineCommentsVisibility = exports.setInlineCommentDraftState = exports.setHoveredAnnotation = exports.removeInlineCommentNearSelection = exports.createAnnotation = exports.closeComponent = exports.clearDirtyMark = exports.addInlineComment = void 0;
7
+ exports.updateMouseState = exports.updateInlineCommentResolvedState = exports.showInlineCommentForBlockNode = exports.setSelectedAnnotation = exports.setPendingSelectedAnnotation = exports.setInlineCommentsVisibility = exports.setInlineCommentDraftState = exports.setHoveredAnnotation = exports.removeInlineCommentNearSelection = exports.removeInlineCommentFromDoc = exports.flushPendingSelections = exports.createAnnotation = exports.closeComponent = exports.clearDirtyMark = exports.addInlineComment = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _adfSchema = require("@atlaskit/adf-schema");
10
10
  var _analytics = require("@atlaskit/editor-common/analytics");
@@ -51,6 +51,25 @@ var clearDirtyMark = exports.clearDirtyMark = function clearDirtyMark() {
51
51
  type: _types.ACTIONS.INLINE_COMMENT_CLEAR_DIRTY_MARK
52
52
  });
53
53
  };
54
+ var flushPendingSelections = exports.flushPendingSelections = function flushPendingSelections(canSetAsSelectedAnnotations) {
55
+ return (0, _pluginFactory.createCommand)({
56
+ type: _types.ACTIONS.FLUSH_PENDING_SELECTIONS,
57
+ data: {
58
+ canSetAsSelectedAnnotations: canSetAsSelectedAnnotations
59
+ }
60
+ });
61
+ };
62
+ var setPendingSelectedAnnotation = exports.setPendingSelectedAnnotation = function setPendingSelectedAnnotation(id) {
63
+ return (0, _pluginFactory.createCommand)({
64
+ type: _types.ACTIONS.SET_PENDING_SELECTIONS,
65
+ data: {
66
+ selectedAnnotations: [{
67
+ id: id,
68
+ type: _adfSchema.AnnotationTypes.INLINE_COMMENT
69
+ }]
70
+ }
71
+ });
72
+ };
54
73
  var removeInlineCommentFromNode = function removeInlineCommentFromNode(id) {
55
74
  var supportedBlockNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
56
75
  var state = arguments.length > 2 ? arguments[2] : undefined;
@@ -112,6 +131,34 @@ var removeInlineCommentNearSelection = exports.removeInlineCommentNearSelection
112
131
  return true;
113
132
  };
114
133
  };
134
+ var removeInlineCommentFromDoc = exports.removeInlineCommentFromDoc = function removeInlineCommentFromDoc(id) {
135
+ var supportedNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
136
+ return function (state, dispatch) {
137
+ var tr = state.tr;
138
+ state.doc.descendants(function (node, pos) {
139
+ // Inline comment on mediaInline is not supported as part of comments on media project
140
+ // Thus, we skip the decoration for mediaInline node
141
+ if (node.type.name === 'mediaInline') {
142
+ return false;
143
+ }
144
+ var isSupportedBlockNode = node.isBlock && (supportedNodes === null || supportedNodes === void 0 ? void 0 : supportedNodes.includes(node.type.name));
145
+ node.marks.filter(function (mark) {
146
+ return mark.type === state.schema.marks.annotation && mark.attrs.id === id;
147
+ }).forEach(function (mark) {
148
+ if (isSupportedBlockNode) {
149
+ tr.removeNodeMark(pos, mark);
150
+ } else {
151
+ tr.removeMark(pos, pos + node.nodeSize, mark);
152
+ }
153
+ });
154
+ });
155
+ if (dispatch) {
156
+ dispatch(tr);
157
+ return true;
158
+ }
159
+ return false;
160
+ };
161
+ };
115
162
  var getDraftCommandAction = function getDraftCommandAction(drafting, targetType, targetNodeId, supportedBlockNodes, isOpeningMediaCommentFromToolbar) {
116
163
  return function (editorState) {
117
164
  // validate selection only when entering draft mode
@@ -135,6 +182,8 @@ var getDraftCommandAction = function getDraftCommandAction(drafting, targetType,
135
182
  /**
136
183
  * Show active inline comments for a given block node, otherwise,
137
184
  * return false if the node has no comments or no unresolved comments.
185
+ * @param supportedBlockNodes
186
+ * @example
138
187
  */
139
188
  var showInlineCommentForBlockNode = exports.showInlineCommentForBlockNode = function showInlineCommentForBlockNode() {
140
189
  var supportedBlockNodes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
@@ -3,10 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.startDraft = exports.getDraft = exports.clearDraft = exports.applyDraft = exports.allowAnnotation = void 0;
6
+ exports.startDraft = exports.setIsAnnotationSelected = exports.setIsAnnotationHovered = exports.getDraft = exports.clearDraft = exports.clearAnnotation = exports.applyDraft = exports.allowAnnotation = void 0;
7
7
  var _adfSchema = require("@atlaskit/adf-schema");
8
8
  var _utils = require("@atlaskit/editor-common/utils");
9
9
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  var _editorCommands = require("../editor-commands");
11
12
  var _types = require("../types");
12
13
  var _utils3 = require("./utils");
@@ -14,6 +15,7 @@ var ERROR_REASON_DRAFT_NOT_STARTED = 'draft-not-started';
14
15
  var ERROR_REASON_DRAFT_IN_PROGRESS = 'draft-in-progress';
15
16
  var ERROR_REASON_RANGE_MISSING = 'range-no-longer-exists';
16
17
  var ERROR_REASON_RANGE_INVALID = 'invalid-range';
18
+ var ERROR_REASON_ID_INVALID = 'id-not-valid';
17
19
  var domRefFromPos = function domRefFromPos(view, position) {
18
20
  var dom;
19
21
  try {
@@ -46,15 +48,34 @@ var allowAnnotation = exports.allowAnnotation = function allowAnnotation(editorV
46
48
  };
47
49
  var startDraft = exports.startDraft = function startDraft(editorView, options) {
48
50
  return function () {
49
- var _getRangeInlineNodeNa, _options$annotationMa;
51
+ var _getRangeInlineNodeNa, _options$annotationMa2;
50
52
  var _ref2 = _utils3.inlineCommentPluginKey.getState(editorView.state) || {},
51
- isDrafting = _ref2.isDrafting;
53
+ isDrafting = _ref2.isDrafting,
54
+ selectedAnnotations = _ref2.selectedAnnotations;
52
55
  if (isDrafting) {
53
56
  return {
54
57
  success: false,
55
58
  reason: ERROR_REASON_DRAFT_IN_PROGRESS
56
59
  };
57
60
  }
61
+ if (!!(selectedAnnotations !== null && selectedAnnotations !== void 0 && selectedAnnotations.length) && (0, _platformFeatureFlags.fg)('platform_editor_comments_api_manager_select')) {
62
+ // if there are selected annotations when starting a draft, we need to clear the selected annotations
63
+ // before we start the draft.
64
+ (0, _editorCommands.closeComponent)()(editorView.state, editorView.dispatch);
65
+
66
+ // not only that but we need to also deselect any other annotations that are currently selected.
67
+ selectedAnnotations === null || selectedAnnotations === void 0 || selectedAnnotations.forEach(function (annotation) {
68
+ var _options$annotationMa, _getAnnotationInlineN;
69
+ (_options$annotationMa = options.annotationManager) === null || _options$annotationMa === void 0 || _options$annotationMa.emit({
70
+ name: 'annotationSelectionChanged',
71
+ data: {
72
+ annotationId: annotation.id,
73
+ isSelected: false,
74
+ inlineNodeTypes: (_getAnnotationInlineN = (0, _utils.getAnnotationInlineNodeTypes)(editorView.state, annotation.id)) !== null && _getAnnotationInlineN !== void 0 ? _getAnnotationInlineN : []
75
+ }
76
+ });
77
+ });
78
+ }
58
79
  (0, _editorCommands.setInlineCommentDraftState)(options.editorAnalyticsAPI)(true)(editorView.state, editorView.dispatch);
59
80
  var _ref3 = _utils3.inlineCommentPluginKey.getState(editorView.state) || {},
60
81
  draftDecorationSet = _ref3.draftDecorationSet;
@@ -76,7 +97,7 @@ var startDraft = exports.startDraft = function startDraft(editorView, options) {
76
97
  to: decorations[decorations.length - 1].to
77
98
  }
78
99
  })) !== null && _getRangeInlineNodeNa !== void 0 ? _getRangeInlineNodeNa : [];
79
- (_options$annotationMa = options.annotationManager) === null || _options$annotationMa === void 0 || _options$annotationMa.emit({
100
+ (_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 || _options$annotationMa2.emit({
80
101
  name: 'draftAnnotationStarted',
81
102
  data: {
82
103
  targetElement: targetElement,
@@ -120,6 +141,7 @@ var clearDraft = exports.clearDraft = function clearDraft(editorView, options) {
120
141
  };
121
142
  var applyDraft = exports.applyDraft = function applyDraft(editorView, options) {
122
143
  return function (id) {
144
+ var _options$annotationMa3, _getAnnotationInlineN2;
123
145
  var _ref5 = _utils3.inlineCommentPluginKey.getState(editorView.state) || {},
124
146
  isDrafting = _ref5.isDrafting,
125
147
  draftDecorationSet = _ref5.draftDecorationSet,
@@ -144,6 +166,17 @@ var applyDraft = exports.applyDraft = function applyDraft(editorView, options) {
144
166
  // Using the original decoration from position we should be able to locate the new target element.
145
167
  // This is because the new annotation will be created at the same position as the draft decoration.
146
168
  var targetElement = domRefFromPos(editorView, from);
169
+
170
+ // When a draft is applied it is automatically selected, so we need to set the selected annotation.
171
+ // emit the event for the selected annotation.
172
+ (_options$annotationMa3 = options.annotationManager) === null || _options$annotationMa3 === void 0 || _options$annotationMa3.emit({
173
+ name: 'annotationSelectionChanged',
174
+ data: {
175
+ annotationId: id,
176
+ isSelected: true,
177
+ inlineNodeTypes: (_getAnnotationInlineN2 = (0, _utils.getAnnotationInlineNodeTypes)(editorView.state, id)) !== null && _getAnnotationInlineN2 !== void 0 ? _getAnnotationInlineN2 : []
178
+ }
179
+ });
147
180
  return {
148
181
  success: true,
149
182
  // Get the dom element from the newly created annotation and return it here.
@@ -188,4 +221,133 @@ var getDraft = exports.getDraft = function getDraft(editorView, options) {
188
221
  actionResult: undefined
189
222
  };
190
223
  };
224
+ };
225
+ var setIsAnnotationSelected = exports.setIsAnnotationSelected = function setIsAnnotationSelected(editorView, options) {
226
+ return function (id, isSelected) {
227
+ var _selectedAnnotations$;
228
+ var _ref7 = _utils3.inlineCommentPluginKey.getState(editorView.state) || {},
229
+ annotations = _ref7.annotations,
230
+ isDrafting = _ref7.isDrafting,
231
+ selectedAnnotations = _ref7.selectedAnnotations;
232
+ if (isDrafting) {
233
+ return {
234
+ success: false,
235
+ reason: ERROR_REASON_DRAFT_IN_PROGRESS
236
+ };
237
+ }
238
+
239
+ // If there is no annotation state with this id then we can assume the annotation is invalid.
240
+ if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {
241
+ return {
242
+ success: false,
243
+ reason: ERROR_REASON_ID_INVALID
244
+ };
245
+ }
246
+ var isCurrentlySelectedIndex = (_selectedAnnotations$ = selectedAnnotations === null || selectedAnnotations === void 0 ? void 0 : selectedAnnotations.findIndex(function (annotation) {
247
+ return annotation.id === id;
248
+ })) !== null && _selectedAnnotations$ !== void 0 ? _selectedAnnotations$ : -1;
249
+ var isCurrentlySelected = isCurrentlySelectedIndex !== -1;
250
+ if (isSelected !== isCurrentlySelected) {
251
+ // the annotation is selection is changing.
252
+ if (isCurrentlySelected && !isSelected) {
253
+ var _options$annotationMa4, _getAnnotationInlineN3;
254
+ // the selected annotaion is being unselected, so we need to close the view.
255
+ (0, _editorCommands.closeComponent)()(editorView.state, editorView.dispatch);
256
+ (_options$annotationMa4 = options.annotationManager) === null || _options$annotationMa4 === void 0 || _options$annotationMa4.emit({
257
+ name: 'annotationSelectionChanged',
258
+ data: {
259
+ annotationId: id,
260
+ isSelected: false,
261
+ inlineNodeTypes: (_getAnnotationInlineN3 = (0, _utils.getAnnotationInlineNodeTypes)(editorView.state, id)) !== null && _getAnnotationInlineN3 !== void 0 ? _getAnnotationInlineN3 : []
262
+ }
263
+ });
264
+ } else if (!isCurrentlySelected && isSelected) {
265
+ var _options$annotationMa6, _getAnnotationInlineN5;
266
+ // the annotation is currently not selected and is being selected, so we need to open the view.
267
+ (0, _editorCommands.setSelectedAnnotation)(id)(editorView.state, editorView.dispatch);
268
+
269
+ // the current annotations are going to be unselected. So we need to notify listeners of this change also.
270
+ selectedAnnotations === null || selectedAnnotations === void 0 || selectedAnnotations.forEach(function (annotation) {
271
+ if (annotation.id !== id) {
272
+ var _options$annotationMa5, _getAnnotationInlineN4;
273
+ (_options$annotationMa5 = options.annotationManager) === null || _options$annotationMa5 === void 0 || _options$annotationMa5.emit({
274
+ name: 'annotationSelectionChanged',
275
+ data: {
276
+ annotationId: annotation.id,
277
+ isSelected: false,
278
+ inlineNodeTypes: (_getAnnotationInlineN4 = (0, _utils.getAnnotationInlineNodeTypes)(editorView.state, annotation.id)) !== null && _getAnnotationInlineN4 !== void 0 ? _getAnnotationInlineN4 : []
279
+ }
280
+ });
281
+ }
282
+ });
283
+
284
+ // Lastly we need to emit the event for the selected annotation.
285
+ (_options$annotationMa6 = options.annotationManager) === null || _options$annotationMa6 === void 0 || _options$annotationMa6.emit({
286
+ name: 'annotationSelectionChanged',
287
+ data: {
288
+ annotationId: id,
289
+ isSelected: true,
290
+ inlineNodeTypes: (_getAnnotationInlineN5 = (0, _utils.getAnnotationInlineNodeTypes)(editorView.state, id)) !== null && _getAnnotationInlineN5 !== void 0 ? _getAnnotationInlineN5 : []
291
+ }
292
+ });
293
+ }
294
+ }
295
+ return {
296
+ success: true,
297
+ isSelected: isSelected
298
+ };
299
+ };
300
+ };
301
+ var setIsAnnotationHovered = exports.setIsAnnotationHovered = function setIsAnnotationHovered(editorView, options) {
302
+ return function (id, isHovered) {
303
+ var _hoveredAnnotations$f;
304
+ var _ref8 = _utils3.inlineCommentPluginKey.getState(editorView.state) || {},
305
+ annotations = _ref8.annotations,
306
+ hoveredAnnotations = _ref8.hoveredAnnotations;
307
+
308
+ // If there is no annotation state with this id then we can assume the annotation is invalid.
309
+ if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {
310
+ return {
311
+ success: false,
312
+ reason: ERROR_REASON_ID_INVALID
313
+ };
314
+ }
315
+ var isCurrentlyHoveredIndex = (_hoveredAnnotations$f = hoveredAnnotations === null || hoveredAnnotations === void 0 ? void 0 : hoveredAnnotations.findIndex(function (annotation) {
316
+ return annotation.id === id;
317
+ })) !== null && _hoveredAnnotations$f !== void 0 ? _hoveredAnnotations$f : -1;
318
+ var isCurrentlyHovered = isCurrentlyHoveredIndex !== -1;
319
+ if (isHovered !== isCurrentlyHovered) {
320
+ // the annotation in hovered is changing.
321
+ if (isCurrentlyHovered && !isHovered) {
322
+ // the hovered annotaion is being unhovered, so we should remove the hover state.
323
+ (0, _editorCommands.setHoveredAnnotation)('')(editorView.state, editorView.dispatch);
324
+ } else if (!isCurrentlyHovered && isHovered) {
325
+ // the annotation is currently not hovered and is being hovered.
326
+ (0, _editorCommands.setHoveredAnnotation)(id)(editorView.state, editorView.dispatch);
327
+ }
328
+ }
329
+ return {
330
+ success: true,
331
+ isHovered: isHovered
332
+ };
333
+ };
334
+ };
335
+ var clearAnnotation = exports.clearAnnotation = function clearAnnotation(editorView, options) {
336
+ return function (id) {
337
+ var _ref9 = _utils3.inlineCommentPluginKey.getState(editorView.state) || {},
338
+ annotations = _ref9.annotations;
339
+
340
+ // If there is no annotation state with this id then we can assume the annotation is invalid.
341
+ if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {
342
+ return {
343
+ success: false,
344
+ reason: ERROR_REASON_ID_INVALID
345
+ };
346
+ }
347
+ (0, _editorCommands.removeInlineCommentFromDoc)(id, options.provider.supportedBlockNodes)(editorView.state, editorView.dispatch);
348
+ return {
349
+ success: true,
350
+ actionResult: undefined
351
+ };
352
+ };
191
353
  };
@@ -11,13 +11,14 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
11
11
  var _adfSchema = require("@atlaskit/adf-schema");
12
12
  var _analytics = require("@atlaskit/editor-common/analytics");
13
13
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
14
+ var _utils = require("@atlaskit/editor-common/utils");
14
15
  var _view = require("@atlaskit/editor-prosemirror/view");
15
16
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
17
  var _editorCommands = require("../editor-commands");
17
18
  var _nodeviews = require("../nodeviews");
18
19
  var _annotationManagerHooks = require("./annotation-manager-hooks");
19
20
  var _pluginFactory = require("./plugin-factory");
20
- var _utils = require("./utils");
21
+ var _utils2 = require("./utils");
21
22
  var fetchProviderStates = /*#__PURE__*/function () {
22
23
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(provider, annotationIds) {
23
24
  var data, result;
@@ -104,7 +105,9 @@ var initialState = function initialState() {
104
105
  isVisible: true,
105
106
  skipSelectionHandling: false,
106
107
  featureFlagsPluginState: featureFlagsPluginState,
107
- isDrafting: false
108
+ isDrafting: false,
109
+ pendingSelectedAnnotations: [],
110
+ pendingSelectedAnnotationsUpdateCount: 0
108
111
  };
109
112
  };
110
113
  var hideToolbar = function hideToolbar(state, dispatch) {
@@ -132,7 +135,7 @@ var onUnResolve = function onUnResolve(editorAnalyticsAPI) {
132
135
  };
133
136
  var onMouseUp = function onMouseUp(state, dispatch) {
134
137
  return function (e) {
135
- var _ref3 = (0, _utils.getPluginState)(state) || {},
138
+ var _ref3 = (0, _utils2.getPluginState)(state) || {},
136
139
  mouseData = _ref3.mouseData;
137
140
  if (mouseData !== null && mouseData !== void 0 && mouseData.isSelecting) {
138
141
  (0, _editorCommands.updateMouseState)({
@@ -160,19 +163,40 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
160
163
  featureFlagsPluginState = options.featureFlagsPluginState,
161
164
  annotationManager = options.annotationManager;
162
165
  return new _safePlugin.SafePlugin({
163
- key: _utils.inlineCommentPluginKey,
166
+ key: _utils2.inlineCommentPluginKey,
164
167
  state: (0, _pluginFactory.createPluginState)(options.dispatch, initialState(provider.disallowOnWhitespace, featureFlagsPluginState)),
165
168
  view: function view(editorView) {
169
+ var allowAnnotationFn;
170
+ var startDraftFn;
171
+ var clearDraftFn;
172
+ var applyDraftFn;
173
+ var getDraftFn;
174
+ var setIsAnnotationSelectedFn;
175
+ var setIsAnnotationHoveredFn;
176
+ var clearAnnotationFn;
166
177
  if (annotationManager && (0, _platformFeatureFlags.fg)('platform_editor_comments_api_manager')) {
167
- annotationManager.hook('allowAnnotation', (0, _annotationManagerHooks.allowAnnotation)(editorView, options));
168
- annotationManager.hook('startDraft', (0, _annotationManagerHooks.startDraft)(editorView, options));
169
- annotationManager.hook('clearDraft', (0, _annotationManagerHooks.clearDraft)(editorView, options));
170
- annotationManager.hook('applyDraft', (0, _annotationManagerHooks.applyDraft)(editorView, options));
171
- annotationManager.hook('getDraft', (0, _annotationManagerHooks.getDraft)(editorView, options));
178
+ allowAnnotationFn = (0, _annotationManagerHooks.allowAnnotation)(editorView, options);
179
+ startDraftFn = (0, _annotationManagerHooks.startDraft)(editorView, options);
180
+ clearDraftFn = (0, _annotationManagerHooks.clearDraft)(editorView, options);
181
+ applyDraftFn = (0, _annotationManagerHooks.applyDraft)(editorView, options);
182
+ getDraftFn = (0, _annotationManagerHooks.getDraft)(editorView, options);
183
+ annotationManager.hook('allowAnnotation', allowAnnotationFn);
184
+ annotationManager.hook('startDraft', startDraftFn);
185
+ annotationManager.hook('clearDraft', clearDraftFn);
186
+ annotationManager.hook('applyDraft', applyDraftFn);
187
+ annotationManager.hook('getDraft', getDraftFn);
188
+ if ((0, _platformFeatureFlags.fg)('platform_editor_comments_api_manager_select')) {
189
+ setIsAnnotationSelectedFn = (0, _annotationManagerHooks.setIsAnnotationSelected)(editorView, options);
190
+ setIsAnnotationHoveredFn = (0, _annotationManagerHooks.setIsAnnotationHovered)(editorView, options);
191
+ clearAnnotationFn = (0, _annotationManagerHooks.clearAnnotation)(editorView, options);
192
+ annotationManager.hook('setIsAnnotationSelected', setIsAnnotationSelectedFn);
193
+ annotationManager.hook('setIsAnnotationHovered', setIsAnnotationHoveredFn);
194
+ annotationManager.hook('clearAnnotation', clearAnnotationFn);
195
+ }
172
196
  }
173
197
  // Get initial state
174
198
  // Need to pass `editorView` to mitigate editor state going stale
175
- fetchState(provider, (0, _utils.getAllAnnotations)(editorView.state.doc), editorView, options.editorAnalyticsAPI);
199
+ fetchState(provider, (0, _utils2.getAllAnnotations)(editorView.state.doc), editorView, options.editorAnalyticsAPI);
176
200
  var resolve = function resolve(annotationId) {
177
201
  return onResolve(options.editorAnalyticsAPI)(editorView.state, editorView.dispatch)(annotationId);
178
202
  };
@@ -186,7 +210,7 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
186
210
  return onSetVisibility(editorView)(isVisible);
187
211
  };
188
212
  var setSelectedAnnotationFn = function setSelectedAnnotationFn(annotationId) {
189
- var pluginState = (0, _utils.getPluginState)(editorView.state);
213
+ var pluginState = (0, _utils2.getPluginState)(editorView.state);
190
214
  if ((0, _platformFeatureFlags.fg)('platform_editor_listen_for_focussed_query_param')) {
191
215
  // When feature flag is true, only close if no annotationId
192
216
  if (!annotationId) {
@@ -226,13 +250,20 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
226
250
 
227
251
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
228
252
  editorView.root.addEventListener('mouseup', mouseUp);
253
+
254
+ /**
255
+ * This flag is used to prevent the preemptive gate from being called multiple times while a check is in-flight.
256
+ * If a check is still pending then it's most likely because the product is busy and trying to block the
257
+ * selection of an annotation.
258
+ */
259
+ var isPreemptiveGateActive = false;
229
260
  return {
230
261
  update: function update(view, _prevState) {
231
262
  var _prevSelectedAnnotati;
232
- var _ref4 = (0, _utils.getPluginState)(view.state) || {},
263
+ var _ref4 = (0, _utils2.getPluginState)(view.state) || {},
233
264
  selectedAnnotations = _ref4.selectedAnnotations,
234
265
  annotations = _ref4.annotations;
235
- var _ref5 = (0, _utils.getPluginState)(_prevState) || {},
266
+ var _ref5 = (0, _utils2.getPluginState)(_prevState) || {},
236
267
  prevSelectedAnnotations = _ref5.selectedAnnotations;
237
268
  var selectedAnnotationId = selectedAnnotations && selectedAnnotations.length !== 0 && selectedAnnotations[0].id ? selectedAnnotations[0].id : undefined;
238
269
  // If the new state has an unresolved selected annotation, and it's different from
@@ -246,13 +277,90 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
246
277
  // The selectComponentExperience is using a simplified object, which is why it's type asserted.
247
278
  (_options$selectCommen = options.selectCommentExperience) === null || _options$selectCommen === void 0 || _options$selectCommen.selectAnnotation.complete(selectedAnnotationId);
248
279
  }
249
- var _ref6 = (0, _utils.getPluginState)(view.state) || {},
250
- dirtyAnnotations = _ref6.dirtyAnnotations;
280
+ if ((0, _platformFeatureFlags.fg)('platform_editor_comments_api_manager_select')) {
281
+ // In the Editor, Annotations can be selected in three ways:
282
+ // 1. By clicking on the annotation in the editor
283
+ // 2. By using the annotation manager to select the annotation
284
+ // 3. By moving the cursor to the annotation and using the keyboard to select it
285
+ // Item 1 & 3 need to be protected by the preemptive gate. This is because these actions could be performed by a user
286
+ // at a time when changing the selection could cause data loss.
287
+ // The following preemptive check is designed to cover these items.
288
+
289
+ var _ref6 = (0, _utils2.getPluginState)(view.state) || {},
290
+ pendingSelectedAnnotations = _ref6.pendingSelectedAnnotations,
291
+ pendingSelectedAnnotationsUpdateCount = _ref6.pendingSelectedAnnotationsUpdateCount;
292
+ var _ref7 = (0, _utils2.getPluginState)(_prevState) || {},
293
+ prevPendingSelectedAnnotationsUpdateCount = _ref7.pendingSelectedAnnotationsUpdateCount;
294
+ if (!isPreemptiveGateActive && pendingSelectedAnnotationsUpdateCount !== prevPendingSelectedAnnotationsUpdateCount && !!(pendingSelectedAnnotations !== null && pendingSelectedAnnotations !== void 0 && pendingSelectedAnnotations.length)) {
295
+ // Need to set a lock to avoid calling gate multiple times. The lock will be released
296
+ // when the preemptive gate is complete.
297
+ isPreemptiveGateActive = true;
298
+ annotationManager === null || annotationManager === void 0 || annotationManager.checkPreemptiveGate().then(function (canSelectAnnotation) {
299
+ var _ref8 = (0, _utils2.getPluginState)(view.state) || {},
300
+ isDrafting = _ref8.isDrafting,
301
+ latestPendingSelectedAnnotations = _ref8.pendingSelectedAnnotations,
302
+ latestSelectedAnnotations = _ref8.selectedAnnotations;
303
+ if (canSelectAnnotation) {
304
+ if (isDrafting) {
305
+ // The user must have chosen to discard there draft. So before we flush the pending selections
306
+ // we need to clear the draft if there is one.
307
+ (0, _editorCommands.setInlineCommentDraftState)(options.editorAnalyticsAPI)(false)(view.state, view.dispatch);
308
+ }
309
+
310
+ // Flush the pending selections into the selected annotations list.
311
+ (0, _editorCommands.flushPendingSelections)(true)(view.state, view.dispatch);
312
+ latestSelectedAnnotations === null || latestSelectedAnnotations === void 0 || latestSelectedAnnotations.filter(function (annotation) {
313
+ return (latestPendingSelectedAnnotations === null || latestPendingSelectedAnnotations === void 0 ? void 0 : latestPendingSelectedAnnotations.findIndex(function (pendingAnnotation) {
314
+ return pendingAnnotation.id === annotation.id;
315
+ })) === -1;
316
+ }).forEach(function (annotation) {
317
+ var _options$annotationMa, _getAnnotationInlineN;
318
+ (_options$annotationMa = options.annotationManager) === null || _options$annotationMa === void 0 || _options$annotationMa.emit({
319
+ name: 'annotationSelectionChanged',
320
+ data: {
321
+ annotationId: annotation.id,
322
+ isSelected: false,
323
+ inlineNodeTypes: (_getAnnotationInlineN = (0, _utils.getAnnotationInlineNodeTypes)(editorView.state, annotation.id)) !== null && _getAnnotationInlineN !== void 0 ? _getAnnotationInlineN : []
324
+ }
325
+ });
326
+ });
327
+
328
+ // Notify the annotation manager that the pending selection has changed.
329
+ latestPendingSelectedAnnotations === null || latestPendingSelectedAnnotations === void 0 || latestPendingSelectedAnnotations.forEach(function (_ref9) {
330
+ var _options$annotationMa2, _getAnnotationInlineN2;
331
+ var id = _ref9.id;
332
+ (_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 || _options$annotationMa2.emit({
333
+ name: 'annotationSelectionChanged',
334
+ data: {
335
+ annotationId: id,
336
+ isSelected: true,
337
+ inlineNodeTypes: (_getAnnotationInlineN2 = (0, _utils.getAnnotationInlineNodeTypes)(view.state, id)) !== null && _getAnnotationInlineN2 !== void 0 ? _getAnnotationInlineN2 : []
338
+ }
339
+ });
340
+ });
341
+ } else {
342
+ // Clears the pending selections if the preemptive gate returns false.
343
+ // We should need to worry about dispatching change events here because the pending selections
344
+ // are being aborted and the selections will remain unchanged.
345
+ (0, _editorCommands.flushPendingSelections)(false)(view.state, view.dispatch);
346
+ }
347
+ }).catch(function (error) {
348
+ // TODO: EDITOR-595 - Ensure and anlytic is fired to indicate which reports on the error.
349
+
350
+ // If an error has occured we will clear any pending selections to avoid accidentally setting the wrong thing.
351
+ (0, _editorCommands.flushPendingSelections)(false)(view.state, view.dispatch);
352
+ }).finally(function () {
353
+ isPreemptiveGateActive = false;
354
+ });
355
+ }
356
+ }
357
+ var _ref10 = (0, _utils2.getPluginState)(view.state) || {},
358
+ dirtyAnnotations = _ref10.dirtyAnnotations;
251
359
  if (!dirtyAnnotations) {
252
360
  return;
253
361
  }
254
362
  (0, _editorCommands.clearDirtyMark)()(view.state, view.dispatch);
255
- fetchState(provider, (0, _utils.getAllAnnotations)(view.state.doc), view, options.editorAnalyticsAPI);
363
+ fetchState(provider, (0, _utils2.getAllAnnotations)(view.state.doc), view, options.editorAnalyticsAPI);
256
364
  },
257
365
  destroy: function destroy() {
258
366
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
@@ -260,13 +368,23 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
260
368
  if (updateSubscriber) {
261
369
  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);
262
370
  }
371
+ if (annotationManager && (0, _platformFeatureFlags.fg)('platform_editor_comments_api_manager')) {
372
+ annotationManager.unhook('allowAnnotation', allowAnnotationFn);
373
+ annotationManager.unhook('startDraft', startDraftFn);
374
+ annotationManager.unhook('clearDraft', clearDraftFn);
375
+ annotationManager.unhook('applyDraft', applyDraftFn);
376
+ annotationManager.unhook('getDraft', getDraftFn);
377
+ annotationManager.unhook('setIsAnnotationSelected', setIsAnnotationSelectedFn);
378
+ annotationManager.unhook('setIsAnnotationHovered', setIsAnnotationHoveredFn);
379
+ annotationManager.unhook('clearAnnotation', clearAnnotationFn);
380
+ }
263
381
  }
264
382
  };
265
383
  },
266
384
  props: {
267
385
  handleDOMEvents: {
268
386
  mousedown: function mousedown(view) {
269
- var pluginState = (0, _utils.getPluginState)(view.state);
387
+ var pluginState = (0, _utils2.getPluginState)(view.state);
270
388
  if (!(pluginState !== null && pluginState !== void 0 && pluginState.mouseData.isSelecting)) {
271
389
  hideToolbar(view.state, view.dispatch)();
272
390
  }
@@ -291,7 +409,7 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
291
409
  if (!annotationId) {
292
410
  return false;
293
411
  }
294
- var pluginState = (0, _utils.getPluginState)(view.state);
412
+ var pluginState = (0, _utils2.getPluginState)(view.state);
295
413
  var isSelected = pluginState === null || pluginState === void 0 || (_pluginState$selected = pluginState.selectedAnnotations) === null || _pluginState$selected === void 0 ? void 0 : _pluginState$selected.some(function (selectedAnnotation) {
296
414
  return selectedAnnotation.id === annotationId;
297
415
  });
@@ -300,27 +418,48 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
300
418
  if (isSelected && !(pluginState !== null && pluginState !== void 0 && pluginState.isInlineCommentViewClosed)) {
301
419
  return false;
302
420
  }
303
- var _ref7 = pluginState || {},
304
- annotations = _ref7.annotations;
421
+ var _ref11 = pluginState || {},
422
+ annotations = _ref11.annotations;
305
423
  var isUnresolved = annotations && annotations[annotationId] === false;
306
424
  if (!isUnresolved) {
307
425
  return false;
308
426
  }
309
- (0, _editorCommands.setSelectedAnnotation)(annotationId)(view.state, view.dispatch);
427
+ if ((0, _platformFeatureFlags.fg)('platform_editor_comments_api_manager_select')) {
428
+ var _pluginState$pendingS;
429
+ // The manager disable setting the selected annotation on click because in the editor this is already
430
+ // handled by the selection update handler. When the manager is enabled, and a selection changes it's pushed into
431
+ // the pendingSelectedAnnotations array. This is then used to update the selection when the preemptive gate
432
+ // is released.
433
+ var isPendingSelection = pluginState === null || pluginState === void 0 || (_pluginState$pendingS = pluginState.pendingSelectedAnnotations) === null || _pluginState$pendingS === void 0 ? void 0 : _pluginState$pendingS.some(function (selectedAnnotation) {
434
+ return selectedAnnotation.id === annotationId;
435
+ });
436
+ // If the annotation is selected and the inline comment view is open, do nothing
437
+ // as the user is already in the comment view.
438
+ if (isPendingSelection) {
439
+ return false;
440
+ }
441
+ (0, _editorCommands.setPendingSelectedAnnotation)(annotationId)(view.state, view.dispatch);
442
+ } else {
443
+ (0, _editorCommands.setSelectedAnnotation)(annotationId)(view.state, view.dispatch);
444
+ }
310
445
  return true;
311
446
  }
312
447
  },
313
448
  decorations: function decorations(state) {
314
449
  // highlight comments, depending on state
315
- var _ref8 = (0, _utils.getPluginState)(state) || {},
316
- draftDecorationSet = _ref8.draftDecorationSet,
317
- annotations = _ref8.annotations,
318
- selectedAnnotations = _ref8.selectedAnnotations,
319
- isVisible = _ref8.isVisible,
320
- isInlineCommentViewClosed = _ref8.isInlineCommentViewClosed,
321
- hoveredAnnotations = _ref8.hoveredAnnotations;
450
+ var _ref12 = (0, _utils2.getPluginState)(state) || {},
451
+ draftDecorationSet = _ref12.draftDecorationSet,
452
+ annotations = _ref12.annotations,
453
+ selectedAnnotations = _ref12.selectedAnnotations,
454
+ isVisible = _ref12.isVisible,
455
+ isInlineCommentViewClosed = _ref12.isInlineCommentViewClosed,
456
+ hoveredAnnotations = _ref12.hoveredAnnotations;
322
457
  var decorations = draftDecorationSet !== null && draftDecorationSet !== void 0 ? draftDecorationSet : _view.DecorationSet.empty;
323
458
  var focusDecorations = [];
459
+
460
+ // TODO: EDITOR-760 - This needs to be optimised, it's not a good idea to scan the entire document
461
+ // everytime we need to update the decorations. This handler will be called alot. We should be caching
462
+ // the decorations in plugin state and only updating them when required.
324
463
  state.doc.descendants(function (node, pos) {
325
464
  var _provider$supportedBl;
326
465
  // Inline comment on mediaInline is not supported as part of comments on media project
@@ -344,7 +483,7 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
344
483
  focusDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
345
484
  class: "".concat((0, _nodeviews.getBlockAnnotationViewClassname)(isUnresolved, isSelected), " ").concat(isUnresolved)
346
485
  }, {
347
- key: _utils.decorationKey.block
486
+ key: _utils2.decorationKey.block
348
487
  }));
349
488
  } else {
350
489
  if ((0, _platformFeatureFlags.fg)('editor_inline_comments_on_inline_nodes')) {
@@ -357,7 +496,7 @@ var inlineCommentPlugin = exports.inlineCommentPlugin = function inlineCommentPl
357
496
  focusDecorations.push(_view.Decoration.node(pos, pos + node.nodeSize, {
358
497
  class: "".concat((0, _nodeviews.getAnnotationViewClassname)(isUnresolved, isSelected, isHovered), " ").concat(isUnresolved)
359
498
  }, {
360
- key: _utils.decorationKey.block
499
+ key: _utils2.decorationKey.block
361
500
  }));
362
501
  }
363
502
  } else {