@atlaskit/editor-plugin-list
Version:
List plugin for @atlaskit/editor-core
46 lines (45 loc) • 1.91 kB
JavaScript
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
const listContainerTypes = new Set(['bulletList', 'orderedList']);
/**
* When wrapping in a list, the paragraph's direct parent will be listItem,
* not the list container itself. For fontSize marks, resolve to listItem
* so mark compatibility is checked against the actual parent.
*/
const resolveEffectiveParentType = newParentType => {
if (newParentType && listContainerTypes.has(newParentType.name) && expValEquals('platform_editor_small_font_size', 'isEnabled', true)) {
return newParentType.schema.nodes.listItem;
}
return newParentType;
};
const isMarkDisallowed = (mark, parent, effectiveParentType) => !(parent !== null && parent !== void 0 && parent.type.allowsMarkType(mark.type)) || effectiveParentType && !effectiveParentType.allowsMarkType(mark.type);
export const sanitiseMarksInSelection = (tr, newParentType) => {
const {
from,
to
} = tr.selection;
const nodesSanitized = [];
tr.doc.nodesBetween(from, to, (node, pos, parent) => {
if (node.isText) {
return false;
}
// Skip expands and layouts if they are outside selection
// but continue to iterate over their children.
if (['expand', 'layoutSection'].includes(node.type.name) && (pos < from || pos > to)) {
return true;
}
node.marks.forEach(mark => {
const effectiveParentType = resolveEffectiveParentType(newParentType);
if (isMarkDisallowed(mark, parent, effectiveParentType)) {
const filteredMarks = node.marks.filter(m => m.type !== mark.type);
const position = pos > 0 ? pos : 0;
const marksRemoved = node.marks.filter(m => m.type === mark.type);
nodesSanitized.push({
node,
marksRemoved
});
tr.setNodeMarkup(position, undefined, node.attrs, filteredMarks);
}
});
});
return nodesSanitized;
};