csswg-drafts
csswg-drafts copied to clipboard
[cssom-view] Specify document.caretPositionFromPoint in shadow DOM scenario
Current spec is vague about the behavior in shadow DOM: https://www.w3.org/TR/cssom-view-1/#dom-document-caretpositionfrompoint
Gecko's current behavior in shadow DOM:
The returned CaretPosition's offset is the text offset of the hit tested text node and the offsetNode depends on the mode of the shadow tree:
- If the tree is created by user agent such as input element, the node is the shadow host.
- Otherwise, the node is the hit tested text node even if the tree is closed.
Gecko's existing behavior can address most of the need for web developers. Should we specify the behavior?
Or are there other alternatives that we should consider:
caretPositionFromPointdo not pierce shadow DOM. Instead, put the API onDocumentOrShadowRoot.- support closed shadow root with a new parameter:
document.caretPositionFromPoint(x, y, closedShadowRoot);
@zcorpan @fantasai @tabatkins Curious if any of you have any thoughts on how we can better define the behavior of caretPositionFromPoint for shadow DOM scenarios?
Are there other APIs that pierce shadow DOM?
Document.getSelection() looks like a similar API to me, which doesn't pierce shadow DOM, and returns (container_node_of_host, host_offset_in_container) if the selection is inside shadow DOM (regardless of open or closed). It might be confusing if getSelection() and caretPositionFromPoint() return different results.
caretPositionFromPointdo not pierce shadow DOM. Instead, put the API onDocumentOrShadowRoot.
+1 to this idea.
Asked opinions from web developer's point of view and got some feedback. Web developer's basic requirement is to be able to get a caret position inside shadow roots. The Firefox approach (piercing through the shadow boundary) is acceptable. In fact, sticking to the already existing behavior would allow web developer to simplify the implementation.
Given that, should we specify the already existing Firefox approach and put it in spec?
So in my opinion, the Gecko approach should definitely not be put in the spec. It trivially reveals shadow root contents, including for closed roots, which is very bad:
<!DOCTYPE html>
<div>
<template shadowrootmode=closed>
<div style="width:300px;height:300px;background:lightblue">
Oops
</div>
</template>
</div>
<script>
const str = document.caretPositionFromPoint(100,100).offsetNode.textContent;
document.body.append(str)
</script>
I'd +1 the comments above that this should follow the behavior of getComposedRanges():
- https://w3c.github.io/selection-api/#dom-selection-getcomposedranges
@annevk @rniwa
Based on all feedback, the best approach seems to be the getComposedRanges() style which takes in a set of ShadowRoots and document.caretPositionFromPoint(ShadowRoot ...shadowRoots) can return position in the given shadow roots.
The alternative approach is to put the API on DocumentOrShadowRoot. But 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).
Web developer needs to adjust the current usage of current API to get position in a shadow root. The existing behavior violates the boundary of closed shadow tree so we should consider fixing it as well.
The CSS Working Group just discussed [cssom-view] Specify document.caretPositionFromPoint in shadow DOM scenario, and agreed to the following:
RESOLVED: add shadowRoots parameter to caretPositionFromPoint, same as getComposedRanges
The full IRC log of that discussion
<fantasai> Liu: This API is defined in cssom-view, and spec doesn't have a definition for behavior in shadow DOM<fantasai> Liu: Existing behavior is [missed]
<fantasai> Liu: Other alternatives are to not pierce shadow DOM
<fantasai> Liu: Another approach is to add a new parameter with set of shadow roots, and will return positio inside the shadow roots
<fantasai> Liu: Gathered feedback from community, and preference is to add parameter and only pierce the specified shadow roots
<fantasai> Liu: If this is acceptable, should we adopt?
<fantasai> Liu: Firefox's implementation is that the API can pierce the shadow tree, and tree can be open or closed shadow tree
<fantasai> mfreed: I'm definitely not a fan of revealing contents of shadow trees, particularly closed ones
<fantasai> mfreed: I heard proposed to use getComposedRanges behavior, where if you don't know about the shadow tree you get the shadow host
<dandclark> q+
<sanketj_> q+
<fantasai> astearns: I'm not familiar with these APIs. Is getComposedRanges same pattern as what's proposed here?
<fantasai> mfreed: Yes. parameters to say which you know about, and it will pierce those, and give you host for those that you don't
<astearns> ack dandclark
<fantasai> dandclark: getComposedRanges spec link dropped in the issue doesn't take a parameter
<fantasai> dandclark: do browsers implement something else?
<fantasai> mfreed: It's only implemented in WebKit, definitely not in Blink yet
<fantasai> astearns: Looking at WebIDL there's a parameter, just not in description
<fantasai> dandclark: OK
<astearns> ack sanketj_
<dholbert> q+
<fantasai> sanketj_: Seems that Firefox is only one that pierces closed shadow tree, so getComposedRanges addresses that, so +1
<astearns> ack dholbert
<fantasai> dholbert: With this version of the API, that takes list of shadow roots to pierce, if web developer listed every shadow root in their page they would get existing Firefox behavior?
<fantasai> mfreed: yes, but not possible if you don't have reference to the shadow root you can't provide it
<fantasai> mfreed: so e.g. closed shadow root, unless you set it up, you can't get it
<fantasai> astearns: wrt the spec descriptions, the descriptions don't mention parameters, but the algorithms do process them
<fantasai> astearns: Sounds like we're ready to resolve? Any additional comments?
<fantasai> astearns: Proposed resolution is that caretPositionFromPoint can follow the getComposedRanges behavior and have a shadowRoots parameter
<fantasai> RESOLVED: add shadowRoots parameter to caretPositionFromPoint, same as getComposedRanges
Created PR https://github.com/w3c/csswg-drafts/pull/10200 to update the spec. @zcorpan would you mind taking a look? Thank you!
The PR was merged, closing.