Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/slate-react/utils/lines.ts
1698 views
1
/**
2
* Utilities for single-line deletion
3
*/
4
5
import { Range, Editor } from "slate";
6
import { ReactEditor } from "..";
7
8
const doRectsIntersect = (rect: DOMRect, compareRect: DOMRect) => {
9
const middle = (compareRect.top + compareRect.bottom) / 2;
10
11
return rect.top <= middle && rect.bottom >= middle;
12
};
13
14
const areRangesSameLine = (
15
editor: ReactEditor,
16
range1: Range,
17
range2: Range
18
) => {
19
const rect1 = ReactEditor.toDOMRange(editor, range1).getBoundingClientRect();
20
const rect2 = ReactEditor.toDOMRange(editor, range2).getBoundingClientRect();
21
22
return doRectsIntersect(rect1, rect2) && doRectsIntersect(rect2, rect1);
23
};
24
25
/**
26
* A helper utility that returns the end portion of a `Range`
27
* which is located on a single line.
28
*
29
* @param {Editor} editor The editor object to compare against
30
* @param {Range} parentRange The parent range to compare against
31
* @returns {Range} A valid portion of the parentRange which is on a single line
32
*/
33
export const findCurrentLineRange = (
34
editor: ReactEditor,
35
parentRange: Range
36
): Range => {
37
const parentRangeBoundary = Editor.range(editor, Range.end(parentRange));
38
const positions = Array.from(Editor.positions(editor, { at: parentRange }));
39
40
let left = 0;
41
let right = positions.length;
42
let middle = Math.floor(right / 2);
43
44
if (
45
areRangesSameLine(
46
editor,
47
Editor.range(editor, positions[left]),
48
parentRangeBoundary
49
)
50
) {
51
return Editor.range(editor, positions[left], parentRangeBoundary);
52
}
53
54
if (positions.length < 2) {
55
return Editor.range(
56
editor,
57
positions[positions.length - 1],
58
parentRangeBoundary
59
);
60
}
61
62
while (middle !== positions.length && middle !== left) {
63
if (
64
areRangesSameLine(
65
editor,
66
Editor.range(editor, positions[middle]),
67
parentRangeBoundary
68
)
69
) {
70
right = middle;
71
} else {
72
left = middle;
73
}
74
75
middle = Math.floor((left + right) / 2);
76
}
77
78
return Editor.range(editor, positions[right], parentRangeBoundary);
79
};
80
81