@atlaskit/editor-plugin-media 1.35.0 → 1.36.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 (48) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/nodeviews/mediaNodeUpdater.js +7 -1
  3. package/dist/cjs/nodeviews/mediaSingle.js +27 -0
  4. package/dist/cjs/nodeviews/mediaSingleNext.js +583 -0
  5. package/dist/cjs/plugin.js +70 -43
  6. package/dist/cjs/pm-plugins/actions.js +10 -0
  7. package/dist/cjs/pm-plugins/commands.js +28 -0
  8. package/dist/cjs/pm-plugins/main.js +14 -0
  9. package/dist/cjs/toolbar/filePreviewItem.js +3 -2
  10. package/dist/cjs/toolbar/index.js +46 -12
  11. package/dist/cjs/toolbar/mediaInline.js +14 -1
  12. package/dist/es2019/nodeviews/mediaNodeUpdater.js +7 -0
  13. package/dist/es2019/nodeviews/mediaSingle.js +27 -0
  14. package/dist/es2019/nodeviews/mediaSingleNext.js +543 -0
  15. package/dist/es2019/plugin.js +31 -2
  16. package/dist/es2019/pm-plugins/actions.js +4 -0
  17. package/dist/es2019/pm-plugins/commands.js +22 -0
  18. package/dist/es2019/pm-plugins/main.js +14 -0
  19. package/dist/es2019/toolbar/filePreviewItem.js +3 -2
  20. package/dist/es2019/toolbar/index.js +40 -5
  21. package/dist/es2019/toolbar/mediaInline.js +15 -2
  22. package/dist/esm/nodeviews/mediaNodeUpdater.js +6 -0
  23. package/dist/esm/nodeviews/mediaSingle.js +27 -0
  24. package/dist/esm/nodeviews/mediaSingleNext.js +576 -0
  25. package/dist/esm/plugin.js +70 -43
  26. package/dist/esm/pm-plugins/actions.js +4 -0
  27. package/dist/esm/pm-plugins/commands.js +22 -0
  28. package/dist/esm/pm-plugins/main.js +14 -0
  29. package/dist/esm/toolbar/filePreviewItem.js +3 -2
  30. package/dist/esm/toolbar/index.js +46 -12
  31. package/dist/esm/toolbar/mediaInline.js +15 -2
  32. package/dist/types/next-plugin-type.d.ts +6 -1
  33. package/dist/types/nodeviews/mediaNodeUpdater.d.ts +1 -0
  34. package/dist/types/nodeviews/mediaSingle.d.ts +1 -1
  35. package/dist/types/nodeviews/mediaSingleNext.d.ts +35 -0
  36. package/dist/types/pm-plugins/actions.d.ts +4 -0
  37. package/dist/types/pm-plugins/commands.d.ts +4 -0
  38. package/dist/types/pm-plugins/types.d.ts +3 -1
  39. package/dist/types/toolbar/index.d.ts +4 -0
  40. package/dist/types-ts4.5/next-plugin-type.d.ts +6 -1
  41. package/dist/types-ts4.5/nodeviews/mediaNodeUpdater.d.ts +1 -0
  42. package/dist/types-ts4.5/nodeviews/mediaSingle.d.ts +1 -1
  43. package/dist/types-ts4.5/nodeviews/mediaSingleNext.d.ts +35 -0
  44. package/dist/types-ts4.5/pm-plugins/actions.d.ts +4 -0
  45. package/dist/types-ts4.5/pm-plugins/commands.d.ts +4 -0
  46. package/dist/types-ts4.5/pm-plugins/types.d.ts +3 -1
  47. package/dist/types-ts4.5/toolbar/index.d.ts +4 -0
  48. package/package.json +13 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 1.36.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#151938](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/151938)
8
+ [`91b5768ef0c7c`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/91b5768ef0c7c) -
9
+ [ux] ED-25203 refactor image previewer outside of floating toolbar
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 1.35.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [#151581](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/151581)
20
+ [`9932832b9aab3`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/9932832b9aab3) -
21
+ [ED-24127] Refactor MediaSingle legacy component
22
+ - Updated dependencies
23
+
3
24
  ## 1.35.0
4
25
 
5
26
  ### Minor Changes
@@ -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.MediaNodeUpdater = void 0;
7
+ exports.createMediaNodeUpdater = exports.MediaNodeUpdater = void 0;
8
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
@@ -777,4 +777,10 @@ var MediaNodeUpdater = exports.MediaNodeUpdater = /*#__PURE__*/function () {
777
777
  }();
778
778
  var hasPrivateAttrsChanged = function hasPrivateAttrsChanged(currentAttrs, newAttrs) {
779
779
  return currentAttrs.__fileName !== newAttrs.__fileName || currentAttrs.__fileMimeType !== newAttrs.__fileMimeType || currentAttrs.__fileSize !== newAttrs.__fileSize || currentAttrs.__contextId !== newAttrs.__contextId;
780
+ };
781
+ var createMediaNodeUpdater = exports.createMediaNodeUpdater = function createMediaNodeUpdater(props) {
782
+ var updaterProps = _objectSpread(_objectSpread({}, props), {}, {
783
+ isMediaSingle: true
784
+ });
785
+ return new MediaNodeUpdater(updaterProps);
780
786
  };
@@ -40,6 +40,7 @@ var _ResizableMediaSingleNext = _interopRequireDefault(require("../ui/ResizableM
40
40
  var _mediaCommon = require("../utils/media-common");
41
41
  var _helpers = require("./helpers");
42
42
  var _mediaNodeUpdater = require("./mediaNodeUpdater");
43
+ var _mediaSingleNext = require("./mediaSingleNext");
43
44
  var _styles = require("./styles");
44
45
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
45
46
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -54,6 +55,9 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
54
55
  var figureWrapperStyles = (0, _react2.css)({
55
56
  margin: 0
56
57
  });
58
+ /*
59
+ * @deprecated Please use the MediaSingleNodeNext
60
+ */
57
61
  // eslint-disable-next-line @repo/internal/react/no-class-components
58
62
  var MediaSingleNode = exports.default = /*#__PURE__*/function (_Component) {
59
63
  (0, _inherits2.default)(MediaSingleNode, _Component);
@@ -559,6 +563,29 @@ var MediaSingleNodeWrapper = function MediaSingleNodeWrapper(_ref7) {
559
563
  var mediaProvider = (0, _react.useMemo)(function () {
560
564
  return mediaState !== null && mediaState !== void 0 && mediaState.mediaProvider ? Promise.resolve(mediaState === null || mediaState === void 0 ? void 0 : mediaState.mediaProvider) : undefined;
561
565
  }, [mediaState === null || mediaState === void 0 ? void 0 : mediaState.mediaProvider]);
566
+ if ((0, _platformFeatureFlags.fg)('platform_editor_react18_phase2__media_single')) {
567
+ return (0, _react2.jsx)(_mediaSingleNext.MediaSingleNodeNext, {
568
+ width: (widthState === null || widthState === void 0 ? void 0 : widthState.width) || 0,
569
+ lineLength: (widthState === null || widthState === void 0 ? void 0 : widthState.lineLength) || 0,
570
+ node: node,
571
+ getPos: getPos,
572
+ mediaProvider: mediaProvider,
573
+ contextIdentifierProvider: contextIdentifierProvider,
574
+ mediaOptions: mediaOptions,
575
+ view: view,
576
+ fullWidthMode: fullWidthMode,
577
+ selected: selected,
578
+ eventDispatcher: eventDispatcher,
579
+ mediaPluginState: mediaState !== null && mediaState !== void 0 ? mediaState : undefined,
580
+ annotationPluginState: annotationState !== null && annotationState !== void 0 ? annotationState : undefined,
581
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
582
+ forwardRef: forwardRef,
583
+ pluginInjectionApi: pluginInjectionApi,
584
+ editorDisabled: editorDisabledState === null || editorDisabledState === void 0 ? void 0 : editorDisabledState.editorDisabled,
585
+ editorViewMode: (editorViewModeState === null || editorViewModeState === void 0 ? void 0 : editorViewModeState.mode) === 'view',
586
+ editorAppearance: editorAppearance
587
+ });
588
+ }
562
589
  return (0, _react2.jsx)(MediaSingleNode, {
563
590
  width: widthState.width,
564
591
  lineLength: widthState.lineLength,
@@ -0,0 +1,583 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.MediaSingleNodeNext = void 0;
9
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
12
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
+ var _react = _interopRequireWildcard(require("react"));
14
+ var _react2 = require("@emotion/react");
15
+ var _hooks = require("@atlaskit/editor-common/hooks");
16
+ var _mediaSingle = require("@atlaskit/editor-common/media-single");
17
+ var _ui = require("@atlaskit/editor-common/ui");
18
+ var _utils = require("@atlaskit/editor-common/utils");
19
+ var _state = require("@atlaskit/editor-prosemirror/state");
20
+ var _utils2 = require("@atlaskit/editor-prosemirror/utils");
21
+ var _mediaClient = require("@atlaskit/media-client");
22
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
23
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
24
+ var _captions = require("../commands/captions");
25
+ var _CaptionPlaceholder = require("../ui/CaptionPlaceholder");
26
+ var _CommentBadge = require("../ui/CommentBadge");
27
+ var _ResizableMediaSingle = _interopRequireDefault(require("../ui/ResizableMediaSingle"));
28
+ var _ResizableMediaSingleNext = _interopRequireDefault(require("../ui/ResizableMediaSingle/ResizableMediaSingleNext"));
29
+ var _mediaCommon = require("../utils/media-common");
30
+ var _helpers = require("./helpers");
31
+ var _mediaNodeUpdater = require("./mediaNodeUpdater");
32
+ var _styles = require("./styles");
33
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
34
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
35
+ 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; }
36
+ 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; } /**
37
+ * @jsxRuntime classic
38
+ * @jsx jsx
39
+ * @jsxFrag
40
+ */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
41
+ var figureWrapperStyles = (0, _react2.css)({
42
+ margin: 0
43
+ });
44
+ var useMediaNodeUpdater = function useMediaNodeUpdater(_ref) {
45
+ var mediaProvider = _ref.mediaProvider,
46
+ mediaNode = _ref.mediaNode,
47
+ dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
48
+ mediaSingleNodeProps = _ref.mediaSingleNodeProps;
49
+ var previousMediaProvider = (0, _hooks.usePreviousState)(mediaProvider);
50
+ var previousMediaNode = (0, _hooks.usePreviousState)(mediaNode);
51
+ var mediaNodeUpdaterRef = _react.default.useRef(null);
52
+ var createOrUpdateMediaNodeUpdater = _react.default.useCallback(function (props) {
53
+ var mediaChildNode = mediaNode.firstChild;
54
+ var updaterProps = _objectSpread(_objectSpread({}, props), {}, {
55
+ isMediaSingle: true,
56
+ node: mediaChildNode ? mediaChildNode : mediaNode,
57
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent
58
+ });
59
+ if (!mediaNodeUpdaterRef.current) {
60
+ mediaNodeUpdaterRef.current = (0, _mediaNodeUpdater.createMediaNodeUpdater)(updaterProps);
61
+ } else {
62
+ mediaNodeUpdaterRef.current.setProps(updaterProps);
63
+ }
64
+ }, [mediaNode, dispatchAnalyticsEvent]);
65
+ _react.default.useEffect(function () {
66
+ // Forced updates not required on mobile
67
+ if (mediaSingleNodeProps.isCopyPasteEnabled === false) {
68
+ return;
69
+ }
70
+ if (!mediaNodeUpdaterRef.current || previousMediaProvider !== mediaProvider) {
71
+ var _mediaNodeUpdaterRef$;
72
+ createOrUpdateMediaNodeUpdater(mediaSingleNodeProps);
73
+ (_mediaNodeUpdaterRef$ = mediaNodeUpdaterRef.current) === null || _mediaNodeUpdaterRef$ === void 0 || _mediaNodeUpdaterRef$.updateMediaSingleFileAttrs();
74
+ } else if (mediaNode.firstChild && previousMediaNode !== null && previousMediaNode !== void 0 && previousMediaNode.firstChild && mediaNode.firstChild !== (previousMediaNode === null || previousMediaNode === void 0 ? void 0 : previousMediaNode.firstChild)) {
75
+ var attrsChanged = (0, _helpers.hasPrivateAttrsChanged)(previousMediaNode.firstChild.attrs, mediaNode.firstChild.attrs);
76
+ if (attrsChanged) {
77
+ var _mediaNodeUpdaterRef$2;
78
+ createOrUpdateMediaNodeUpdater(mediaSingleNodeProps);
79
+ // We need to call this method on any prop change since attrs can get removed with collab editing
80
+ (_mediaNodeUpdaterRef$2 = mediaNodeUpdaterRef.current) === null || _mediaNodeUpdaterRef$2 === void 0 || _mediaNodeUpdaterRef$2.updateMediaSingleFileAttrs();
81
+ }
82
+ }
83
+ }, [createOrUpdateMediaNodeUpdater, mediaNode, mediaProvider, mediaSingleNodeProps, previousMediaNode, previousMediaProvider]);
84
+ return mediaNodeUpdaterRef.current;
85
+ };
86
+ var mediaAsyncOperations = /*#__PURE__*/function () {
87
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(props) {
88
+ var updatedDimensions, currentAttrs, updatingNode, contextId, hasDifferentContextId, copyNode;
89
+ return _regenerator.default.wrap(function _callee$(_context) {
90
+ while (1) switch (_context.prev = _context.next) {
91
+ case 0:
92
+ _context.next = 2;
93
+ return props.updater.getRemoteDimensions();
94
+ case 2:
95
+ updatedDimensions = _context.sent;
96
+ currentAttrs = props.mediaChildNode.attrs;
97
+ if (updatedDimensions && ((currentAttrs === null || currentAttrs === void 0 ? void 0 : currentAttrs.width) !== updatedDimensions.width || (currentAttrs === null || currentAttrs === void 0 ? void 0 : currentAttrs.height) !== updatedDimensions.height)) {
98
+ props.updater.updateDimensions(updatedDimensions);
99
+ }
100
+ if (!(props.mediaChildNode.attrs.type === 'external' && props.mediaChildNode.attrs.__external)) {
101
+ _context.next = 11;
102
+ break;
103
+ }
104
+ updatingNode = props.updater.handleExternalMedia(props.getPos);
105
+ props.addPendingTask(updatingNode);
106
+ _context.next = 10;
107
+ return updatingNode;
108
+ case 10:
109
+ return _context.abrupt("return");
110
+ case 11:
111
+ contextId = props.updater.getNodeContextId();
112
+ if (contextId) {
113
+ _context.next = 15;
114
+ break;
115
+ }
116
+ _context.next = 15;
117
+ return props.updater.updateContextId();
118
+ case 15:
119
+ _context.next = 17;
120
+ return props.updater.hasDifferentContextId();
121
+ case 17:
122
+ hasDifferentContextId = _context.sent;
123
+ if (!hasDifferentContextId) {
124
+ _context.next = 28;
125
+ break;
126
+ }
127
+ _context.prev = 19;
128
+ copyNode = props.updater.copyNode({
129
+ traceId: props.mediaNode.attrs.__mediaTraceId
130
+ });
131
+ props.addPendingTask(copyNode);
132
+ _context.next = 24;
133
+ return copyNode;
134
+ case 24:
135
+ _context.next = 28;
136
+ break;
137
+ case 26:
138
+ _context.prev = 26;
139
+ _context.t0 = _context["catch"](19);
140
+ case 28:
141
+ case "end":
142
+ return _context.stop();
143
+ }
144
+ }, _callee, null, [[19, 26]]);
145
+ }));
146
+ return function mediaAsyncOperations(_x) {
147
+ return _ref2.apply(this, arguments);
148
+ };
149
+ }();
150
+ var useMediaAsyncOperations = function useMediaAsyncOperations(_ref3) {
151
+ var mediaNode = _ref3.mediaNode,
152
+ mediaNodeUpdater = _ref3.mediaNodeUpdater,
153
+ addPendingTask = _ref3.addPendingTask,
154
+ getPos = _ref3.getPos;
155
+ _react.default.useEffect(function () {
156
+ if (!mediaNodeUpdater) {
157
+ return;
158
+ }
159
+ // we want the first child of MediaSingle (type "media")
160
+ var childNode = mediaNode.firstChild;
161
+ if (!childNode) {
162
+ return;
163
+ }
164
+ mediaAsyncOperations({
165
+ mediaChildNode: childNode,
166
+ updater: mediaNodeUpdater,
167
+ getPos: getPos,
168
+ mediaNode: mediaNode,
169
+ addPendingTask: addPendingTask
170
+ });
171
+ }, [mediaNode, addPendingTask, mediaNodeUpdater, getPos]);
172
+ };
173
+ var noop = function noop() {};
174
+
175
+ /**
176
+ * Keep returning the same ProseMirror Node, unless the node content changed.
177
+ *
178
+ * React uses shallow comparation with `Object.is`,
179
+ * but that can cause multiple re-renders when the same node is given in a different instance.
180
+ *
181
+ * To avoid unnecessary re-renders, this hook uses the `Node.eq` from ProseMirror API to compare
182
+ * previous and new values.
183
+ */
184
+ var useLatestMediaNode = function useLatestMediaNode(nextMediaNode) {
185
+ var previousMediaNode = (0, _hooks.usePreviousState)(nextMediaNode);
186
+ var _React$useState = _react.default.useState(nextMediaNode),
187
+ _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
188
+ mediaNode = _React$useState2[0],
189
+ setMediaNode = _React$useState2[1];
190
+ _react.default.useEffect(function () {
191
+ if (!previousMediaNode) {
192
+ return;
193
+ }
194
+ if (!previousMediaNode.eq(nextMediaNode)) {
195
+ setMediaNode(nextMediaNode);
196
+ }
197
+ }, [previousMediaNode, nextMediaNode]);
198
+ return mediaNode;
199
+ };
200
+ var useMediaDimensionsLogic = function useMediaDimensionsLogic(_ref4) {
201
+ var childMediaNodeAttrs = _ref4.childMediaNodeAttrs;
202
+ var originalWidth = childMediaNodeAttrs.width,
203
+ originalHeight = childMediaNodeAttrs.height;
204
+ var isExternalMedia = childMediaNodeAttrs.type === 'external';
205
+ var hasMediaUrlBlob = isExternalMedia && typeof childMediaNodeAttrs.url === 'string' && (0, _mediaCommon.isMediaBlobUrlFromAttrs)(childMediaNodeAttrs);
206
+ var urlBlobAttrs = _react.default.useMemo(function () {
207
+ if (!hasMediaUrlBlob) {
208
+ return null;
209
+ }
210
+ return (0, _mediaClient.getAttrsFromUrl)(childMediaNodeAttrs.url);
211
+ }, [hasMediaUrlBlob, childMediaNodeAttrs]);
212
+ var _React$useMemo = _react.default.useMemo(function () {
213
+ // original width and height of child media node (scaled)
214
+ var width = originalWidth;
215
+ var height = originalHeight;
216
+ if (isExternalMedia) {
217
+ if (urlBlobAttrs) {
218
+ if (urlBlobAttrs) {
219
+ var urlWidth = urlBlobAttrs.width,
220
+ urlHeight = urlBlobAttrs.height;
221
+ width = width || urlWidth;
222
+ height = height || urlHeight;
223
+ }
224
+ }
225
+ if (width === null) {
226
+ width = _mediaSingle.DEFAULT_IMAGE_WIDTH;
227
+ }
228
+ if (height === null) {
229
+ height = _mediaSingle.DEFAULT_IMAGE_HEIGHT;
230
+ }
231
+ }
232
+ if (!width || !height) {
233
+ width = _mediaSingle.DEFAULT_IMAGE_WIDTH;
234
+ height = _mediaSingle.DEFAULT_IMAGE_HEIGHT;
235
+ }
236
+ return {
237
+ width: width,
238
+ height: height
239
+ };
240
+ }, [originalWidth, originalHeight, isExternalMedia, urlBlobAttrs]),
241
+ width = _React$useMemo.width,
242
+ height = _React$useMemo.height;
243
+ return {
244
+ width: width,
245
+ height: height
246
+ };
247
+ };
248
+ var useUpdateSizeCallback = function useUpdateSizeCallback(_ref5) {
249
+ var mediaNode = _ref5.mediaNode,
250
+ view = _ref5.view,
251
+ getPos = _ref5.getPos;
252
+ var updateSize = _react.default.useCallback(function (width, layout) {
253
+ var state = view.state,
254
+ dispatch = view.dispatch;
255
+ var pos = getPos();
256
+ if (typeof pos === 'undefined') {
257
+ return;
258
+ }
259
+ var tr = state.tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, mediaNode.attrs), {}, {
260
+ layout: layout,
261
+ width: width,
262
+ widthType: 'pixel'
263
+ }));
264
+ tr.setMeta('scrollIntoView', false);
265
+ /**
266
+ * Any changes to attributes of a node count the node as "recreated" in Prosemirror[1]
267
+ * This makes it so Prosemirror resets the selection to the child i.e. "media" instead of "media-single"
268
+ * The recommended fix is to reset the selection.[2]
269
+ *
270
+ * [1] https://discuss.prosemirror.net/t/setnodemarkup-loses-current-nodeselection/976
271
+ * [2] https://discuss.prosemirror.net/t/setnodemarkup-and-deselect/3673
272
+ */
273
+ tr.setSelection(_state.NodeSelection.create(tr.doc, pos));
274
+ return dispatch(tr);
275
+ }, [view, getPos, mediaNode]);
276
+ return updateSize;
277
+ };
278
+
279
+ /**
280
+ * This value is used to fallback when widthState is undefined.
281
+ *
282
+ * Previously, the old MediaSingle was ignoring the undefined situation:
283
+ *
284
+ * <MediaSingleNode
285
+ * width={widthState!.width}
286
+ * lineLength={widthState!.lineLength}
287
+ */
288
+ var FALLBACK_MOST_COMMON_WIDTH = 760;
289
+ var MediaSingleNodeNext = exports.MediaSingleNodeNext = function MediaSingleNodeNext(mediaSingleNodeNextProps) {
290
+ var _mediaOptions$getEdit, _pluginInjectionApi$m, _mediaNode$firstChild2;
291
+ var selected = mediaSingleNodeNextProps.selected,
292
+ getPos = mediaSingleNodeNextProps.getPos,
293
+ nextMediaNode = mediaSingleNodeNextProps.node,
294
+ mediaOptions = mediaSingleNodeNextProps.mediaOptions,
295
+ fullWidthMode = mediaSingleNodeNextProps.fullWidthMode,
296
+ view = mediaSingleNodeNextProps.view,
297
+ pluginInjectionApi = mediaSingleNodeNextProps.pluginInjectionApi,
298
+ containerWidth = mediaSingleNodeNextProps.width,
299
+ lineLength = mediaSingleNodeNextProps.lineLength,
300
+ dispatchAnalyticsEvent = mediaSingleNodeNextProps.dispatchAnalyticsEvent,
301
+ editorViewMode = mediaSingleNodeNextProps.editorViewMode,
302
+ editorDisabled = mediaSingleNodeNextProps.editorDisabled,
303
+ annotationPluginState = mediaSingleNodeNextProps.annotationPluginState,
304
+ editorAppearance = mediaSingleNodeNextProps.editorAppearance,
305
+ mediaProviderPromise = mediaSingleNodeNextProps.mediaProvider,
306
+ forwardRef = mediaSingleNodeNextProps.forwardRef,
307
+ contextIdentifierProviderPromise = mediaSingleNodeNextProps.contextIdentifierProvider,
308
+ mediaPluginState = mediaSingleNodeNextProps.mediaPluginState;
309
+ var _ref6 = (mediaOptions === null || mediaOptions === void 0 || (_mediaOptions$getEdit = mediaOptions.getEditorFeatureFlags) === null || _mediaOptions$getEdit === void 0 ? void 0 : _mediaOptions$getEdit.call(mediaOptions)) || {},
310
+ _ref6$commentsOnMedia = _ref6.commentsOnMedia,
311
+ commentsOnMedia = _ref6$commentsOnMedia === void 0 ? false : _ref6$commentsOnMedia;
312
+ var _React$useState3 = _react.default.useState(null),
313
+ _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
314
+ mediaProvider = _React$useState4[0],
315
+ setMediaProvider = _React$useState4[1];
316
+ var _React$useState5 = _react.default.useState(null),
317
+ _React$useState6 = (0, _slicedToArray2.default)(_React$useState5, 2),
318
+ _contextIdentifierProvider = _React$useState6[0],
319
+ setContextIdentifierProvider = _React$useState6[1];
320
+ var _React$useState7 = _react.default.useState(),
321
+ _React$useState8 = (0, _slicedToArray2.default)(_React$useState7, 2),
322
+ viewMediaClientConfig = _React$useState8[0],
323
+ setViewMediaClientConfig = _React$useState8[1];
324
+ var mountedRef = _react.default.useRef(true);
325
+ var pos = getPos();
326
+ var isSelected = selected();
327
+ var contentWidthForLegacyExperience = (0, _mediaSingle.getMaxWidthForNestedNode)(view, getPos()) || lineLength;
328
+ var mediaNode = useLatestMediaNode(nextMediaNode);
329
+ var mediaNodeUpdater = useMediaNodeUpdater({
330
+ mediaNode: mediaNode,
331
+ mediaSingleNodeProps: mediaSingleNodeNextProps,
332
+ mediaProvider: mediaProvider,
333
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent
334
+ });
335
+ useMediaAsyncOperations({
336
+ mediaNodeUpdater: mediaNodeUpdater,
337
+ getPos: getPos,
338
+ mediaNode: mediaNode,
339
+ addPendingTask: (mediaPluginState === null || mediaPluginState === void 0 ? void 0 : mediaPluginState.addPendingTask) || noop
340
+ });
341
+ _react.default.useLayoutEffect(function () {
342
+ mountedRef.current = true;
343
+ return function () {
344
+ mountedRef.current = false;
345
+ };
346
+ }, []);
347
+ _react.default.useLayoutEffect(function () {
348
+ if (!mediaProviderPromise) {
349
+ return;
350
+ }
351
+ mediaProviderPromise.then(function (resolvedProvider) {
352
+ var viewMediaClientConfig = resolvedProvider.viewMediaClientConfig;
353
+ if (mountedRef.current) {
354
+ setViewMediaClientConfig(viewMediaClientConfig);
355
+ setMediaProvider(resolvedProvider);
356
+ }
357
+ });
358
+ }, [mediaProviderPromise]);
359
+ _react.default.useEffect(function () {
360
+ if (!contextIdentifierProviderPromise) {
361
+ return;
362
+ }
363
+ contextIdentifierProviderPromise.then(function (provider) {
364
+ if (mountedRef.current) {
365
+ setContextIdentifierProvider(provider);
366
+ }
367
+ });
368
+ }, [contextIdentifierProviderPromise]);
369
+ _react.default.useEffect(function () {
370
+ var _mediaNode$firstChild;
371
+ // No-op but logging an exposure when an external image is rendered
372
+ // Remove this block when cleaning up platform_editor_add_media_from_url
373
+ if (((_mediaNode$firstChild = mediaNode.firstChild) === null || _mediaNode$firstChild === void 0 ? void 0 : _mediaNode$firstChild.attrs.type) === 'external') {
374
+ if ((0, _experiments.editorExperiment)('add-media-from-url', true)) {
375
+ (0, _experiments.editorExperiment)('add-media-from-url', true, {
376
+ exposure: true
377
+ });
378
+ } else {
379
+ (0, _experiments.editorExperiment)('add-media-from-url', false, {
380
+ exposure: true
381
+ });
382
+ }
383
+ }
384
+ }, [mediaNode]);
385
+ var _ref7 = mediaNode.attrs,
386
+ layout = _ref7.layout,
387
+ widthType = _ref7.widthType,
388
+ mediaSingleWidthAttribute = _ref7.width;
389
+ var childNode = mediaNode.firstChild;
390
+ var childMediaNodeAttrs = _react.default.useMemo(function () {
391
+ return (childNode === null || childNode === void 0 ? void 0 : childNode.attrs) || {};
392
+ }, [childNode]);
393
+ var _useMediaDimensionsLo = useMediaDimensionsLogic({
394
+ childMediaNodeAttrs: childMediaNodeAttrs
395
+ }),
396
+ width = _useMediaDimensionsLo.width,
397
+ height = _useMediaDimensionsLo.height;
398
+ var updateSize = useUpdateSizeCallback({
399
+ view: view,
400
+ getPos: getPos,
401
+ mediaNode: mediaNode
402
+ });
403
+ var canResize = _react.default.useMemo(function () {
404
+ if (typeof pos !== 'number') {
405
+ return false;
406
+ }
407
+ var result = Boolean(!!mediaOptions.allowResizing && !editorDisabled && !editorViewMode);
408
+ if (mediaOptions.allowResizingInTables) {
409
+ return result;
410
+ }
411
+
412
+ // If resizing not allowed in tables, check parents for tables
413
+ var $pos = view.state.doc.resolve(pos);
414
+ var table = view.state.schema.nodes.table;
415
+ var disabledNode = !!(0, _utils2.findParentNodeOfTypeClosestToPos)($pos, [table]);
416
+ return Boolean(result && !disabledNode);
417
+ }, [mediaOptions, pos, view, editorDisabled, editorViewMode]);
418
+ var badgeOffsetRight = _react.default.useMemo(function () {
419
+ if (typeof pos !== 'number') {
420
+ return undefined;
421
+ }
422
+ var $pos = view.state.doc.resolve(pos);
423
+ var table = view.state.schema.nodes.table;
424
+ var foundTableNode = (0, _utils2.findParentNodeOfTypeClosestToPos)($pos, [table]);
425
+ return foundTableNode ? '2px' : '14px';
426
+ }, [pos, view]);
427
+ var shouldShowPlaceholder = _react.default.useMemo(function () {
428
+ var result = mediaOptions.allowCaptions && mediaNode.childCount !== 2 && isSelected && view.state.selection instanceof _state.NodeSelection;
429
+ return !editorDisabled && result;
430
+ }, [editorDisabled, mediaOptions.allowCaptions, mediaNode, view, isSelected]);
431
+ var isInsideTable = _react.default.useMemo(function () {
432
+ if (typeof pos !== 'number') {
433
+ return false;
434
+ }
435
+ return (0, _utils2.findParentNodeOfTypeClosestToPos)(view.state.doc.resolve(pos), [view.state.schema.nodes.table]);
436
+ }, [pos, view]);
437
+ var currentMediaElement = _react.default.useCallback(function () {
438
+ if (typeof pos !== 'number') {
439
+ return null;
440
+ }
441
+ var mediaNode = view.domAtPos(pos + 1).node;
442
+ return mediaNode instanceof HTMLElement ? mediaNode : null;
443
+ }, [view, pos]);
444
+ var mediaSingleWidth = _react.default.useMemo(function () {
445
+ return (0, _mediaSingle.calcMediaSinglePixelWidth)({
446
+ width: mediaSingleWidthAttribute,
447
+ widthType: widthType,
448
+ origWidth: width,
449
+ layout: layout,
450
+ // This will only be used when calculating legacy media single width
451
+ // thus we use the legacy value (exclude table as container node)
452
+ contentWidth: contentWidthForLegacyExperience,
453
+ containerWidth: containerWidth,
454
+ gutterOffset: _mediaSingle.MEDIA_SINGLE_GUTTER_SIZE
455
+ });
456
+ }, [mediaSingleWidthAttribute, widthType, width, layout, contentWidthForLegacyExperience, containerWidth]);
457
+ var currentMaxWidth = isSelected ? pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$m = pluginInjectionApi.media) === null || _pluginInjectionApi$m === void 0 || (_pluginInjectionApi$m = _pluginInjectionApi$m.sharedState.currentState()) === null || _pluginInjectionApi$m === void 0 ? void 0 : _pluginInjectionApi$m.currentMaxWidth : undefined;
458
+ var contentWidth = currentMaxWidth || lineLength;
459
+ var isCurrentNodeDrafting = Boolean((annotationPluginState === null || annotationPluginState === void 0 ? void 0 : annotationPluginState.isDrafting) && (annotationPluginState === null || annotationPluginState === void 0 ? void 0 : annotationPluginState.targetNodeId) === (mediaNode === null || mediaNode === void 0 || (_mediaNode$firstChild2 = mediaNode.firstChild) === null || _mediaNode$firstChild2 === void 0 ? void 0 : _mediaNode$firstChild2.attrs.id));
460
+ var shouldShowExternalMediaBadge = childMediaNodeAttrs.type === 'external';
461
+ var mediaSingleWrapperRef = /*#__PURE__*/_react.default.createRef();
462
+ var captionPlaceHolderRef = /*#__PURE__*/_react.default.createRef();
463
+ var onMediaSingleClicked = _react.default.useCallback(function (event) {
464
+ var _captionPlaceHolderRe;
465
+ // Workaround for iOS 16 Caption selection issue
466
+ // @see https://product-fabric.atlassian.net/browse/MEX-2012
467
+ if (!_utils.browser.ios) {
468
+ return;
469
+ }
470
+ if (mediaSingleWrapperRef.current !== event.target) {
471
+ return;
472
+ }
473
+ (_captionPlaceHolderRe = captionPlaceHolderRef.current) === null || _captionPlaceHolderRe === void 0 || _captionPlaceHolderRe.click();
474
+ }, [mediaSingleWrapperRef, captionPlaceHolderRef]);
475
+ var clickPlaceholder = _react.default.useCallback(function () {
476
+ var _pluginInjectionApi$a;
477
+ if (typeof getPos === 'boolean') {
478
+ return;
479
+ }
480
+ (0, _captions.insertAndSelectCaptionFromMediaSinglePos)(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions)(getPos(), mediaNode)(view.state, view.dispatch);
481
+ }, [view, getPos, mediaNode, pluginInjectionApi]);
482
+ var legacySize = _react.default.useMemo(function () {
483
+ return {
484
+ width: mediaSingleWidthAttribute,
485
+ widthType: widthType
486
+ };
487
+ }, [widthType, mediaSingleWidthAttribute]);
488
+ var MediaChildren = (0, _react2.jsx)("figure", {
489
+ ref: mediaSingleWrapperRef,
490
+ css: figureWrapperStyles
491
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
492
+ ,
493
+ className: _styles.MediaSingleNodeSelector,
494
+ onClick: onMediaSingleClicked
495
+ }, (0, _experiments.editorExperiment)('add-media-from-url', true) && (0, _react2.jsx)(_mediaSingle.MediaBadges, {
496
+ mediaElement: currentMediaElement(),
497
+ mediaHeight: height,
498
+ mediaWidth: width,
499
+ extendedResizeOffset: (0, _platformFeatureFlags.fg)('platform.editor.media.extended-resize-experience') && !isInsideTable
500
+ }, function (_ref8) {
501
+ var badgeSize = _ref8.badgeSize;
502
+ return (0, _react2.jsx)(_react.default.Fragment, null, shouldShowExternalMediaBadge && (0, _react2.jsx)(_mediaSingle.ExternalImageBadge, {
503
+ badgeSize: badgeSize
504
+ }), commentsOnMedia && (0, _react2.jsx)(_CommentBadge.CommentBadgeNextWrapper, {
505
+ view: view,
506
+ api: pluginInjectionApi,
507
+ mediaNode: mediaNode === null || mediaNode === void 0 ? void 0 : mediaNode.firstChild,
508
+ getPos: getPos,
509
+ isDrafting: isCurrentNodeDrafting,
510
+ badgeSize: badgeSize
511
+ }));
512
+ }), !(0, _experiments.editorExperiment)('add-media-from-url', true) && commentsOnMedia && (0, _react2.jsx)(_CommentBadge.CommentBadge, {
513
+ view: view,
514
+ api: pluginInjectionApi,
515
+ mediaNode: mediaNode === null || mediaNode === void 0 ? void 0 : mediaNode.firstChild,
516
+ badgeOffsetRight: badgeOffsetRight,
517
+ getPos: getPos,
518
+ isDrafting: isCurrentNodeDrafting
519
+ }), (0, _react2.jsx)("div", {
520
+ ref: forwardRef
521
+ }), shouldShowPlaceholder && ((0, _experiments.editorExperiment)('typography_migration_ugc', true) ? (0, _react2.jsx)(_CaptionPlaceholder.CaptionPlaceholderButton
522
+ // platform_editor_typography_migration_ugc clean up
523
+ // remove typecasting
524
+ , {
525
+ ref: captionPlaceHolderRef,
526
+ onClick: clickPlaceholder
527
+ }) : (0, _react2.jsx)(_CaptionPlaceholder.CaptionPlaceholder, {
528
+ ref: captionPlaceHolderRef,
529
+ onClick: clickPlaceholder
530
+ })));
531
+ return (0, _react2.jsx)(_react.Fragment, null, canResize ? (0, _platformFeatureFlags.fg)('platform.editor.media.extended-resize-experience') ? (0, _react2.jsx)(_ResizableMediaSingleNext.default, {
532
+ view: view,
533
+ getPos: getPos,
534
+ updateSize: updateSize,
535
+ gridSize: 12,
536
+ viewMediaClientConfig: viewMediaClientConfig,
537
+ allowBreakoutSnapPoints: mediaOptions && mediaOptions.allowBreakoutSnapPoints,
538
+ selected: isSelected,
539
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
540
+ pluginInjectionApi: pluginInjectionApi,
541
+ layout: layout,
542
+ width: width,
543
+ height: height,
544
+ containerWidth: containerWidth,
545
+ lineLength: contentWidth || FALLBACK_MOST_COMMON_WIDTH,
546
+ fullWidthMode: fullWidthMode,
547
+ hasFallbackContainer: false,
548
+ mediaSingleWidth: mediaSingleWidth,
549
+ editorAppearance: editorAppearance,
550
+ showLegacyNotification: widthType !== 'pixel'
551
+ }, MediaChildren) : (0, _react2.jsx)(_ResizableMediaSingle.default, {
552
+ view: view,
553
+ getPos: getPos,
554
+ updateSize: updateSize,
555
+ gridSize: 12,
556
+ viewMediaClientConfig: viewMediaClientConfig,
557
+ allowBreakoutSnapPoints: mediaOptions && mediaOptions.allowBreakoutSnapPoints,
558
+ selected: isSelected,
559
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
560
+ pluginInjectionApi: pluginInjectionApi,
561
+ layout: layout,
562
+ width: width,
563
+ height: height,
564
+ containerWidth: containerWidth,
565
+ fullWidthMode: fullWidthMode,
566
+ hasFallbackContainer: false,
567
+ mediaSingleWidth: mediaSingleWidth,
568
+ editorAppearance: editorAppearance,
569
+ lineLength: contentWidthForLegacyExperience || FALLBACK_MOST_COMMON_WIDTH,
570
+ pctWidth: mediaSingleWidthAttribute
571
+ }, MediaChildren) : (0, _react2.jsx)(_ui.MediaSingle, {
572
+ layout: layout,
573
+ width: width,
574
+ height: height,
575
+ containerWidth: containerWidth,
576
+ fullWidthMode: fullWidthMode,
577
+ hasFallbackContainer: false,
578
+ editorAppearance: editorAppearance,
579
+ pctWidth: mediaSingleWidthAttribute,
580
+ lineLength: lineLength || FALLBACK_MOST_COMMON_WIDTH,
581
+ size: legacySize
582
+ }, MediaChildren));
583
+ };