@atlaskit/editor-plugin-media 2.3.3 → 2.3.4

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,17 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 2.3.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#122831](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/122831)
8
+ [`002ac06bd6251`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/002ac06bd6251) -
9
+ [ED-26937] Fix broken typeaheads in inline comment editor
10
+ - [#122309](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/122309)
11
+ [`7042c11d59f4c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7042c11d59f4c) -
12
+ [ux] Add linking buttons to media
13
+ - Updated dependencies
14
+
3
15
  ## 2.3.3
4
16
 
5
17
  ### Patch Changes
@@ -622,6 +622,15 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
622
622
  });
623
623
  }
624
624
  }
625
+
626
+ // open link
627
+ if (allowLinking && (0, _linking3.shouldShowMediaLinkToolbar)(state) && mediaLinkingState && mediaLinkingState.editable) {
628
+ toolbarButtons.push((0, _linking3.getOpenLinkToolbarButtonOption)(intl, mediaLinkingState, pluginInjectionApi), {
629
+ type: 'separator',
630
+ supportsViewMode: true,
631
+ fullHeight: true
632
+ });
633
+ }
625
634
  isViewOnly && toolbarButtons.push({
626
635
  type: 'copy-button',
627
636
  items: [{
@@ -740,19 +749,21 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
740
749
  }
741
750
  if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
742
751
  var _pluginInjectionApi$a10;
743
- if (items[items.length - 1].type === 'separator') {
744
- var separatorItem = items[items.length - 1];
745
- separatorItem.fullHeight = true;
746
- } else {
747
- items.push({
748
- type: 'separator',
749
- fullHeight: true
750
- });
752
+ if (items.length) {
753
+ if (items[items.length - 1].type === 'separator') {
754
+ var separatorItem = items[items.length - 1];
755
+ separatorItem.fullHeight = true;
756
+ } else {
757
+ items.push({
758
+ type: 'separator',
759
+ fullHeight: true
760
+ });
761
+ }
751
762
  }
752
763
  var altTextTitle = intl.formatMessage(_media.altTextMessages.addAltText);
753
764
  items.push({
754
765
  type: 'overflow-dropdown',
755
- options: [{
766
+ options: [].concat((0, _toConsumableArray2.default)((0, _linking3.getLinkingDropdownOptions)(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly)), [{
756
767
  title: altTextTitle,
757
768
  onClick: (0, _commands.openMediaAltTextMenu)(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a10 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a10 === void 0 ? void 0 : _pluginInjectionApi$a10.actions),
758
769
  icon: /*#__PURE__*/_react.default.createElement(_text.default, {
@@ -786,7 +797,7 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
786
797
  icon: /*#__PURE__*/_react.default.createElement(_delete.default, {
787
798
  label: "Delete"
788
799
  })
789
- }]
800
+ }])
790
801
  });
791
802
  }
792
803
 
@@ -4,13 +4,19 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getLinkingToolbar = void 0;
7
+ exports.getOpenLinkToolbarButtonOption = exports.getLinkingToolbar = exports.getLinkingDropdownOptions = void 0;
8
8
  exports.shouldShowMediaLinkToolbar = shouldShowMediaLinkToolbar;
9
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
10
  var _react = _interopRequireDefault(require("react"));
11
+ var _adfSchema = require("@atlaskit/adf-schema");
12
+ var _analytics = require("@atlaskit/editor-common/analytics");
13
+ var _messages = require("@atlaskit/editor-common/messages");
11
14
  var _ui = require("@atlaskit/editor-common/ui");
15
+ var _link = _interopRequireDefault(require("@atlaskit/icon/core/link"));
16
+ var _linkExternal = _interopRequireDefault(require("@atlaskit/icon/core/link-external"));
12
17
  var _linking = require("../../pm-plugins/commands/linking");
13
18
  var _linking2 = require("../../pm-plugins/linking");
19
+ var _currentMediaNode = require("../../pm-plugins/utils/current-media-node");
14
20
  var _MediaLinkingToolbar = _interopRequireDefault(require("../../ui/MediaLinkingToolbar"));
15
21
  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; }
16
22
  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; }
@@ -95,4 +101,87 @@ var getLinkingToolbar = exports.getLinkingToolbar = function getLinkingToolbar(t
95
101
  });
96
102
  }
97
103
  }
104
+ };
105
+ var mediaTypes = ['image', 'video', 'audio', 'doc', 'archive', 'unknown'];
106
+ var getMediaType = function getMediaType(selectedNodeTypeSingle) {
107
+ return mediaTypes.find(function (type) {
108
+ return selectedNodeTypeSingle === null || selectedNodeTypeSingle === void 0 ? void 0 : selectedNodeTypeSingle.includes(type);
109
+ });
110
+ };
111
+ var getLinkingDropdownOptions = exports.getLinkingDropdownOptions = function getLinkingDropdownOptions(editorState, intl, mediaLinkingState, isInlineNode, allowLinking, isViewOnly) {
112
+ if (isViewOnly || !allowLinking || !shouldShowMediaLinkToolbar(editorState)) {
113
+ return [];
114
+ }
115
+ var mediaType;
116
+ var mediaNode = isInlineNode ? (0, _currentMediaNode.currentMediaInlineNode)(editorState) : (0, _currentMediaNode.currentMediaNode)(editorState);
117
+ if (mediaNode) {
118
+ var selectedNodeTypeSingle = mediaNode === null || mediaNode === void 0 ? void 0 : mediaNode.attrs.__fileMimeType;
119
+ mediaType = getMediaType(selectedNodeTypeSingle);
120
+ }
121
+ if (mediaType !== 'external' && mediaType !== 'image') {
122
+ return [];
123
+ }
124
+ if (mediaLinkingState && mediaLinkingState.editable) {
125
+ var title = intl.formatMessage(_messages.linkToolbarMessages.editLink);
126
+ return [{
127
+ title: title,
128
+ onClick: function onClick(editorState, dispatch, editorView) {
129
+ if (editorView) {
130
+ var state = editorView.state,
131
+ _dispatch = editorView.dispatch;
132
+ (0, _linking.showLinkingToolbar)(state, _dispatch);
133
+ }
134
+ return true;
135
+ },
136
+ icon: /*#__PURE__*/_react.default.createElement(_link.default, {
137
+ label: title
138
+ })
139
+ }];
140
+ } else {
141
+ var _title = intl.formatMessage(_messages.linkToolbarMessages.addLink);
142
+ return [{
143
+ title: _title,
144
+ onClick: function onClick(editorState, dispatch, editorView) {
145
+ if (editorView) {
146
+ var state = editorView.state,
147
+ _dispatch2 = editorView.dispatch;
148
+ (0, _linking.showLinkingToolbar)(state, _dispatch2);
149
+ }
150
+ return true;
151
+ },
152
+ icon: /*#__PURE__*/_react.default.createElement(_link.default, {
153
+ label: _title
154
+ })
155
+ }];
156
+ }
157
+ };
158
+ var getOpenLinkToolbarButtonOption = exports.getOpenLinkToolbarButtonOption = function getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi) {
159
+ var isValidUrl = (0, _adfSchema.isSafeUrl)(mediaLinkingState.link);
160
+ var linkTitle = intl.formatMessage(isValidUrl ? _messages.linkMessages.openLink : _messages.linkToolbarMessages.unableToOpenLink);
161
+ return {
162
+ id: 'editor.media.open-link',
163
+ testId: 'open-link-toolbar-button',
164
+ type: 'button',
165
+ icon: _linkExternal.default,
166
+ title: linkTitle,
167
+ target: '_blank',
168
+ href: isValidUrl ? mediaLinkingState.link : undefined,
169
+ disabled: !isValidUrl,
170
+ onClick: function onClick(state, dispatch, editorView) {
171
+ if (editorView) {
172
+ var _pluginInjectionApi$a4;
173
+ var tr = editorView.state.tr,
174
+ _dispatch3 = editorView.dispatch;
175
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 || _pluginInjectionApi$a4.actions.attachAnalyticsEvent({
176
+ eventType: _analytics.EVENT_TYPE.TRACK,
177
+ action: _analytics.ACTION.VISITED,
178
+ actionSubject: _analytics.ACTION_SUBJECT.MEDIA,
179
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.LINK
180
+ })(tr);
181
+ _dispatch3(tr);
182
+ }
183
+ return true;
184
+ },
185
+ supportsViewMode: true
186
+ };
98
187
  };
@@ -29,6 +29,7 @@ var _ImageBorder = _interopRequireDefault(require("../../ui/ImageBorder"));
29
29
  var _altText = require("./alt-text");
30
30
  var _commands = require("./commands");
31
31
  var _imageBorder = require("./imageBorder");
32
+ var _linking3 = require("./linking");
32
33
  var _linkingToolbarAppearance = require("./linking-toolbar-appearance");
33
34
  var _utils = require("./utils");
34
35
  var _index = require("./index");
@@ -322,6 +323,15 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
322
323
  fullHeight: (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')
323
324
  });
324
325
  }
326
+
327
+ // open link
328
+ if (options.allowLinking && (0, _linking3.shouldShowMediaLinkToolbar)(state) && mediaLinkingState && mediaLinkingState.editable && (0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
329
+ inlineImageItems.push((0, _linking3.getOpenLinkToolbarButtonOption)(intl, mediaLinkingState, pluginInjectionApi), {
330
+ type: 'separator',
331
+ supportsViewMode: true,
332
+ fullHeight: true
333
+ });
334
+ }
325
335
  if (options.isViewOnly) {
326
336
  inlineImageItems.push({
327
337
  id: 'editor.media.image.download',
@@ -40,7 +40,7 @@ import { changeMediaCardToInline, changeMediaSingleToMediaInline, setBorderMark,
40
40
  import { commentButton } from './comments';
41
41
  import { shouldShowImageBorder } from './imageBorder';
42
42
  import { LayoutGroup } from './layout-group';
43
- import { getLinkingToolbar, shouldShowMediaLinkToolbar } from './linking';
43
+ import { getLinkingDropdownOptions, getLinkingToolbar, getOpenLinkToolbarButtonOption, shouldShowMediaLinkToolbar } from './linking';
44
44
  import { LinkToolbarAppearance } from './linking-toolbar-appearance';
45
45
  import { generateMediaInlineFloatingToolbar } from './mediaInline';
46
46
  import { calcNewLayout, canShowSwitchButtons, downloadMedia, getMaxToolbarWidth, getPixelWidthOfElement, getSelectedLayoutIcon, getSelectedMediaSingle, getSelectedNearestMediaContainerNodeAttrs, removeMediaGroupNode } from './utils';
@@ -624,6 +624,15 @@ const generateMediaSingleFloatingToolbar = (state, intl, options, pluginState, m
624
624
  });
625
625
  }
626
626
  }
627
+
628
+ // open link
629
+ if (allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable) {
630
+ toolbarButtons.push(getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi), {
631
+ type: 'separator',
632
+ supportsViewMode: true,
633
+ fullHeight: true
634
+ });
635
+ }
627
636
  isViewOnly && toolbarButtons.push({
628
637
  type: 'copy-button',
629
638
  items: [{
@@ -740,19 +749,21 @@ export const floatingToolbar = (state, intl, options = {}, pluginInjectionApi) =
740
749
  }
741
750
  if (editorExperiment('platform_editor_controls', 'variant1')) {
742
751
  var _pluginInjectionApi$a10;
743
- if (items[items.length - 1].type === 'separator') {
744
- const separatorItem = items[items.length - 1];
745
- separatorItem.fullHeight = true;
746
- } else {
747
- items.push({
748
- type: 'separator',
749
- fullHeight: true
750
- });
752
+ if (items.length) {
753
+ if (items[items.length - 1].type === 'separator') {
754
+ const separatorItem = items[items.length - 1];
755
+ separatorItem.fullHeight = true;
756
+ } else {
757
+ items.push({
758
+ type: 'separator',
759
+ fullHeight: true
760
+ });
761
+ }
751
762
  }
752
763
  const altTextTitle = intl.formatMessage(altTextMessages.addAltText);
753
764
  items.push({
754
765
  type: 'overflow-dropdown',
755
- options: [{
766
+ options: [...getLinkingDropdownOptions(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly), {
756
767
  title: altTextTitle,
757
768
  onClick: openMediaAltTextMenu(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a10 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a10 === void 0 ? void 0 : _pluginInjectionApi$a10.actions),
758
769
  icon: /*#__PURE__*/React.createElement(TextIcon, {
@@ -1,7 +1,13 @@
1
1
  import React from 'react';
2
+ import { isSafeUrl } from '@atlaskit/adf-schema';
3
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
4
+ import { linkMessages, linkToolbarMessages } from '@atlaskit/editor-common/messages';
2
5
  import { RECENT_SEARCH_HEIGHT_IN_PX, RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
3
- import { hideLinkingToolbar, setUrlToMedia, unlink } from '../../pm-plugins/commands/linking';
6
+ import LinkIcon from '@atlaskit/icon/core/link';
7
+ import LinkExternalIcon from '@atlaskit/icon/core/link-external';
8
+ import { hideLinkingToolbar, setUrlToMedia, showLinkingToolbar, unlink } from '../../pm-plugins/commands/linking';
4
9
  import { getMediaLinkingState } from '../../pm-plugins/linking';
10
+ import { currentMediaInlineNode, currentMediaNode } from '../../pm-plugins/utils/current-media-node';
5
11
  import MediaLinkingToolbar from '../../ui/MediaLinkingToolbar';
6
12
  const FORCE_FOCUS_SELECTOR = '[data-testid="add-link-button"],[data-testid="edit-link-button"]';
7
13
  export function shouldShowMediaLinkToolbar(editorState) {
@@ -96,4 +102,93 @@ export const getLinkingToolbar = (toolbarBaseConfig, mediaLinkingState, state, i
96
102
  };
97
103
  }
98
104
  }
105
+ };
106
+ const mediaTypes = ['image', 'video', 'audio', 'doc', 'archive', 'unknown'];
107
+ const getMediaType = selectedNodeTypeSingle => {
108
+ return mediaTypes.find(type => selectedNodeTypeSingle === null || selectedNodeTypeSingle === void 0 ? void 0 : selectedNodeTypeSingle.includes(type));
109
+ };
110
+ export const getLinkingDropdownOptions = (editorState, intl, mediaLinkingState, isInlineNode, allowLinking, isViewOnly) => {
111
+ if (isViewOnly || !allowLinking || !shouldShowMediaLinkToolbar(editorState)) {
112
+ return [];
113
+ }
114
+ let mediaType;
115
+ const mediaNode = isInlineNode ? currentMediaInlineNode(editorState) : currentMediaNode(editorState);
116
+ if (mediaNode) {
117
+ const selectedNodeTypeSingle = mediaNode === null || mediaNode === void 0 ? void 0 : mediaNode.attrs.__fileMimeType;
118
+ mediaType = getMediaType(selectedNodeTypeSingle);
119
+ }
120
+ if (mediaType !== 'external' && mediaType !== 'image') {
121
+ return [];
122
+ }
123
+ if (mediaLinkingState && mediaLinkingState.editable) {
124
+ const title = intl.formatMessage(linkToolbarMessages.editLink);
125
+ return [{
126
+ title,
127
+ onClick: (editorState, dispatch, editorView) => {
128
+ if (editorView) {
129
+ const {
130
+ state,
131
+ dispatch
132
+ } = editorView;
133
+ showLinkingToolbar(state, dispatch);
134
+ }
135
+ return true;
136
+ },
137
+ icon: /*#__PURE__*/React.createElement(LinkIcon, {
138
+ label: title
139
+ })
140
+ }];
141
+ } else {
142
+ const title = intl.formatMessage(linkToolbarMessages.addLink);
143
+ return [{
144
+ title,
145
+ onClick: (editorState, dispatch, editorView) => {
146
+ if (editorView) {
147
+ const {
148
+ state,
149
+ dispatch
150
+ } = editorView;
151
+ showLinkingToolbar(state, dispatch);
152
+ }
153
+ return true;
154
+ },
155
+ icon: /*#__PURE__*/React.createElement(LinkIcon, {
156
+ label: title
157
+ })
158
+ }];
159
+ }
160
+ };
161
+ export const getOpenLinkToolbarButtonOption = (intl, mediaLinkingState, pluginInjectionApi) => {
162
+ const isValidUrl = isSafeUrl(mediaLinkingState.link);
163
+ const linkTitle = intl.formatMessage(isValidUrl ? linkMessages.openLink : linkToolbarMessages.unableToOpenLink);
164
+ return {
165
+ id: 'editor.media.open-link',
166
+ testId: 'open-link-toolbar-button',
167
+ type: 'button',
168
+ icon: LinkExternalIcon,
169
+ title: linkTitle,
170
+ target: '_blank',
171
+ href: isValidUrl ? mediaLinkingState.link : undefined,
172
+ disabled: !isValidUrl,
173
+ onClick: (state, dispatch, editorView) => {
174
+ if (editorView) {
175
+ var _pluginInjectionApi$a4;
176
+ const {
177
+ state: {
178
+ tr
179
+ },
180
+ dispatch
181
+ } = editorView;
182
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.actions.attachAnalyticsEvent({
183
+ eventType: EVENT_TYPE.TRACK,
184
+ action: ACTION.VISITED,
185
+ actionSubject: ACTION_SUBJECT.MEDIA,
186
+ actionSubjectId: ACTION_SUBJECT_ID.LINK
187
+ })(tr);
188
+ dispatch(tr);
189
+ }
190
+ return true;
191
+ },
192
+ supportsViewMode: true
193
+ };
99
194
  };
@@ -21,6 +21,7 @@ import ImageBorderItem from '../../ui/ImageBorder';
21
21
  import { altTextButton } from './alt-text';
22
22
  import { changeInlineToMediaCard, changeMediaInlineToMediaSingle, removeInlineCard, setBorderMark, toggleBorderMark } from './commands';
23
23
  import { shouldShowImageBorder } from './imageBorder';
24
+ import { getOpenLinkToolbarButtonOption, shouldShowMediaLinkToolbar } from './linking';
24
25
  import { LinkToolbarAppearance } from './linking-toolbar-appearance';
25
26
  import { downloadMedia } from './utils';
26
27
  import { handleShowMediaViewer } from './index';
@@ -314,6 +315,15 @@ const getMediaInlineImageToolbar = (state, intl, mediaPluginState, hoverDecorati
314
315
  fullHeight: editorExperiment('platform_editor_controls', 'variant1')
315
316
  });
316
317
  }
318
+
319
+ // open link
320
+ if (options.allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable && editorExperiment('platform_editor_controls', 'variant1')) {
321
+ inlineImageItems.push(getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi), {
322
+ type: 'separator',
323
+ supportsViewMode: true,
324
+ fullHeight: true
325
+ });
326
+ }
317
327
  if (options.isViewOnly) {
318
328
  inlineImageItems.push({
319
329
  id: 'editor.media.image.download',
@@ -44,7 +44,7 @@ import { changeMediaCardToInline, changeMediaSingleToMediaInline, setBorderMark,
44
44
  import { commentButton } from './comments';
45
45
  import { shouldShowImageBorder } from './imageBorder';
46
46
  import { LayoutGroup } from './layout-group';
47
- import { getLinkingToolbar, shouldShowMediaLinkToolbar } from './linking';
47
+ import { getLinkingDropdownOptions, getLinkingToolbar, getOpenLinkToolbarButtonOption, shouldShowMediaLinkToolbar } from './linking';
48
48
  import { LinkToolbarAppearance } from './linking-toolbar-appearance';
49
49
  import { generateMediaInlineFloatingToolbar } from './mediaInline';
50
50
  import { calcNewLayout, canShowSwitchButtons, downloadMedia, getMaxToolbarWidth, getPixelWidthOfElement, getSelectedLayoutIcon, getSelectedMediaSingle, getSelectedNearestMediaContainerNodeAttrs, removeMediaGroupNode } from './utils';
@@ -612,6 +612,15 @@ var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToo
612
612
  });
613
613
  }
614
614
  }
615
+
616
+ // open link
617
+ if (allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable) {
618
+ toolbarButtons.push(getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi), {
619
+ type: 'separator',
620
+ supportsViewMode: true,
621
+ fullHeight: true
622
+ });
623
+ }
615
624
  isViewOnly && toolbarButtons.push({
616
625
  type: 'copy-button',
617
626
  items: [{
@@ -730,19 +739,21 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
730
739
  }
731
740
  if (editorExperiment('platform_editor_controls', 'variant1')) {
732
741
  var _pluginInjectionApi$a10;
733
- if (items[items.length - 1].type === 'separator') {
734
- var separatorItem = items[items.length - 1];
735
- separatorItem.fullHeight = true;
736
- } else {
737
- items.push({
738
- type: 'separator',
739
- fullHeight: true
740
- });
742
+ if (items.length) {
743
+ if (items[items.length - 1].type === 'separator') {
744
+ var separatorItem = items[items.length - 1];
745
+ separatorItem.fullHeight = true;
746
+ } else {
747
+ items.push({
748
+ type: 'separator',
749
+ fullHeight: true
750
+ });
751
+ }
741
752
  }
742
753
  var altTextTitle = intl.formatMessage(altTextMessages.addAltText);
743
754
  items.push({
744
755
  type: 'overflow-dropdown',
745
- options: [{
756
+ options: [].concat(_toConsumableArray(getLinkingDropdownOptions(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly)), [{
746
757
  title: altTextTitle,
747
758
  onClick: openMediaAltTextMenu(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a10 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a10 === void 0 ? void 0 : _pluginInjectionApi$a10.actions),
748
759
  icon: /*#__PURE__*/React.createElement(TextIcon, {
@@ -776,7 +787,7 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
776
787
  icon: /*#__PURE__*/React.createElement(DeleteIcon, {
777
788
  label: "Delete"
778
789
  })
779
- }]
790
+ }])
780
791
  });
781
792
  }
782
793
 
@@ -2,9 +2,15 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  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; }
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 React from 'react';
5
+ import { isSafeUrl } from '@atlaskit/adf-schema';
6
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
7
+ import { linkMessages, linkToolbarMessages } from '@atlaskit/editor-common/messages';
5
8
  import { RECENT_SEARCH_HEIGHT_IN_PX, RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
6
- import { hideLinkingToolbar, setUrlToMedia, unlink } from '../../pm-plugins/commands/linking';
9
+ import LinkIcon from '@atlaskit/icon/core/link';
10
+ import LinkExternalIcon from '@atlaskit/icon/core/link-external';
11
+ import { hideLinkingToolbar, setUrlToMedia, showLinkingToolbar, unlink } from '../../pm-plugins/commands/linking';
7
12
  import { getMediaLinkingState } from '../../pm-plugins/linking';
13
+ import { currentMediaInlineNode, currentMediaNode } from '../../pm-plugins/utils/current-media-node';
8
14
  import MediaLinkingToolbar from '../../ui/MediaLinkingToolbar';
9
15
  var FORCE_FOCUS_SELECTOR = '[data-testid="add-link-button"],[data-testid="edit-link-button"]';
10
16
  export function shouldShowMediaLinkToolbar(editorState) {
@@ -87,4 +93,87 @@ export var getLinkingToolbar = function getLinkingToolbar(toolbarBaseConfig, med
87
93
  });
88
94
  }
89
95
  }
96
+ };
97
+ var mediaTypes = ['image', 'video', 'audio', 'doc', 'archive', 'unknown'];
98
+ var getMediaType = function getMediaType(selectedNodeTypeSingle) {
99
+ return mediaTypes.find(function (type) {
100
+ return selectedNodeTypeSingle === null || selectedNodeTypeSingle === void 0 ? void 0 : selectedNodeTypeSingle.includes(type);
101
+ });
102
+ };
103
+ export var getLinkingDropdownOptions = function getLinkingDropdownOptions(editorState, intl, mediaLinkingState, isInlineNode, allowLinking, isViewOnly) {
104
+ if (isViewOnly || !allowLinking || !shouldShowMediaLinkToolbar(editorState)) {
105
+ return [];
106
+ }
107
+ var mediaType;
108
+ var mediaNode = isInlineNode ? currentMediaInlineNode(editorState) : currentMediaNode(editorState);
109
+ if (mediaNode) {
110
+ var selectedNodeTypeSingle = mediaNode === null || mediaNode === void 0 ? void 0 : mediaNode.attrs.__fileMimeType;
111
+ mediaType = getMediaType(selectedNodeTypeSingle);
112
+ }
113
+ if (mediaType !== 'external' && mediaType !== 'image') {
114
+ return [];
115
+ }
116
+ if (mediaLinkingState && mediaLinkingState.editable) {
117
+ var title = intl.formatMessage(linkToolbarMessages.editLink);
118
+ return [{
119
+ title: title,
120
+ onClick: function onClick(editorState, dispatch, editorView) {
121
+ if (editorView) {
122
+ var state = editorView.state,
123
+ _dispatch = editorView.dispatch;
124
+ showLinkingToolbar(state, _dispatch);
125
+ }
126
+ return true;
127
+ },
128
+ icon: /*#__PURE__*/React.createElement(LinkIcon, {
129
+ label: title
130
+ })
131
+ }];
132
+ } else {
133
+ var _title = intl.formatMessage(linkToolbarMessages.addLink);
134
+ return [{
135
+ title: _title,
136
+ onClick: function onClick(editorState, dispatch, editorView) {
137
+ if (editorView) {
138
+ var state = editorView.state,
139
+ _dispatch2 = editorView.dispatch;
140
+ showLinkingToolbar(state, _dispatch2);
141
+ }
142
+ return true;
143
+ },
144
+ icon: /*#__PURE__*/React.createElement(LinkIcon, {
145
+ label: _title
146
+ })
147
+ }];
148
+ }
149
+ };
150
+ export var getOpenLinkToolbarButtonOption = function getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi) {
151
+ var isValidUrl = isSafeUrl(mediaLinkingState.link);
152
+ var linkTitle = intl.formatMessage(isValidUrl ? linkMessages.openLink : linkToolbarMessages.unableToOpenLink);
153
+ return {
154
+ id: 'editor.media.open-link',
155
+ testId: 'open-link-toolbar-button',
156
+ type: 'button',
157
+ icon: LinkExternalIcon,
158
+ title: linkTitle,
159
+ target: '_blank',
160
+ href: isValidUrl ? mediaLinkingState.link : undefined,
161
+ disabled: !isValidUrl,
162
+ onClick: function onClick(state, dispatch, editorView) {
163
+ if (editorView) {
164
+ var _pluginInjectionApi$a4;
165
+ var tr = editorView.state.tr,
166
+ _dispatch3 = editorView.dispatch;
167
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 || _pluginInjectionApi$a4.actions.attachAnalyticsEvent({
168
+ eventType: EVENT_TYPE.TRACK,
169
+ action: ACTION.VISITED,
170
+ actionSubject: ACTION_SUBJECT.MEDIA,
171
+ actionSubjectId: ACTION_SUBJECT_ID.LINK
172
+ })(tr);
173
+ _dispatch3(tr);
174
+ }
175
+ return true;
176
+ },
177
+ supportsViewMode: true
178
+ };
90
179
  };
@@ -21,6 +21,7 @@ import ImageBorderItem from '../../ui/ImageBorder';
21
21
  import { altTextButton } from './alt-text';
22
22
  import { changeInlineToMediaCard, changeMediaInlineToMediaSingle, removeInlineCard, setBorderMark, toggleBorderMark } from './commands';
23
23
  import { shouldShowImageBorder } from './imageBorder';
24
+ import { getOpenLinkToolbarButtonOption, shouldShowMediaLinkToolbar } from './linking';
24
25
  import { LinkToolbarAppearance } from './linking-toolbar-appearance';
25
26
  import { downloadMedia } from './utils';
26
27
  import { handleShowMediaViewer } from './index';
@@ -312,6 +313,15 @@ var getMediaInlineImageToolbar = function getMediaInlineImageToolbar(state, intl
312
313
  fullHeight: editorExperiment('platform_editor_controls', 'variant1')
313
314
  });
314
315
  }
316
+
317
+ // open link
318
+ if (options.allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable && editorExperiment('platform_editor_controls', 'variant1')) {
319
+ inlineImageItems.push(getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi), {
320
+ type: 'separator',
321
+ supportsViewMode: true,
322
+ fullHeight: true
323
+ });
324
+ }
315
325
  if (options.isViewOnly) {
316
326
  inlineImageItems.push({
317
327
  id: 'editor.media.image.download',
@@ -1,9 +1,11 @@
1
1
  import type { IntlShape } from 'react-intl-next';
2
2
  import type { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
3
- import type { ExtractInjectionAPI, FloatingToolbarConfig } from '@atlaskit/editor-common/types';
3
+ import type { Command, ExtractInjectionAPI, FloatingToolbarConfig, FloatingToolbarItem, FloatingToolbarOverflowDropdownOptions } from '@atlaskit/editor-common/types';
4
4
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
5
5
  import type { MediaNextEditorPluginType } from '../../mediaPluginType';
6
6
  import type { MediaLinkingState } from '../../pm-plugins/linking/types';
7
7
  import type { MediaToolbarBaseConfig } from '../../types';
8
8
  export declare function shouldShowMediaLinkToolbar(editorState: EditorState): boolean;
9
9
  export declare const getLinkingToolbar: (toolbarBaseConfig: MediaToolbarBaseConfig, mediaLinkingState: MediaLinkingState, state: EditorState, intl: IntlShape, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, providerFactory?: ProviderFactory) => FloatingToolbarConfig | undefined;
10
+ export declare const getLinkingDropdownOptions: (editorState: EditorState, intl: IntlShape, mediaLinkingState: MediaLinkingState, isInlineNode?: boolean, allowLinking?: boolean, isViewOnly?: boolean) => FloatingToolbarOverflowDropdownOptions<Command>;
11
+ export declare const getOpenLinkToolbarButtonOption: (intl: IntlShape, mediaLinkingState: MediaLinkingState, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined) => FloatingToolbarItem<Command>;
@@ -1,9 +1,11 @@
1
1
  import type { IntlShape } from 'react-intl-next';
2
2
  import type { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
3
- import type { ExtractInjectionAPI, FloatingToolbarConfig } from '@atlaskit/editor-common/types';
3
+ import type { Command, ExtractInjectionAPI, FloatingToolbarConfig, FloatingToolbarItem, FloatingToolbarOverflowDropdownOptions } from '@atlaskit/editor-common/types';
4
4
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
5
5
  import type { MediaNextEditorPluginType } from '../../mediaPluginType';
6
6
  import type { MediaLinkingState } from '../../pm-plugins/linking/types';
7
7
  import type { MediaToolbarBaseConfig } from '../../types';
8
8
  export declare function shouldShowMediaLinkToolbar(editorState: EditorState): boolean;
9
9
  export declare const getLinkingToolbar: (toolbarBaseConfig: MediaToolbarBaseConfig, mediaLinkingState: MediaLinkingState, state: EditorState, intl: IntlShape, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined, providerFactory?: ProviderFactory) => FloatingToolbarConfig | undefined;
10
+ export declare const getLinkingDropdownOptions: (editorState: EditorState, intl: IntlShape, mediaLinkingState: MediaLinkingState, isInlineNode?: boolean, allowLinking?: boolean, isViewOnly?: boolean) => FloatingToolbarOverflowDropdownOptions<Command>;
11
+ export declare const getOpenLinkToolbarButtonOption: (intl: IntlShape, mediaLinkingState: MediaLinkingState, pluginInjectionApi: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined) => FloatingToolbarItem<Command>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -68,7 +68,7 @@
68
68
  "@atlaskit/platform-feature-flags": "^1.1.0",
69
69
  "@atlaskit/primitives": "^14.1.0",
70
70
  "@atlaskit/textfield": "^8.0.0",
71
- "@atlaskit/theme": "^17.0.0",
71
+ "@atlaskit/theme": "^18.0.0",
72
72
  "@atlaskit/tmp-editor-statsig": "^3.4.0",
73
73
  "@atlaskit/tokens": "^4.3.0",
74
74
  "@atlaskit/tooltip": "^20.0.0",