@atlaskit/editor-plugin-media 1.31.6 → 1.31.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 1.31.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [#141594](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/141594)
8
+ [`3f6b2eb7bd493`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/3f6b2eb7bd493) -
9
+ [ux] [ED-24867] This change moves nesting codeblocks and media in blockquotes via insertion
10
+ methods behind an experiment gate.
11
+ - Updated dependencies
12
+
13
+ ## 1.31.7
14
+
15
+ ### Patch Changes
16
+
17
+ - [#140707](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/140707)
18
+ [`972fb840acf35`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/972fb840acf35) -
19
+ Switch from fg to experiment for media-from-url
20
+ - Updated dependencies
21
+
3
22
  ## 1.31.6
4
23
 
5
24
  ### Patch Changes
@@ -30,6 +30,7 @@ var _utils2 = require("@atlaskit/editor-prosemirror/utils");
30
30
  var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
31
31
  var _mediaClient = require("@atlaskit/media-client");
32
32
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
33
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
33
34
  var _captions = require("../commands/captions");
34
35
  var _main = require("../pm-plugins/main");
35
36
  var _CaptionPlaceholder = _interopRequireDefault(require("../ui/CaptionPlaceholder"));
@@ -466,7 +467,7 @@ var MediaSingleNode = exports.default = /*#__PURE__*/function (_Component) {
466
467
  ,
467
468
  className: _styles.MediaSingleNodeSelector,
468
469
  onClick: this.onMediaSingleClicked
469
- }, (0, _platformFeatureFlags.fg)('platform_editor_insert_media_plugin_phase_one') && (0, _react2.jsx)(_mediaSingle.MediaBadges, {
470
+ }, (0, _experiments.editorExperiment)('add-media-from-url', true) && (0, _react2.jsx)(_mediaSingle.MediaBadges, {
470
471
  mediaElement: currentMediaElement(),
471
472
  mediaHeight: height,
472
473
  mediaWidth: width,
@@ -483,7 +484,7 @@ var MediaSingleNode = exports.default = /*#__PURE__*/function (_Component) {
483
484
  isDrafting: isCurrentNodeDrafting,
484
485
  badgeSize: badgeSize
485
486
  }));
486
- }), !(0, _platformFeatureFlags.fg)('platform_editor_insert_media_plugin_phase_one') && commentsOnMedia && (0, _react2.jsx)(_CommentBadge.CommentBadge, {
487
+ }), !(0, _experiments.editorExperiment)('add-media-from-url', true) && commentsOnMedia && (0, _react2.jsx)(_CommentBadge.CommentBadge, {
487
488
  commentsOnMediaBugFixEnabled: mediaOptions === null || mediaOptions === void 0 || (_mediaOptions$getEdit2 = mediaOptions.getEditorFeatureFlags) === null || _mediaOptions$getEdit2 === void 0 || (_mediaOptions$getEdit2 = _mediaOptions$getEdit2.call(mediaOptions)) === null || _mediaOptions$getEdit2 === void 0 ? void 0 : _mediaOptions$getEdit2.commentsOnMediaBugFix,
488
489
  view: view,
489
490
  api: pluginInjectionApi,
@@ -32,6 +32,8 @@ var _utils2 = require("@atlaskit/editor-prosemirror/utils");
32
32
  var _view2 = require("@atlaskit/editor-prosemirror/view");
33
33
  var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
34
34
  var _mediaCommon = require("@atlaskit/media-common");
35
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
36
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
35
37
  var _helpers = _interopRequireWildcard(require("../commands/helpers"));
36
38
  var helpers = _helpers;
37
39
  var _pickerFacade = _interopRequireDefault(require("../picker-facade"));
@@ -125,9 +127,10 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
125
127
  * called when we insert a new file via the picker (connected via pickerfacade)
126
128
  */
127
129
  (0, _defineProperty2.default)(this, "insertFile", function (mediaState, onMediaStateChanged, pickerType) {
128
- var _this$pluginInjection, _mediaState$collectio, _this$pluginInjection2;
130
+ var _this$pluginInjection, _this$pluginInjection2, _mediaState$collectio, _this$pluginInjection3;
129
131
  var state = _this.view.state;
130
132
  var editorAnalyticsAPI = (_this$pluginInjection = _this.pluginInjectionApi) === null || _this$pluginInjection === void 0 || (_this$pluginInjection = _this$pluginInjection.analytics) === null || _this$pluginInjection === void 0 ? void 0 : _this$pluginInjection.actions;
133
+ var isNestingInQuoteSupported = ((_this$pluginInjection2 = _this.pluginInjectionApi) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.featureFlags) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.sharedState.currentState()) === null || _this$pluginInjection2 === void 0 ? void 0 : _this$pluginInjection2.nestMediaAndCodeblockInQuote) || (0, _platformFeatureFlags.fg)('editor_nest_media_and_codeblock_in_quotes_jira');
131
134
  var mediaStateWithContext = _objectSpread(_objectSpread({}, mediaState), {}, {
132
135
  contextId: _this.contextIdentifierProvider ? _this.contextIdentifierProvider.objectId : undefined
133
136
  });
@@ -154,11 +157,11 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
154
157
  break;
155
158
  case 'block':
156
159
  // read width state right before inserting to get up-to-date and define values
157
- var widthPluginState = (_this$pluginInjection2 = _this.pluginInjectionApi) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.width) === null || _this$pluginInjection2 === void 0 ? void 0 : _this$pluginInjection2.sharedState.currentState();
158
- (0, _mediaSingle2.insertMediaSingleNode)(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, _this.onNodeInserted);
160
+ var widthPluginState = (_this$pluginInjection3 = _this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.width) === null || _this$pluginInjection3 === void 0 ? void 0 : _this$pluginInjection3.sharedState.currentState();
161
+ (0, _mediaSingle2.insertMediaSingleNode)(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, _this.onNodeInserted, isNestingInQuoteSupported);
159
162
  break;
160
163
  case 'group':
161
- (0, _mediaFiles.insertMediaGroupNode)(editorAnalyticsAPI)(_this.view, [mediaStateWithContext], collection, _this.getInputMethod(pickerType));
164
+ (0, _mediaFiles.insertMediaGroupNode)(editorAnalyticsAPI)(_this.view, [mediaStateWithContext], collection, _this.getInputMethod(pickerType), isNestingInQuoteSupported);
162
165
  break;
163
166
  }
164
167
 
@@ -211,6 +214,9 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
211
214
  });
212
215
  (0, _defineProperty2.default)(this, "showMediaPicker", function () {
213
216
  if (_this.openMediaPickerBrowser) {
217
+ (0, _experiments.editorExperiment)('add-media-from-url', false, {
218
+ exposure: true
219
+ });
214
220
  return _this.openMediaPickerBrowser();
215
221
  }
216
222
  _this.onPopupToggleCallback(true);
@@ -594,8 +600,8 @@ var MediaPluginStateImplementation = exports.MediaPluginStateImplementation = /*
594
600
  }, {
595
601
  key: "contextIdentifierProvider",
596
602
  get: function get() {
597
- var _this$pluginInjection3;
598
- return (_this$pluginInjection3 = this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.contextIdentifier) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.sharedState.currentState()) === null || _this$pluginInjection3 === void 0 ? void 0 : _this$pluginInjection3.contextIdentifierProvider;
603
+ var _this$pluginInjection4;
604
+ return (_this$pluginInjection4 = this.pluginInjectionApi) === null || _this$pluginInjection4 === void 0 || (_this$pluginInjection4 = _this$pluginInjection4.contextIdentifier) === null || _this$pluginInjection4 === void 0 || (_this$pluginInjection4 = _this$pluginInjection4.sharedState.currentState()) === null || _this$pluginInjection4 === void 0 ? void 0 : _this$pluginInjection4.contextIdentifierProvider;
599
605
  }
600
606
  }, {
601
607
  key: "selectLastAddedMediaNode",
@@ -87,7 +87,7 @@ var CommentBadge = exports.CommentBadge = (0, _reactIntlNext.injectIntl)(Comment
87
87
  /**
88
88
  * Remove CommentBadgeWrapper component above
89
89
  * and rename CommentBadgeNextWrapper to CommentBadgeWrapper
90
- * when clean up platform_editor_insert_media_plugin_phase_one feature flag
90
+ * when clean up platform_editor_add_media_from_url feature flag
91
91
  */
92
92
 
93
93
  var CommentBadgeNextWrapper = exports.CommentBadgeNextWrapper = function CommentBadgeNextWrapper(_ref2) {
@@ -146,7 +146,7 @@ var insertMediaInlineNode = exports.insertMediaInlineNode = function insertMedia
146
146
  * @param collection Collection for the media to be added
147
147
  */
148
148
  var insertMediaGroupNode = exports.insertMediaGroupNode = function insertMediaGroupNode(editorAnalyticsAPI) {
149
- return function (view, mediaStates, collection, inputMethod) {
149
+ return function (view, mediaStates, collection, inputMethod, isNestingInQuoteSupported) {
150
150
  var state = view.state,
151
151
  dispatch = view.dispatch;
152
152
  var tr = state.tr,
@@ -168,6 +168,17 @@ var insertMediaGroupNode = exports.insertMediaGroupNode = function insertMediaGr
168
168
  var withParagraph = shouldAppendParagraph(state, nodeAtInsertionPoint);
169
169
  var content = parent.type === schema.nodes.mediaGroup ? mediaNodes // If parent is a mediaGroup do not wrap items again.
170
170
  : [schema.nodes.mediaGroup.createChecked({}, mediaNodes)];
171
+
172
+ /** we only allow the insertion of media groups inside a blockquote if nesting in quotes is supported */
173
+ var grandParentNode = state.selection.$from.node(-1);
174
+ var grandParentNodeType = grandParentNode === null || grandParentNode === void 0 ? void 0 : grandParentNode.type.name;
175
+ if (grandParentNodeType === 'blockquote' && !isNestingInQuoteSupported) {
176
+ var grandparentEndPos = state.selection.$from.start(-1) + grandParentNode.nodeSize - 1;
177
+ (0, _utils2.safeInsert)(content[0], grandparentEndPos)(tr).scrollIntoView();
178
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(getInsertMediaGroupAnalytics(mediaStates, inputMethod))(tr);
179
+ dispatch(tr);
180
+ return;
181
+ }
171
182
  if (shouldSplit) {
172
183
  content = withParagraph ? content.concat(paragraph.create()) : content;
173
184
  // delete the selection or empty paragraph
@@ -16,6 +16,7 @@ var _model = require("@atlaskit/editor-prosemirror/model");
16
16
  var _state = require("@atlaskit/editor-prosemirror/state");
17
17
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
18
18
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
19
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
19
20
  var _mediaCommon = require("../utils/media-common");
20
21
  var _analytics2 = require("./analytics");
21
22
  var _isType = require("./is-type");
@@ -40,6 +41,7 @@ function shouldAddParagraph(state) {
40
41
  function insertNodesWithOptionalParagraph(nodes) {
41
42
  var analyticsAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
42
43
  var editorAnalyticsAPI = arguments.length > 2 ? arguments[2] : undefined;
44
+ var isNestingInQuoteSupported = arguments.length > 3 ? arguments[3] : undefined;
43
45
  return function (state, dispatch) {
44
46
  var tr = state.tr,
45
47
  schema = state.schema;
@@ -53,7 +55,14 @@ function insertNodesWithOptionalParagraph(nodes) {
53
55
  nodes.push(paragraph.create());
54
56
  openEnd = 1;
55
57
  }
56
- if (state.selection.empty) {
58
+
59
+ /** we only allow the insertion of media singles inside a blockquote if nesting in quotes is supported */
60
+ var grandParentNode = state.selection.$from.node(-1);
61
+ var grandParentNodeType = grandParentNode === null || grandParentNode === void 0 ? void 0 : grandParentNode.type.name;
62
+ if (grandParentNodeType === 'blockquote' && !isNestingInQuoteSupported) {
63
+ var grandparentEndPos = state.selection.$from.start(-1) + grandParentNode.nodeSize - 1;
64
+ (0, _utils2.safeInsert)(nodes[0], grandparentEndPos)(tr).scrollIntoView();
65
+ } else if (state.selection.empty) {
57
66
  tr.insert(state.selection.from, nodes);
58
67
  // Set the cursor position at the end of the insertion
59
68
  var endPos = state.selection.from + nodes.reduce(function (totalSize, currNode) {
@@ -78,7 +87,7 @@ function insertNodesWithOptionalParagraph(nodes) {
78
87
  var isMediaSingle = exports.isMediaSingle = function isMediaSingle(schema, fileMimeType) {
79
88
  return !!schema.nodes.mediaSingle && (0, _isType.isImage)(fileMimeType);
80
89
  };
81
- var insertMediaAsMediaSingle = exports.insertMediaAsMediaSingle = function insertMediaAsMediaSingle(view, node, inputMethod, editorAnalyticsAPI) {
90
+ var insertMediaAsMediaSingle = exports.insertMediaAsMediaSingle = function insertMediaAsMediaSingle(view, node, inputMethod, editorAnalyticsAPI, isNestingInQuoteSupported) {
82
91
  var _node$attrs$width;
83
92
  var state = view.state,
84
93
  dispatch = view.dispatch;
@@ -94,7 +103,7 @@ var insertMediaAsMediaSingle = exports.insertMediaAsMediaSingle = function inser
94
103
  return false;
95
104
  }
96
105
  var resizeExperience = (0, _platformFeatureFlags.fg)('platform.editor.media.extended-resize-experience');
97
- var insertMediaPopup = (0, _platformFeatureFlags.fg)('platform_editor_insert_media_plugin_phase_one');
106
+ var insertMediaPopup = (0, _experiments.editorExperiment)('add-media-from-url', true);
98
107
  var mediaSingleAttrs = resizeExperience && insertMediaPopup ? {
99
108
  widthType: 'pixel',
100
109
  width: (0, _mediaSingle.getMediaSingleInitialWidth)((_node$attrs$width = node.attrs.width) !== null && _node$attrs$width !== void 0 ? _node$attrs$width : _mediaSingle.DEFAULT_IMAGE_WIDTH),
@@ -106,7 +115,7 @@ var insertMediaAsMediaSingle = exports.insertMediaAsMediaSingle = function inser
106
115
  inputMethod: inputMethod,
107
116
  fileExtension: node.attrs.__fileMimeType
108
117
  };
109
- return insertNodesWithOptionalParagraph(nodes, analyticsAttributes, editorAnalyticsAPI)(state, dispatch);
118
+ return insertNodesWithOptionalParagraph(nodes, analyticsAttributes, editorAnalyticsAPI, isNestingInQuoteSupported)(state, dispatch);
110
119
  };
111
120
  var getFileExtension = function getFileExtension(fileName) {
112
121
  if (fileName) {
@@ -115,7 +124,7 @@ var getFileExtension = function getFileExtension(fileName) {
115
124
  }
116
125
  return undefined;
117
126
  };
118
- var insertMediaSingleNode = exports.insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted) {
127
+ var insertMediaSingleNode = exports.insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted, isNestingInQuoteSupported) {
119
128
  var _state$selection$$fro;
120
129
  if (collection === undefined) {
121
130
  return false;
@@ -144,7 +153,7 @@ var insertMediaSingleNode = exports.insertMediaSingleNode = function insertMedia
144
153
  insertNodesWithOptionalParagraph([node], {
145
154
  fileExtension: fileExtension,
146
155
  inputMethod: inputMethod
147
- }, editorAnalyticsAPI)(state, dispatch);
156
+ }, editorAnalyticsAPI, isNestingInQuoteSupported)(state, dispatch);
148
157
  } else {
149
158
  var tr = null;
150
159
  tr = (0, _insert.safeInsert)(node, state.selection.from)(state.tr);
@@ -11,8 +11,7 @@ import React, { Component, Fragment, useMemo } from 'react';
11
11
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
12
12
  import { css, jsx } from '@emotion/react';
13
13
  import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
14
- import { calcMediaSinglePixelWidth, DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH, getMaxWidthForNestedNode, MEDIA_SINGLE_GUTTER_SIZE } from '@atlaskit/editor-common/media-single';
15
- import { ExternalImageBadge, MediaBadges } from '@atlaskit/editor-common/media-single';
14
+ import { calcMediaSinglePixelWidth, DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH, ExternalImageBadge, getMaxWidthForNestedNode, MEDIA_SINGLE_GUTTER_SIZE, MediaBadges } from '@atlaskit/editor-common/media-single';
16
15
  import { WithProviders } from '@atlaskit/editor-common/provider-factory';
17
16
  import ReactNodeView from '@atlaskit/editor-common/react-node-view';
18
17
  import { MediaSingle } from '@atlaskit/editor-common/ui';
@@ -22,6 +21,7 @@ import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/u
22
21
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
23
22
  import { getAttrsFromUrl } from '@atlaskit/media-client';
24
23
  import { fg } from '@atlaskit/platform-feature-flags';
24
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
25
25
  import { insertAndSelectCaptionFromMediaSinglePos } from '../commands/captions';
26
26
  import { MEDIA_CONTENT_WRAP_CLASS_NAME } from '../pm-plugins/main';
27
27
  import CaptionPlaceholder from '../ui/CaptionPlaceholder';
@@ -384,7 +384,7 @@ export default class MediaSingleNode extends Component {
384
384
  ,
385
385
  className: MediaSingleNodeSelector,
386
386
  onClick: this.onMediaSingleClicked
387
- }, fg('platform_editor_insert_media_plugin_phase_one') && jsx(MediaBadges, {
387
+ }, editorExperiment('add-media-from-url', true) && jsx(MediaBadges, {
388
388
  mediaElement: currentMediaElement(),
389
389
  mediaHeight: height,
390
390
  mediaWidth: width,
@@ -400,7 +400,7 @@ export default class MediaSingleNode extends Component {
400
400
  getPos: getPos,
401
401
  isDrafting: isCurrentNodeDrafting,
402
402
  badgeSize: badgeSize
403
- }))), !fg('platform_editor_insert_media_plugin_phase_one') && commentsOnMedia && jsx(CommentBadge, {
403
+ }))), !editorExperiment('add-media-from-url', true) && commentsOnMedia && jsx(CommentBadge, {
404
404
  commentsOnMediaBugFixEnabled: mediaOptions === null || mediaOptions === void 0 ? void 0 : (_mediaOptions$getEdit2 = mediaOptions.getEditorFeatureFlags) === null || _mediaOptions$getEdit2 === void 0 ? void 0 : (_mediaOptions$getEdit3 = _mediaOptions$getEdit2.call(mediaOptions)) === null || _mediaOptions$getEdit3 === void 0 ? void 0 : _mediaOptions$getEdit3.commentsOnMediaBugFix,
405
405
  view: view,
406
406
  api: pluginInjectionApi,
@@ -14,6 +14,8 @@ import { findDomRefAtPos, findParentNodeOfType, findSelectedNodeOfType, isNodeSe
14
14
  import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
15
15
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
16
16
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
17
+ import { fg } from '@atlaskit/platform-feature-flags';
18
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
17
19
  import * as helpers from '../commands/helpers';
18
20
  import { updateMediaNodeAttrs } from '../commands/helpers';
19
21
  import PickerFacade from '../picker-facade';
@@ -98,11 +100,12 @@ export class MediaPluginStateImplementation {
98
100
  * called when we insert a new file via the picker (connected via pickerfacade)
99
101
  */
100
102
  _defineProperty(this, "insertFile", (mediaState, onMediaStateChanged, pickerType) => {
101
- var _this$pluginInjection, _this$pluginInjection2, _mediaState$collectio, _this$pluginInjection3, _this$pluginInjection4;
103
+ var _this$pluginInjection, _this$pluginInjection2, _this$pluginInjection3, _this$pluginInjection4, _this$pluginInjection5, _mediaState$collectio, _this$pluginInjection6, _this$pluginInjection7;
102
104
  const {
103
105
  state
104
106
  } = this.view;
105
107
  const editorAnalyticsAPI = (_this$pluginInjection = this.pluginInjectionApi) === null || _this$pluginInjection === void 0 ? void 0 : (_this$pluginInjection2 = _this$pluginInjection.analytics) === null || _this$pluginInjection2 === void 0 ? void 0 : _this$pluginInjection2.actions;
108
+ const isNestingInQuoteSupported = ((_this$pluginInjection3 = this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 ? void 0 : (_this$pluginInjection4 = _this$pluginInjection3.featureFlags) === null || _this$pluginInjection4 === void 0 ? void 0 : (_this$pluginInjection5 = _this$pluginInjection4.sharedState.currentState()) === null || _this$pluginInjection5 === void 0 ? void 0 : _this$pluginInjection5.nestMediaAndCodeblockInQuote) || fg('editor_nest_media_and_codeblock_in_quotes_jira');
106
109
  const mediaStateWithContext = {
107
110
  ...mediaState,
108
111
  contextId: this.contextIdentifierProvider ? this.contextIdentifierProvider.objectId : undefined
@@ -128,11 +131,11 @@ export class MediaPluginStateImplementation {
128
131
  break;
129
132
  case 'block':
130
133
  // read width state right before inserting to get up-to-date and define values
131
- const widthPluginState = (_this$pluginInjection3 = this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 ? void 0 : (_this$pluginInjection4 = _this$pluginInjection3.width) === null || _this$pluginInjection4 === void 0 ? void 0 : _this$pluginInjection4.sharedState.currentState();
132
- insertMediaSingleNode(this.view, mediaStateWithContext, this.getInputMethod(pickerType), collection, this.mediaOptions && this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, this.onNodeInserted);
134
+ const widthPluginState = (_this$pluginInjection6 = this.pluginInjectionApi) === null || _this$pluginInjection6 === void 0 ? void 0 : (_this$pluginInjection7 = _this$pluginInjection6.width) === null || _this$pluginInjection7 === void 0 ? void 0 : _this$pluginInjection7.sharedState.currentState();
135
+ insertMediaSingleNode(this.view, mediaStateWithContext, this.getInputMethod(pickerType), collection, this.mediaOptions && this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, this.onNodeInserted, isNestingInQuoteSupported);
133
136
  break;
134
137
  case 'group':
135
- insertMediaGroupNode(editorAnalyticsAPI)(this.view, [mediaStateWithContext], collection, this.getInputMethod(pickerType));
138
+ insertMediaGroupNode(editorAnalyticsAPI)(this.view, [mediaStateWithContext], collection, this.getInputMethod(pickerType), isNestingInQuoteSupported);
136
139
  break;
137
140
  }
138
141
 
@@ -181,6 +184,9 @@ export class MediaPluginStateImplementation {
181
184
  });
182
185
  _defineProperty(this, "showMediaPicker", () => {
183
186
  if (this.openMediaPickerBrowser) {
187
+ editorExperiment('add-media-from-url', false, {
188
+ exposure: true
189
+ });
184
190
  return this.openMediaPickerBrowser();
185
191
  }
186
192
  this.onPopupToggleCallback(true);
@@ -518,8 +524,8 @@ export class MediaPluginStateImplementation {
518
524
  return;
519
525
  }
520
526
  get contextIdentifierProvider() {
521
- var _this$pluginInjection5, _this$pluginInjection6, _this$pluginInjection7;
522
- return (_this$pluginInjection5 = this.pluginInjectionApi) === null || _this$pluginInjection5 === void 0 ? void 0 : (_this$pluginInjection6 = _this$pluginInjection5.contextIdentifier) === null || _this$pluginInjection6 === void 0 ? void 0 : (_this$pluginInjection7 = _this$pluginInjection6.sharedState.currentState()) === null || _this$pluginInjection7 === void 0 ? void 0 : _this$pluginInjection7.contextIdentifierProvider;
527
+ var _this$pluginInjection8, _this$pluginInjection9, _this$pluginInjection10;
528
+ return (_this$pluginInjection8 = this.pluginInjectionApi) === null || _this$pluginInjection8 === void 0 ? void 0 : (_this$pluginInjection9 = _this$pluginInjection8.contextIdentifier) === null || _this$pluginInjection9 === void 0 ? void 0 : (_this$pluginInjection10 = _this$pluginInjection9.sharedState.currentState()) === null || _this$pluginInjection10 === void 0 ? void 0 : _this$pluginInjection10.contextIdentifierProvider;
523
529
  }
524
530
  selectLastAddedMediaNode() {
525
531
  // if lastAddedMediaSingleFileIds is empty exit because there are no added media single nodes to be selected
@@ -76,7 +76,7 @@ export const CommentBadge = injectIntl(CommentBadgeWrapper);
76
76
  /**
77
77
  * Remove CommentBadgeWrapper component above
78
78
  * and rename CommentBadgeNextWrapper to CommentBadgeWrapper
79
- * when clean up platform_editor_insert_media_plugin_phase_one feature flag
79
+ * when clean up platform_editor_add_media_from_url feature flag
80
80
  */
81
81
 
82
82
  export const CommentBadgeNextWrapper = ({
@@ -153,7 +153,7 @@ export const insertMediaInlineNode = editorAnalyticsAPI => (view, mediaState, co
153
153
  * @param mediaStates Media files to be added to the editor
154
154
  * @param collection Collection for the media to be added
155
155
  */
156
- export const insertMediaGroupNode = editorAnalyticsAPI => (view, mediaStates, collection, inputMethod) => {
156
+ export const insertMediaGroupNode = editorAnalyticsAPI => (view, mediaStates, collection, inputMethod, isNestingInQuoteSupported) => {
157
157
  const {
158
158
  state,
159
159
  dispatch
@@ -180,6 +180,17 @@ export const insertMediaGroupNode = editorAnalyticsAPI => (view, mediaStates, co
180
180
  const withParagraph = shouldAppendParagraph(state, nodeAtInsertionPoint);
181
181
  let content = parent.type === schema.nodes.mediaGroup ? mediaNodes // If parent is a mediaGroup do not wrap items again.
182
182
  : [schema.nodes.mediaGroup.createChecked({}, mediaNodes)];
183
+
184
+ /** we only allow the insertion of media groups inside a blockquote if nesting in quotes is supported */
185
+ const grandParentNode = state.selection.$from.node(-1);
186
+ const grandParentNodeType = grandParentNode === null || grandParentNode === void 0 ? void 0 : grandParentNode.type.name;
187
+ if (grandParentNodeType === 'blockquote' && !isNestingInQuoteSupported) {
188
+ const grandparentEndPos = state.selection.$from.start(-1) + grandParentNode.nodeSize - 1;
189
+ safeInsert(content[0], grandparentEndPos)(tr).scrollIntoView();
190
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent(getInsertMediaGroupAnalytics(mediaStates, inputMethod))(tr);
191
+ dispatch(tr);
192
+ return;
193
+ }
183
194
  if (shouldSplit) {
184
195
  content = withParagraph ? content.concat(paragraph.create()) : content;
185
196
  // delete the selection or empty paragraph
@@ -8,6 +8,7 @@ import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
8
8
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
9
9
  import { safeInsert as pmSafeInsert, removeSelectedNode } from '@atlaskit/editor-prosemirror/utils';
10
10
  import { fg } from '@atlaskit/platform-feature-flags';
11
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
11
12
  import { copyOptionalAttrsFromMediaState } from '../utils/media-common';
12
13
  import { findChangeFromLocation, getChangeMediaAnalytics } from './analytics';
13
14
  import { isImage } from './is-type';
@@ -25,7 +26,7 @@ const getInsertMediaAnalytics = (inputMethod, fileExtension) => ({
25
26
  function shouldAddParagraph(state) {
26
27
  return atTheBeginningOfBlock(state) && !checkNodeDown(state.selection, state.doc, isEmptyParagraph);
27
28
  }
28
- function insertNodesWithOptionalParagraph(nodes, analyticsAttributes = {}, editorAnalyticsAPI) {
29
+ function insertNodesWithOptionalParagraph(nodes, analyticsAttributes = {}, editorAnalyticsAPI, isNestingInQuoteSupported) {
29
30
  return function (state, dispatch) {
30
31
  const {
31
32
  tr,
@@ -45,7 +46,14 @@ function insertNodesWithOptionalParagraph(nodes, analyticsAttributes = {}, edito
45
46
  nodes.push(paragraph.create());
46
47
  openEnd = 1;
47
48
  }
48
- if (state.selection.empty) {
49
+
50
+ /** we only allow the insertion of media singles inside a blockquote if nesting in quotes is supported */
51
+ const grandParentNode = state.selection.$from.node(-1);
52
+ const grandParentNodeType = grandParentNode === null || grandParentNode === void 0 ? void 0 : grandParentNode.type.name;
53
+ if (grandParentNodeType === 'blockquote' && !isNestingInQuoteSupported) {
54
+ const grandparentEndPos = state.selection.$from.start(-1) + grandParentNode.nodeSize - 1;
55
+ pmSafeInsert(nodes[0], grandparentEndPos)(tr).scrollIntoView();
56
+ } else if (state.selection.empty) {
49
57
  tr.insert(state.selection.from, nodes);
50
58
  // Set the cursor position at the end of the insertion
51
59
  const endPos = state.selection.from + nodes.reduce((totalSize, currNode) => totalSize + currNode.nodeSize, 0);
@@ -66,7 +74,7 @@ function insertNodesWithOptionalParagraph(nodes, analyticsAttributes = {}, edito
66
74
  };
67
75
  }
68
76
  export const isMediaSingle = (schema, fileMimeType) => !!schema.nodes.mediaSingle && isImage(fileMimeType);
69
- export const insertMediaAsMediaSingle = (view, node, inputMethod, editorAnalyticsAPI) => {
77
+ export const insertMediaAsMediaSingle = (view, node, inputMethod, editorAnalyticsAPI, isNestingInQuoteSupported) => {
70
78
  var _node$attrs$width;
71
79
  const {
72
80
  state,
@@ -85,7 +93,7 @@ export const insertMediaAsMediaSingle = (view, node, inputMethod, editorAnalytic
85
93
  return false;
86
94
  }
87
95
  const resizeExperience = fg('platform.editor.media.extended-resize-experience');
88
- const insertMediaPopup = fg('platform_editor_insert_media_plugin_phase_one');
96
+ const insertMediaPopup = editorExperiment('add-media-from-url', true);
89
97
  const mediaSingleAttrs = resizeExperience && insertMediaPopup ? {
90
98
  widthType: 'pixel',
91
99
  width: getMediaSingleInitialWidth((_node$attrs$width = node.attrs.width) !== null && _node$attrs$width !== void 0 ? _node$attrs$width : DEFAULT_IMAGE_WIDTH),
@@ -97,7 +105,7 @@ export const insertMediaAsMediaSingle = (view, node, inputMethod, editorAnalytic
97
105
  inputMethod,
98
106
  fileExtension: node.attrs.__fileMimeType
99
107
  };
100
- return insertNodesWithOptionalParagraph(nodes, analyticsAttributes, editorAnalyticsAPI)(state, dispatch);
108
+ return insertNodesWithOptionalParagraph(nodes, analyticsAttributes, editorAnalyticsAPI, isNestingInQuoteSupported)(state, dispatch);
101
109
  };
102
110
  const getFileExtension = fileName => {
103
111
  if (fileName) {
@@ -106,7 +114,7 @@ const getFileExtension = fileName => {
106
114
  }
107
115
  return undefined;
108
116
  };
109
- export const insertMediaSingleNode = (view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted) => {
117
+ export const insertMediaSingleNode = (view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted, isNestingInQuoteSupported) => {
110
118
  var _state$selection$$fro;
111
119
  if (collection === undefined) {
112
120
  return false;
@@ -137,7 +145,7 @@ export const insertMediaSingleNode = (view, mediaState, inputMethod, collection,
137
145
  insertNodesWithOptionalParagraph([node], {
138
146
  fileExtension,
139
147
  inputMethod
140
- }, editorAnalyticsAPI)(state, dispatch);
148
+ }, editorAnalyticsAPI, isNestingInQuoteSupported)(state, dispatch);
141
149
  } else {
142
150
  let tr = null;
143
151
  tr = safeInsert(node, state.selection.from)(state.tr);
@@ -24,8 +24,7 @@ import React, { Component, Fragment, useMemo } from 'react';
24
24
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
25
25
  import { css, jsx } from '@emotion/react';
26
26
  import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
27
- import { calcMediaSinglePixelWidth, DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH, getMaxWidthForNestedNode, MEDIA_SINGLE_GUTTER_SIZE } from '@atlaskit/editor-common/media-single';
28
- import { ExternalImageBadge, MediaBadges } from '@atlaskit/editor-common/media-single';
27
+ import { calcMediaSinglePixelWidth, DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH, ExternalImageBadge, getMaxWidthForNestedNode, MEDIA_SINGLE_GUTTER_SIZE, MediaBadges } from '@atlaskit/editor-common/media-single';
29
28
  import { WithProviders } from '@atlaskit/editor-common/provider-factory';
30
29
  import ReactNodeView from '@atlaskit/editor-common/react-node-view';
31
30
  import { MediaSingle } from '@atlaskit/editor-common/ui';
@@ -35,6 +34,7 @@ import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/u
35
34
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
36
35
  import { getAttrsFromUrl } from '@atlaskit/media-client';
37
36
  import { fg } from '@atlaskit/platform-feature-flags';
37
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
38
38
  import { insertAndSelectCaptionFromMediaSinglePos } from '../commands/captions';
39
39
  import { MEDIA_CONTENT_WRAP_CLASS_NAME } from '../pm-plugins/main';
40
40
  import CaptionPlaceholder from '../ui/CaptionPlaceholder';
@@ -461,7 +461,7 @@ var MediaSingleNode = /*#__PURE__*/function (_Component) {
461
461
  ,
462
462
  className: MediaSingleNodeSelector,
463
463
  onClick: this.onMediaSingleClicked
464
- }, fg('platform_editor_insert_media_plugin_phase_one') && jsx(MediaBadges, {
464
+ }, editorExperiment('add-media-from-url', true) && jsx(MediaBadges, {
465
465
  mediaElement: currentMediaElement(),
466
466
  mediaHeight: height,
467
467
  mediaWidth: width,
@@ -478,7 +478,7 @@ var MediaSingleNode = /*#__PURE__*/function (_Component) {
478
478
  isDrafting: isCurrentNodeDrafting,
479
479
  badgeSize: badgeSize
480
480
  }));
481
- }), !fg('platform_editor_insert_media_plugin_phase_one') && commentsOnMedia && jsx(CommentBadge, {
481
+ }), !editorExperiment('add-media-from-url', true) && commentsOnMedia && jsx(CommentBadge, {
482
482
  commentsOnMediaBugFixEnabled: mediaOptions === null || mediaOptions === void 0 || (_mediaOptions$getEdit2 = mediaOptions.getEditorFeatureFlags) === null || _mediaOptions$getEdit2 === void 0 || (_mediaOptions$getEdit2 = _mediaOptions$getEdit2.call(mediaOptions)) === null || _mediaOptions$getEdit2 === void 0 ? void 0 : _mediaOptions$getEdit2.commentsOnMediaBugFix,
483
483
  view: view,
484
484
  api: pluginInjectionApi,
@@ -23,6 +23,8 @@ import { findDomRefAtPos, findParentNodeOfType, findSelectedNodeOfType, isNodeSe
23
23
  import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
24
24
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
25
25
  import { getMediaFeatureFlag } from '@atlaskit/media-common';
26
+ import { fg } from '@atlaskit/platform-feature-flags';
27
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
26
28
  import * as helpers from '../commands/helpers';
27
29
  import { updateMediaNodeAttrs } from '../commands/helpers';
28
30
  import PickerFacade from '../picker-facade';
@@ -110,9 +112,10 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
110
112
  * called when we insert a new file via the picker (connected via pickerfacade)
111
113
  */
112
114
  _defineProperty(this, "insertFile", function (mediaState, onMediaStateChanged, pickerType) {
113
- var _this$pluginInjection, _mediaState$collectio, _this$pluginInjection2;
115
+ var _this$pluginInjection, _this$pluginInjection2, _mediaState$collectio, _this$pluginInjection3;
114
116
  var state = _this.view.state;
115
117
  var editorAnalyticsAPI = (_this$pluginInjection = _this.pluginInjectionApi) === null || _this$pluginInjection === void 0 || (_this$pluginInjection = _this$pluginInjection.analytics) === null || _this$pluginInjection === void 0 ? void 0 : _this$pluginInjection.actions;
118
+ var isNestingInQuoteSupported = ((_this$pluginInjection2 = _this.pluginInjectionApi) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.featureFlags) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.sharedState.currentState()) === null || _this$pluginInjection2 === void 0 ? void 0 : _this$pluginInjection2.nestMediaAndCodeblockInQuote) || fg('editor_nest_media_and_codeblock_in_quotes_jira');
116
119
  var mediaStateWithContext = _objectSpread(_objectSpread({}, mediaState), {}, {
117
120
  contextId: _this.contextIdentifierProvider ? _this.contextIdentifierProvider.objectId : undefined
118
121
  });
@@ -139,11 +142,11 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
139
142
  break;
140
143
  case 'block':
141
144
  // read width state right before inserting to get up-to-date and define values
142
- var widthPluginState = (_this$pluginInjection2 = _this.pluginInjectionApi) === null || _this$pluginInjection2 === void 0 || (_this$pluginInjection2 = _this$pluginInjection2.width) === null || _this$pluginInjection2 === void 0 ? void 0 : _this$pluginInjection2.sharedState.currentState();
143
- insertMediaSingleNode(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, _this.onNodeInserted);
145
+ var widthPluginState = (_this$pluginInjection3 = _this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.width) === null || _this$pluginInjection3 === void 0 ? void 0 : _this$pluginInjection3.sharedState.currentState();
146
+ insertMediaSingleNode(_this.view, mediaStateWithContext, _this.getInputMethod(pickerType), collection, _this.mediaOptions && _this.mediaOptions.alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, _this.onNodeInserted, isNestingInQuoteSupported);
144
147
  break;
145
148
  case 'group':
146
- insertMediaGroupNode(editorAnalyticsAPI)(_this.view, [mediaStateWithContext], collection, _this.getInputMethod(pickerType));
149
+ insertMediaGroupNode(editorAnalyticsAPI)(_this.view, [mediaStateWithContext], collection, _this.getInputMethod(pickerType), isNestingInQuoteSupported);
147
150
  break;
148
151
  }
149
152
 
@@ -196,6 +199,9 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
196
199
  });
197
200
  _defineProperty(this, "showMediaPicker", function () {
198
201
  if (_this.openMediaPickerBrowser) {
202
+ editorExperiment('add-media-from-url', false, {
203
+ exposure: true
204
+ });
199
205
  return _this.openMediaPickerBrowser();
200
206
  }
201
207
  _this.onPopupToggleCallback(true);
@@ -579,8 +585,8 @@ export var MediaPluginStateImplementation = /*#__PURE__*/function () {
579
585
  }, {
580
586
  key: "contextIdentifierProvider",
581
587
  get: function get() {
582
- var _this$pluginInjection3;
583
- return (_this$pluginInjection3 = this.pluginInjectionApi) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.contextIdentifier) === null || _this$pluginInjection3 === void 0 || (_this$pluginInjection3 = _this$pluginInjection3.sharedState.currentState()) === null || _this$pluginInjection3 === void 0 ? void 0 : _this$pluginInjection3.contextIdentifierProvider;
588
+ var _this$pluginInjection4;
589
+ return (_this$pluginInjection4 = this.pluginInjectionApi) === null || _this$pluginInjection4 === void 0 || (_this$pluginInjection4 = _this$pluginInjection4.contextIdentifier) === null || _this$pluginInjection4 === void 0 || (_this$pluginInjection4 = _this$pluginInjection4.sharedState.currentState()) === null || _this$pluginInjection4 === void 0 ? void 0 : _this$pluginInjection4.contextIdentifierProvider;
584
590
  }
585
591
  }, {
586
592
  key: "selectLastAddedMediaNode",
@@ -77,7 +77,7 @@ export var CommentBadge = injectIntl(CommentBadgeWrapper);
77
77
  /**
78
78
  * Remove CommentBadgeWrapper component above
79
79
  * and rename CommentBadgeNextWrapper to CommentBadgeWrapper
80
- * when clean up platform_editor_insert_media_plugin_phase_one feature flag
80
+ * when clean up platform_editor_add_media_from_url feature flag
81
81
  */
82
82
 
83
83
  export var CommentBadgeNextWrapper = function CommentBadgeNextWrapper(_ref2) {
@@ -140,7 +140,7 @@ export var insertMediaInlineNode = function insertMediaInlineNode(editorAnalytic
140
140
  * @param collection Collection for the media to be added
141
141
  */
142
142
  export var insertMediaGroupNode = function insertMediaGroupNode(editorAnalyticsAPI) {
143
- return function (view, mediaStates, collection, inputMethod) {
143
+ return function (view, mediaStates, collection, inputMethod, isNestingInQuoteSupported) {
144
144
  var state = view.state,
145
145
  dispatch = view.dispatch;
146
146
  var tr = state.tr,
@@ -162,6 +162,17 @@ export var insertMediaGroupNode = function insertMediaGroupNode(editorAnalyticsA
162
162
  var withParagraph = shouldAppendParagraph(state, nodeAtInsertionPoint);
163
163
  var content = parent.type === schema.nodes.mediaGroup ? mediaNodes // If parent is a mediaGroup do not wrap items again.
164
164
  : [schema.nodes.mediaGroup.createChecked({}, mediaNodes)];
165
+
166
+ /** we only allow the insertion of media groups inside a blockquote if nesting in quotes is supported */
167
+ var grandParentNode = state.selection.$from.node(-1);
168
+ var grandParentNodeType = grandParentNode === null || grandParentNode === void 0 ? void 0 : grandParentNode.type.name;
169
+ if (grandParentNodeType === 'blockquote' && !isNestingInQuoteSupported) {
170
+ var grandparentEndPos = state.selection.$from.start(-1) + grandParentNode.nodeSize - 1;
171
+ safeInsert(content[0], grandparentEndPos)(tr).scrollIntoView();
172
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(getInsertMediaGroupAnalytics(mediaStates, inputMethod))(tr);
173
+ dispatch(tr);
174
+ return;
175
+ }
165
176
  if (shouldSplit) {
166
177
  content = withParagraph ? content.concat(paragraph.create()) : content;
167
178
  // delete the selection or empty paragraph
@@ -11,6 +11,7 @@ import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
11
11
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
12
12
  import { safeInsert as pmSafeInsert, removeSelectedNode } from '@atlaskit/editor-prosemirror/utils';
13
13
  import { fg } from '@atlaskit/platform-feature-flags';
14
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
14
15
  import { copyOptionalAttrsFromMediaState } from '../utils/media-common';
15
16
  import { findChangeFromLocation, getChangeMediaAnalytics } from './analytics';
16
17
  import { isImage } from './is-type';
@@ -33,6 +34,7 @@ function shouldAddParagraph(state) {
33
34
  function insertNodesWithOptionalParagraph(nodes) {
34
35
  var analyticsAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
35
36
  var editorAnalyticsAPI = arguments.length > 2 ? arguments[2] : undefined;
37
+ var isNestingInQuoteSupported = arguments.length > 3 ? arguments[3] : undefined;
36
38
  return function (state, dispatch) {
37
39
  var tr = state.tr,
38
40
  schema = state.schema;
@@ -46,7 +48,14 @@ function insertNodesWithOptionalParagraph(nodes) {
46
48
  nodes.push(paragraph.create());
47
49
  openEnd = 1;
48
50
  }
49
- if (state.selection.empty) {
51
+
52
+ /** we only allow the insertion of media singles inside a blockquote if nesting in quotes is supported */
53
+ var grandParentNode = state.selection.$from.node(-1);
54
+ var grandParentNodeType = grandParentNode === null || grandParentNode === void 0 ? void 0 : grandParentNode.type.name;
55
+ if (grandParentNodeType === 'blockquote' && !isNestingInQuoteSupported) {
56
+ var grandparentEndPos = state.selection.$from.start(-1) + grandParentNode.nodeSize - 1;
57
+ pmSafeInsert(nodes[0], grandparentEndPos)(tr).scrollIntoView();
58
+ } else if (state.selection.empty) {
50
59
  tr.insert(state.selection.from, nodes);
51
60
  // Set the cursor position at the end of the insertion
52
61
  var endPos = state.selection.from + nodes.reduce(function (totalSize, currNode) {
@@ -71,7 +80,7 @@ function insertNodesWithOptionalParagraph(nodes) {
71
80
  export var isMediaSingle = function isMediaSingle(schema, fileMimeType) {
72
81
  return !!schema.nodes.mediaSingle && isImage(fileMimeType);
73
82
  };
74
- export var insertMediaAsMediaSingle = function insertMediaAsMediaSingle(view, node, inputMethod, editorAnalyticsAPI) {
83
+ export var insertMediaAsMediaSingle = function insertMediaAsMediaSingle(view, node, inputMethod, editorAnalyticsAPI, isNestingInQuoteSupported) {
75
84
  var _node$attrs$width;
76
85
  var state = view.state,
77
86
  dispatch = view.dispatch;
@@ -87,7 +96,7 @@ export var insertMediaAsMediaSingle = function insertMediaAsMediaSingle(view, no
87
96
  return false;
88
97
  }
89
98
  var resizeExperience = fg('platform.editor.media.extended-resize-experience');
90
- var insertMediaPopup = fg('platform_editor_insert_media_plugin_phase_one');
99
+ var insertMediaPopup = editorExperiment('add-media-from-url', true);
91
100
  var mediaSingleAttrs = resizeExperience && insertMediaPopup ? {
92
101
  widthType: 'pixel',
93
102
  width: getMediaSingleInitialWidth((_node$attrs$width = node.attrs.width) !== null && _node$attrs$width !== void 0 ? _node$attrs$width : DEFAULT_IMAGE_WIDTH),
@@ -99,7 +108,7 @@ export var insertMediaAsMediaSingle = function insertMediaAsMediaSingle(view, no
99
108
  inputMethod: inputMethod,
100
109
  fileExtension: node.attrs.__fileMimeType
101
110
  };
102
- return insertNodesWithOptionalParagraph(nodes, analyticsAttributes, editorAnalyticsAPI)(state, dispatch);
111
+ return insertNodesWithOptionalParagraph(nodes, analyticsAttributes, editorAnalyticsAPI, isNestingInQuoteSupported)(state, dispatch);
103
112
  };
104
113
  var getFileExtension = function getFileExtension(fileName) {
105
114
  if (fileName) {
@@ -108,7 +117,7 @@ var getFileExtension = function getFileExtension(fileName) {
108
117
  }
109
118
  return undefined;
110
119
  };
111
- export var insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted) {
120
+ export var insertMediaSingleNode = function insertMediaSingleNode(view, mediaState, inputMethod, collection, alignLeftOnInsert, widthPluginState, editorAnalyticsAPI, onNodeInserted, isNestingInQuoteSupported) {
112
121
  var _state$selection$$fro;
113
122
  if (collection === undefined) {
114
123
  return false;
@@ -137,7 +146,7 @@ export var insertMediaSingleNode = function insertMediaSingleNode(view, mediaSta
137
146
  insertNodesWithOptionalParagraph([node], {
138
147
  fileExtension: fileExtension,
139
148
  inputMethod: inputMethod
140
- }, editorAnalyticsAPI)(state, dispatch);
149
+ }, editorAnalyticsAPI, isNestingInQuoteSupported)(state, dispatch);
141
150
  } else {
142
151
  var tr = null;
143
152
  tr = safeInsert(node, state.selection.from)(state.tr);
@@ -6,6 +6,7 @@ import type { ContextIdentifierPlugin } from '@atlaskit/editor-plugin-context-id
6
6
  import type { DecorationsPlugin } from '@atlaskit/editor-plugin-decorations';
7
7
  import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
8
8
  import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode';
9
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
9
10
  import type { FloatingToolbarPlugin } from '@atlaskit/editor-plugin-floating-toolbar';
10
11
  import type { FocusPlugin } from '@atlaskit/editor-plugin-focus';
11
12
  import type { GridPlugin } from '@atlaskit/editor-plugin-grid';
@@ -29,7 +30,8 @@ export type MediaNextEditorPluginType = NextEditorPlugin<'media', {
29
30
  EditorDisabledPlugin,
30
31
  FocusPlugin,
31
32
  SelectionPlugin,
32
- OptionalPlugin<AnnotationPlugin>
33
+ OptionalPlugin<AnnotationPlugin>,
34
+ OptionalPlugin<FeatureFlagsPlugin>
33
35
  ];
34
36
  sharedState: MediaPluginState | null;
35
37
  actions: {
@@ -22,7 +22,7 @@ export declare const CommentBadge: React.FC<import("react-intl-next").WithIntlPr
22
22
  /**
23
23
  * Remove CommentBadgeWrapper component above
24
24
  * and rename CommentBadgeNextWrapper to CommentBadgeWrapper
25
- * when clean up platform_editor_insert_media_plugin_phase_one feature flag
25
+ * when clean up platform_editor_add_media_from_url feature flag
26
26
  */
27
27
  type CommentBadgeNextWrapperProps = {
28
28
  mediaSingleElement?: HTMLElement | null;
@@ -18,7 +18,7 @@ export declare const insertMediaInlineNode: (editorAnalyticsAPI: EditorAnalytics
18
18
  * @param mediaStates Media files to be added to the editor
19
19
  * @param collection Collection for the media to be added
20
20
  */
21
- export declare const insertMediaGroupNode: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, mediaStates: MediaState[], collection: string, inputMethod?: InputMethodInsertMedia) => void;
21
+ export declare const insertMediaGroupNode: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, mediaStates: MediaState[], collection: string, inputMethod?: InputMethodInsertMedia, isNestingInQuoteSupported?: boolean) => void;
22
22
  /**
23
23
  * Return position of media to be inserted, if it is inside a list
24
24
  * @param content Content to be inserted
@@ -4,8 +4,8 @@ import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model'
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { MediaState } from '../types';
6
6
  export declare const isMediaSingle: (schema: Schema, fileMimeType?: string) => boolean;
7
- export type InsertMediaAsMediaSingle = (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia) => boolean;
8
- export declare const insertMediaAsMediaSingle: (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => boolean;
9
- export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined, onNodeInserted?: ((id: string, selectionPosition: number) => void) | undefined) => boolean;
7
+ export type InsertMediaAsMediaSingle = (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, isNestingInQuoteSupported?: boolean) => boolean;
8
+ export declare const insertMediaAsMediaSingle: (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, isNestingInQuoteSupported?: boolean) => boolean;
9
+ export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined, onNodeInserted?: ((id: string, selectionPosition: number) => void) | undefined, isNestingInQuoteSupported?: boolean) => boolean;
10
10
  export declare const changeFromMediaInlineToMediaSingleNode: (view: EditorView, fromNode: PMNode, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined) => boolean;
11
11
  export declare const isVideo: import("memoize-one").MemoizedFn<(fileType?: string) => boolean>;
@@ -6,6 +6,7 @@ import type { ContextIdentifierPlugin } from '@atlaskit/editor-plugin-context-id
6
6
  import type { DecorationsPlugin } from '@atlaskit/editor-plugin-decorations';
7
7
  import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
8
8
  import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode';
9
+ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
9
10
  import type { FloatingToolbarPlugin } from '@atlaskit/editor-plugin-floating-toolbar';
10
11
  import type { FocusPlugin } from '@atlaskit/editor-plugin-focus';
11
12
  import type { GridPlugin } from '@atlaskit/editor-plugin-grid';
@@ -29,7 +30,8 @@ export type MediaNextEditorPluginType = NextEditorPlugin<'media', {
29
30
  EditorDisabledPlugin,
30
31
  FocusPlugin,
31
32
  SelectionPlugin,
32
- OptionalPlugin<AnnotationPlugin>
33
+ OptionalPlugin<AnnotationPlugin>,
34
+ OptionalPlugin<FeatureFlagsPlugin>
33
35
  ];
34
36
  sharedState: MediaPluginState | null;
35
37
  actions: {
@@ -22,7 +22,7 @@ export declare const CommentBadge: React.FC<import("react-intl-next").WithIntlPr
22
22
  /**
23
23
  * Remove CommentBadgeWrapper component above
24
24
  * and rename CommentBadgeNextWrapper to CommentBadgeWrapper
25
- * when clean up platform_editor_insert_media_plugin_phase_one feature flag
25
+ * when clean up platform_editor_add_media_from_url feature flag
26
26
  */
27
27
  type CommentBadgeNextWrapperProps = {
28
28
  mediaSingleElement?: HTMLElement | null;
@@ -18,7 +18,7 @@ export declare const insertMediaInlineNode: (editorAnalyticsAPI: EditorAnalytics
18
18
  * @param mediaStates Media files to be added to the editor
19
19
  * @param collection Collection for the media to be added
20
20
  */
21
- export declare const insertMediaGroupNode: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, mediaStates: MediaState[], collection: string, inputMethod?: InputMethodInsertMedia) => void;
21
+ export declare const insertMediaGroupNode: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, mediaStates: MediaState[], collection: string, inputMethod?: InputMethodInsertMedia, isNestingInQuoteSupported?: boolean) => void;
22
22
  /**
23
23
  * Return position of media to be inserted, if it is inside a list
24
24
  * @param content Content to be inserted
@@ -4,8 +4,8 @@ import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model'
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { MediaState } from '../types';
6
6
  export declare const isMediaSingle: (schema: Schema, fileMimeType?: string) => boolean;
7
- export type InsertMediaAsMediaSingle = (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia) => boolean;
8
- export declare const insertMediaAsMediaSingle: (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => boolean;
9
- export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined, onNodeInserted?: ((id: string, selectionPosition: number) => void) | undefined) => boolean;
7
+ export type InsertMediaAsMediaSingle = (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, isNestingInQuoteSupported?: boolean) => boolean;
8
+ export declare const insertMediaAsMediaSingle: (view: EditorView, node: PMNode, inputMethod: InputMethodInsertMedia, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, isNestingInQuoteSupported?: boolean) => boolean;
9
+ export declare const insertMediaSingleNode: (view: EditorView, mediaState: MediaState, inputMethod?: InputMethodInsertMedia, collection?: string, alignLeftOnInsert?: boolean, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined, onNodeInserted?: ((id: string, selectionPosition: number) => void) | undefined, isNestingInQuoteSupported?: boolean) => boolean;
10
10
  export declare const changeFromMediaInlineToMediaSingleNode: (view: EditorView, fromNode: PMNode, widthPluginState?: WidthPluginState | undefined, editorAnalyticsAPI?: EditorAnalyticsAPI | undefined) => boolean;
11
11
  export declare const isVideo: import("memoize-one").MemoizedFn<(fileType?: string) => boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "1.31.6",
3
+ "version": "1.31.8",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -36,7 +36,7 @@
36
36
  "@atlaskit/analytics-namespaced-context": "^6.12.0",
37
37
  "@atlaskit/analytics-next": "^10.1.0",
38
38
  "@atlaskit/button": "^20.1.0",
39
- "@atlaskit/editor-common": "^89.1.0",
39
+ "@atlaskit/editor-common": "^89.2.0",
40
40
  "@atlaskit/editor-palette": "1.6.0",
41
41
  "@atlaskit/editor-plugin-analytics": "^1.8.0",
42
42
  "@atlaskit/editor-plugin-annotation": "1.19.6",
@@ -44,7 +44,7 @@
44
44
  "@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
45
45
  "@atlaskit/editor-plugin-editor-viewmode": "^2.1.0",
46
46
  "@atlaskit/editor-plugin-floating-toolbar": "^1.13.0",
47
- "@atlaskit/editor-plugin-focus": "^1.3.0",
47
+ "@atlaskit/editor-plugin-focus": "^1.4.0",
48
48
  "@atlaskit/editor-plugin-grid": "^1.2.0",
49
49
  "@atlaskit/editor-plugin-guideline": "^1.2.0",
50
50
  "@atlaskit/editor-plugin-selection": "^1.4.0",
@@ -53,21 +53,21 @@
53
53
  "@atlaskit/editor-shared-styles": "^2.13.0",
54
54
  "@atlaskit/editor-tables": "^2.8.0",
55
55
  "@atlaskit/form": "^10.5.0",
56
- "@atlaskit/icon": "^22.17.0",
57
- "@atlaskit/media-card": "^78.3.0",
56
+ "@atlaskit/icon": "^22.18.0",
57
+ "@atlaskit/media-card": "^78.4.0",
58
58
  "@atlaskit/media-client": "^28.0.0",
59
59
  "@atlaskit/media-client-react": "^2.2.0",
60
60
  "@atlaskit/media-common": "^11.4.0",
61
61
  "@atlaskit/media-filmstrip": "^47.2.0",
62
- "@atlaskit/media-picker": "^66.5.0",
63
- "@atlaskit/media-ui": "^25.11.0",
64
- "@atlaskit/media-viewer": "^48.8.0",
62
+ "@atlaskit/media-picker": "^66.6.0",
63
+ "@atlaskit/media-ui": "^25.12.0",
64
+ "@atlaskit/media-viewer": "^48.9.0",
65
65
  "@atlaskit/platform-feature-flags": "^0.3.0",
66
66
  "@atlaskit/primitives": "^12.1.0",
67
67
  "@atlaskit/textfield": "^6.5.0",
68
68
  "@atlaskit/theme": "^13.0.0",
69
69
  "@atlaskit/tmp-editor-statsig": "^2.1.8",
70
- "@atlaskit/tokens": "^1.59.0",
70
+ "@atlaskit/tokens": "^1.60.0",
71
71
  "@atlaskit/tooltip": "^18.7.0",
72
72
  "@babel/runtime": "^7.0.0",
73
73
  "@emotion/react": "^11.7.1",
@@ -144,10 +144,10 @@
144
144
  "platform-editor-a11y-image-border-options-dropdown": {
145
145
  "type": "boolean"
146
146
  },
147
- "platform_editor_insert_media_plugin_phase_one": {
147
+ "platform_editor_media_batch_updates": {
148
148
  "type": "boolean"
149
149
  },
150
- "platform_editor_media_batch_updates": {
150
+ "editor_nest_media_and_codeblock_in_quotes_jira": {
151
151
  "type": "boolean"
152
152
  }
153
153
  },