#949: document.caretPositionFromPoint API in shadow DOM scenario

Visit on Github.

Opened Apr 25, 2024

こんにちは TAG-さん!

I'm requesting a TAG review of document.caretPositionFromPoint API in shadow DOM scenario.

The document.caretPositionFromPoint returns a CaretPosition which represents the caret position indicating current text insertion point. However, the current spec is vague about the behavior in shadow DOM scenario. The proposal attempts to specify the behavior in shadow DOM.

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • Relevant time constraints or deadlines: None
  • The group where the work on this specification is currently being done: CSSWG
  • The group where standardization of this work is intended to be done (if current group is a community group or other incubation venue): CSSWG
  • Major unresolved issues with or opposition to this specification: We have not heard of opposition, the proposal has been discussed in CSSWG and came to an agreement.
  • This work is being funded by: Microsoft

[1] document.caretPositionFromPoint in shadow DOM scenario explainer:

Use case/developer need

It's necessary for web developers to have a method to determine the caret position within shadow roots. This allows for indentifying node and offset within the shadow root so that range/selection creation is possible in shadow root at specific point.

With the proposal, web developer can get caret position inside shadow root like:

var caret_position = document.caretPositionFromPoint(x, y, shadowRoot1);
// caret_position.offsetNode is inside shadowRoot1
// caret_position.offset is the offset within offsetNode
// caret_position.getClientRect() returns a DOMRect which would be the caret bounds in shadowRoot1.

Background

The document.caretPositionFromPoint API returns a CaretPosition which represents the caret position indicating current text insertion point. However, the current spec doesn't specifically define if and how shadow DOM scenarios should be supported. We want to update the API and spec to support shadow DOM cases in a well defined way.

Proposal

Similar to Selection.getComposedRanges API, We should introduce another argument shadowRoots which is the list of shadow roots that the API can pierce into. The API will look like:

document.caretPositionFromPoint(double x, double y, ShadowRoot... shadowRoots)

the returned caret position will only be in the shadow root if it's provided in shadowRoots argument. Otherwise, the caret position will be in the shadow host's parent at the offset of the shadow host.

The proposed change to the API maintains the boundary of closed shadow tree unless the shadow root is provided to the API.

Alternative considered

  • Do not let this API pierce into shadow tree. Instead, put this API on DocumentOrShadowRoot.

The con to this approach is that the usage might be cumbersome to get a position inside nested shadow roots (need to call the API on each level of shadow root).


Discussions

2024-06-17

Minutes

Matthew: this has cross-engine support. The explainer is in the comment.

Lea: what are they getting?

Matthew: returns a caret position...

Lea: point is relative to...? If there is only one shadowroot why is this not a method on the shadowroot?

Matthew: this is an extension on an existing API...

Lea: it does take multiple shadows. OK.

Matthew: comment at the bottom about alternative that they had which would be more difficult...

Lea: open shadow roots are taken into accounts... Providing the shadow roots argument serves double duty...

Dan: explainer starts with developer need not user need, would like to flag that

Lea: I can post about that too. Also the explainer is not only for the TAG review so it should be standalone.

agree to come back to it in breakout B

2024-06-24

Minutes

Lea: they've changed it to a dictionary...

Dan: Multi-implementer...? https://github.com/WebKit/standards-positions/issues/301 (webkit support) and https://github.com/mozilla/standards-positions/issues/1012 (firefox positive). So great to see that.

<blockquote>

Thank you for being responsive to our feedback.

Indeed, consistency is a good point, though depending on the use cases, it could end up being a good choice to change both of these methods. Therefore, it would still be good to list use cases (starting with user needs).

Nevertheless, we see a shadowRoots argument as a low-level primitive that could later be expanded so it's ok to start from it, especially if it has already shipped in other methods. I would reiterate that elementFromPoint() could also be expanded in the same way for consistency (and I suspect there are plenty of use cases for that too).

It's great to see support from additional implementers.

We’re going to go ahead and close this. Thank you for flying TAG!

</blockquote>