UNPKG

@atlaskit/editor-plugin-indentation

Version:

Indentation plugin for @atlaskit/editor-core

124 lines (119 loc) 3.69 kB
import { INDENT_DIRECTION, INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { toggleBlockMark } from '@atlaskit/editor-common/commands'; import { MAX_INDENTATION_LEVEL } from '@atlaskit/editor-common/indentation'; import { default as getAttrsWithChangesRecorder } from './getAttrsWithChangesRecorder'; import { createAnalyticsDispatch } from './utils'; export const isIndentationAllowed = (schema, node) => { const { nodes: { paragraph, heading }, marks: { alignment } } = schema; if ([paragraph, heading].indexOf(node.type) > -1) { if (alignment) { const hasAlignment = node.marks.filter(mark => mark.type === alignment)[0]; return !hasAlignment; } return true; } return false; }; /** * Create new indentation command (Either indent or outdent depend of getArgsFn) * @param getNewIndentationAttrs Function to handle new indentation level */ function createIndentationCommand(getNewIndentationAttrs) { return (state, dispatch) => { const { indentation } = state.schema.marks; return toggleBlockMark(indentation, getNewIndentationAttrs, isIndentationAllowed)(state, dispatch); }; } function createIndentationCommandWithAnalytics({ getNewIndentationAttrs, direction, inputMethod, editorAnalyticsAPI }) { // Create a new getAttrs function to record the changes const { getAttrs, getAndResetAttrsChanges } = getAttrsWithChangesRecorder(getNewIndentationAttrs, { direction }); // Use new getAttrs wrapper const indentationCommand = createIndentationCommand(getAttrs); // Return a new command where we change dispatch for our analytics dispatch return (state, dispatch) => { return indentationCommand(state, createAnalyticsDispatch({ getAttrsChanges: getAndResetAttrsChanges, inputMethod, editorAnalyticsAPI, state, dispatch })); }; } /** * Get new level for outdent * @param oldAttr Old attributes for the mark, undefined if the mark doesn't exit * @returns - undefined; No change required * - false; Remove the mark * - object; Update attributes */ const getIndentAttrs = oldAttr => { if (!oldAttr) { return { level: 1 }; // No mark exist, create a new one with level 1 } const { level } = oldAttr; if (level >= MAX_INDENTATION_LEVEL) { return undefined; // Max indentation level reached, do nothing. } return { level: level + 1 }; // Otherwise, increase the level by one }; export const getIndentCommand = editorAnalyticsAPI => (inputMethod = INPUT_METHOD.KEYBOARD) => createIndentationCommandWithAnalytics({ getNewIndentationAttrs: getIndentAttrs, direction: INDENT_DIRECTION.INDENT, inputMethod, editorAnalyticsAPI }); /** * Get new level for outdent * @param oldAttr Old attributes for the mark, undefined if the mark doesn't exit * @returns - undefined; No change required * - false; Remove the mark * - object; Update attributes */ const getOutdentAttrs = oldAttr => { if (!oldAttr) { return undefined; // Do nothing; } const { level } = oldAttr; if (level <= 1) { return false; // Remove the mark } return { level: level - 1 }; // Decrease the level on other cases }; export const getOutdentCommand = editorAnalyticsAPI => (inputMethod = INPUT_METHOD.KEYBOARD) => createIndentationCommandWithAnalytics({ getNewIndentationAttrs: getOutdentAttrs, direction: INDENT_DIRECTION.OUTDENT, inputMethod, editorAnalyticsAPI }); export const removeIndentation = (state, dispatch) => toggleBlockMark(state.schema.marks.indentation, () => false)(state, dispatch);