@atlaskit/editor-plugin-media 1.2.3 → 1.4.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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 1.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#76770](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/76770) [`7eb1d4032d40`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/7eb1d4032d40) - [ux] Select upladed image. In case there are mulitple image files being pasted or drag&dropped, select last image.
8
+
9
+ ## 1.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#75635](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/75635) [`af4972f3a9bb`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/af4972f3a9bb) - [ux] Added comment button for media single floating toolbar
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies
18
+
3
19
  ## 1.2.3
4
20
 
5
21
  ### Patch Changes
@@ -279,7 +279,8 @@ var mediaPlugin = exports.mediaPlugin = function mediaPlugin(_ref2) {
279
279
  allowAltTextOnImages: options && options.allowAltTextOnImages,
280
280
  altTextValidator: options && options.altTextValidator,
281
281
  fullWidthEnabled: options && options.fullWidthEnabled,
282
- allowMediaInlineImages: options && options.allowMediaInlineImages
282
+ allowMediaInlineImages: options && options.allowMediaInlineImages,
283
+ getEditorFeatureFlags: options && options.getEditorFeatureFlags
283
284
  }, api);
284
285
  }
285
286
  }
@@ -32,6 +32,7 @@ var _utils2 = require("@atlaskit/editor-prosemirror/utils");
32
32
  var _view2 = require("@atlaskit/editor-prosemirror/view");
33
33
  var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
34
34
  var _mediaCommon = require("@atlaskit/media-common");
35
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
35
36
  var _helpers = _interopRequireWildcard(require("../commands/helpers"));
36
37
  var helpers = _helpers;
37
38
  var _pickerFacade = _interopRequireDefault(require("../picker-facade"));
@@ -86,6 +87,8 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
86
87
  (0, _defineProperty2.default)(this, "isResizing", false);
87
88
  (0, _defineProperty2.default)(this, "resizingWidth", 0);
88
89
  (0, _defineProperty2.default)(this, "allowInlineImages", false);
90
+ // this is only a temporary variable, which gets cleared after the last inserted node has been selected
91
+ (0, _defineProperty2.default)(this, "lastAddedMediaSingleFileIds", []);
89
92
  (0, _defineProperty2.default)(this, "destroyed", false);
90
93
  (0, _defineProperty2.default)(this, "removeOnCloseListener", function () {});
91
94
  (0, _defineProperty2.default)(this, "onPopupToggleCallback", function () {});
@@ -198,6 +201,13 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
198
201
  }
199
202
  return type === mediaSingle;
200
203
  });
204
+ // callback to flag that a node has been inserted
205
+ (0, _defineProperty2.default)(this, "onNodeInserted", function (id, selectionPosition) {
206
+ _this.lastAddedMediaSingleFileIds.unshift({
207
+ id: id,
208
+ selectionPosition: selectionPosition
209
+ });
210
+ });
201
211
  /**
202
212
  * we insert a new file by inserting a initial state for that file.
203
213
  *
@@ -228,7 +238,7 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
228
238
  case 'block':
229
239
  // read width state right before inserting to get up-to-date and define values
230
240
  var widthPluginState = (_this$pluginInjection2 = _this.pluginInjectionApi) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.width) === null || _this$pluginInjection2 === void 0 ? void 0 : _this$pluginInjection2.sharedState.currentState();
231
- (0, _mediaSingle2.insertMediaSingleNode)(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI);
241
+ (0, _mediaSingle2.insertMediaSingleNode)(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, _this.onNodeInserted);
232
242
  break;
233
243
  case 'group':
234
244
  (0, _mediaFiles.insertMediaGroupNode)(editorAnalyticsAPI)(_this.view, [mediaStateWithContext], collection, _this.getInputMethod(pickerType));
@@ -263,6 +273,9 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
263
273
  if (!view.hasFocus()) {
264
274
  view.focus();
265
275
  }
276
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.media.autoselect-inserted-image_oumto')) {
277
+ _this.selectLastAddedMediaNode();
278
+ }
266
279
  });
267
280
  (0, _defineProperty2.default)(this, "addPendingTask", function (task) {
268
281
  _this.taskManager.addPendingTask(task);
@@ -546,6 +559,36 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
546
559
  var _this$pluginInjection3;
547
560
  return (_this$pluginInjection3 = this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.contextIdentifier) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.sharedState.currentState()) === null || _this$pluginInjection3 === void 0 ? void 0 : _this$pluginInjection3.contextIdentifierProvider;
548
561
  }
562
+ }, {
563
+ key: "selectLastAddedMediaNode",
564
+ value: function selectLastAddedMediaNode() {
565
+ var _this2 = this;
566
+ // if lastAddedMediaSingleFileIds is empty exit because there are no added media single nodes to be selected
567
+ if (this.lastAddedMediaSingleFileIds.length !== 0) {
568
+ this.waitForPendingTasks().then(function () {
569
+ var lastTrackedAddedNode = _this2.lastAddedMediaSingleFileIds[0];
570
+ // execute selection only if selection did not change after the node has been inserted
571
+ if ((lastTrackedAddedNode === null || lastTrackedAddedNode === void 0 ? void 0 : lastTrackedAddedNode.selectionPosition) === _this2.view.state.selection.from) {
572
+ var lastAddedNode = _this2.mediaNodes.find(function (node) {
573
+ return node.node.attrs.id === lastTrackedAddedNode.id;
574
+ });
575
+ var lastAddedNodePos = lastAddedNode === null || lastAddedNode === void 0 ? void 0 : lastAddedNode.getPos();
576
+ if (lastAddedNodePos) {
577
+ var _this2$view = _this2.view,
578
+ dispatch = _this2$view.dispatch,
579
+ state = _this2$view.state;
580
+ var tr = state.tr;
581
+ tr.setSelection(_state2.NodeSelection.create(tr.doc, lastAddedNodePos));
582
+ if (dispatch) {
583
+ dispatch(tr);
584
+ }
585
+ }
586
+ }
587
+ // reset temp constant after uploads finished
588
+ _this2.lastAddedMediaSingleFileIds = [];
589
+ });
590
+ }
591
+ }
549
592
  }, {
550
593
  key: "setView",
551
594
  value: function setView(view) {
@@ -567,7 +610,7 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
567
610
  key: "initPickers",
568
611
  value: function () {
569
612
  var _initPickers = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(uploadParams, Picker) {
570
- var _this2 = this;
613
+ var _this3 = this;
571
614
  var errorReporter, pickers, pickerPromises, pickerFacadeConfig, customPicker;
572
615
  return _regenerator.default.wrap(function _callee2$(_context2) {
573
616
  while (1) switch (_context2.prev = _context2.next) {
@@ -601,7 +644,7 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
601
644
  _context2.t0.push.call(_context2.t0, _context2.t1);
602
645
  case 13:
603
646
  pickers.forEach(function (picker) {
604
- picker.onNewMedia(_this2.insertFile);
647
+ picker.onNewMedia(_this3.insertFile);
605
648
  });
606
649
  case 14:
607
650
  // set new upload params for the pickers
@@ -627,13 +670,13 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
627
670
  }, {
628
671
  key: "updateAndDispatch",
629
672
  value: function updateAndDispatch(props) {
630
- var _this3 = this;
673
+ var _this4 = this;
631
674
  // update plugin state
632
675
  Object.keys(props).forEach(function (_key) {
633
676
  var key = _key;
634
677
  var value = props[key];
635
678
  if (value !== undefined) {
636
- _this3[key] = value;
679
+ _this4[key] = value;
637
680
  }
638
681
  });
639
682
  if (this.dispatch) {
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.commentButton = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _keymaps = require("@atlaskit/editor-common/keymaps");
10
+ var _media = require("@atlaskit/editor-common/media");
11
+ var _comment = _interopRequireDefault(require("@atlaskit/icon/glyph/comment"));
12
+ var commentButton = exports.commentButton = function commentButton(intl, state, editorAnalyticsAPI) {
13
+ var title = intl.formatMessage(_media.commentMessages.addCommentOnMedia);
14
+ var onClickHandler = function onClickHandler() {
15
+ return true;
16
+ };
17
+ return {
18
+ type: 'button',
19
+ testId: 'add-comment-media-button',
20
+ icon: _comment.default,
21
+ title: title,
22
+ onClick: onClickHandler,
23
+ tooltipContent: /*#__PURE__*/_react.default.createElement(_keymaps.ToolTipContent, {
24
+ description: title
25
+ })
26
+ };
27
+ };
@@ -34,6 +34,7 @@ var _currentMediaNode = require("../utils/current-media-node");
34
34
  var _mediaSingle2 = require("../utils/media-single");
35
35
  var _altText2 = require("./alt-text");
36
36
  var _commands = require("./commands");
37
+ var _comments = require("./comments");
37
38
  var _filePreviewItem = require("./filePreviewItem");
38
39
  var _imageBorder = require("./imageBorder");
39
40
  var _layoutGroup = require("./layout-group");
@@ -166,7 +167,7 @@ var generateMediaCardFloatingToolbar = function generateMediaCardFloatingToolbar
166
167
  });
167
168
  return items;
168
169
  };
169
- var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToolbar(state, intl, options, pluginState, mediaLinkingState, pluginInjectionApi, getEditorFeatureFlags) {
170
+ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToolbar(state, intl, options, pluginState, mediaLinkingState, pluginInjectionApi) {
170
171
  var _pluginInjectionApi$d, _pluginInjectionApi$d2;
171
172
  var mediaSingle = state.schema.nodes.mediaSingle;
172
173
  var allowResizing = options.allowResizing,
@@ -175,7 +176,9 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
175
176
  allowResizingInTables = options.allowResizingInTables,
176
177
  allowAltTextOnImages = options.allowAltTextOnImages,
177
178
  allowMediaInline = options.allowMediaInline,
178
- allowMediaInlineImages = options.allowMediaInlineImages;
179
+ allowMediaInlineImages = options.allowMediaInlineImages,
180
+ getEditorFeatureFlags = options.getEditorFeatureFlags;
181
+ var editorFeatureFlags = getEditorFeatureFlags ? getEditorFeatureFlags() : undefined;
179
182
  var toolbarButtons = [];
180
183
  var _ref = (_pluginInjectionApi$d = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$d2 = pluginInjectionApi.decorations) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.actions) !== null && _pluginInjectionApi$d !== void 0 ? _pluginInjectionApi$d : {},
181
184
  hoverDecoration = _ref.hoverDecoration;
@@ -398,6 +401,12 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
398
401
  type: 'separator'
399
402
  });
400
403
  }
404
+ if (editorFeatureFlags && editorFeatureFlags.commentsOnMedia) {
405
+ var _pluginInjectionApi$a6;
406
+ toolbarButtons.push((0, _comments.commentButton)(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a6 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a6 === void 0 ? void 0 : _pluginInjectionApi$a6.actions), {
407
+ type: 'separator'
408
+ });
409
+ }
401
410
  if (allowLinking && (0, _linking3.shouldShowMediaLinkToolbar)(state)) {
402
411
  toolbarButtons.push({
403
412
  type: 'custom',
@@ -413,10 +422,10 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
413
422
  };
414
423
  var openLink = function openLink() {
415
424
  if (editorView) {
416
- var _pluginInjectionApi$a6;
425
+ var _pluginInjectionApi$a7;
417
426
  var tr = editorView.state.tr,
418
427
  dispatch = editorView.dispatch;
419
- pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a6 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a6 === void 0 || _pluginInjectionApi$a6.actions.attachAnalyticsEvent({
428
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a7 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a7 === void 0 || _pluginInjectionApi$a7.actions.attachAnalyticsEvent({
420
429
  eventType: _analytics.EVENT_TYPE.TRACK,
421
430
  action: _analytics.ACTION.VISITED,
422
431
  actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
@@ -442,8 +451,8 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
442
451
  }
443
452
  }
444
453
  if (allowAltTextOnImages) {
445
- var _pluginInjectionApi$a7;
446
- toolbarButtons.push((0, _altText2.altTextButton)(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a7 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a7 === void 0 ? void 0 : _pluginInjectionApi$a7.actions), {
454
+ var _pluginInjectionApi$a8;
455
+ toolbarButtons.push((0, _altText2.altTextButton)(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a8 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a8 === void 0 ? void 0 : _pluginInjectionApi$a8.actions), {
447
456
  type: 'separator'
448
457
  });
449
458
  }
@@ -493,8 +502,7 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
493
502
  allowAltTextOnImages = options.allowAltTextOnImages,
494
503
  providerFactory = options.providerFactory,
495
504
  allowMediaInline = options.allowMediaInline,
496
- allowResizing = options.allowResizing,
497
- getEditorFeatureFlags = options.getEditorFeatureFlags;
505
+ allowResizing = options.allowResizing;
498
506
  var mediaPluginState = _pluginKey.stateKey.getState(state);
499
507
  var mediaLinkingState = (0, _linking2.getMediaLinkingState)(state);
500
508
  var _ref3 = (_pluginInjectionApi$d3 = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$d4 = pluginInjectionApi.decorations) === null || _pluginInjectionApi$d4 === void 0 ? void 0 : _pluginInjectionApi$d4.actions) !== null && _pluginInjectionApi$d3 !== void 0 ? _pluginInjectionApi$d3 : {},
@@ -533,14 +541,14 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
533
541
  selectedNodeType = state.selection.node.type;
534
542
  }
535
543
  if (allowMediaInline && (parentMediaGroupNode === null || parentMediaGroupNode === void 0 ? void 0 : parentMediaGroupNode.node.type) === mediaGroup) {
536
- var _pluginInjectionApi$a8, _pluginInjectionApi$f2;
544
+ var _pluginInjectionApi$a9, _pluginInjectionApi$f2;
537
545
  var mediaOffset = state.selection.$from.parentOffset + 1;
538
546
  baseToolbar.getDomRef = function () {
539
547
  var _mediaPluginState$ele;
540
548
  var selector = (0, _mediaFilmstrip.mediaFilmstripItemDOMSelector)(mediaOffset);
541
549
  return (_mediaPluginState$ele = mediaPluginState.element) === null || _mediaPluginState$ele === void 0 ? void 0 : _mediaPluginState$ele.querySelector(selector);
542
550
  };
543
- items = generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a8 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a8 === void 0 ? void 0 : _pluginInjectionApi$a8.actions, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f2 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f2 === void 0 || (_pluginInjectionApi$f2 = _pluginInjectionApi$f2.actions) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.forceFocusSelector);
551
+ items = generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a9 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a9 === void 0 ? void 0 : _pluginInjectionApi$a9.actions, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f2 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f2 === void 0 || (_pluginInjectionApi$f2 = _pluginInjectionApi$f2.actions) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.forceFocusSelector);
544
552
  } else if (allowMediaInline && selectedNodeType && selectedNodeType === mediaInline) {
545
553
  baseToolbar.getDomRef = function () {
546
554
  var _mediaPluginState$ele2;
@@ -554,7 +562,7 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
554
562
  var element = (_mediaPluginState$ele3 = mediaPluginState.element) === null || _mediaPluginState$ele3 === void 0 ? void 0 : _mediaPluginState$ele3.querySelector(".".concat(_styles.MediaSingleNodeSelector));
555
563
  return element || mediaPluginState.element;
556
564
  };
557
- items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi, getEditorFeatureFlags);
565
+ items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi);
558
566
  }
559
567
  var assistiveMessage = '';
560
568
  var selectedMediaSingleNode = (0, _utils2.getSelectedMediaSingle)(state);
@@ -113,7 +113,7 @@ var getFileExtension = function getFileExtension(fileName) {
113
113
  }
114
114
  return undefined;
115
115
  };
116
- var insertMediaSingleNode = exports.insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI) {
116
+ var insertMediaSingleNode = exports.insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted) {
117
117
  var _state$selection$$fro;
118
118
  if (collection === undefined) {
119
119
  return false;
@@ -155,6 +155,9 @@ var insertMediaSingleNode = exports.insertMediaSingleNode = function insertMedia
155
155
  }
156
156
  dispatch(tr);
157
157
  }
158
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.media.autoselect-inserted-image_oumto') && onNodeInserted) {
159
+ onNodeInserted(mediaState.id, view.state.selection.to);
160
+ }
158
161
  return true;
159
162
  };
160
163
  var changeFromMediaInlineToMediaSingleNode = exports.changeFromMediaInlineToMediaSingleNode = function changeFromMediaInlineToMediaSingleNode(view, fromNode, widthPluginState, editorAnalyticsAPI) {
@@ -272,7 +272,8 @@ export const mediaPlugin = ({
272
272
  allowAltTextOnImages: options && options.allowAltTextOnImages,
273
273
  altTextValidator: options && options.altTextValidator,
274
274
  fullWidthEnabled: options && options.fullWidthEnabled,
275
- allowMediaInlineImages: options && options.allowMediaInlineImages
275
+ allowMediaInlineImages: options && options.allowMediaInlineImages,
276
+ getEditorFeatureFlags: options && options.getEditorFeatureFlags
276
277
  }, api)
277
278
  }
278
279
  };
@@ -14,6 +14,7 @@ import { findDomRefAtPos, findParentNodeOfType, findSelectedNodeOfType, isNodeSe
14
14
  import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
15
15
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
16
16
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
17
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
17
18
  import * as helpers from '../commands/helpers';
18
19
  import { updateMediaNodeAttrs } from '../commands/helpers';
19
20
  import PickerFacade from '../picker-facade';
@@ -59,6 +60,8 @@ export class MediaPluginStateImplementation {
59
60
  _defineProperty(this, "isResizing", false);
60
61
  _defineProperty(this, "resizingWidth", 0);
61
62
  _defineProperty(this, "allowInlineImages", false);
63
+ // this is only a temporary variable, which gets cleared after the last inserted node has been selected
64
+ _defineProperty(this, "lastAddedMediaSingleFileIds", []);
62
65
  _defineProperty(this, "destroyed", false);
63
66
  _defineProperty(this, "removeOnCloseListener", () => {});
64
67
  _defineProperty(this, "onPopupToggleCallback", () => {});
@@ -143,6 +146,13 @@ export class MediaPluginStateImplementation {
143
146
  }
144
147
  return type === mediaSingle;
145
148
  });
149
+ // callback to flag that a node has been inserted
150
+ _defineProperty(this, "onNodeInserted", (id, selectionPosition) => {
151
+ this.lastAddedMediaSingleFileIds.unshift({
152
+ id,
153
+ selectionPosition
154
+ });
155
+ });
146
156
  /**
147
157
  * we insert a new file by inserting a initial state for that file.
148
158
  *
@@ -176,7 +186,7 @@ export class MediaPluginStateImplementation {
176
186
  case 'block':
177
187
  // read width state right before inserting to get up-to-date and define values
178
188
  const widthPluginState = (_this$pluginInjection3 = this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 ? void 0 : (_this$pluginInjection4 = _this$pluginInjection3.width) === null || _this$pluginInjection4 === void 0 ? void 0 : _this$pluginInjection4.sharedState.currentState();
179
- insertMediaSingleNode(this.view, mediaStateWithContext, this.getInputMethod(pickerType), collection, this.mediaOptions && this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI);
189
+ insertMediaSingleNode(this.view, mediaStateWithContext, this.getInputMethod(pickerType), collection, this.mediaOptions && this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, this.onNodeInserted);
180
190
  break;
181
191
  case 'group':
182
192
  insertMediaGroupNode(editorAnalyticsAPI)(this.view, [mediaStateWithContext], collection, this.getInputMethod(pickerType));
@@ -211,6 +221,9 @@ export class MediaPluginStateImplementation {
211
221
  if (!view.hasFocus()) {
212
222
  view.focus();
213
223
  }
224
+ if (getBooleanFF('platform.editor.media.autoselect-inserted-image_oumto')) {
225
+ this.selectLastAddedMediaNode();
226
+ }
214
227
  });
215
228
  _defineProperty(this, "addPendingTask", task => {
216
229
  this.taskManager.addPendingTask(task);
@@ -483,6 +496,34 @@ export class MediaPluginStateImplementation {
483
496
  var _this$pluginInjection5, _this$pluginInjection6, _this$pluginInjection7;
484
497
  return (_this$pluginInjection5 = this.pluginInjectionApi) === null || _this$pluginInjection5 === void 0 ? void 0 : (_this$pluginInjection6 = _this$pluginInjection5.contextIdentifier) === null || _this$pluginInjection6 === void 0 ? void 0 : (_this$pluginInjection7 = _this$pluginInjection6.sharedState.currentState()) === null || _this$pluginInjection7 === void 0 ? void 0 : _this$pluginInjection7.contextIdentifierProvider;
485
498
  }
499
+ selectLastAddedMediaNode() {
500
+ // if lastAddedMediaSingleFileIds is empty exit because there are no added media single nodes to be selected
501
+ if (this.lastAddedMediaSingleFileIds.length !== 0) {
502
+ this.waitForPendingTasks().then(() => {
503
+ const lastTrackedAddedNode = this.lastAddedMediaSingleFileIds[0];
504
+ // execute selection only if selection did not change after the node has been inserted
505
+ if ((lastTrackedAddedNode === null || lastTrackedAddedNode === void 0 ? void 0 : lastTrackedAddedNode.selectionPosition) === this.view.state.selection.from) {
506
+ const lastAddedNode = this.mediaNodes.find(node => {
507
+ return node.node.attrs.id === lastTrackedAddedNode.id;
508
+ });
509
+ const lastAddedNodePos = lastAddedNode === null || lastAddedNode === void 0 ? void 0 : lastAddedNode.getPos();
510
+ if (lastAddedNodePos) {
511
+ const {
512
+ dispatch,
513
+ state
514
+ } = this.view;
515
+ const tr = state.tr;
516
+ tr.setSelection(NodeSelection.create(tr.doc, lastAddedNodePos));
517
+ if (dispatch) {
518
+ dispatch(tr);
519
+ }
520
+ }
521
+ }
522
+ // reset temp constant after uploads finished
523
+ this.lastAddedMediaSingleFileIds = [];
524
+ });
525
+ }
526
+ }
486
527
  setView(view) {
487
528
  this.view = view;
488
529
  }
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { ToolTipContent } from '@atlaskit/editor-common/keymaps';
3
+ import { commentMessages as messages } from '@atlaskit/editor-common/media';
4
+ import CommentIcon from '@atlaskit/icon/glyph/comment';
5
+ export const commentButton = (intl, state, editorAnalyticsAPI) => {
6
+ const title = intl.formatMessage(messages.addCommentOnMedia);
7
+ const onClickHandler = () => {
8
+ return true;
9
+ };
10
+ return {
11
+ type: 'button',
12
+ testId: 'add-comment-media-button',
13
+ icon: CommentIcon,
14
+ title,
15
+ onClick: onClickHandler,
16
+ tooltipContent: /*#__PURE__*/React.createElement(ToolTipContent, {
17
+ description: title
18
+ })
19
+ };
20
+ };
@@ -24,6 +24,7 @@ import { currentMediaOrInlineNodeBorderMark } from '../utils/current-media-node'
24
24
  import { isVideo } from '../utils/media-single';
25
25
  import { altTextButton, getAltTextToolbar } from './alt-text';
26
26
  import { changeMediaCardToInline, changeMediaSingleToMediaInline, setBorderMark, toggleBorderMark, updateMediaSingleWidth } from './commands';
27
+ import { commentButton } from './comments';
27
28
  import { FilePreviewItem } from './filePreviewItem';
28
29
  import { shouldShowImageBorder } from './imageBorder';
29
30
  import { LayoutGroup } from './layout-group';
@@ -152,7 +153,7 @@ const generateMediaCardFloatingToolbar = (state, intl, mediaPluginState, hoverDe
152
153
  });
153
154
  return items;
154
155
  };
155
- const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, mediaLinkingState, pluginInjectionApi, getEditorFeatureFlags) => {
156
+ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, mediaLinkingState, pluginInjectionApi) => {
156
157
  var _pluginInjectionApi$d, _pluginInjectionApi$d2;
157
158
  const {
158
159
  mediaSingle
@@ -164,8 +165,10 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
164
165
  allowResizingInTables,
165
166
  allowAltTextOnImages,
166
167
  allowMediaInline,
167
- allowMediaInlineImages
168
+ allowMediaInlineImages,
169
+ getEditorFeatureFlags
168
170
  } = options;
171
+ const editorFeatureFlags = getEditorFeatureFlags ? getEditorFeatureFlags() : undefined;
169
172
  let toolbarButtons = [];
170
173
  const {
171
174
  hoverDecoration
@@ -395,6 +398,12 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
395
398
  type: 'separator'
396
399
  });
397
400
  }
401
+ if (editorFeatureFlags && editorFeatureFlags.commentsOnMedia) {
402
+ var _pluginInjectionApi$a6;
403
+ toolbarButtons.push(commentButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a6 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a6 === void 0 ? void 0 : _pluginInjectionApi$a6.actions), {
404
+ type: 'separator'
405
+ });
406
+ }
398
407
  if (allowLinking && shouldShowMediaLinkToolbar(state)) {
399
408
  toolbarButtons.push({
400
409
  type: 'custom',
@@ -412,14 +421,14 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
412
421
  };
413
422
  const openLink = () => {
414
423
  if (editorView) {
415
- var _pluginInjectionApi$a6;
424
+ var _pluginInjectionApi$a7;
416
425
  const {
417
426
  state: {
418
427
  tr
419
428
  },
420
429
  dispatch
421
430
  } = editorView;
422
- pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a6 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a6 === void 0 ? void 0 : _pluginInjectionApi$a6.actions.attachAnalyticsEvent({
431
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a7 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a7 === void 0 ? void 0 : _pluginInjectionApi$a7.actions.attachAnalyticsEvent({
423
432
  eventType: EVENT_TYPE.TRACK,
424
433
  action: ACTION.VISITED,
425
434
  actionSubject: ACTION_SUBJECT.MEDIA,
@@ -445,8 +454,8 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
445
454
  }
446
455
  }
447
456
  if (allowAltTextOnImages) {
448
- var _pluginInjectionApi$a7;
449
- toolbarButtons.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a7 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a7 === void 0 ? void 0 : _pluginInjectionApi$a7.actions), {
457
+ var _pluginInjectionApi$a8;
458
+ toolbarButtons.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a8 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a8 === void 0 ? void 0 : _pluginInjectionApi$a8.actions), {
450
459
  type: 'separator'
451
460
  });
452
461
  }
@@ -494,8 +503,7 @@ export const floatingToolbar = (state, intl, options = {}, pluginInjectionApi) =
494
503
  allowAltTextOnImages,
495
504
  providerFactory,
496
505
  allowMediaInline,
497
- allowResizing,
498
- getEditorFeatureFlags
506
+ allowResizing
499
507
  } = options;
500
508
  const mediaPluginState = stateKey.getState(state);
501
509
  const mediaLinkingState = getMediaLinkingState(state);
@@ -534,14 +542,14 @@ export const floatingToolbar = (state, intl, options = {}, pluginInjectionApi) =
534
542
  selectedNodeType = state.selection.node.type;
535
543
  }
536
544
  if (allowMediaInline && (parentMediaGroupNode === null || parentMediaGroupNode === void 0 ? void 0 : parentMediaGroupNode.node.type) === mediaGroup) {
537
- var _pluginInjectionApi$a8, _pluginInjectionApi$f3, _pluginInjectionApi$f4;
545
+ var _pluginInjectionApi$a9, _pluginInjectionApi$f3, _pluginInjectionApi$f4;
538
546
  const mediaOffset = state.selection.$from.parentOffset + 1;
539
547
  baseToolbar.getDomRef = () => {
540
548
  var _mediaPluginState$ele;
541
549
  const selector = mediaFilmstripItemDOMSelector(mediaOffset);
542
550
  return (_mediaPluginState$ele = mediaPluginState.element) === null || _mediaPluginState$ele === void 0 ? void 0 : _mediaPluginState$ele.querySelector(selector);
543
551
  };
544
- items = generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a8 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a8 === void 0 ? void 0 : _pluginInjectionApi$a8.actions, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$f3 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f3 === void 0 ? void 0 : (_pluginInjectionApi$f4 = _pluginInjectionApi$f3.actions) === null || _pluginInjectionApi$f4 === void 0 ? void 0 : _pluginInjectionApi$f4.forceFocusSelector);
552
+ items = generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a9 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a9 === void 0 ? void 0 : _pluginInjectionApi$a9.actions, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$f3 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f3 === void 0 ? void 0 : (_pluginInjectionApi$f4 = _pluginInjectionApi$f3.actions) === null || _pluginInjectionApi$f4 === void 0 ? void 0 : _pluginInjectionApi$f4.forceFocusSelector);
545
553
  } else if (allowMediaInline && selectedNodeType && selectedNodeType === mediaInline) {
546
554
  baseToolbar.getDomRef = () => {
547
555
  var _mediaPluginState$ele2;
@@ -555,7 +563,7 @@ export const floatingToolbar = (state, intl, options = {}, pluginInjectionApi) =
555
563
  const element = (_mediaPluginState$ele3 = mediaPluginState.element) === null || _mediaPluginState$ele3 === void 0 ? void 0 : _mediaPluginState$ele3.querySelector(`.${MediaSingleNodeSelector}`);
556
564
  return element || mediaPluginState.element;
557
565
  };
558
- items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi, getEditorFeatureFlags);
566
+ items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi);
559
567
  }
560
568
  var assistiveMessage = '';
561
569
  const selectedMediaSingleNode = getSelectedMediaSingle(state);
@@ -102,7 +102,7 @@ const getFileExtension = fileName => {
102
102
  }
103
103
  return undefined;
104
104
  };
105
- export const insertMediaSingleNode = (view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI) => {
105
+ export const insertMediaSingleNode = (view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted) => {
106
106
  var _state$selection$$fro;
107
107
  if (collection === undefined) {
108
108
  return false;
@@ -146,6 +146,9 @@ export const insertMediaSingleNode = (view, mediaState, inputMethod, collection,
146
146
  }
147
147
  dispatch(tr);
148
148
  }
149
+ if (getBooleanFF('platform.editor.media.autoselect-inserted-image_oumto') && onNodeInserted) {
150
+ onNodeInserted(mediaState.id, view.state.selection.to);
151
+ }
149
152
  return true;
150
153
  };
151
154
  export const changeFromMediaInlineToMediaSingleNode = (view, fromNode, widthPluginState, editorAnalyticsAPI) => {
@@ -268,7 +268,8 @@ export var mediaPlugin = function mediaPlugin(_ref2) {
268
268
  allowAltTextOnImages: options && options.allowAltTextOnImages,
269
269
  altTextValidator: options && options.altTextValidator,
270
270
  fullWidthEnabled: options && options.fullWidthEnabled,
271
- allowMediaInlineImages: options && options.allowMediaInlineImages
271
+ allowMediaInlineImages: options && options.allowMediaInlineImages,
272
+ getEditorFeatureFlags: options && options.getEditorFeatureFlags
272
273
  }, api);
273
274
  }
274
275
  }
@@ -23,6 +23,7 @@ import { findDomRefAtPos, findParentNodeOfType, findSelectedNodeOfType, isNodeSe
23
23
  import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
24
24
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
25
25
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
26
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
26
27
  import * as helpers from '../commands/helpers';
27
28
  import { updateMediaNodeAttrs } from '../commands/helpers';
28
29
  import PickerFacade from '../picker-facade';
@@ -71,6 +72,8 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
71
72
  _defineProperty(this, "isResizing", false);
72
73
  _defineProperty(this, "resizingWidth", 0);
73
74
  _defineProperty(this, "allowInlineImages", false);
75
+ // this is only a temporary variable, which gets cleared after the last inserted node has been selected
76
+ _defineProperty(this, "lastAddedMediaSingleFileIds", []);
74
77
  _defineProperty(this, "destroyed", false);
75
78
  _defineProperty(this, "removeOnCloseListener", function () {});
76
79
  _defineProperty(this, "onPopupToggleCallback", function () {});
@@ -183,6 +186,13 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
183
186
  }
184
187
  return type === mediaSingle;
185
188
  });
189
+ // callback to flag that a node has been inserted
190
+ _defineProperty(this, "onNodeInserted", function (id, selectionPosition) {
191
+ _this.lastAddedMediaSingleFileIds.unshift({
192
+ id: id,
193
+ selectionPosition: selectionPosition
194
+ });
195
+ });
186
196
  /**
187
197
  * we insert a new file by inserting a initial state for that file.
188
198
  *
@@ -213,7 +223,7 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
213
223
  case 'block':
214
224
  // read width state right before inserting to get up-to-date and define values
215
225
  var widthPluginState = (_this$pluginInjection2 = _this.pluginInjectionApi) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.width) === null || _this$pluginInjection2 === void 0 ? void 0 : _this$pluginInjection2.sharedState.currentState();
216
- insertMediaSingleNode(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI);
226
+ insertMediaSingleNode(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, _this.onNodeInserted);
217
227
  break;
218
228
  case 'group':
219
229
  insertMediaGroupNode(editorAnalyticsAPI)(_this.view, [mediaStateWithContext], collection, _this.getInputMethod(pickerType));
@@ -248,6 +258,9 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
248
258
  if (!view.hasFocus()) {
249
259
  view.focus();
250
260
  }
261
+ if (getBooleanFF('platform.editor.media.autoselect-inserted-image_oumto')) {
262
+ _this.selectLastAddedMediaNode();
263
+ }
251
264
  });
252
265
  _defineProperty(this, "addPendingTask", function (task) {
253
266
  _this.taskManager.addPendingTask(task);
@@ -531,6 +544,36 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
531
544
  var _this$pluginInjection3;
532
545
  return (_this$pluginInjection3 = this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.contextIdentifier) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.sharedState.currentState()) === null || _this$pluginInjection3 === void 0 ? void 0 : _this$pluginInjection3.contextIdentifierProvider;
533
546
  }
547
+ }, {
548
+ key: "selectLastAddedMediaNode",
549
+ value: function selectLastAddedMediaNode() {
550
+ var _this2 = this;
551
+ // if lastAddedMediaSingleFileIds is empty exit because there are no added media single nodes to be selected
552
+ if (this.lastAddedMediaSingleFileIds.length !== 0) {
553
+ this.waitForPendingTasks().then(function () {
554
+ var lastTrackedAddedNode = _this2.lastAddedMediaSingleFileIds[0];
555
+ // execute selection only if selection did not change after the node has been inserted
556
+ if ((lastTrackedAddedNode === null || lastTrackedAddedNode === void 0 ? void 0 : lastTrackedAddedNode.selectionPosition) === _this2.view.state.selection.from) {
557
+ var lastAddedNode = _this2.mediaNodes.find(function (node) {
558
+ return node.node.attrs.id === lastTrackedAddedNode.id;
559
+ });
560
+ var lastAddedNodePos = lastAddedNode === null || lastAddedNode === void 0 ? void 0 : lastAddedNode.getPos();
561
+ if (lastAddedNodePos) {
562
+ var _this2$view = _this2.view,
563
+ dispatch = _this2$view.dispatch,
564
+ state = _this2$view.state;
565
+ var tr = state.tr;
566
+ tr.setSelection(NodeSelection.create(tr.doc, lastAddedNodePos));
567
+ if (dispatch) {
568
+ dispatch(tr);
569
+ }
570
+ }
571
+ }
572
+ // reset temp constant after uploads finished
573
+ _this2.lastAddedMediaSingleFileIds = [];
574
+ });
575
+ }
576
+ }
534
577
  }, {
535
578
  key: "setView",
536
579
  value: function setView(view) {
@@ -552,7 +595,7 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
552
595
  key: "initPickers",
553
596
  value: function () {
554
597
  var _initPickers = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(uploadParams, Picker) {
555
- var _this2 = this;
598
+ var _this3 = this;
556
599
  var errorReporter, pickers, pickerPromises, pickerFacadeConfig, customPicker;
557
600
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
558
601
  while (1) switch (_context2.prev = _context2.next) {
@@ -586,7 +629,7 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
586
629
  _context2.t0.push.call(_context2.t0, _context2.t1);
587
630
  case 13:
588
631
  pickers.forEach(function (picker) {
589
- picker.onNewMedia(_this2.insertFile);
632
+ picker.onNewMedia(_this3.insertFile);
590
633
  });
591
634
  case 14:
592
635
  // set new upload params for the pickers
@@ -612,13 +655,13 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
612
655
  }, {
613
656
  key: "updateAndDispatch",
614
657
  value: function updateAndDispatch(props) {
615
- var _this3 = this;
658
+ var _this4 = this;
616
659
  // update plugin state
617
660
  Object.keys(props).forEach(function (_key) {
618
661
  var key = _key;
619
662
  var value = props[key];
620
663
  if (value !== undefined) {
621
- _this3[key] = value;
664
+ _this4[key] = value;
622
665
  }
623
666
  });
624
667
  if (this.dispatch) {
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { ToolTipContent } from '@atlaskit/editor-common/keymaps';
3
+ import { commentMessages as messages } from '@atlaskit/editor-common/media';
4
+ import CommentIcon from '@atlaskit/icon/glyph/comment';
5
+ export var commentButton = function commentButton(intl, state, editorAnalyticsAPI) {
6
+ var title = intl.formatMessage(messages.addCommentOnMedia);
7
+ var onClickHandler = function onClickHandler() {
8
+ return true;
9
+ };
10
+ return {
11
+ type: 'button',
12
+ testId: 'add-comment-media-button',
13
+ icon: CommentIcon,
14
+ title: title,
15
+ onClick: onClickHandler,
16
+ tooltipContent: /*#__PURE__*/React.createElement(ToolTipContent, {
17
+ description: title
18
+ })
19
+ };
20
+ };
@@ -28,6 +28,7 @@ import { currentMediaOrInlineNodeBorderMark } from '../utils/current-media-node'
28
28
  import { isVideo } from '../utils/media-single';
29
29
  import { altTextButton, getAltTextToolbar } from './alt-text';
30
30
  import { changeMediaCardToInline, changeMediaSingleToMediaInline, setBorderMark, toggleBorderMark, updateMediaSingleWidth } from './commands';
31
+ import { commentButton } from './comments';
31
32
  import { FilePreviewItem } from './filePreviewItem';
32
33
  import { shouldShowImageBorder } from './imageBorder';
33
34
  import { LayoutGroup } from './layout-group';
@@ -156,7 +157,7 @@ var generateMediaCardFloatingToolbar = function generateMediaCardFloatingToolbar
156
157
  });
157
158
  return items;
158
159
  };
159
- var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToolbar(state, intl, options, pluginState, mediaLinkingState, pluginInjectionApi, getEditorFeatureFlags) {
160
+ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToolbar(state, intl, options, pluginState, mediaLinkingState, pluginInjectionApi) {
160
161
  var _pluginInjectionApi$d, _pluginInjectionApi$d2;
161
162
  var mediaSingle = state.schema.nodes.mediaSingle;
162
163
  var allowResizing = options.allowResizing,
@@ -165,7 +166,9 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
165
166
  allowResizingInTables = options.allowResizingInTables,
166
167
  allowAltTextOnImages = options.allowAltTextOnImages,
167
168
  allowMediaInline = options.allowMediaInline,
168
- allowMediaInlineImages = options.allowMediaInlineImages;
169
+ allowMediaInlineImages = options.allowMediaInlineImages,
170
+ getEditorFeatureFlags = options.getEditorFeatureFlags;
171
+ var editorFeatureFlags = getEditorFeatureFlags ? getEditorFeatureFlags() : undefined;
169
172
  var toolbarButtons = [];
170
173
  var _ref = (_pluginInjectionApi$d = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$d2 = pluginInjectionApi.decorations) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.actions) !== null && _pluginInjectionApi$d !== void 0 ? _pluginInjectionApi$d : {},
171
174
  hoverDecoration = _ref.hoverDecoration;
@@ -388,6 +391,12 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
388
391
  type: 'separator'
389
392
  });
390
393
  }
394
+ if (editorFeatureFlags && editorFeatureFlags.commentsOnMedia) {
395
+ var _pluginInjectionApi$a6;
396
+ toolbarButtons.push(commentButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a6 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a6 === void 0 ? void 0 : _pluginInjectionApi$a6.actions), {
397
+ type: 'separator'
398
+ });
399
+ }
391
400
  if (allowLinking && shouldShowMediaLinkToolbar(state)) {
392
401
  toolbarButtons.push({
393
402
  type: 'custom',
@@ -403,10 +412,10 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
403
412
  };
404
413
  var openLink = function openLink() {
405
414
  if (editorView) {
406
- var _pluginInjectionApi$a6;
415
+ var _pluginInjectionApi$a7;
407
416
  var tr = editorView.state.tr,
408
417
  dispatch = editorView.dispatch;
409
- pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a6 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a6 === void 0 || _pluginInjectionApi$a6.actions.attachAnalyticsEvent({
418
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a7 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a7 === void 0 || _pluginInjectionApi$a7.actions.attachAnalyticsEvent({
410
419
  eventType: EVENT_TYPE.TRACK,
411
420
  action: ACTION.VISITED,
412
421
  actionSubject: ACTION_SUBJECT.MEDIA,
@@ -432,8 +441,8 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
432
441
  }
433
442
  }
434
443
  if (allowAltTextOnImages) {
435
- var _pluginInjectionApi$a7;
436
- toolbarButtons.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a7 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a7 === void 0 ? void 0 : _pluginInjectionApi$a7.actions), {
444
+ var _pluginInjectionApi$a8;
445
+ toolbarButtons.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a8 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a8 === void 0 ? void 0 : _pluginInjectionApi$a8.actions), {
437
446
  type: 'separator'
438
447
  });
439
448
  }
@@ -483,8 +492,7 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
483
492
  allowAltTextOnImages = options.allowAltTextOnImages,
484
493
  providerFactory = options.providerFactory,
485
494
  allowMediaInline = options.allowMediaInline,
486
- allowResizing = options.allowResizing,
487
- getEditorFeatureFlags = options.getEditorFeatureFlags;
495
+ allowResizing = options.allowResizing;
488
496
  var mediaPluginState = stateKey.getState(state);
489
497
  var mediaLinkingState = getMediaLinkingState(state);
490
498
  var _ref3 = (_pluginInjectionApi$d3 = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$d4 = pluginInjectionApi.decorations) === null || _pluginInjectionApi$d4 === void 0 ? void 0 : _pluginInjectionApi$d4.actions) !== null && _pluginInjectionApi$d3 !== void 0 ? _pluginInjectionApi$d3 : {},
@@ -523,14 +531,14 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
523
531
  selectedNodeType = state.selection.node.type;
524
532
  }
525
533
  if (allowMediaInline && (parentMediaGroupNode === null || parentMediaGroupNode === void 0 ? void 0 : parentMediaGroupNode.node.type) === mediaGroup) {
526
- var _pluginInjectionApi$a8, _pluginInjectionApi$f2;
534
+ var _pluginInjectionApi$a9, _pluginInjectionApi$f2;
527
535
  var mediaOffset = state.selection.$from.parentOffset + 1;
528
536
  baseToolbar.getDomRef = function () {
529
537
  var _mediaPluginState$ele;
530
538
  var selector = mediaFilmstripItemDOMSelector(mediaOffset);
531
539
  return (_mediaPluginState$ele = mediaPluginState.element) === null || _mediaPluginState$ele === void 0 ? void 0 : _mediaPluginState$ele.querySelector(selector);
532
540
  };
533
- items = generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a8 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a8 === void 0 ? void 0 : _pluginInjectionApi$a8.actions, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f2 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f2 === void 0 || (_pluginInjectionApi$f2 = _pluginInjectionApi$f2.actions) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.forceFocusSelector);
541
+ items = generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a9 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a9 === void 0 ? void 0 : _pluginInjectionApi$a9.actions, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f2 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f2 === void 0 || (_pluginInjectionApi$f2 = _pluginInjectionApi$f2.actions) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.forceFocusSelector);
534
542
  } else if (allowMediaInline && selectedNodeType && selectedNodeType === mediaInline) {
535
543
  baseToolbar.getDomRef = function () {
536
544
  var _mediaPluginState$ele2;
@@ -544,7 +552,7 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
544
552
  var element = (_mediaPluginState$ele3 = mediaPluginState.element) === null || _mediaPluginState$ele3 === void 0 ? void 0 : _mediaPluginState$ele3.querySelector(".".concat(MediaSingleNodeSelector));
545
553
  return element || mediaPluginState.element;
546
554
  };
547
- items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi, getEditorFeatureFlags);
555
+ items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi);
548
556
  }
549
557
  var assistiveMessage = '';
550
558
  var selectedMediaSingleNode = getSelectedMediaSingle(state);
@@ -104,7 +104,7 @@ var getFileExtension = function getFileExtension(fileName) {
104
104
  }
105
105
  return undefined;
106
106
  };
107
- export var insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI) {
107
+ export var insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted) {
108
108
  var _state$selection$$fro;
109
109
  if (collection === undefined) {
110
110
  return false;
@@ -146,6 +146,9 @@ export var insertMediaSingleNode = function insertMediaSingleNode(view, mediaSta
146
146
  }
147
147
  dispatch(tr);
148
148
  }
149
+ if (getBooleanFF('platform.editor.media.autoselect-inserted-image_oumto') && onNodeInserted) {
150
+ onNodeInserted(mediaState.id, view.state.selection.to);
151
+ }
149
152
  return true;
150
153
  };
151
154
  export var changeFromMediaInlineToMediaSingleNode = function changeFromMediaInlineToMediaSingleNode(view, fromNode, widthPluginState, editorAnalyticsAPI) {
@@ -37,6 +37,10 @@ export declare class MediaPluginStateImplementation implements MediaPluginState
37
37
  resizingWidth: number;
38
38
  currentMaxWidth?: number;
39
39
  allowInlineImages: boolean;
40
+ lastAddedMediaSingleFileIds: {
41
+ id: string;
42
+ selectionPosition: number;
43
+ }[];
40
44
  private view;
41
45
  private destroyed;
42
46
  private errorReporter;
@@ -64,12 +68,14 @@ export declare class MediaPluginStateImplementation implements MediaPluginState
64
68
  private isMediaSchemaNode;
65
69
  private getDomElement;
66
70
  get contextIdentifierProvider(): import("@atlaskit/editor-common/provider-factory").ContextIdentifierProvider | undefined;
71
+ onNodeInserted: (id: string, selectionPosition: number) => void;
67
72
  /**
68
73
  * we insert a new file by inserting a initial state for that file.
69
74
  *
70
75
  * called when we insert a new file via the picker (connected via pickerfacade)
71
76
  */
72
77
  insertFile: (mediaState: MediaState, onMediaStateChanged: MediaStateEventSubscriber, pickerType?: string) => void;
78
+ private selectLastAddedMediaNode;
73
79
  addPendingTask: (task: Promise<any>) => void;
74
80
  splitMediaGroup: () => boolean;
75
81
  onPopupPickerClose: () => void;
@@ -35,6 +35,10 @@ export interface MediaPluginState {
35
35
  resizingWidth: number;
36
36
  currentMaxWidth?: number;
37
37
  allowInlineImages?: boolean;
38
+ lastAddedMediaSingleFileIds: {
39
+ id: string;
40
+ selectionPosition: number;
41
+ }[];
38
42
  dispatch?: Dispatch;
39
43
  setMediaProvider: (mediaProvider?: Promise<MediaProvider>) => Promise<void>;
40
44
  getMediaOptions: () => MediaPluginOptions;
@@ -0,0 +1,5 @@
1
+ import type { IntlShape } from 'react-intl-next';
2
+ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
3
+ import type { Command, FloatingToolbarButton } from '@atlaskit/editor-common/types';
4
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
5
+ export declare const commentButton: (intl: IntlShape, state: EditorState, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => FloatingToolbarButton<Command>;
@@ -14,7 +14,7 @@ export interface MediaSingleState extends MediaState {
14
14
  export declare const isMediaSingle: (schema: Schema, fileMimeType?: string) => boolean;
15
15
  export type InsertMediaAsMediaSingle = (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia) => boolean;
16
16
  export declare const insertMediaAsMediaSingle: (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => boolean;
17
- export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined) => boolean;
17
+ export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined, onNodeInserted?: ((id: string, selectionPosition: number) => void) | undefined) => boolean;
18
18
  export declare const changeFromMediaInlineToMediaSingleNode: (view: EditorView, fromNode: PMNode, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined) => boolean;
19
19
  export declare const createMediaSingleNode: (schema: Schema, collection: string, maxWidth?: number, minWidth?: number, alignLeftOnInsert?: boolean) => (mediaState: MediaSingleState) => PMNode;
20
20
  export declare function isCaptionNode(editorView: EditorView): boolean;
@@ -37,6 +37,10 @@ export declare class MediaPluginStateImplementation implements MediaPluginState
37
37
  resizingWidth: number;
38
38
  currentMaxWidth?: number;
39
39
  allowInlineImages: boolean;
40
+ lastAddedMediaSingleFileIds: {
41
+ id: string;
42
+ selectionPosition: number;
43
+ }[];
40
44
  private view;
41
45
  private destroyed;
42
46
  private errorReporter;
@@ -64,12 +68,14 @@ export declare class MediaPluginStateImplementation implements MediaPluginState
64
68
  private isMediaSchemaNode;
65
69
  private getDomElement;
66
70
  get contextIdentifierProvider(): import("@atlaskit/editor-common/provider-factory").ContextIdentifierProvider | undefined;
71
+ onNodeInserted: (id: string, selectionPosition: number) => void;
67
72
  /**
68
73
  * we insert a new file by inserting a initial state for that file.
69
74
  *
70
75
  * called when we insert a new file via the picker (connected via pickerfacade)
71
76
  */
72
77
  insertFile: (mediaState: MediaState, onMediaStateChanged: MediaStateEventSubscriber, pickerType?: string) => void;
78
+ private selectLastAddedMediaNode;
73
79
  addPendingTask: (task: Promise<any>) => void;
74
80
  splitMediaGroup: () => boolean;
75
81
  onPopupPickerClose: () => void;
@@ -35,6 +35,10 @@ export interface MediaPluginState {
35
35
  resizingWidth: number;
36
36
  currentMaxWidth?: number;
37
37
  allowInlineImages?: boolean;
38
+ lastAddedMediaSingleFileIds: {
39
+ id: string;
40
+ selectionPosition: number;
41
+ }[];
38
42
  dispatch?: Dispatch;
39
43
  setMediaProvider: (mediaProvider?: Promise<MediaProvider>) => Promise<void>;
40
44
  getMediaOptions: () => MediaPluginOptions;
@@ -0,0 +1,5 @@
1
+ import type { IntlShape } from 'react-intl-next';
2
+ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
3
+ import type { Command, FloatingToolbarButton } from '@atlaskit/editor-common/types';
4
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
5
+ export declare const commentButton: (intl: IntlShape, state: EditorState, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => FloatingToolbarButton<Command>;
@@ -14,7 +14,7 @@ export interface MediaSingleState extends MediaState {
14
14
  export declare const isMediaSingle: (schema: Schema, fileMimeType?: string) => boolean;
15
15
  export type InsertMediaAsMediaSingle = (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia) => boolean;
16
16
  export declare const insertMediaAsMediaSingle: (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => boolean;
17
- export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined) => boolean;
17
+ export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined, onNodeInserted?: ((id: string, selectionPosition: number) => void) | undefined) => boolean;
18
18
  export declare const changeFromMediaInlineToMediaSingleNode: (view: EditorView, fromNode: PMNode, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined) => boolean;
19
19
  export declare const createMediaSingleNode: (schema: Schema, collection: string, maxWidth?: number, minWidth?: number, alignLeftOnInsert?: boolean) => (mediaState: MediaSingleState) => PMNode;
20
20
  export declare function isCaptionNode(editorView: EditorView): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "1.2.3",
3
+ "version": "1.4.0",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -37,7 +37,7 @@
37
37
  "@atlaskit/analytics-namespaced-context": "^6.9.0",
38
38
  "@atlaskit/analytics-next": "^9.2.0",
39
39
  "@atlaskit/button": "^17.6.0",
40
- "@atlaskit/editor-common": "^78.7.0",
40
+ "@atlaskit/editor-common": "^78.8.0",
41
41
  "@atlaskit/editor-palette": "1.5.2",
42
42
  "@atlaskit/editor-plugin-analytics": "^1.0.0",
43
43
  "@atlaskit/editor-plugin-decorations": "^1.0.0",
@@ -62,7 +62,7 @@
62
62
  "@atlaskit/media-ui": "^25.2.0",
63
63
  "@atlaskit/media-viewer": "^48.2.0",
64
64
  "@atlaskit/platform-feature-flags": "^0.2.0",
65
- "@atlaskit/primitives": "^3.0.0",
65
+ "@atlaskit/primitives": "^3.1.0",
66
66
  "@atlaskit/textfield": "^6.0.0",
67
67
  "@atlaskit/theme": "^12.6.0",
68
68
  "@atlaskit/tokens": "^1.38.0",
@@ -143,6 +143,9 @@
143
143
  },
144
144
  "platform.editor.media.fix-copy-paste-excel_62g4s": {
145
145
  "type": "boolean"
146
+ },
147
+ "platform.editor.media.autoselect-inserted-image_oumto": {
148
+ "type": "boolean"
146
149
  }
147
150
  },
148
151
  "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.0",