UNPKG

@atlaskit/editor-plugin-insert-block

Version:

Insert block plugin for @atlaskit/editor-core

366 lines (363 loc) 21 kB
"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 }); }