Skip to content

Commit 5482e35

Browse files
committed
[WIP] useTextSelection hook
1 parent 93faf4d commit 5482e35

1 file changed

Lines changed: 71 additions & 75 deletions

File tree

Lines changed: 71 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,81 @@
1-
function getSelectedTextDirection(selection) {
1+
function getSelectedTextDirection(selection: Selection) {
22
const range = document.createRange();
3-
range.setStart(selection.anchorNode, selection.anchorOffset);
4-
range.setEnd(selection.focusNode, selection.focusOffset);
3+
range.setStart(selection.anchorNode!, selection.anchorOffset);
4+
range.setEnd(selection.focusNode!, selection.focusOffset);
55
return range.collapsed ? 'backward' : 'forward';
66
}
77
function getTextSelectionDataSet() {
8-
let ws = window.getSelection();
9-
let data = {
10-
text: '',
11-
rect: null,
12-
rectAnnotations: []
13-
}
14-
if (ws === null) {
15-
return data;
16-
}
17-
data = {
18-
text: ws?.toString(),
19-
rect: ws?.getRangeAt(0).getBoundingClientRect(),
20-
rectAnnotations: [],
21-
}
22-
if(data.text === "") {
23-
return data;
24-
}
25-
let allText = ws.toString();
26-
let direction = getSelectedTextDirection(ws);
27-
let ranges = [];
28-
let spanText, spanContainer, selectedText, offset;
8+
const ws = window.getSelection();
9+
if (ws === null || ws.toString() === "") {
10+
return { text: "", rect: null, rects: [] };
11+
}
12+
const data: { text: string, rect: DOMRect | null, rects: Omit<DOMRect, "toJSON">[] } = {
13+
text: ws.toString(),
14+
rect: ws.getRangeAt(0).getBoundingClientRect(),
15+
rects: []
16+
}
17+
const direction = getSelectedTextDirection(ws),
18+
ranges = [];
19+
let allText = data.text;
20+
let spanText: Node | null, selectedText, offset;
2921

30-
if(direction === "backward") {
31-
spanText = ws.focusNode.parentNode;
32-
spanContainer = spanText.parentNode;
33-
offset = ws.focusOffset;
34-
} else {
35-
spanText = ws.baseNode.parentNode;
36-
spanContainer = spanText.parentNode;
37-
offset = ws.anchorOffset;
38-
}
22+
if (direction === "backward") {
23+
spanText = ws.focusNode!.parentNode;
24+
offset = ws.focusOffset;
25+
} else {
26+
spanText = ws.anchorNode!.parentNode;
27+
offset = ws.anchorOffset;
28+
}
3929

40-
let range = document.createRange();
41-
range.setStart(spanText.firstChild, offset);
42-
selectedText = spanText.firstChild.data.toString().substring(offset);
43-
if(allText.length<= selectedText.length) {
44-
range.setEnd(spanText.firstChild, offset+allText.length);
45-
ranges.push(range);
46-
allText = "";
47-
} else {
48-
range.setEnd(spanText.firstChild, offset+selectedText.length);
49-
ranges.push(range);
50-
allText = allText.substring(selectedText.length);
51-
}
30+
const range = document.createRange();
31+
range.setStart(spanText!.firstChild!, offset);
32+
selectedText = (spanText!.firstChild! as ChildNode & {data: string}).data.toString().substring(offset);
33+
if (allText.length <= selectedText.length) {
34+
range.setEnd(spanText!.firstChild!, offset + allText.length);
35+
ranges.push(range);
36+
allText = "";
37+
} else {
38+
range.setEnd(spanText!.firstChild!, offset + selectedText.length);
39+
ranges.push(range);
40+
allText = allText.substring(selectedText.length);
41+
}
5242

53-
while(allText !== "") {
54-
while(allText.charAt(0) === "\n") {allText = allText.substring(1)};
55-
allText = allText.charAt(0) === "\n" ? allText.substring(1) : allText;
56-
while(spanText.nextSibling !== null) {
57-
spanText = spanText.nextSibling;
58-
}
59-
let range = document.createRange();
60-
selectedText = spanText.firstChild.data.toString();
61-
range.setStart(spanText.firstChild, 0);
62-
if(allText.length <= selectedText.length) {
63-
range.setEnd(spanText.firstChild, allText.length);
64-
ranges.push(range);
65-
allText = "";
66-
} else {
67-
range.setEnd(spanText.firstChild, selectedText.length);
68-
ranges.push(range);
69-
allText = allText.substring(selectedText.length);
70-
}
71-
}
43+
while (allText !== "") {
44+
while (allText.charAt(0) === "\n") {
45+
allText = allText.substring(1);
46+
}
47+
spanText = spanText!.nextSibling;
48+
if (spanText === null || allText === "") {
49+
break;
50+
}
51+
const range = document.createRange();
52+
selectedText = (spanText!.firstChild! as ChildNode & { data: string }).data.toString();
53+
range.setStart(spanText!.firstChild!, 0);
54+
if (allText.length <= selectedText.length) {
55+
range.setEnd(spanText!.firstChild!, allText.length);
56+
ranges.push(range);
57+
allText = "";
58+
} else {
59+
range.setEnd(spanText!.firstChild!, selectedText.length);
60+
ranges.push(range);
61+
allText = allText.substring(selectedText.length);
62+
}
63+
}
7264

73-
data.rectAnnotations = ranges.map(el => {
74-
let dim = el.getBoundingClientRect();
75-
return {
76-
x: dim.x-(data.rect ? data.rect.x : 0) ,
77-
y: dim.y-(data.rect ? data.rect.y : 0),
78-
width: dim.width,
79-
height: dim.height
80-
}
81-
});
65+
data.rects = ranges.map(el => {
66+
const dim = el.getBoundingClientRect();
67+
return {
68+
x: dim.x - (data.rect ? data.rect.x : 0),
69+
y: dim.y - (data.rect ? data.rect.y : 0),
70+
top: dim.top - (data.rect ? data.rect.top : 0),
71+
left: dim.left - (data.rect ? data.rect.left : 0),
72+
right: dim.right - (data.rect ? data.rect.right : 0),
73+
bottom: dim.bottom - (data.rect ? data.rect.bottom : 0),
74+
width: dim.width,
75+
height: dim.height
76+
}
77+
});
8278

83-
window.getSelection()?.removeAllRanges();
84-
console.log("TEXT_SELECTION_RANGES", data);
79+
window.getSelection()?.removeAllRanges();
80+
console.log("TEXT_SELECTION_RANGES", data);
8581
}

0 commit comments

Comments
 (0)