@atlaskit/editor-plugin-media 8.8.0 → 8.10.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/mediaPlugin.js +44 -77
  3. package/dist/cjs/nodeviews/mediaNodeView/index.js +92 -7
  4. package/dist/cjs/nodeviews/mediaSingle.js +8 -1
  5. package/dist/cjs/pm-plugins/commands.js +1 -23
  6. package/dist/cjs/pm-plugins/main.js +0 -16
  7. package/dist/cjs/ui/ResizableMediaSingle/ResizableMediaSingleNext.js +16 -2
  8. package/dist/cjs/ui/ResizableMediaSingle/index.js +11 -0
  9. package/dist/cjs/ui/toolbar/index.js +3 -2
  10. package/dist/es2019/mediaPlugin.js +4 -39
  11. package/dist/es2019/nodeviews/mediaNodeView/index.js +88 -8
  12. package/dist/es2019/nodeviews/mediaSingle.js +8 -1
  13. package/dist/es2019/pm-plugins/commands.js +0 -22
  14. package/dist/es2019/pm-plugins/main.js +0 -14
  15. package/dist/es2019/ui/ResizableMediaSingle/ResizableMediaSingleNext.js +13 -2
  16. package/dist/es2019/ui/ResizableMediaSingle/index.js +11 -0
  17. package/dist/es2019/ui/toolbar/index.js +3 -2
  18. package/dist/esm/mediaPlugin.js +45 -78
  19. package/dist/esm/nodeviews/mediaNodeView/index.js +92 -7
  20. package/dist/esm/nodeviews/mediaSingle.js +8 -1
  21. package/dist/esm/pm-plugins/commands.js +0 -22
  22. package/dist/esm/pm-plugins/main.js +0 -16
  23. package/dist/esm/ui/ResizableMediaSingle/ResizableMediaSingleNext.js +16 -2
  24. package/dist/esm/ui/ResizableMediaSingle/index.js +11 -0
  25. package/dist/esm/ui/toolbar/index.js +3 -2
  26. package/dist/types/mediaPluginType.d.ts +3 -3
  27. package/dist/types/nodeviews/mediaNodeView/index.d.ts +13 -4
  28. package/dist/types/nodeviews/mediaSingle.d.ts +1 -0
  29. package/dist/types/pm-plugins/commands.d.ts +0 -2
  30. package/dist/types/pm-plugins/main.d.ts +1 -4
  31. package/dist/types/pm-plugins/types.d.ts +0 -3
  32. package/dist/types/ui/ResizableMediaSingle/index.d.ts +1 -0
  33. package/dist/types-ts4.5/mediaPluginType.d.ts +3 -3
  34. package/dist/types-ts4.5/nodeviews/mediaNodeView/index.d.ts +13 -4
  35. package/dist/types-ts4.5/nodeviews/mediaSingle.d.ts +1 -0
  36. package/dist/types-ts4.5/pm-plugins/commands.d.ts +0 -2
  37. package/dist/types-ts4.5/pm-plugins/main.d.ts +1 -4
  38. package/dist/types-ts4.5/pm-plugins/types.d.ts +0 -3
  39. package/dist/types-ts4.5/ui/ResizableMediaSingle/index.d.ts +1 -0
  40. package/package.json +3 -4
  41. package/dist/cjs/ui/ImageEditor/ModalWrapper.js +0 -69
  42. package/dist/cjs/ui/ImageEditor/index.js +0 -62
  43. package/dist/es2019/ui/ImageEditor/ModalWrapper.js +0 -58
  44. package/dist/es2019/ui/ImageEditor/index.js +0 -53
  45. package/dist/esm/ui/ImageEditor/ModalWrapper.js +0 -60
  46. package/dist/esm/ui/ImageEditor/index.js +0 -52
  47. package/dist/types/ui/ImageEditor/ModalWrapper.d.ts +0 -13
  48. package/dist/types/ui/ImageEditor/index.d.ts +0 -12
  49. package/dist/types-ts4.5/ui/ImageEditor/ModalWrapper.d.ts +0 -13
  50. package/dist/types-ts4.5/ui/ImageEditor/index.d.ts +0 -12
@@ -6,7 +6,6 @@ import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-che
6
6
  import { NodeSelection, PluginKey } from '@atlaskit/editor-prosemirror/state';
7
7
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
10
9
  import { lazyMediaView } from './nodeviews/lazy-media';
11
10
  import { lazyMediaGroupView } from './nodeviews/lazy-media-group';
12
11
  import { lazyMediaInlineView } from './nodeviews/lazy-media-inline';
@@ -17,7 +16,7 @@ import { mediaInlineSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/mediaInli
17
16
  import { mediaSingleSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/mediaSingle';
18
17
  import { createPlugin as createMediaAltTextPlugin } from './pm-plugins/alt-text';
19
18
  import keymapMediaAltTextPlugin from './pm-plugins/alt-text/keymap';
20
- import { hideMediaViewer, showMediaViewer, trackMediaPaste, hideImageEditor, showImageEditor } from './pm-plugins/commands';
19
+ import { hideMediaViewer, showMediaViewer, trackMediaPaste } from './pm-plugins/commands';
21
20
  import keymapPlugin from './pm-plugins/keymap';
22
21
  import keymapMediaSinglePlugin from './pm-plugins/keymap-media';
23
22
  import linkingPlugin from './pm-plugins/linking';
@@ -27,7 +26,6 @@ import { createPlugin as createMediaPixelResizingPlugin } from './pm-plugins/pix
27
26
  import { stateKey } from './pm-plugins/plugin-key';
28
27
  import { createMediaIdentifierArray, extractMediaNodes } from './pm-plugins/utils/media-common';
29
28
  import { insertMediaAsMediaSingle } from './pm-plugins/utils/media-single';
30
- import { RenderImageEditor } from './ui/ImageEditor/ModalWrapper';
31
29
  import { MediaPickerComponents } from './ui/MediaPicker';
32
30
  import { RenderMediaViewer } from './ui/MediaViewer/PortalWrapper';
33
31
  import { floatingToolbar } from './ui/toolbar';
@@ -101,34 +99,6 @@ const MediaViewerFunctionalComponent = ({
101
99
  items: mediaItems
102
100
  });
103
101
  };
104
- const imageEditorStateSelector = states => {
105
- var _states$mediaState6, _states$mediaState7, _states$mediaState8;
106
- return {
107
- isImageEditorVisible: (_states$mediaState6 = states.mediaState) === null || _states$mediaState6 === void 0 ? void 0 : _states$mediaState6.isImageEditorVisible,
108
- imageEditorSelectedMedia: (_states$mediaState7 = states.mediaState) === null || _states$mediaState7 === void 0 ? void 0 : _states$mediaState7.imageEditorSelectedMedia,
109
- mediaClientConfig: (_states$mediaState8 = states.mediaState) === null || _states$mediaState8 === void 0 ? void 0 : _states$mediaState8.mediaClientConfig
110
- };
111
- };
112
- const ImageEditorFunctionalComponent = ({
113
- api
114
- }) => {
115
- const {
116
- isImageEditorVisible,
117
- imageEditorSelectedMedia,
118
- mediaClientConfig
119
- } = useSharedPluginStateWithSelector(api, ['media'], imageEditorStateSelector);
120
- if (!isImageEditorVisible || !imageEditorSelectedMedia || !mediaClientConfig) {
121
- return null;
122
- }
123
- const handleOnClose = () => {
124
- api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.media.commands.hideImageEditor);
125
- };
126
- return /*#__PURE__*/React.createElement(RenderImageEditor, {
127
- mediaClientConfig: mediaClientConfig,
128
- onClose: handleOnClose,
129
- selectedNodeAttrs: imageEditorSelectedMedia
130
- });
131
- };
132
102
  export const mediaPlugin = ({
133
103
  config: options = {},
134
104
  api
@@ -183,9 +153,7 @@ export const mediaPlugin = ({
183
153
  commands: {
184
154
  showMediaViewer,
185
155
  hideMediaViewer,
186
- trackMediaPaste,
187
- showImageEditor,
188
- hideImageEditor
156
+ trackMediaPaste
189
157
  },
190
158
  nodes() {
191
159
  const {
@@ -351,10 +319,7 @@ export const mediaPlugin = ({
351
319
  if (!editorView) {
352
320
  return null;
353
321
  }
354
- return /*#__PURE__*/React.createElement(React.Fragment, null, (options === null || options === void 0 ? void 0 : options.allowImageEditing) && expValEquals('platform_editor_add_image_editing', 'isEnabled', true) && /*#__PURE__*/React.createElement(ImageEditorFunctionalComponent, {
355
- api: api,
356
- editorView: editorView
357
- }), /*#__PURE__*/React.createElement(MediaViewerFunctionalComponent, {
322
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MediaViewerFunctionalComponent, {
358
323
  api: api,
359
324
  editorView: editorView
360
325
  }), /*#__PURE__*/React.createElement(MediaPickerFunctionalComponent, {
@@ -385,7 +350,7 @@ export const mediaPlugin = ({
385
350
  allowLinking: options && options.allowLinking,
386
351
  allowAdvancedToolBarOptions: options && options.allowAdvancedToolBarOptions,
387
352
  allowAltTextOnImages: options && options.allowAltTextOnImages,
388
- allowImageEditing: options && options.allowImageEditing,
353
+ allowImageEditing: !!(api !== null && api !== void 0 && api.mediaEditing) && options && options.allowImageEditing,
389
354
  allowImagePreview: options && options.allowImagePreview,
390
355
  altTextValidator: options && options.altTextValidator,
391
356
  fullWidthEnabled: options && options.fullWidthEnabled,
@@ -1,11 +1,14 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
+ import { bind } from 'bind-event-listener';
3
4
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
5
  import { DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH } from '@atlaskit/editor-common/media-single';
5
6
  import { WithProviders } from '@atlaskit/editor-common/provider-factory';
6
7
  import { SelectionBasedNodeView } from '@atlaskit/editor-common/selection-based-node-view';
7
8
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
9
+ import { akEditorFullWidthLayoutWidth, akEditorDefaultLayoutWidth, akEditorCalculatedWideLayoutWidth } from '@atlaskit/editor-shared-styles';
8
10
  import { getAttrsFromUrl } from '@atlaskit/media-client';
11
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
9
12
  import { updateCurrentMediaNodeAttrs } from '../../pm-plugins/commands/helpers';
10
13
  import { isMediaBlobUrlFromAttrs } from '../../pm-plugins/utils/media-common';
11
14
  // Ignored via go/ees005
@@ -37,6 +40,13 @@ class MediaNodeView extends SelectionBasedNodeView {
37
40
  constructor(...args) {
38
41
  super(...args);
39
42
  _defineProperty(this, "isSelected", false);
43
+ _defineProperty(this, "hasBeenResized", false);
44
+ _defineProperty(this, "hasResizedListener", () => {
45
+ if (!this.hasBeenResized) {
46
+ this.hasBeenResized = true;
47
+ this.update(this.node, this.decorations);
48
+ }
49
+ });
40
50
  _defineProperty(this, "onExternalImageLoaded", dimensions => {
41
51
  const getPos = this.getPos;
42
52
  const {
@@ -55,9 +65,37 @@ class MediaNodeView extends SelectionBasedNodeView {
55
65
  }, true)(this.view.state, this.view.dispatch);
56
66
  }
57
67
  });
68
+ _defineProperty(this, "getMaxCardDimensions", () => {
69
+ const flexibleDimensions = {
70
+ width: '100%',
71
+ height: '100%'
72
+ };
73
+ if (expValEquals('platform_editor_media_vc_fixes', 'isEnabled', true)) {
74
+ const pos = this.getPos();
75
+ if (typeof pos !== 'number') {
76
+ return flexibleDimensions;
77
+ }
78
+ if (this.hasBeenResized) {
79
+ return flexibleDimensions;
80
+ }
81
+ const mediaSingleNodeParent = this.getMediaSingleNode(this.getPos);
82
+
83
+ // If media parent not found, return default
84
+ if (!mediaSingleNodeParent) {
85
+ return flexibleDimensions;
86
+ }
87
+
88
+ // Compute normal dimensions
89
+ const maxWidth = this.getMaxWidthFromMediaSingleNode(mediaSingleNodeParent);
90
+ return {
91
+ width: `${maxWidth}px`,
92
+ height: '100%'
93
+ };
94
+ }
95
+ return flexibleDimensions;
96
+ });
58
97
  _defineProperty(this, "renderMediaNodeWithState", contextIdentifierProvider => {
59
98
  return ({
60
- width: editorWidth,
61
99
  mediaProvider,
62
100
  interactionState
63
101
  }) => {
@@ -85,20 +123,17 @@ class MediaNodeView extends SelectionBasedNodeView {
85
123
  }
86
124
  width = width || DEFAULT_IMAGE_WIDTH;
87
125
  height = height || DEFAULT_IMAGE_HEIGHT;
126
+ const {
127
+ pluginInjectionApi
128
+ } = this.reactComponentProps;
88
129
 
89
130
  // mediaSingle defines the max dimensions, so we don't need to constrain twice.
90
- const maxDimensions = {
91
- width: `100%`,
92
- height: `100%`
93
- };
131
+ const maxDimensions = this.getMaxCardDimensions();
94
132
  const originalDimensions = {
95
133
  width,
96
134
  height
97
135
  };
98
136
  const isSelectedAndInteracted = this.nodeInsideSelection() && interactionState !== 'hasNotHadInteraction';
99
- const {
100
- pluginInjectionApi
101
- } = this.reactComponentProps;
102
137
  return /*#__PURE__*/React.createElement(MediaNode, {
103
138
  api: pluginInjectionApi,
104
139
  view: this.view,
@@ -129,6 +164,39 @@ class MediaNodeView extends SelectionBasedNodeView {
129
164
  });
130
165
  });
131
166
  }
167
+ getMediaSingleNode(getPos) {
168
+ const pos = getPos();
169
+ if (typeof pos !== 'number') {
170
+ return null;
171
+ }
172
+ const $pos = this.view.state.doc.resolve(pos);
173
+
174
+ // The parent of the media node should be mediaSingle
175
+ if ($pos.parent && $pos.parent.type.name === 'mediaSingle') {
176
+ return $pos.parent;
177
+ }
178
+ return null;
179
+ }
180
+ getMaxWidthFromMediaSingleNode(mediaSingleNode) {
181
+ const {
182
+ width: widthAttr,
183
+ widthType: widthTypeAttr,
184
+ layout: layoutAttr
185
+ } = mediaSingleNode.attrs;
186
+ // for extended mediaSingle nodes with width and widthType attributes ( default behaviour )
187
+ if (widthAttr && widthTypeAttr === 'pixel') {
188
+ return widthAttr;
189
+ }
190
+ // for legacy mediaSingle nodes without widthType attribute
191
+ switch (layoutAttr) {
192
+ case 'full-width':
193
+ return akEditorFullWidthLayoutWidth;
194
+ case 'wide':
195
+ return akEditorCalculatedWideLayoutWidth;
196
+ default:
197
+ return akEditorDefaultLayoutWidth;
198
+ }
199
+ }
132
200
  createDomRef() {
133
201
  const domRef = document.createElement('div');
134
202
  if (this.reactComponentProps.mediaOptions && this.reactComponentProps.mediaOptions.allowMediaSingleEditable) {
@@ -136,6 +204,12 @@ class MediaNodeView extends SelectionBasedNodeView {
136
204
  // see also: https://github.com/ProseMirror/prosemirror/issues/884
137
205
  domRef.contentEditable = 'true';
138
206
  }
207
+ if (expValEquals('platform_editor_media_vc_fixes', 'isEnabled', true)) {
208
+ this.resizeListenerBinding = bind(domRef, {
209
+ type: 'resized',
210
+ listener: this.hasResizedListener
211
+ });
212
+ }
139
213
  return domRef;
140
214
  }
141
215
  viewShouldUpdate(nextNode, decorations) {
@@ -179,6 +253,12 @@ class MediaNodeView extends SelectionBasedNodeView {
179
253
  renderNode: this.renderMediaNodeWithProviders
180
254
  });
181
255
  }
256
+ destroy() {
257
+ if (this.resizeListenerBinding) {
258
+ this.resizeListenerBinding();
259
+ }
260
+ super.destroy();
261
+ }
182
262
  }
183
263
  export const ReactMediaNode = (portalProviderAPI, eventDispatcher, providerFactory, mediaOptions = {}, pluginInjectionApi) => (node, view, getPos) => {
184
264
  return new MediaNodeView(node, view, getPos, portalProviderAPI, eventDispatcher, {
@@ -13,6 +13,7 @@ import { WithProviders } from '@atlaskit/editor-common/provider-factory';
13
13
  import ReactNodeView from '@atlaskit/editor-common/react-node-view';
14
14
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
15
15
  import { isNodeSelectedOrInRange } from '@atlaskit/editor-common/utils';
16
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
16
17
  import { MEDIA_CONTENT_WRAP_CLASS_NAME } from '../pm-plugins/main';
17
18
  import { MediaSingleNodeNext } from './mediaSingleNext';
18
19
  const selector = states => {
@@ -84,6 +85,7 @@ class MediaSingleNodeView extends ReactNodeView {
84
85
  _defineProperty(this, "lastOffsetLeft", 0);
85
86
  _defineProperty(this, "forceViewUpdate", false);
86
87
  _defineProperty(this, "selectionType", null);
88
+ _defineProperty(this, "hasResized", false);
87
89
  _defineProperty(this, "checkAndUpdateSelectionType", () => {
88
90
  const getPos = this.getPos;
89
91
  const {
@@ -98,7 +100,7 @@ class MediaSingleNodeView extends ReactNodeView {
98
100
  let pos;
99
101
  try {
100
102
  pos = getPos ? getPos() : undefined;
101
- } catch (e) {
103
+ } catch {
102
104
  pos = undefined;
103
105
  }
104
106
  const isNodeSelected = isNodeSelectedOrInRange(selection.$anchor.pos, selection.$head.pos, pos, this.node.nodeSize);
@@ -188,6 +190,11 @@ class MediaSingleNodeView extends ReactNodeView {
188
190
  if (!isValidUpdate) {
189
191
  isValidUpdate = (currentNode, newNode) => this.getNodeMediaId(currentNode) === this.getNodeMediaId(newNode);
190
192
  }
193
+ // Detect mediaSingle width attribute changes and signal child media node to update
194
+ if (!this.hasResized && this.node.attrs.width !== node.attrs.width && expValEquals('platform_editor_media_vc_fixes', 'isEnabled', true)) {
195
+ const target = this.dom.querySelector('div[data-prosemirror-node-name="media"]');
196
+ target === null || target === void 0 ? void 0 : target.dispatchEvent(new CustomEvent('resized'));
197
+ }
191
198
  return super.update(node, decorations, _innerDecorations, isValidUpdate);
192
199
  }
193
200
  render(props, forwardRef) {
@@ -30,26 +30,4 @@ export const trackMediaPaste = attrs => ({
30
30
  identifier
31
31
  });
32
32
  return tr;
33
- };
34
- export const showImageEditor = media => ({
35
- tr
36
- }) => {
37
- tr.setMeta(stateKey, {
38
- type: ACTIONS.SHOW_IMAGE_EDITOR,
39
- imageEditorSelectedMedia: media,
40
- isImageEditorVisible: true
41
- });
42
- tr.setMeta('addToHistory', false);
43
- return tr;
44
- };
45
- export const hideImageEditor = ({
46
- tr
47
- }) => {
48
- tr.setMeta(stateKey, {
49
- type: ACTIONS.HIDE_IMAGE_EDITOR,
50
- imageEditorSelectedMedia: null,
51
- isImageEditorVisible: false
52
- });
53
- tr.setMeta('addToHistory', false);
54
- return tr;
55
33
  };
@@ -67,7 +67,6 @@ export class MediaPluginStateImplementation {
67
67
  _defineProperty(this, "allowInlineImages", false);
68
68
  _defineProperty(this, "uploadInProgressSubscriptions", []);
69
69
  _defineProperty(this, "uploadInProgressSubscriptionsNotified", false);
70
- _defineProperty(this, "isImageEditorVisible", false);
71
70
  // this is only a temporary variable, which gets cleared after the last inserted node has been selected
72
71
  _defineProperty(this, "lastAddedMediaSingleFileIds", []);
73
72
  _defineProperty(this, "destroyed", false);
@@ -569,9 +568,6 @@ export class MediaPluginStateImplementation {
569
568
  setResizingWidth(width) {
570
569
  this.resizingWidth = width;
571
570
  }
572
- setImageEditorVisibility(isVisible) {
573
- this.isImageEditorVisible = isVisible;
574
- }
575
571
  updateElement() {
576
572
  let newElement;
577
573
  const selectedContainer = this.selectedMediaContainerNode();
@@ -775,16 +771,6 @@ export const createPlugin = (_schema, options, getIntl, pluginInjectionApi, node
775
771
  nextPluginState = pluginState.clone();
776
772
  }
777
773
  break;
778
- case ACTIONS.SHOW_IMAGE_EDITOR:
779
- pluginState.imageEditorSelectedMedia = meta.imageEditorSelectedMedia;
780
- pluginState.isImageEditorVisible = meta.isImageEditorVisible;
781
- nextPluginState = nextPluginState.clone();
782
- break;
783
- case ACTIONS.HIDE_IMAGE_EDITOR:
784
- pluginState.imageEditorSelectedMedia = undefined;
785
- pluginState.isImageEditorVisible = meta.isImageEditorVisible;
786
- nextPluginState = nextPluginState.clone();
787
- break;
788
774
  }
789
775
 
790
776
  // NOTE: We're not calling passing new state to the Editor, because we depend on the view.state reference
@@ -179,6 +179,7 @@ export const ResizableMediaSingleNextFunctional = props => {
179
179
  const [snaps, setSnaps] = useState({});
180
180
  const [isResizing, setIsResizing] = useState(false);
181
181
  const [isVideoFile, setIsVideoFile] = useState(!(fg('platform_editor_media_video_check_fix') || fg('platform_editor_ssr_media')));
182
+ const [hasResized, setHasResized] = useState(false);
182
183
  const nodePosition = useMemo(() => {
183
184
  if (typeof getPos !== 'function') {
184
185
  return null;
@@ -348,6 +349,7 @@ export const ResizableMediaSingleNextFunctional = props => {
348
349
  width: props.width,
349
350
  height: props.height
350
351
  }));
352
+ const resizerContainerRef = useRef(null);
351
353
  const handleResize = useCallback((size, delta) => {
352
354
  const {
353
355
  width,
@@ -360,6 +362,14 @@ export const ResizableMediaSingleNextFunctional = props => {
360
362
  fullWidthMode,
361
363
  isNestedNode: isAdjacentMode
362
364
  })(size, delta, false, aspectRatioRef.current);
365
+ const resizerDomEl = resizerContainerRef.current;
366
+ if (resizerDomEl && !hasResized && expValEquals('platform_editor_media_vc_fixes', 'isEnabled', true)) {
367
+ // dispatch resize event to media node DOM element inside resizerDom
368
+ const mediaDomEl = resizerDomEl.querySelector('div[data-prosemirror-node-name="media"]');
369
+ const event = new CustomEvent('resized');
370
+ mediaDomEl === null || mediaDomEl === void 0 ? void 0 : mediaDomEl.dispatchEvent(event);
371
+ setHasResized(true);
372
+ }
363
373
  if (isGuidelineEnabled) {
364
374
  const guidelineSnaps = getGuidelineSnaps(guidelinesRef.current, lineLength, layout);
365
375
  updateActiveGuidelines(width, guidelinesRef.current, guidelineSnaps);
@@ -379,7 +389,7 @@ export const ResizableMediaSingleNextFunctional = props => {
379
389
  if (newLayout !== layout) {
380
390
  updateSize(width, newLayout);
381
391
  }
382
- }, [view, updateSize, layout, isGuidelineEnabled, containerWidth, lineLength, fullWidthMode, isAdjacentMode, updateActiveGuidelines]);
392
+ }, [layout, containerWidth, lineLength, fullWidthMode, isAdjacentMode, hasResized, isGuidelineEnabled, view, updateActiveGuidelines, updateSize]);
383
393
  const handleResizeStop = useCallback((size, delta) => {
384
394
  var _pluginInjectionApi$g5, _pluginInjectionApi$g6;
385
395
  if (typeof nodePosition !== 'number') {
@@ -472,7 +482,8 @@ export const ResizableMediaSingleNextFunctional = props => {
472
482
  }, [forceHandlePositioning, isAdjacentMode]);
473
483
  return jsx("div", {
474
484
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
475
- css: memoizedCss
485
+ css: memoizedCss,
486
+ ref: resizerContainerRef
476
487
  }, jsx(ResizerNext, {
477
488
  minWidth: minViewWidth,
478
489
  maxWidth: maxWidth
@@ -14,12 +14,14 @@ import { calculateSnapPoints } from '@atlaskit/editor-common/utils';
14
14
  import { findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
15
15
  import { akEditorWideLayoutWidth } from '@atlaskit/editor-shared-styles';
16
16
  import { fg } from '@atlaskit/platform-feature-flags';
17
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
17
18
  import { checkMediaType } from '../../pm-plugins/utils/check-media-type';
18
19
  import { wrapperStyle } from './styled';
19
20
  // eslint-disable-next-line @repo/internal/react/no-class-components
20
21
  export default class ResizableMediaSingle extends React.Component {
21
22
  constructor(...args) {
22
23
  super(...args);
24
+ _defineProperty(this, "hasResized", false);
23
25
  _defineProperty(this, "state", {
24
26
  offsetLeft: calculateOffsetLeft(this.insideInlineLike, this.insideLayout, this.props.view.dom, undefined),
25
27
  isVideoFile: !fg('platform_editor_media_video_check_fix')
@@ -43,6 +45,15 @@ export default class ResizableMediaSingle extends React.Component {
43
45
  state
44
46
  }
45
47
  } = this.props;
48
+ if (!this.hasResized && expValEquals('platform_editor_media_vc_fixes', 'isEnabled', true)) {
49
+ var _this$wrapper;
50
+ const mediaDomEl = (_this$wrapper = this.wrapper) === null || _this$wrapper === void 0 ? void 0 : _this$wrapper.querySelector('div[data-prosemirror-node-name="media"]');
51
+ if (mediaDomEl) {
52
+ const event = new CustomEvent('resized');
53
+ mediaDomEl === null || mediaDomEl === void 0 ? void 0 : mediaDomEl.dispatchEvent(event);
54
+ }
55
+ this.hasResized = true;
56
+ }
46
57
  const newPct = calcPctFromPx(newWidth, this.props.lineLength) * 100;
47
58
  this.setState({
48
59
  resizedPctWidth: newPct
@@ -114,11 +114,12 @@ export const handleShowImageEditor = ({
114
114
  api,
115
115
  mediaPluginState
116
116
  }) => {
117
+ var _api$mediaEditing;
117
118
  const selectedNodeAttrs = getSelectedNearestMediaContainerNodeAttrs(mediaPluginState);
118
119
  if (!selectedNodeAttrs) {
119
120
  return false;
120
121
  }
121
- api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : api.media.commands.showImageEditor(selectedNodeAttrs));
122
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$mediaEditing = api.mediaEditing) === null || _api$mediaEditing === void 0 ? void 0 : _api$mediaEditing.commands.showImageEditor(selectedNodeAttrs));
122
123
  };
123
124
  const generateMediaCardFloatingToolbar = (state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi, editorAnalyticsAPI, forceFocusSelector, isViewOnly) => {
124
125
  var _pluginInjectionApi$c, _pluginInjectionApi$c2, _pluginInjectionApi$c3;
@@ -562,7 +563,7 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
562
563
  });
563
564
  }
564
565
  // Image Editing Support
565
- if (allowImageEditing && expValEquals('platform_editor_add_image_editing', 'isEnabled', true)) {
566
+ if (!!(pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.mediaEditing) && allowImageEditing && expValEquals('platform_editor_add_image_editing', 'isEnabled', true)) {
566
567
  var _mediaNode$attrs;
567
568
  const selectedMediaSingleNode = getSelectedMediaSingle(state);
568
569
  const mediaNode = selectedMediaSingleNode === null || selectedMediaSingleNode === void 0 ? void 0 : selectedMediaSingleNode.node.content.firstChild;