@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
64 lines • 2.56 kB
JavaScript
import { closeHistory } from '@atlaskit/editor-prosemirror/history';
import { canJoin, findWrapping } from '@atlaskit/editor-prosemirror/transform';
import { JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST } from '../analytics';
// Roughly based on atlassian-frontend/packages/editor/editor-core/src/utils/input-rules.ts but with the Editor Analytics API that's injected in plugins
export const inputRuleWithAnalytics = (getPayload, analyticsApi) => {
return originalRule => {
const onHandlerApply = (state, tr, matchResult) => {
const payload = typeof getPayload === 'function' ? getPayload(state, matchResult) : getPayload;
if (payload && payload.attributes) {
payload.attributes.formatSize = typeof matchResult[0] === 'string' ? matchResult[0].length : 0;
}
analyticsApi === null || analyticsApi === void 0 ? void 0 : analyticsApi.attachAnalyticsEvent(payload)(tr);
if (originalRule.onHandlerApply) {
originalRule.onHandlerApply(state, tr, matchResult);
}
};
return {
...originalRule,
onHandlerApply
};
};
};
export const createWrappingJoinRule = ({
match,
nodeType,
getAttrs,
joinPredicate
}) => {
const handler = (state, match, start, end) => {
const attrs = (getAttrs instanceof Function ? getAttrs(match) : getAttrs) || {};
const tr = state.tr;
const fixedStart = Math.max(start, 1);
tr.delete(fixedStart, end);
const $start = tr.doc.resolve(fixedStart);
const range = $start.blockRange();
const wrapping = range && findWrapping(range, nodeType, attrs);
if (!wrapping || !range) {
return null;
}
const parentNodePosMapped = tr.mapping.map(range.start);
const parentNode = tr.doc.nodeAt(parentNodePosMapped);
const lastWrap = wrapping[wrapping.length - 1];
if (parentNode && lastWrap) {
const allowedMarks = lastWrap.type.allowedMarks(parentNode.marks) || [];
tr.setNodeMarkup(parentNodePosMapped, parentNode.type, parentNode.attrs, allowedMarks);
}
tr.wrap(range, wrapping);
const before = tr.doc.resolve(fixedStart - 1).nodeBefore;
if (before && before.type === nodeType && canJoin(tr.doc, fixedStart - 1) && (!joinPredicate || joinPredicate(match, before, JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST.JOINED_TO_LIST_ABOVE))) {
tr.join(fixedStart - 1);
}
return tr;
};
return createRule(match, handler);
};
export const createRule = (match, handler) => {
return {
match,
handler,
onHandlerApply: (_state, tr) => {
closeHistory(tr);
}
};
};