@atlaskit/editor-plugin-insert-block
Version:
Insert block plugin for @atlaskit/editor-core
366 lines (363 loc) • 21 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toolbarSizeToButtons = exports.insertBlockPlugin = void 0;
var _react = _interopRequireWildcard(require("react"));
var _analytics = require("@atlaskit/editor-common/analytics");
var _elementBrowser = require("@atlaskit/editor-common/element-browser");
var _hooks = require("@atlaskit/editor-common/hooks");
var _providerFactory = require("@atlaskit/editor-common/provider-factory");
var _types = require("@atlaskit/editor-common/types");
var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
var _consts = require("@atlaskit/editor-plugin-block-type/consts");
var _editorPluginConnectivity = require("@atlaskit/editor-plugin-connectivity");
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
var _toolbarActionExperiences = require("./pm-plugins/experiences/toolbar-action-experiences");
var _toggleInsertBlock = require("./pm-plugins/toggleInsertBlock");
var _toolbarComponents = require("./ui/toolbar-components");
var _ToolbarInsertBlock = _interopRequireDefault(require("./ui/ToolbarInsertBlock"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
// Ignored via go/ees005
// eslint-disable-next-line import/no-named-as-default
var toolbarSizeToButtons = exports.toolbarSizeToButtons = function toolbarSizeToButtons(toolbarSize, appearance) {
// Different button numbers for full-page to better match full page toolbar breakpoints
if (appearance === 'full-page' && (0, _platformFeatureFlags.fg)('platform_editor_toolbar_responsive_fixes')) {
switch (toolbarSize) {
case _types.ToolbarSize.XXL:
case _types.ToolbarSize.XL:
case _types.ToolbarSize.L:
return 7;
case _types.ToolbarSize.M:
return 3;
default:
return 0;
}
}
if ((0, _platformFeatureFlags.fg)('platform_editor_toolbar_responsive_fixes')) {
switch (toolbarSize) {
case _types.ToolbarSize.XXL:
case _types.ToolbarSize.XL:
return 7;
case _types.ToolbarSize.L:
return 5;
case _types.ToolbarSize.M:
case _types.ToolbarSize.S:
return 2;
default:
return 0;
}
} else {
switch (toolbarSize) {
case _types.ToolbarSize.XXL:
case _types.ToolbarSize.XL:
case _types.ToolbarSize.L:
case _types.ToolbarSize.M:
return 7;
case _types.ToolbarSize.S:
return 2;
default:
return 0;
}
}
};
/**
* Wrapper over insertBlockTypeWithAnalytics to autobind toolbar input method
* @param name Block name
*/
function handleInsertBlockType(insertCodeBlock, insertPanel, insertBlockQuote) {
return function (name) {
if (name === _consts.CODE_BLOCK.name && insertCodeBlock) {
return insertCodeBlock(_analytics.INPUT_METHOD.TOOLBAR);
}
if (name === _consts.PANEL.name && insertPanel) {
return insertPanel(_analytics.INPUT_METHOD.TOOLBAR);
}
if (name === _consts.BLOCK_QUOTE.name && insertBlockQuote) {
return insertBlockQuote(_analytics.INPUT_METHOD.INSERT_MENU);
}
return function () {
return false;
};
};
}
function delayUntilIdle(cb) {
if (typeof window === 'undefined') {
return;
}
// eslint-disable-next-line compat/compat
if (window.requestIdleCallback !== undefined) {
// eslint-disable-next-line compat/compat
return window.requestIdleCallback(function () {
return cb();
}, {
timeout: 500
});
}
return window.requestAnimationFrame(function () {
return cb();
});
}
var insertBlockPlugin = exports.insertBlockPlugin = function insertBlockPlugin(_ref) {
var _ref$config = _ref.config,
options = _ref$config === void 0 ? {} : _ref$config,
api = _ref.api;
var isToolbarAIFCEnabled = Boolean(api === null || api === void 0 ? void 0 : api.toolbar);
var refs = {};
var primaryToolbarComponent = function primaryToolbarComponent(_ref2) {
var editorView = _ref2.editorView,
editorActions = _ref2.editorActions,
dispatchAnalyticsEvent = _ref2.dispatchAnalyticsEvent,
providerFactory = _ref2.providerFactory,
popupsMountPoint = _ref2.popupsMountPoint,
popupsBoundariesElement = _ref2.popupsBoundariesElement,
popupsScrollableElement = _ref2.popupsScrollableElement,
toolbarSize = _ref2.toolbarSize,
disabled = _ref2.disabled,
isToolbarReducedSpacing = _ref2.isToolbarReducedSpacing,
isLastItem = _ref2.isLastItem;
refs.popupsMountPoint = popupsMountPoint || undefined;
var renderNode = function renderNode(providers) {
if (!editorView) {
return null;
}
return /*#__PURE__*/_react.default.createElement(ToolbarInsertBlockWithInjectionApi, {
pluginInjectionApi: api,
editorView: editorView,
editorActions: editorActions,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
providerFactory: providerFactory,
popupsMountPoint: popupsMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement,
toolbarSize: toolbarSize,
disabled: disabled,
isToolbarReducedSpacing: isToolbarReducedSpacing,
isLastItem: isLastItem,
providers: providers,
options: options,
appearance: options.appearance
});
};
if ((0, _experiments.editorExperiment)('platform_editor_prevent_toolbar_layout_shifts', true)) {
if (!editorView) {
return null;
}
return /*#__PURE__*/_react.default.createElement(ToolbarInsertBlockWithInjectionApi, {
pluginInjectionApi: api,
editorView: editorView,
editorActions: editorActions,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
providerFactory: providerFactory,
popupsMountPoint: popupsMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement,
toolbarSize: toolbarSize,
disabled: disabled,
isToolbarReducedSpacing: isToolbarReducedSpacing,
isLastItem: isLastItem,
options: options,
appearance: options.appearance
});
}
return /*#__PURE__*/_react.default.createElement(_providerFactory.WithProviders, {
providerFactory: providerFactory
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
providers: ['emojiProvider'],
renderNode: renderNode
});
};
if (isToolbarAIFCEnabled) {
var _api$toolbar, _api$codeBlock, _api$panel, _api$blockType;
api === null || api === void 0 || (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 || _api$toolbar.actions.registerComponents((0, _toolbarComponents.getToolbarComponents)({
api: api,
onInsertBlockType: handleInsertBlockType(api === null || api === void 0 || (_api$codeBlock = api.codeBlock) === null || _api$codeBlock === void 0 ? void 0 : _api$codeBlock.actions.insertCodeBlock, api === null || api === void 0 || (_api$panel = api.panel) === null || _api$panel === void 0 ? void 0 : _api$panel.actions.insertPanel, api === null || api === void 0 || (_api$blockType = api.blockType) === null || _api$blockType === void 0 ? void 0 : _api$blockType.actions.insertBlockQuote),
options: options
}));
} else {
var _api$primaryToolbar;
api === null || api === void 0 || (_api$primaryToolbar = api.primaryToolbar) === null || _api$primaryToolbar === void 0 || _api$primaryToolbar.actions.registerComponent({
name: 'insertBlock',
component: primaryToolbarComponent
});
}
var plugin = {
name: 'insertBlock',
actions: {
toggleAdditionalMenu: function toggleAdditionalMenu() {
var _api$core;
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref3) {
var tr = _ref3.tr;
return tr.setMeta(_toggleInsertBlock.toggleInsertBlockPmKey, true);
});
}
},
getSharedState: function getSharedState(editorState) {
var _options$appearance;
if (!editorState || !['full-page', 'full-width'].includes((_options$appearance = options.appearance) !== null && _options$appearance !== void 0 ? _options$appearance : '')) {
return;
}
var toggleInsertBlockPluginState = _toggleInsertBlock.toggleInsertBlockPmKey.getState(editorState);
return {
showElementBrowser: (toggleInsertBlockPluginState === null || toggleInsertBlockPluginState === void 0 ? void 0 : toggleInsertBlockPluginState.showElementBrowser) || false
};
},
usePluginHook: function usePluginHook() {
(0, _react.useEffect)(function () {
// This is to optimise the UI so that when the user first clicks on the insert
// menu it opens instantly. As we're delaying the loading this won't affect the
// initial editor rendering metrics.
delayUntilIdle(function () {
_elementBrowser.ElementBrowser.preload();
});
}, []);
},
pmPlugins: function pmPlugins() {
var _options$appearance2;
if (!['full-page', 'full-width'].includes((_options$appearance2 = options.appearance) !== null && _options$appearance2 !== void 0 ? _options$appearance2 : '')) {
[];
}
var plugins = [];
plugins.push({
name: 'toggleInsertBlockPmPlugin',
plugin: function plugin() {
return (0, _toggleInsertBlock.toggleInsertBlockPmPlugin)();
}
});
if ((0, _platformFeatureFlags.fg)('platform_editor_experience_tracking_toolbar_button')) {
plugins.push({
name: 'toolbarActionExperiences',
plugin: function plugin() {
return (0, _toolbarActionExperiences.getToolbarActionExperiencesPlugin)({
dispatchAnalyticsEvent: function dispatchAnalyticsEvent(payload) {
var _api$analytics;
return api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 ? void 0 : _api$analytics.fireAnalyticsEvent(payload);
}
});
}
});
}
return plugins;
},
pluginsOptions: {},
primaryToolbarComponent: !(api !== null && api !== void 0 && api.primaryToolbar) ? primaryToolbarComponent : undefined
};
return plugin;
};
var selector = function selector(states) {
var _states$emojiState, _states$mediaState, _states$mediaState2, _states$insertBlockSt, _states$typeAheadStat, _states$mentionState, _states$mentionState2, _states$dateState, _states$placeholderTe, _states$connectivityS, _states$imageUploadSt, _states$blockTypeStat, _states$hyperlinkStat, _states$hyperlinkStat2;
return {
emojiProviderSelector: (_states$emojiState = states.emojiState) === null || _states$emojiState === void 0 ? void 0 : _states$emojiState.emojiProvider,
showMediaPicker: (_states$mediaState = states.mediaState) === null || _states$mediaState === void 0 ? void 0 : _states$mediaState.showMediaPicker,
mediaAllowsUploads: (_states$mediaState2 = states.mediaState) === null || _states$mediaState2 === void 0 ? void 0 : _states$mediaState2.allowsUploads,
showElementBrowser: (_states$insertBlockSt = states.insertBlockState) === null || _states$insertBlockSt === void 0 ? void 0 : _states$insertBlockSt.showElementBrowser,
isTypeAheadAllowed: (_states$typeAheadStat = states.typeAheadState) === null || _states$typeAheadStat === void 0 ? void 0 : _states$typeAheadStat.isAllowed,
mentionProvider: (_states$mentionState = states.mentionState) === null || _states$mentionState === void 0 ? void 0 : _states$mentionState.mentionProvider,
canInsertMention: (_states$mentionState2 = states.mentionState) === null || _states$mentionState2 === void 0 ? void 0 : _states$mentionState2.canInsertMention,
dateEnabled: (_states$dateState = states.dateState) === null || _states$dateState === void 0 ? void 0 : _states$dateState.isInitialised,
placeholderTextAllowInserting: (_states$placeholderTe = states.placeholderTextState) === null || _states$placeholderTe === void 0 ? void 0 : _states$placeholderTe.allowInserting,
connectivityMode: (_states$connectivityS = states.connectivityState) === null || _states$connectivityS === void 0 ? void 0 : _states$connectivityS.mode,
imageUploadEnabled: (_states$imageUploadSt = states.imageUploadState) === null || _states$imageUploadSt === void 0 ? void 0 : _states$imageUploadSt.enabled,
availableWrapperBlockTypes: (_states$blockTypeStat = states.blockTypeState) === null || _states$blockTypeStat === void 0 ? void 0 : _states$blockTypeStat.availableWrapperBlockTypes,
canInsertLink: (_states$hyperlinkStat = states.hyperlinkState) === null || _states$hyperlinkStat === void 0 ? void 0 : _states$hyperlinkStat.canInsertLink,
activeLinkMark: (_states$hyperlinkStat2 = states.hyperlinkState) === null || _states$hyperlinkStat2 === void 0 ? void 0 : _states$hyperlinkStat2.activeLinkMark
};
};
function ToolbarInsertBlockWithInjectionApi(_ref4) {
var _pluginInjectionApi$i, _pluginInjectionApi$c2, _pluginInjectionApi$p, _pluginInjectionApi$b, _pluginInjectionApi$e;
var editorView = _ref4.editorView,
editorActions = _ref4.editorActions,
dispatchAnalyticsEvent = _ref4.dispatchAnalyticsEvent,
popupsMountPoint = _ref4.popupsMountPoint,
popupsBoundariesElement = _ref4.popupsBoundariesElement,
popupsScrollableElement = _ref4.popupsScrollableElement,
toolbarSize = _ref4.toolbarSize,
disabled = _ref4.disabled,
isToolbarReducedSpacing = _ref4.isToolbarReducedSpacing,
isLastItem = _ref4.isLastItem,
pluginInjectionApi = _ref4.pluginInjectionApi,
options = _ref4.options,
appearance = _ref4.appearance;
var buttons = toolbarSizeToButtons(toolbarSize, appearance);
var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(pluginInjectionApi, ['hyperlink', 'date', 'imageUpload', 'mention', 'emoji', 'blockType', 'media', 'typeAhead', 'placeholderText', 'insertBlock', 'connectivity'], selector),
emojiProviderSelector = _useSharedPluginState.emojiProviderSelector,
showMediaPicker = _useSharedPluginState.showMediaPicker,
mediaAllowsUploads = _useSharedPluginState.mediaAllowsUploads,
showElementBrowser = _useSharedPluginState.showElementBrowser,
isTypeAheadAllowed = _useSharedPluginState.isTypeAheadAllowed,
mentionProvider = _useSharedPluginState.mentionProvider,
canInsertMention = _useSharedPluginState.canInsertMention,
dateEnabled = _useSharedPluginState.dateEnabled,
placeholderTextAllowInserting = _useSharedPluginState.placeholderTextAllowInserting,
connectivityMode = _useSharedPluginState.connectivityMode,
imageUploadEnabled = _useSharedPluginState.imageUploadEnabled,
availableWrapperBlockTypes = _useSharedPluginState.availableWrapperBlockTypes,
canInsertLink = _useSharedPluginState.canInsertLink,
activeLinkMark = _useSharedPluginState.activeLinkMark;
var emojiProviderPromise = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(pluginInjectionApi, 'emoji.emojiProviderPromise', {
disabled: !(0, _experiments.editorExperiment)('platform_editor_prevent_toolbar_layout_shifts', true)
});
var getEmojiProvider = function getEmojiProvider() {
if (emojiProviderSelector) {
return Promise.resolve(emojiProviderSelector);
}
};
var emojiProvider = (0, _experiments.editorExperiment)('platform_editor_prevent_toolbar_layout_shifts', true, {
exposure: true
}) ? emojiProviderPromise : getEmojiProvider();
var onShowMediaPicker = function onShowMediaPicker(mountInfo) {
var _pluginInjectionApi$m, _pluginInjectionApi$c, _pluginInjectionApi$m2;
if (!showMediaPicker) {
return;
}
pluginInjectionApi !== null && pluginInjectionApi !== void 0 && (_pluginInjectionApi$m = pluginInjectionApi.mediaInsert) !== null && _pluginInjectionApi$m !== void 0 && _pluginInjectionApi$m.commands.showMediaInsertPopup ? pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.core) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$m2 = pluginInjectionApi.mediaInsert) === null || _pluginInjectionApi$m2 === void 0 ? void 0 : _pluginInjectionApi$m2.commands.showMediaInsertPopup(mountInfo)) : showMediaPicker();
};
return /*#__PURE__*/_react.default.createElement(_ToolbarInsertBlock.default, {
showElementBrowser: showElementBrowser || false,
pluginInjectionApi: pluginInjectionApi,
buttons: buttons,
isReducedSpacing: isToolbarReducedSpacing,
isDisabled: disabled,
isTypeAheadAllowed: Boolean(isTypeAheadAllowed),
editorView: editorView,
tableSupported: !!editorView.state.schema.nodes.table,
tableSelectorSupported: options.tableSelectorSupported && !!editorView.state.schema.nodes.table,
actionSupported: !!editorView.state.schema.nodes.taskItem,
mentionsSupported: !!mentionProvider,
mentionsDisabled: !canInsertMention,
decisionSupported: !!editorView.state.schema.nodes.decisionItem,
dateEnabled: !!dateEnabled,
placeholderTextEnabled: !!placeholderTextAllowInserting,
layoutSectionEnabled: Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.layout),
expandEnabled: !!options.allowExpand,
mediaUploadsEnabled: mediaAllowsUploads !== null && mediaAllowsUploads !== void 0 ? mediaAllowsUploads : undefined,
onShowMediaPicker: onShowMediaPicker,
mediaSupported: mediaAllowsUploads !== undefined,
isEditorOffline: (0, _editorPluginConnectivity.isOfflineMode)(connectivityMode),
imageUploadSupported: !!(pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.imageUpload),
imageUploadEnabled: imageUploadEnabled,
handleImageUpload: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$i = pluginInjectionApi.imageUpload) === null || _pluginInjectionApi$i === void 0 ? void 0 : _pluginInjectionApi$i.actions.startUpload,
availableWrapperBlockTypes: availableWrapperBlockTypes,
linkSupported: canInsertLink !== undefined,
linkDisabled: !canInsertLink || !!activeLinkMark,
emojiDisabled: !emojiProvider,
emojiProvider: emojiProvider,
nativeStatusSupported: options.nativeStatusSupported,
horizontalRuleEnabled: options.horizontalRuleEnabled,
onInsertBlockType: handleInsertBlockType(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c2 = pluginInjectionApi.codeBlock) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.actions.insertCodeBlock, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$p = pluginInjectionApi.panel) === null || _pluginInjectionApi$p === void 0 ? void 0 : _pluginInjectionApi$p.actions.insertPanel, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$b = pluginInjectionApi.blockType) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.insertBlockQuote),
onInsertMacroFromMacroBrowser: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$e = pluginInjectionApi.extension) === null || _pluginInjectionApi$e === void 0 ? void 0 : _pluginInjectionApi$e.actions.insertMacroFromMacroBrowser,
popupsMountPoint: popupsMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement,
insertMenuItems: options.insertMenuItems,
editorActions: editorActions,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
showElementBrowserLink: options.showElementBrowserLink,
showSeparator: !isLastItem && toolbarSize <= _types.ToolbarSize.S,
editorAppearance: options.appearance
});
}