More moves to react-query for key library functions
This commit is contained in:
@ -54,7 +54,7 @@ export async function createHighlight(
|
||||
if (!input.selection.selection) {
|
||||
return {}
|
||||
}
|
||||
|
||||
console.log(' overlapping: ', input.selection.overlapHighlights)
|
||||
const shouldMerge = input.selection.overlapHighlights.length > 0
|
||||
|
||||
const { range, selection } = input.selection
|
||||
|
||||
@ -8,19 +8,20 @@ import type { SelectionAttributes } from './highlightHelpers'
|
||||
|
||||
/**
|
||||
* Get the range of text with {@link SelectionAttributes} that user has selected
|
||||
*
|
||||
*
|
||||
* Event Handlers for detecting/using new highlight selection are registered
|
||||
*
|
||||
*
|
||||
* If the new highlight selection overlaps with existing highlights, the new selection is merged.
|
||||
*
|
||||
*
|
||||
* @param highlightLocations existing highlights
|
||||
* @returns selection range and its setter
|
||||
*/
|
||||
export function useSelection(
|
||||
highlightLocations: HighlightLocation[]
|
||||
): [SelectionAttributes | null, (x: SelectionAttributes | null) => void] {
|
||||
const [touchStartPos, setTouchStartPos] =
|
||||
useState<{ x: number; y: number } | undefined>(undefined)
|
||||
const [touchStartPos, setTouchStartPos] = useState<
|
||||
{ x: number; y: number } | undefined
|
||||
>(undefined)
|
||||
const [selectionAttributes, setSelectionAttributes] =
|
||||
useState<SelectionAttributes | null>(null)
|
||||
|
||||
@ -246,32 +247,38 @@ async function makeSelectionRange(): Promise<
|
||||
|
||||
/**
|
||||
* Edge case:
|
||||
* If the selection ends on range endContainer (or startContainer in reverse select) but no text is selected (i.e. selection ends at
|
||||
* an empty area), the preceding text is highlighted due to range normalizing.
|
||||
* If the selection ends on range endContainer (or startContainer in reverse select) but no text is selected (i.e. selection ends at
|
||||
* an empty area), the preceding text is highlighted due to range normalizing.
|
||||
* This is a visual bug and would sometimes lead to weird highlight behavior during removal.
|
||||
*/
|
||||
const selectionEndNode = selection.focusNode
|
||||
const selectionEndOffset = selection.focusOffset
|
||||
const selectionStartNode = isReverseSelected ? range.endContainer : range.startContainer
|
||||
const selectionStartNode = isReverseSelected
|
||||
? range.endContainer
|
||||
: range.startContainer
|
||||
|
||||
if (selectionEndNode?.nodeType === Node.TEXT_NODE) {
|
||||
const selectionEndNodeEdgeIndex = isReverseSelected ? selectionEndNode.textContent?.length : 0
|
||||
const selectionEndNodeEdgeIndex = isReverseSelected
|
||||
? selectionEndNode.textContent?.length
|
||||
: 0
|
||||
|
||||
if (selectionStartNode !== selectionEndNode &&
|
||||
selectionEndOffset == selectionEndNodeEdgeIndex) {
|
||||
clipRangeToNearestAnchor(range, selectionEndNode, isReverseSelected)
|
||||
if (
|
||||
selectionStartNode !== selectionEndNode &&
|
||||
selectionEndOffset == selectionEndNodeEdgeIndex
|
||||
) {
|
||||
clipRangeToNearestAnchor(range, selectionEndNode, isReverseSelected)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return isRangeAllowed ? { range, isReverseSelected, selection } : undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Clip selection range to the beginning/end of the adjacent anchor element
|
||||
*
|
||||
*
|
||||
* @param range selection range
|
||||
* @param selectionEndNode the node where the selection ended at
|
||||
* @param isReverseSelected
|
||||
* @param isReverseSelected
|
||||
*/
|
||||
const clipRangeToNearestAnchor = (
|
||||
range: Range,
|
||||
@ -279,30 +286,44 @@ const clipRangeToNearestAnchor = (
|
||||
isReverseSelected: boolean
|
||||
) => {
|
||||
let nearestAnchorElement = selectionEndNode.parentElement
|
||||
while (nearestAnchorElement !== null && !nearestAnchorElement.hasAttribute('data-omnivore-anchor-idx')) {
|
||||
nearestAnchorElement = nearestAnchorElement.parentElement;
|
||||
while (
|
||||
nearestAnchorElement !== null &&
|
||||
!nearestAnchorElement.hasAttribute('data-omnivore-anchor-idx')
|
||||
) {
|
||||
nearestAnchorElement = nearestAnchorElement.parentElement
|
||||
}
|
||||
if (!nearestAnchorElement) {
|
||||
throw Error('Unable to find nearest anchor element for node: ' + selectionEndNode)
|
||||
throw Error(
|
||||
'Unable to find nearest anchor element for node: ' + selectionEndNode
|
||||
)
|
||||
}
|
||||
let anchorId = Number(nearestAnchorElement.getAttribute('data-omnivore-anchor-idx')!)
|
||||
let anchorId = Number(
|
||||
nearestAnchorElement.getAttribute('data-omnivore-anchor-idx')!
|
||||
)
|
||||
let adjacentAnchorId, adjacentAnchor, adjacentAnchorOffset
|
||||
if (isReverseSelected) {
|
||||
// move down to find adjacent anchor node and clip at its beginning
|
||||
adjacentAnchorId = anchorId + 1
|
||||
adjacentAnchor = document.querySelectorAll(`[data-omnivore-anchor-idx='${adjacentAnchorId}']`)[0]
|
||||
adjacentAnchor = document.querySelectorAll(
|
||||
`[data-omnivore-anchor-idx='${adjacentAnchorId}']`
|
||||
)[0]
|
||||
adjacentAnchorOffset = 0
|
||||
range.setStart(adjacentAnchor, adjacentAnchorOffset)
|
||||
} else {
|
||||
// move up to find adjacent anchor node and clip at its end
|
||||
do {
|
||||
adjacentAnchorId = --anchorId
|
||||
adjacentAnchor = document.querySelectorAll(`[data-omnivore-anchor-idx='${adjacentAnchorId}']`)[0]
|
||||
adjacentAnchor = document.querySelectorAll(
|
||||
`[data-omnivore-anchor-idx='${adjacentAnchorId}']`
|
||||
)[0]
|
||||
} while (adjacentAnchor.contains(selectionEndNode))
|
||||
if (adjacentAnchor.textContent) {
|
||||
let lastTextNodeChild = adjacentAnchor.lastChild
|
||||
while (!!lastTextNodeChild && lastTextNodeChild.nodeType !== Node.TEXT_NODE) {
|
||||
lastTextNodeChild = lastTextNodeChild.previousSibling;
|
||||
while (
|
||||
!!lastTextNodeChild &&
|
||||
lastTextNodeChild.nodeType !== Node.TEXT_NODE
|
||||
) {
|
||||
lastTextNodeChild = lastTextNodeChild.previousSibling
|
||||
}
|
||||
adjacentAnchor = lastTextNodeChild
|
||||
adjacentAnchorOffset = adjacentAnchor?.nodeValue?.length ?? 0
|
||||
@ -326,7 +347,7 @@ export type RangeEndPos = {
|
||||
|
||||
/**
|
||||
* Return coordinates of the screen area occupied by the last line of user selection
|
||||
*
|
||||
*
|
||||
* @param range range of user selection
|
||||
* @param getFirst whether to get first line of user selection. Get last if false (default)
|
||||
* @returns {RangeEndPos} selection coordinates
|
||||
|
||||
Reference in New Issue
Block a user