-
Notifications
You must be signed in to change notification settings - Fork 169
/
Copy pathindent.ts
83 lines (64 loc) · 1.78 KB
/
indent.ts
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { TextSelection, AllSelection, Transaction } from 'prosemirror-state';
import { CommandFunction } from 'tiptap-commands';
import { isListNode } from './list';
import { clamp } from './shared';
export const enum IndentProps {
max = 7,
min = 0,
more = 1,
less = -1,
}
function updateIndentLevel (tr: Transaction, delta: number): Transaction {
const { doc, selection } = tr;
if (!doc || !selection) return tr;
if (!(selection instanceof TextSelection || selection instanceof AllSelection)) {
return tr;
}
const { from, to } = selection;
doc.nodesBetween(from, to, (node, pos) => {
const nodeType = node.type;
if (
nodeType.name === 'paragraph' ||
nodeType.name === 'heading' ||
nodeType.name === 'blockquote'
) {
tr = setNodeIndentMarkup(tr, pos, delta);
return false;
} else if (isListNode(node)) {
return false;
}
return true;
});
return tr;
}
function setNodeIndentMarkup (tr: Transaction, pos: number, delta: number): Transaction {
if (!tr.doc) return tr;
const node = tr.doc.nodeAt(pos);
if (!node) return tr;
const minIndent = IndentProps.min;
const maxIndent = IndentProps.max;
const indent = clamp(
(node.attrs.indent || 0) + delta,
minIndent,
maxIndent,
);
if (indent === node.attrs.indent) return tr;
const nodeAttrs = {
...node.attrs,
indent,
};
return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);
}
export function createIndentCommand (delta: number): CommandFunction {
return (state, dispatch) => {
const { selection } = state;
let { tr } = state;
tr = tr.setSelection(selection);
tr = updateIndentLevel(tr, delta);
if (tr.docChanged) {
dispatch && dispatch(tr);
return true;
}
return false;
};
}