-
Notifications
You must be signed in to change notification settings - Fork 23k
Editorial review: Add docs for the HighlightRegistry.highlightsFromPoint() method #40390
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
Merged
estelle
merged 8 commits into
mdn:main
from
chrisdavidmills:highlightregistry-highlightsfrompoint
Jul 23, 2025
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
d2d14a5
Add docs for the HighlightRegistry.highlightsFromPoint() method
chrisdavidmills fc68b5a
Fixes for ffiori review comments
chrisdavidmills 228f652
final few bits of cleanup
chrisdavidmills 47f07c1
Merge branch 'main' of github.com:mdn/content into highlightregistry-…
chrisdavidmills b0ebafe
Update files/en-us/web/api/highlightregistry/highlightsfrompoint/inde…
chrisdavidmills 3867bbb
Update files/en-us/web/api/highlightregistry/highlightsfrompoint/inde…
chrisdavidmills 620fa1d
Address estelle review comments
chrisdavidmills 6037da2
Split the JS section into two
chrisdavidmills File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
204 changes: 204 additions & 0 deletions
204
files/en-us/web/api/highlightregistry/highlightsfrompoint/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,204 @@ | ||||||||||
| --- | ||||||||||
| title: "HighlightRegistry: highlightsFromPoint() method" | ||||||||||
| short-title: highlightsFromPoint() | ||||||||||
| slug: Web/API/HighlightRegistry/highlightsFromPoint | ||||||||||
| page-type: web-api-instance-method | ||||||||||
| browser-compat: api.HighlightRegistry.highlightsFromPoint | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| {{APIRef("CSS Custom Highlight API")}} | ||||||||||
|
|
||||||||||
| The **`highlightsFromPoint()`** method of the {{domxref("HighlightRegistry")}} interface returns an array of objects representing the custom highlights applied at a specific point within the viewport. | ||||||||||
|
|
||||||||||
| ## Syntax | ||||||||||
|
|
||||||||||
| ```js-nolint | ||||||||||
| highlightsFromPoint(x, y) | ||||||||||
| highlightsFromPoint(x, y, options) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### Parameters | ||||||||||
|
|
||||||||||
| - `x` | ||||||||||
| - : The x-coordinate of the point within the viewport from which to return custom highlight information. | ||||||||||
| - `y` | ||||||||||
| - : The y-coordinate of the point within the viewport from which to return custom highlight information. | ||||||||||
| - `options` {{optional_inline}} | ||||||||||
| - : An object containing options, which can include: | ||||||||||
| - `shadowRoots` | ||||||||||
| - : An array of {{domxref("ShadowRoot")}} objects. Custom highlights that exist at the specified point inside shadow roots in the array will also be included in the return value, in addition to those present in the light DOM. By default, highlights inside shadow roots are not returned. | ||||||||||
|
|
||||||||||
| ### Return value | ||||||||||
|
|
||||||||||
| An array of `HighlightHitResult` objects representing the custom highlights applied at the point in the viewport specified by the `x` and `y` parameters. | ||||||||||
|
|
||||||||||
| Each `HighlightHitResult` object contains the following properties: | ||||||||||
|
|
||||||||||
| - `highlight` | ||||||||||
| - : A {{domxref("Highlight")}} object representing the applied custom highlight. | ||||||||||
| - `ranges` | ||||||||||
| - : An array of {{domxref("AbstractRange")}} objects representing the ranges to which the custom highlight is applied. | ||||||||||
|
|
||||||||||
| If no custom highlights are applied at the specified point, or the specified point is outside the viewport, the method returns an empty array. | ||||||||||
|
|
||||||||||
| ## Examples | ||||||||||
|
|
||||||||||
| ### Output custom highlights applied at the mouse pointer position | ||||||||||
|
|
||||||||||
| In this example, you can apply custom highlights to a paragraph of text. These custom highlights can be overlapping. When the user double-clicks the paragraph, we use the `highlightsFromPoint()` method to return the content of any custom highlights located at the mouse pointer coordinates of the double-click. | ||||||||||
|
|
||||||||||
| #### HTML | ||||||||||
|
|
||||||||||
| The markup includes a {{htmlelement("p")}} element containing text to which you can apply custom highlights, and a {{htmlelement("section")}} element into which we will output the highlighted text fragments. | ||||||||||
|
|
||||||||||
| ```html live-sample___highlights-from-point-example | ||||||||||
| <h1>highlightsFromPoint() demo</h1> | ||||||||||
| <p class="highlightable-text"> | ||||||||||
| When you select a section of text then press "h" on the keyboard, the text you | ||||||||||
| selected will be given a custom highlight. Multiple highlights will be colored | ||||||||||
| yellow, red, and blue, in that order. When you double-click on a highlighted | ||||||||||
| section of text, that section will be outputted at the bottom of the UI. If | ||||||||||
| multiple highlights overlap the section, you'll see multiple text sections | ||||||||||
| outputted. | ||||||||||
| </p> | ||||||||||
| <h2>Highlighted text at point</h2> | ||||||||||
| <section></section> | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| #### CSS | ||||||||||
|
|
||||||||||
| In the CSS, we define styling for three custom highlights named `highlight1`, `highlight2`, and `highlight3`. We select each custom highlight by passing its name into the {{cssxref("::highlight()")}} pseudo-element, giving them yellow, red, and blue background colors respectively. | ||||||||||
|
|
||||||||||
| ```css hidden live-sample___highlights-from-point-example | ||||||||||
| * { | ||||||||||
| box-sizing: border-box; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| body { | ||||||||||
| background-color: #fff; | ||||||||||
| color: #333; | ||||||||||
| font: | ||||||||||
| 1em / 1.4 Helvetica Neue, | ||||||||||
| Helvetica, | ||||||||||
| Arial, | ||||||||||
| sans-serif; | ||||||||||
| padding: 1em; | ||||||||||
| max-width: 800px; | ||||||||||
| margin: 0 auto; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| section { | ||||||||||
| display: flex; | ||||||||||
| gap: 10px; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| .highlightable-text, | ||||||||||
| article { | ||||||||||
| padding: 10px; | ||||||||||
| background-color: #eee; | ||||||||||
| border: 2px solid #ddd; | ||||||||||
| border-radius: 5px; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| .instructions { | ||||||||||
| font-size: 0.8rem; | ||||||||||
| } | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ```css live-sample___highlights-from-point-example | ||||||||||
| :root::highlight(highlight1) { | ||||||||||
| background-color: rgb(255 255 0 / 0.5); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| :root::highlight(highlight2) { | ||||||||||
| background-color: rgb(255 0 0 / 0.5); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| :root::highlight(highlight3) { | ||||||||||
| background-color: rgb(0 0 255 / 0.75); | ||||||||||
| color: white; | ||||||||||
| } | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| #### JavaScript | ||||||||||
|
|
||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||||||||||
| The script for this example has two distinct areas of functionality: We first need to create custom highlights and apply them to our content, then we can use the `highlightsFromPoint()` method to return custom highlights from a specific point. | ||||||||||
|
|
||||||||||
| ##### Creating and applying custom highlights | ||||||||||
|
|
||||||||||
| To create custom highlights, we start by grabbing references to the `<p>` element and its contained text node. We then create a variable called `highlightCount`, initially set to `1`, which will be used to specify which custom highlight to apply later on. | ||||||||||
|
|
||||||||||
| ```js live-sample___highlights-from-point-example | ||||||||||
| const pElem = document.querySelector(".highlightable-text"); | ||||||||||
| const textNode = pElem.firstChild; | ||||||||||
| let highlightCount = 1; | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Next, we define a [`keydown`](/en-US/docs/Web/API/Element/keydown_event) event handler that applies a custom highlight to any selected text if <kbd>h</kbd> is pressed on the keyboard. Inside, we start by grabbing the selected text using {{domxref("Window.getSelection()")}} and converting it to a {{domxref("Range")}} using {{domxref("Selection.getRangeAt()")}}. | ||||||||||
|
|
||||||||||
| We check that the `selectedRange` object's [`startContainer`](/en-US/docs/Web/API/Range/startContainer) and [`endContainer`](/en-US/docs/Web/API/Range/endContainer) are both equal to the paragraph `textNode`, to make sure we don't allow any cross-container highlights. If so, we set the custom `highlightName` we want to apply to the `selectedRange` using `highlight${highlightCount++}`. Since we are incrementing `highlightCount`, we add in a check — when it reaches `4`, we set it back to `1`. This has the effect of cycling through the available highlights in order as they are set. | ||||||||||
|
|
||||||||||
| Finally for the `keydown` event handler, we create a new `highlight` object using the {{domxref("Highlight.Highlight", "Highlight()")}} constructor, passing it the `selectedRange` we created earlier. We then apply the chosen custom highlight referenced in `highlightName` to `highlight` using the {{domxref("HighlightRegistry.set()")}} method. | ||||||||||
|
|
||||||||||
| ```js live-sample___highlights-from-point-example | ||||||||||
| window.addEventListener("keydown", (event) => { | ||||||||||
| if (event.key === "h") { | ||||||||||
| const selection = window.getSelection(); | ||||||||||
| const selectedRange = selection.getRangeAt(0); | ||||||||||
| if ( | ||||||||||
| selectedRange.startContainer === textNode && | ||||||||||
| selectedRange.endContainer === textNode | ||||||||||
| ) { | ||||||||||
| const highlightName = `highlight${highlightCount++}`; | ||||||||||
| if (highlightCount === 4) { | ||||||||||
| highlightCount = 1; | ||||||||||
| } | ||||||||||
| const highlight = new Highlight(selectedRange); | ||||||||||
| CSS.highlights.set(highlightName, highlight); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ##### Returning custom highlights from a point | ||||||||||
|
|
||||||||||
| Now that we have the ability to create and apply custom highlights, we can use the `highlightsFromPoint()` method to return the custom highlights applied at a specific point. | ||||||||||
|
|
||||||||||
| We grab a reference to our `<section>` element, then define a [`dblclick`](/en-US/docs/Web/API/Element/dblclick_event) event handler function to handle outputting the highlighted text at the mouse cursor position when the event fires. Inside the handler we pass the current mouse coordinates into a `highlightsFromPoint()` call, clear the contents of the `<section>` element, then loop through each highlight in the `highlights` array. | ||||||||||
|
|
||||||||||
| For each `highlight`, we grab the first range in the [`ranges`](#ranges) array (there is only ever one range in each highlight, in this case), then get the exact highlighted string using {{domxref("Range.toString()")}} and add it to the `<section>` element's `innerHTML`, inside an `<article>` element. | ||||||||||
|
|
||||||||||
| ```js live-sample___highlights-from-point-example | ||||||||||
| const section = document.querySelector("section"); | ||||||||||
|
|
||||||||||
| pElem.addEventListener("dblclick", (event) => { | ||||||||||
| const highlights = CSS.highlights.highlightsFromPoint( | ||||||||||
| event.clientX, | ||||||||||
| event.clientY, | ||||||||||
| ); | ||||||||||
|
|
||||||||||
| section.innerHTML = ""; | ||||||||||
| for (highlight of highlights) { | ||||||||||
| const range = highlight.ranges[0]; | ||||||||||
| const textSelection = range.toString(); | ||||||||||
| section.innerHTML += `<article>${textSelection}</article>`; | ||||||||||
| } | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| #### Result | ||||||||||
|
|
||||||||||
| {{EmbedLiveSample("highlights-from-point-example", "100%", "600")}} | ||||||||||
|
|
||||||||||
| ## Specifications | ||||||||||
|
|
||||||||||
| {{Specifications}} | ||||||||||
chrisdavidmills marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ## Browser compatibility | ||||||||||
|
|
||||||||||
| {{Compat}} | ||||||||||
|
|
||||||||||
| ## See also | ||||||||||
|
|
||||||||||
| - {{domxref("css_custom_highlight_api", "The CSS Custom Highlight API", "", "nocode")}} | ||||||||||
chrisdavidmills marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| - [CSS custom highlight API](/en-US/docs/Web/CSS/CSS_custom_highlight_API) module | ||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.