@atlaskit/editor-plugin-media 2.3.3 → 2.3.5

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,28 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 2.3.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#122997](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/122997)
8
+ [`791cc6fffe214`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/791cc6fffe214) -
9
+ Cleanup FF platform_editor_fix_edit_caption_on_edge
10
+ - [#122924](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/122924)
11
+ [`cf36dece8da78`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cf36dece8da78) -
12
+ [ED-26945] Hide overflow menu when resizing media single
13
+
14
+ ## 2.3.4
15
+
16
+ ### Patch Changes
17
+
18
+ - [#122831](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/122831)
19
+ [`002ac06bd6251`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/002ac06bd6251) -
20
+ [ED-26937] Fix broken typeaheads in inline comment editor
21
+ - [#122309](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/122309)
22
+ [`7042c11d59f4c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7042c11d59f4c) -
23
+ [ux] Add linking buttons to media
24
+ - Updated dependencies
25
+
3
26
  ## 2.3.3
4
27
 
5
28
  ### Patch Changes
@@ -12,7 +12,6 @@ var _react2 = require("@emotion/react");
12
12
  var _reactIntlNext = require("react-intl-next");
13
13
  var _media = require("@atlaskit/editor-common/media");
14
14
  var _mediaSingle = require("@atlaskit/editor-common/media-single");
15
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
15
  var _primitives = require("@atlaskit/primitives");
17
16
  var _colors = require("@atlaskit/theme/colors");
18
17
  var _templateObject;
@@ -42,27 +41,12 @@ var CaptionPlaceholder = exports.CaptionPlaceholder = /*#__PURE__*/_react.defaul
42
41
 
43
42
  // This issue is a temporary fix for users being able to edit captions on edge browsers. This will be removed
44
43
  // replaced with CaptionPlaceholderButton in the near future and this code can be removed.
45
- if ((0, _platformFeatureFlags.fg)('platform_editor_fix_edit_caption_on_edge')) {
46
- return (
47
- // eslint-disable-next-line @atlaskit/design-system/use-primitives-text, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
48
- (0, _react2.jsx)("span", {
49
- ref: ref,
50
- css: placeholder,
51
- onPointerDown: handlePointerDown,
52
- "data-id": _mediaSingle.CAPTION_PLACEHOLDER_ID,
53
- "data-testid": "caption-placeholder"
54
- }, (0, _react2.jsx)(_reactIntlNext.FormattedMessage
55
- // Ignored via go/ees005
56
- // eslint-disable-next-line react/jsx-props-no-spreading
57
- , computedPlaceholderMessage))
58
- );
59
- }
60
44
  return (
61
45
  // eslint-disable-next-line @atlaskit/design-system/use-primitives-text, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
62
46
  (0, _react2.jsx)("span", {
63
47
  ref: ref,
64
48
  css: placeholder,
65
- onClick: onClick,
49
+ onPointerDown: handlePointerDown,
66
50
  "data-id": _mediaSingle.CAPTION_PLACEHOLDER_ID,
67
51
  "data-testid": "caption-placeholder"
68
52
  }, (0, _react2.jsx)(_reactIntlNext.FormattedMessage
@@ -45,7 +45,9 @@ var pixelEntryHiddenSubmit = exports.pixelEntryHiddenSubmit = (0, _react.css)({
45
45
  gridArea: 'submit',
46
46
  visibility: 'hidden',
47
47
  width: 0,
48
- height: 0
48
+ height: 0,
49
+ // this is needed so that this button doesn't contribute to scroll width of media floating toolbar and display scroll buttons unnecessarily
50
+ padding: 0
49
51
  });
50
52
 
51
53
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
@@ -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: [{
@@ -738,12 +747,12 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
738
747
  };
739
748
  items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi);
740
749
  }
741
- if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
750
+ if (!mediaPluginState.isResizing && (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 {
752
+ var lastItem = items.at(-1);
753
+ if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === 'separator') {
754
+ lastItem.fullHeight = true;
755
+ } else if (items.length) {
747
756
  items.push({
748
757
  type: 'separator',
749
758
  fullHeight: true
@@ -752,7 +761,7 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
752
761
  var altTextTitle = intl.formatMessage(_media.altTextMessages.addAltText);
753
762
  items.push({
754
763
  type: 'overflow-dropdown',
755
- options: [{
764
+ options: [].concat((0, _toConsumableArray2.default)((0, _linking3.getLinkingDropdownOptions)(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly)), [{
756
765
  title: altTextTitle,
757
766
  onClick: (0, _commands.openMediaAltTextMenu)(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a10 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a10 === void 0 ? void 0 : _pluginInjectionApi$a10.actions),
758
767
  icon: /*#__PURE__*/_react.default.createElement(_text.default, {
@@ -786,7 +795,7 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(state,
786
795
  icon: /*#__PURE__*/_react.default.createElement(_delete.default, {
787
796
  label: "Delete"
788
797
  })
789
- }]
798
+ }])
790
799
  });
791
800
  }
792
801
 
@@ -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',
@@ -9,7 +9,6 @@ import { css, jsx } from '@emotion/react';
9
9
  import { FormattedMessage } from 'react-intl-next';
10
10
  import { captionMessages as messages } from '@atlaskit/editor-common/media';
11
11
  import { CAPTION_PLACEHOLDER_ID } from '@atlaskit/editor-common/media-single';
12
- import { fg } from '@atlaskit/platform-feature-flags';
13
12
  import { Pressable, Text, xcss } from '@atlaskit/primitives';
14
13
  import { N200 } from '@atlaskit/theme/colors';
15
14
  // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
@@ -38,27 +37,12 @@ export const CaptionPlaceholder = /*#__PURE__*/React.forwardRef(({
38
37
 
39
38
  // This issue is a temporary fix for users being able to edit captions on edge browsers. This will be removed
40
39
  // replaced with CaptionPlaceholderButton in the near future and this code can be removed.
41
- if (fg('platform_editor_fix_edit_caption_on_edge')) {
42
- return (
43
- // eslint-disable-next-line @atlaskit/design-system/use-primitives-text, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
44
- jsx("span", {
45
- ref: ref,
46
- css: placeholder,
47
- onPointerDown: handlePointerDown,
48
- "data-id": CAPTION_PLACEHOLDER_ID,
49
- "data-testid": "caption-placeholder"
50
- }, jsx(FormattedMessage
51
- // Ignored via go/ees005
52
- // eslint-disable-next-line react/jsx-props-no-spreading
53
- , computedPlaceholderMessage))
54
- );
55
- }
56
40
  return (
57
41
  // eslint-disable-next-line @atlaskit/design-system/use-primitives-text, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
58
42
  jsx("span", {
59
43
  ref: ref,
60
44
  css: placeholder,
61
- onClick: onClick,
45
+ onPointerDown: handlePointerDown,
62
46
  "data-id": CAPTION_PLACEHOLDER_ID,
63
47
  "data-testid": "caption-placeholder"
64
48
  }, jsx(FormattedMessage
@@ -50,7 +50,9 @@ export const pixelEntryHiddenSubmit = css({
50
50
  gridArea: 'submit',
51
51
  visibility: 'hidden',
52
52
  width: 0,
53
- height: 0
53
+ height: 0,
54
+ // this is needed so that this button doesn't contribute to scroll width of media floating toolbar and display scroll buttons unnecessarily
55
+ padding: 0
54
56
  });
55
57
 
56
58
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
@@ -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: [{
@@ -738,12 +747,12 @@ export const floatingToolbar = (state, intl, options = {}, pluginInjectionApi) =
738
747
  };
739
748
  items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi);
740
749
  }
741
- if (editorExperiment('platform_editor_controls', 'variant1')) {
750
+ if (!mediaPluginState.isResizing && 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 {
752
+ const lastItem = items.at(-1);
753
+ if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === 'separator') {
754
+ lastItem.fullHeight = true;
755
+ } else if (items.length) {
747
756
  items.push({
748
757
  type: 'separator',
749
758
  fullHeight: true
@@ -752,7 +761,7 @@ export const floatingToolbar = (state, intl, options = {}, pluginInjectionApi) =
752
761
  const altTextTitle = intl.formatMessage(altTextMessages.addAltText);
753
762
  items.push({
754
763
  type: 'overflow-dropdown',
755
- options: [{
764
+ options: [...getLinkingDropdownOptions(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly), {
756
765
  title: altTextTitle,
757
766
  onClick: openMediaAltTextMenu(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a10 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a10 === void 0 ? void 0 : _pluginInjectionApi$a10.actions),
758
767
  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',
@@ -11,7 +11,6 @@ import { css, jsx } from '@emotion/react';
11
11
  import { FormattedMessage } from 'react-intl-next';
12
12
  import { captionMessages as messages } from '@atlaskit/editor-common/media';
13
13
  import { CAPTION_PLACEHOLDER_ID } from '@atlaskit/editor-common/media-single';
14
- import { fg } from '@atlaskit/platform-feature-flags';
15
14
  import { Pressable, Text, xcss } from '@atlaskit/primitives';
16
15
  import { N200 } from '@atlaskit/theme/colors';
17
16
  // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
@@ -33,27 +32,12 @@ export var CaptionPlaceholder = /*#__PURE__*/React.forwardRef(function (_ref, re
33
32
 
34
33
  // This issue is a temporary fix for users being able to edit captions on edge browsers. This will be removed
35
34
  // replaced with CaptionPlaceholderButton in the near future and this code can be removed.
36
- if (fg('platform_editor_fix_edit_caption_on_edge')) {
37
- return (
38
- // eslint-disable-next-line @atlaskit/design-system/use-primitives-text, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
39
- jsx("span", {
40
- ref: ref,
41
- css: placeholder,
42
- onPointerDown: handlePointerDown,
43
- "data-id": CAPTION_PLACEHOLDER_ID,
44
- "data-testid": "caption-placeholder"
45
- }, jsx(FormattedMessage
46
- // Ignored via go/ees005
47
- // eslint-disable-next-line react/jsx-props-no-spreading
48
- , computedPlaceholderMessage))
49
- );
50
- }
51
35
  return (
52
36
  // eslint-disable-next-line @atlaskit/design-system/use-primitives-text, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
53
37
  jsx("span", {
54
38
  ref: ref,
55
39
  css: placeholder,
56
- onClick: onClick,
40
+ onPointerDown: handlePointerDown,
57
41
  "data-id": CAPTION_PLACEHOLDER_ID,
58
42
  "data-testid": "caption-placeholder"
59
43
  }, jsx(FormattedMessage
@@ -39,7 +39,9 @@ export var pixelEntryHiddenSubmit = css({
39
39
  gridArea: 'submit',
40
40
  visibility: 'hidden',
41
41
  width: 0,
42
- height: 0
42
+ height: 0,
43
+ // this is needed so that this button doesn't contribute to scroll width of media floating toolbar and display scroll buttons unnecessarily
44
+ padding: 0
43
45
  });
44
46
 
45
47
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
@@ -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: [{
@@ -728,12 +737,12 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
728
737
  };
729
738
  items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi);
730
739
  }
731
- if (editorExperiment('platform_editor_controls', 'variant1')) {
740
+ if (!mediaPluginState.isResizing && 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 {
742
+ var lastItem = items.at(-1);
743
+ if ((lastItem === null || lastItem === void 0 ? void 0 : lastItem.type) === 'separator') {
744
+ lastItem.fullHeight = true;
745
+ } else if (items.length) {
737
746
  items.push({
738
747
  type: 'separator',
739
748
  fullHeight: true
@@ -742,7 +751,7 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
742
751
  var altTextTitle = intl.formatMessage(altTextMessages.addAltText);
743
752
  items.push({
744
753
  type: 'overflow-dropdown',
745
- options: [{
754
+ options: [].concat(_toConsumableArray(getLinkingDropdownOptions(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly)), [{
746
755
  title: altTextTitle,
747
756
  onClick: openMediaAltTextMenu(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a10 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a10 === void 0 ? void 0 : _pluginInjectionApi$a10.actions),
748
757
  icon: /*#__PURE__*/React.createElement(TextIcon, {
@@ -776,7 +785,7 @@ export var floatingToolbar = function floatingToolbar(state, intl) {
776
785
  icon: /*#__PURE__*/React.createElement(DeleteIcon, {
777
786
  label: "Delete"
778
787
  })
779
- }]
788
+ }])
780
789
  });
781
790
  }
782
791
 
@@ -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.5",
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",