@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
180 lines (178 loc) • 9.31 kB
JavaScript
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _regeneratorRuntime from "@babel/runtime/regenerator";
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 Loadable from 'react-loadable';
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, fireAnalyticsEvent, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { getQuickInsertItemsFromModule, resolveImport } from '@atlaskit/editor-common/extensions';
import { combineProviders } from '@atlaskit/editor-common/provider-helpers';
import { findInsertLocation } from '@atlaskit/editor-common/utils/analytics';
import { fg } from '@atlaskit/platform-feature-flags';
// Structural shape of the markdown-mode plugin's slice of the injection API.
// Used to read `isMarkdownMode` without importing the `MarkdownModePlugin`
// type — that would pull editor-plugin-markdown-mode into editor-core's
// dependency graph and force every consuming product to rebuild.
/**
* Utils to send analytics event when a extension is inserted using quickInsert
*/
function sendExtensionQuickInsertAnalytics(item, selection, createAnalyticsEvent, source) {
if (createAnalyticsEvent) {
var insertLocation = findInsertLocation(selection);
fireAnalyticsEvent(createAnalyticsEvent)({
payload: {
action: ACTION.INSERTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.EXTENSION,
attributes: _objectSpread({
extensionType: item.extensionType,
extensionKey: item.extensionKey,
key: item.key,
// @note inputMethod defaults to QUICK_INSERT if not provided
inputMethod: source || INPUT_METHOD.QUICK_INSERT
}, insertLocation ? {
insertLocation: insertLocation
} : {}),
eventType: EVENT_TYPE.TRACK
}
});
}
}
var showDummyAPIWarning = function showDummyAPIWarning(location) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn("Extension plugin not attached to editor - cannot use extension API in ".concat(location));
}
};
var dummyExtensionAPI = {
editInContextPanel: function editInContextPanel() {
return showDummyAPIWarning('editInContextPanel');
},
_editInLegacyMacroBrowser: function _editInLegacyMacroBrowser() {
return showDummyAPIWarning('_editInLegacyMacroBrowser');
},
getNodeWithPosByLocalId: function getNodeWithPosByLocalId() {
return {
node: null,
pos: null
};
},
doc: {
insertAfter: function insertAfter() {
return showDummyAPIWarning('doc:insertAfter');
},
scrollTo: function scrollTo() {
return showDummyAPIWarning('doc:scrollTo');
},
update: function update() {
return showDummyAPIWarning('doc:update');
}
}
};
export function extensionProviderToQuickInsertProvider(_x, _x2, _x3, _x4) {
return _extensionProviderToQuickInsertProvider.apply(this, arguments);
}
function _extensionProviderToQuickInsertProvider() {
_extensionProviderToQuickInsertProvider = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(extensionProvider, editorActions, apiRef, createAnalyticsEvent) {
var extensions;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return extensionProvider.getExtensions();
case 2:
extensions = _context.sent;
return _context.abrupt("return", {
getItems: function getItems() {
var _apiRef$current;
// `extensionProvider` is supplied independently of the preset, so
// suppress its items in markdown mode where rich-only content cannot
// be inserted. See `MarkdownModeReader` above for why this is read
// via a structural cast rather than the typed plugin API.
var isMarkdownMode = (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 || (_apiRef$current = _apiRef$current.markdownMode) === null || _apiRef$current === void 0 || (_apiRef$current = _apiRef$current.sharedState.currentState()) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.isMarkdownMode;
if (isMarkdownMode) {
return Promise.resolve([]);
}
var quickInsertItems = getQuickInsertItemsFromModule(extensions, function (item) {
var Icon = Loadable({
loader: item.icon,
loading: function loading() {
return null;
}
});
return _objectSpread(_objectSpread(_objectSpread({
// Add module key so typeahead/quick-insert can identify items
// **locale-agnostically**! nb: we _already_ send key in analytics
// events, this standardises and makes our items more predictable.
key: item.key,
title: item.title,
description: item.description,
icon: function icon() {
return /*#__PURE__*/React.createElement(Icon, {
label: ""
});
},
keywords: item.keywords,
featured: item.featured
}, (fg('cc_fd_wb_create_priority_in_slash_menu_enabled') || fg('rovo_chat_enable_skills_ui_m1')) && {
priority: item.priority
}), {}, {
categories: item.categories
}, item.lozenge != null && {
lozenge: item.lozenge
}), {}, {
isDisabledOffline: true,
action: function action(insert, state, source) {
if (typeof item.node === 'function') {
var _apiRef$current2;
var extensionAPI = apiRef === null || apiRef === void 0 || (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 || (_apiRef$current2 = _apiRef$current2.extension) === null || _apiRef$current2 === void 0 || (_apiRef$current2 = _apiRef$current2.actions) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.api();
// While this should only run when the extension some setups of editor
// may not have the extension API
if (extensionAPI) {
resolveImport(item.node(extensionAPI)).then(function (node) {
sendExtensionQuickInsertAnalytics(item, state.selection, createAnalyticsEvent, source);
if (node) {
editorActions.replaceSelection(node);
}
});
} else {
// Originally it was understood we could only use this if we were using the extension plugin
// However there are some edge cases where this is not true (ie. in jira)
// Since making it optional now would be a breaking change - instead we can just pass a dummy
// extension API to consumers that warns them of using the methods.
resolveImport(item.node(dummyExtensionAPI)).then(function (node) {
sendExtensionQuickInsertAnalytics(item, state.selection, createAnalyticsEvent, source);
if (node) {
editorActions.replaceSelection(node);
}
});
}
return insert('');
} else {
sendExtensionQuickInsertAnalytics(item, state.selection, createAnalyticsEvent, source);
return insert(item.node);
}
}
});
});
return Promise.all(quickInsertItems);
}
});
case 4:
case "end":
return _context.stop();
}
}, _callee);
}));
return _extensionProviderToQuickInsertProvider.apply(this, arguments);
}
export function combineQuickInsertProviders(quickInsertProviders) {
var _combineProviders = combineProviders(quickInsertProviders),
invokeList = _combineProviders.invokeList;
return {
getItems: function getItems() {
return invokeList('getItems');
}
};
}