@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
66 lines (63 loc) • 1.85 kB
JavaScript
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({
state,
type,
nodeAttributes
}) {
let {
tr
} = state;
const {
alignment,
indentation
} = state.schema.marks;
/** Alignment or Indentation is not valid inside block types */
const removeAlignTr = removeBlockMarks(state, [alignment, indentation]);
tr = removeAlignTr || tr;
/**Get range and wrapping needed for the selection*/
const {
range,
wrapping
} = getWrappingOptions(state, type, nodeAttributes);
if (wrapping) {
tr.wrap(range, wrapping).scrollIntoView();
} else {
/** We always want to append a block type */
safeInsert(type.createAndFill(nodeAttributes))(tr).scrollIntoView();
}
return tr;
}
function getWrappingOptions(state, type, nodeAttributes) {
const {
$from,
$to
} = state.selection;
const range = $from.blockRange($to);
let isAllowedChild = true;
/**
* Added a check to avoid wrapping codeblock
*/
if (state.selection.empty) {
state.doc.nodesBetween($from.pos, $to.pos, node => {
if (!isAllowedChild) {
return false;
}
return isAllowedChild = node.type !== state.schema.nodes.codeBlock;
});
}
const wrapping = isAllowedChild && range && findWrapping(range, type, nodeAttributes);
return {
range,
wrapping
};
}