UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

80 lines (75 loc) 2.9 kB
import { NodeSelection } from '@atlaskit/editor-prosemirror/state'; import { findWrapping } from '@atlaskit/editor-prosemirror/transform'; import { safeInsert } from '@atlaskit/editor-prosemirror/utils'; import { removeBlockMarks } from './editor-core-utils'; /** * This function creates a new transaction that wraps the current selection * in the specified node type if it results in a valid transaction. * If not valid, it performs a safe insert operation. * * Example of when wrapping might not be valid is when attempting to wrap * content that is already inside a panel with another panel */ export function createWrapSelectionTransaction(_ref) { var state = _ref.state, type = _ref.type, nodeAttributes = _ref.nodeAttributes; var tr = state.tr; var _state$schema$marks = state.schema.marks, alignment = _state$schema$marks.alignment, indentation = _state$schema$marks.indentation; /** Alignment or Indentation is not valid inside block types */ var removeAlignTr = removeBlockMarks(state, [alignment, indentation]); tr = removeAlignTr || tr; /**Get range and wrapping needed for the selection*/ var _getWrappingOptions = getWrappingOptions(state, type, nodeAttributes), range = _getWrappingOptions.range, wrapping = _getWrappingOptions.wrapping; if (wrapping) { tr.wrap(range, wrapping).scrollIntoView(); } else { /** We always want to append a block type */ safeInsert(type.createAndFill(nodeAttributes))(tr).scrollIntoView(); } return tr; } export function getWrappingOptions(state, type, // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any nodeAttributes) { var _state$selection = state.selection, $from = _state$selection.$from, $to = _state$selection.$to, from = _state$selection.from; // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any var range = $from.blockRange($to); var isMediaSelection = state.selection instanceof NodeSelection && state.selection.node.type === state.schema.nodes.media; /** * To wrap a media group we need to start the range from one position * before a media selection's from position. */ if (isMediaSelection) { var prev = from - 1; range = state.doc.resolve(from > 0 ? prev : from).blockRange($to); } var isAllowedChild = true; /** * Added a check to avoid wrapping codeblock */ if (state.selection.empty) { state.doc.nodesBetween($from.pos, $to.pos, function (node) { if (!isAllowedChild) { return false; } return isAllowedChild = node.type !== state.schema.nodes.codeBlock; }); } // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any var wrapping = isAllowedChild && range && findWrapping(range, type, nodeAttributes); return { range: range, wrapping: wrapping }; }