@atlaskit/editor-plugin-code-block
Version:
Code block plugin for @atlaskit/editor-core
76 lines (72 loc) • 3.08 kB
JavaScript
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { insertBlock } from '@atlaskit/editor-common/commands';
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import { createRule, inputRuleWithAnalytics } from '@atlaskit/editor-common/utils';
import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
import { createPlugin, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
import { isConvertableToCodeBlock, transformToCodeBlockAction } from './transform-to-code-block';
export function createCodeBlockInputRule(schema, editorAnalyticsAPI, isNestingInQuoteSupported) {
const rules = getCodeBlockRules(editorAnalyticsAPI, schema, isNestingInQuoteSupported);
return new SafePlugin(createPlugin('code-block-input-rule', rules, {
isBlockNodeRule: true
}));
}
/**
* Get all code block input rules
*
* @param {Schema} schema
* @returns {InputRuleWithHandler[]}
*/
function getCodeBlockRules(editorAnalyticsAPI, schema, isNestingInQuoteSupported) {
const ruleAnalytics = inputRuleWithAnalytics({
action: ACTION.INSERTED,
actionSubject: ACTION_SUBJECT.DOCUMENT,
actionSubjectId: ACTION_SUBJECT_ID.CODE_BLOCK,
attributes: {
inputMethod: INPUT_METHOD.FORMATTING
},
eventType: EVENT_TYPE.TRACK
}, editorAnalyticsAPI);
const validMatchLength = match => match.length > 0 && match[0].length === 3;
// Ignored via go/ees005
// eslint-disable-next-line require-unicode-regexp, @typescript-eslint/max-params
const threeTildeRule = createRule(/(?!\s)(`{3,})$/, (state, match, start, end) => {
if (!validMatchLength(match)) {
return null;
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const attributes = {};
if (match[4]) {
attributes.language = match[4];
}
if (isConvertableToCodeBlock(state)) {
return transformToCodeBlockAction(state, start, attributes, isNestingInQuoteSupported);
}
const tr = state.tr;
tr.delete(start, end);
const codeBlock = tr.doc.type.schema.nodes.codeBlock.createChecked();
safeInsert(codeBlock)(tr);
return tr;
});
const leftNodeReplacementThreeTildeRule = createRule(
// Ignored via go/ees005
// eslint-disable-next-line require-unicode-regexp
new RegExp(`((${leafNodeReplacementCharacter}\`{3,})|^\\s(\`{3,}))(\\S*)$`),
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/max-params
(state, match, start, end) => {
if (!validMatchLength(match)) {
return null;
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const attributes = {};
if (match[4]) {
attributes.language = match[4];
}
const inlineStart = Math.max(match.index + state.selection.$from.start(), 1);
return insertBlock(state, schema.nodes.codeBlock, inlineStart, end, attributes);
});
return [ruleAnalytics(threeTildeRule), ruleAnalytics(leftNodeReplacementThreeTildeRule)];
}