recogito / text-annotator-js

A JavaScript library for text annotation.
BSD 3-Clause "New" or "Revised" License
15 stars 5 forks source link

Browser's selection highlight dimensions don't match the emulated highlights #109

Open oleksandr-danylchenko opened 1 week ago

oleksandr-danylchenko commented 1 week ago

Issue

When users select the text, both the default browser's selection highlight and the customly drawn highlight appear. Unfortunately, their dimensions don't match and that leads to the following views across browsers: Chrome Safari Firefox
image image image
That hanging bluish default selection background looks a bit out of place. Ideally, the emulated highlight should match its dimensions. Fortunately, that can be achieved by applying various sizes of compensations based on the browser: Chrome Safari Firefox
image image image

The padding can be applied in the concrete renderers, as I did for the canvasRenderer:

// // Chrome
// const selectionHighlightTopCompensation = 3;
// const selectionHighlightBottomCompensation = 7;

// // Safari
// const selectionHighlightTopCompensation = 7;
// const selectionHighlightBottomCompensation = 7;

// Firefox
const selectionHighlightTopCompensation = 0;
const selectionHighlightBottomCompensation = 0;
offsetRects.forEach(({ x, y, width, height }) =>
  ctx.fillRect(
    x,
    y - selectionHighlightTopCompensation ,
    width,
    height + selectionHighlightBottomCompensation
  )
);
oleksandr-danylchenko commented 1 week ago

I'm surprised that Firefox is the only browser that doesn't apply some magical padding to its selection highlights 👀👀👀

rsimon commented 1 week ago

Thanks for testing this out. I was thinking about whether I should just CSS-disable the native selection. But then left it because a) it's probably something that the host application would want to control; b) the native selection is, simply, rendered faster. Not a massive issue, and only for really large (XML - in our case) documents. But still.

About matching the sizes: I wonder how reliable those numbers are though, across different OSes and version increments...

oleksandr-danylchenko commented 1 week ago

I already tried disabling the native selection in my app and it didn't go that well 😅

${ANNOTATABLE_SELECTOR}::selection {
  background: none;
}
${ANNOTATABLE_SELECTOR} {
  *::selection {
    background: none;
  }
}

Especially when you have not-annotatable content in between the annotatable parts:

https://github.com/recogito/text-annotator-js/assets/68850090/21080513-89da-4d52-942b-1fedd9050027

screen-capture (11).webm

https://github.com/recogito/text-annotator-js/assets/68850090/655593f8-2311-44f1-ab16-3ce1ce7731e1


However, it worked fine when you work exclusively with the textual content and don't have any headers/footers/etc. that can get selected via the Ctrl+A 😓

https://github.com/recogito/text-annotator-js/assets/68850090/8d931de0-2124-4569-be53-7e2e750022ad

oleksandr-danylchenko commented 1 week ago

About matching the sizes: I wonder how reliable those numbers are though, across different OSes and version increments...

That's a great question! I was just about to experiment with that using the Browserstack. I'll get back with the results 🙌🏻

oleksandr-danylchenko commented 1 week ago

Aha, it's even more complex than I anticipated... The browser's selection highlight height can differ based on the selection element (h vs p) and the text row number 🤯

Here are the demos of the selection behavior across browsers with the:

const selectionHighlightTopCompensation = 0;
const selectionHighlightBottomCompensation = 0;

TL;DR;

Firefox is the most stable one and it always paints the selection hight using the same height.

Chrome:

https://github.com/recogito/text-annotator-js/assets/68850090/a295843d-a219-483b-b9cb-8ff546b235ce

Safari:

https://github.com/recogito/text-annotator-js/assets/68850090/4f029b1c-d4d4-4981-a617-60cddb135a6d

Firefox:

https://github.com/recogito/text-annotator-js/assets/68850090/a161771b-61e5-48fd-b9bb-e3925df4b665

oleksandr-danylchenko commented 1 week ago

However, the font-size doesn't seem to cause any variations in the highlight height. The shape is the same, it just scales up/down:

https://github.com/recogito/text-annotator-js/assets/68850090/cf3559cf-d9b8-4698-b2e9-b506aefbcf02

oleksandr-danylchenko commented 6 days ago

After many trials and tests in different environments, I would say that the selectionHighlightCompensation should be removed and we should draw highlights using just the "raw dimensions". Such a conclusion comes from multiple factors:

https://github.com/recogito/text-annotator-js/assets/68850090/2667de32-640b-4d56-9215-7f6077fc357c

In the video, you can see that only in Chrome the default selection highlight is higher than the CSS one. Which begs the question whether that was intended behavior added by the Chromium devs 🤔