@atlaskit/editor-plugin-media 0.8.1 → 0.9.1

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,18 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 0.9.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#63950](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/63950) [`aa44815a0e60`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/aa44815a0e60) - [ux] changed color for instructions to add alt text
8
+ - Updated dependencies
9
+
10
+ ## 0.9.0
11
+
12
+ ### Minor Changes
13
+
14
+ - [#63809](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/63809) [`0a735e84c669`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/0a735e84c669) - Added alt text support for inline images
15
+
3
16
  ## 0.8.1
4
17
 
5
18
  ### Patch Changes
@@ -4,10 +4,11 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.updateAltText = exports.openMediaAltTextMenu = exports.closeMediaAltTextMenu = void 0;
7
+ exports.updateAltTextTransform = exports.updateAltText = exports.openMediaAltTextMenu = exports.closeMediaAltTextMenuAndSave = exports.closeMediaAltTextMenu = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _analytics = require("@atlaskit/editor-common/analytics");
10
10
  var _editorAnalytics = require("@atlaskit/editor-common/editor-analytics");
11
+ var _state = require("@atlaskit/editor-prosemirror/state");
11
12
  var _mediaCommon = require("../../utils/media-common");
12
13
  var _index = require("./index");
13
14
  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; }
@@ -22,16 +23,22 @@ var createCommandWithAnalytics = function createCommandWithAnalytics(actionType,
22
23
  })((0, _index.createCommand)(action, transform));
23
24
  };
24
25
  };
25
- var closeMediaAltTextMenu = exports.closeMediaAltTextMenu = (0, _index.createCommand)(function (state) {
26
- if ((0, _mediaCommon.isSelectionMediaSingleNode)(state)) {
27
- return {
28
- type: 'closeMediaAltTextMenu'
29
- };
30
- }
31
- return false;
32
- });
26
+
27
+ // pass in undefined to close the alt text menu without saving
28
+ var closeMediaAltTextMenuAndSave = exports.closeMediaAltTextMenuAndSave = function closeMediaAltTextMenuAndSave(altText) {
29
+ var commandTransform = typeof altText === 'string' ? updateAltTextTransform(altText) : undefined;
30
+ return (0, _index.createCommand)(function (state) {
31
+ if ((0, _mediaCommon.isMediaSingleOrInlineNodeSelected)(state)) {
32
+ return {
33
+ type: 'closeMediaAltTextMenu'
34
+ };
35
+ }
36
+ return false;
37
+ }, commandTransform);
38
+ };
39
+ var closeMediaAltTextMenu = exports.closeMediaAltTextMenu = closeMediaAltTextMenuAndSave();
33
40
  var openMediaAltTextMenu = exports.openMediaAltTextMenu = createCommandWithAnalytics(_analytics.ACTION.OPENED, function (state) {
34
- if ((0, _mediaCommon.isSelectionMediaSingleNode)(state)) {
41
+ if ((0, _mediaCommon.isMediaSingleOrInlineNodeSelected)(state)) {
35
42
  return {
36
43
  type: 'openMediaAltTextMenu'
37
44
  };
@@ -40,20 +47,34 @@ var openMediaAltTextMenu = exports.openMediaAltTextMenu = createCommandWithAnaly
40
47
  }, function (tr) {
41
48
  return tr.setMeta('scrollIntoView', false);
42
49
  });
43
- var updateAltText = exports.updateAltText = function updateAltText(newAltText) {
44
- return (0, _index.createCommand)(function (state) {
45
- return (0, _mediaCommon.isSelectionMediaSingleNode)(state) ? {
46
- type: 'updateAltText'
47
- } : false;
48
- }, function (tr, state) {
49
- var mediaNode = (0, _mediaCommon.getMediaNodeFromSelection)(state);
50
- var pos = tr.selection.from + 1;
50
+ var updateAltTextTransform = exports.updateAltTextTransform = function updateAltTextTransform(newAltText) {
51
+ return function (tr, state) {
52
+ var mediaNode = (0, _mediaCommon.getMediaSingleOrInlineNodeFromSelection)(state);
51
53
  if (mediaNode) {
52
- tr.setMeta('scrollIntoView', false);
53
- tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, mediaNode.attrs), {}, {
54
+ var pos = mediaNode.type === state.schema.nodes.media ? tr.selection.from + 1 : tr.selection.from;
55
+
56
+ /**
57
+ * Any changes to attributes of a node count the node as "recreated" in Prosemirror[1]
58
+ * This makes it so Prosemirror resets the selection to the child i.e. "media" instead of "media-single"
59
+ * The recommended fix is to reset the selection.[2]
60
+ *
61
+ * [1] https://discuss.prosemirror.net/t/setnodemarkup-loses-current-nodeselection/976
62
+ * [2] https://discuss.prosemirror.net/t/setnodemarkup-and-deselect/3673
63
+ */
64
+ tr.setMeta('scrollIntoView', false).setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, mediaNode.attrs), {}, {
54
65
  alt: newAltText
55
- }));
66
+ })).setSelection(_state.NodeSelection.create(tr.doc, pos));
56
67
  }
57
68
  return tr;
58
- });
69
+ };
70
+ };
71
+ var updateAltText = exports.updateAltText = function updateAltText(newAltText) {
72
+ return (0, _index.createCommand)(function (state) {
73
+ if ((0, _mediaCommon.isMediaSingleOrInlineNodeSelected)(state)) {
74
+ return {
75
+ type: 'updateAltText'
76
+ };
77
+ }
78
+ return false;
79
+ }, updateAltTextTransform(newAltText));
59
80
  };
@@ -33,7 +33,7 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
33
33
  var CONTAINER_WIDTH_IN_PX = exports.CONTAINER_WIDTH_IN_PX = _ui.RECENT_SEARCH_WIDTH_IN_PX;
34
34
  var MAX_ALT_TEXT_LENGTH = exports.MAX_ALT_TEXT_LENGTH = 510; // double tweet length
35
35
 
36
- var supportText = (0, _react2.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n color: ", ";\n font-size: ", ";\n padding: ", " ", ";\n line-height: 20px;\n border-top: 1px solid ", ";\n margin: 0;\n"])), "var(--ds-text-subtlest, ".concat(_colors.N100, ")"), (0, _editorSharedStyles.relativeFontSizeToBase16)(12), "var(--ds-space-150, 12px)", "var(--ds-space-500, 40px)", "var(--ds-border, ".concat(_colors.N30, ")"));
36
+ var supportText = (0, _react2.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n color: ", ";\n font-size: ", ";\n padding: ", " ", ";\n line-height: 20px;\n border-top: 1px solid ", ";\n margin: 0;\n"])), "var(--ds-text-subtlest, ".concat(_colors.N200, ")"), (0, _editorSharedStyles.relativeFontSizeToBase16)(12), "var(--ds-space-150, 12px)", "var(--ds-space-500, 40px)", "var(--ds-border, ".concat(_colors.N30, ")"));
37
37
  var container = (0, _react2.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n width: ", "px;\n display: flex;\n flex-direction: column;\n overflow: auto;\n line-height: 2;\n"])), CONTAINER_WIDTH_IN_PX);
38
38
  var inputWrapper = (0, _react2.css)(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n line-height: 0;\n padding: 5px 0;\n align-items: center;\n"])));
39
39
  var validationWrapper = (0, _react2.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n line-height: 0;\n padding: ", " ", "\n ", " 0;\n margin: 0 ", " 0 ", ";\n border-top: 1px solid ", ";\n align-items: start;\n flex-direction: column;\n"])), "var(--ds-space-150, 12px)", "var(--ds-space-300, 24px)", "var(--ds-space-150, 12px)", "var(--ds-space-150, 12px)", "var(--ds-space-500, 40px)", "var(--ds-border-danger, ".concat(_colors.R400, ")"));
@@ -54,7 +54,11 @@ var AltTextEditComponent = exports.AltTextEditComponent = /*#__PURE__*/function
54
54
  });
55
55
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "closeMediaAltTextMenu", function () {
56
56
  var view = _this.props.view;
57
- (0, _commands.closeMediaAltTextMenu)(view.state, view.dispatch);
57
+ if (_this.state.validationErrors.length === 0) {
58
+ (0, _commands.closeMediaAltTextMenuAndSave)(_this.state.lastValue || '')(view.state, view.dispatch);
59
+ } else {
60
+ (0, _commands.closeMediaAltTextMenu)(view.state, view.dispatch);
61
+ }
58
62
  });
59
63
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "dispatchCancelEvent", function (event) {
60
64
  var _this$props = _this.props,
@@ -69,11 +73,6 @@ var AltTextEditComponent = exports.AltTextEditComponent = /*#__PURE__*/function
69
73
  });
70
74
  onEscape === null || onEscape === void 0 || onEscape();
71
75
  });
72
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateAltText", function (newAltText) {
73
- var view = _this.props.view;
74
- var newValue = newAltText.length === 0 ? '' : newAltText;
75
- (0, _commands.updateAltText)(newValue)(view.state, view.dispatch);
76
- });
77
76
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleOnChange", function (newAltText) {
78
77
  var _this$state;
79
78
  var validationErrors = _this.getValidationErrors(newAltText);
@@ -91,18 +90,12 @@ var AltTextEditComponent = exports.AltTextEditComponent = /*#__PURE__*/function
91
90
  showClearTextButton: Boolean(newAltText),
92
91
  validationErrors: validationErrors,
93
92
  lastValue: newAltText
94
- }, function () {
95
- if (!validationErrors || !validationErrors.length) {
96
- _this.updateAltText(newAltText);
97
- }
98
93
  });
99
94
  });
100
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleOnBlur", function () {
101
- // Handling the trimming onBlur() because PanelTextInput doesn't sync
102
- // defaultValue properly during unmount
103
- var value = _this.props.value;
104
- var newValue = (_this.state.lastValue || value || '').trim();
105
- _this.handleOnChange(newValue);
95
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleOnBlur", function (e) {
96
+ // prevent other selection transaction gets triggered
97
+ e.stopPropagation();
98
+ _this.closeMediaAltTextMenu();
106
99
  });
107
100
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleClearText", function () {
108
101
  _this.handleOnChange('');
@@ -20,7 +20,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
20
20
  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; }
21
21
  var testId = 'alt-text-edit-button';
22
22
  var altTextButton = exports.altTextButton = function altTextButton(intl, state, editorAnalyticsAPI) {
23
- var mediaNode = (0, _mediaCommon.getMediaNodeFromSelection)(state);
23
+ var mediaNode = (0, _mediaCommon.getMediaSingleOrInlineNodeFromSelection)(state);
24
24
  var message = mediaNode && mediaNode.attrs.alt ? _messages.messages.editAltText : _messages.messages.altText;
25
25
  var title = intl.formatMessage(message);
26
26
  return {
@@ -45,7 +45,8 @@ var altTextEditComponent = exports.altTextEditComponent = function altTextEditCo
45
45
  if (!view) {
46
46
  return null;
47
47
  }
48
- var mediaNode = (0, _mediaCommon.getMediaNodeFromSelection)(view.state);
48
+ var state = view.state;
49
+ var mediaNode = (0, _mediaCommon.getMediaSingleOrInlineNodeFromSelection)(state);
49
50
  if (!mediaNode) {
50
51
  return null;
51
52
  }
@@ -17,6 +17,7 @@ var _mediaUi = require("@atlaskit/media-ui");
17
17
  var _linking = require("../commands/linking");
18
18
  var _linking2 = require("../pm-plugins/linking");
19
19
  var _isType = require("../utils/is-type");
20
+ var _altText = require("./alt-text");
20
21
  var _commands = require("./commands");
21
22
  var _filePreviewItem = require("./filePreviewItem");
22
23
  var _linkingToolbarAppearance = require("./linking-toolbar-appearance");
@@ -24,15 +25,14 @@ var _utils = require("./utils");
24
25
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
26
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
26
27
  var generateMediaInlineFloatingToolbar = exports.generateMediaInlineFloatingToolbar = function generateMediaInlineFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi) {
27
- var _pluginInjectionApi$a, _pluginInjectionApi$w;
28
+ var _pluginInjectionApi$a;
28
29
  var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
29
30
  var editorAnalyticsAPI = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions;
30
- var widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
31
31
  var mediaInline = state.schema.nodes.mediaInline;
32
32
  var mediaType = state.selection instanceof _state2.NodeSelection && state.selection.node.attrs.type;
33
33
  var mediaLinkingState = (0, _linking2.getMediaLinkingState)(state);
34
34
  if (mediaPluginState.allowInlineImages && (0, _isType.isImage)(mediaType)) {
35
- return getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, widthPluginState, pluginInjectionApi, mediaLinkingState);
35
+ return getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, pluginInjectionApi, mediaLinkingState, options);
36
36
  }
37
37
  var items = [{
38
38
  id: 'editor.media.view.switcher',
@@ -105,14 +105,18 @@ var generateMediaInlineFloatingToolbar = exports.generateMediaInlineFloatingTool
105
105
  }];
106
106
  return items;
107
107
  };
108
- var getMediaInlineImageToolbar = exports.getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, widthPluginState, pluginInjectionApi, mediaLinkingState) {
108
+ var getMediaInlineImageToolbar = exports.getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, pluginInjectionApi, mediaLinkingState) {
109
+ var _pluginInjectionApi$w;
110
+ var options = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : {};
109
111
  var mediaInline = state.schema.nodes.mediaInline;
110
112
  var mediaInlineImageTitle = intl.formatMessage(_messages.mediaAndEmbedToolbarMessages.changeToMediaInlineImage);
111
113
  var mediaSingleTitle = intl.formatMessage(_messages.mediaAndEmbedToolbarMessages.changeToMediaSingle);
112
114
 
115
+ // TODO: border marks, media single switcher, alt text, etc
116
+ var widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
113
117
  // if type is image, return inline image floating toolbar items
114
118
  var inlineImageItems = [
115
- // TODO: border marks, media single switcher, alt text, etc
119
+ // TODO: border marks, media single switcher, link, etc
116
120
  {
117
121
  id: 'editor.media.convert.mediainline',
118
122
  type: 'button',
@@ -140,7 +144,14 @@ var getMediaInlineImageToolbar = exports.getMediaInlineImageToolbar = function g
140
144
  onClick: (0, _commands.changeMediaInlineToMediaSingle)(editorAnalyticsAPI, widthPluginState)
141
145
  }, {
142
146
  type: 'separator'
143
- }, {
147
+ }];
148
+ if (options.allowAltTextOnImages) {
149
+ var _pluginInjectionApi$a2;
150
+ inlineImageItems.push((0, _altText.altTextButton)(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.actions), {
151
+ type: 'separator'
152
+ });
153
+ }
154
+ inlineImageItems.push({
144
155
  type: 'custom',
145
156
  fallback: [],
146
157
  render: function render(editorView, idx) {
@@ -154,10 +165,10 @@ var getMediaInlineImageToolbar = exports.getMediaInlineImageToolbar = function g
154
165
  };
155
166
  var openLink = function openLink() {
156
167
  if (editorView) {
157
- var _pluginInjectionApi$a2;
168
+ var _pluginInjectionApi$a3;
158
169
  var tr = editorView.state.tr,
159
170
  dispatch = editorView.dispatch;
160
- pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 || _pluginInjectionApi$a2.actions.attachAnalyticsEvent({
171
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 || _pluginInjectionApi$a3.actions.attachAnalyticsEvent({
161
172
  eventType: _analytics.EVENT_TYPE.TRACK,
162
173
  action: _analytics.ACTION.VISITED,
163
174
  actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
@@ -202,6 +213,6 @@ var getMediaInlineImageToolbar = exports.getMediaInlineImageToolbar = function g
202
213
  title: intl.formatMessage(_messages.default.remove),
203
214
  onClick: _commands.removeInlineCard,
204
215
  testId: 'media-toolbar-remove-button'
205
- }];
216
+ });
206
217
  return inlineImageItems;
207
218
  };
@@ -3,13 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.splitMediaGroup = exports.removeMediaNode = exports.posOfPrecedingMediaGroup = exports.posOfParentMediaGroup = exports.posOfMediaGroupNearby = exports.isSelectionNonMediaBlockNode = exports.isSelectionMediaSingleNode = exports.isMediaBlobUrlFromAttrs = exports.isInsidePotentialEmptyParagraph = exports.getMediaNodeFromSelection = exports.copyOptionalAttrsFromMediaState = void 0;
6
+ exports.splitMediaGroup = exports.removeMediaNode = exports.posOfPrecedingMediaGroup = exports.posOfParentMediaGroup = exports.posOfMediaGroupNearby = exports.isSelectionNonMediaBlockNode = exports.isSelectionMediaSingleNode = exports.isSelectionMediaInlineNode = exports.isMediaSingleOrInlineNodeSelected = exports.isMediaBlobUrlFromAttrs = exports.isInsidePotentialEmptyParagraph = exports.getMediaSingleOrInlineNodeFromSelection = exports.getMediaNodeFromSelection = exports.getMediaInlineNodeFromSelection = exports.copyOptionalAttrsFromMediaState = void 0;
7
7
  var _selection = require("@atlaskit/editor-common/selection");
8
8
  var _utils = require("@atlaskit/editor-common/utils");
9
9
  var _commands = require("@atlaskit/editor-prosemirror/commands");
10
10
  var _state = require("@atlaskit/editor-prosemirror/state");
11
11
  var _utils2 = require("@atlaskit/editor-prosemirror/utils");
12
12
  var _mediaClient = require("@atlaskit/media-client");
13
+ var _main = require("../pm-plugins/main");
13
14
  var isTemporary = function isTemporary(id) {
14
15
  return id.indexOf('temporary:') === 0;
15
16
  };
@@ -29,6 +30,11 @@ var isSelectionMediaSingleNode = exports.isSelectionMediaSingleNode = function i
29
30
  node = _ref2.node;
30
31
  return node && node.type === state.schema.nodes.mediaSingle;
31
32
  };
33
+ var isSelectionMediaInlineNode = exports.isSelectionMediaInlineNode = function isSelectionMediaInlineNode(state) {
34
+ var _ref3 = state.selection,
35
+ node = _ref3.node;
36
+ return node && node.type === state.schema.nodes.mediaInline;
37
+ };
32
38
  var posOfPrecedingMediaGroup = exports.posOfPrecedingMediaGroup = function posOfPrecedingMediaGroup(state) {
33
39
  if (!(0, _selection.atTheBeginningOfBlock)(state)) {
34
40
  return;
@@ -178,4 +184,24 @@ var getMediaNodeFromSelection = exports.getMediaNodeFromSelection = function get
178
184
  return mediaNode;
179
185
  }
180
186
  return null;
187
+ };
188
+ var getMediaInlineNodeFromSelection = exports.getMediaInlineNodeFromSelection = function getMediaInlineNodeFromSelection(state) {
189
+ if (!isSelectionMediaInlineNode(state)) {
190
+ return null;
191
+ }
192
+ var tr = state.tr;
193
+ var pos = tr.selection.from;
194
+ var mediaNode = tr.doc.nodeAt(pos);
195
+ return mediaNode;
196
+ };
197
+ var isMediaSingleOrInlineNodeSelected = exports.isMediaSingleOrInlineNodeSelected = function isMediaSingleOrInlineNodeSelected(state) {
198
+ var _getMediaPluginState = (0, _main.getMediaPluginState)(state),
199
+ allowInlineImages = _getMediaPluginState.allowInlineImages;
200
+ return isSelectionMediaSingleNode(state) || allowInlineImages && isSelectionMediaInlineNode(state);
201
+ };
202
+ var getMediaSingleOrInlineNodeFromSelection = exports.getMediaSingleOrInlineNodeFromSelection = function getMediaSingleOrInlineNodeFromSelection(state) {
203
+ var _getMediaPluginState2 = (0, _main.getMediaPluginState)(state),
204
+ allowInlineImages = _getMediaPluginState2.allowInlineImages;
205
+ var mediaNode = getMediaNodeFromSelection(state) || allowInlineImages && getMediaInlineNodeFromSelection(state);
206
+ return mediaNode || null;
181
207
  };
@@ -1,6 +1,7 @@
1
1
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
2
2
  import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
3
- import { getMediaNodeFromSelection, isSelectionMediaSingleNode } from '../../utils/media-common';
3
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
4
+ import { getMediaSingleOrInlineNodeFromSelection, isMediaSingleOrInlineNodeSelected } from '../../utils/media-common';
4
5
  import { createCommand } from './index';
5
6
  const createCommandWithAnalytics = (actionType, action, transform) => {
6
7
  return editorAnalyticsAPI => withAnalytics(editorAnalyticsAPI, {
@@ -10,33 +11,53 @@ const createCommandWithAnalytics = (actionType, action, transform) => {
10
11
  eventType: EVENT_TYPE.TRACK
11
12
  })(createCommand(action, transform));
12
13
  };
13
- export const closeMediaAltTextMenu = createCommand(state => {
14
- if (isSelectionMediaSingleNode(state)) {
15
- return {
16
- type: 'closeMediaAltTextMenu'
17
- };
18
- }
19
- return false;
20
- });
14
+
15
+ // pass in undefined to close the alt text menu without saving
16
+ export const closeMediaAltTextMenuAndSave = altText => {
17
+ const commandTransform = typeof altText === 'string' ? updateAltTextTransform(altText) : undefined;
18
+ return createCommand(state => {
19
+ if (isMediaSingleOrInlineNodeSelected(state)) {
20
+ return {
21
+ type: 'closeMediaAltTextMenu'
22
+ };
23
+ }
24
+ return false;
25
+ }, commandTransform);
26
+ };
27
+ export const closeMediaAltTextMenu = closeMediaAltTextMenuAndSave();
21
28
  export const openMediaAltTextMenu = createCommandWithAnalytics(ACTION.OPENED, state => {
22
- if (isSelectionMediaSingleNode(state)) {
29
+ if (isMediaSingleOrInlineNodeSelected(state)) {
23
30
  return {
24
31
  type: 'openMediaAltTextMenu'
25
32
  };
26
33
  }
27
34
  return false;
28
35
  }, tr => tr.setMeta('scrollIntoView', false));
29
- export const updateAltText = newAltText => createCommand(state => isSelectionMediaSingleNode(state) ? {
30
- type: 'updateAltText'
31
- } : false, (tr, state) => {
32
- const mediaNode = getMediaNodeFromSelection(state);
33
- const pos = tr.selection.from + 1;
36
+ export const updateAltTextTransform = newAltText => (tr, state) => {
37
+ const mediaNode = getMediaSingleOrInlineNodeFromSelection(state);
34
38
  if (mediaNode) {
35
- tr.setMeta('scrollIntoView', false);
36
- tr.setNodeMarkup(pos, undefined, {
39
+ const pos = mediaNode.type === state.schema.nodes.media ? tr.selection.from + 1 : tr.selection.from;
40
+
41
+ /**
42
+ * Any changes to attributes of a node count the node as "recreated" in Prosemirror[1]
43
+ * This makes it so Prosemirror resets the selection to the child i.e. "media" instead of "media-single"
44
+ * The recommended fix is to reset the selection.[2]
45
+ *
46
+ * [1] https://discuss.prosemirror.net/t/setnodemarkup-loses-current-nodeselection/976
47
+ * [2] https://discuss.prosemirror.net/t/setnodemarkup-and-deselect/3673
48
+ */
49
+ tr.setMeta('scrollIntoView', false).setNodeMarkup(pos, undefined, {
37
50
  ...mediaNode.attrs,
38
51
  alt: newAltText
39
- });
52
+ }).setSelection(NodeSelection.create(tr.doc, pos));
40
53
  }
41
54
  return tr;
42
- });
55
+ };
56
+ export const updateAltText = newAltText => createCommand(state => {
57
+ if (isMediaSingleOrInlineNodeSelected(state)) {
58
+ return {
59
+ type: 'updateAltText'
60
+ };
61
+ }
62
+ return false;
63
+ }, updateAltTextTransform(newAltText));
@@ -7,21 +7,18 @@ import { injectIntl } from 'react-intl-next';
7
7
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
8
8
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, fireAnalyticsEvent } from '@atlaskit/editor-common/analytics';
9
9
  import { escape, ToolTipContent } from '@atlaskit/editor-common/keymaps';
10
- import { PanelTextInput } from '@atlaskit/editor-common/ui';
11
- import { FloatingToolbarButton as Button } from '@atlaskit/editor-common/ui';
12
- import { RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
13
- import { ErrorMessage } from '@atlaskit/editor-common/ui';
10
+ import { FloatingToolbarButton as Button, ErrorMessage, PanelTextInput, RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
14
11
  import { relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles';
15
12
  import ChevronLeftLargeIcon from '@atlaskit/icon/glyph/chevron-left-large';
16
13
  import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
17
- import { N100, N30, N80, R400 } from '@atlaskit/theme/colors';
18
- import { closeMediaAltTextMenu, updateAltText } from '../commands';
14
+ import { N200, N30, N80, R400 } from '@atlaskit/theme/colors';
15
+ import { closeMediaAltTextMenu, closeMediaAltTextMenuAndSave } from '../commands';
19
16
  import { messages } from '../messages';
20
17
  export const CONTAINER_WIDTH_IN_PX = RECENT_SEARCH_WIDTH_IN_PX;
21
18
  export const MAX_ALT_TEXT_LENGTH = 510; // double tweet length
22
19
 
23
20
  const supportText = css`
24
- color: ${`var(--ds-text-subtlest, ${N100})`};
21
+ color: ${`var(--ds-text-subtlest, ${N200})`};
25
22
  font-size: ${relativeFontSizeToBase16(12)};
26
23
  padding: ${"var(--ds-space-150, 12px)"} ${"var(--ds-space-500, 40px)"};
27
24
  line-height: 20px;
@@ -71,7 +68,11 @@ export class AltTextEditComponent extends React.Component {
71
68
  const {
72
69
  view
73
70
  } = this.props;
74
- closeMediaAltTextMenu(view.state, view.dispatch);
71
+ if (this.state.validationErrors.length === 0) {
72
+ closeMediaAltTextMenuAndSave(this.state.lastValue || '')(view.state, view.dispatch);
73
+ } else {
74
+ closeMediaAltTextMenu(view.state, view.dispatch);
75
+ }
75
76
  });
76
77
  _defineProperty(this, "dispatchCancelEvent", event => {
77
78
  const {
@@ -85,13 +86,6 @@ export class AltTextEditComponent extends React.Component {
85
86
  view.someProp('handleKeyDown', fn => fn(view, event));
86
87
  onEscape === null || onEscape === void 0 ? void 0 : onEscape();
87
88
  });
88
- _defineProperty(this, "updateAltText", newAltText => {
89
- const {
90
- view
91
- } = this.props;
92
- const newValue = newAltText.length === 0 ? '' : newAltText;
93
- updateAltText(newValue)(view.state, view.dispatch);
94
- });
95
89
  _defineProperty(this, "handleOnChange", newAltText => {
96
90
  var _this$state, _this$state$validatio;
97
91
  const validationErrors = this.getValidationErrors(newAltText);
@@ -109,20 +103,12 @@ export class AltTextEditComponent extends React.Component {
109
103
  showClearTextButton: Boolean(newAltText),
110
104
  validationErrors,
111
105
  lastValue: newAltText
112
- }, () => {
113
- if (!validationErrors || !validationErrors.length) {
114
- this.updateAltText(newAltText);
115
- }
116
106
  });
117
107
  });
118
- _defineProperty(this, "handleOnBlur", () => {
119
- // Handling the trimming onBlur() because PanelTextInput doesn't sync
120
- // defaultValue properly during unmount
121
- const {
122
- value
123
- } = this.props;
124
- const newValue = (this.state.lastValue || value || '').trim();
125
- this.handleOnChange(newValue);
108
+ _defineProperty(this, "handleOnBlur", e => {
109
+ // prevent other selection transaction gets triggered
110
+ e.stopPropagation();
111
+ this.closeMediaAltTextMenu();
126
112
  });
127
113
  _defineProperty(this, "handleClearText", () => {
128
114
  this.handleOnChange('');
@@ -4,10 +4,10 @@ import { MediaSharedClassNames as ClassNames } from '@atlaskit/editor-common/sty
4
4
  import { openMediaAltTextMenu } from '../pm-plugins/alt-text/commands';
5
5
  import { messages } from '../pm-plugins/alt-text/messages';
6
6
  import AltTextEdit, { CONTAINER_WIDTH_IN_PX } from '../pm-plugins/alt-text/ui/AltTextEdit';
7
- import { getMediaNodeFromSelection } from '../utils/media-common';
7
+ import { getMediaSingleOrInlineNodeFromSelection } from '../utils/media-common';
8
8
  const testId = 'alt-text-edit-button';
9
9
  export const altTextButton = (intl, state, editorAnalyticsAPI) => {
10
- const mediaNode = getMediaNodeFromSelection(state);
10
+ const mediaNode = getMediaSingleOrInlineNodeFromSelection(state);
11
11
  const message = mediaNode && mediaNode.attrs.alt ? messages.editAltText : messages.altText;
12
12
  const title = intl.formatMessage(message);
13
13
  return {
@@ -32,7 +32,8 @@ export const altTextEditComponent = options => {
32
32
  if (!view) {
33
33
  return null;
34
34
  }
35
- const mediaNode = getMediaNodeFromSelection(view.state);
35
+ const state = view.state;
36
+ const mediaNode = getMediaSingleOrInlineNodeFromSelection(state);
36
37
  if (!mediaNode) {
37
38
  return null;
38
39
  }
@@ -9,21 +9,21 @@ import { messages } from '@atlaskit/media-ui';
9
9
  import { showLinkingToolbar } from '../commands/linking';
10
10
  import { getMediaLinkingState } from '../pm-plugins/linking';
11
11
  import { isImage } from '../utils/is-type';
12
+ import { altTextButton } from './alt-text';
12
13
  import { changeInlineToMediaCard, changeMediaInlineToMediaSingle, removeInlineCard } from './commands';
13
14
  import { FilePreviewItem } from './filePreviewItem';
14
15
  import { LinkToolbarAppearance } from './linking-toolbar-appearance';
15
16
  import { downloadMedia } from './utils';
16
17
  export const generateMediaInlineFloatingToolbar = (state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi, options = {}) => {
17
- var _pluginInjectionApi$a, _pluginInjectionApi$w;
18
+ var _pluginInjectionApi$a;
18
19
  const editorAnalyticsAPI = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions;
19
- const widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
20
20
  const {
21
21
  mediaInline
22
22
  } = state.schema.nodes;
23
23
  const mediaType = state.selection instanceof NodeSelection && state.selection.node.attrs.type;
24
24
  const mediaLinkingState = getMediaLinkingState(state);
25
25
  if (mediaPluginState.allowInlineImages && isImage(mediaType)) {
26
- return getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, widthPluginState, pluginInjectionApi, mediaLinkingState);
26
+ return getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, pluginInjectionApi, mediaLinkingState, options);
27
27
  }
28
28
  const items = [{
29
29
  id: 'editor.media.view.switcher',
@@ -96,16 +96,19 @@ export const generateMediaInlineFloatingToolbar = (state, intl, mediaPluginState
96
96
  }];
97
97
  return items;
98
98
  };
99
- export const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, widthPluginState, pluginInjectionApi, mediaLinkingState) => {
99
+ export const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, pluginInjectionApi, mediaLinkingState, options = {}) => {
100
+ var _pluginInjectionApi$w;
100
101
  const {
101
102
  mediaInline
102
103
  } = state.schema.nodes;
103
104
  const mediaInlineImageTitle = intl.formatMessage(mediaAndEmbedToolbarMessages.changeToMediaInlineImage);
104
105
  const mediaSingleTitle = intl.formatMessage(mediaAndEmbedToolbarMessages.changeToMediaSingle);
105
106
 
107
+ // TODO: border marks, media single switcher, alt text, etc
108
+ const widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
106
109
  // if type is image, return inline image floating toolbar items
107
110
  const inlineImageItems = [
108
- // TODO: border marks, media single switcher, alt text, etc
111
+ // TODO: border marks, media single switcher, link, etc
109
112
  {
110
113
  id: 'editor.media.convert.mediainline',
111
114
  type: 'button',
@@ -129,7 +132,14 @@ export const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverD
129
132
  onClick: changeMediaInlineToMediaSingle(editorAnalyticsAPI, widthPluginState)
130
133
  }, {
131
134
  type: 'separator'
132
- }, {
135
+ }];
136
+ if (options.allowAltTextOnImages) {
137
+ var _pluginInjectionApi$a2;
138
+ inlineImageItems.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.actions), {
139
+ type: 'separator'
140
+ });
141
+ }
142
+ inlineImageItems.push({
133
143
  type: 'custom',
134
144
  fallback: [],
135
145
  render: (editorView, idx) => {
@@ -145,14 +155,14 @@ export const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverD
145
155
  };
146
156
  const openLink = () => {
147
157
  if (editorView) {
148
- var _pluginInjectionApi$a2;
158
+ var _pluginInjectionApi$a3;
149
159
  const {
150
160
  state: {
151
161
  tr
152
162
  },
153
163
  dispatch
154
164
  } = editorView;
155
- pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.actions.attachAnalyticsEvent({
165
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 ? void 0 : _pluginInjectionApi$a3.actions.attachAnalyticsEvent({
156
166
  eventType: EVENT_TYPE.TRACK,
157
167
  action: ACTION.VISITED,
158
168
  actionSubject: ACTION_SUBJECT.MEDIA,
@@ -197,6 +207,6 @@ export const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverD
197
207
  title: intl.formatMessage(commonMessages.remove),
198
208
  onClick: removeInlineCard,
199
209
  testId: 'media-toolbar-remove-button'
200
- }];
210
+ });
201
211
  return inlineImageItems;
202
212
  };
@@ -4,6 +4,7 @@ import { deleteSelection, splitBlock } from '@atlaskit/editor-prosemirror/comman
4
4
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
5
5
  import { findPositionOfNodeBefore } from '@atlaskit/editor-prosemirror/utils';
6
6
  import { isMediaBlobUrl } from '@atlaskit/media-client';
7
+ import { getMediaPluginState } from '../pm-plugins/main';
7
8
  const isTemporary = id => {
8
9
  return id.indexOf('temporary:') === 0;
9
10
  };
@@ -25,6 +26,12 @@ export const isSelectionMediaSingleNode = state => {
25
26
  } = state.selection;
26
27
  return node && node.type === state.schema.nodes.mediaSingle;
27
28
  };
29
+ export const isSelectionMediaInlineNode = state => {
30
+ const {
31
+ node
32
+ } = state.selection;
33
+ return node && node.type === state.schema.nodes.mediaInline;
34
+ };
28
35
  export const posOfPrecedingMediaGroup = state => {
29
36
  if (!atTheBeginningOfBlock(state)) {
30
37
  return;
@@ -186,4 +193,26 @@ export const getMediaNodeFromSelection = state => {
186
193
  return mediaNode;
187
194
  }
188
195
  return null;
196
+ };
197
+ export const getMediaInlineNodeFromSelection = state => {
198
+ if (!isSelectionMediaInlineNode(state)) {
199
+ return null;
200
+ }
201
+ const tr = state.tr;
202
+ const pos = tr.selection.from;
203
+ const mediaNode = tr.doc.nodeAt(pos);
204
+ return mediaNode;
205
+ };
206
+ export const isMediaSingleOrInlineNodeSelected = state => {
207
+ const {
208
+ allowInlineImages
209
+ } = getMediaPluginState(state);
210
+ return isSelectionMediaSingleNode(state) || allowInlineImages && isSelectionMediaInlineNode(state);
211
+ };
212
+ export const getMediaSingleOrInlineNodeFromSelection = state => {
213
+ const {
214
+ allowInlineImages
215
+ } = getMediaPluginState(state);
216
+ const mediaNode = getMediaNodeFromSelection(state) || allowInlineImages && getMediaInlineNodeFromSelection(state);
217
+ return mediaNode || null;
189
218
  };
@@ -3,7 +3,8 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
3
3
  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) { _defineProperty(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; }
4
4
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
5
5
  import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
6
- import { getMediaNodeFromSelection, isSelectionMediaSingleNode } from '../../utils/media-common';
6
+ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
7
+ import { getMediaSingleOrInlineNodeFromSelection, isMediaSingleOrInlineNodeSelected } from '../../utils/media-common';
7
8
  import { createCommand } from './index';
8
9
  var createCommandWithAnalytics = function createCommandWithAnalytics(actionType, action, transform) {
9
10
  return function (editorAnalyticsAPI) {
@@ -15,16 +16,22 @@ var createCommandWithAnalytics = function createCommandWithAnalytics(actionType,
15
16
  })(createCommand(action, transform));
16
17
  };
17
18
  };
18
- export var closeMediaAltTextMenu = createCommand(function (state) {
19
- if (isSelectionMediaSingleNode(state)) {
20
- return {
21
- type: 'closeMediaAltTextMenu'
22
- };
23
- }
24
- return false;
25
- });
19
+
20
+ // pass in undefined to close the alt text menu without saving
21
+ export var closeMediaAltTextMenuAndSave = function closeMediaAltTextMenuAndSave(altText) {
22
+ var commandTransform = typeof altText === 'string' ? updateAltTextTransform(altText) : undefined;
23
+ return createCommand(function (state) {
24
+ if (isMediaSingleOrInlineNodeSelected(state)) {
25
+ return {
26
+ type: 'closeMediaAltTextMenu'
27
+ };
28
+ }
29
+ return false;
30
+ }, commandTransform);
31
+ };
32
+ export var closeMediaAltTextMenu = closeMediaAltTextMenuAndSave();
26
33
  export var openMediaAltTextMenu = createCommandWithAnalytics(ACTION.OPENED, function (state) {
27
- if (isSelectionMediaSingleNode(state)) {
34
+ if (isMediaSingleOrInlineNodeSelected(state)) {
28
35
  return {
29
36
  type: 'openMediaAltTextMenu'
30
37
  };
@@ -33,20 +40,34 @@ export var openMediaAltTextMenu = createCommandWithAnalytics(ACTION.OPENED, func
33
40
  }, function (tr) {
34
41
  return tr.setMeta('scrollIntoView', false);
35
42
  });
36
- export var updateAltText = function updateAltText(newAltText) {
37
- return createCommand(function (state) {
38
- return isSelectionMediaSingleNode(state) ? {
39
- type: 'updateAltText'
40
- } : false;
41
- }, function (tr, state) {
42
- var mediaNode = getMediaNodeFromSelection(state);
43
- var pos = tr.selection.from + 1;
43
+ export var updateAltTextTransform = function updateAltTextTransform(newAltText) {
44
+ return function (tr, state) {
45
+ var mediaNode = getMediaSingleOrInlineNodeFromSelection(state);
44
46
  if (mediaNode) {
45
- tr.setMeta('scrollIntoView', false);
46
- tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, mediaNode.attrs), {}, {
47
+ var pos = mediaNode.type === state.schema.nodes.media ? tr.selection.from + 1 : tr.selection.from;
48
+
49
+ /**
50
+ * Any changes to attributes of a node count the node as "recreated" in Prosemirror[1]
51
+ * This makes it so Prosemirror resets the selection to the child i.e. "media" instead of "media-single"
52
+ * The recommended fix is to reset the selection.[2]
53
+ *
54
+ * [1] https://discuss.prosemirror.net/t/setnodemarkup-loses-current-nodeselection/976
55
+ * [2] https://discuss.prosemirror.net/t/setnodemarkup-and-deselect/3673
56
+ */
57
+ tr.setMeta('scrollIntoView', false).setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, mediaNode.attrs), {}, {
47
58
  alt: newAltText
48
- }));
59
+ })).setSelection(NodeSelection.create(tr.doc, pos));
49
60
  }
50
61
  return tr;
51
- });
62
+ };
63
+ };
64
+ export var updateAltText = function updateAltText(newAltText) {
65
+ return createCommand(function (state) {
66
+ if (isMediaSingleOrInlineNodeSelected(state)) {
67
+ return {
68
+ type: 'updateAltText'
69
+ };
70
+ }
71
+ return false;
72
+ }, updateAltTextTransform(newAltText));
52
73
  };
@@ -17,20 +17,17 @@ import { injectIntl } from 'react-intl-next';
17
17
  import { withAnalyticsEvents } from '@atlaskit/analytics-next';
18
18
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, fireAnalyticsEvent } from '@atlaskit/editor-common/analytics';
19
19
  import { escape, ToolTipContent } from '@atlaskit/editor-common/keymaps';
20
- import { PanelTextInput } from '@atlaskit/editor-common/ui';
21
- import { FloatingToolbarButton as Button } from '@atlaskit/editor-common/ui';
22
- import { RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
23
- import { ErrorMessage } from '@atlaskit/editor-common/ui';
20
+ import { FloatingToolbarButton as Button, ErrorMessage, PanelTextInput, RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
24
21
  import { relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles';
25
22
  import ChevronLeftLargeIcon from '@atlaskit/icon/glyph/chevron-left-large';
26
23
  import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
27
- import { N100, N30, N80, R400 } from '@atlaskit/theme/colors';
28
- import { closeMediaAltTextMenu, updateAltText } from '../commands';
24
+ import { N200, N30, N80, R400 } from '@atlaskit/theme/colors';
25
+ import { closeMediaAltTextMenu, closeMediaAltTextMenuAndSave } from '../commands';
29
26
  import { messages } from '../messages';
30
27
  export var CONTAINER_WIDTH_IN_PX = RECENT_SEARCH_WIDTH_IN_PX;
31
28
  export var MAX_ALT_TEXT_LENGTH = 510; // double tweet length
32
29
 
33
- var supportText = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n color: ", ";\n font-size: ", ";\n padding: ", " ", ";\n line-height: 20px;\n border-top: 1px solid ", ";\n margin: 0;\n"])), "var(--ds-text-subtlest, ".concat(N100, ")"), relativeFontSizeToBase16(12), "var(--ds-space-150, 12px)", "var(--ds-space-500, 40px)", "var(--ds-border, ".concat(N30, ")"));
30
+ var supportText = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n color: ", ";\n font-size: ", ";\n padding: ", " ", ";\n line-height: 20px;\n border-top: 1px solid ", ";\n margin: 0;\n"])), "var(--ds-text-subtlest, ".concat(N200, ")"), relativeFontSizeToBase16(12), "var(--ds-space-150, 12px)", "var(--ds-space-500, 40px)", "var(--ds-border, ".concat(N30, ")"));
34
31
  var container = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n width: ", "px;\n display: flex;\n flex-direction: column;\n overflow: auto;\n line-height: 2;\n"])), CONTAINER_WIDTH_IN_PX);
35
32
  var inputWrapper = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n display: flex;\n line-height: 0;\n padding: 5px 0;\n align-items: center;\n"])));
36
33
  var validationWrapper = css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n display: flex;\n line-height: 0;\n padding: ", " ", "\n ", " 0;\n margin: 0 ", " 0 ", ";\n border-top: 1px solid ", ";\n align-items: start;\n flex-direction: column;\n"])), "var(--ds-space-150, 12px)", "var(--ds-space-300, 24px)", "var(--ds-space-150, 12px)", "var(--ds-space-150, 12px)", "var(--ds-space-500, 40px)", "var(--ds-border-danger, ".concat(R400, ")"));
@@ -51,7 +48,11 @@ export var AltTextEditComponent = /*#__PURE__*/function (_React$Component) {
51
48
  });
52
49
  _defineProperty(_assertThisInitialized(_this), "closeMediaAltTextMenu", function () {
53
50
  var view = _this.props.view;
54
- closeMediaAltTextMenu(view.state, view.dispatch);
51
+ if (_this.state.validationErrors.length === 0) {
52
+ closeMediaAltTextMenuAndSave(_this.state.lastValue || '')(view.state, view.dispatch);
53
+ } else {
54
+ closeMediaAltTextMenu(view.state, view.dispatch);
55
+ }
55
56
  });
56
57
  _defineProperty(_assertThisInitialized(_this), "dispatchCancelEvent", function (event) {
57
58
  var _this$props = _this.props,
@@ -66,11 +67,6 @@ export var AltTextEditComponent = /*#__PURE__*/function (_React$Component) {
66
67
  });
67
68
  onEscape === null || onEscape === void 0 || onEscape();
68
69
  });
69
- _defineProperty(_assertThisInitialized(_this), "updateAltText", function (newAltText) {
70
- var view = _this.props.view;
71
- var newValue = newAltText.length === 0 ? '' : newAltText;
72
- updateAltText(newValue)(view.state, view.dispatch);
73
- });
74
70
  _defineProperty(_assertThisInitialized(_this), "handleOnChange", function (newAltText) {
75
71
  var _this$state;
76
72
  var validationErrors = _this.getValidationErrors(newAltText);
@@ -88,18 +84,12 @@ export var AltTextEditComponent = /*#__PURE__*/function (_React$Component) {
88
84
  showClearTextButton: Boolean(newAltText),
89
85
  validationErrors: validationErrors,
90
86
  lastValue: newAltText
91
- }, function () {
92
- if (!validationErrors || !validationErrors.length) {
93
- _this.updateAltText(newAltText);
94
- }
95
87
  });
96
88
  });
97
- _defineProperty(_assertThisInitialized(_this), "handleOnBlur", function () {
98
- // Handling the trimming onBlur() because PanelTextInput doesn't sync
99
- // defaultValue properly during unmount
100
- var value = _this.props.value;
101
- var newValue = (_this.state.lastValue || value || '').trim();
102
- _this.handleOnChange(newValue);
89
+ _defineProperty(_assertThisInitialized(_this), "handleOnBlur", function (e) {
90
+ // prevent other selection transaction gets triggered
91
+ e.stopPropagation();
92
+ _this.closeMediaAltTextMenu();
103
93
  });
104
94
  _defineProperty(_assertThisInitialized(_this), "handleClearText", function () {
105
95
  _this.handleOnChange('');
@@ -7,10 +7,10 @@ import { MediaSharedClassNames as ClassNames } from '@atlaskit/editor-common/sty
7
7
  import { openMediaAltTextMenu } from '../pm-plugins/alt-text/commands';
8
8
  import { messages } from '../pm-plugins/alt-text/messages';
9
9
  import AltTextEdit, { CONTAINER_WIDTH_IN_PX } from '../pm-plugins/alt-text/ui/AltTextEdit';
10
- import { getMediaNodeFromSelection } from '../utils/media-common';
10
+ import { getMediaSingleOrInlineNodeFromSelection } from '../utils/media-common';
11
11
  var testId = 'alt-text-edit-button';
12
12
  export var altTextButton = function altTextButton(intl, state, editorAnalyticsAPI) {
13
- var mediaNode = getMediaNodeFromSelection(state);
13
+ var mediaNode = getMediaSingleOrInlineNodeFromSelection(state);
14
14
  var message = mediaNode && mediaNode.attrs.alt ? messages.editAltText : messages.altText;
15
15
  var title = intl.formatMessage(message);
16
16
  return {
@@ -35,7 +35,8 @@ export var altTextEditComponent = function altTextEditComponent(options) {
35
35
  if (!view) {
36
36
  return null;
37
37
  }
38
- var mediaNode = getMediaNodeFromSelection(view.state);
38
+ var state = view.state;
39
+ var mediaNode = getMediaSingleOrInlineNodeFromSelection(state);
39
40
  if (!mediaNode) {
40
41
  return null;
41
42
  }
@@ -9,20 +9,20 @@ import { messages } from '@atlaskit/media-ui';
9
9
  import { showLinkingToolbar } from '../commands/linking';
10
10
  import { getMediaLinkingState } from '../pm-plugins/linking';
11
11
  import { isImage } from '../utils/is-type';
12
+ import { altTextButton } from './alt-text';
12
13
  import { changeInlineToMediaCard, changeMediaInlineToMediaSingle, removeInlineCard } from './commands';
13
14
  import { FilePreviewItem } from './filePreviewItem';
14
15
  import { LinkToolbarAppearance } from './linking-toolbar-appearance';
15
16
  import { downloadMedia } from './utils';
16
17
  export var generateMediaInlineFloatingToolbar = function generateMediaInlineFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi) {
17
- var _pluginInjectionApi$a, _pluginInjectionApi$w;
18
+ var _pluginInjectionApi$a;
18
19
  var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
19
20
  var editorAnalyticsAPI = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions;
20
- var widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
21
21
  var mediaInline = state.schema.nodes.mediaInline;
22
22
  var mediaType = state.selection instanceof NodeSelection && state.selection.node.attrs.type;
23
23
  var mediaLinkingState = getMediaLinkingState(state);
24
24
  if (mediaPluginState.allowInlineImages && isImage(mediaType)) {
25
- return getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, widthPluginState, pluginInjectionApi, mediaLinkingState);
25
+ return getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, pluginInjectionApi, mediaLinkingState, options);
26
26
  }
27
27
  var items = [{
28
28
  id: 'editor.media.view.switcher',
@@ -95,14 +95,18 @@ export var generateMediaInlineFloatingToolbar = function generateMediaInlineFloa
95
95
  }];
96
96
  return items;
97
97
  };
98
- export var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, widthPluginState, pluginInjectionApi, mediaLinkingState) {
98
+ export var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl, mediaPluginState, hoverDecoration, editorAnalyticsAPI, pluginInjectionApi, mediaLinkingState) {
99
+ var _pluginInjectionApi$w;
100
+ var options = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : {};
99
101
  var mediaInline = state.schema.nodes.mediaInline;
100
102
  var mediaInlineImageTitle = intl.formatMessage(mediaAndEmbedToolbarMessages.changeToMediaInlineImage);
101
103
  var mediaSingleTitle = intl.formatMessage(mediaAndEmbedToolbarMessages.changeToMediaSingle);
102
104
 
105
+ // TODO: border marks, media single switcher, alt text, etc
106
+ var widthPluginState = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$w = pluginInjectionApi.width) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.sharedState.currentState();
103
107
  // if type is image, return inline image floating toolbar items
104
108
  var inlineImageItems = [
105
- // TODO: border marks, media single switcher, alt text, etc
109
+ // TODO: border marks, media single switcher, link, etc
106
110
  {
107
111
  id: 'editor.media.convert.mediainline',
108
112
  type: 'button',
@@ -130,7 +134,14 @@ export var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(stat
130
134
  onClick: changeMediaInlineToMediaSingle(editorAnalyticsAPI, widthPluginState)
131
135
  }, {
132
136
  type: 'separator'
133
- }, {
137
+ }];
138
+ if (options.allowAltTextOnImages) {
139
+ var _pluginInjectionApi$a2;
140
+ inlineImageItems.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.actions), {
141
+ type: 'separator'
142
+ });
143
+ }
144
+ inlineImageItems.push({
134
145
  type: 'custom',
135
146
  fallback: [],
136
147
  render: function render(editorView, idx) {
@@ -144,10 +155,10 @@ export var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(stat
144
155
  };
145
156
  var openLink = function openLink() {
146
157
  if (editorView) {
147
- var _pluginInjectionApi$a2;
158
+ var _pluginInjectionApi$a3;
148
159
  var tr = editorView.state.tr,
149
160
  dispatch = editorView.dispatch;
150
- pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 || _pluginInjectionApi$a2.actions.attachAnalyticsEvent({
161
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 || _pluginInjectionApi$a3.actions.attachAnalyticsEvent({
151
162
  eventType: EVENT_TYPE.TRACK,
152
163
  action: ACTION.VISITED,
153
164
  actionSubject: ACTION_SUBJECT.MEDIA,
@@ -192,6 +203,6 @@ export var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(stat
192
203
  title: intl.formatMessage(commonMessages.remove),
193
204
  onClick: removeInlineCard,
194
205
  testId: 'media-toolbar-remove-button'
195
- }];
206
+ });
196
207
  return inlineImageItems;
197
208
  };
@@ -4,6 +4,7 @@ import { deleteSelection, splitBlock } from '@atlaskit/editor-prosemirror/comman
4
4
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
5
5
  import { findPositionOfNodeBefore } from '@atlaskit/editor-prosemirror/utils';
6
6
  import { isMediaBlobUrl } from '@atlaskit/media-client';
7
+ import { getMediaPluginState } from '../pm-plugins/main';
7
8
  var isTemporary = function isTemporary(id) {
8
9
  return id.indexOf('temporary:') === 0;
9
10
  };
@@ -23,6 +24,11 @@ export var isSelectionMediaSingleNode = function isSelectionMediaSingleNode(stat
23
24
  node = _ref2.node;
24
25
  return node && node.type === state.schema.nodes.mediaSingle;
25
26
  };
27
+ export var isSelectionMediaInlineNode = function isSelectionMediaInlineNode(state) {
28
+ var _ref3 = state.selection,
29
+ node = _ref3.node;
30
+ return node && node.type === state.schema.nodes.mediaInline;
31
+ };
26
32
  export var posOfPrecedingMediaGroup = function posOfPrecedingMediaGroup(state) {
27
33
  if (!atTheBeginningOfBlock(state)) {
28
34
  return;
@@ -172,4 +178,24 @@ export var getMediaNodeFromSelection = function getMediaNodeFromSelection(state)
172
178
  return mediaNode;
173
179
  }
174
180
  return null;
181
+ };
182
+ export var getMediaInlineNodeFromSelection = function getMediaInlineNodeFromSelection(state) {
183
+ if (!isSelectionMediaInlineNode(state)) {
184
+ return null;
185
+ }
186
+ var tr = state.tr;
187
+ var pos = tr.selection.from;
188
+ var mediaNode = tr.doc.nodeAt(pos);
189
+ return mediaNode;
190
+ };
191
+ export var isMediaSingleOrInlineNodeSelected = function isMediaSingleOrInlineNodeSelected(state) {
192
+ var _getMediaPluginState = getMediaPluginState(state),
193
+ allowInlineImages = _getMediaPluginState.allowInlineImages;
194
+ return isSelectionMediaSingleNode(state) || allowInlineImages && isSelectionMediaInlineNode(state);
195
+ };
196
+ export var getMediaSingleOrInlineNodeFromSelection = function getMediaSingleOrInlineNodeFromSelection(state) {
197
+ var _getMediaPluginState2 = getMediaPluginState(state),
198
+ allowInlineImages = _getMediaPluginState2.allowInlineImages;
199
+ var mediaNode = getMediaNodeFromSelection(state) || allowInlineImages && getMediaInlineNodeFromSelection(state);
200
+ return mediaNode || null;
175
201
  };
@@ -1,4 +1,7 @@
1
1
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
2
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ export declare const closeMediaAltTextMenuAndSave: (altText?: string) => import("@atlaskit/editor-common/types").Command;
2
4
  export declare const closeMediaAltTextMenu: import("@atlaskit/editor-common/types").Command;
3
5
  export declare const openMediaAltTextMenu: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => import("@atlaskit/editor-common/types").Command;
6
+ export declare const updateAltTextTransform: (newAltText: string) => (tr: Transaction, state: EditorState) => Transaction;
4
7
  export declare const updateAltText: (newAltText: string) => import("@atlaskit/editor-common/types").Command;
@@ -33,7 +33,6 @@ export declare class AltTextEditComponent extends React.Component<Props, AltText
33
33
  private closeMediaAltTextMenu;
34
34
  private fireAnalytics;
35
35
  private dispatchCancelEvent;
36
- private updateAltText;
37
36
  private handleOnChange;
38
37
  private handleOnBlur;
39
38
  private handleClearText;
@@ -2,11 +2,10 @@ import type { IntlShape } from 'react-intl-next';
2
2
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
3
3
  import type { Command, ExtractInjectionAPI, FloatingToolbarItem } from '@atlaskit/editor-common/types';
4
4
  import type { HoverDecorationHandler } from '@atlaskit/editor-plugin-decorations';
5
- import type { WidthPluginState } from '@atlaskit/editor-plugin-width';
6
5
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
7
6
  import type { MediaNextEditorPluginType } from '../next-plugin-type';
8
7
  import type { MediaLinkingState } from '../pm-plugins/linking';
9
8
  import type { MediaPluginState } from '../pm-plugins/types';
10
9
  import type { MediaFloatingToolbarOptions } from '../types';
11
10
  export declare const generateMediaInlineFloatingToolbar: (state: EditorState, intl: IntlShape, mediaPluginState: MediaPluginState, hoverDecoration: HoverDecorationHandler | undefined, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, options?: MediaFloatingToolbarOptions) => FloatingToolbarItem<Command>[];
12
- export declare const getMediaInlineImageToolbar: (state: EditorState, intl: IntlShape, mediaPluginState: MediaPluginState, hoverDecoration: HoverDecorationHandler | undefined, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, widthPluginState: WidthPluginState | undefined, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, mediaLinkingState: MediaLinkingState) => FloatingToolbarItem<Command>[];
11
+ export declare const getMediaInlineImageToolbar: (state: EditorState, intl: IntlShape, mediaPluginState: MediaPluginState, hoverDecoration: HoverDecorationHandler | undefined, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, mediaLinkingState: MediaLinkingState, options?: MediaFloatingToolbarOptions) => FloatingToolbarItem<Command>[];
@@ -7,6 +7,7 @@ export declare const isMediaBlobUrlFromAttrs: (attrs: MediaADFAttrs) => boolean;
7
7
  export declare const posOfMediaGroupNearby: (state: EditorState) => number | undefined;
8
8
  export declare const isSelectionNonMediaBlockNode: (state: EditorState) => boolean;
9
9
  export declare const isSelectionMediaSingleNode: (state: EditorState) => boolean;
10
+ export declare const isSelectionMediaInlineNode: (state: EditorState) => boolean;
10
11
  export declare const posOfPrecedingMediaGroup: (state: EditorState) => number | undefined;
11
12
  /**
12
13
  * Determine whether the cursor is inside empty paragraph
@@ -18,3 +19,6 @@ export declare const removeMediaNode: (view: EditorView, node: PMNode, getPos: P
18
19
  export declare const splitMediaGroup: (view: EditorView) => boolean;
19
20
  export declare const copyOptionalAttrsFromMediaState: (mediaState: MediaState, node: PMNode) => void;
20
21
  export declare const getMediaNodeFromSelection: (state: EditorState) => PMNode | null;
22
+ export declare const getMediaInlineNodeFromSelection: (state: EditorState) => PMNode | null;
23
+ export declare const isMediaSingleOrInlineNodeSelected: (state: EditorState) => boolean | undefined;
24
+ export declare const getMediaSingleOrInlineNodeFromSelection: (state: EditorState) => PMNode | null;
@@ -1,4 +1,7 @@
1
1
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
2
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ export declare const closeMediaAltTextMenuAndSave: (altText?: string) => import("@atlaskit/editor-common/types").Command;
2
4
  export declare const closeMediaAltTextMenu: import("@atlaskit/editor-common/types").Command;
3
5
  export declare const openMediaAltTextMenu: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => import("@atlaskit/editor-common/types").Command;
6
+ export declare const updateAltTextTransform: (newAltText: string) => (tr: Transaction, state: EditorState) => Transaction;
4
7
  export declare const updateAltText: (newAltText: string) => import("@atlaskit/editor-common/types").Command;
@@ -33,7 +33,6 @@ export declare class AltTextEditComponent extends React.Component<Props, AltText
33
33
  private closeMediaAltTextMenu;
34
34
  private fireAnalytics;
35
35
  private dispatchCancelEvent;
36
- private updateAltText;
37
36
  private handleOnChange;
38
37
  private handleOnBlur;
39
38
  private handleClearText;
@@ -2,11 +2,10 @@ import type { IntlShape } from 'react-intl-next';
2
2
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
3
3
  import type { Command, ExtractInjectionAPI, FloatingToolbarItem } from '@atlaskit/editor-common/types';
4
4
  import type { HoverDecorationHandler } from '@atlaskit/editor-plugin-decorations';
5
- import type { WidthPluginState } from '@atlaskit/editor-plugin-width';
6
5
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
7
6
  import type { MediaNextEditorPluginType } from '../next-plugin-type';
8
7
  import type { MediaLinkingState } from '../pm-plugins/linking';
9
8
  import type { MediaPluginState } from '../pm-plugins/types';
10
9
  import type { MediaFloatingToolbarOptions } from '../types';
11
10
  export declare const generateMediaInlineFloatingToolbar: (state: EditorState, intl: IntlShape, mediaPluginState: MediaPluginState, hoverDecoration: HoverDecorationHandler | undefined, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, options?: MediaFloatingToolbarOptions) => FloatingToolbarItem<Command>[];
12
- export declare const getMediaInlineImageToolbar: (state: EditorState, intl: IntlShape, mediaPluginState: MediaPluginState, hoverDecoration: HoverDecorationHandler | undefined, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, widthPluginState: WidthPluginState | undefined, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, mediaLinkingState: MediaLinkingState) => FloatingToolbarItem<Command>[];
11
+ export declare const getMediaInlineImageToolbar: (state: EditorState, intl: IntlShape, mediaPluginState: MediaPluginState, hoverDecoration: HoverDecorationHandler | undefined, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, mediaLinkingState: MediaLinkingState, options?: MediaFloatingToolbarOptions) => FloatingToolbarItem<Command>[];
@@ -7,6 +7,7 @@ export declare const isMediaBlobUrlFromAttrs: (attrs: MediaADFAttrs) => boolean;
7
7
  export declare const posOfMediaGroupNearby: (state: EditorState) => number | undefined;
8
8
  export declare const isSelectionNonMediaBlockNode: (state: EditorState) => boolean;
9
9
  export declare const isSelectionMediaSingleNode: (state: EditorState) => boolean;
10
+ export declare const isSelectionMediaInlineNode: (state: EditorState) => boolean;
10
11
  export declare const posOfPrecedingMediaGroup: (state: EditorState) => number | undefined;
11
12
  /**
12
13
  * Determine whether the cursor is inside empty paragraph
@@ -18,3 +19,6 @@ export declare const removeMediaNode: (view: EditorView, node: PMNode, getPos: P
18
19
  export declare const splitMediaGroup: (view: EditorView) => boolean;
19
20
  export declare const copyOptionalAttrsFromMediaState: (mediaState: MediaState, node: PMNode) => void;
20
21
  export declare const getMediaNodeFromSelection: (state: EditorState) => PMNode | null;
22
+ export declare const getMediaInlineNodeFromSelection: (state: EditorState) => PMNode | null;
23
+ export declare const isMediaSingleOrInlineNodeSelected: (state: EditorState) => boolean | undefined;
24
+ export declare const getMediaSingleOrInlineNodeFromSelection: (state: EditorState) => PMNode | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -36,8 +36,8 @@
36
36
  "@atlaskit/adf-schema": "^35.2.0",
37
37
  "@atlaskit/analytics-namespaced-context": "^6.7.0",
38
38
  "@atlaskit/analytics-next": "^9.1.0",
39
- "@atlaskit/button": "^17.1.0",
40
- "@atlaskit/editor-common": "^76.29.0",
39
+ "@atlaskit/button": "^17.2.0",
40
+ "@atlaskit/editor-common": "^76.34.0",
41
41
  "@atlaskit/editor-palette": "1.5.2",
42
42
  "@atlaskit/editor-plugin-analytics": "^0.4.0",
43
43
  "@atlaskit/editor-plugin-decorations": "^0.2.0",
@@ -50,7 +50,7 @@
50
50
  "@atlaskit/editor-plugin-selection": "^0.1.0",
51
51
  "@atlaskit/editor-plugin-width": "^0.2.0",
52
52
  "@atlaskit/editor-prosemirror": "1.1.0",
53
- "@atlaskit/editor-shared-styles": "^2.6.0",
53
+ "@atlaskit/editor-shared-styles": "^2.9.0",
54
54
  "@atlaskit/editor-tables": "^2.3.0",
55
55
  "@atlaskit/form": "^9.0.3",
56
56
  "@atlaskit/icon": "^22.0.0",
@@ -65,7 +65,7 @@
65
65
  "@atlaskit/platform-feature-flags": "^0.2.0",
66
66
  "@atlaskit/textfield": "^6.0.0",
67
67
  "@atlaskit/theme": "^12.6.0",
68
- "@atlaskit/tokens": "^1.32.0",
68
+ "@atlaskit/tokens": "^1.33.0",
69
69
  "@atlaskit/tooltip": "^18.1.0",
70
70
  "@babel/runtime": "^7.0.0",
71
71
  "@emotion/react": "^11.7.1",