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

Anchor higlights on multiple elements. #289

Open
karger opened this issue Nov 15, 2024 · 0 comments
Open

Anchor higlights on multiple elements. #289

karger opened this issue Nov 15, 2024 · 0 comments

Comments

@karger
Copy link
Member

karger commented Nov 15, 2024

The way NB currently creates its highlights by inserting, at the top level of the document body, a single svg element that spans the entire body. To create highlight a particular content on the page, nb determines the location of that content on the page and draws one or more colored rectangles on the svg element at the same coordinates as the content being highlighted. Since the svg element is in the body, any time the page is scrolled both the content and the highlight move together, so the highlight always stays on top of the content.

This approach breaks down when different parts of the page can move independently of the containing body. For example a descendant element can be given its own scrollbar and moved independently of the main body. Since the highlights are on an svg at the top level, they will not move with the content and will thus be in the wrong place.

An incremental improvement to this situation would be, instead of a single svg to place numerous svg's lower down in the dom tree. Basically, once you determine the range that needs to be highlighted, you find the lowest DOM node X that contains the entire range, place an svg element there, and draw the highlight on that particular svg element. Now the highlight will stay aligned with its range so long as the content is unmoving relative to X, instead of needing to be unmoving relative to the entire DOM. So for example it's OK if X is inside some inner scrolling element.

But the DOM spec has been evolving, and there's now a better approach to highlighting than svg. They have no introduced a CSS Custom HIghlights API. It allows a highlight to be applied to any range, in particular a static range anywhere on the page. The range is exactly what we want to highlight, so a highlight generated this way will always move perfectly aligned with the content being highlighted.

This gives a good solution to drawing the highlight, but it's also necessary to handle a click on the highlight which is supposed to select and scroll to the corresponding annotation content in the sidebar. I think you can do this by (i) putting an event listener on the lowest DOM node containing the entire range and, when a click occurs in that element, (ii) using geometry to test whether the click actually occurred inside the range.

Looking ahead, there's a potentially even more powerful approach to our problem, using so-called anchor positioning. This allows you to place an element outside the flow of the dom at a fixed position relative to a particular DOM element. So you e.g. you could place a rectangular element (ie a div) that has a particular fixed offset from the lowest containing dom node to both highhight particular content and also receive the click event that tells you that a highlight has been clicked. Unfortunately, according the above link at caniuse, anchor positioning has been deployed on chrome and edge but not safari or firefox so you can't rely on its working everywhere. However, this could change before you begin development so we should keep an eye on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant