Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#283 - Resize span #3720

Merged
merged 1 commit into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<script lang="ts">
import { caretRangeFromPoint } from '@inception-project/inception-js-api'
import { createEventDispatcher, onMount } from 'svelte'
import { closestChunk } from '../visualizer/Visualizer'
import { findClosestChunkElement } from '../visualizer/Visualizer'

export let highlight: Element = undefined
export let position: 'begin' | 'end'
Expand Down Expand Up @@ -102,23 +102,52 @@
return
}

console.log(`clientX: ${event.clientX}, clientY: ${event.clientY}`)
const range = caretRangeFromPoint(event.clientX, event.clientY)

if (!range || !closestChunk(range.startContainer)) {
const chunk = findClosestChunkElement(range.startContainer)
console.log(chunk)
if (!range || !chunk) {
markerVisibility = 'hidden'
return
}

const rect = range.getBoundingClientRect()
const scrollerContainerRect = scrollContainer.getBoundingClientRect()
const rect = range.getBoundingClientRect()

// In Safari and Firefox, the bounding rect of the caret rect is completely broken and we need
// to fix it up. We can detect if the caret rect is broken by checking if the caret rect is
// withing the rect of the container element of the range (which should always be true!).
let container = range.commonAncestorContainer instanceof Element ? range.commonAncestorContainer : range.commonAncestorContainer.parentElement
const containerRect = container.getBoundingClientRect()

const isRectConsistent = containerRect.left <= rect.x && rect.x <= containerRect.right
&& containerRect.top <= rect.y && rect.y <= containerRect.bottom
if (!isRectConsistent) {
rect.x = rect.x - scrollerContainerRect.left + containerRect.left
rect.y = rect.y - scrollerContainerRect.top + containerRect.top

// Firefox has the additional problem that the caret rect always snaps to the begin of the
// ancestor range, so we need to adjust the rect to the actual caret position based on the
// offset within the container. This is a very rough approximation...
const avgGlyphWidth = containerRect.width / container.textContent.length
const isRtl = container.closest('svg[direction="rtl"]') !== null
const tolerance = 5
const expectedX = isRtl ?
containerRect.right - (avgGlyphWidth * range.startOffset) :
containerRect.left + (avgGlyphWidth * range.startOffset)
if (Math.abs(rect.x - expectedX) > tolerance) {
rect.x = expectedX
}
}

markerX = rect.left + scrollContainer.scrollLeft - scrollerContainerRect.left
markerY = rect.top + scrollContainer.scrollTop - scrollerContainerRect.top
markerHeight = rect.height
markerHeight = rect.height || containerRect.height // Firefox does not return a height for the caret rect
markerVisibility = 'visible'
}

function handleDragEnd(event: MouseEvent) {
console.log("handleDragEnd")
// Prevent the drag-end from turning into a mouse-up event which would trigger a selection
// of the annotation
event.stopPropagation()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ import { Box, Svg, SVGTypeMapping, Point } from '@svgdotjs/svg.js'
import { DocumentData } from '../visualizer/DocumentData'
import { INSTANCE as Configuration } from '../configuration/Configuration'
import { INSTANCE as Util } from '../util/Util'
import { DiamAjax, Offsets } from '@inception-project/inception-js-api'
import { DiamAjax } from '@inception-project/inception-js-api'
import { EntityTypeDto, VID } from '../protocol/Protocol'
import { closestChunk, Visualizer } from '../visualizer/Visualizer'
import { timeStamp } from 'console'
import { findClosestChunkElement, Visualizer } from '../visualizer/Visualizer'

export class AnnotatorUI {
private data: DocumentData
Expand Down Expand Up @@ -363,8 +362,8 @@ export class AnnotatorUI {

// let chunkIndexFrom = sel.anchorNode && $(sel.anchorNode.parentNode).attr('data-chunk-id')
// let chunkIndexTo = sel.focusNode && $(sel.focusNode.parentNode).attr('data-chunk-id')
let chunkIndexFrom = closestChunk(sel.anchorNode)?.getAttribute('data-chunk-id')
let chunkIndexTo = closestChunk(sel.focusNode)?.getAttribute('data-chunk-id')
let chunkIndexFrom = findClosestChunkElement(sel.anchorNode)?.getAttribute('data-chunk-id')
let chunkIndexTo = findClosestChunkElement(sel.focusNode)?.getAttribute('data-chunk-id')
// fallback for firefox (at least):
// it's unclear why, but for firefox the anchor and focus node parents are always undefined,
// the the anchor and focus nodes themselves do (often) have the necessary chunk ID. However,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4111,9 +4111,9 @@ export class Visualizer {
rangeToOffsets (range: Range | null) : Offsets | null {
if (!range || !this.data) return null

let anchorNode = closestChunk(range.startContainer)
let anchorNode = findClosestChunkElement(range.startContainer)
let anchorOffset = range.startOffset
let focusNode = closestChunk(range.endContainer)
let focusNode = findClosestChunkElement(range.endContainer)
let focusOffset = range.endOffset

// If neither approach worked, give up - the user didn't click on selectable text.
Expand Down Expand Up @@ -4195,13 +4195,13 @@ export class Visualizer {
* @param target a DOM node.
* @returns the closest highlight element or null if none is found.
*/
export function closestChunk (target: Node | null): Element | null {
export function findClosestChunkElement (target: Node | null): Element | null {
if (target instanceof Text) {
target = target.parentElement
}

if (target instanceof Element) {
return target.closest('[data-chunk-id]')
return target.closest(':not(.spacing)[data-chunk-id]')
}

return null
Expand Down