@atlaskit/editor-plugin-media 2.3.13 → 2.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/nodeviews/mediaInline.js +2 -1
  3. package/dist/cjs/nodeviews/mediaNodeView/index.js +3 -1
  4. package/dist/cjs/nodeviews/mediaNodeView/media.js +13 -1
  5. package/dist/cjs/pm-plugins/utils/media-single.js +13 -2
  6. package/dist/cjs/ui/toolbar/alt-text.js +20 -1
  7. package/dist/cjs/ui/toolbar/index.js +59 -82
  8. package/dist/cjs/ui/toolbar/mediaInline.js +75 -71
  9. package/dist/cjs/ui/toolbar/pixel-resizing.js +28 -3
  10. package/dist/cjs/ui/toolbar/utils.js +12 -1
  11. package/dist/es2019/nodeviews/mediaInline.js +2 -1
  12. package/dist/es2019/nodeviews/mediaNodeView/index.js +3 -1
  13. package/dist/es2019/nodeviews/mediaNodeView/media.js +13 -1
  14. package/dist/es2019/pm-plugins/utils/media-single.js +13 -2
  15. package/dist/es2019/ui/toolbar/alt-text.js +20 -0
  16. package/dist/es2019/ui/toolbar/index.js +55 -78
  17. package/dist/es2019/ui/toolbar/mediaInline.js +81 -75
  18. package/dist/es2019/ui/toolbar/pixel-resizing.js +28 -1
  19. package/dist/es2019/ui/toolbar/utils.js +11 -0
  20. package/dist/esm/nodeviews/mediaInline.js +2 -1
  21. package/dist/esm/nodeviews/mediaNodeView/index.js +3 -1
  22. package/dist/esm/nodeviews/mediaNodeView/media.js +13 -1
  23. package/dist/esm/pm-plugins/utils/media-single.js +13 -2
  24. package/dist/esm/ui/toolbar/alt-text.js +19 -0
  25. package/dist/esm/ui/toolbar/index.js +55 -78
  26. package/dist/esm/ui/toolbar/mediaInline.js +75 -71
  27. package/dist/esm/ui/toolbar/pixel-resizing.js +25 -0
  28. package/dist/esm/ui/toolbar/utils.js +11 -0
  29. package/dist/types/nodeviews/mediaNodeView/media.d.ts +1 -0
  30. package/dist/types/ui/toolbar/alt-text.d.ts +4 -2
  31. package/dist/types/ui/toolbar/pixel-resizing.d.ts +6 -2
  32. package/dist/types/ui/toolbar/utils.d.ts +2 -0
  33. package/dist/types-ts4.5/nodeviews/mediaNodeView/media.d.ts +1 -0
  34. package/dist/types-ts4.5/ui/toolbar/alt-text.d.ts +4 -2
  35. package/dist/types-ts4.5/ui/toolbar/pixel-resizing.d.ts +6 -2
  36. package/dist/types-ts4.5/ui/toolbar/utils.d.ts +2 -0
  37. package/package.json +5 -2
@@ -178,7 +178,6 @@ var generateMediaInlineFloatingToolbar = exports.generateMediaInlineFloatingTool
178
178
  fullHeight: true
179
179
  }, download, {
180
180
  type: 'separator',
181
- fullHeight: true,
182
181
  supportsViewMode: true
183
182
  }, preview, {
184
183
  type: 'separator',
@@ -195,6 +194,11 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
195
194
  var mediaSingleTitle = intl.formatMessage(_messages.mediaAndEmbedToolbarMessages.changeToMediaSingle);
196
195
  var widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
197
196
  var inlineImageItems = [];
197
+ var isEditorControlsEnabled = (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1');
198
+ var isViewOnly = options.isViewOnly,
199
+ allowAltTextOnImages = options.allowAltTextOnImages,
200
+ allowLinking = options.allowLinking,
201
+ allowImagePreview = options.allowImagePreview;
198
202
  if ((0, _imageBorder.shouldShowImageBorder)(state)) {
199
203
  inlineImageItems.push({
200
204
  type: 'custom',
@@ -224,9 +228,20 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
224
228
  type: 'separator'
225
229
  });
226
230
  }
231
+ var download = {
232
+ id: 'editor.media.image.download',
233
+ type: 'button',
234
+ icon: _download.default,
235
+ onClick: function onClick() {
236
+ (0, _utils.downloadMedia)(mediaPluginState, options.isViewOnly);
237
+ return true;
238
+ },
239
+ title: intl.formatMessage(_mediaUi.messages.download),
240
+ supportsViewMode: true
241
+ };
227
242
 
228
243
  // For Editor Controls: show options to convert from 'Inline' to 'Original size' via dropdown
229
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'control')) {
244
+ if (!isEditorControlsEnabled) {
230
245
  inlineImageItems.push({
231
246
  id: 'editor.media.convert.mediainline',
232
247
  type: 'button',
@@ -260,6 +275,48 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
260
275
  onClick: (0, _commands.changeMediaInlineToMediaSingle)(editorAnalyticsAPI, widthPluginState)
261
276
  }, {
262
277
  type: 'separator'
278
+ }, {
279
+ type: 'custom',
280
+ fallback: [],
281
+ render: function render(editorView, idx) {
282
+ if (editorView !== null && editorView !== void 0 && editorView.state) {
283
+ var editLink = function editLink() {
284
+ if (editorView) {
285
+ var _state = editorView.state,
286
+ dispatch = editorView.dispatch;
287
+ (0, _linking.showLinkingToolbar)(_state, dispatch);
288
+ }
289
+ };
290
+ var openLink = function openLink() {
291
+ if (editorView) {
292
+ var _pluginInjectionApi$a4;
293
+ var tr = editorView.state.tr,
294
+ dispatch = editorView.dispatch;
295
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 || _pluginInjectionApi$a4.actions.attachAnalyticsEvent({
296
+ eventType: _analytics.EVENT_TYPE.TRACK,
297
+ action: _analytics.ACTION.VISITED,
298
+ actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
299
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.LINK
300
+ })(tr);
301
+ dispatch(tr);
302
+ return true;
303
+ }
304
+ };
305
+ return /*#__PURE__*/_react.default.createElement(_linkingToolbarAppearance.LinkToolbarAppearance, {
306
+ key: idx,
307
+ editorState: editorView.state,
308
+ intl: intl,
309
+ mediaLinkingState: mediaLinkingState,
310
+ onAddLink: editLink,
311
+ onEditLink: editLink,
312
+ onOpenLink: openLink,
313
+ isInlineNode: true,
314
+ isViewOnly: options.isViewOnly
315
+ });
316
+ }
317
+ return null;
318
+ },
319
+ supportsViewMode: true
263
320
  });
264
321
  } else {
265
322
  var _options2 = [{
@@ -309,62 +366,21 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
309
366
  type: 'separator',
310
367
  fullHeight: true
311
368
  });
312
- }
313
-
314
- // TODO: ED-26961 - editor controls move to overflow menu
315
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'control')) {
316
- inlineImageItems.push({
317
- type: 'custom',
318
- fallback: [],
319
- render: function render(editorView, idx) {
320
- if (editorView !== null && editorView !== void 0 && editorView.state) {
321
- var editLink = function editLink() {
322
- if (editorView) {
323
- var _state = editorView.state,
324
- dispatch = editorView.dispatch;
325
- (0, _linking.showLinkingToolbar)(_state, dispatch);
326
- }
327
- };
328
- var openLink = function openLink() {
329
- if (editorView) {
330
- var _pluginInjectionApi$a4;
331
- var tr = editorView.state.tr,
332
- dispatch = editorView.dispatch;
333
- pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 || _pluginInjectionApi$a4.actions.attachAnalyticsEvent({
334
- eventType: _analytics.EVENT_TYPE.TRACK,
335
- action: _analytics.ACTION.VISITED,
336
- actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
337
- actionSubjectId: _analytics.ACTION_SUBJECT_ID.LINK
338
- })(tr);
339
- dispatch(tr);
340
- return true;
341
- }
342
- };
343
- return /*#__PURE__*/_react.default.createElement(_linkingToolbarAppearance.LinkToolbarAppearance, {
344
- key: idx,
345
- editorState: editorView.state,
346
- intl: intl,
347
- mediaLinkingState: mediaLinkingState,
348
- onAddLink: editLink,
349
- onEditLink: editLink,
350
- onOpenLink: openLink,
351
- isInlineNode: true,
352
- isViewOnly: options.isViewOnly
353
- });
354
- }
355
- return null;
356
- },
357
- supportsViewMode: true
358
- });
369
+ if (isViewOnly) {
370
+ inlineImageItems.push(download, {
371
+ type: 'separator',
372
+ supportsViewMode: true
373
+ });
374
+ }
359
375
  }
360
376
 
361
377
  //Image Preview
362
- if (options.allowImagePreview) {
378
+ if (allowImagePreview) {
363
379
  inlineImageItems.push({
364
380
  id: 'editor.media.viewer',
365
381
  testId: 'file-preview-toolbar-button',
366
382
  type: 'button',
367
- icon: _maximize.default,
383
+ icon: isEditorControlsEnabled ? _growDiagonal.default : _maximize.default,
368
384
  iconFallback: _filePreview.default,
369
385
  title: intl.formatMessage(_mediaUi.messages.preview),
370
386
  onClick: function onClick() {
@@ -377,42 +393,30 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
377
393
  supportsViewMode: true
378
394
  }, {
379
395
  type: 'separator',
380
- supportsViewMode: true,
381
- fullHeight: (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')
396
+ supportsViewMode: true
382
397
  });
383
398
  }
384
399
 
385
400
  // open link
386
- if (options.allowLinking && (0, _linking3.shouldShowMediaLinkToolbar)(state) && mediaLinkingState && mediaLinkingState.editable && (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
401
+ if (allowLinking && (0, _linking3.shouldShowMediaLinkToolbar)(state) && mediaLinkingState && mediaLinkingState.editable && isEditorControlsEnabled) {
387
402
  inlineImageItems.push((0, _linking3.getOpenLinkToolbarButtonOption)(intl, mediaLinkingState, pluginInjectionApi), {
388
403
  type: 'separator',
389
- supportsViewMode: true,
390
- fullHeight: true
404
+ supportsViewMode: true
391
405
  });
392
406
  }
393
- if (options.isViewOnly) {
394
- inlineImageItems.push({
395
- id: 'editor.media.image.download',
396
- type: 'button',
397
- icon: _download.default,
398
- onClick: function onClick() {
399
- (0, _utils.downloadMedia)(mediaPluginState, options.isViewOnly);
400
- return true;
401
- },
402
- title: intl.formatMessage(_mediaUi.messages.download),
403
- supportsViewMode: true
404
- }, {
407
+ if (isViewOnly && !isEditorControlsEnabled) {
408
+ inlineImageItems.push(download, {
405
409
  type: 'separator',
406
410
  supportsViewMode: true
407
411
  });
408
412
  }
409
- if (options.allowAltTextOnImages && (0, _experiments.editorExperiment)('platform_editor_controls', 'control')) {
413
+ if (allowAltTextOnImages && !isEditorControlsEnabled) {
410
414
  var _pluginInjectionApi$a5;
411
415
  inlineImageItems.push((0, _altText.altTextButton)(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a5 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a5 === void 0 ? void 0 : _pluginInjectionApi$a5.actions), {
412
416
  type: 'separator'
413
417
  });
414
418
  }
415
- if (options.isViewOnly || (0, _experiments.editorExperiment)('platform_editor_controls', 'control')) {
419
+ if (isViewOnly || !isEditorControlsEnabled) {
416
420
  inlineImageItems.push({
417
421
  type: 'copy-button',
418
422
  supportsViewMode: true,
@@ -423,7 +427,7 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
423
427
  }]
424
428
  });
425
429
  }
426
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'control')) {
430
+ if (!isEditorControlsEnabled) {
427
431
  inlineImageItems.push({
428
432
  type: 'separator'
429
433
  });
@@ -4,12 +4,17 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getPixelResizingToolbar = void 0;
7
+ exports.getResizeDropdownOption = exports.getPixelResizingToolbar = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = _interopRequireDefault(require("react"));
10
+ var _media = require("@atlaskit/editor-common/media");
11
+ var _utils = require("@atlaskit/editor-prosemirror/utils");
12
+ var _growHorizontal = _interopRequireDefault(require("@atlaskit/icon/core/grow-horizontal"));
13
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
+ var _commands = require("../../pm-plugins/pixel-resizing/commands");
10
15
  var _ui = require("../../pm-plugins/pixel-resizing/ui");
11
16
  var _constants = require("../../pm-plugins/pixel-resizing/ui/constants");
12
- var _utils = require("./utils");
17
+ var _utils2 = require("./utils");
13
18
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
19
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
20
  var getPixelResizingToolbar = exports.getPixelResizingToolbar = function getPixelResizingToolbar(toolbarBaseConfig, _ref) {
@@ -28,7 +33,7 @@ var getPixelResizingToolbar = exports.getPixelResizingToolbar = function getPixe
28
33
  if (!editorView) {
29
34
  return null;
30
35
  }
31
- var selectedMediaSingleNode = (0, _utils.getSelectedMediaSingle)(editorView.state);
36
+ var selectedMediaSingleNode = (0, _utils2.getSelectedMediaSingle)(editorView.state);
32
37
  if (!editorView || !selectedMediaSingleNode) {
33
38
  return null;
34
39
  }
@@ -44,4 +49,24 @@ var getPixelResizingToolbar = exports.getPixelResizingToolbar = function getPixe
44
49
  }
45
50
  }]
46
51
  });
52
+ };
53
+ var getResizeDropdownOption = exports.getResizeDropdownOption = function getResizeDropdownOption(mediaOptions, state, formatMessage, selectedNodeType) {
54
+ if ((selectedNodeType === null || selectedNodeType === void 0 ? void 0 : selectedNodeType.name) !== 'mediaSingle') {
55
+ return [];
56
+ }
57
+ var allowResizing = mediaOptions.allowResizing,
58
+ allowResizingInTables = mediaOptions.allowResizingInTables,
59
+ allowAdvancedToolBarOptions = mediaOptions.allowAdvancedToolBarOptions;
60
+ var isWithinTable = (0, _utils.hasParentNodeOfType)(state.schema.nodes.table)(state.selection);
61
+ if (allowAdvancedToolBarOptions && allowResizing && (!isWithinTable || allowResizingInTables === true) && (0, _platformFeatureFlags.fg)('platform_editor_media_extended_resize_experience')) {
62
+ return [{
63
+ title: formatMessage(_media.pixelEntryMessages.resizeOption),
64
+ onClick: (0, _commands.openPixelEditor)(),
65
+ icon: /*#__PURE__*/_react.default.createElement(_growHorizontal.default, {
66
+ label: ""
67
+ }),
68
+ testId: 'media-pixel-resizing-dropdown-option'
69
+ }];
70
+ }
71
+ return [];
47
72
  };
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.removeMediaGroupNode = exports.isExternalMedia = exports.getSelectedNearestMediaContainerNodeAttrs = exports.getSelectedMediaSingle = exports.getSelectedLayoutIcon = exports.getPixelWidthOfElement = exports.getMaxToolbarWidth = exports.downloadMedia = exports.canShowSwitchButtons = exports.calcNewLayout = void 0;
7
+ exports.updateToFullHeightSeparator = exports.removeMediaGroupNode = exports.isExternalMedia = exports.getSelectedNearestMediaContainerNodeAttrs = exports.getSelectedMediaSingle = exports.getSelectedLayoutIcon = exports.getPixelWidthOfElement = exports.getMaxToolbarWidth = exports.downloadMedia = exports.canShowSwitchButtons = exports.calcNewLayout = void 0;
8
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
10
  var _memoizeOne = _interopRequireDefault(require("memoize-one"));
@@ -153,4 +153,15 @@ var canShowSwitchButtons = exports.canShowSwitchButtons = function canShowSwitch
153
153
  return mediaNode && !(0, _mediaSingle2.isVideo)(mediaNode.attrs.__fileMimeType);
154
154
  }
155
155
  return false;
156
+ };
157
+ var updateToFullHeightSeparator = exports.updateToFullHeightSeparator = function updateToFullHeightSeparator(items) {
158
+ var lastItem = items.at(-1);
159
+ if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === 'separator') {
160
+ lastItem.fullHeight = true;
161
+ } else if (items.length) {
162
+ items.push({
163
+ type: 'separator',
164
+ fullHeight: true
165
+ });
166
+ }
156
167
  };
@@ -137,7 +137,8 @@ export const MediaInline = props => {
137
137
  border: {
138
138
  borderSize: borderMark === null || borderMark === void 0 ? void 0 : borderMark.attrs.size,
139
139
  borderColor: borderMark === null || borderMark === void 0 ? void 0 : borderMark.attrs.color
140
- }
140
+ },
141
+ isViewOnly: props.editorViewMode
141
142
  });
142
143
  }
143
144
  return jsx(MediaViewerContainer, {
@@ -53,6 +53,7 @@ class MediaNodeView extends SelectionBasedNodeView {
53
53
  width: editorWidth,
54
54
  mediaProvider
55
55
  }) => {
56
+ var _this$reactComponentP, _this$reactComponentP2, _this$reactComponentP3;
56
57
  const getPos = this.getPos;
57
58
  const {
58
59
  mediaOptions
@@ -97,7 +98,8 @@ class MediaNodeView extends SelectionBasedNodeView {
97
98
  mediaProvider: mediaProvider,
98
99
  contextIdentifierProvider: contextIdentifierProvider,
99
100
  mediaOptions: mediaOptions,
100
- onExternalImageLoaded: this.onExternalImageLoaded
101
+ onExternalImageLoaded: this.onExternalImageLoaded,
102
+ isViewOnly: ((_this$reactComponentP = this.reactComponentProps.pluginInjectionApi) === null || _this$reactComponentP === void 0 ? void 0 : (_this$reactComponentP2 = _this$reactComponentP.editorViewMode) === null || _this$reactComponentP2 === void 0 ? void 0 : (_this$reactComponentP3 = _this$reactComponentP2.sharedState.currentState()) === null || _this$reactComponentP3 === void 0 ? void 0 : _this$reactComponentP3.mode) === 'view'
101
103
  });
102
104
  };
103
105
  });
@@ -6,6 +6,7 @@ import { AnalyticsContext } from '@atlaskit/analytics-next';
6
6
  import { setNodeSelection, setTextSelection, withImageLoader } from '@atlaskit/editor-common/utils';
7
7
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
8
8
  import { Card, CardLoading } from '@atlaskit/media-card';
9
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
9
10
  import { stateKey as mediaStateKey } from '../../pm-plugins/plugin-key';
10
11
  import { MediaCardWrapper } from '../styles';
11
12
 
@@ -32,6 +33,13 @@ export class MediaNode extends Component {
32
33
  event
33
34
  }) => {
34
35
  this.selectMediaSingle(event);
36
+
37
+ // In edit mode (node content wrapper has contenteditable set to true), link redirection is disabled by default
38
+ // We need to call "stopPropagation" here in order to prevent in editor view mode, the browser from navigating to
39
+ // another URL if the media node is wrapped in a link mark.
40
+ if (this.props.isViewOnly && editorExperiment('platform_editor_controls', 'variant1')) {
41
+ event.preventDefault();
42
+ }
35
43
  });
36
44
  _defineProperty(this, "selectMediaSingle", event => {
37
45
  const propPos = this.props.getPos();
@@ -39,9 +47,13 @@ export class MediaNode extends Component {
39
47
  return;
40
48
  }
41
49
 
50
+ // NOTE: This does not prevent the link navigation in the editor view mode, .preventDefault is needed (see selectMediaSingleFromCard)
51
+ // Hence it should be removed
42
52
  // We need to call "stopPropagation" here in order to prevent the browser from navigating to
43
53
  // another URL if the media node is wrapped in a link mark.
44
- event.stopPropagation();
54
+ if (editorExperiment('platform_editor_controls', 'control')) {
55
+ event.stopPropagation();
56
+ }
45
57
  const {
46
58
  state
47
59
  } = this.props.view;
@@ -55,8 +55,19 @@ function insertNodesWithOptionalParagraph({
55
55
  if (state.selection.empty) {
56
56
  const insertFrom = atTheBeginningOfBlock(state) && fg('platform_editor_axe_leading_paragraph_from_media') ? state.selection.$from.before() : state.selection.from;
57
57
  if (fg('platform_editor_axe_leading_paragraph_from_media')) {
58
- const shouldInsertFrom = !isInsidePotentialEmptyParagraph(state);
59
- updatedTr = atTheBeginningOfBlock(state) ? pmSafeInsert(nodes[0], shouldInsertFrom ? insertFrom : undefined, false)(updatedTr) : updatedTr.insert(insertFrom, nodes);
58
+ if (fg('platform_editor_multi_images_overridden_upload_fix')) {
59
+ // the use of pmSafeInsert causes the node selection to media single node.
60
+ // It leads to discrepancy between the full-page and comment editor - not sure why :shrug:
61
+ // When multiple images are uploaded, the node selection is set to the previous node
62
+ // and got overridden by the next node inserted.
63
+ // It also causes the images position shifted when the images are uploaded.
64
+ // E.g the images are uploaded after a table, the images will be inserted inside the table.
65
+ // so we revert to use tr.insert instead. No extra paragraph is added.
66
+ updatedTr = updatedTr.insert(insertFrom, nodes);
67
+ } else {
68
+ const shouldInsertFrom = !isInsidePotentialEmptyParagraph(state);
69
+ updatedTr = atTheBeginningOfBlock(state) ? pmSafeInsert(nodes[0], shouldInsertFrom ? insertFrom : undefined, false)(updatedTr) : updatedTr.insert(insertFrom, nodes);
70
+ }
60
71
  } else {
61
72
  updatedTr.insert(insertFrom, nodes);
62
73
  }
@@ -3,8 +3,11 @@ import { addAltText, ToolTipContent } from '@atlaskit/editor-common/keymaps';
3
3
  import { altTextMessages as messages } from '@atlaskit/editor-common/media';
4
4
  import { MediaSharedClassNames as ClassNames } from '@atlaskit/editor-common/styles';
5
5
  import { RECENT_SEARCH_WIDTH_IN_PX as CONTAINER_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
6
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
7
+ import TextIcon from '@atlaskit/icon/core/text';
6
8
  import { openMediaAltTextMenu } from '../../pm-plugins/alt-text/commands';
7
9
  import AltTextEdit from '../../pm-plugins/alt-text/ui/AltTextEdit';
10
+ import { isImage } from '../../pm-plugins/utils/is-type';
8
11
  import { getMediaSingleOrInlineNodeFromSelection } from '../../pm-plugins/utils/media-common';
9
12
  import { getNodeType } from './commands';
10
13
  const testId = 'alt-text-edit-button';
@@ -75,4 +78,21 @@ export const getAltTextToolbar = (toolbarBaseConfig, options) => {
75
78
  className: ClassNames.FLOATING_TOOLBAR_COMPONENT,
76
79
  items: [altTextEditComponent(options)]
77
80
  };
81
+ };
82
+ export const getAltTextDropdownOption = (state, formatMessage, allowAltTextOnImages, selectedNodeType, editorAnalyticsAPI) => {
83
+ const {
84
+ mediaSingle,
85
+ mediaInline
86
+ } = state.schema.nodes;
87
+ const mediaType = state.selection instanceof NodeSelection && state.selection.node.attrs.type;
88
+ if (allowAltTextOnImages && (selectedNodeType === mediaSingle || selectedNodeType === mediaInline && isImage(mediaType))) {
89
+ return [{
90
+ title: formatMessage(messages.addAltText),
91
+ onClick: openMediaAltTextMenu(editorAnalyticsAPI),
92
+ icon: /*#__PURE__*/React.createElement(TextIcon, {
93
+ label: ""
94
+ })
95
+ }];
96
+ }
97
+ return [];
78
98
  };