@atlaskit/editor-plugin-card
Version:
Card plugin for @atlaskit/editor-core
132 lines (128 loc) • 6.07 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isNativeEmbedNode = exports.isNativeEmbedAppearanceSupported = exports.getNativeEmbedUrl = exports.changeNativeEmbedAppearance = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _url = require("@atlaskit/adf-schema/url");
var _analytics = require("@atlaskit/editor-common/analytics");
var _extensions = require("@atlaskit/editor-common/extensions");
/**
* A native embed is an `extension` node that `editor-plugin-native-embeds` builds from
* embedCard ADF (via the `embedCardNodeTransformer` registered on the card plugin).
* A 1P link that resolves to an embed appearance — a whiteboard, page, slide or
* database — therefore lands in the document as one of these rather than as an
* `embedCard`, so card node types alone are not enough to describe what was pasted.
*
* `editor-plugin-native-embeds` owns the equivalent predicate, but the card plugin
* cannot depend on it: that would close the cycle
* editor-plugin-card -> editor-plugin-native-embeds -> editor-plugin-card.
*/
var isNativeEmbedNode = exports.isNativeEmbedNode = function isNativeEmbedNode(node) {
var _node$attrs, _node$attrs2;
return (node === null || node === void 0 ? void 0 : node.type.name) === 'extension' && ((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.extensionType) === _extensions.NATIVE_EMBED_EXTENSION_TYPE && typeof ((_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.extensionKey) === 'string' && node.attrs.extensionKey.includes(_extensions.NATIVE_EMBED_EXTENSION_KEY);
};
/**
* Reads the embedded URL from a native embed node. The URL is stored in
* `parameters.macroParams`, where values may be wrapped (`{ value }`) or bare, and is
* mirrored in `parameters.macroMetadata` so it survives a revert to a card.
*/
var getNativeEmbedUrl = exports.getNativeEmbedUrl = function getNativeEmbedUrl(node) {
var _node$attrs3, _parameters$macroPara, _ref, _parameters$macroMeta;
var parameters = (_node$attrs3 = node.attrs) === null || _node$attrs3 === void 0 ? void 0 : _node$attrs3.parameters;
var macroParamUrl = parameters === null || parameters === void 0 || (_parameters$macroPara = parameters.macroParams) === null || _parameters$macroPara === void 0 ? void 0 : _parameters$macroPara.url;
var url = (_ref = macroParamUrl && (0, _typeof2.default)(macroParamUrl) === 'object' && 'value' in macroParamUrl ? macroParamUrl.value : macroParamUrl) !== null && _ref !== void 0 ? _ref : parameters === null || parameters === void 0 || (_parameters$macroMeta = parameters.macroMetadata) === null || _parameters$macroMeta === void 0 ? void 0 : _parameters$macroMeta.url;
return typeof url === 'string' ? url : undefined;
};
var canReplaceNodeWith = function canReplaceNodeWith(view, pos, nodeType) {
if (!nodeType) {
return false;
}
try {
var $pos = view.state.doc.resolve(pos);
var index = $pos.index();
return $pos.parent.canReplaceWith(index, index + 1, nodeType);
} catch (_unused) {
return false;
}
};
/**
* Whether a native embed at `pos` can be replaced by the given appearance. `url` and
* `inline` both become a paragraph, `block` becomes a blockCard.
*/
var isNativeEmbedAppearanceSupported = exports.isNativeEmbedAppearanceSupported = function isNativeEmbedAppearanceSupported(_ref2) {
var editorView = _ref2.editorView,
pos = _ref2.pos,
appearance = _ref2.appearance;
var _editorView$state$sch = editorView.state.schema.nodes,
paragraph = _editorView$state$sch.paragraph,
inlineCard = _editorView$state$sch.inlineCard,
blockCard = _editorView$state$sch.blockCard;
if (appearance === 'block') {
return canReplaceNodeWith(editorView, pos, blockCard);
}
if (appearance === 'inline' && !inlineCard) {
return false;
}
if (appearance === 'url' && !editorView.state.schema.marks.link) {
return false;
}
return canReplaceNodeWith(editorView, pos, paragraph);
};
/**
* Replaces a native embed with a link, an inline card or a block card. Mirrors
* `setNativeEmbedAppearance` in `editor-plugin-native-embeds`, which cannot be reused
* here because of the package cycle described on `isNativeEmbedNode`.
*/
var changeNativeEmbedAppearance = exports.changeNativeEmbedAppearance = function changeNativeEmbedAppearance(_ref3) {
var editorView = _ref3.editorView,
pos = _ref3.pos,
node = _ref3.node,
appearance = _ref3.appearance,
url = _ref3.url,
editorAnalyticsApi = _ref3.editorAnalyticsApi;
var state = editorView.state,
dispatch = editorView.dispatch;
var _state$schema$nodes = state.schema.nodes,
paragraph = _state$schema$nodes.paragraph,
inlineCard = _state$schema$nodes.inlineCard,
blockCard = _state$schema$nodes.blockCard;
var link = state.schema.marks.link;
if (!(0, _url.isSafeUrl)(url)) {
return false;
}
var content;
if (appearance === 'url' && link && paragraph) {
content = paragraph.create(null, state.schema.text(url, [link.create({
href: url
})]));
} else if (appearance === 'inline' && inlineCard && paragraph) {
content = paragraph.create(null, inlineCard.create({
url: url
}));
} else if (appearance === 'block' && blockCard) {
content = blockCard.create({
url: url
});
}
if (!content) {
return false;
}
try {
var tr = state.tr.replaceWith(pos, pos + node.nodeSize, content).scrollIntoView();
editorAnalyticsApi === null || editorAnalyticsApi === void 0 || editorAnalyticsApi.attachAnalyticsEvent({
action: _analytics.ACTION.CHANGED_TYPE,
actionSubject: _analytics.ACTION_SUBJECT.NATIVE_EMBED,
eventType: _analytics.EVENT_TYPE.TRACK,
attributes: {
newType: appearance,
previousType: 'nativeEmbed'
}
})(tr);
dispatch(tr);
return true;
} catch (_unused2) {
return false;
}
};