File size: 1,568 Bytes
f56a29b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import type { Schema, Node, NodeType } from 'prosemirror-model';
import type { Transaction } from 'prosemirror-state';
import type { EditorView } from 'prosemirror-view';
export const setTextAlign = (tr: Transaction, schema: Schema, alignment: string) => {
const { selection, doc } = tr;
if (!selection || !doc) return tr;
const { from, to } = selection;
const { nodes } = schema;
const blockquote = nodes.blockquote;
const listItem = nodes.list_item;
const paragraph = nodes.paragraph;
interface Task {
node: Node;
pos: number;
nodeType: NodeType;
}
const tasks: Task[] = [];
alignment = alignment || '';
const allowedNodeTypes = new Set([blockquote, listItem, paragraph]);
doc.nodesBetween(from, to, (node, pos) => {
const nodeType = node.type;
const align = node.attrs.align || '';
if (align !== alignment && allowedNodeTypes.has(nodeType)) {
tasks.push({
node,
pos,
nodeType,
});
}
return true;
});
if (!tasks.length) return tr;
tasks.forEach((task) => {
const { node, pos, nodeType } = task;
let { attrs } = node;
if (alignment) attrs = { ...attrs, align: alignment };
else attrs = { ...attrs, align: null };
tr = tr.setNodeMarkup(pos, nodeType, attrs, node.marks);
});
return tr;
};
export const alignmentCommand = (view: EditorView, alignment: string) => {
const { state } = view;
const { schema, selection } = state;
const tr = setTextAlign(state.tr.setSelection(selection), schema, alignment);
view.dispatch(tr);
};
|