@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
108 lines (103 loc) • 4.72 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
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 { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
import { findCellClosestToPos } from '@atlaskit/editor-tables/utils';
import { TableCssClassName as ClassName } from '../../types';
var EMPTY_STATE = {
cellPos: -1,
decorationSet: DecorationSet.empty
};
export var activeCellHighlightPluginKey = new PluginKey('tableActiveCellHighlight');
/**
* Returns the position of the cell containing the cursor, or -1 if the cursor
* is not in a table cell or the selection is a CellSelection.
*/
var getActiveCellPos = function getActiveCellPos(state) {
if (state.selection instanceof CellSelection) {
return -1;
}
try {
var cell = findCellClosestToPos(state.selection.$from);
return cell ? cell.pos : -1;
} catch (_unused) {
return -1;
}
};
/** Builds the decoration state highlighting the cell at `cellPos`. */
var buildState = function buildState(cellPos, state) {
if (cellPos === -1) {
return EMPTY_STATE;
}
try {
var cell = state.doc.nodeAt(cellPos);
if (!cell) {
return EMPTY_STATE;
}
var decoration = Decoration.node(cellPos, cellPos + cell.nodeSize, {
class: ClassName.ACTIVE_CURSOR_CELL
});
return {
cellPos: cellPos,
decorationSet: DecorationSet.create(state.doc, [decoration])
};
} catch (_unused2) {
return EMPTY_STATE;
}
};
var hasHadInteraction = function hasHadInteraction(api) {
var _api$interaction$shar;
// The interaction plugin is optional - when absent, default to treating the editor as
// interacted.
if (!(api !== null && api !== void 0 && api.interaction)) {
return true;
}
return ((_api$interaction$shar = api.interaction.sharedState.currentState()) === null || _api$interaction$shar === void 0 ? void 0 : _api$interaction$shar.interactionState) !== 'hasNotHadInteraction';
};
/** Stays hidden until the first interaction. */
var createStateField = function createStateField(api) {
return {
init: function init(_config, state) {
var interacted = hasHadInteraction(api);
return _objectSpread(_objectSpread({}, interacted ? buildState(getActiveCellPos(state), state) : EMPTY_STATE), {}, {
hasHadInteraction: interacted
});
},
apply: function apply(tr, prev, _oldState, newState) {
var interacted = hasHadInteraction(api);
// Keep the highlight hidden until the first interaction has happened.
if (!interacted) {
return prev;
}
// `true` only on the single transaction that crosses from "no interaction"
// to "interacted" — the meta-only transaction that reveals the highlight.
var isFirstInteraction = !prev.hasHadInteraction;
if (!tr.docChanged && !tr.selectionSet && !isFirstInteraction) {
// Doc, selection and interaction are all unchanged — nothing to do.
return prev;
}
var nextCellPos = getActiveCellPos(newState);
if (nextCellPos === prev.cellPos && !isFirstInteraction) {
return prev;
}
return _objectSpread(_objectSpread({}, buildState(nextCellPos, newState)), {}, {
hasHadInteraction: true
});
}
};
};
export var createPlugin = function createPlugin(api) {
return new SafePlugin({
key: activeCellHighlightPluginKey,
state: createStateField(api),
props: {
decorations: function decorations(state) {
var _activeCellHighlightP, _activeCellHighlightP2;
return (_activeCellHighlightP = (_activeCellHighlightP2 = activeCellHighlightPluginKey.getState(state)) === null || _activeCellHighlightP2 === void 0 ? void 0 : _activeCellHighlightP2.decorationSet) !== null && _activeCellHighlightP !== void 0 ? _activeCellHighlightP : DecorationSet.empty;
}
}
});
};