@atlaskit/editor-plugin-selection-marker
Version:
Selection marker plugin for @atlaskit/editor-core.
89 lines • 3.94 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import debounce from 'lodash/debounce';
import { getBrowserInfo } from '@atlaskit/editor-common/browser';
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import { isEmptyDocument } from '@atlaskit/editor-common/utils';
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
import { selectionDecoration } from '../ui/selection-decoration';
import { createWidgetDecoration } from '../ui/widget-decoration';
export var key = new PluginKey('selectionMarker');
function getDecorations(tr, type) {
var selection = tr.selection;
switch (type) {
case 'none':
return DecorationSet.empty;
case 'highlight':
return DecorationSet.create(tr.doc, [].concat(_toConsumableArray(createWidgetDecoration(selection.$anchor, 'anchor', selection, true)), _toConsumableArray(selectionDecoration(tr.doc, selection, true)), _toConsumableArray(createWidgetDecoration(selection.$head, 'head', selection, true))));
case 'blur':
return DecorationSet.create(tr.doc, [].concat(_toConsumableArray(createWidgetDecoration(selection.$anchor, 'anchor', selection, false)), _toConsumableArray(selectionDecoration(tr.doc, selection, false))));
}
}
function getDecorationType(tr, shouldHideDecorations) {
if (shouldHideDecorations || isEmptyDocument(tr.doc)) {
return 'none';
}
// TODO: ED-26961 - implement "highlight" for AI features
return 'blur';
}
export var applyNextPluginState = function applyNextPluginState(tr, currentState, oldEditorState) {
var _meta$forceHide, _meta$shouldHideDecor;
var meta = tr.getMeta(key);
if (!meta && !tr.selectionSet) {
return currentState;
}
var forceHide = (_meta$forceHide = meta === null || meta === void 0 ? void 0 : meta.forceHide) !== null && _meta$forceHide !== void 0 ? _meta$forceHide : currentState.forceHide;
var shouldHideDecorations = (_meta$shouldHideDecor = meta === null || meta === void 0 ? void 0 : meta.shouldHideDecorations) !== null && _meta$shouldHideDecor !== void 0 ? _meta$shouldHideDecor : currentState.shouldHideDecorations;
var type = getDecorationType(tr, shouldHideDecorations);
var nextDecorations = currentState.decorations;
var hasSelectionChangedToRange = oldEditorState.selection.empty && !tr.selection.empty;
if (hasSelectionChangedToRange || currentState.decorationType !== type) {
nextDecorations = getDecorations(tr, type);
} else {
nextDecorations = nextDecorations.map(tr.mapping, tr.doc, {});
}
return {
decorations: nextDecorations,
shouldHideDecorations: shouldHideDecorations,
forceHide: forceHide,
decorationType: type
};
};
var debouncedDecorations = debounce(function (state) {
var _key$getState;
return (_key$getState = key.getState(state)) === null || _key$getState === void 0 ? void 0 : _key$getState.decorations;
}, 25);
export var createPlugin = function createPlugin(api) {
return new SafePlugin({
key: key,
state: {
init: function init() {
return {
decorations: DecorationSet.empty,
shouldHideDecorations: true,
forceHide: false,
decorationType: 'none'
};
},
apply: applyNextPluginState
},
props: {
decorations: function decorations(state) {
var browser = getBrowserInfo();
if (browser.ie) {
return debouncedDecorations(state);
} else {
var _key$getState2;
return (_key$getState2 = key.getState(state)) === null || _key$getState2 === void 0 ? void 0 : _key$getState2.decorations;
}
}
}
});
};
export function dispatchShouldHideDecorations(editorView, shouldHideDecorations) {
var dispatch = editorView.dispatch,
state = editorView.state;
dispatch(state.tr.setMeta(key, {
shouldHideDecorations: shouldHideDecorations
}));
}