UNPKG

@atlaskit/editor-plugin-media

Version:

Media plugin for @atlaskit/editor-core

933 lines (927 loc) 50.7 kB
import _extends from "@babel/runtime/helpers/extends"; import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; 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; } 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; } import React from 'react'; import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { alignmentIcons, buildLayoutButtons, buildLayoutDropdown, layoutToMessages, wrappingIcons } from '@atlaskit/editor-common/card'; import { withAnalytics } from '@atlaskit/editor-common/editor-analytics'; import { mediaInlineImagesEnabled } from '@atlaskit/editor-common/media-inline'; import commonMessages, { cardMessages, mediaAndEmbedToolbarMessages } from '@atlaskit/editor-common/messages'; import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check'; import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity'; import { NodeSelection } from '@atlaskit/editor-prosemirror/state'; import { contains, findParentNodeOfType, hasParentNodeOfType, removeSelectedNode } from '@atlaskit/editor-prosemirror/utils'; import { akEditorSelectedNodeClassName } from '@atlaskit/editor-shared-styles'; import ImageCropIcon from '@atlaskit/icon-lab/core/image-crop'; import CopyIcon from '@atlaskit/icon/core/copy'; import DeleteIcon from '@atlaskit/icon/core/delete'; import DownloadIcon from '@atlaskit/icon/core/download'; import GrowDiagonalIcon from '@atlaskit/icon/core/grow-diagonal'; import ImageFullscreenIcon from '@atlaskit/icon/core/image-fullscreen'; import ImageInlineIcon from '@atlaskit/icon/core/image-inline'; import MaximizeIcon from '@atlaskit/icon/core/maximize'; import SmartLinkCardIcon from '@atlaskit/icon/core/smart-link-card'; import { mediaFilmstripItemDOMSelector } from '@atlaskit/media-filmstrip'; import { messages } from '@atlaskit/media-ui'; import { fg } from '@atlaskit/platform-feature-flags'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { MediaSingleNodeSelector } from '../../nodeviews/styles'; import { getPluginState as getMediaAltTextPluginState } from '../../pm-plugins/alt-text'; import { showLinkingToolbar } from '../../pm-plugins/commands/linking'; import { getMediaLinkingState } from '../../pm-plugins/linking'; import { getPluginState as getMediaPixelResizingPluginState } from '../../pm-plugins/pixel-resizing'; import { FullWidthDisplay, PixelEntry } from '../../pm-plugins/pixel-resizing/ui'; import { stateKey } from '../../pm-plugins/plugin-key'; import { currentMediaOrInlineNodeBorderMark } from '../../pm-plugins/utils/current-media-node'; import { isVideo } from '../../pm-plugins/utils/media-single'; import ImageBorderItem from '../../ui/ImageBorder'; import { altTextButton, getAltTextDropdownOption, getAltTextToolbar } from './alt-text'; import { changeMediaCardToInline, changeMediaSingleToMediaInline, setBorderMark, toggleBorderMark } from './commands'; import { commentButton } from './comments'; import { shouldShowImageBorder } from './imageBorder'; import { LayoutGroup } from './layout-group'; import { getLinkingDropdownOptions, getLinkingToolbar, getOpenLinkToolbarButtonOption, shouldShowMediaLinkToolbar } from './linking'; import { LinkToolbarAppearance } from './linking-toolbar-appearance'; import { generateMediaInlineFloatingToolbar } from './mediaInline'; import { getPixelResizingToolbar, getResizeDropdownOption } from './pixel-resizing'; import { canShowSwitchButtons, downloadMedia, getIsDownloadDisabledByDataSecurityPolicy, getMaxToolbarWidth, getMediaSingleAndMediaInlineSwitcherDropdown, getSelectedLayoutIcon, getSelectedMediaSingle, getSelectedNearestMediaContainerNodeAttrs, removeMediaGroupNode, updateToFullHeightSeparator } from './utils'; var mediaTypeMessages = { image: messages.file_image_is_selected, video: messages.file_video_is_selected, audio: messages.file_audio_is_selected, doc: messages.file_doc_is_selected, archive: messages.file_archive_is_selected, unknown: messages.file_unknown_is_selected }; var getMediaActionSubject = function getMediaActionSubject(nodeType) { switch (nodeType.name) { case 'mediaSingle': return ACTION_SUBJECT.MEDIA_SINGLE; case 'mediaInline': return ACTION_SUBJECT.MEDIA_INLINE; case 'mediaGroup': return ACTION_SUBJECT.MEDIA_GROUP; default: return ACTION_SUBJECT.MEDIA; } }; var removeWithAnalytics = function removeWithAnalytics(editorAnalyticsApi, nodeType) { if (!nodeType) { return remove; } var mediaType = getMediaActionSubject(nodeType); return withAnalytics(editorAnalyticsApi, { action: ACTION.DELETED, actionSubject: mediaType, attributes: { inputMethod: INPUT_METHOD.FLOATING_TB }, eventType: EVENT_TYPE.TRACK })(remove); }; var remove = function remove(state, dispatch) { if (dispatch) { dispatch(removeSelectedNode(state.tr)); } return true; }; var handleRemoveMediaGroupWithAnalytics = function handleRemoveMediaGroupWithAnalytics(editorAnalyticsApi) { return withAnalytics(editorAnalyticsApi, { action: ACTION.DELETED, actionSubject: ACTION_SUBJECT.MEDIA_GROUP, attributes: { inputMethod: INPUT_METHOD.FLOATING_TB }, eventType: EVENT_TYPE.TRACK })(handleRemoveMediaGroup); }; var handleRemoveMediaGroup = function handleRemoveMediaGroup(state, dispatch) { var tr = removeMediaGroupNode(state); if (dispatch) { dispatch(tr); } return true; }; export var handleShowMediaViewer = function handleShowMediaViewer(_ref) { var api = _ref.api, mediaPluginState = _ref.mediaPluginState; var selectedNodeAttrs = getSelectedNearestMediaContainerNodeAttrs(mediaPluginState); if (!selectedNodeAttrs) { return false; } api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 ? void 0 : api.media.commands.showMediaViewer(selectedNodeAttrs)); }; export var handleShowImageEditor = function handleShowImageEditor(_ref2) { var _api$mediaEditing; var api = _ref2.api, mediaPluginState = _ref2.mediaPluginState; var selectedNodeAttrs = getSelectedNearestMediaContainerNodeAttrs(mediaPluginState); if (!selectedNodeAttrs) { return false; } api === null || api === void 0 || api.core.actions.execute(api === null || api === void 0 || (_api$mediaEditing = api.mediaEditing) === null || _api$mediaEditing === void 0 ? void 0 : _api$mediaEditing.commands.showImageEditor(selectedNodeAttrs)); }; var generateMediaCardFloatingToolbar = function generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi, editorAnalyticsAPI, forceFocusSelector, isViewOnly) { var _pluginInjectionApi$c; var disableDownloadButton = getIsDownloadDisabledByDataSecurityPolicy(mediaPluginState); var areAnyNewToolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar)); var preview = { id: 'editor.media.viewer', testId: 'file-preview-toolbar-button', type: 'button', icon: areAnyNewToolbarFlagsEnabled ? GrowDiagonalIcon : MaximizeIcon, title: intl.formatMessage(messages.preview), onClick: function onClick() { var _handleShowMediaViewe; return (_handleShowMediaViewe = handleShowMediaViewer({ mediaPluginState: mediaPluginState, api: pluginInjectionApi })) !== null && _handleShowMediaViewe !== void 0 ? _handleShowMediaViewe : false; }, disabled: isOfflineMode(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.connectivity) === null || _pluginInjectionApi$c === void 0 || (_pluginInjectionApi$c = _pluginInjectionApi$c.sharedState) === null || _pluginInjectionApi$c === void 0 || (_pluginInjectionApi$c = _pluginInjectionApi$c.currentState()) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.mode), supportsViewMode: true }; var download = _objectSpread({ id: 'editor.media.card.download', type: 'button', icon: DownloadIcon, onClick: function onClick() { downloadMedia(mediaPluginState); return true; }, title: intl.formatMessage(messages.download), disabled: disableDownloadButton }, areAnyNewToolbarFlagsEnabled && { supportsViewMode: true }); if (isViewOnly && !areAnyNewToolbarFlagsEnabled) { return []; } var mediaGroup = state.schema.nodes.mediaGroup; var items = []; if (!areAnyNewToolbarFlagsEnabled) { items.push({ id: 'editor.media.view.switcher.inline', type: 'button', icon: ImageInlineIcon, selected: false, focusEditoronEnter: true, disabled: false, onClick: changeMediaCardToInline(editorAnalyticsAPI, forceFocusSelector), title: intl.formatMessage(cardMessages.inlineTitle), testId: 'inline-appearance', className: 'inline-appearance' // a11y. uses to force focus on item }, { id: 'editor.media.view.switcher.thumbnail', type: 'button', icon: SmartLinkCardIcon, selected: true, disabled: false, focusEditoronEnter: true, onClick: function onClick() { return true; }, title: intl.formatMessage(cardMessages.blockTitle), testId: 'thumbnail-appearance', className: 'thumbnail-appearance' // a11y. uses to force focus on item }, { type: 'separator' }, preview, { type: 'separator' }, download, { type: 'separator' }, { type: 'copy-button', supportsViewMode: true, items: [{ state: state, formatMessage: intl.formatMessage, nodeType: mediaGroup }] }, { type: 'separator' }, { id: 'editor.media.delete', type: 'button', appearance: 'danger', focusEditoronEnter: true, icon: DeleteIcon, onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaGroup, true), onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaGroup, false), onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaGroup, true), onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaGroup, false), title: intl.formatMessage(commonMessages.remove), onClick: handleRemoveMediaGroupWithAnalytics(editorAnalyticsAPI), testId: 'media-toolbar-remove-button' }); } else { var options = [{ id: 'editor.media.view.switcher.inline', title: intl.formatMessage(cardMessages.inlineTitle), onClick: changeMediaCardToInline(editorAnalyticsAPI, forceFocusSelector), icon: /*#__PURE__*/React.createElement(ImageInlineIcon, { label: "", spacing: "spacious" }) }, { id: 'editor.media.view.switcher.thumbnail', title: intl.formatMessage(cardMessages.blockTitle), selected: true, onClick: function onClick() { return true; }, icon: /*#__PURE__*/React.createElement(SmartLinkCardIcon, { label: "", spacing: "spacious" }) }]; var switcherDropdown = { title: intl.formatMessage(messages.fileDisplayOptions), id: 'media-group-inline-switcher-toolbar-item', testId: 'media-group-inline-switcher-dropdown', type: 'dropdown', options: options, icon: function icon() { return /*#__PURE__*/React.createElement(SmartLinkCardIcon, { label: "", spacing: "spacious" }); } }; items.push(switcherDropdown, { type: 'separator', fullHeight: true }, download, { type: 'separator', supportsViewMode: true }, preview, { type: 'separator', fullHeight: true }); } return items; }; var generateMediaSingleFloatingToolbar = function generateMediaSingleFloatingToolbar(state, intl, options, pluginState, mediaLinkingState, pluginInjectionApi) { var _pluginInjectionApi$d, _pluginInjectionApi$d2; var mediaSingle = state.schema.nodes.mediaSingle; var allowResizing = options.allowResizing, allowLinking = options.allowLinking, allowAdvancedToolBarOptions = options.allowAdvancedToolBarOptions, allowCommentsOnMedia = options.allowCommentsOnMedia, allowResizingInTables = options.allowResizingInTables, allowAltTextOnImages = options.allowAltTextOnImages, allowMediaInline = options.allowMediaInline, allowMediaInlineImages = options.allowMediaInlineImages, allowImageEditing = options.allowImageEditing, allowImagePreview = options.allowImagePreview, isViewOnly = options.isViewOnly, allowPixelResizing = options.allowPixelResizing, onCommentButtonMount = options.onCommentButtonMount, createCommentExperience = options.createCommentExperience; var toolbarButtons = []; var _ref3 = (_pluginInjectionApi$d = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$d2 = pluginInjectionApi.decorations) === null || _pluginInjectionApi$d2 === void 0 ? void 0 : _pluginInjectionApi$d2.actions) !== null && _pluginInjectionApi$d !== void 0 ? _pluginInjectionApi$d : {}, hoverDecoration = _ref3.hoverDecoration; var areAnyNewToolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar)); var disableDownloadButton = getIsDownloadDisabledByDataSecurityPolicy(pluginState); if (shouldShowImageBorder(state)) { toolbarButtons.push({ type: 'custom', fallback: [], render: function render(editorView) { if (!editorView) { return null; } var dispatch = editorView.dispatch, state = editorView.state; var borderMark = currentMediaOrInlineNodeBorderMark(state); return /*#__PURE__*/React.createElement(ImageBorderItem // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , { toggleBorder: function toggleBorder() { var _pluginInjectionApi$a; toggleBorderMark(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions)(state, dispatch); } // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , setBorder: function setBorder(attrs) { var _pluginInjectionApi$a2; setBorderMark(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.actions)(attrs)(state, dispatch); }, borderMark: borderMark, intl: intl }); } }); if (!areAnyNewToolbarFlagsEnabled) { toolbarButtons.push({ type: 'separator' }); } } if (allowAdvancedToolBarOptions) { var _pluginInjectionApi$a3; var widthPlugin = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.width; var isChangingLayoutDisabled = false; var selectedNode = getSelectedMediaSingle(state); if (allowPixelResizing) { var _widthPlugin$sharedSt; var contentWidth = widthPlugin === null || widthPlugin === void 0 || (_widthPlugin$sharedSt = widthPlugin.sharedState.currentState()) === null || _widthPlugin$sharedSt === void 0 ? void 0 : _widthPlugin$sharedSt.lineLength; var selectedNodeMaxWidth = pluginState.currentMaxWidth || contentWidth; if (selectedNode && selectedNodeMaxWidth && selectedNode.node.attrs.width >= selectedNodeMaxWidth) { isChangingLayoutDisabled = true; } } var layoutButtons = buildLayoutButtons(state, intl, state.schema.nodes.mediaSingle, widthPlugin, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 ? void 0 : _pluginInjectionApi$a3.actions, allowResizing, allowResizingInTables, true, true, isChangingLayoutDisabled, allowPixelResizing); var addLayoutDropdownToToolbar = function addLayoutDropdownToToolbar() { if (areAnyNewToolbarFlagsEnabled) { var _pluginInjectionApi$a4; var layoutDropdown = buildLayoutDropdown(state, intl, state.schema.nodes.mediaSingle, widthPlugin, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.actions, allowResizing, allowResizingInTables, true, true, isChangingLayoutDisabled, allowPixelResizing); toolbarButtons = [].concat(_toConsumableArray(toolbarButtons), _toConsumableArray(layoutDropdown)); } else { var selectedLayoutIcon = getSelectedLayoutIcon([].concat(_toConsumableArray(alignmentIcons), _toConsumableArray(wrappingIcons)), // eslint-disable-next-line @typescript-eslint/no-non-null-assertion selectedNode.node); if (selectedLayoutIcon && layoutButtons.length) { var _options = { render: function render(props) { return /*#__PURE__*/React.createElement(LayoutGroup, _extends({ layoutButtons: layoutButtons // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading }, props, { areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled })); }, width: 188, height: 32 }; var trigger = { id: 'media-single-layout', testId: 'media-single-layout-dropdown-trigger', type: 'dropdown', options: _options, title: intl.formatMessage(layoutToMessages[selectedLayoutIcon.value]), icon: selectedLayoutIcon.icon }; toolbarButtons = [].concat(_toConsumableArray(toolbarButtons), [trigger], _toConsumableArray(areAnyNewToolbarFlagsEnabled ? [] : [{ type: 'separator' }])); } } }; if (fg('platform_editor_remove_media_inline_feature_flag')) { if (allowMediaInlineImages && selectedNode) { addLayoutDropdownToToolbar(); } else { toolbarButtons = [].concat(_toConsumableArray(toolbarButtons), _toConsumableArray(layoutButtons)); if (layoutButtons.length) { toolbarButtons.push({ type: 'separator' }); } } } else { if (mediaInlineImagesEnabled(allowMediaInline, allowMediaInlineImages) && selectedNode) { addLayoutDropdownToToolbar(); } else { toolbarButtons = [].concat(_toConsumableArray(toolbarButtons), _toConsumableArray(layoutButtons)); if (layoutButtons.length && !areAnyNewToolbarFlagsEnabled) { toolbarButtons.push({ type: 'separator' }); } } } // floating and inline switcher if (pluginState.allowInlineImages && selectedNode && canShowSwitchButtons(selectedNode.node)) { var _selectedNode$node$fi; // mediaInlne doesn't suppprt external images, so hiding buttons to prevent conversion from mediaSingle to mediaInline if (((_selectedNode$node$fi = selectedNode.node.firstChild) === null || _selectedNode$node$fi === void 0 ? void 0 : _selectedNode$node$fi.attrs.type) !== 'external') { var hasCaption = contains(selectedNode.node, state.schema.nodes.caption); var inlineSwitcherTitle = intl.formatMessage(hasCaption ? mediaAndEmbedToolbarMessages.changeToMediaInlineImageCaptionWarning : mediaAndEmbedToolbarMessages.changeToMediaInlineImage); var floatingSwitcherTitle = intl.formatMessage(mediaAndEmbedToolbarMessages.changeToMediaSingle); if (!areAnyNewToolbarFlagsEnabled) { var _pluginInjectionApi$a5; toolbarButtons.push({ type: 'button', id: 'editor.media.image.view.switcher.inline', title: inlineSwitcherTitle, icon: function icon() { return /*#__PURE__*/React.createElement(ImageInlineIcon, { color: "currentColor", spacing: "spacious", label: inlineSwitcherTitle }); }, onClick: changeMediaSingleToMediaInline(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a5 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a5 === void 0 ? void 0 : _pluginInjectionApi$a5.actions), testId: 'image-inline-appearance', selected: false }, { type: 'button', id: 'editor.media.image.view.switcher.floating', title: floatingSwitcherTitle, icon: function icon() { return /*#__PURE__*/React.createElement(ImageFullscreenIcon, { color: "currentColor", spacing: "spacious", label: floatingSwitcherTitle }); }, onClick: function onClick() { return true; }, testId: 'image-floating-appearance', selected: true }, { type: 'separator' }); } else { var switchFromBlockToInline = getMediaSingleAndMediaInlineSwitcherDropdown('block', intl, pluginInjectionApi, hasCaption); toolbarButtons.push(switchFromBlockToInline, { type: 'separator', fullHeight: true }); } } } // A separator is needed regardless switcher is enabled or not if (Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar)) { toolbarButtons.push({ type: 'separator', fullHeight: true }); } // Pixel Entry Toolbar Support var selection = state.selection; var isWithinTable = hasParentNodeOfType([state.schema.nodes.table])(selection); if (allowResizing && (!isWithinTable || allowResizingInTables === true) && allowPixelResizing) { var selectedMediaSingleNode = getSelectedMediaSingle(state); var sizeInput = { type: 'custom', fallback: [], render: function render(editorView) { if (!editorView || !selectedMediaSingleNode) { return null; } return /*#__PURE__*/React.createElement(PixelEntry, { editorView: editorView, intl: intl, selectedMediaSingleNode: selectedMediaSingleNode, pluginInjectionApi: pluginInjectionApi, pluginState: pluginState, hoverDecoration: hoverDecoration, isEditorFullWidthEnabled: options.fullWidthEnabled }); } }; if (pluginState.isResizing) { // If the image is resizing // then return pixel entry component or full width label as the only toolbar item if (!selectedMediaSingleNode) { return []; } var layout = selectedMediaSingleNode.node.attrs.layout; if (layout === 'full-width') { var fullWidthLabel = { type: 'custom', fallback: [], render: function render() { return /*#__PURE__*/React.createElement(FullWidthDisplay, { intl: intl }); } }; return [fullWidthLabel]; } return [sizeInput]; } if (!areAnyNewToolbarFlagsEnabled) { toolbarButtons.push(sizeInput); toolbarButtons.push({ type: 'separator' }); } } if (!areAnyNewToolbarFlagsEnabled) { if (allowCommentsOnMedia) { toolbarButtons.push(commentButton(intl, state, pluginInjectionApi, onCommentButtonMount, createCommentExperience), { type: 'separator', supportsViewMode: true }); } if (allowLinking && shouldShowMediaLinkToolbar(state)) { toolbarButtons.push({ type: 'custom', fallback: [], render: function render(editorView, idx) { if (editorView !== null && editorView !== void 0 && editorView.state) { var editLink = function editLink() { if (editorView) { var _state = editorView.state, dispatch = editorView.dispatch; showLinkingToolbar(_state, dispatch); } }; var openLink = function openLink() { if (editorView) { var _pluginInjectionApi$a6; var tr = editorView.state.tr, dispatch = editorView.dispatch; pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a6 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a6 === void 0 || _pluginInjectionApi$a6.actions.attachAnalyticsEvent({ eventType: EVENT_TYPE.TRACK, action: ACTION.VISITED, actionSubject: ACTION_SUBJECT.MEDIA, actionSubjectId: ACTION_SUBJECT_ID.LINK })(tr); dispatch(tr); return true; } }; return /*#__PURE__*/React.createElement(LinkToolbarAppearance, { key: idx, editorState: editorView.state, intl: intl, mediaLinkingState: mediaLinkingState, onAddLink: editLink, onEditLink: editLink, onOpenLink: openLink, isViewOnly: isViewOnly, areAnyNewToolbarFlagsEnabled: false }); } return null; }, supportsViewMode: true }); } // Image Editing Support if (!!(pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.mediaEditing) && allowImageEditing && expValEquals('platform_editor_add_image_editing', 'isEnabled', true)) { var _mediaNode$attrs, _mediaNode$attrs2, _mediaNode$attrs3; var _selectedMediaSingleNode = getSelectedMediaSingle(state); var mediaNode = _selectedMediaSingleNode === null || _selectedMediaSingleNode === void 0 ? void 0 : _selectedMediaSingleNode.node.content.firstChild; // Disable image editing for external media, as we cannot save changes to external images per CORS policy var isExternal = (mediaNode === null || mediaNode === void 0 || (_mediaNode$attrs = mediaNode.attrs) === null || _mediaNode$attrs === void 0 ? void 0 : _mediaNode$attrs.type) === 'external'; // Disable image editing for gifs as CropperJS does not support gif editing var isGif = (mediaNode === null || mediaNode === void 0 || (_mediaNode$attrs2 = mediaNode.attrs) === null || _mediaNode$attrs2 === void 0 ? void 0 : _mediaNode$attrs2.__fileMimeType) === 'image/gif'; if (!isVideo(mediaNode === null || mediaNode === void 0 || (_mediaNode$attrs3 = mediaNode.attrs) === null || _mediaNode$attrs3 === void 0 ? void 0 : _mediaNode$attrs3.__fileMimeType) && !isExternal && !isGif) { toolbarButtons.push({ id: 'editor.media.edit', testId: 'image-edit-toolbar-button', type: 'button', icon: ImageCropIcon, title: intl.formatMessage(commonMessages.imageEdit), onClick: function onClick() { var _handleShowImageEdito; return (_handleShowImageEdito = handleShowImageEditor({ api: pluginInjectionApi, mediaPluginState: pluginState })) !== null && _handleShowImageEdito !== void 0 ? _handleShowImageEdito : false; }, // Making the button more accessible supportsViewMode: false, isRadioButton: true, selected: false }); } } // Preview Support if (allowImagePreview) { var _mediaNode$attrs4; var _selectedMediaSingleNode2 = getSelectedMediaSingle(state); var _mediaNode = _selectedMediaSingleNode2 === null || _selectedMediaSingleNode2 === void 0 ? void 0 : _selectedMediaSingleNode2.node.content.firstChild; if (!isVideo(_mediaNode === null || _mediaNode === void 0 || (_mediaNode$attrs4 = _mediaNode.attrs) === null || _mediaNode$attrs4 === void 0 ? void 0 : _mediaNode$attrs4.__fileMimeType)) { var _pluginInjectionApi$c2; toolbarButtons.push({ id: 'editor.media.viewer', testId: 'file-preview-toolbar-button', type: 'button', icon: MaximizeIcon, title: intl.formatMessage(messages.preview), onClick: function onClick() { var _handleShowMediaViewe2; return (_handleShowMediaViewe2 = handleShowMediaViewer({ api: pluginInjectionApi, mediaPluginState: pluginState })) !== null && _handleShowMediaViewe2 !== void 0 ? _handleShowMediaViewe2 : false; }, disabled: isOfflineMode(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c2 = pluginInjectionApi.connectivity) === null || _pluginInjectionApi$c2 === void 0 || (_pluginInjectionApi$c2 = _pluginInjectionApi$c2.sharedState) === null || _pluginInjectionApi$c2 === void 0 || (_pluginInjectionApi$c2 = _pluginInjectionApi$c2.currentState()) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.mode), supportsViewMode: true }, { type: 'separator', supportsViewMode: true }); } } } } if (isViewOnly) { toolbarButtons.push({ id: 'editor.media.image.download', type: 'button', icon: DownloadIcon, onClick: function onClick() { downloadMedia(pluginState, isViewOnly); return true; }, disabled: disableDownloadButton, title: intl.formatMessage(messages.download), supportsViewMode: true }, { type: 'separator', supportsViewMode: true }); } if (!areAnyNewToolbarFlagsEnabled) { var _pluginInjectionApi$a8; if (allowAltTextOnImages) { var _pluginInjectionApi$a7; toolbarButtons.push(altTextButton(intl, state, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a7 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a7 === void 0 ? void 0 : _pluginInjectionApi$a7.actions), { type: 'separator' }); } var removeButton = { id: 'editor.media.delete', type: 'button', appearance: 'danger', focusEditoronEnter: true, icon: DeleteIcon, onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, true), onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, false), onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, true), onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, false), title: intl.formatMessage(commonMessages.remove), onClick: removeWithAnalytics(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a8 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a8 === void 0 ? void 0 : _pluginInjectionApi$a8.actions), testId: 'media-toolbar-remove-button', supportsViewMode: false }; var items = [].concat(_toConsumableArray(toolbarButtons), [{ type: 'copy-button', items: [{ state: state, formatMessage: intl.formatMessage, nodeType: mediaSingle }], supportsViewMode: true }]); items.push({ type: 'separator', supportsViewMode: false }); items.push(removeButton); return items; } else { // Preview Support if (allowAdvancedToolBarOptions && allowImagePreview) { var _mediaNode2$attrs; var _selectedMediaSingleNode3 = getSelectedMediaSingle(state); var _mediaNode2 = _selectedMediaSingleNode3 === null || _selectedMediaSingleNode3 === void 0 ? void 0 : _selectedMediaSingleNode3.node.content.firstChild; if (!isVideo(_mediaNode2 === null || _mediaNode2 === void 0 || (_mediaNode2$attrs = _mediaNode2.attrs) === null || _mediaNode2$attrs === void 0 ? void 0 : _mediaNode2$attrs.__fileMimeType)) { var _pluginInjectionApi$c3; toolbarButtons.push({ id: 'editor.media.viewer', testId: 'file-preview-toolbar-button', type: 'button', icon: GrowDiagonalIcon, title: intl.formatMessage(messages.preview), onClick: function onClick() { var _handleShowMediaViewe3; return (_handleShowMediaViewe3 = handleShowMediaViewer({ api: pluginInjectionApi, mediaPluginState: pluginState })) !== null && _handleShowMediaViewe3 !== void 0 ? _handleShowMediaViewe3 : false; }, disabled: isOfflineMode(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c3 = pluginInjectionApi.connectivity) === null || _pluginInjectionApi$c3 === void 0 || (_pluginInjectionApi$c3 = _pluginInjectionApi$c3.sharedState) === null || _pluginInjectionApi$c3 === void 0 || (_pluginInjectionApi$c3 = _pluginInjectionApi$c3.currentState()) === null || _pluginInjectionApi$c3 === void 0 ? void 0 : _pluginInjectionApi$c3.mode), supportsViewMode: true }, { type: 'separator', supportsViewMode: true }); } } if (allowAdvancedToolBarOptions && allowImageEditing && expValEquals('platform_editor_add_image_editing', 'isEnabled', true)) { var _mediaNode3$attrs, _mediaNode3$attrs2, _mediaNode3$attrs3; var _selectedMediaSingleNode4 = getSelectedMediaSingle(state); var _mediaNode3 = _selectedMediaSingleNode4 === null || _selectedMediaSingleNode4 === void 0 ? void 0 : _selectedMediaSingleNode4.node.content.firstChild; // Disable image editing for external media, as we cannot save changes to external images per CORS policy var _isExternal = (_mediaNode3 === null || _mediaNode3 === void 0 || (_mediaNode3$attrs = _mediaNode3.attrs) === null || _mediaNode3$attrs === void 0 ? void 0 : _mediaNode3$attrs.type) === 'external'; // Disable image editing for gifs as CropperJS does not support gif editing var _isGif = (_mediaNode3 === null || _mediaNode3 === void 0 || (_mediaNode3$attrs2 = _mediaNode3.attrs) === null || _mediaNode3$attrs2 === void 0 ? void 0 : _mediaNode3$attrs2.__fileMimeType) === 'image/gif'; if (!isVideo(_mediaNode3 === null || _mediaNode3 === void 0 || (_mediaNode3$attrs3 = _mediaNode3.attrs) === null || _mediaNode3$attrs3 === void 0 ? void 0 : _mediaNode3$attrs3.__fileMimeType) && !_isExternal && !_isGif) { toolbarButtons.push({ id: 'editor.media.edit', testId: 'image-edit-toolbar-button', type: 'button', icon: ImageCropIcon, title: intl.formatMessage(commonMessages.imageEdit), onClick: function onClick() { var _handleShowImageEdito2; return (_handleShowImageEdito2 = handleShowImageEditor({ api: pluginInjectionApi, mediaPluginState: pluginState })) !== null && _handleShowImageEdito2 !== void 0 ? _handleShowImageEdito2 : false; }, supportsViewMode: false }, { type: 'separator', supportsViewMode: false }); } } // open link if (allowLinking && shouldShowMediaLinkToolbar(state) && mediaLinkingState && mediaLinkingState.editable) { toolbarButtons.push(getOpenLinkToolbarButtonOption(intl, mediaLinkingState, pluginInjectionApi), { type: 'separator', supportsViewMode: true }); } isViewOnly && toolbarButtons.push({ type: 'copy-button', items: [{ state: state, formatMessage: intl.formatMessage, nodeType: mediaSingle }], supportsViewMode: true }, { type: 'separator', supportsViewMode: true }); if (allowAdvancedToolBarOptions && allowCommentsOnMedia) { updateToFullHeightSeparator(toolbarButtons); toolbarButtons.push(commentButton(intl, state, pluginInjectionApi, onCommentButtonMount, createCommentExperience)); } return toolbarButtons; } }; var getMediaTypeMessage = function getMediaTypeMessage(selectedNodeTypeSingle) { var mediaType = Object.keys(mediaTypeMessages).find(function (key) { return selectedNodeTypeSingle === null || selectedNodeTypeSingle === void 0 ? void 0 : selectedNodeTypeSingle.includes(key); }); return mediaType ? mediaTypeMessages[mediaType] : messages.file_unknown_is_selected; }; export var overflowDropdwonBtnTriggerTestId = 'media-overflow-dropdown-trigger'; var isMediaSelection = function isMediaSelection(selection, nodeType) { if (selection instanceof NodeSelection) { return nodeType.includes(selection.node.type); } return false; }; export var floatingToolbar = function floatingToolbar(state, intl) { var _pluginInjectionApi$d3, _pluginInjectionApi$d4; var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var pluginInjectionApi = arguments.length > 3 ? arguments[3] : undefined; var _state$schema$nodes = state.schema.nodes, media = _state$schema$nodes.media, mediaInline = _state$schema$nodes.mediaInline, mediaSingle = _state$schema$nodes.mediaSingle, mediaGroup = _state$schema$nodes.mediaGroup; var altTextValidator = options.altTextValidator, allowLinking = options.allowLinking, allowAltTextOnImages = options.allowAltTextOnImages, providerFactory = options.providerFactory, allowMediaInlineImages = options.allowMediaInlineImages, allowResizing = options.allowResizing, isViewOnly = options.isViewOnly, allowResizingInTables = options.allowResizingInTables, allowAdvancedToolBarOptions = options.allowAdvancedToolBarOptions, allowPixelResizing = options.allowPixelResizing; var allowMediaInline = options.allowMediaInline; allowMediaInline = fg('platform_editor_remove_media_inline_feature_flag') ? allowMediaInlineImages : allowMediaInline; var mediaPluginState = stateKey.getState(state); var mediaLinkingState = getMediaLinkingState(state); var _ref4 = (_pluginInjectionApi$d3 = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$d4 = pluginInjectionApi.decorations) === null || _pluginInjectionApi$d4 === void 0 ? void 0 : _pluginInjectionApi$d4.actions) !== null && _pluginInjectionApi$d3 !== void 0 ? _pluginInjectionApi$d3 : {}, hoverDecoration = _ref4.hoverDecoration; if (!mediaPluginState) { return; } var nodeType = allowMediaInline ? [mediaInline, mediaSingle, media] : [mediaSingle]; var isSelectedNodeMediaSingle = state.selection instanceof NodeSelection && state.selection.node.type === mediaSingle; if (!isMediaSelection(state.selection, nodeType)) { return; } var baseToolbar = { title: 'Media floating controls', nodeType: nodeType, getDomRef: function getDomRef() { var _mediaPluginState$ele; var element = isSelectedNodeMediaSingle ? ((_mediaPluginState$ele = mediaPluginState.element) === null || _mediaPluginState$ele === void 0 ? void 0 : _mediaPluginState$ele.querySelector(".".concat(MediaSingleNodeSelector))) || mediaPluginState.element : mediaPluginState.element; return element; } }; if (allowLinking && mediaLinkingState && mediaLinkingState.visible && shouldShowMediaLinkToolbar(state)) { var linkingToolbar = getLinkingToolbar(baseToolbar, mediaLinkingState, state, intl, pluginInjectionApi, providerFactory); if (linkingToolbar) { return linkingToolbar; } } // testId is required to show focus on trigger button on ESC key press // see hideOnEsc in platform/packages/editor/editor-plugin-floating-toolbar/src/ui/Dropdown.tsx var overflowButtonSelector = areToolbarFlagsEnabled(Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar)) ? "[data-testid=\"".concat(overflowDropdwonBtnTriggerTestId, "\"]") : undefined; if (allowAltTextOnImages) { var mediaAltTextPluginState = getMediaAltTextPluginState(state); if (mediaAltTextPluginState.isAltTextEditorOpen) { var _pluginInjectionApi$f; return getAltTextToolbar(baseToolbar, { altTextValidator: altTextValidator, forceFocusSelector: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f === void 0 || (_pluginInjectionApi$f = _pluginInjectionApi$f.actions) === null || _pluginInjectionApi$f === void 0 ? void 0 : _pluginInjectionApi$f.forceFocusSelector, triggerButtonSelector: overflowButtonSelector, areAnyNewToolbarFlagsEnabled: areToolbarFlagsEnabled(Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar)) }); } } var selection = state.selection; var isWithinTable = hasParentNodeOfType([state.schema.nodes.table])(selection); if (allowAdvancedToolBarOptions && allowResizing && (!isWithinTable || allowResizingInTables === true) && allowPixelResizing && areToolbarFlagsEnabled(Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar))) { var mediaPixelResizingPluginState = getMediaPixelResizingPluginState(state); if (mediaPixelResizingPluginState !== null && mediaPixelResizingPluginState !== void 0 && mediaPixelResizingPluginState.isPixelEditorOpen) { return getPixelResizingToolbar(baseToolbar, { intl: intl, pluginInjectionApi: pluginInjectionApi, pluginState: mediaPluginState, hoverDecoration: hoverDecoration, isEditorFullWidthEnabled: options.fullWidthEnabled, triggerButtonSelector: overflowButtonSelector }); } } var items = []; var parentMediaGroupNode = findParentNodeOfType(mediaGroup)(state.selection); var selectedNodeType; if (state.selection instanceof NodeSelection) { selectedNodeType = state.selection.node.type; } if (allowMediaInline && (parentMediaGroupNode === null || parentMediaGroupNode === void 0 ? void 0 : parentMediaGroupNode.node.type) === mediaGroup) { var _pluginInjectionApi$a9, _pluginInjectionApi$f2; var mediaOffset = state.selection.$from.parentOffset + 1; baseToolbar.getDomRef = function () { var _mediaPluginState$ele2; var selector = mediaFilmstripItemDOMSelector(mediaOffset); // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting return (_mediaPluginState$ele2 = mediaPluginState.element) === null || _mediaPluginState$ele2 === void 0 ? void 0 : _mediaPluginState$ele2.querySelector(selector); }; items = generateMediaCardFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a9 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a9 === void 0 ? void 0 : _pluginInjectionApi$a9.actions, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f2 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f2 === void 0 || (_pluginInjectionApi$f2 = _pluginInjectionApi$f2.actions) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.forceFocusSelector, isViewOnly); } else if (allowMediaInline && selectedNodeType && selectedNodeType === mediaInline) { items = generateMediaInlineFloatingToolbar(state, intl, mediaPluginState, hoverDecoration, pluginInjectionApi, options); } else { baseToolbar.getDomRef = function () { var _mediaPluginState$ele3; // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting var element = (_mediaPluginState$ele3 = mediaPluginState.element) === null || _mediaPluginState$ele3 === void 0 ? void 0 : _mediaPluginState$ele3.querySelector(".".concat(MediaSingleNodeSelector)); return element || mediaPluginState.element; }; items = generateMediaSingleFloatingToolbar(state, intl, options, mediaPluginState, mediaLinkingState, pluginInjectionApi); } if (!mediaPluginState.isResizing && areToolbarFlagsEnabled(Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar))) { var _pluginInjectionApi$a0, _pluginInjectionApi$a1, _pluginInjectionApi$a10; updateToFullHeightSeparator(items); var customOptions = [].concat(_toConsumableArray(getLinkingDropdownOptions(state, intl, mediaLinkingState, allowMediaInline && selectedNodeType && selectedNodeType === mediaInline, allowLinking, isViewOnly)), _toConsumableArray(getAltTextDropdownOption(state, intl.formatMessage, allowAltTextOnImages, selectedNodeType, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a0 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a0 === void 0 ? void 0 : _pluginInjectionApi$a0.actions)), _toConsumableArray(getResizeDropdownOption(options, state, intl.formatMessage, selectedNodeType))); if (customOptions.length) { customOptions.push({ type: 'separator' }); } var hoverDecorationProps = function hoverDecorationProps(nodeType, className) { return { onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, true, className), onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, false, className), onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, true, className), onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(nodeType, false, className) }; }; items.push({ type: 'overflow-dropdown', id: 'media', testId: overflowDropdwonBtnTriggerTestId, options: [].concat(_toConsumableArray(customOptions), [_objectSpread({ title: intl === null || intl === void 0 ? void 0 : intl.formatMessage(commonMessages.copyToClipboard), onClick: function onClick() { var _pluginInjectionApi$c4, _pluginInjectionApi$f3; pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c4 = pluginInjectionApi.core) === null || _pluginInjectionApi$c4 === void 0 || _pluginInjectionApi$c4.actions.execute( // @ts-ignore pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f3 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f3 === void 0 ? void 0 : _pluginInjectionApi$f3.commands.copyNode(nodeType, INPUT_METHOD.FLOATING_TB)); return true; }, icon: /*#__PURE__*/React.createElement(CopyIcon, { label: "" }) }, hoverDecorationProps(nodeType, akEditorSelectedNodeClassName)), _objectSpread({ title: intl === null || intl === void 0 ? void 0 : intl.formatMessage(commonMessages.delete), onClick: (parentMediaGroupNode === null || parentMediaGroupNode === void 0 ? void 0 : parentMediaGroupNode.node.type) === mediaGroup ? handleRemoveMediaGroupWithAnalytics(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a1 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a1 === void 0 ? void 0 : _pluginInjectionApi$a1.actions) : removeWithAnalytics(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a10 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a10 === void 0 ? void 0 : _pluginInjectionApi$a10.actions, selectedNodeType), icon: /*#__PURE__*/React.createElement(DeleteIcon, { label: "" }) }, hoverDecorationProps(nodeType))]) }); } // Ignored via go/ees005 // eslint-disable-next-line no-var var assistiveMessage = ''; var selectedMediaSingleNode = getSelectedMediaSingle(state); if (selectedMediaSingleNode) { var selectedMediaNodeView = selectedMediaSingleNode === null || selectedMediaSingleNode === void 0 ? void 0 : selectedMediaSingleNode.node.content; if (selectedMediaNodeView) { var selectedMediaNode = selectedMediaNodeView.firstChild; var selectedNodeTypeSingle = selectedMediaNode === null || selectedMediaNode === void 0 ? void 0 : selectedMediaNode.attrs.__fileMi