@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
@@ -2,7 +2,6 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React from 'react';
3
3
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
4
4
  import { alignmentIcons, buildLayoutButtons, IconCard, IconEmbed, IconInline, layoutToMessages, wrappingIcons } from '@atlaskit/editor-common/card';
5
- import { altTextMessages } from '@atlaskit/editor-common/media';
6
5
  import { mediaInlineImagesEnabled } from '@atlaskit/editor-common/media-inline';
7
6
  import commonMessages, { cardMessages, mediaAndEmbedToolbarMessages } from '@atlaskit/editor-common/messages';
8
7
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
@@ -10,13 +9,11 @@ import { contains, findParentNodeOfType, hasParentNodeOfType, removeSelectedNode
10
9
  import CopyIcon from '@atlaskit/icon/core/copy';
11
10
  import DeleteIcon from '@atlaskit/icon/core/delete';
12
11
  import GrowDiagonalIcon from '@atlaskit/icon/core/grow-diagonal';
13
- import GrowHorizontalIcon from '@atlaskit/icon/core/grow-horizontal';
14
12
  import ImageFullscreenIcon from '@atlaskit/icon/core/image-fullscreen';
15
13
  import ImageInlineIcon from '@atlaskit/icon/core/image-inline';
16
14
  import MaximizeIcon from '@atlaskit/icon/core/maximize';
17
15
  import DownloadIcon from '@atlaskit/icon/core/migration/download';
18
16
  import SmartLinkCardIcon from '@atlaskit/icon/core/smart-link-card';
19
- import TextIcon from '@atlaskit/icon/core/text';
20
17
  import FilePreviewIcon from '@atlaskit/icon/glyph/editor/file-preview';
21
18
  import RemoveIcon from '@atlaskit/icon/glyph/editor/remove';
22
19
  import { mediaFilmstripItemDOMSelector } from '@atlaskit/media-filmstrip';
@@ -25,17 +22,15 @@ import { fg } from '@atlaskit/platform-feature-flags';
25
22
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
26
23
  import { MediaSingleNodeSelector } from '../../nodeviews/styles';
27
24
  import { getPluginState as getMediaAltTextPluginState } from '../../pm-plugins/alt-text';
28
- import { openMediaAltTextMenu } from '../../pm-plugins/alt-text/commands';
29
25
  import { showLinkingToolbar } from '../../pm-plugins/commands/linking';
30
26
  import { getMediaLinkingState } from '../../pm-plugins/linking';
31
27
  import { getPluginState as getMediaPixelResizingPluginState } from '../../pm-plugins/pixel-resizing';
32
- import { openPixelEditor } from '../../pm-plugins/pixel-resizing/commands';
33
28
  import { FullWidthDisplay, PixelEntry } from '../../pm-plugins/pixel-resizing/ui';
34
29
  import { stateKey } from '../../pm-plugins/plugin-key';
35
30
  import { currentMediaOrInlineNodeBorderMark } from '../../pm-plugins/utils/current-media-node';
36
31
  import { isVideo } from '../../pm-plugins/utils/media-single';
37
32
  import ImageBorderItem from '../../ui/ImageBorder';
38
- import { altTextButton, getAltTextToolbar } from './alt-text';
33
+ import { altTextButton, getAltTextToolbar, getAltTextDropdownOption } from './alt-text';
39
34
  import { changeMediaCardToInline, changeMediaSingleToMediaInline, setBorderMark, toggleBorderMark } from './commands';
40
35
  import { commentButton } from './comments';
41
36
  import { shouldShowImageBorder } from './imageBorder';
@@ -43,8 +38,8 @@ import { LayoutGroup } from './layout-group';
43
38
  import { getLinkingDropdownOptions, getLinkingToolbar, getOpenLinkToolbarButtonOption, shouldShowMediaLinkToolbar } from './linking';
44
39
  import { LinkToolbarAppearance } from './linking-toolbar-appearance';
45
40
  import { generateMediaInlineFloatingToolbar } from './mediaInline';
46
- import { getPixelResizingToolbar } from './pixel-resizing';
47
- import { canShowSwitchButtons, downloadMedia, getMaxToolbarWidth, getSelectedLayoutIcon, getSelectedMediaSingle, getSelectedNearestMediaContainerNodeAttrs, removeMediaGroupNode } from './utils';
41
+ import { getPixelResizingToolbar, getResizeDropdownOption } from './pixel-resizing';
42
+ import { canShowSwitchButtons, downloadMedia, getMaxToolbarWidth, getSelectedLayoutIcon, getSelectedMediaSingle, getSelectedNearestMediaContainerNodeAttrs, removeMediaGroupNode, updateToFullHeightSeparator } from './utils';
48
43
  const mediaTypeMessages = {
49
44
  image: messages.file_image_is_selected,
50
45
  video: messages.file_video_is_selected,
@@ -210,7 +205,6 @@ const generateMediaCardFloatingToolbar = (state, intl, mediaPluginState, hoverDe
210
205
  fullHeight: true
211
206
  }, download, {
212
207
  type: 'separator',
213
- fullHeight: true,
214
208
  supportsViewMode: true
215
209
  }, preview, {
216
210
  type: 'separator',
@@ -240,6 +234,7 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
240
234
  const {
241
235
  hoverDecoration
242
236
  } = (_pluginInjectionApi$d = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d2 = pluginInjectionApi.decorations) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.actions) !== null && _pluginInjectionApi$d !== void 0 ? _pluginInjectionApi$d : {};
237
+ const isEditorControlsEnabled = editorExperiment('platform_editor_controls', 'variant1');
243
238
  if (shouldShowImageBorder(state)) {
244
239
  toolbarButtons.push({
245
240
  type: 'custom',
@@ -328,7 +323,7 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
328
323
  const hasCaption = contains(selectedNode.node, state.schema.nodes.caption);
329
324
  const inlineSwitcherTitle = intl.formatMessage(hasCaption ? mediaAndEmbedToolbarMessages.changeToMediaInlineImageCaptionWarning : mediaAndEmbedToolbarMessages.changeToMediaInlineImage);
330
325
  const floatingSwitcherTitle = intl.formatMessage(mediaAndEmbedToolbarMessages.changeToMediaSingle);
331
- if (editorExperiment('platform_editor_controls', 'control')) {
326
+ if (!isEditorControlsEnabled) {
332
327
  var _pluginInjectionApi$a4;
333
328
  toolbarButtons.push({
334
329
  type: 'button',
@@ -462,14 +457,14 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
462
457
  }
463
458
  return [sizeInput];
464
459
  }
465
- if (editorExperiment('platform_editor_controls', 'control')) {
460
+ if (!isEditorControlsEnabled) {
466
461
  toolbarButtons.push(sizeInput);
467
462
  toolbarButtons.push({
468
463
  type: 'separator'
469
464
  });
470
465
  }
471
466
  }
472
- if (editorExperiment('platform_editor_controls', 'control')) {
467
+ if (!isEditorControlsEnabled) {
473
468
  if (allowCommentsOnMedia) {
474
469
  toolbarButtons.push(commentButton(intl, state, pluginInjectionApi), {
475
470
  type: 'separator',
@@ -573,29 +568,45 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
573
568
  supportsViewMode: true
574
569
  });
575
570
  }
576
- if (allowAltTextOnImages && editorExperiment('platform_editor_controls', 'control')) {
577
- var _pluginInjectionApi$a7;
578
- 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), {
579
- type: 'separator'
571
+ if (!isEditorControlsEnabled) {
572
+ if (allowAltTextOnImages) {
573
+ var _pluginInjectionApi$a7;
574
+ 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), {
575
+ type: 'separator'
576
+ });
577
+ }
578
+ const removeButton = {
579
+ id: 'editor.media.delete',
580
+ type: 'button',
581
+ appearance: 'danger',
582
+ focusEditoronEnter: true,
583
+ icon: DeleteIcon,
584
+ iconFallback: RemoveIcon,
585
+ onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, true),
586
+ onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, false),
587
+ onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, true),
588
+ onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, false),
589
+ title: intl.formatMessage(commonMessages.remove),
590
+ onClick: remove,
591
+ testId: 'media-toolbar-remove-button',
592
+ supportsViewMode: false
593
+ };
594
+ const items = [...toolbarButtons, {
595
+ type: 'copy-button',
596
+ items: [{
597
+ state,
598
+ formatMessage: intl.formatMessage,
599
+ nodeType: mediaSingle
600
+ }],
601
+ supportsViewMode: true
602
+ }];
603
+ items.push({
604
+ type: 'separator',
605
+ supportsViewMode: false
580
606
  });
581
- }
582
- const removeButton = {
583
- id: 'editor.media.delete',
584
- type: 'button',
585
- appearance: 'danger',
586
- focusEditoronEnter: true,
587
- icon: DeleteIcon,
588
- iconFallback: RemoveIcon,
589
- onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, true),
590
- onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, false),
591
- onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, true),
592
- onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, false),
593
- title: intl.formatMessage(commonMessages.remove),
594
- onClick: remove,
595
- testId: 'media-toolbar-remove-button',
596
- supportsViewMode: false
597
- };
598
- if (editorExperiment('platform_editor_controls', 'variant1')) {
607
+ items.push(removeButton);
608
+ return items;
609
+ } else {
599
610
  // Preview Support
600
611
  if (allowAdvancedToolBarOptions && allowImagePreview) {
601
612
  var _mediaNode$attrs2;
@@ -621,8 +632,7 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
621
632
  supportsViewMode: true
622
633
  }, {
623
634
  type: 'separator',
624
- supportsViewMode: true,
625
- fullHeight: true
635
+ supportsViewMode: true
626
636
  });
627
637
  }
628
638
  }
@@ -631,8 +641,7 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
631
641
  if (allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable) {
632
642
  toolbarButtons.push(getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi), {
633
643
  type: 'separator',
634
- supportsViewMode: true,
635
- fullHeight: true
644
+ supportsViewMode: true
636
645
  });
637
646
  }
638
647
  isViewOnly && toolbarButtons.push({
@@ -648,26 +657,11 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
648
657
  supportsViewMode: true
649
658
  });
650
659
  if (allowAdvancedToolBarOptions && allowCommentsOnMedia) {
651
- // TODO: ED-26962 - add separator when overflow menu is added
660
+ updateToFullHeightSeparator(toolbarButtons);
652
661
  toolbarButtons.push(commentButton(intl, state, pluginInjectionApi));
653
662
  }
654
663
  return toolbarButtons;
655
664
  }
656
- const items = [...toolbarButtons, {
657
- type: 'copy-button',
658
- items: [{
659
- state,
660
- formatMessage: intl.formatMessage,
661
- nodeType: mediaSingle
662
- }],
663
- supportsViewMode: true
664
- }];
665
- items.push({
666
- type: 'separator',
667
- supportsViewMode: false
668
- });
669
- items.push(removeButton);
670
- return items;
671
665
  };
672
666
  const getMediaTypeMessage = selectedNodeTypeSingle => {
673
667
  const mediaType = Object.keys(mediaTypeMessages).find(key => selectedNodeTypeSingle === null || selectedNodeTypeSingle === void 0 ? void 0 : selectedNodeTypeSingle.includes(key));
@@ -769,34 +763,17 @@ export const floatingToolbar = (state, intl, options = {}, pluginInjectionApi) =
769
763
  }
770
764
  if (!mediaPluginState.isResizing && editorExperiment('platform_editor_controls', 'variant1')) {
771
765
  var _pluginInjectionApi$a9;
772
- const lastItem = items.at(-1);
773
- if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === 'separator') {
774
- lastItem.fullHeight = true;
775
- } else if (items.length) {
776
- items.push({
777
- type: 'separator',
778
- fullHeight: true
766
+ updateToFullHeightSeparator(items);
767
+ const customOptions = [...getLinkingDropdownOptions(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly), ...getAltTextDropdownOption(state, intl.formatMessage, allowAltTextOnImages, selectedNodeType, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a9 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a9 === void 0 ? void 0 : _pluginInjectionApi$a9.actions), ...getResizeDropdownOption(options, state, intl.formatMessage, selectedNodeType)];
768
+ if (customOptions.length) {
769
+ customOptions.push({
770
+ type: 'separator'
779
771
  });
780
772
  }
781
- const altTextTitle = intl.formatMessage(altTextMessages.addAltText);
782
773
  items.push({
783
774
  type: 'overflow-dropdown',
784
- options: [...getLinkingDropdownOptions(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly), {
785
- title: altTextTitle,
786
- onClick: openMediaAltTextMenu(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a9 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a9 === void 0 ? void 0 : _pluginInjectionApi$a9.actions),
787
- icon: /*#__PURE__*/React.createElement(TextIcon, {
788
- label: ""
789
- })
790
- }, {
791
- title: 'Resize',
792
- onClick: openPixelEditor(),
793
- icon: /*#__PURE__*/React.createElement(GrowHorizontalIcon, {
794
- label: ""
795
- }),
796
- testId: 'media-pixel-resizing-dropdown-option'
797
- }, {
798
- type: 'separator'
799
- }, {
775
+ id: 'media',
776
+ options: [...customOptions, {
800
777
  title: 'Copy',
801
778
  onClick: () => {
802
779
  var _pluginInjectionApi$c10, _pluginInjectionApi$f5;
@@ -162,7 +162,6 @@ export const generateMediaInlineFloatingToolbar = (state, intl, mediaPluginState
162
162
  fullHeight: true
163
163
  }, download, {
164
164
  type: 'separator',
165
- fullHeight: true,
166
165
  supportsViewMode: true
167
166
  }, preview, {
168
167
  type: 'separator',
@@ -180,6 +179,13 @@ const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecorati
180
179
  const mediaSingleTitle = intl.formatMessage(mediaAndEmbedToolbarMessages.changeToMediaSingle);
181
180
  const widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
182
181
  const inlineImageItems = [];
182
+ const isEditorControlsEnabled = editorExperiment('platform_editor_controls', 'variant1');
183
+ const {
184
+ isViewOnly,
185
+ allowAltTextOnImages,
186
+ allowLinking,
187
+ allowImagePreview
188
+ } = options;
183
189
  if (shouldShowImageBorder(state)) {
184
190
  inlineImageItems.push({
185
191
  type: 'custom',
@@ -211,9 +217,20 @@ const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecorati
211
217
  type: 'separator'
212
218
  });
213
219
  }
220
+ const download = {
221
+ id: 'editor.media.image.download',
222
+ type: 'button',
223
+ icon: DownloadIcon,
224
+ onClick: () => {
225
+ downloadMedia(mediaPluginState, options.isViewOnly);
226
+ return true;
227
+ },
228
+ title: intl.formatMessage(messages.download),
229
+ supportsViewMode: true
230
+ };
214
231
 
215
232
  // For Editor Controls: show options to convert from 'Inline' to 'Original size' via dropdown
216
- if (editorExperiment('platform_editor_controls', 'control')) {
233
+ if (!isEditorControlsEnabled) {
217
234
  inlineImageItems.push({
218
235
  id: 'editor.media.convert.mediainline',
219
236
  type: 'button',
@@ -243,58 +260,7 @@ const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecorati
243
260
  onClick: changeMediaInlineToMediaSingle(editorAnalyticsAPI, widthPluginState)
244
261
  }, {
245
262
  type: 'separator'
246
- });
247
- } else {
248
- const options = [{
249
- id: 'editor.media.convert.mediainline',
250
- title: mediaInlineImageTitle,
251
- onClick: () => {
252
- return true;
253
- },
254
- selected: true,
255
- disabled: false,
256
- icon: /*#__PURE__*/React.createElement(ImageInlineIcon, {
257
- color: "currentColor",
258
- spacing: "spacious",
259
- label: mediaInlineImageTitle,
260
- LEGACY_size: "medium",
261
- LEGACY_fallbackIcon: IconInline
262
- })
263
263
  }, {
264
- id: 'editor.media.convert.mediasingle',
265
- title: mediaSingleTitle,
266
- onClick: changeMediaInlineToMediaSingle(editorAnalyticsAPI, widthPluginState),
267
- icon: /*#__PURE__*/React.createElement(ImageFullscreenIcon, {
268
- color: "currentColor",
269
- spacing: "spacious",
270
- label: mediaSingleTitle,
271
- LEGACY_size: "medium",
272
- LEGACY_fallbackIcon: IconEmbed
273
- })
274
- }];
275
- const switchFromInlineToBlock = {
276
- id: 'media-inline-to-block-toolbar-item',
277
- testId: 'media-inline-to-block-dropdown',
278
- type: 'dropdown',
279
- options: options,
280
- title: intl.formatMessage(messages.sizeOptions),
281
- icon: () => /*#__PURE__*/React.createElement(ImageInlineIcon, {
282
- color: "currentColor",
283
- spacing: "spacious",
284
- label: mediaInlineImageTitle,
285
- LEGACY_size: "medium",
286
- LEGACY_fallbackIcon: IconInline
287
- })
288
- };
289
- inlineImageItems.push(switchFromInlineToBlock, {
290
- type: 'separator',
291
- fullHeight: true
292
- });
293
- }
294
-
295
- // TODO: ED-26961 - editor controls move to overflow menu
296
- if (editorExperiment('platform_editor_controls', 'control')) {
297
- inlineImageItems.push({
298
264
  type: 'custom',
299
265
  fallback: [],
300
266
  render: (editorView, idx) => {
@@ -343,15 +309,67 @@ const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecorati
343
309
  },
344
310
  supportsViewMode: true
345
311
  });
312
+ } else {
313
+ const options = [{
314
+ id: 'editor.media.convert.mediainline',
315
+ title: mediaInlineImageTitle,
316
+ onClick: () => {
317
+ return true;
318
+ },
319
+ selected: true,
320
+ disabled: false,
321
+ icon: /*#__PURE__*/React.createElement(ImageInlineIcon, {
322
+ color: "currentColor",
323
+ spacing: "spacious",
324
+ label: mediaInlineImageTitle,
325
+ LEGACY_size: "medium",
326
+ LEGACY_fallbackIcon: IconInline
327
+ })
328
+ }, {
329
+ id: 'editor.media.convert.mediasingle',
330
+ title: mediaSingleTitle,
331
+ onClick: changeMediaInlineToMediaSingle(editorAnalyticsAPI, widthPluginState),
332
+ icon: /*#__PURE__*/React.createElement(ImageFullscreenIcon, {
333
+ color: "currentColor",
334
+ spacing: "spacious",
335
+ label: mediaSingleTitle,
336
+ LEGACY_size: "medium",
337
+ LEGACY_fallbackIcon: IconEmbed
338
+ })
339
+ }];
340
+ const switchFromInlineToBlock = {
341
+ id: 'media-inline-to-block-toolbar-item',
342
+ testId: 'media-inline-to-block-dropdown',
343
+ type: 'dropdown',
344
+ options: options,
345
+ title: intl.formatMessage(messages.sizeOptions),
346
+ icon: () => /*#__PURE__*/React.createElement(ImageInlineIcon, {
347
+ color: "currentColor",
348
+ spacing: "spacious",
349
+ label: mediaInlineImageTitle,
350
+ LEGACY_size: "medium",
351
+ LEGACY_fallbackIcon: IconInline
352
+ })
353
+ };
354
+ inlineImageItems.push(switchFromInlineToBlock, {
355
+ type: 'separator',
356
+ fullHeight: true
357
+ });
358
+ if (isViewOnly) {
359
+ inlineImageItems.push(download, {
360
+ type: 'separator',
361
+ supportsViewMode: true
362
+ });
363
+ }
346
364
  }
347
365
 
348
366
  //Image Preview
349
- if (options.allowImagePreview) {
367
+ if (allowImagePreview) {
350
368
  inlineImageItems.push({
351
369
  id: 'editor.media.viewer',
352
370
  testId: 'file-preview-toolbar-button',
353
371
  type: 'button',
354
- icon: MaximizeIcon,
372
+ icon: isEditorControlsEnabled ? GrowDiagonalIcon : MaximizeIcon,
355
373
  iconFallback: FilePreviewIcon,
356
374
  title: intl.formatMessage(messages.preview),
357
375
  onClick: () => {
@@ -364,42 +382,30 @@ const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecorati
364
382
  supportsViewMode: true
365
383
  }, {
366
384
  type: 'separator',
367
- supportsViewMode: true,
368
- fullHeight: editorExperiment('platform_editor_controls', 'variant1')
385
+ supportsViewMode: true
369
386
  });
370
387
  }
371
388
 
372
389
  // open link
373
- if (options.allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable && editorExperiment('platform_editor_controls', 'variant1')) {
390
+ if (allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable && isEditorControlsEnabled) {
374
391
  inlineImageItems.push(getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi), {
375
392
  type: 'separator',
376
- supportsViewMode: true,
377
- fullHeight: true
393
+ supportsViewMode: true
378
394
  });
379
395
  }
380
- if (options.isViewOnly) {
381
- inlineImageItems.push({
382
- id: 'editor.media.image.download',
383
- type: 'button',
384
- icon: DownloadIcon,
385
- onClick: () => {
386
- downloadMedia(mediaPluginState, options.isViewOnly);
387
- return true;
388
- },
389
- title: intl.formatMessage(messages.download),
390
- supportsViewMode: true
391
- }, {
396
+ if (isViewOnly && !isEditorControlsEnabled) {
397
+ inlineImageItems.push(download, {
392
398
  type: 'separator',
393
399
  supportsViewMode: true
394
400
  });
395
401
  }
396
- if (options.allowAltTextOnImages && editorExperiment('platform_editor_controls', 'control')) {
402
+ if (allowAltTextOnImages && !isEditorControlsEnabled) {
397
403
  var _pluginInjectionApi$a5;
398
404
  inlineImageItems.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a5 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a5 === void 0 ? void 0 : _pluginInjectionApi$a5.actions), {
399
405
  type: 'separator'
400
406
  });
401
407
  }
402
- if (options.isViewOnly || editorExperiment('platform_editor_controls', 'control')) {
408
+ if (isViewOnly || !isEditorControlsEnabled) {
403
409
  inlineImageItems.push({
404
410
  type: 'copy-button',
405
411
  supportsViewMode: true,
@@ -410,7 +416,7 @@ const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecorati
410
416
  }]
411
417
  });
412
418
  }
413
- if (editorExperiment('platform_editor_controls', 'control')) {
419
+ if (!isEditorControlsEnabled) {
414
420
  inlineImageItems.push({
415
421
  type: 'separator'
416
422
  });
@@ -1,4 +1,9 @@
1
1
  import React from 'react';
2
+ import { pixelEntryMessages as messages } from '@atlaskit/editor-common/media';
3
+ import { hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
4
+ import GrowHorizontalIcon from '@atlaskit/icon/core/grow-horizontal';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
6
+ import { openPixelEditor } from '../../pm-plugins/pixel-resizing/commands';
2
7
  import { PixelEntry } from '../../pm-plugins/pixel-resizing/ui';
3
8
  import { PIXEL_RESIZING_TOOLBAR_WIDTH } from '../../pm-plugins/pixel-resizing/ui/constants';
4
9
  import { getSelectedMediaSingle } from './utils';
@@ -34,4 +39,26 @@ export const getPixelResizingToolbar = (toolbarBaseConfig, {
34
39
  });
35
40
  }
36
41
  }]
37
- });
42
+ });
43
+ export const getResizeDropdownOption = (mediaOptions, state, formatMessage, selectedNodeType) => {
44
+ if ((selectedNodeType === null || selectedNodeType === void 0 ? void 0 : selectedNodeType.name) !== 'mediaSingle') {
45
+ return [];
46
+ }
47
+ const {
48
+ allowResizing,
49
+ allowResizingInTables,
50
+ allowAdvancedToolBarOptions
51
+ } = mediaOptions;
52
+ const isWithinTable = hasParentNodeOfType(state.schema.nodes.table)(state.selection);
53
+ if (allowAdvancedToolBarOptions && allowResizing && (!isWithinTable || allowResizingInTables === true) && fg('platform_editor_media_extended_resize_experience')) {
54
+ return [{
55
+ title: formatMessage(messages.resizeOption),
56
+ onClick: openPixelEditor(),
57
+ icon: /*#__PURE__*/React.createElement(GrowHorizontalIcon, {
58
+ label: ""
59
+ }),
60
+ testId: 'media-pixel-resizing-dropdown-option'
61
+ }];
62
+ }
63
+ return [];
64
+ };
@@ -126,4 +126,15 @@ export const canShowSwitchButtons = mediaSingleNode => {
126
126
  return mediaNode && !isVideo(mediaNode.attrs.__fileMimeType);
127
127
  }
128
128
  return false;
129
+ };
130
+ export const updateToFullHeightSeparator = items => {
131
+ const lastItem = items.at(-1);
132
+ if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === 'separator') {
133
+ lastItem.fullHeight = true;
134
+ } else if (items.length) {
135
+ items.push({
136
+ type: 'separator',
137
+ fullHeight: true
138
+ });
139
+ }
129
140
  };
@@ -201,7 +201,8 @@ export var MediaInline = function MediaInline(props) {
201
201
  border: {
202
202
  borderSize: borderMark === null || borderMark === void 0 ? void 0 : borderMark.attrs.size,
203
203
  borderColor: borderMark === null || borderMark === void 0 ? void 0 : borderMark.attrs.color
204
- }
204
+ },
205
+ isViewOnly: props.editorViewMode
205
206
  });
206
207
  }
207
208
  return jsx(MediaViewerContainer, {
@@ -64,6 +64,7 @@ var MediaNodeView = /*#__PURE__*/function (_SelectionBasedNodeVi) {
64
64
  });
65
65
  _defineProperty(_this, "renderMediaNodeWithState", function (contextIdentifierProvider) {
66
66
  return function (_ref2) {
67
+ var _this$reactComponentP;
67
68
  var editorWidth = _ref2.width,
68
69
  mediaProvider = _ref2.mediaProvider;
69
70
  var getPos = _this.getPos;
@@ -104,7 +105,8 @@ var MediaNodeView = /*#__PURE__*/function (_SelectionBasedNodeVi) {
104
105
  mediaProvider: mediaProvider,
105
106
  contextIdentifierProvider: contextIdentifierProvider,
106
107
  mediaOptions: mediaOptions,
107
- onExternalImageLoaded: _this.onExternalImageLoaded
108
+ onExternalImageLoaded: _this.onExternalImageLoaded,
109
+ isViewOnly: ((_this$reactComponentP = _this.reactComponentProps.pluginInjectionApi) === null || _this$reactComponentP === void 0 || (_this$reactComponentP = _this$reactComponentP.editorViewMode) === null || _this$reactComponentP === void 0 || (_this$reactComponentP = _this$reactComponentP.sharedState.currentState()) === null || _this$reactComponentP === void 0 ? void 0 : _this$reactComponentP.mode) === 'view'
108
110
  });
109
111
  };
110
112
  });
@@ -15,6 +15,7 @@ import { AnalyticsContext } from '@atlaskit/analytics-next';
15
15
  import { setNodeSelection, setTextSelection, withImageLoader } from '@atlaskit/editor-common/utils';
16
16
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
17
17
  import { Card, CardLoading } from '@atlaskit/media-card';
18
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
18
19
  import { stateKey as mediaStateKey } from '../../pm-plugins/plugin-key';
19
20
  import { MediaCardWrapper } from '../styles';
20
21
 
@@ -54,6 +55,13 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
54
55
  _defineProperty(_this, "selectMediaSingleFromCard", function (_ref2) {
55
56
  var event = _ref2.event;
56
57
  _this.selectMediaSingle(event);
58
+
59
+ // In edit mode (node content wrapper has contenteditable set to true), link redirection is disabled by default
60
+ // We need to call "stopPropagation" here in order to prevent in editor view mode, the browser from navigating to
61
+ // another URL if the media node is wrapped in a link mark.
62
+ if (_this.props.isViewOnly && editorExperiment('platform_editor_controls', 'variant1')) {
63
+ event.preventDefault();
64
+ }
57
65
  });
58
66
  _defineProperty(_this, "selectMediaSingle", function (event) {
59
67
  var propPos = _this.props.getPos();
@@ -61,9 +69,13 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
61
69
  return;
62
70
  }
63
71
 
72
+ // NOTE: This does not prevent the link navigation in the editor view mode, .preventDefault is needed (see selectMediaSingleFromCard)
73
+ // Hence it should be removed
64
74
  // We need to call "stopPropagation" here in order to prevent the browser from navigating to
65
75
  // another URL if the media node is wrapped in a link mark.
66
- event.stopPropagation();
76
+ if (editorExperiment('platform_editor_controls', 'control')) {
77
+ event.stopPropagation();
78
+ }
67
79
  var state = _this.props.view.state;
68
80
  if (event.shiftKey) {
69
81
  // don't select text if there is current selection in a table (as this would override selected cells)
@@ -54,8 +54,19 @@ function insertNodesWithOptionalParagraph(_ref) {
54
54
  if (state.selection.empty) {
55
55
  var insertFrom = atTheBeginningOfBlock(state) && fg('platform_editor_axe_leading_paragraph_from_media') ? state.selection.$from.before() : state.selection.from;
56
56
  if (fg('platform_editor_axe_leading_paragraph_from_media')) {
57
- var shouldInsertFrom = !isInsidePotentialEmptyParagraph(state);
58
- updatedTr = atTheBeginningOfBlock(state) ? pmSafeInsert(nodes[0], shouldInsertFrom ? insertFrom : undefined, false)(updatedTr) : updatedTr.insert(insertFrom, nodes);
57
+ if (fg('platform_editor_multi_images_overridden_upload_fix')) {
58
+ // the use of pmSafeInsert causes the node selection to media single node.
59
+ // It leads to discrepancy between the full-page and comment editor - not sure why :shrug:
60
+ // When multiple images are uploaded, the node selection is set to the previous node
61
+ // and got overridden by the next node inserted.
62
+ // It also causes the images position shifted when the images are uploaded.
63
+ // E.g the images are uploaded after a table, the images will be inserted inside the table.
64
+ // so we revert to use tr.insert instead. No extra paragraph is added.
65
+ updatedTr = updatedTr.insert(insertFrom, nodes);
66
+ } else {
67
+ var shouldInsertFrom = !isInsidePotentialEmptyParagraph(state);
68
+ updatedTr = atTheBeginningOfBlock(state) ? pmSafeInsert(nodes[0], shouldInsertFrom ? insertFrom : undefined, false)(updatedTr) : updatedTr.insert(insertFrom, nodes);
69
+ }
59
70
  } else {
60
71
  updatedTr.insert(insertFrom, nodes);
61
72
  }
@@ -6,8 +6,11 @@ import { addAltText, ToolTipContent } from '@atlaskit/editor-common/keymaps';
6
6
  import { altTextMessages as messages } from '@atlaskit/editor-common/media';
7
7
  import { MediaSharedClassNames as ClassNames } from '@atlaskit/editor-common/styles';
8
8
  import { RECENT_SEARCH_WIDTH_IN_PX as CONTAINER_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
9
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
10
+ import TextIcon from '@atlaskit/icon/core/text';
9
11
  import { openMediaAltTextMenu } from '../../pm-plugins/alt-text/commands';
10
12
  import AltTextEdit from '../../pm-plugins/alt-text/ui/AltTextEdit';
13
+ import { isImage } from '../../pm-plugins/utils/is-type';
11
14
  import { getMediaSingleOrInlineNodeFromSelection } from '../../pm-plugins/utils/media-common';
12
15
  import { getNodeType } from './commands';
13
16
  var testId = 'alt-text-edit-button';
@@ -73,4 +76,20 @@ export var getAltTextToolbar = function getAltTextToolbar(toolbarBaseConfig, opt
73
76
  className: ClassNames.FLOATING_TOOLBAR_COMPONENT,
74
77
  items: [altTextEditComponent(options)]
75
78
  });
79
+ };
80
+ export var getAltTextDropdownOption = function getAltTextDropdownOption(state, formatMessage, allowAltTextOnImages, selectedNodeType, editorAnalyticsAPI) {
81
+ var _state$schema$nodes = state.schema.nodes,
82
+ mediaSingle = _state$schema$nodes.mediaSingle,
83
+ mediaInline = _state$schema$nodes.mediaInline;
84
+ var mediaType = state.selection instanceof NodeSelection && state.selection.node.attrs.type;
85
+ if (allowAltTextOnImages && (selectedNodeType === mediaSingle || selectedNodeType === mediaInline && isImage(mediaType))) {
86
+ return [{
87
+ title: formatMessage(messages.addAltText),
88
+ onClick: openMediaAltTextMenu(editorAnalyticsAPI),
89
+ icon: /*#__PURE__*/React.createElement(TextIcon, {
90
+ label: ""
91
+ })
92
+ }];
93
+ }
94
+ return [];
76
95
  };