@atlaskit/editor-plugin-media
Version:
Media plugin for @atlaskit/editor-core
240 lines (239 loc) • 9.41 kB
JavaScript
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 { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
import { createToggleBlockMarkOnRange, createToggleInlineMarkOnRange } from '@atlaskit/editor-common/commands';
import { normalizeUrl } from '@atlaskit/editor-common/utils';
import { createMediaLinkingCommand, getMediaLinkingState, mediaLinkingPluginKey } from '../linking';
import { MediaLinkingActionsTypes } from '../linking/actions';
import { getMediaPluginState } from '../main';
import { checkMediaType } from '../utils/check-media-type';
import { currentMediaInlineNode, currentMediaNode } from '../utils/current-media-node';
export var showLinkingToolbar = createMediaLinkingCommand(function (state) {
var mediaLinkingState = getMediaLinkingState(state);
if (mediaLinkingState && mediaLinkingState.mediaPos !== null) {
var node = state.doc.nodeAt(mediaLinkingState.mediaPos);
if (node) {
return {
type: MediaLinkingActionsTypes.showToolbar
};
}
}
return false;
});
export var showLinkingToolbarWithMediaTypeCheck = function showLinkingToolbarWithMediaTypeCheck(editorState, dispatch, editorView) {
if (dispatch && editorView) {
var mediaNode = currentMediaNode(editorState);
var mediaInlineNode = currentMediaInlineNode(editorState);
var nodeSelection = editorState.selection;
var currentSelectedNode = nodeSelection.node;
if (!mediaNode && !mediaInlineNode) {
return false;
}
var _getMediaPluginState = getMediaPluginState(editorState),
mediaClientConfig = _getMediaPluginState.mediaClientConfig;
if (!mediaClientConfig) {
return false;
}
if (mediaNode && currentSelectedNode !== mediaInlineNode) {
checkMediaType(mediaNode, mediaClientConfig).then(function (mediaType) {
if ((mediaType === 'external' || mediaType === 'image') &&
// We make sure the selection and the node hasn't changed.
currentMediaNode(editorView.state) === mediaNode) {
dispatch(editorView.state.tr.setMeta(mediaLinkingPluginKey, {
type: MediaLinkingActionsTypes.showToolbar
}));
}
});
}
if (mediaInlineNode) {
checkMediaType(mediaInlineNode, mediaClientConfig).then(function (mediaType) {
if ((mediaType === 'external' || mediaType === 'image') &&
// We make sure the selection and the node hasn't changed.
currentMediaInlineNode(editorView.state) === mediaInlineNode) {
dispatch(editorView.state.tr.setMeta(mediaLinkingPluginKey, {
type: MediaLinkingActionsTypes.showToolbar
}));
}
});
}
}
return true;
};
var hideLinkingToolbarCommand = createMediaLinkingCommand({
type: MediaLinkingActionsTypes.hideToolbar
});
export var hideLinkingToolbar = function hideLinkingToolbar(state, dispatch, view, focusFloatingToolbar) {
hideLinkingToolbarCommand(state, dispatch, view);
// restore focus on the editor so keyboard shortcuts aren't lost to the browser
if (view && !focusFloatingToolbar) {
view.focus();
}
};
function getCurrentUrl(state) {
var linkType = state.schema.marks.link;
var mediaLinkingState = getMediaLinkingState(state);
if (!mediaLinkingState || mediaLinkingState.mediaPos === null) {
return;
}
var $pos = state.doc.resolve(mediaLinkingState.mediaPos);
var node = state.doc.nodeAt($pos.pos);
if (!node) {
return;
}
var hasLink = linkType.isInSet(node.marks);
if (!hasLink) {
return;
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
var link = node.marks.find(function (mark) {
return mark.type === linkType;
}); // Already check exist
var url = link.attrs.href;
return url;
}
function toggleLinkMark(tr, state, _ref) {
var _ref$forceRemove = _ref.forceRemove,
forceRemove = _ref$forceRemove === void 0 ? false : _ref$forceRemove,
url = _ref.url;
var mediaLinkingState = getMediaLinkingState(state);
if (!mediaLinkingState || mediaLinkingState.mediaPos === null) {
return tr;
}
var $pos = state.doc.resolve(mediaLinkingState.mediaPos);
var node = state.doc.nodeAt($pos.pos);
if (!node) {
return tr;
}
var linkMark = state.schema.marks.link;
var _state$schema$nodes = state.schema.nodes,
media = _state$schema$nodes.media,
mediaInline = _state$schema$nodes.mediaInline;
if (node.type !== mediaInline) {
var toggleBlockLinkMark = createToggleBlockMarkOnRange(linkMark, function (prevAttrs, node) {
// Only add mark to media
if (!node || node.type !== media) {
return; //No op
}
if (forceRemove) {
return false;
}
var href = normalizeUrl(url);
if (prevAttrs && prevAttrs.href === href) {
return; //No op
}
if (href.trim() === '') {
return false; // remove
}
return _objectSpread(_objectSpread({}, prevAttrs), {}, {
href: href
});
}, [media]);
toggleBlockLinkMark($pos.pos, $pos.pos + node.nodeSize, tr, state);
}
var toggleInlineLinkMark = createToggleInlineMarkOnRange(linkMark, function (prevAttrs, node) {
// Only add mark to mediaInline
if (!node || node.type !== mediaInline) {
return; //No op
}
if (forceRemove) {
return false;
}
var href = normalizeUrl(url);
if (prevAttrs && prevAttrs.href === href) {
return; //No op
}
if (href.trim() === '') {
return false; // remove
}
return _objectSpread(_objectSpread({}, prevAttrs), {}, {
href: href
});
});
toggleInlineLinkMark($pos.pos, $pos.pos + node.nodeSize, tr, state);
return tr;
}
var fireAnalyticForMediaLink = function fireAnalyticForMediaLink(tr, action) {
var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
var editorAnalyticsAPI = arguments.length > 3 ? arguments[3] : undefined;
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
action: action,
eventType: EVENT_TYPE.TRACK,
actionSubject: ACTION_SUBJECT.MEDIA,
actionSubjectId: ACTION_SUBJECT_ID.LINK,
attributes: attributes
})(tr);
return tr;
};
export var unlink = function unlink(editorAnalyticsAPI) {
return createMediaLinkingCommand({
type: MediaLinkingActionsTypes.unlink
}, function (tr, state) {
var transaction = toggleLinkMark(tr, state, {
forceRemove: true
});
return fireAnalyticForMediaLink(transaction, ACTION.DELETED, _objectSpread({}, getNodeTypeAndMediaTypeAttributes(state)), editorAnalyticsAPI);
});
};
var getAction = function getAction(newUrl, state) {
var currentUrl = getCurrentUrl(state);
if (!currentUrl) {
return ACTION.ADDED;
} else if (newUrl !== currentUrl) {
return ACTION.EDITED;
}
return undefined;
};
var getNodeTypeAndMediaTypeAttributes = function getNodeTypeAndMediaTypeAttributes(state) {
var mediaLinkingState = getMediaLinkingState(state);
var _getMediaPluginState2 = getMediaPluginState(state),
allowInlineImages = _getMediaPluginState2.allowInlineImages;
var _state$schema$nodes2 = state.schema.nodes,
mediaInline = _state$schema$nodes2.mediaInline,
mediaSingle = _state$schema$nodes2.mediaSingle;
if (!mediaLinkingState || mediaLinkingState.mediaPos === null) {
return;
}
var $pos = state.doc.resolve(mediaLinkingState.mediaPos);
var node = state.doc.nodeAt($pos.pos);
if (!node) {
return {};
}
if (allowInlineImages && node.type === mediaInline) {
return {
type: mediaInline.name,
mediaType: node.attrs.type
};
}
return {
type: mediaSingle.name,
mediaType: node.attrs.type
};
};
export var setUrlToMedia = function setUrlToMedia(url, inputMethod, editorAnalyticsAPI) {
return createMediaLinkingCommand({
type: MediaLinkingActionsTypes.setUrl,
payload: normalizeUrl(url)
}, function (tr, state) {
var action = getAction(url, state);
if (!action) {
return tr;
}
var nodeTypeAndMediaTypeAttrs = getNodeTypeAndMediaTypeAttributes(state);
try {
var toggleLinkMarkResult = toggleLinkMark(tr, state, {
url: url
});
fireAnalyticForMediaLink(tr, action, action === ACTION.ADDED ? _objectSpread({
inputMethod: inputMethod
}, nodeTypeAndMediaTypeAttrs) : nodeTypeAndMediaTypeAttrs, editorAnalyticsAPI);
return toggleLinkMarkResult;
} catch (e) {
fireAnalyticForMediaLink(tr, ACTION.ERRORED, _objectSpread({
action: action
}, nodeTypeAndMediaTypeAttrs), editorAnalyticsAPI);
throw e;
}
});
};