@atlaskit/editor-plugin-rule
Version:
Rule plugin for @atlaskit/editor-core
79 lines (78 loc) • 3.25 kB
JavaScript
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { safeInsert } from '@atlaskit/editor-common/insert';
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import { createRule } from '@atlaskit/editor-common/utils';
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
import { hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
import { fg } from '@atlaskit/platform-feature-flags';
import { createPlugin, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
export const createHorizontalRule = (state, start, end, inputMethod, editorAnalyticsAPI) => {
if (!state.selection.empty) {
return null;
}
let tr = null;
const {
rule
} = state.schema.nodes;
/**
* This is a workaround to get rid of the typeahead text when using quick insert
* Once we insert *nothing*, we get a new transaction, so we can use the new selection
* without considering the extra text after the `/` command.
**/
tr = state.tr.replaceWith(start, end, Fragment.empty);
tr = safeInsert(rule.createChecked(), tr.selection.from)(tr);
if (!tr) {
tr = state.tr.replaceRange(start, end, new Slice(Fragment.from(state.schema.nodes.rule.createChecked()), 0, 0));
}
const resolvedInputMethod = fg('platform_editor_element_browser_analytic') ? inputMethod : INPUT_METHOD.QUICK_INSERT;
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
action: ACTION.INSERTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.DIVIDER,
attributes: {
inputMethod: resolvedInputMethod
},
eventType: EVENT_TYPE.TRACK
})(tr);
return tr;
};
const createHorizontalRuleAutoformat = (state, start, end, editorAnalyticsAPI) => {
const {
listItem
} = state.schema.nodes;
if (hasParentNodeOfType(listItem)(state.selection)) {
return null;
}
return createHorizontalRule(state, start, end, INPUT_METHOD.FORMATTING, editorAnalyticsAPI);
};
export function inputRulePlugin(schema, editorAnalyticsAPI) {
const rules = [];
if (schema.nodes.rule) {
// '---' and '***' for hr
rules.push(
// eslint-disable-next-line require-unicode-regexp
createRule(/^(\-\-\-|\*\*\*)$/, (state, _match, start, end) => createHorizontalRuleAutoformat(state, start, end, editorAnalyticsAPI)));
// '---' and '***' after shift+enter for hr
rules.push(createRule(
// Ignored via go/ees005
// eslint-disable-next-line require-unicode-regexp
new RegExp(`${leafNodeReplacementCharacter}(\\-\\-\\-|\\*\\*\\*)`), (state, _match, start, end) => {
const {
hardBreak
} = state.schema.nodes;
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (state.doc.resolve(start).nodeAfter.type !== hardBreak) {
return null;
}
return createHorizontalRuleAutoformat(state, start, end, editorAnalyticsAPI);
}));
}
if (rules.length !== 0) {
return new SafePlugin(createPlugin('rule', rules, {
isBlockNodeRule: true
}));
}
return;
}
export default inputRulePlugin;