UNPKG

@atlaskit/editor-plugin-code-block

Version:

Code block plugin for @atlaskit/editor-core

76 lines (72 loc) 3.08 kB
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)]; }