-
Notifications
You must be signed in to change notification settings - Fork 8
/
DecorationUtils.js
97 lines (92 loc) · 2.53 KB
/
DecorationUtils.js
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { DecorationSet, Decoration } from "prosemirror-view";
const noteWrapper = (
id,
notePos,
cursorPos,
type,
side,
inside,
pluginPriority = 1
) => {
const dom = document.createElement("span");
// fixes a firefox bug that makes the decos appear selected
const content = document.createElement("span");
dom.appendChild(content);
dom.classList.add(
`note-${id}`,
`note-wrapper--${side < 0 ? "start" : "end"}`,
`note-wrapper--${type}`
);
dom.dataset.toggleNoteId = id;
const cursorAtWidgetAndInsideNote = inside && cursorPos === notePos;
// If we have a cursor at the note widget position and we're inside a note,
// we need to ensure that other widgets don't alter its render order, so
// we keep the sign of the side value and shrink it to ensure it keeps its
// precedence.
const sideToRender = cursorAtWidgetAndInsideNote
? side - Math.sign(side) / 2
: 0 - side;
return Decoration.widget(notePos, dom, {
// MAX_SAFE_INTEGER is here to order note decorations consistently across
// plugins without imposing a (realistic) limit on the number of noting
// plugins that can run concurrently.
side:
sideToRender + pluginPriority / Number.MAX_SAFE_INTEGER * Math.sign(side),
marks: []
});
};
const placeholderDecos = (noteTransaction, state) => {
const type = noteTransaction.hasPlaceholder(state);
return state.selection.$cursor && type
? [
noteWrapper(
"NONE",
state.selection.$cursor.pos,
state.selection.$cursor.pos,
type,
-1,
true
),
noteWrapper(
"NONE",
state.selection.$cursor.pos,
state.selection.$cursor.pos,
type,
1,
true
)
]
: [];
};
export const createDecorateNotes = (
noteTransaction,
noteTracker,
pluginPriority
) => state =>
DecorationSet.create(state.doc, [
...noteTracker.notes.reduce(
(out, { id, start, end, meta: { type } }) => [
...out,
noteWrapper(
id,
start,
state.selection.$cursor && state.selection.$cursor.pos,
type,
-1,
noteTransaction.currentNoteID === id,
pluginPriority
),
noteWrapper(
id,
end,
state.selection.$cursor && state.selection.$cursor.pos,
type,
1,
noteTransaction.currentNoteID === id,
pluginPriority
)
],
[]
),
...placeholderDecos(noteTransaction, state)
]);