UNPKG

@atlaskit/editor-plugin-selection-marker

Version:

Selection marker plugin for @atlaskit/editor-core.

146 lines (144 loc) 9.64 kB
"use strict"; var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.selectionMarkerPlugin = void 0; var _react = _interopRequireWildcard(require("react")); var _hooks = require("@atlaskit/editor-common/hooks"); var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector"); var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure"); var _experiments = require("@atlaskit/tmp-editor-statsig/experiments"); var _main = require("./pm-plugins/main"); var _globalStyles = require("./ui/global-styles"); 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); } var selectionMarkerPlugin = exports.selectionMarkerPlugin = function selectionMarkerPlugin(_ref) { var config = _ref.config, api = _ref.api; return { name: 'selectionMarker', pmPlugins: function pmPlugins() { return [{ name: 'selectionMarkerPmPlugin', plugin: function plugin() { return (0, _main.createPlugin)(api); } }]; }, getSharedState: function getSharedState(editorState) { var _key$getState$forceHi, _key$getState, _key$getState2; if (!editorState) { return undefined; } return { isForcedHidden: (_key$getState$forceHi = (_key$getState = _main.key.getState(editorState)) === null || _key$getState === void 0 ? void 0 : _key$getState.forceHide) !== null && _key$getState$forceHi !== void 0 ? _key$getState$forceHi : false, isMarkerActive: !((_key$getState2 = _main.key.getState(editorState)) !== null && _key$getState2 !== void 0 && _key$getState2.shouldHideDecorations) }; }, actions: { // For now this is a very simple locking mechanism that only allows one // plugin to hide / release at a time. hideDecoration: function hideDecoration() { var _api$selectionMarker, _api$core; if (api !== null && api !== void 0 && (_api$selectionMarker = api.selectionMarker) !== null && _api$selectionMarker !== void 0 && (_api$selectionMarker = _api$selectionMarker.sharedState.currentState()) !== null && _api$selectionMarker !== void 0 && _api$selectionMarker.isForcedHidden) { return undefined; } var success = api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(function (_ref2) { var tr = _ref2.tr; return tr.setMeta(_main.key, { forceHide: true }); }); if (!success) { return undefined; } return cleanupHiddenDecoration(api); }, queueHideDecoration: function queueHideDecoration(setCleanup) { var result = api === null || api === void 0 ? void 0 : api.selectionMarker.actions.hideDecoration(); if (result === undefined) { var _api$selectionMarker2; var cleanup = api === null || api === void 0 || (_api$selectionMarker2 = api.selectionMarker) === null || _api$selectionMarker2 === void 0 ? void 0 : _api$selectionMarker2.sharedState.onChange(function (_ref3) { var nextSharedState = _ref3.nextSharedState; if ((nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.isForcedHidden) === false && (nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.isMarkerActive) === false) { var _result = api === null || api === void 0 ? void 0 : api.selectionMarker.actions.hideDecoration(); setCleanup(_result); cleanup === null || cleanup === void 0 || cleanup(); } }); return cleanup; } setCleanup(result); return function () {}; } }, usePluginHook: function usePluginHook(_ref4) { var editorView = _ref4.editorView; var editorHasNotBeenFocused = (0, _react.useRef)(true); (0, _react.useEffect)(function () { // relatch when editorView changes (pretty good signal for reinit) editorHasNotBeenFocused.current = true; }, [editorView]); var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['focus', 'typeAhead', 'editorDisabled', 'toolbar', 'decorations', 'userIntent'], function (states) { var _states$focusState, _states$typeAheadStat, _states$editorDisable, _states$toolbarState, _states$decorationsSt, _states$userIntentSta; return { hasFocus: (_states$focusState = states.focusState) === null || _states$focusState === void 0 ? void 0 : _states$focusState.hasFocus, isOpen: (_states$typeAheadStat = states.typeAheadState) === null || _states$typeAheadStat === void 0 ? void 0 : _states$typeAheadStat.isOpen, editorDisabled: (_states$editorDisable = states.editorDisabledState) === null || _states$editorDisable === void 0 ? void 0 : _states$editorDisable.editorDisabled, showToolbar: (_states$toolbarState = states.toolbarState) === null || _states$toolbarState === void 0 ? void 0 : _states$toolbarState.shouldShowToolbar, hasDangerDecorations: (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_block_menu', 'isEnabled', true) ? (_states$decorationsSt = states.decorationsState) === null || _states$decorationsSt === void 0 ? void 0 : _states$decorationsSt.hasDangerDecorations : undefined, currentUserIntent: (_states$userIntentSta = states.userIntentState) === null || _states$userIntentSta === void 0 ? void 0 : _states$userIntentSta.currentUserIntent }; }), hasFocus = _useSharedPluginState.hasFocus, isOpen = _useSharedPluginState.isOpen, editorDisabled = _useSharedPluginState.editorDisabled, showToolbar = _useSharedPluginState.showToolbar, hasDangerDecorations = _useSharedPluginState.hasDangerDecorations, currentUserIntent = _useSharedPluginState.currentUserIntent; var isForcedHidden = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(api, 'selectionMarker.isForcedHidden'); (0, _react.useEffect)(function () { // On editor init we should use this latch to keep the marker hidden until // editor has received focus. This means editor will be initially hidden until // the first focus occurs, and after first focus the normal above rules will // apply if (hasFocus === true) { editorHasNotBeenFocused.current = false; } var isBlockMenuOpen = currentUserIntent === 'blockMenuOpen' && (0, _experiments.editorExperiment)('platform_editor_block_menu', true); /** * There are a number of conditions we should not show the marker, * - Editor has not been focused: to keep the marker hidden until first focus if config is set * - Focus: to ensure it doesn't interrupt the normal cursor * - Typeahead Open: To ensure it doesn't show when we're typing in the typeahead * - Disabled: So that it behaves similar to the renderer in live pages/disabled * - Via the API: If another plugin has requested it to be hidden (force hidden). * - If danger styles is shown in decorationsPlugin, then we don't need to show the selection marker */ var shouldHide = (config === null || config === void 0 ? void 0 : config.hideCursorOnInit) && editorHasNotBeenFocused.current || hasFocus || (isOpen !== null && isOpen !== void 0 ? isOpen : false) || isForcedHidden || (editorDisabled !== null && editorDisabled !== void 0 ? editorDisabled : false) || (showToolbar !== null && showToolbar !== void 0 ? showToolbar : false) || !!hasDangerDecorations && (0, _experiments.editorExperiment)('platform_editor_block_menu', true) || isBlockMenuOpen; requestAnimationFrame(function () { return (0, _main.dispatchShouldHideDecorations)(editorView, shouldHide); }); }, [editorView, hasFocus, isOpen, isForcedHidden, editorDisabled, showToolbar, hasDangerDecorations, currentUserIntent]); }, contentComponent: function contentComponent() { return /*#__PURE__*/_react.default.createElement(_globalStyles.GlobalStylesWrapper, null); } }; }; function cleanupHiddenDecoration(api) { var hasRun = false; return function () { var _api$selectionMarker3; if (!hasRun && api !== null && api !== void 0 && (_api$selectionMarker3 = api.selectionMarker) !== null && _api$selectionMarker3 !== void 0 && (_api$selectionMarker3 = _api$selectionMarker3.sharedState.currentState()) !== null && _api$selectionMarker3 !== void 0 && _api$selectionMarker3.isForcedHidden) { var _api$core2; hasRun = true; return api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(function (_ref5) { var tr = _ref5.tr; return tr.setMeta(_main.key, { forceHide: false }); }); } }; }