@atlaskit/editor-plugin-annotation 27.0.6 → 28.1.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.
@@ -1,14 +1,18 @@
1
1
  import { AnnotationTypes } from '@atlaskit/adf-schema/annotation';
2
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
3
  import { getAnnotationInlineNodeTypes, getRangeInlineNodeNames } from '@atlaskit/editor-common/utils/annotation';
4
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
5
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
4
6
  import { setInlineCommentDraftState, createAnnotation, setSelectedAnnotation, closeComponent, setHoveredAnnotation, removeInlineCommentFromDoc } from '../editor-commands';
5
7
  import { AnnotationSelectionType } from '../types';
8
+ import { resolveAnnotatableTargetFromLocalId } from './resolve-annotatable-target';
6
9
  import { inlineCommentPluginKey, isSelectionValid } from './utils';
7
10
  const ERROR_REASON_DRAFT_NOT_STARTED = 'draft-not-started';
8
11
  const ERROR_REASON_DRAFT_IN_PROGRESS = 'draft-in-progress';
9
12
  const ERROR_REASON_RANGE_MISSING = 'range-no-longer-exists';
10
13
  const ERROR_REASON_RANGE_INVALID = 'invalid-range';
11
14
  const ERROR_REASON_ID_INVALID = 'id-not-valid';
15
+ const ERROR_REASON_INVALID_LOCAL_ID = 'invalid-localId';
12
16
  const domRefFromPos = (view, position) => {
13
17
  let dom;
14
18
  try {
@@ -38,8 +42,8 @@ export const allowAnnotation = (editorView, options) => () => {
38
42
  }
39
43
  return isSelectionValid(editorView.state, options.provider.supportedBlockNodes, options.provider.isBlockNodeSupported) === AnnotationSelectionType.VALID;
40
44
  };
41
- export const startDraft = (editorView, options) => () => {
42
- var _getRangeInlineNodeNa, _options$annotationMa2;
45
+ export const startDraft = (editorView, options) => localId => {
46
+ var _getRangeInlineNodeNa2, _options$annotationMa3;
43
47
  const {
44
48
  isDrafting,
45
49
  selectedAnnotations
@@ -68,6 +72,71 @@ export const startDraft = (editorView, options) => () => {
68
72
  });
69
73
  });
70
74
  }
75
+ if (localId !== undefined) {
76
+ var _$target$parent, _target$node$attrs$id, _getRangeInlineNodeNa, _options$annotationMa2;
77
+ const target = resolveAnnotatableTargetFromLocalId(editorView.state, localId, {
78
+ supportedBlockNodes: options.provider.supportedBlockNodes
79
+ });
80
+ if (!target) {
81
+ return {
82
+ success: false,
83
+ reason: ERROR_REASON_INVALID_LOCAL_ID
84
+ };
85
+ }
86
+
87
+ // The resolver returns the node accepting the annotation (the inner `media`), but
88
+ // `isSelectionValid` requires the selection to be on the selectable `mediaSingle`.
89
+ const {
90
+ doc
91
+ } = editorView.state;
92
+ let selectionPos = target.pos;
93
+ const $target = doc.resolve(target.pos);
94
+ if (target.node.type.name === 'media' && ((_$target$parent = $target.parent) === null || _$target$parent === void 0 ? void 0 : _$target$parent.type.name) === 'mediaSingle') {
95
+ selectionPos = $target.before();
96
+ }
97
+
98
+ // A NodeSelection makes resolveDraftBookmark record isBlockNode: true.
99
+ editorView.dispatch(editorView.state.tr.setSelection(NodeSelection.create(doc, selectionPos)));
100
+ const targetNodeId = (_target$node$attrs$id = target.node.attrs.id) !== null && _target$node$attrs$id !== void 0 ? _target$node$attrs$id : target.node.attrs.localId;
101
+ setInlineCommentDraftState(options.editorAnalyticsAPI, options.provider.supportedBlockNodes, options.api, options.provider.isBlockNodeSupported)(true, INPUT_METHOD.FLOATING_TB, 'block', targetNodeId, true)(editorView.state, editorView.dispatch);
102
+ const {
103
+ draftDecorationSet
104
+ } = inlineCommentPluginKey.getState(editorView.state) || {};
105
+ const decorations = draftDecorationSet === null || draftDecorationSet === void 0 ? void 0 : draftDecorationSet.find();
106
+ if (!(decorations !== null && decorations !== void 0 && decorations.length)) {
107
+ return {
108
+ success: false,
109
+ reason: ERROR_REASON_RANGE_INVALID
110
+ };
111
+ }
112
+ const from = decorations[0].from;
113
+ const targetElement = domRefFromPos(editorView, from);
114
+ const inlineNodeTypes = (_getRangeInlineNodeNa = getRangeInlineNodeNames({
115
+ doc: editorView.state.doc,
116
+ pos: {
117
+ from,
118
+ to: decorations[decorations.length - 1].to
119
+ }
120
+ })) !== null && _getRangeInlineNodeNa !== void 0 ? _getRangeInlineNodeNa : [];
121
+ const targetNodeType = target.node.type.name;
122
+ (_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 ? void 0 : _options$annotationMa2.emit({
123
+ name: 'draftAnnotationStarted',
124
+ data: {
125
+ targetElement,
126
+ actionResult: undefined,
127
+ inlineNodeTypes,
128
+ targetNodeType
129
+ }
130
+ });
131
+ return {
132
+ success: true,
133
+ targetElement,
134
+ // In Editor the action result is undefined, because the editor will perform the transaction on the document.
135
+ actionResult: undefined,
136
+ inlineNodeTypes,
137
+ targetNodeType
138
+ };
139
+ }
71
140
  setInlineCommentDraftState(options.editorAnalyticsAPI, options.provider.supportedBlockNodes, options.api, options.provider.isBlockNodeSupported)(true)(editorView.state, editorView.dispatch);
72
141
  const {
73
142
  draftDecorationSet
@@ -83,14 +152,14 @@ export const startDraft = (editorView, options) => () => {
83
152
  }
84
153
  const from = decorations[0].from;
85
154
  const targetElement = domRefFromPos(editorView, from);
86
- const inlineNodeTypes = (_getRangeInlineNodeNa = getRangeInlineNodeNames({
155
+ const inlineNodeTypes = (_getRangeInlineNodeNa2 = getRangeInlineNodeNames({
87
156
  doc: editorView.state.doc,
88
157
  pos: {
89
158
  from,
90
159
  to: decorations[decorations.length - 1].to
91
160
  }
92
- })) !== null && _getRangeInlineNodeNa !== void 0 ? _getRangeInlineNodeNa : [];
93
- (_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 ? void 0 : _options$annotationMa2.emit({
161
+ })) !== null && _getRangeInlineNodeNa2 !== void 0 ? _getRangeInlineNodeNa2 : [];
162
+ (_options$annotationMa3 = options.annotationManager) === null || _options$annotationMa3 === void 0 ? void 0 : _options$annotationMa3.emit({
94
163
  name: 'draftAnnotationStarted',
95
164
  data: {
96
165
  targetElement,
@@ -107,6 +176,7 @@ export const startDraft = (editorView, options) => () => {
107
176
  };
108
177
  };
109
178
  export const clearDraft = (editorView, options) => () => {
179
+ var _options$annotationMa4;
110
180
  const {
111
181
  isDrafting,
112
182
  draftDecorationSet
@@ -126,12 +196,15 @@ export const clearDraft = (editorView, options) => () => {
126
196
  }
127
197
  setInlineCommentDraftState(options.editorAnalyticsAPI, undefined, options.api)(false)(editorView.state, editorView.dispatch);
128
198
  !editorView.hasFocus() && editorView.focus();
199
+ (_options$annotationMa4 = options.annotationManager) === null || _options$annotationMa4 === void 0 ? void 0 : _options$annotationMa4.emit({
200
+ name: 'draftAnnotationCleared'
201
+ });
129
202
  return {
130
203
  success: true
131
204
  };
132
205
  };
133
206
  export const applyDraft = (editorView, options) => id => {
134
- var _options$annotationMa3, _getAnnotationInlineN2;
207
+ var _options$annotationMa5, _getAnnotationInlineN2;
135
208
  const {
136
209
  isDrafting,
137
210
  draftDecorationSet,
@@ -160,7 +233,7 @@ export const applyDraft = (editorView, options) => id => {
160
233
 
161
234
  // When a draft is applied it is automatically selected, so we need to set the selected annotation.
162
235
  // emit the event for the selected annotation.
163
- (_options$annotationMa3 = options.annotationManager) === null || _options$annotationMa3 === void 0 ? void 0 : _options$annotationMa3.emit({
236
+ (_options$annotationMa5 = options.annotationManager) === null || _options$annotationMa5 === void 0 ? void 0 : _options$annotationMa5.emit({
164
237
  name: 'annotationSelectionChanged',
165
238
  data: {
166
239
  annotationId: id,
@@ -177,7 +250,7 @@ export const applyDraft = (editorView, options) => id => {
177
250
  };
178
251
  };
179
252
  export const getDraft = (editorView, _options) => () => {
180
- var _getRangeInlineNodeNa2;
253
+ var _getRangeInlineNodeNa3;
181
254
  const {
182
255
  isDrafting,
183
256
  draftDecorationSet
@@ -197,13 +270,13 @@ export const getDraft = (editorView, _options) => () => {
197
270
  }
198
271
  const from = decorations[0].from;
199
272
  const targetElement = domRefFromPos(editorView, from);
200
- const inlineNodeTypes = (_getRangeInlineNodeNa2 = getRangeInlineNodeNames({
273
+ const inlineNodeTypes = (_getRangeInlineNodeNa3 = getRangeInlineNodeNames({
201
274
  doc: editorView.state.doc,
202
275
  pos: {
203
276
  from,
204
277
  to: decorations[decorations.length - 1].to
205
278
  }
206
- })) !== null && _getRangeInlineNodeNa2 !== void 0 ? _getRangeInlineNodeNa2 : [];
279
+ })) !== null && _getRangeInlineNodeNa3 !== void 0 ? _getRangeInlineNodeNa3 : [];
207
280
  return {
208
281
  success: true,
209
282
  inlineNodeTypes,
@@ -237,10 +310,10 @@ export const setIsAnnotationSelected = (editorView, options) => (id, isSelected)
237
310
  if (isSelected !== isCurrentlySelected) {
238
311
  // the annotation is selection is changing.
239
312
  if (isCurrentlySelected && !isSelected) {
240
- var _options$annotationMa4, _getAnnotationInlineN3;
313
+ var _options$annotationMa6, _getAnnotationInlineN3;
241
314
  // the selected annotaion is being unselected, so we need to close the view.
242
315
  closeComponent()(editorView.state, editorView.dispatch);
243
- (_options$annotationMa4 = options.annotationManager) === null || _options$annotationMa4 === void 0 ? void 0 : _options$annotationMa4.emit({
316
+ (_options$annotationMa6 = options.annotationManager) === null || _options$annotationMa6 === void 0 ? void 0 : _options$annotationMa6.emit({
244
317
  name: 'annotationSelectionChanged',
245
318
  data: {
246
319
  annotationId: id,
@@ -249,15 +322,15 @@ export const setIsAnnotationSelected = (editorView, options) => (id, isSelected)
249
322
  }
250
323
  });
251
324
  } else if (!isCurrentlySelected && isSelected) {
252
- var _options$annotationMa6, _getAnnotationInlineN5;
325
+ var _options$annotationMa8, _getAnnotationInlineN5;
253
326
  // the annotation is currently not selected and is being selected, so we need to open the view.
254
327
  setSelectedAnnotation(id)(editorView.state, editorView.dispatch);
255
328
 
256
329
  // the current annotations are going to be unselected. So we need to notify listeners of this change also.
257
330
  selectedAnnotations === null || selectedAnnotations === void 0 ? void 0 : selectedAnnotations.forEach(annotation => {
258
331
  if (annotation.id !== id) {
259
- var _options$annotationMa5, _getAnnotationInlineN4;
260
- (_options$annotationMa5 = options.annotationManager) === null || _options$annotationMa5 === void 0 ? void 0 : _options$annotationMa5.emit({
332
+ var _options$annotationMa7, _getAnnotationInlineN4;
333
+ (_options$annotationMa7 = options.annotationManager) === null || _options$annotationMa7 === void 0 ? void 0 : _options$annotationMa7.emit({
261
334
  name: 'annotationSelectionChanged',
262
335
  data: {
263
336
  annotationId: annotation.id,
@@ -269,7 +342,7 @@ export const setIsAnnotationSelected = (editorView, options) => (id, isSelected)
269
342
  });
270
343
 
271
344
  // Lastly we need to emit the event for the selected annotation.
272
- (_options$annotationMa6 = options.annotationManager) === null || _options$annotationMa6 === void 0 ? void 0 : _options$annotationMa6.emit({
345
+ (_options$annotationMa8 = options.annotationManager) === null || _options$annotationMa8 === void 0 ? void 0 : _options$annotationMa8.emit({
273
346
  name: 'annotationSelectionChanged',
274
347
  data: {
275
348
  annotationId: id,
@@ -90,6 +90,13 @@ export var annotationPlugin = function annotationPlugin(_ref) {
90
90
  var _annotationProviders$, _annotationProviders$2;
91
91
  return fg('cc_maui_annotations_on_extensions') && (annotationProviders === null || annotationProviders === void 0 || (_annotationProviders$ = (_annotationProviders$2 = annotationProviders.inlineComment).isBlockNodeSupported) === null || _annotationProviders$ === void 0 ? void 0 : _annotationProviders$.call(_annotationProviders$2, node)) === true;
92
92
  },
93
+ getAddCommentPermission: function getAddCommentPermission() {
94
+ var _annotationProviders$3, _annotationProviders$4, _annotationProviders$5;
95
+ return {
96
+ canAddComments: (_annotationProviders$3 = annotationProviders === null || annotationProviders === void 0 || (_annotationProviders$4 = (_annotationProviders$5 = annotationProviders.inlineComment).getCanAddComments) === null || _annotationProviders$4 === void 0 ? void 0 : _annotationProviders$4.call(_annotationProviders$5)) !== null && _annotationProviders$3 !== void 0 ? _annotationProviders$3 : true,
97
+ contentType: annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.contentType
98
+ };
99
+ },
93
100
  hasAnyUnResolvedAnnotationInPage: hasAnyUnResolvedAnnotationInPage,
94
101
  requestCloseInlineComment: requestCloseInlineComment,
95
102
  stripNonExistingAnnotations: stripNonExistingAnnotations,
@@ -98,10 +105,10 @@ export var annotationPlugin = function annotationPlugin(_ref) {
98
105
  return createAnnotation(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, api)(annotationId, AnnotationTypes.INLINE_COMMENT, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.isBlockNodeSupported);
99
106
  },
100
107
  removeInlineCommentAnnotation: function removeInlineCommentAnnotation(annotationId) {
101
- var _api$analytics2, _annotationProviders$3;
102
- return removeInlineCommentFromDoc(api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions)(annotationId, (_annotationProviders$3 = annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes) !== null && _annotationProviders$3 !== void 0 ? _annotationProviders$3 : [], annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.isBlockNodeSupported);
108
+ var _api$analytics2, _annotationProviders$6;
109
+ return removeInlineCommentFromDoc(api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions)(annotationId, (_annotationProviders$6 = annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes) !== null && _annotationProviders$6 !== void 0 ? _annotationProviders$6 : [], annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.isBlockNodeSupported);
103
110
  },
104
- setInlineCommentDraftState: setInlineCommentDraftState(api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes, undefined, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.isBlockNodeSupported),
111
+ setInlineCommentDraftState: setInlineCommentDraftState(api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes, undefined, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.isBlockNodeSupported, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.createCommentExperience),
105
112
  showCommentForBlockNode: showInlineCommentForBlockNode(annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.isBlockNodeSupported),
106
113
  setSelectedAnnotation: setSelectedAnnotation,
107
114
  setPendingSelectedAnnotation: setPendingSelectedAnnotation
@@ -113,7 +120,9 @@ export var annotationPlugin = function annotationPlugin(_ref) {
113
120
  var pluginState = getPluginState(editorState) || undefined;
114
121
  var clonedPluginState = Object.assign({}, pluginState);
115
122
  clonedPluginState === null || clonedPluginState === void 0 || delete clonedPluginState.featureFlagsPluginState;
116
- return clonedPluginState;
123
+ return _objectSpread(_objectSpread({}, clonedPluginState), {}, {
124
+ annotationManager: annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.annotationManager
125
+ });
117
126
  },
118
127
  pmPlugins: function pmPlugins() {
119
128
  return [{
@@ -166,11 +175,11 @@ export var annotationPlugin = function annotationPlugin(_ref) {
166
175
  var pluginState = getPluginState(state);
167
176
  if (pluginState && pluginState.isVisible && !pluginState.bookmark && !pluginState.mouseData.isSelecting) {
168
177
  var _api$analytics5;
169
- var _annotationProviders$4 = annotationProviders.inlineComment,
170
- isToolbarAbove = _annotationProviders$4.isToolbarAbove,
171
- onCommentButtonMount = _annotationProviders$4.onCommentButtonMount,
172
- getCanAddComments = _annotationProviders$4.getCanAddComments,
173
- contentType = _annotationProviders$4.contentType;
178
+ var _annotationProviders$7 = annotationProviders.inlineComment,
179
+ isToolbarAbove = _annotationProviders$7.isToolbarAbove,
180
+ onCommentButtonMount = _annotationProviders$7.onCommentButtonMount,
181
+ getCanAddComments = _annotationProviders$7.getCanAddComments,
182
+ contentType = _annotationProviders$7.contentType;
174
183
  var toolbarConfig = buildToolbar(api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions)({
175
184
  state: state,
176
185
  intl: intl,
@@ -4,7 +4,9 @@ import { AnnotationTypes } from '@atlaskit/adf-schema/annotation';
4
4
 
5
5
  import { INPUT_METHOD } from '@atlaskit/editor-common/analytics/types/enums';
6
6
  import { RESOLVE_METHOD } from '@atlaskit/editor-common/analytics/types/inline-comment-events';
7
+ import { NATIVE_EMBED_EXTENSION_KEY } from '@atlaskit/editor-common/extensions/manifest-helpers';
7
8
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
9
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
8
10
  import { createCommand } from '../pm-plugins/plugin-factory';
9
11
  import { ACTIONS } from '../pm-plugins/types';
10
12
  import { getPluginState, inlineCommentPluginKey, isSelectionValid, isSupportedBlockNode } from '../pm-plugins/utils';
@@ -243,16 +245,35 @@ export var setInlineCommentDraftState = function setInlineCommentDraftState(edit
243
245
  var supportedBlockNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
244
246
  var api = arguments.length > 2 ? arguments[2] : undefined;
245
247
  var isBlockNodeSupported = arguments.length > 3 ? arguments[3] : undefined;
248
+ var createCommentExperience = arguments.length > 4 ? arguments[4] : undefined;
246
249
  return function (drafting) {
247
250
  var inputMethod = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : INPUT_METHOD.TOOLBAR;
248
251
  var targetType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'inline';
249
252
  var targetNodeId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
250
253
  var isOpeningMediaCommentFromToolbar = arguments.length > 4 ? arguments[4] : undefined;
251
254
  var commandAction = getDraftCommandAction(drafting, targetType, targetNodeId, supportedBlockNodes, isBlockNodeSupported, isOpeningMediaCommentFromToolbar);
252
- if (Boolean(api === null || api === void 0 ? void 0 : api.toolbar)) {
253
- return function (state, dispatch) {
254
- var tr = transform.handleDraftState(editorAnalyticsAPI)(drafting, inputMethod)(state.tr, state);
255
+ var draftCommand = !(api !== null && api !== void 0 && api.toolbar) ? createCommand(commandAction, transform.handleDraftState(editorAnalyticsAPI)(drafting, inputMethod)) : undefined;
256
+ return function (state, dispatch, view) {
257
+ // Start tracking only when a valid draft is dispatched, never during dry runs.
258
+ var dispatchDraft = dispatch && drafting && targetType === 'block' && state.selection instanceof NodeSelection && state.selection.node.type.name === 'extension' && state.selection.node.attrs.extensionKey === "".concat(NATIVE_EMBED_EXTENSION_KEY, ":maui") && fg('cc_maui_annotations_on_extensions') ? function (tr) {
259
+ createCommentExperience === null || createCommentExperience === void 0 || createCommentExperience.start({
260
+ attributes: {
261
+ pageClass: 'editor',
262
+ commentType: 'block',
263
+ blockType: 'extension',
264
+ commentTargetType: 'remixEmbed',
265
+ entryPoint: 'highlightActions'
266
+ }
267
+ });
268
+ createCommentExperience === null || createCommentExperience === void 0 || createCommentExperience.initExperience.start();
269
+ dispatch(tr);
270
+ } : dispatch;
271
+ if (Boolean(api === null || api === void 0 ? void 0 : api.toolbar)) {
255
272
  var newPluginState = commandAction(state);
273
+ if (!newPluginState) {
274
+ return false;
275
+ }
276
+ var tr = transform.handleDraftState(editorAnalyticsAPI)(drafting, inputMethod)(state.tr, state);
256
277
  if (tr && newPluginState) {
257
278
  tr.setMeta(inlineCommentPluginKey, newPluginState);
258
279
  if (drafting) {
@@ -260,17 +281,16 @@ export var setInlineCommentDraftState = function setInlineCommentDraftState(edit
260
281
  } else {
261
282
  resetUserIntent(api, tr);
262
283
  }
263
- if (dispatch) {
264
- dispatch(tr);
284
+ if (dispatchDraft) {
285
+ dispatchDraft(tr);
265
286
  }
266
287
  } else {
267
288
  return false;
268
289
  }
269
290
  return true;
270
- };
271
- } else {
272
- return createCommand(commandAction, transform.handleDraftState(editorAnalyticsAPI)(drafting, inputMethod));
273
- }
291
+ }
292
+ return draftCommand ? draftCommand(state, dispatchDraft, view) : false;
293
+ };
274
294
  };
275
295
  };
276
296
  export var addInlineComment = function addInlineComment(editorAnalyticsAPI, editorAPI) {
@@ -1,14 +1,18 @@
1
1
  import { AnnotationTypes } from '@atlaskit/adf-schema/annotation';
2
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
3
  import { getAnnotationInlineNodeTypes, getRangeInlineNodeNames } from '@atlaskit/editor-common/utils/annotation';
4
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
3
5
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
4
6
  import { setInlineCommentDraftState, createAnnotation, setSelectedAnnotation, closeComponent, setHoveredAnnotation, removeInlineCommentFromDoc } from '../editor-commands';
5
7
  import { AnnotationSelectionType } from '../types';
8
+ import { resolveAnnotatableTargetFromLocalId } from './resolve-annotatable-target';
6
9
  import { inlineCommentPluginKey, isSelectionValid } from './utils';
7
10
  var ERROR_REASON_DRAFT_NOT_STARTED = 'draft-not-started';
8
11
  var ERROR_REASON_DRAFT_IN_PROGRESS = 'draft-in-progress';
9
12
  var ERROR_REASON_RANGE_MISSING = 'range-no-longer-exists';
10
13
  var ERROR_REASON_RANGE_INVALID = 'invalid-range';
11
14
  var ERROR_REASON_ID_INVALID = 'id-not-valid';
15
+ var ERROR_REASON_INVALID_LOCAL_ID = 'invalid-localId';
12
16
  var domRefFromPos = function domRefFromPos(view, position) {
13
17
  var dom;
14
18
  try {
@@ -40,8 +44,8 @@ export var allowAnnotation = function allowAnnotation(editorView, options) {
40
44
  };
41
45
  };
42
46
  export var startDraft = function startDraft(editorView, options) {
43
- return function () {
44
- var _getRangeInlineNodeNa, _options$annotationMa2;
47
+ return function (localId) {
48
+ var _getRangeInlineNodeNa2, _options$annotationMa3;
45
49
  var _ref2 = inlineCommentPluginKey.getState(editorView.state) || {},
46
50
  isDrafting = _ref2.isDrafting,
47
51
  selectedAnnotations = _ref2.selectedAnnotations;
@@ -69,9 +73,71 @@ export var startDraft = function startDraft(editorView, options) {
69
73
  });
70
74
  });
71
75
  }
76
+ if (localId !== undefined) {
77
+ var _$target$parent, _target$node$attrs$id, _getRangeInlineNodeNa, _options$annotationMa2;
78
+ var target = resolveAnnotatableTargetFromLocalId(editorView.state, localId, {
79
+ supportedBlockNodes: options.provider.supportedBlockNodes
80
+ });
81
+ if (!target) {
82
+ return {
83
+ success: false,
84
+ reason: ERROR_REASON_INVALID_LOCAL_ID
85
+ };
86
+ }
87
+
88
+ // The resolver returns the node accepting the annotation (the inner `media`), but
89
+ // `isSelectionValid` requires the selection to be on the selectable `mediaSingle`.
90
+ var doc = editorView.state.doc;
91
+ var selectionPos = target.pos;
92
+ var $target = doc.resolve(target.pos);
93
+ if (target.node.type.name === 'media' && ((_$target$parent = $target.parent) === null || _$target$parent === void 0 ? void 0 : _$target$parent.type.name) === 'mediaSingle') {
94
+ selectionPos = $target.before();
95
+ }
96
+
97
+ // A NodeSelection makes resolveDraftBookmark record isBlockNode: true.
98
+ editorView.dispatch(editorView.state.tr.setSelection(NodeSelection.create(doc, selectionPos)));
99
+ var targetNodeId = (_target$node$attrs$id = target.node.attrs.id) !== null && _target$node$attrs$id !== void 0 ? _target$node$attrs$id : target.node.attrs.localId;
100
+ setInlineCommentDraftState(options.editorAnalyticsAPI, options.provider.supportedBlockNodes, options.api, options.provider.isBlockNodeSupported)(true, INPUT_METHOD.FLOATING_TB, 'block', targetNodeId, true)(editorView.state, editorView.dispatch);
101
+ var _ref3 = inlineCommentPluginKey.getState(editorView.state) || {},
102
+ _draftDecorationSet = _ref3.draftDecorationSet;
103
+ var _decorations = _draftDecorationSet === null || _draftDecorationSet === void 0 ? void 0 : _draftDecorationSet.find();
104
+ if (!(_decorations !== null && _decorations !== void 0 && _decorations.length)) {
105
+ return {
106
+ success: false,
107
+ reason: ERROR_REASON_RANGE_INVALID
108
+ };
109
+ }
110
+ var _from = _decorations[0].from;
111
+ var _targetElement = domRefFromPos(editorView, _from);
112
+ var _inlineNodeTypes = (_getRangeInlineNodeNa = getRangeInlineNodeNames({
113
+ doc: editorView.state.doc,
114
+ pos: {
115
+ from: _from,
116
+ to: _decorations[_decorations.length - 1].to
117
+ }
118
+ })) !== null && _getRangeInlineNodeNa !== void 0 ? _getRangeInlineNodeNa : [];
119
+ var targetNodeType = target.node.type.name;
120
+ (_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 || _options$annotationMa2.emit({
121
+ name: 'draftAnnotationStarted',
122
+ data: {
123
+ targetElement: _targetElement,
124
+ actionResult: undefined,
125
+ inlineNodeTypes: _inlineNodeTypes,
126
+ targetNodeType: targetNodeType
127
+ }
128
+ });
129
+ return {
130
+ success: true,
131
+ targetElement: _targetElement,
132
+ // In Editor the action result is undefined, because the editor will perform the transaction on the document.
133
+ actionResult: undefined,
134
+ inlineNodeTypes: _inlineNodeTypes,
135
+ targetNodeType: targetNodeType
136
+ };
137
+ }
72
138
  setInlineCommentDraftState(options.editorAnalyticsAPI, options.provider.supportedBlockNodes, options.api, options.provider.isBlockNodeSupported)(true)(editorView.state, editorView.dispatch);
73
- var _ref3 = inlineCommentPluginKey.getState(editorView.state) || {},
74
- draftDecorationSet = _ref3.draftDecorationSet;
139
+ var _ref4 = inlineCommentPluginKey.getState(editorView.state) || {},
140
+ draftDecorationSet = _ref4.draftDecorationSet;
75
141
  var decorations = draftDecorationSet === null || draftDecorationSet === void 0 ? void 0 : draftDecorationSet.find();
76
142
 
77
143
  // If the matching decorations is not found containing the id, it means something went wrong with the draft.
@@ -83,14 +149,14 @@ export var startDraft = function startDraft(editorView, options) {
83
149
  }
84
150
  var from = decorations[0].from;
85
151
  var targetElement = domRefFromPos(editorView, from);
86
- var inlineNodeTypes = (_getRangeInlineNodeNa = getRangeInlineNodeNames({
152
+ var inlineNodeTypes = (_getRangeInlineNodeNa2 = getRangeInlineNodeNames({
87
153
  doc: editorView.state.doc,
88
154
  pos: {
89
155
  from: from,
90
156
  to: decorations[decorations.length - 1].to
91
157
  }
92
- })) !== null && _getRangeInlineNodeNa !== void 0 ? _getRangeInlineNodeNa : [];
93
- (_options$annotationMa2 = options.annotationManager) === null || _options$annotationMa2 === void 0 || _options$annotationMa2.emit({
158
+ })) !== null && _getRangeInlineNodeNa2 !== void 0 ? _getRangeInlineNodeNa2 : [];
159
+ (_options$annotationMa3 = options.annotationManager) === null || _options$annotationMa3 === void 0 || _options$annotationMa3.emit({
94
160
  name: 'draftAnnotationStarted',
95
161
  data: {
96
162
  targetElement: targetElement,
@@ -109,9 +175,10 @@ export var startDraft = function startDraft(editorView, options) {
109
175
  };
110
176
  export var clearDraft = function clearDraft(editorView, options) {
111
177
  return function () {
112
- var _ref4 = inlineCommentPluginKey.getState(editorView.state) || {},
113
- isDrafting = _ref4.isDrafting,
114
- draftDecorationSet = _ref4.draftDecorationSet;
178
+ var _options$annotationMa4;
179
+ var _ref5 = inlineCommentPluginKey.getState(editorView.state) || {},
180
+ isDrafting = _ref5.isDrafting,
181
+ draftDecorationSet = _ref5.draftDecorationSet;
115
182
  if (!isDrafting) {
116
183
  return {
117
184
  success: false,
@@ -127,6 +194,9 @@ export var clearDraft = function clearDraft(editorView, options) {
127
194
  }
128
195
  setInlineCommentDraftState(options.editorAnalyticsAPI, undefined, options.api)(false)(editorView.state, editorView.dispatch);
129
196
  !editorView.hasFocus() && editorView.focus();
197
+ (_options$annotationMa4 = options.annotationManager) === null || _options$annotationMa4 === void 0 || _options$annotationMa4.emit({
198
+ name: 'draftAnnotationCleared'
199
+ });
130
200
  return {
131
201
  success: true
132
202
  };
@@ -134,11 +204,11 @@ export var clearDraft = function clearDraft(editorView, options) {
134
204
  };
135
205
  export var applyDraft = function applyDraft(editorView, options) {
136
206
  return function (id) {
137
- var _options$annotationMa3, _getAnnotationInlineN2;
138
- var _ref5 = inlineCommentPluginKey.getState(editorView.state) || {},
139
- isDrafting = _ref5.isDrafting,
140
- draftDecorationSet = _ref5.draftDecorationSet,
141
- bookmark = _ref5.bookmark;
207
+ var _options$annotationMa5, _getAnnotationInlineN2;
208
+ var _ref6 = inlineCommentPluginKey.getState(editorView.state) || {},
209
+ isDrafting = _ref6.isDrafting,
210
+ draftDecorationSet = _ref6.draftDecorationSet,
211
+ bookmark = _ref6.bookmark;
142
212
  if (!isDrafting) {
143
213
  return {
144
214
  success: false,
@@ -162,7 +232,7 @@ export var applyDraft = function applyDraft(editorView, options) {
162
232
 
163
233
  // When a draft is applied it is automatically selected, so we need to set the selected annotation.
164
234
  // emit the event for the selected annotation.
165
- (_options$annotationMa3 = options.annotationManager) === null || _options$annotationMa3 === void 0 || _options$annotationMa3.emit({
235
+ (_options$annotationMa5 = options.annotationManager) === null || _options$annotationMa5 === void 0 || _options$annotationMa5.emit({
166
236
  name: 'annotationSelectionChanged',
167
237
  data: {
168
238
  annotationId: id,
@@ -181,10 +251,10 @@ export var applyDraft = function applyDraft(editorView, options) {
181
251
  };
182
252
  export var getDraft = function getDraft(editorView, _options) {
183
253
  return function () {
184
- var _getRangeInlineNodeNa2;
185
- var _ref6 = inlineCommentPluginKey.getState(editorView.state) || {},
186
- isDrafting = _ref6.isDrafting,
187
- draftDecorationSet = _ref6.draftDecorationSet;
254
+ var _getRangeInlineNodeNa3;
255
+ var _ref7 = inlineCommentPluginKey.getState(editorView.state) || {},
256
+ isDrafting = _ref7.isDrafting,
257
+ draftDecorationSet = _ref7.draftDecorationSet;
188
258
  if (!isDrafting) {
189
259
  return {
190
260
  success: false,
@@ -200,13 +270,13 @@ export var getDraft = function getDraft(editorView, _options) {
200
270
  }
201
271
  var from = decorations[0].from;
202
272
  var targetElement = domRefFromPos(editorView, from);
203
- var inlineNodeTypes = (_getRangeInlineNodeNa2 = getRangeInlineNodeNames({
273
+ var inlineNodeTypes = (_getRangeInlineNodeNa3 = getRangeInlineNodeNames({
204
274
  doc: editorView.state.doc,
205
275
  pos: {
206
276
  from: from,
207
277
  to: decorations[decorations.length - 1].to
208
278
  }
209
- })) !== null && _getRangeInlineNodeNa2 !== void 0 ? _getRangeInlineNodeNa2 : [];
279
+ })) !== null && _getRangeInlineNodeNa3 !== void 0 ? _getRangeInlineNodeNa3 : [];
210
280
  return {
211
281
  success: true,
212
282
  inlineNodeTypes: inlineNodeTypes,
@@ -218,10 +288,10 @@ export var getDraft = function getDraft(editorView, _options) {
218
288
  export var setIsAnnotationSelected = function setIsAnnotationSelected(editorView, options) {
219
289
  return function (id, isSelected) {
220
290
  var _selectedAnnotations$;
221
- var _ref7 = inlineCommentPluginKey.getState(editorView.state) || {},
222
- annotations = _ref7.annotations,
223
- isDrafting = _ref7.isDrafting,
224
- selectedAnnotations = _ref7.selectedAnnotations;
291
+ var _ref8 = inlineCommentPluginKey.getState(editorView.state) || {},
292
+ annotations = _ref8.annotations,
293
+ isDrafting = _ref8.isDrafting,
294
+ selectedAnnotations = _ref8.selectedAnnotations;
225
295
  if (isDrafting) {
226
296
  return {
227
297
  success: false,
@@ -243,10 +313,10 @@ export var setIsAnnotationSelected = function setIsAnnotationSelected(editorView
243
313
  if (isSelected !== isCurrentlySelected) {
244
314
  // the annotation is selection is changing.
245
315
  if (isCurrentlySelected && !isSelected) {
246
- var _options$annotationMa4, _getAnnotationInlineN3;
316
+ var _options$annotationMa6, _getAnnotationInlineN3;
247
317
  // the selected annotaion is being unselected, so we need to close the view.
248
318
  closeComponent()(editorView.state, editorView.dispatch);
249
- (_options$annotationMa4 = options.annotationManager) === null || _options$annotationMa4 === void 0 || _options$annotationMa4.emit({
319
+ (_options$annotationMa6 = options.annotationManager) === null || _options$annotationMa6 === void 0 || _options$annotationMa6.emit({
250
320
  name: 'annotationSelectionChanged',
251
321
  data: {
252
322
  annotationId: id,
@@ -255,15 +325,15 @@ export var setIsAnnotationSelected = function setIsAnnotationSelected(editorView
255
325
  }
256
326
  });
257
327
  } else if (!isCurrentlySelected && isSelected) {
258
- var _options$annotationMa6, _getAnnotationInlineN5;
328
+ var _options$annotationMa8, _getAnnotationInlineN5;
259
329
  // the annotation is currently not selected and is being selected, so we need to open the view.
260
330
  setSelectedAnnotation(id)(editorView.state, editorView.dispatch);
261
331
 
262
332
  // the current annotations are going to be unselected. So we need to notify listeners of this change also.
263
333
  selectedAnnotations === null || selectedAnnotations === void 0 || selectedAnnotations.forEach(function (annotation) {
264
334
  if (annotation.id !== id) {
265
- var _options$annotationMa5, _getAnnotationInlineN4;
266
- (_options$annotationMa5 = options.annotationManager) === null || _options$annotationMa5 === void 0 || _options$annotationMa5.emit({
335
+ var _options$annotationMa7, _getAnnotationInlineN4;
336
+ (_options$annotationMa7 = options.annotationManager) === null || _options$annotationMa7 === void 0 || _options$annotationMa7.emit({
267
337
  name: 'annotationSelectionChanged',
268
338
  data: {
269
339
  annotationId: annotation.id,
@@ -275,7 +345,7 @@ export var setIsAnnotationSelected = function setIsAnnotationSelected(editorView
275
345
  });
276
346
 
277
347
  // Lastly we need to emit the event for the selected annotation.
278
- (_options$annotationMa6 = options.annotationManager) === null || _options$annotationMa6 === void 0 || _options$annotationMa6.emit({
348
+ (_options$annotationMa8 = options.annotationManager) === null || _options$annotationMa8 === void 0 || _options$annotationMa8.emit({
279
349
  name: 'annotationSelectionChanged',
280
350
  data: {
281
351
  annotationId: id,
@@ -294,9 +364,9 @@ export var setIsAnnotationSelected = function setIsAnnotationSelected(editorView
294
364
  export var setIsAnnotationHovered = function setIsAnnotationHovered(editorView, _options) {
295
365
  return function (id, isHovered) {
296
366
  var _hoveredAnnotations$f;
297
- var _ref8 = inlineCommentPluginKey.getState(editorView.state) || {},
298
- annotations = _ref8.annotations,
299
- hoveredAnnotations = _ref8.hoveredAnnotations;
367
+ var _ref9 = inlineCommentPluginKey.getState(editorView.state) || {},
368
+ annotations = _ref9.annotations,
369
+ hoveredAnnotations = _ref9.hoveredAnnotations;
300
370
 
301
371
  // If there is no annotation state with this id then we can assume the annotation is invalid.
302
372
  if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {
@@ -327,8 +397,8 @@ export var setIsAnnotationHovered = function setIsAnnotationHovered(editorView,
327
397
  };
328
398
  export var clearAnnotation = function clearAnnotation(editorView, options) {
329
399
  return function (id) {
330
- var _ref9 = inlineCommentPluginKey.getState(editorView.state) || {},
331
- annotations = _ref9.annotations;
400
+ var _ref0 = inlineCommentPluginKey.getState(editorView.state) || {},
401
+ annotations = _ref0.annotations;
332
402
 
333
403
  // If there is no annotation state with this id then we can assume the annotation is invalid.
334
404
  if (!(annotations !== null && annotations !== void 0 && annotations.hasOwnProperty(id))) {